Read wireFormatLeadingByte value from curve object

This commit is contained in:
larabr 2024-05-16 16:45:18 +02:00 committed by larabr
parent 52611e7f26
commit cf94380e26
2 changed files with 10 additions and 9 deletions

View File

@ -95,7 +95,7 @@ async function genPublicEphemeralKey(curve, Q) {
const d = getRandomBytes(32); const d = getRandomBytes(32);
const { secretKey, sharedKey } = await genPrivateEphemeralKey(curve, Q, null, d); const { secretKey, sharedKey } = await genPrivateEphemeralKey(curve, Q, null, d);
let { publicKey } = nacl.box.keyPair.fromSecretKey(secretKey); let { publicKey } = nacl.box.keyPair.fromSecretKey(secretKey);
publicKey = util.concatUint8Array([new Uint8Array([0x40]), publicKey]); publicKey = util.concatUint8Array([new Uint8Array([curve.wireFormatLeadingByte]), publicKey]);
return { publicKey, sharedKey }; // Note: sharedKey is little-endian here, unlike below return { publicKey, sharedKey }; // Note: sharedKey is little-endian here, unlike below
} }
case 'web': case 'web':
@ -327,7 +327,7 @@ async function webPublicEphemeralKey(curve, Q) {
); );
[s, p] = await Promise.all([s, p]); [s, p] = await Promise.all([s, p]);
const sharedKey = new Uint8Array(s); const sharedKey = new Uint8Array(s);
const publicKey = new Uint8Array(jwkToRawPublic(p)); const publicKey = new Uint8Array(jwkToRawPublic(p, curve.wireFormatLeadingByte));
return { publicKey, sharedKey }; return { publicKey, sharedKey };
} }

View File

@ -157,6 +157,7 @@ class CurveWithOID {
this.web = params.web; this.web = params.web;
this.payloadSize = params.payloadSize; this.payloadSize = params.payloadSize;
this.sharedSize = params.sharedSize; this.sharedSize = params.sharedSize;
this.wireFormatLeadingByte = params.wireFormatLeadingByte;
if (this.web && util.getWebCrypto()) { if (this.web && util.getWebCrypto()) {
this.type = 'web'; this.type = 'web';
} else if (this.node && util.getNodeCrypto()) { } else if (this.node && util.getNodeCrypto()) {
@ -172,7 +173,7 @@ class CurveWithOID {
switch (this.type) { switch (this.type) {
case 'web': case 'web':
try { try {
return await webGenKeyPair(this.name); return await webGenKeyPair(this.name, this.wireFormatLeadingByte);
} catch (err) { } catch (err) {
util.printDebugError('Browser did not support generating ec key ' + err.message); util.printDebugError('Browser did not support generating ec key ' + err.message);
return jsGenKeyPair(this.name); return jsGenKeyPair(this.name);
@ -185,13 +186,13 @@ class CurveWithOID {
privateKey[31] &= 248; privateKey[31] &= 248;
const secretKey = privateKey.slice().reverse(); const secretKey = privateKey.slice().reverse();
const { publicKey: rawPublicKey } = nacl.box.keyPair.fromSecretKey(secretKey); const { publicKey: rawPublicKey } = nacl.box.keyPair.fromSecretKey(secretKey);
const publicKey = util.concatUint8Array([new Uint8Array([0x40]), rawPublicKey]); const publicKey = util.concatUint8Array([new Uint8Array([this.wireFormatLeadingByte]), rawPublicKey]);
return { publicKey, privateKey }; return { publicKey, privateKey };
} }
case 'ed25519Legacy': { case 'ed25519Legacy': {
const privateKey = getRandomBytes(32); const privateKey = getRandomBytes(32);
const keyPair = nacl.sign.keyPair.fromSeed(privateKey); const keyPair = nacl.sign.keyPair.fromSeed(privateKey);
const publicKey = util.concatUint8Array([new Uint8Array([0x40]), keyPair.publicKey]); const publicKey = util.concatUint8Array([new Uint8Array([this.wireFormatLeadingByte]), keyPair.publicKey]);
return { publicKey, privateKey }; return { publicKey, privateKey };
} }
default: default:
@ -308,7 +309,7 @@ async function jsGenKeyPair(name) {
return { publicKey, privateKey }; return { publicKey, privateKey };
} }
async function webGenKeyPair(name) { async function webGenKeyPair(name, wireFormatLeadingByte) {
// Note: keys generated with ECDSA and ECDH are structurally equivalent // Note: keys generated with ECDSA and ECDH are structurally equivalent
const webCryptoKey = await webCrypto.generateKey({ name: 'ECDSA', namedCurve: webCurves[name] }, true, ['sign', 'verify']); const webCryptoKey = await webCrypto.generateKey({ name: 'ECDSA', namedCurve: webCurves[name] }, true, ['sign', 'verify']);
@ -316,7 +317,7 @@ async function webGenKeyPair(name) {
const publicKey = await webCrypto.exportKey('jwk', webCryptoKey.publicKey); const publicKey = await webCrypto.exportKey('jwk', webCryptoKey.publicKey);
return { return {
publicKey: jwkToRawPublic(publicKey), publicKey: jwkToRawPublic(publicKey, wireFormatLeadingByte),
privateKey: b64ToUint8Array(privateKey.d, true) privateKey: b64ToUint8Array(privateKey.d, true)
}; };
} }
@ -342,11 +343,11 @@ async function nodeGenKeyPair(name) {
* *
* @returns {Uint8Array} Raw public key. * @returns {Uint8Array} Raw public key.
*/ */
function jwkToRawPublic(jwk) { function jwkToRawPublic(jwk, wireFormatLeadingByte) {
const bufX = b64ToUint8Array(jwk.x); const bufX = b64ToUint8Array(jwk.x);
const bufY = b64ToUint8Array(jwk.y); const bufY = b64ToUint8Array(jwk.y);
const publicKey = new Uint8Array(bufX.length + bufY.length + 1); const publicKey = new Uint8Array(bufX.length + bufY.length + 1);
publicKey[0] = 0x04; publicKey[0] = wireFormatLeadingByte;
publicKey.set(bufX, 1); publicKey.set(bufX, 1);
publicKey.set(bufY, bufX.length + 1); publicKey.set(bufY, bufX.length + 1);
return publicKey; return publicKey;