From 2da6abb3363699df1c04e993bceecbba343c634e Mon Sep 17 00:00:00 2001 From: Paul Miller Date: Mon, 2 Oct 2023 23:15:43 +0000 Subject: [PATCH] Fix x448 private keys: must be 56 bytes, not 57. Reported by @larabr --- src/abstract/montgomery.ts | 10 ++++------ src/ed448.ts | 2 +- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/abstract/montgomery.ts b/src/abstract/montgomery.ts index 64d1b53..6461096 100644 --- a/src/abstract/montgomery.ts +++ b/src/abstract/montgomery.ts @@ -150,17 +150,15 @@ export function montgomery(curveDef: CurveType): CurveFn { function decodeUCoordinate(uEnc: Hex): bigint { // Section 5: When receiving such an array, implementations of X25519 // MUST mask the most significant bit in the final byte. - // This is very ugly way, but it works because fieldLen-1 is outside of bounds for X448, so this becomes NOOP - // fieldLen - scalaryBytes = 1 for X448 and = 0 for X25519 const u = ensureBytes('u coordinate', uEnc, montgomeryBytes); - // u[fieldLen-1] crashes QuickJS (TypeError: out-of-bound numeric index) - if (fieldLen === montgomeryBytes) u[fieldLen - 1] &= 127; // 0b0111_1111 + if (fieldLen === 32) u[31] &= 127; // 0b0111_1111 return bytesToNumberLE(u); } function decodeScalar(n: Hex): bigint { const bytes = ensureBytes('scalar', n); - if (bytes.length !== montgomeryBytes && bytes.length !== fieldLen) - throw new Error(`Expected ${montgomeryBytes} or ${fieldLen} bytes, got ${bytes.length}`); + const len = bytes.length; + if (len !== montgomeryBytes && len !== fieldLen) + throw new Error(`Expected ${montgomeryBytes} or ${fieldLen} bytes, got ${len}`); return bytesToNumberLE(adjustScalarBytes(bytes)); } function scalarMult(scalar: Hex, u: Hex): Uint8Array { diff --git a/src/ed448.ts b/src/ed448.ts index ccc8e3b..a45f58d 100644 --- a/src/ed448.ts +++ b/src/ed448.ts @@ -140,7 +140,7 @@ export const x448 = /* @__PURE__ */ (() => a: BigInt(156326), // RFC 7748 has 56-byte keys, RFC 8032 has 57-byte keys montgomeryBits: 448, - nByteLength: 57, + nByteLength: 56, P: ed448P, Gu: BigInt(5), powPminus2: (x: bigint): bigint => {