noble-curves/test/stark/basic.test.js
2023-01-25 04:51:08 +01:00

202 lines
7.1 KiB
JavaScript

import { deepStrictEqual, throws } from 'assert';
import { describe, should } from 'micro-should';
import * as starknet from '../../lib/esm/stark.js';
import { default as issue2 } from './fixtures/issue2.json' assert { type: 'json' };
import * as bip32 from '@scure/bip32';
import * as bip39 from '@scure/bip39';
describe('starknet basic', () => {
should('Basic elliptic sanity check', () => {
const g1 = starknet.ProjectivePoint.BASE;
deepStrictEqual(
g1.toAffine().x.toString(16),
'1ef15c18599971b7beced415a40f0c7deacfd9b0d1819e03d723d8bc943cfca'
);
deepStrictEqual(
g1.toAffine().y.toString(16),
'5668060aa49730b7be4801df46ec62de53ecd11abe43a32873000c36e8dc1f'
);
const g2 = g1.double();
deepStrictEqual(
g2.toAffine().x.toString(16),
'759ca09377679ecd535a81e83039658bf40959283187c654c5416f439403cf5'
);
deepStrictEqual(
g2.toAffine().y.toString(16),
'6f524a3400e7708d5c01a28598ad272e7455aa88778b19f93b562d7a9646c41'
);
const g3 = g2.add(g1);
deepStrictEqual(
g3.toAffine().x.toString(16),
'411494b501a98abd8262b0da1351e17899a0c4ef23dd2f96fec5ba847310b20'
);
deepStrictEqual(
g3.toAffine().y.toString(16),
'7e1b3ebac08924d2c26f409549191fcf94f3bf6f301ed3553e22dfb802f0686'
);
const g32 = g1.multiply(3n);
deepStrictEqual(
g32.toAffine().x.toString(16),
'411494b501a98abd8262b0da1351e17899a0c4ef23dd2f96fec5ba847310b20'
);
deepStrictEqual(
g32.toAffine().y.toString(16),
'7e1b3ebac08924d2c26f409549191fcf94f3bf6f301ed3553e22dfb802f0686'
);
const minus1 = g1.multiply(starknet.CURVE.n - 1n);
deepStrictEqual(
minus1.toAffine().x.toString(16),
'1ef15c18599971b7beced415a40f0c7deacfd9b0d1819e03d723d8bc943cfca'
);
deepStrictEqual(
minus1.toAffine().y.toString(16),
'7a997f9f55b68e04841b7fe20b9139d21ac132ee541bc5cd78cfff3c91723e2'
);
});
should('Pedersen', () => {
deepStrictEqual(
starknet.pedersen(2, 3),
'0x5774fa77b3d843ae9167abd61cf80365a9b2b02218fc2f628494b5bdc9b33b8'
);
deepStrictEqual(
starknet.pedersen(1, 2),
'0x5bb9440e27889a364bcb678b1f679ecd1347acdedcbf36e83494f857cc58026'
);
deepStrictEqual(
starknet.pedersen(3, 4),
'0x262697b88544f733e5c6907c3e1763131e9f14c51ee7951258abbfb29415fbf'
);
});
should('Hash chain', () => {
deepStrictEqual(
starknet.hashChain([1, 2, 3]),
'0x5d9d62d4040b977c3f8d2389d494e4e89a96a8b45c44b1368f1cc6ec5418915'
);
});
should('Pedersen hash edgecases', () => {
// >>> pedersen_hash(0,0)
const zero = '0x49ee3eba8c1600700ee1b87eb599f16716b0b1022947733551fde4050ca6804';
deepStrictEqual(starknet.pedersen(0, 0), zero);
deepStrictEqual(starknet.pedersen(0n, 0n), zero);
deepStrictEqual(starknet.pedersen('0', '0'), zero);
deepStrictEqual(starknet.pedersen('0x0', '0x0'), zero);
// >>> pedersen_hash(3618502788666131213697322783095070105623107215331596699973092056135872020475,3618502788666131213697322783095070105623107215331596699973092056135872020475)
// 3226051580231087455100099637526672350308978851161639703631919449959447036451
const big = 3618502788666131213697322783095070105623107215331596699973092056135872020475n;
const bigExp = '0x721e167a36655994e88efa865e2ed8a0488d36db4d988fec043cda755728223';
deepStrictEqual(starknet.pedersen(big, big), bigExp);
// >= FIELD
const big2 = 36185027886661312136973227830950701056231072153315966999730920561358720204751n;
throws(() => starknet.pedersen(big2, big2), 'big2');
// FIELD -1
const big3 = 3618502788666131213697322783095070105623107215331596699973092056135872020480n;
const big3exp = '0x7258fccaf3371fad51b117471d9d888a1786c5694c3e6099160477b593a576e';
deepStrictEqual(starknet.pedersen(big3, big3), big3exp, 'big3');
// FIELD
const big4 = 3618502788666131213697322783095070105623107215331596699973092056135872020481n;
throws(() => starknet.pedersen(big4, big4), 'big4');
throws(() => starknet.pedersen(-1, -1), 'neg');
throws(() => starknet.pedersen(false, false), 'false');
throws(() => starknet.pedersen(true, true), 'true');
throws(() => starknet.pedersen(10.1, 10.1), 'float');
});
should('hashChain edgecases', () => {
deepStrictEqual(starknet.hashChain([32312321312321312312312321n]), '0x1aba6672c014b4838cc201');
deepStrictEqual(
starknet.hashChain([1n, 2n]),
'0x5bb9440e27889a364bcb678b1f679ecd1347acdedcbf36e83494f857cc58026'
);
deepStrictEqual(
starknet.hashChain([1, 2]),
'0x5bb9440e27889a364bcb678b1f679ecd1347acdedcbf36e83494f857cc58026'
);
throws(() => starknet.hashChain([]));
throws(() => starknet.hashChain('123'));
deepStrictEqual(
starknet.hashChain([1, 2]),
'0x5bb9440e27889a364bcb678b1f679ecd1347acdedcbf36e83494f857cc58026'
);
});
should('Pedersen hash, issue #2', () => {
// Verified with starnet.js
deepStrictEqual(
starknet.computeHashOnElements(issue2),
'0x22064462ea33a6ce5272a295e0f551c5da3834f80d8444e7a4df68190b1bc42'
);
deepStrictEqual(
starknet.computeHashOnElements([]),
'0x49ee3eba8c1600700ee1b87eb599f16716b0b1022947733551fde4050ca6804'
);
deepStrictEqual(
starknet.computeHashOnElements([1]),
'0x78d74f61aeaa8286418fd34b3a12a610445eba11d00ecc82ecac2542d55f7a4'
);
});
should('Seed derivation (example)', () => {
const layer = 'starkex';
const application = 'starkdeployement';
const mnemonic =
'range mountain blast problem vibrant void vivid doctor cluster enough melody ' +
'salt layer language laptop boat major space monkey unit glimpse pause change vibrant';
const ethAddress = '0xa4864d977b944315389d1765ffa7e66F74ee8cd7';
const hdKey = bip32.HDKey.fromMasterSeed(bip39.mnemonicToSeedSync(mnemonic)).derive(
starknet.getAccountPath(layer, application, ethAddress, 0)
);
deepStrictEqual(
starknet.grindKey(hdKey.privateKey),
'6cf0a8bf113352eb863157a45c5e5567abb34f8d32cddafd2c22aa803f4892c'
);
});
should('Compressed keys', () => {
const G = starknet.ProjectivePoint.BASE;
const half = starknet.CURVE.n / 2n;
const last = starknet.CURVE.n;
const vectors = [
1n,
2n,
3n,
4n,
5n,
half - 5n,
half - 4n,
half - 3n,
half - 2n,
half - 1n,
half,
half + 1n,
half + 2n,
half + 3n,
half + 4n,
half + 5n,
last - 5n,
last - 4n,
last - 3n,
last - 2n,
last - 1n,
].map((i) => G.multiply(i));
const fixPoint = (pt) => pt.toAffine();
for (const v of vectors) {
const uncompressed = v.toHex();
const compressed = v.toHex(true);
const exp = fixPoint(v);
deepStrictEqual(fixPoint(starknet.ProjectivePoint.fromHex(uncompressed)), exp);
deepStrictEqual(fixPoint(starknet.ProjectivePoint.fromHex(compressed)), exp);
deepStrictEqual(starknet.ProjectivePoint.fromHex(compressed).toHex(), uncompressed);
}
});
});
// ESM is broken.
import url from 'url';
if (import.meta.url === url.pathToFileURL(process.argv[1]).href) {
should.run();
}