forked from tornado-packages/noble-curves
Refactor tests slightly: group tests
This commit is contained in:
parent
fd75293334
commit
43b18ea13b
@ -30,19 +30,12 @@ old_secp.utils.hmacSha256Sync = (key, ...msgs) =>
|
||||
.update(concatBytes(...msgs))
|
||||
.digest();
|
||||
import * as noble_ed25519 from '@noble/ed25519';
|
||||
|
||||
secp256k1.utils.precompute(8); // Not enabled by default?
|
||||
ed25519.utils.precompute(8);
|
||||
ed448.utils.precompute(8);
|
||||
P256.utils.precompute(8);
|
||||
P384.utils.precompute(8);
|
||||
P521.utils.precompute(8);
|
||||
|
||||
noble_ed25519.utils.sha512Sync = (...m) => sha512(concatBytes(...m));
|
||||
old_secp.utils.precompute(8);
|
||||
noble_ed25519.utils.precompute(8);
|
||||
|
||||
const wrapBuf = (arrayBuffer) => new Uint8Array(arrayBuffer);
|
||||
for (let item of [secp256k1, ed25519, ed448, P256, P384, P521, old_secp, noble_ed25519]) {
|
||||
item.utils.precompute(8);
|
||||
}
|
||||
|
||||
const ONLY_NOBLE = process.argv[2] === 'noble';
|
||||
|
||||
function generateData(namespace) {
|
||||
@ -73,17 +66,23 @@ export const CURVES = {
|
||||
secp256k1_old: ({ msg, priv }) => old_secp.signSync(msg, priv),
|
||||
secp256k1: ({ msg, priv }) => secp256k1.sign(msg, priv),
|
||||
},
|
||||
getSharedSecret: {
|
||||
samples: 1000,
|
||||
secp256k1_old: ({ pub, priv }) => old_secp.getSharedSecret(priv, pub),
|
||||
secp256k1: ({ pub, priv }) => secp256k1.getSharedSecret(priv, pub),
|
||||
},
|
||||
verify: {
|
||||
samples: 1000,
|
||||
secp256k1_old: ({ sig, msg, pub }) => {
|
||||
return old_secp.verify((new old_secp.Signature(sig.r, sig.s)), msg, pub);
|
||||
},
|
||||
secp256k1: ({ sig, msg, pub }) => secp256k1.verify(sig, msg, pub)
|
||||
},
|
||||
getSharedSecret: {
|
||||
samples: 1000,
|
||||
secp256k1_old: ({ pub, priv }) => old_secp.getSharedSecret(priv, pub),
|
||||
secp256k1: ({ pub, priv }) => secp256k1.getSharedSecret(priv, pub),
|
||||
},
|
||||
recoverPublicKey: {
|
||||
samples: 1000,
|
||||
secp256k1_old: ({ sig, msg }) =>
|
||||
old_secp.recoverPublicKey(msg, (new old_secp.Signature(sig.r, sig.s)), sig.recovery),
|
||||
secp256k1: ({ sig, msg }) => sig.recoverPublicKey(msg)
|
||||
}
|
||||
},
|
||||
ed25519: {
|
||||
|
@ -508,13 +508,14 @@ should('RFC7748 getSharedKey', () => {
|
||||
|
||||
{
|
||||
const group = x25519vectors.testGroups[0];
|
||||
for (let i = 0; i < group.tests.length; i++) {
|
||||
const v = group.tests[i];
|
||||
should(`Wycheproof/X25519(${i}, ${v.result}) ${v.comment}`, () => {
|
||||
should(`Wycheproof/X25519`, () => {
|
||||
for (let i = 0; i < group.tests.length; i++) {
|
||||
const v = group.tests[i];
|
||||
const comment = `(${i}, ${v.result}) ${v.comment}`;
|
||||
if (v.result === 'valid' || v.result === 'acceptable') {
|
||||
try {
|
||||
const shared = hex(x25519.scalarMult(v.public, v.private));
|
||||
deepStrictEqual(shared, v.shared, 'valid');
|
||||
deepStrictEqual(shared, v.shared, comment);
|
||||
} catch (e) {
|
||||
// We are more strict
|
||||
if (e.message.includes('Expected valid scalar')) return;
|
||||
@ -528,38 +529,35 @@ should('RFC7748 getSharedKey', () => {
|
||||
} catch (error) {
|
||||
failed = true;
|
||||
}
|
||||
deepStrictEqual(failed, true, 'invalid');
|
||||
deepStrictEqual(failed, true, comment);
|
||||
} else throw new Error('unknown test result');
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
{
|
||||
should(`Wycheproof/ED25519`, () => {
|
||||
for (let g = 0; g < ed25519vectors.testGroups.length; g++) {
|
||||
const group = ed25519vectors.testGroups[g];
|
||||
const key = group.key;
|
||||
should(`Wycheproof/ED25519(${g}, public)`, () => {
|
||||
deepStrictEqual(hex(ed.getPublicKey(key.sk)), key.pk);
|
||||
});
|
||||
deepStrictEqual(hex(ed.getPublicKey(key.sk)), key.pk, `(${g}, public)`);
|
||||
for (let i = 0; i < group.tests.length; i++) {
|
||||
const v = group.tests[i];
|
||||
should(`Wycheproof/ED25519(${g}/${i}, ${v.result}): ${v.comment}`, () => {
|
||||
if (v.result === 'valid' || v.result === 'acceptable') {
|
||||
deepStrictEqual(hex(ed.sign(v.msg, key.sk)), v.sig);
|
||||
deepStrictEqual(ed.verify(v.sig, v.msg, key.pk), true);
|
||||
} else if (v.result === 'invalid') {
|
||||
let failed = false;
|
||||
try {
|
||||
failed = !ed.verify(v.sig, v.msg, key.pk);
|
||||
} catch (error) {
|
||||
failed = true;
|
||||
}
|
||||
deepStrictEqual(failed, true, 'invalid');
|
||||
} else throw new Error('unknown test result');
|
||||
});
|
||||
const comment = `(${g}/${i}, ${v.result}): ${v.comment}`;
|
||||
if (v.result === 'valid' || v.result === 'acceptable') {
|
||||
deepStrictEqual(hex(ed.sign(v.msg, key.sk)), v.sig, comment);
|
||||
deepStrictEqual(ed.verify(v.sig, v.msg, key.pk), true, comment);
|
||||
} else if (v.result === 'invalid') {
|
||||
let failed = false;
|
||||
try {
|
||||
failed = !ed.verify(v.sig, v.msg, key.pk);
|
||||
} catch (error) {
|
||||
failed = true;
|
||||
}
|
||||
deepStrictEqual(failed, true, comment);
|
||||
} else throw new Error('unknown test result');
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
should('Property test issue #1', () => {
|
||||
const message = new Uint8Array([12, 12, 12]);
|
||||
|
@ -439,12 +439,13 @@ should('input immutability: sign/verify are immutable', () => {
|
||||
should(`Wycheproof/ED448(${g}, public)`, () => {
|
||||
deepStrictEqual(hex(ed.getPublicKey(key.sk)), key.pk);
|
||||
});
|
||||
for (let i = 0; i < group.tests.length; i++) {
|
||||
const v = group.tests[i];
|
||||
should(`Wycheproof/ED448(${g}/${i}, ${v.result}): ${v.comment}`, () => {
|
||||
should(`Wycheproof/ED448`, () => {
|
||||
for (let i = 0; i < group.tests.length; i++) {
|
||||
const v = group.tests[i];
|
||||
const index = `${g}/${i} ${v.comment}`;
|
||||
if (v.result === 'valid' || v.result === 'acceptable') {
|
||||
deepStrictEqual(hex(ed.sign(v.msg, key.sk)), v.sig);
|
||||
deepStrictEqual(ed.verify(v.sig, v.msg, key.pk), true);
|
||||
deepStrictEqual(hex(ed.sign(v.msg, key.sk)), v.sig, index);
|
||||
deepStrictEqual(ed.verify(v.sig, v.msg, key.pk), true, index);
|
||||
} else if (v.result === 'invalid') {
|
||||
let failed = false;
|
||||
try {
|
||||
@ -452,10 +453,10 @@ should('input immutability: sign/verify are immutable', () => {
|
||||
} catch (error) {
|
||||
failed = true;
|
||||
}
|
||||
deepStrictEqual(failed, true, 'invalid');
|
||||
deepStrictEqual(failed, true, index);
|
||||
} else throw new Error('unknown test result');
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -524,13 +525,14 @@ should('RFC7748 getSharedKey', () => {
|
||||
|
||||
{
|
||||
const group = x448vectors.testGroups[0];
|
||||
for (let i = 0; i < group.tests.length; i++) {
|
||||
const v = group.tests[i];
|
||||
should(`Wycheproof/X448(${i}, ${v.result}) ${v.comment}`, () => {
|
||||
should(`Wycheproof/X448`, () => {
|
||||
for (let i = 0; i < group.tests.length; i++) {
|
||||
const v = group.tests[i];
|
||||
const index = `(${i}, ${v.result}) ${v.comment}`;
|
||||
if (v.result === 'valid' || v.result === 'acceptable') {
|
||||
try {
|
||||
const shared = hex(x448.scalarMult(v.public, v.private));
|
||||
deepStrictEqual(shared, v.shared, 'valid');
|
||||
deepStrictEqual(shared, v.shared, index);
|
||||
} catch (e) {
|
||||
// We are more strict
|
||||
if (e.message.includes('Expected valid scalar')) return;
|
||||
@ -545,10 +547,10 @@ should('RFC7748 getSharedKey', () => {
|
||||
} catch (error) {
|
||||
failed = true;
|
||||
}
|
||||
deepStrictEqual(failed, true, 'invalid');
|
||||
deepStrictEqual(failed, true, index);
|
||||
} else throw new Error('unknown test result');
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// should('X448: should convert base point to montgomery using fromPoint', () => {
|
||||
|
@ -308,49 +308,55 @@ const WYCHEPROOF_ECDSA = {
|
||||
},
|
||||
};
|
||||
|
||||
function runWycheproof(name, CURVE, group, index) {
|
||||
const pubKey = CURVE.Point.fromHex(group.key.uncompressed);
|
||||
deepStrictEqual(pubKey.x, BigInt(`0x${group.key.wx}`));
|
||||
deepStrictEqual(pubKey.y, BigInt(`0x${group.key.wy}`));
|
||||
for (const test of group.tests) {
|
||||
const m = CURVE.CURVE.hash(hexToBytes(test.msg));
|
||||
|
||||
if (test.result === 'valid' || test.result === 'acceptable') {
|
||||
try {
|
||||
CURVE.Signature.fromDER(test.sig);
|
||||
} catch (e) {
|
||||
// Some tests has invalid signature which we don't accept
|
||||
if (e.message.includes('Invalid signature: incorrect length')) continue;
|
||||
throw e;
|
||||
}
|
||||
const verified = CURVE.verify(test.sig, m, pubKey);
|
||||
if (name === 'secp256k1') {
|
||||
// lowS: true for secp256k1
|
||||
deepStrictEqual(verified, !CURVE.Signature.fromDER(test.sig).hasHighS(), `${index}: valid`);
|
||||
} else {
|
||||
deepStrictEqual(verified, true, `${index}: valid`);
|
||||
}
|
||||
|
||||
} else if (test.result === 'invalid') {
|
||||
let failed = false;
|
||||
try {
|
||||
failed = !CURVE.verify(test.sig, m, pubKey);
|
||||
} catch (error) {
|
||||
failed = true;
|
||||
}
|
||||
deepStrictEqual(failed, true, `${index}: invalid`);
|
||||
} else throw new Error('unknown test result');
|
||||
}
|
||||
}
|
||||
|
||||
for (const name in WYCHEPROOF_ECDSA) {
|
||||
const { curve, hashes } = WYCHEPROOF_ECDSA[name];
|
||||
for (const hName in hashes) {
|
||||
const { hash, tests } = hashes[hName];
|
||||
const CURVE = curve.create(hash);
|
||||
for (let i = 0; i < tests.length; i++) {
|
||||
const test = tests[i];
|
||||
for (let j = 0; j < test.testGroups.length; j++) {
|
||||
const group = test.testGroups[j];
|
||||
should(`Wycheproof/WYCHEPROOF_ECDSA ${name}/${hName} (${i}/${j})`, () => {
|
||||
const pubKey = CURVE.Point.fromHex(group.key.uncompressed);
|
||||
deepStrictEqual(pubKey.x, BigInt(`0x${group.key.wx}`));
|
||||
deepStrictEqual(pubKey.y, BigInt(`0x${group.key.wy}`));
|
||||
for (const test of group.tests) {
|
||||
const m = CURVE.CURVE.hash(hexToBytes(test.msg));
|
||||
if (test.result === 'valid' || test.result === 'acceptable') {
|
||||
try {
|
||||
CURVE.Signature.fromDER(test.sig);
|
||||
} catch (e) {
|
||||
// Some tests has invalid signature which we don't accept
|
||||
if (e.message.includes('Invalid signature: incorrect length')) continue;
|
||||
throw e;
|
||||
}
|
||||
const verified = CURVE.verify(test.sig, m, pubKey);
|
||||
if (name === 'secp256k1') {
|
||||
// lowS: true for secp256k1
|
||||
deepStrictEqual(verified, !CURVE.Signature.fromDER(test.sig).hasHighS());
|
||||
} else {
|
||||
deepStrictEqual(verified, true, 'valid');
|
||||
}
|
||||
} else if (test.result === 'invalid') {
|
||||
let failed = false;
|
||||
try {
|
||||
failed = !CURVE.verify(test.sig, m, pubKey);
|
||||
} catch (error) {
|
||||
failed = true;
|
||||
}
|
||||
deepStrictEqual(failed, true, 'invalid');
|
||||
} else throw new Error('unknown test result');
|
||||
}
|
||||
});
|
||||
should(`Wycheproof/WYCHEPROOF_ECDSA ${name}/${hName}`, () => {
|
||||
for (let i = 0; i < tests.length; i++) {
|
||||
const groups = tests[i].testGroups;
|
||||
for (let j = 0; j < groups.length; j++) {
|
||||
const group = groups[j];
|
||||
runWycheproof(name, CURVE, group, `${i}/${j}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user