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))
|
.update(concatBytes(...msgs))
|
||||||
.digest();
|
.digest();
|
||||||
import * as noble_ed25519 from '@noble/ed25519';
|
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));
|
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';
|
const ONLY_NOBLE = process.argv[2] === 'noble';
|
||||||
|
|
||||||
function generateData(namespace) {
|
function generateData(namespace) {
|
||||||
@ -73,17 +66,23 @@ export const CURVES = {
|
|||||||
secp256k1_old: ({ msg, priv }) => old_secp.signSync(msg, priv),
|
secp256k1_old: ({ msg, priv }) => old_secp.signSync(msg, priv),
|
||||||
secp256k1: ({ msg, priv }) => secp256k1.sign(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: {
|
verify: {
|
||||||
samples: 1000,
|
samples: 1000,
|
||||||
secp256k1_old: ({ sig, msg, pub }) => {
|
secp256k1_old: ({ sig, msg, pub }) => {
|
||||||
return old_secp.verify((new old_secp.Signature(sig.r, sig.s)), 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)
|
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: {
|
ed25519: {
|
||||||
|
@ -508,13 +508,14 @@ should('RFC7748 getSharedKey', () => {
|
|||||||
|
|
||||||
{
|
{
|
||||||
const group = x25519vectors.testGroups[0];
|
const group = x25519vectors.testGroups[0];
|
||||||
|
should(`Wycheproof/X25519`, () => {
|
||||||
for (let i = 0; i < group.tests.length; i++) {
|
for (let i = 0; i < group.tests.length; i++) {
|
||||||
const v = group.tests[i];
|
const v = group.tests[i];
|
||||||
should(`Wycheproof/X25519(${i}, ${v.result}) ${v.comment}`, () => {
|
const comment = `(${i}, ${v.result}) ${v.comment}`;
|
||||||
if (v.result === 'valid' || v.result === 'acceptable') {
|
if (v.result === 'valid' || v.result === 'acceptable') {
|
||||||
try {
|
try {
|
||||||
const shared = hex(x25519.scalarMult(v.public, v.private));
|
const shared = hex(x25519.scalarMult(v.public, v.private));
|
||||||
deepStrictEqual(shared, v.shared, 'valid');
|
deepStrictEqual(shared, v.shared, comment);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// We are more strict
|
// We are more strict
|
||||||
if (e.message.includes('Expected valid scalar')) return;
|
if (e.message.includes('Expected valid scalar')) return;
|
||||||
@ -528,25 +529,23 @@ should('RFC7748 getSharedKey', () => {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
failed = true;
|
failed = true;
|
||||||
}
|
}
|
||||||
deepStrictEqual(failed, true, 'invalid');
|
deepStrictEqual(failed, true, comment);
|
||||||
} else throw new Error('unknown test result');
|
} else throw new Error('unknown test result');
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
should(`Wycheproof/ED25519`, () => {
|
||||||
for (let g = 0; g < ed25519vectors.testGroups.length; g++) {
|
for (let g = 0; g < ed25519vectors.testGroups.length; g++) {
|
||||||
const group = ed25519vectors.testGroups[g];
|
const group = ed25519vectors.testGroups[g];
|
||||||
const key = group.key;
|
const key = group.key;
|
||||||
should(`Wycheproof/ED25519(${g}, public)`, () => {
|
deepStrictEqual(hex(ed.getPublicKey(key.sk)), key.pk, `(${g}, public)`);
|
||||||
deepStrictEqual(hex(ed.getPublicKey(key.sk)), key.pk);
|
|
||||||
});
|
|
||||||
for (let i = 0; i < group.tests.length; i++) {
|
for (let i = 0; i < group.tests.length; i++) {
|
||||||
const v = group.tests[i];
|
const v = group.tests[i];
|
||||||
should(`Wycheproof/ED25519(${g}/${i}, ${v.result}): ${v.comment}`, () => {
|
const comment = `(${g}/${i}, ${v.result}): ${v.comment}`;
|
||||||
if (v.result === 'valid' || v.result === 'acceptable') {
|
if (v.result === 'valid' || v.result === 'acceptable') {
|
||||||
deepStrictEqual(hex(ed.sign(v.msg, key.sk)), v.sig);
|
deepStrictEqual(hex(ed.sign(v.msg, key.sk)), v.sig, comment);
|
||||||
deepStrictEqual(ed.verify(v.sig, v.msg, key.pk), true);
|
deepStrictEqual(ed.verify(v.sig, v.msg, key.pk), true, comment);
|
||||||
} else if (v.result === 'invalid') {
|
} else if (v.result === 'invalid') {
|
||||||
let failed = false;
|
let failed = false;
|
||||||
try {
|
try {
|
||||||
@ -554,12 +553,11 @@ should('RFC7748 getSharedKey', () => {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
failed = true;
|
failed = true;
|
||||||
}
|
}
|
||||||
deepStrictEqual(failed, true, 'invalid');
|
deepStrictEqual(failed, true, comment);
|
||||||
} else throw new Error('unknown test result');
|
} else throw new Error('unknown test result');
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
should('Property test issue #1', () => {
|
should('Property test issue #1', () => {
|
||||||
const message = new Uint8Array([12, 12, 12]);
|
const message = new Uint8Array([12, 12, 12]);
|
||||||
|
@ -439,12 +439,13 @@ should('input immutability: sign/verify are immutable', () => {
|
|||||||
should(`Wycheproof/ED448(${g}, public)`, () => {
|
should(`Wycheproof/ED448(${g}, public)`, () => {
|
||||||
deepStrictEqual(hex(ed.getPublicKey(key.sk)), key.pk);
|
deepStrictEqual(hex(ed.getPublicKey(key.sk)), key.pk);
|
||||||
});
|
});
|
||||||
|
should(`Wycheproof/ED448`, () => {
|
||||||
for (let i = 0; i < group.tests.length; i++) {
|
for (let i = 0; i < group.tests.length; i++) {
|
||||||
const v = group.tests[i];
|
const v = group.tests[i];
|
||||||
should(`Wycheproof/ED448(${g}/${i}, ${v.result}): ${v.comment}`, () => {
|
const index = `${g}/${i} ${v.comment}`;
|
||||||
if (v.result === 'valid' || v.result === 'acceptable') {
|
if (v.result === 'valid' || v.result === 'acceptable') {
|
||||||
deepStrictEqual(hex(ed.sign(v.msg, key.sk)), v.sig);
|
deepStrictEqual(hex(ed.sign(v.msg, key.sk)), v.sig, index);
|
||||||
deepStrictEqual(ed.verify(v.sig, v.msg, key.pk), true);
|
deepStrictEqual(ed.verify(v.sig, v.msg, key.pk), true, index);
|
||||||
} else if (v.result === 'invalid') {
|
} else if (v.result === 'invalid') {
|
||||||
let failed = false;
|
let failed = false;
|
||||||
try {
|
try {
|
||||||
@ -452,10 +453,10 @@ should('input immutability: sign/verify are immutable', () => {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
failed = true;
|
failed = true;
|
||||||
}
|
}
|
||||||
deepStrictEqual(failed, true, 'invalid');
|
deepStrictEqual(failed, true, index);
|
||||||
} else throw new Error('unknown test result');
|
} else throw new Error('unknown test result');
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -524,13 +525,14 @@ should('RFC7748 getSharedKey', () => {
|
|||||||
|
|
||||||
{
|
{
|
||||||
const group = x448vectors.testGroups[0];
|
const group = x448vectors.testGroups[0];
|
||||||
|
should(`Wycheproof/X448`, () => {
|
||||||
for (let i = 0; i < group.tests.length; i++) {
|
for (let i = 0; i < group.tests.length; i++) {
|
||||||
const v = group.tests[i];
|
const v = group.tests[i];
|
||||||
should(`Wycheproof/X448(${i}, ${v.result}) ${v.comment}`, () => {
|
const index = `(${i}, ${v.result}) ${v.comment}`;
|
||||||
if (v.result === 'valid' || v.result === 'acceptable') {
|
if (v.result === 'valid' || v.result === 'acceptable') {
|
||||||
try {
|
try {
|
||||||
const shared = hex(x448.scalarMult(v.public, v.private));
|
const shared = hex(x448.scalarMult(v.public, v.private));
|
||||||
deepStrictEqual(shared, v.shared, 'valid');
|
deepStrictEqual(shared, v.shared, index);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// We are more strict
|
// We are more strict
|
||||||
if (e.message.includes('Expected valid scalar')) return;
|
if (e.message.includes('Expected valid scalar')) return;
|
||||||
@ -545,10 +547,10 @@ should('RFC7748 getSharedKey', () => {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
failed = true;
|
failed = true;
|
||||||
}
|
}
|
||||||
deepStrictEqual(failed, true, 'invalid');
|
deepStrictEqual(failed, true, index);
|
||||||
} else throw new Error('unknown test result');
|
} else throw new Error('unknown test result');
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// should('X448: should convert base point to montgomery using fromPoint', () => {
|
// should('X448: should convert base point to montgomery using fromPoint', () => {
|
||||||
|
@ -308,21 +308,13 @@ const WYCHEPROOF_ECDSA = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const name in WYCHEPROOF_ECDSA) {
|
function runWycheproof(name, CURVE, group, index) {
|
||||||
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);
|
const pubKey = CURVE.Point.fromHex(group.key.uncompressed);
|
||||||
deepStrictEqual(pubKey.x, BigInt(`0x${group.key.wx}`));
|
deepStrictEqual(pubKey.x, BigInt(`0x${group.key.wx}`));
|
||||||
deepStrictEqual(pubKey.y, BigInt(`0x${group.key.wy}`));
|
deepStrictEqual(pubKey.y, BigInt(`0x${group.key.wy}`));
|
||||||
for (const test of group.tests) {
|
for (const test of group.tests) {
|
||||||
const m = CURVE.CURVE.hash(hexToBytes(test.msg));
|
const m = CURVE.CURVE.hash(hexToBytes(test.msg));
|
||||||
|
|
||||||
if (test.result === 'valid' || test.result === 'acceptable') {
|
if (test.result === 'valid' || test.result === 'acceptable') {
|
||||||
try {
|
try {
|
||||||
CURVE.Signature.fromDER(test.sig);
|
CURVE.Signature.fromDER(test.sig);
|
||||||
@ -334,10 +326,11 @@ for (const name in WYCHEPROOF_ECDSA) {
|
|||||||
const verified = CURVE.verify(test.sig, m, pubKey);
|
const verified = CURVE.verify(test.sig, m, pubKey);
|
||||||
if (name === 'secp256k1') {
|
if (name === 'secp256k1') {
|
||||||
// lowS: true for secp256k1
|
// lowS: true for secp256k1
|
||||||
deepStrictEqual(verified, !CURVE.Signature.fromDER(test.sig).hasHighS());
|
deepStrictEqual(verified, !CURVE.Signature.fromDER(test.sig).hasHighS(), `${index}: valid`);
|
||||||
} else {
|
} else {
|
||||||
deepStrictEqual(verified, true, 'valid');
|
deepStrictEqual(verified, true, `${index}: valid`);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (test.result === 'invalid') {
|
} else if (test.result === 'invalid') {
|
||||||
let failed = false;
|
let failed = false;
|
||||||
try {
|
try {
|
||||||
@ -345,13 +338,26 @@ for (const name in WYCHEPROOF_ECDSA) {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
failed = true;
|
failed = true;
|
||||||
}
|
}
|
||||||
deepStrictEqual(failed, true, 'invalid');
|
deepStrictEqual(failed, true, `${index}: invalid`);
|
||||||
} else throw new Error('unknown test result');
|
} 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);
|
||||||
|
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}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const hexToBigint = (hex) => BigInt(`0x${hex}`);
|
const hexToBigint = (hex) => BigInt(`0x${hex}`);
|
||||||
|
Loading…
Reference in New Issue
Block a user