Skip to content

Commit fa3894e

Browse files
committed
Reject non-canonical signatures to prevent malleability
1 parent 72336cc commit fa3894e

1 file changed

Lines changed: 15 additions & 1 deletion

File tree

packages/ed25519/ed25519.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ const I = gf([
7979
0xd7a7, 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83
8080
]);
8181

82+
8283
function set25519(r: GF, a: GF) {
8384
for (let i = 0; i < 16; i++) {
8485
r[i] = a[i] | 0;
@@ -691,7 +692,7 @@ export function extractPublicKeyFromSecretKey(secretKey: Uint8Array): Uint8Array
691692
return new Uint8Array(secretKey.subarray(32));
692693
}
693694

694-
const L = new Float64Array([
695+
const L = new Uint8Array([
695696
0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2,
696697
0xde, 0xf9, 0xde, 0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10
697698
]);
@@ -726,6 +727,16 @@ function modL(r: Uint8Array, x: Float64Array) {
726727
}
727728
}
728729

730+
function iscanonical(s: Uint8Array) {
731+
let c = 0;
732+
let n = 1;
733+
for (let i = 31; i >= 0; i--) {
734+
c |= ((s[i] - L[i]) >> 8) & n;
735+
n &= ((s[i] ^ L[i]) - 1) >> 8;
736+
}
737+
return c !== 0;
738+
}
739+
729740
function reduce(r: Uint8Array) {
730741
const x = new Float64Array(64);
731742
for (let i = 0; i < 64; i++) {
@@ -835,6 +846,9 @@ export function verify(publicKey: Uint8Array, message: Uint8Array, signature: Ui
835846
throw new Error(`ed25519: signature must be ${SIGNATURE_LENGTH} bytes`);
836847
}
837848

849+
if (!iscanonical(signature.subarray(32))) {
850+
return false;
851+
}
838852
if (unpackneg(q, publicKey)) {
839853
return false;
840854
}

0 commit comments

Comments
 (0)