Compare commits
80 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1c6aa07ff7 | ||
|
|
e110237298 | ||
|
|
45393db807 | ||
|
|
acc3a9dc4d | ||
|
|
9295b0dbae | ||
|
|
5784ef23f6 | ||
|
|
ef55efe842 | ||
|
|
1cfd6a76ca | ||
|
|
89f81b2204 | ||
|
|
d77ac16f51 | ||
|
|
fe68da61f6 | ||
|
|
32c0841bed | ||
|
|
49a659b248 | ||
|
|
9d0a2e25dc | ||
|
|
7c461af2b2 | ||
|
|
4a8f447c8d | ||
|
|
4b2d31ce7f | ||
|
|
16115f27a6 | ||
|
|
0e0d0f530d | ||
|
|
fa5105aef2 | ||
|
|
11f1626ecc | ||
|
|
53ff287bf7 | ||
|
|
214c9aa553 | ||
|
|
ec2c3e1248 | ||
|
|
e64a9d654c | ||
|
|
088edd0fbb | ||
|
|
3e90930e9d | ||
|
|
b8b2e91f74 | ||
|
|
9ee694ae23 | ||
|
|
6bc4b35cf4 | ||
|
|
0163b63532 | ||
|
|
7e825520f1 | ||
|
|
d739297b2c | ||
|
|
285aa6375d | ||
|
|
8c77331ef2 | ||
|
|
669641e0a3 | ||
|
|
68dd57ed31 | ||
|
|
a9fdd6df9f | ||
|
|
d485d8b0e6 | ||
|
|
0fdd763dc7 | ||
|
|
586e2ad5fb | ||
|
|
ed81707bdc | ||
|
|
6d56b2d78e | ||
|
|
8397241a8f | ||
|
|
001d0cc24a | ||
|
|
ce9d165657 | ||
|
|
2902b0299a | ||
|
|
e1cb8549e8 | ||
|
|
26ebb5dcce | ||
|
|
8b2863aeac | ||
|
|
b1f50d9364 | ||
|
|
b81d74d3cb | ||
|
|
d5fe537159 | ||
|
|
cde1d5c488 | ||
|
|
3486bbf6b8 | ||
|
|
0d7a8296c5 | ||
|
|
0f1e7a5a43 | ||
|
|
3da48cf899 | ||
|
|
4ec46dd65d | ||
|
|
7073f63c6b | ||
|
|
80966cbd03 | ||
|
|
98ea15dca4 | ||
|
|
e1910e85ea | ||
|
|
4d311d7294 | ||
|
|
c36d90cae6 | ||
|
|
af5aa8424f | ||
|
|
67b99652fc | ||
|
|
c8d292976b | ||
|
|
daffaa2339 | ||
|
|
a462fc5779 | ||
|
|
fe3491c5aa | ||
|
|
c0877ba69a | ||
|
|
8e449cc78c | ||
|
|
1b6071cabd | ||
|
|
debb9d9709 | ||
|
|
d2c6459756 | ||
|
|
47533b6336 | ||
|
|
00b73b68d3 | ||
|
|
cef4b52d12 | ||
|
|
47ce547dcf |
14
.gitignore
vendored
14
.gitignore
vendored
@@ -1,7 +1,13 @@
|
||||
build/
|
||||
node_modules/
|
||||
coverage/
|
||||
/lib/**/*.js
|
||||
/lib/**/*.ts
|
||||
/lib/**/*.d.ts.map
|
||||
/curve-definitions/lib
|
||||
/*.js
|
||||
/*.ts
|
||||
/*.js.map
|
||||
/*.d.ts.map
|
||||
/esm/*.js
|
||||
/esm/*.ts
|
||||
/esm/*.js.map
|
||||
/esm/*.d.ts.map
|
||||
/esm/abstract
|
||||
/abstract/
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
|
||||
| Version | Supported |
|
||||
| ------- | ------------------ |
|
||||
| >=0.5.0 | :white_check_mark: |
|
||||
| <0.5.0 | :x: |
|
||||
| >=1.0.0 | :white_check_mark: |
|
||||
| <1.0.0 | :x: |
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
|
||||
BIN
audit/2023-01-trailofbits-audit-curves.pdf
Normal file
BIN
audit/2023-01-trailofbits-audit-curves.pdf
Normal file
Binary file not shown.
11
audit/README.md
Normal file
11
audit/README.md
Normal file
@@ -0,0 +1,11 @@
|
||||
# Audit
|
||||
|
||||
The library has been audited during Jan-Feb 2023 by an independent security firm [Trail of Bits](https://www.trailofbits.com):
|
||||
[PDF](https://github.com/trailofbits/publications/blob/master/reviews/2023-01-ryanshea-noblecurveslibrary-securityreview.pdf).
|
||||
The audit has been funded by Ryan Shea. Audit scope was abstract modules `curve`, `hash-to-curve`, `modular`, `poseidon`, `utils`, `weierstrass`, and top-level modules `_shortw_utils` and `secp256k1`. See [changes since audit](https://github.com/paulmillr/noble-curves/compare/0.7.3..main).
|
||||
|
||||
File in the directory was saved from
|
||||
[github.com/trailofbits/publications](https://github.com/trailofbits/publications).
|
||||
Check out their repo and verify checksums to ensure the PDF in this directory has not been altered.
|
||||
|
||||
See information about fuzzing in root [README](../README.md).
|
||||
@@ -1,6 +1,6 @@
|
||||
import { readFileSync } from 'fs';
|
||||
import { mark, run } from 'micro-bmark';
|
||||
import { bls12_381 as bls } from '../lib/bls12-381.js';
|
||||
import { bls12_381 as bls } from '../bls12-381.js';
|
||||
|
||||
const G2_VECTORS = readFileSync('../test/bls12-381/bls12-381-g2-test-vectors.txt', 'utf-8')
|
||||
.trim()
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { run, mark, utils } from 'micro-bmark';
|
||||
import { generateData } from './_shared.js';
|
||||
import { P256 } from '../lib/p256.js';
|
||||
import { P384 } from '../lib/p384.js';
|
||||
import { P521 } from '../lib/p521.js';
|
||||
import { ed25519 } from '../lib/ed25519.js';
|
||||
import { ed448 } from '../lib/ed448.js';
|
||||
import { P256 } from '../p256.js';
|
||||
import { P384 } from '../p384.js';
|
||||
import { P521 } from '../p521.js';
|
||||
import { ed25519 } from '../ed25519.js';
|
||||
import { ed448 } from '../ed448.js';
|
||||
|
||||
run(async () => {
|
||||
const RAM = false
|
||||
|
||||
19
benchmark/ecdh.js
Normal file
19
benchmark/ecdh.js
Normal file
@@ -0,0 +1,19 @@
|
||||
import { run, mark, compare, utils } from 'micro-bmark';
|
||||
import { generateData } from './_shared.js';
|
||||
import { secp256k1 } from '../secp256k1.js';
|
||||
import { P256 } from '../p256.js';
|
||||
import { P384 } from '../p384.js';
|
||||
import { P521 } from '../p521.js';
|
||||
import { x25519 } from '../ed25519.js';
|
||||
import { x448 } from '../ed448.js';
|
||||
|
||||
run(async () => {
|
||||
const curves = { x25519, secp256k1, P256, P384, P521, x448 };
|
||||
const fns = {};
|
||||
for (let [k, c] of Object.entries(curves)) {
|
||||
const pubB = c.getPublicKey(c.utils.randomPrivateKey());
|
||||
const privA = c.utils.randomPrivateKey();
|
||||
fns[k] = () => c.getSharedSecret(privA, pubB);
|
||||
}
|
||||
await compare('ecdh', 1000, fns);
|
||||
});
|
||||
29
benchmark/hash-to-curve.js
Normal file
29
benchmark/hash-to-curve.js
Normal file
@@ -0,0 +1,29 @@
|
||||
import { run, mark, utils } from 'micro-bmark';
|
||||
import { hash_to_field } from '../abstract/hash-to-curve.js';
|
||||
import { hashToPrivateScalar } from '../abstract/modular.js';
|
||||
import { randomBytes } from '@noble/hashes/utils';
|
||||
import { sha256 } from '@noble/hashes/sha256';
|
||||
// import { generateData } from './_shared.js';
|
||||
import { hashToCurve as secp256k1 } from '../secp256k1.js';
|
||||
import { hashToCurve as P256 } from '../p256.js';
|
||||
import { hashToCurve as P384 } from '../p384.js';
|
||||
import { hashToCurve as P521 } from '../p521.js';
|
||||
import { hashToCurve as ed25519 } from '../ed25519.js';
|
||||
import { hashToCurve as ed448 } from '../ed448.js';
|
||||
import { utf8ToBytes } from '../abstract/utils.js';
|
||||
|
||||
const N = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141n;
|
||||
run(async () => {
|
||||
const rand = randomBytes(40);
|
||||
await mark('hashToPrivateScalar', 1000000, () => hashToPrivateScalar(rand, N));
|
||||
// - p, the characteristic of F
|
||||
// - m, the extension degree of F, m >= 1
|
||||
// - L = ceil((ceil(log2(p)) + k) / 8), where k is the security of suite (e.g. 128)
|
||||
await mark('hash_to_field', 1000000, () =>
|
||||
hash_to_field(rand, 1, { DST: 'secp256k1', hash: sha256, p: N, m: 1, k: 128 })
|
||||
);
|
||||
const msg = utf8ToBytes('message');
|
||||
for (let [title, fn] of Object.entries({ secp256k1, P256, P384, P521, ed25519, ed448 })) {
|
||||
await mark(`hashToCurve ${title}`, 1000, () => fn(msg));
|
||||
}
|
||||
});
|
||||
13
benchmark/modular.js
Normal file
13
benchmark/modular.js
Normal file
@@ -0,0 +1,13 @@
|
||||
import { run, mark } from 'micro-bmark';
|
||||
import { secp256k1 } from '../secp256k1.js';
|
||||
import { Fp } from '../abstract/modular.js';
|
||||
|
||||
run(async () => {
|
||||
console.log(`\x1b[36mmodular, secp256k1 field\x1b[0m`);
|
||||
const { Fp: secpFp } = secp256k1.CURVE;
|
||||
await mark('invert a', 300000, () => secpFp.inv(2n ** 232n - 5910n));
|
||||
await mark('invert b', 300000, () => secpFp.inv(2n ** 231n - 5910n));
|
||||
await mark('sqrt p = 3 mod 4', 15000, () => secpFp.sqrt(2n ** 231n - 5910n));
|
||||
const FpStark = Fp(BigInt('0x800000000000011000000000000000000000000000000000000000000000001'));
|
||||
await mark('sqrt tonneli-shanks', 500, () => FpStark.sqrt(2n ** 231n - 5909n))
|
||||
});
|
||||
@@ -16,7 +16,6 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@noble/hashes": "^1.1.5",
|
||||
"@starkware-industries/starkware-crypto-utils": "^0.0.2",
|
||||
"elliptic": "^6.5.4"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { run, mark, utils } from 'micro-bmark';
|
||||
import { secp256k1, schnorr } from '../lib/secp256k1.js';
|
||||
import { secp256k1, schnorr } from '../secp256k1.js';
|
||||
import { generateData } from './_shared.js';
|
||||
|
||||
run(async () => {
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
import { run, mark, compare, utils } from 'micro-bmark';
|
||||
import * as starkwareCrypto from '@starkware-industries/starkware-crypto-utils';
|
||||
import * as stark from '../lib/stark.js';
|
||||
|
||||
run(async () => {
|
||||
const RAM = false;
|
||||
if (RAM) utils.logMem();
|
||||
console.log(`\x1b[36mstark\x1b[0m`);
|
||||
await mark('init', 1, () => stark.utils.precompute(8));
|
||||
const d = (() => {
|
||||
const priv = '2dccce1da22003777062ee0870e9881b460a8b7eca276870f57c601f182136c';
|
||||
const msg = 'c465dd6b1bbffdb05442eb17f5ca38ad1aa78a6f56bf4415bdee219114a47';
|
||||
const pub = stark.getPublicKey(priv);
|
||||
const sig = stark.sign(msg, priv);
|
||||
|
||||
const privateKey = '2dccce1da22003777062ee0870e9881b460a8b7eca276870f57c601f182136c';
|
||||
const msgHash = 'c465dd6b1bbffdb05442eb17f5ca38ad1aa78a6f56bf4415bdee219114a47';
|
||||
const keyPair = starkwareCrypto.default.ec.keyFromPrivate(privateKey, 'hex');
|
||||
const publicKeyStark = starkwareCrypto.default.ec.keyFromPublic(
|
||||
keyPair.getPublic(true, 'hex'),
|
||||
'hex'
|
||||
);
|
||||
return { priv, sig, msg, pub, publicKeyStark, msgHash, keyPair };
|
||||
})();
|
||||
await compare('pedersen', 500, {
|
||||
old: () => {
|
||||
return starkwareCrypto.default.pedersen([
|
||||
'3d937c035c878245caf64531a5756109c53068da139362728feb561405371cb',
|
||||
'208a0a10250e382e1e4bbe2880906c2791bf6275695e02fbbc6aeff9cd8b31a',
|
||||
]);
|
||||
},
|
||||
noble: () => {
|
||||
return stark.pedersen(
|
||||
'3d937c035c878245caf64531a5756109c53068da139362728feb561405371cb',
|
||||
'208a0a10250e382e1e4bbe2880906c2791bf6275695e02fbbc6aeff9cd8b31a'
|
||||
);
|
||||
},
|
||||
});
|
||||
await mark('poseidon', 10000, () => stark.poseidonHash(
|
||||
0x3d937c035c878245caf64531a5756109c53068da139362728feb561405371cbn,
|
||||
0x208a0a10250e382e1e4bbe2880906c2791bf6275695e02fbbc6aeff9cd8b31an
|
||||
));
|
||||
await compare('verify', 500, {
|
||||
old: () => {
|
||||
return starkwareCrypto.default.verify(
|
||||
d.publicKeyStark,
|
||||
d.msgHash,
|
||||
starkwareCrypto.default.sign(d.keyPair, d.msgHash)
|
||||
);
|
||||
},
|
||||
noble: () => {
|
||||
return stark.verify(stark.sign(d.msg, d.priv), d.msg, d.pub);
|
||||
},
|
||||
});
|
||||
if (RAM) utils.logMem();
|
||||
});
|
||||
@@ -2,6 +2,6 @@
|
||||
"type": "module",
|
||||
"browser": {
|
||||
"crypto": false,
|
||||
"./crypto": "./esm/cryptoBrowser.js"
|
||||
"./crypto": "./esm/crypto.js"
|
||||
}
|
||||
}
|
||||
202
package-lock.json
generated
Normal file
202
package-lock.json
generated
Normal file
@@ -0,0 +1,202 @@
|
||||
{
|
||||
"name": "@noble/curves",
|
||||
"version": "0.8.3",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@noble/curves",
|
||||
"version": "0.8.3",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@noble/hashes": "1.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@scure/bip32": "~1.1.5",
|
||||
"@scure/bip39": "~1.1.1",
|
||||
"@types/node": "18.11.18",
|
||||
"fast-check": "3.0.0",
|
||||
"micro-bmark": "0.3.1",
|
||||
"micro-should": "0.4.0",
|
||||
"prettier": "2.8.4",
|
||||
"typescript": "5.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@noble/hashes": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.0.tgz",
|
||||
"integrity": "sha512-ilHEACi9DwqJB0pw7kv+Apvh50jiiSyR/cQ3y4W7lOR5mhvn/50FLUfsnfJz0BDZtl/RR16kXvptiv6q1msYZg==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
]
|
||||
},
|
||||
"node_modules/@noble/secp256k1": {
|
||||
"version": "1.7.1",
|
||||
"resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-1.7.1.tgz",
|
||||
"integrity": "sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
]
|
||||
},
|
||||
"node_modules/@scure/base": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.1.tgz",
|
||||
"integrity": "sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
]
|
||||
},
|
||||
"node_modules/@scure/bip32": {
|
||||
"version": "1.1.5",
|
||||
"resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.1.5.tgz",
|
||||
"integrity": "sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"@noble/hashes": "~1.2.0",
|
||||
"@noble/secp256k1": "~1.7.0",
|
||||
"@scure/base": "~1.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@scure/bip32/node_modules/@noble/hashes": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.2.0.tgz",
|
||||
"integrity": "sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
]
|
||||
},
|
||||
"node_modules/@scure/bip39": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.1.tgz",
|
||||
"integrity": "sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"@noble/hashes": "~1.2.0",
|
||||
"@scure/base": "~1.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@scure/bip39/node_modules/@noble/hashes": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.2.0.tgz",
|
||||
"integrity": "sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
]
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "18.11.18",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.18.tgz",
|
||||
"integrity": "sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/fast-check": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fast-check/-/fast-check-3.0.0.tgz",
|
||||
"integrity": "sha512-uujtrFJEQQqnIMO52ARwzPcuV4omiL1OJBUBLE9WnNFeu0A97sREXDOmCIHY+Z6KLVcemUf09rWr0q0Xy/Y/Ew==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"pure-rand": "^5.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/fast-check"
|
||||
}
|
||||
},
|
||||
"node_modules/micro-bmark": {
|
||||
"version": "0.3.1",
|
||||
"resolved": "https://registry.npmjs.org/micro-bmark/-/micro-bmark-0.3.1.tgz",
|
||||
"integrity": "sha512-bNaKObD4yPAAPrpEqp5jO6LJ2sEFgLoFSmRjEY809mJ62+2AehI/K3+RlVpN3Oo92RHpgC2RQhj6b1Tb4dmo+w==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/micro-should": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/micro-should/-/micro-should-0.4.0.tgz",
|
||||
"integrity": "sha512-Vclj8yrngSYc9Y3dL2C+AdUlTkyx/syWc4R7LYfk4h7+icfF0DoUBGjjUIaEDzZA19RzoI+Hg8rW9IRoNGP0tQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/prettier": {
|
||||
"version": "2.8.4",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.4.tgz",
|
||||
"integrity": "sha512-vIS4Rlc2FNh0BySk3Wkd6xmwxB0FpOndW5fisM5H8hsZSxU2VWVB5CWIkIjWvrHjIhxk2g3bfMKM87zNTrZddw==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"prettier": "bin-prettier.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.13.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/prettier/prettier?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/pure-rand": {
|
||||
"version": "5.0.5",
|
||||
"resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-5.0.5.tgz",
|
||||
"integrity": "sha512-BwQpbqxSCBJVpamI6ydzcKqyFmnd5msMWUGvzXLm1aXvusbbgkbOto/EUPM00hjveJEaJtdbhUjKSzWRhQVkaw==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://github.com/sponsors/dubzzz"
|
||||
},
|
||||
{
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/fast-check"
|
||||
}
|
||||
]
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "5.0.2",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.2.tgz",
|
||||
"integrity": "sha512-wVORMBGO/FAs/++blGNeAVdbNKtIh1rbBL2EyQ1+J9lClJ93KiiKe8PmFIVdXhHcyv44SL9oglmfeSsndo0jRw==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.20"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
177
package.json
177
package.json
@@ -1,14 +1,21 @@
|
||||
{
|
||||
"name": "@noble/curves",
|
||||
"version": "0.6.2",
|
||||
"version": "0.8.3",
|
||||
"description": "Minimal, auditable JS implementation of elliptic curve cryptography",
|
||||
"files": [
|
||||
"lib"
|
||||
"abstract",
|
||||
"esm",
|
||||
"src",
|
||||
"*.js",
|
||||
"*.js.map",
|
||||
"*.d.ts",
|
||||
"*.d.ts.map"
|
||||
],
|
||||
"scripts": {
|
||||
"bench": "cd benchmark; node secp256k1.js; node curves.js; node stark.js; node bls.js",
|
||||
"bench": "cd benchmark; node secp256k1.js; node curves.js; node ecdh.js; node hash-to-curve.js; node modular.js; node bls.js",
|
||||
"build": "tsc && tsc -p tsconfig.esm.json",
|
||||
"build:release": "rollup -c rollup.config.js",
|
||||
"build:clean": "rm *.{js,d.ts,d.ts.map,js.map} esm/*.{js,d.ts,d.ts.map,js.map} 2> /dev/null",
|
||||
"lint": "prettier --check 'src/**/*.{js,ts}' 'test/*.js'",
|
||||
"format": "prettier --write 'src/**/*.{js,ts}' 'test/*.js'",
|
||||
"test": "node test/index.test.js"
|
||||
@@ -21,147 +28,129 @@
|
||||
},
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@noble/hashes": "1.1.5"
|
||||
"@noble/hashes": "1.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-node-resolve": "13.3.0",
|
||||
"@scure/base": "~1.1.1",
|
||||
"@scure/bip32": "~1.1.1",
|
||||
"@scure/bip39": "~1.1.0",
|
||||
"@types/node": "18.11.3",
|
||||
"@scure/bip32": "~1.1.5",
|
||||
"@scure/bip39": "~1.1.1",
|
||||
"@types/node": "18.11.18",
|
||||
"fast-check": "3.0.0",
|
||||
"micro-bmark": "0.3.0",
|
||||
"micro-bmark": "0.3.1",
|
||||
"micro-should": "0.4.0",
|
||||
"prettier": "2.8.3",
|
||||
"rollup": "2.75.5",
|
||||
"typescript": "4.7.3"
|
||||
"prettier": "2.8.4",
|
||||
"typescript": "5.0.2"
|
||||
},
|
||||
"main": "index.js",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./lib/index.d.ts",
|
||||
"import": "./lib/esm/index.js",
|
||||
"default": "./lib/index.js"
|
||||
"types": "./index.d.ts",
|
||||
"import": "./esm/index.js",
|
||||
"default": "./index.js"
|
||||
},
|
||||
"./abstract/edwards": {
|
||||
"types": "./lib/abstract/edwards.d.ts",
|
||||
"import": "./lib/esm/abstract/edwards.js",
|
||||
"default": "./lib/abstract/edwards.js"
|
||||
"types": "./abstract/edwards.d.ts",
|
||||
"import": "./esm/abstract/edwards.js",
|
||||
"default": "./abstract/edwards.js"
|
||||
},
|
||||
"./abstract/modular": {
|
||||
"types": "./lib/abstract/modular.d.ts",
|
||||
"import": "./lib/esm/abstract/modular.js",
|
||||
"default": "./lib/abstract/modular.js"
|
||||
"types": "./abstract/modular.d.ts",
|
||||
"import": "./esm/abstract/modular.js",
|
||||
"default": "./abstract/modular.js"
|
||||
},
|
||||
"./abstract/montgomery": {
|
||||
"types": "./lib/abstract/montgomery.d.ts",
|
||||
"import": "./lib/esm/abstract/montgomery.js",
|
||||
"default": "./lib/abstract/montgomery.js"
|
||||
"types": "./abstract/montgomery.d.ts",
|
||||
"import": "./esm/abstract/montgomery.js",
|
||||
"default": "./abstract/montgomery.js"
|
||||
},
|
||||
"./abstract/weierstrass": {
|
||||
"types": "./lib/abstract/weierstrass.d.ts",
|
||||
"import": "./lib/esm/abstract/weierstrass.js",
|
||||
"default": "./lib/abstract/weierstrass.js"
|
||||
"types": "./abstract/weierstrass.d.ts",
|
||||
"import": "./esm/abstract/weierstrass.js",
|
||||
"default": "./abstract/weierstrass.js"
|
||||
},
|
||||
"./abstract/bls": {
|
||||
"types": "./lib/abstract/bls.d.ts",
|
||||
"import": "./lib/esm/abstract/bls.js",
|
||||
"default": "./lib/abstract/bls.js"
|
||||
"types": "./abstract/bls.d.ts",
|
||||
"import": "./esm/abstract/bls.js",
|
||||
"default": "./abstract/bls.js"
|
||||
},
|
||||
"./abstract/hash-to-curve": {
|
||||
"types": "./lib/abstract/hash-to-curve.d.ts",
|
||||
"import": "./lib/esm/abstract/hash-to-curve.js",
|
||||
"default": "./lib/abstract/hash-to-curve.js"
|
||||
"types": "./abstract/hash-to-curve.d.ts",
|
||||
"import": "./esm/abstract/hash-to-curve.js",
|
||||
"default": "./abstract/hash-to-curve.js"
|
||||
},
|
||||
"./abstract/curve": {
|
||||
"types": "./lib/abstract/curve.d.ts",
|
||||
"import": "./lib/esm/abstract/curve.js",
|
||||
"default": "./lib/abstract/curve.js"
|
||||
"types": "./abstract/curve.d.ts",
|
||||
"import": "./esm/abstract/curve.js",
|
||||
"default": "./abstract/curve.js"
|
||||
},
|
||||
"./abstract/utils": {
|
||||
"types": "./lib/abstract/utils.d.ts",
|
||||
"import": "./lib/esm/abstract/utils.js",
|
||||
"default": "./lib/abstract/utils.js"
|
||||
"types": "./abstract/utils.d.ts",
|
||||
"import": "./esm/abstract/utils.js",
|
||||
"default": "./abstract/utils.js"
|
||||
},
|
||||
"./abstract/poseidon": {
|
||||
"types": "./lib/abstract/poseidon.d.ts",
|
||||
"import": "./lib/esm/abstract/poseidon.js",
|
||||
"default": "./lib/abstract/poseidon.js"
|
||||
"types": "./abstract/poseidon.d.ts",
|
||||
"import": "./esm/abstract/poseidon.js",
|
||||
"default": "./abstract/poseidon.js"
|
||||
},
|
||||
"./_shortw_utils": {
|
||||
"types": "./lib/_shortw_utils.d.ts",
|
||||
"import": "./lib/esm/_shortw_utils.js",
|
||||
"default": "./lib/_shortw_utils.js"
|
||||
"types": "./_shortw_utils.d.ts",
|
||||
"import": "./esm/_shortw_utils.js",
|
||||
"default": "./_shortw_utils.js"
|
||||
},
|
||||
"./bls12-381": {
|
||||
"types": "./lib/bls12-381.d.ts",
|
||||
"import": "./lib/esm/bls12-381.js",
|
||||
"default": "./lib/bls12-381.js"
|
||||
"types": "./bls12-381.d.ts",
|
||||
"import": "./esm/bls12-381.js",
|
||||
"default": "./bls12-381.js"
|
||||
},
|
||||
"./bn": {
|
||||
"types": "./lib/bn.d.ts",
|
||||
"import": "./lib/esm/bn.js",
|
||||
"default": "./lib/bn.js"
|
||||
"types": "./bn.d.ts",
|
||||
"import": "./esm/bn.js",
|
||||
"default": "./bn.js"
|
||||
},
|
||||
"./ed25519": {
|
||||
"types": "./lib/ed25519.d.ts",
|
||||
"import": "./lib/esm/ed25519.js",
|
||||
"default": "./lib/ed25519.js"
|
||||
"types": "./ed25519.d.ts",
|
||||
"import": "./esm/ed25519.js",
|
||||
"default": "./ed25519.js"
|
||||
},
|
||||
"./ed448": {
|
||||
"types": "./lib/ed448.d.ts",
|
||||
"import": "./lib/esm/ed448.js",
|
||||
"default": "./lib/ed448.js"
|
||||
"types": "./ed448.d.ts",
|
||||
"import": "./esm/ed448.js",
|
||||
"default": "./ed448.js"
|
||||
},
|
||||
"./index": {
|
||||
"types": "./lib/index.d.ts",
|
||||
"import": "./lib/esm/index.js",
|
||||
"default": "./lib/index.js"
|
||||
"types": "./index.d.ts",
|
||||
"import": "./esm/index.js",
|
||||
"default": "./index.js"
|
||||
},
|
||||
"./jubjub": {
|
||||
"types": "./lib/jubjub.d.ts",
|
||||
"import": "./lib/esm/jubjub.js",
|
||||
"default": "./lib/jubjub.js"
|
||||
},
|
||||
"./p192": {
|
||||
"types": "./lib/p192.d.ts",
|
||||
"import": "./lib/esm/p192.js",
|
||||
"default": "./lib/p192.js"
|
||||
},
|
||||
"./p224": {
|
||||
"types": "./lib/p224.d.ts",
|
||||
"import": "./lib/esm/p224.js",
|
||||
"default": "./lib/p224.js"
|
||||
"types": "./jubjub.d.ts",
|
||||
"import": "./esm/jubjub.js",
|
||||
"default": "./jubjub.js"
|
||||
},
|
||||
"./p256": {
|
||||
"types": "./lib/p256.d.ts",
|
||||
"import": "./lib/esm/p256.js",
|
||||
"default": "./lib/p256.js"
|
||||
"types": "./p256.d.ts",
|
||||
"import": "./esm/p256.js",
|
||||
"default": "./p256.js"
|
||||
},
|
||||
"./p384": {
|
||||
"types": "./lib/p384.d.ts",
|
||||
"import": "./lib/esm/p384.js",
|
||||
"default": "./lib/p384.js"
|
||||
"types": "./p384.d.ts",
|
||||
"import": "./esm/p384.js",
|
||||
"default": "./p384.js"
|
||||
},
|
||||
"./p521": {
|
||||
"types": "./lib/p521.d.ts",
|
||||
"import": "./lib/esm/p521.js",
|
||||
"default": "./lib/p521.js"
|
||||
"types": "./p521.d.ts",
|
||||
"import": "./esm/p521.js",
|
||||
"default": "./p521.js"
|
||||
},
|
||||
"./pasta": {
|
||||
"types": "./lib/pasta.d.ts",
|
||||
"import": "./lib/esm/pasta.js",
|
||||
"default": "./lib/pasta.js"
|
||||
"types": "./pasta.d.ts",
|
||||
"import": "./esm/pasta.js",
|
||||
"default": "./pasta.js"
|
||||
},
|
||||
"./secp256k1": {
|
||||
"types": "./lib/secp256k1.d.ts",
|
||||
"import": "./lib/esm/secp256k1.js",
|
||||
"default": "./lib/secp256k1.js"
|
||||
},
|
||||
"./stark": {
|
||||
"types": "./lib/stark.d.ts",
|
||||
"import": "./lib/esm/stark.js",
|
||||
"default": "./lib/stark.js"
|
||||
"types": "./secp256k1.d.ts",
|
||||
"import": "./esm/secp256k1.js",
|
||||
"default": "./secp256k1.js"
|
||||
}
|
||||
},
|
||||
"keywords": [
|
||||
|
||||
@@ -4,6 +4,7 @@ import { concatBytes, randomBytes } from '@noble/hashes/utils';
|
||||
import { weierstrass, CurveType } from './abstract/weierstrass.js';
|
||||
import { CHash } from './abstract/utils.js';
|
||||
|
||||
// connects noble-curves to noble-hashes
|
||||
export function getHash(hash: CHash) {
|
||||
return {
|
||||
hash,
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
*/
|
||||
import { AffinePoint } from './curve.js';
|
||||
import { Field, hashToPrivateScalar } from './modular.js';
|
||||
import { Hex, PrivKey, CHash, bitLen, bitGet, hexToBytes, bytesToHex } from './utils.js';
|
||||
import { Hex, PrivKey, CHash, bitLen, bitGet, ensureBytes } from './utils.js';
|
||||
import * as htf from './hash-to-curve.js';
|
||||
import {
|
||||
CurvePointsType,
|
||||
@@ -67,16 +67,11 @@ export type CurveFn<Fp, Fp2, Fp6, Fp12> = {
|
||||
Fp2: Field<Fp2>;
|
||||
Fp6: Field<Fp6>;
|
||||
Fp12: Field<Fp12>;
|
||||
G1: CurvePointsRes<Fp>;
|
||||
G2: CurvePointsRes<Fp2>;
|
||||
G1: CurvePointsRes<Fp> & ReturnType<typeof htf.createHasher<Fp>>;
|
||||
G2: CurvePointsRes<Fp2> & ReturnType<typeof htf.createHasher<Fp2>>;
|
||||
Signature: SignatureCoder<Fp2>;
|
||||
millerLoop: (ell: [Fp2, Fp2, Fp2][], g1: [Fp, Fp]) => Fp12;
|
||||
calcPairingPrecomputes: (p: AffinePoint<Fp2>) => [Fp2, Fp2, Fp2][];
|
||||
// prettier-ignore
|
||||
hashToCurve: {
|
||||
G1: ReturnType<(typeof htf.hashToCurve<Fp>)>,
|
||||
G2: ReturnType<(typeof htf.hashToCurve<Fp2>)>,
|
||||
},
|
||||
pairing: (P: ProjPointType<Fp>, Q: ProjPointType<Fp2>, withFinalExponent?: boolean) => Fp12;
|
||||
getPublicKey: (privateKey: PrivKey) => Uint8Array;
|
||||
sign: {
|
||||
@@ -102,16 +97,14 @@ export type CurveFn<Fp, Fp2, Fp6, Fp12> = {
|
||||
publicKeys: (Hex | ProjPointType<Fp>)[]
|
||||
) => boolean;
|
||||
utils: {
|
||||
stringToBytes: typeof htf.stringToBytes;
|
||||
hashToField: typeof htf.hash_to_field;
|
||||
expandMessageXMD: typeof htf.expand_message_xmd;
|
||||
randomPrivateKey: () => Uint8Array;
|
||||
};
|
||||
};
|
||||
|
||||
export function bls<Fp2, Fp6, Fp12>(
|
||||
CURVE: CurveType<Fp, Fp2, Fp6, Fp12>
|
||||
): CurveFn<Fp, Fp2, Fp6, Fp12> {
|
||||
// Fields looks pretty specific for curve, so for now we need to pass them with options
|
||||
// Fields looks pretty specific for curve, so for now we need to pass them with opts
|
||||
const { Fp, Fr, Fp2, Fp6, Fp12 } = CURVE;
|
||||
const BLS_X_LEN = bitLen(CURVE.x);
|
||||
const groupLen = 32; // TODO: calculate; hardcoded for now
|
||||
@@ -180,31 +173,20 @@ export function bls<Fp2, Fp6, Fp12>(
|
||||
}
|
||||
|
||||
const utils = {
|
||||
hexToBytes: hexToBytes,
|
||||
bytesToHex: bytesToHex,
|
||||
stringToBytes: htf.stringToBytes,
|
||||
// TODO: do we need to export it here?
|
||||
hashToField: (
|
||||
msg: Uint8Array,
|
||||
count: number,
|
||||
options: Partial<typeof CURVE.htfDefaults> = {}
|
||||
) => htf.hash_to_field(msg, count, { ...CURVE.htfDefaults, ...options }),
|
||||
expandMessageXMD: (msg: Uint8Array, DST: Uint8Array, lenInBytes: number, H = CURVE.hash) =>
|
||||
htf.expand_message_xmd(msg, DST, lenInBytes, H),
|
||||
hashToPrivateKey: (hash: Hex): Uint8Array => Fr.toBytes(hashToPrivateScalar(hash, CURVE.r)),
|
||||
randomBytes: (bytesLength: number = groupLen): Uint8Array => CURVE.randomBytes(bytesLength),
|
||||
randomPrivateKey: (): Uint8Array => utils.hashToPrivateKey(utils.randomBytes(groupLen + 8)),
|
||||
randomPrivateKey: (): Uint8Array => {
|
||||
return Fr.toBytes(hashToPrivateScalar(CURVE.randomBytes(groupLen + 8), CURVE.r));
|
||||
},
|
||||
};
|
||||
|
||||
// Point on G1 curve: (x, y)
|
||||
const G1 = weierstrassPoints({
|
||||
n: Fr.ORDER,
|
||||
...CURVE.G1,
|
||||
});
|
||||
const G1HashToCurve = htf.hashToCurve(G1.ProjectivePoint, CURVE.G1.mapToCurve, {
|
||||
...CURVE.htfDefaults,
|
||||
...CURVE.G1.htfDefaults,
|
||||
});
|
||||
const G1_ = weierstrassPoints({ n: Fr.ORDER, ...CURVE.G1 });
|
||||
const G1 = Object.assign(
|
||||
G1_,
|
||||
htf.createHasher(G1_.ProjectivePoint, CURVE.G1.mapToCurve, {
|
||||
...CURVE.htfDefaults,
|
||||
...CURVE.G1.htfDefaults,
|
||||
})
|
||||
);
|
||||
|
||||
// Sparse multiplication against precomputed coefficients
|
||||
// TODO: replace with weakmap?
|
||||
@@ -223,15 +205,14 @@ export function bls<Fp2, Fp6, Fp12>(
|
||||
// }
|
||||
|
||||
// Point on G2 curve (complex numbers): (x₁, x₂+i), (y₁, y₂+i)
|
||||
const G2 = weierstrassPoints({
|
||||
n: Fr.ORDER,
|
||||
...CURVE.G2,
|
||||
});
|
||||
const C = G2.ProjectivePoint as htf.H2CPointConstructor<Fp2>; // TODO: fix
|
||||
const G2HashToCurve = htf.hashToCurve(C, CURVE.G2.mapToCurve, {
|
||||
...CURVE.htfDefaults,
|
||||
...CURVE.G2.htfDefaults,
|
||||
});
|
||||
const G2_ = weierstrassPoints({ n: Fr.ORDER, ...CURVE.G2 });
|
||||
const G2 = Object.assign(
|
||||
G2_,
|
||||
htf.createHasher(G2_.ProjectivePoint as htf.H2CPointConstructor<Fp2>, CURVE.G2.mapToCurve, {
|
||||
...CURVE.htfDefaults,
|
||||
...CURVE.G2.htfDefaults,
|
||||
})
|
||||
);
|
||||
|
||||
const { Signature } = CURVE.G2;
|
||||
|
||||
@@ -260,7 +241,7 @@ export function bls<Fp2, Fp6, Fp12>(
|
||||
function normP2Hash(point: G2Hex, htfOpts?: htf.htfBasicOpts): G2 {
|
||||
return point instanceof G2.ProjectivePoint
|
||||
? point
|
||||
: (G2HashToCurve.hashToCurve(point, htfOpts) as G2);
|
||||
: (G2.hashToCurve(ensureBytes('point', point), htfOpts) as G2);
|
||||
}
|
||||
|
||||
// Multiplies generator by private key.
|
||||
@@ -276,7 +257,7 @@ export function bls<Fp2, Fp6, Fp12>(
|
||||
function sign(message: G2Hex, privateKey: PrivKey, htfOpts?: htf.htfBasicOpts): Uint8Array | G2 {
|
||||
const msgPoint = normP2Hash(message, htfOpts);
|
||||
msgPoint.assertValidity();
|
||||
const sigPoint = msgPoint.multiply(G1.normalizePrivateKey(privateKey));
|
||||
const sigPoint = msgPoint.multiply(G1.normPrivateKeyToScalar(privateKey));
|
||||
if (message instanceof G2.ProjectivePoint) return sigPoint;
|
||||
return Signature.encode(sigPoint);
|
||||
}
|
||||
@@ -383,7 +364,6 @@ export function bls<Fp2, Fp6, Fp12>(
|
||||
Signature,
|
||||
millerLoop,
|
||||
calcPairingPrecomputes,
|
||||
hashToCurve: { G1: G1HashToCurve, G2: G2HashToCurve },
|
||||
pairing,
|
||||
getPublicKey,
|
||||
sign,
|
||||
|
||||
@@ -25,8 +25,17 @@ export type GroupConstructor<T> = {
|
||||
};
|
||||
export type Mapper<T> = (i: T[]) => T[];
|
||||
|
||||
// Elliptic curve multiplication of Point by scalar. Complicated and fragile. Uses wNAF method.
|
||||
// Windowed method is 10% faster, but takes 2x longer to generate & consumes 2x memory.
|
||||
// Elliptic curve multiplication of Point by scalar. Fragile.
|
||||
// Scalars should always be less than curve order: this should be checked inside of a curve itself.
|
||||
// Creates precomputation tables for fast multiplication:
|
||||
// - private scalar is split by fixed size windows of W bits
|
||||
// - every window point is collected from window's table & added to accumulator
|
||||
// - since windows are different, same point inside tables won't be accessed more than once per calc
|
||||
// - each multiplication is 'Math.ceil(CURVE_ORDER / 𝑊) + 1' point additions (fixed for any scalar)
|
||||
// - +1 window is neccessary for wNAF
|
||||
// - wNAF reduces table size: 2x less memory + 2x faster generation, but 10% slower multiplication
|
||||
// TODO: Research returning 2d JS array of windows, instead of a single window. This would allow
|
||||
// windows to be in different memory locations
|
||||
export function wNAF<T extends Group<T>>(c: GroupConstructor<T>, bits: number) {
|
||||
const constTimeNegate = (condition: boolean, item: T): T => {
|
||||
const neg = item.negate();
|
||||
@@ -54,8 +63,12 @@ export function wNAF<T extends Group<T>>(c: GroupConstructor<T>, bits: number) {
|
||||
/**
|
||||
* Creates a wNAF precomputation window. Used for caching.
|
||||
* Default window size is set by `utils.precompute()` and is equal to 8.
|
||||
* Which means we are caching 65536 points: 256 points for every bit from 0 to 256.
|
||||
* @returns 65K precomputed points, depending on W
|
||||
* Number of precomputed points depends on the curve size:
|
||||
* 2^(𝑊−1) * (Math.ceil(𝑛 / 𝑊) + 1), where:
|
||||
* - 𝑊 is the window size
|
||||
* - 𝑛 is the bitlength of the curve order.
|
||||
* For a 256-bit curve and window size 8, the number of precomputed points is 128 * 33 = 4224.
|
||||
* @returns precomputed point tables flattened to a single array
|
||||
*/
|
||||
precomputeWindow(elm: T, W: number): Group<T>[] {
|
||||
const { windows, windowSize } = opts(W);
|
||||
@@ -76,14 +89,14 @@ export function wNAF<T extends Group<T>>(c: GroupConstructor<T>, bits: number) {
|
||||
},
|
||||
|
||||
/**
|
||||
* Implements w-ary non-adjacent form for calculating ec multiplication.
|
||||
* Implements ec multiplication using precomputed tables and w-ary non-adjacent form.
|
||||
* @param W window size
|
||||
* @param affinePoint optional 2d point to save cached precompute windows on it.
|
||||
* @param n bits
|
||||
* @param precomputes precomputed tables
|
||||
* @param n scalar (we don't check here, but should be less than curve order)
|
||||
* @returns real and fake (for const-time) points
|
||||
*/
|
||||
wNAF(W: number, precomputes: T[], n: bigint): { p: T; f: T } {
|
||||
// TODO: maybe check that scalar is less than group order? wNAF will fail otherwise
|
||||
// TODO: maybe check that scalar is less than group order? wNAF behavious is undefined otherwise
|
||||
// But need to carefully remove other checks before wNAF. ORDER == bits here
|
||||
const { windows, windowSize } = opts(W);
|
||||
|
||||
|
||||
@@ -344,7 +344,7 @@ export function twistedEdwards(curveDef: CurveType): CurveFn {
|
||||
static fromHex(hex: Hex, strict = true): Point {
|
||||
const { d, a } = CURVE;
|
||||
const len = Fp.BYTES;
|
||||
hex = ensureBytes(hex, len); // copy hex to a new array
|
||||
hex = ensureBytes('pointHex', hex, len); // copy hex to a new array
|
||||
const normed = hex.slice(); // copy again, we'll manipulate it
|
||||
const lastByte = hex[len - 1]; // select last byte
|
||||
normed[len - 1] = lastByte & ~0x80; // clear last bit
|
||||
@@ -392,18 +392,14 @@ export function twistedEdwards(curveDef: CurveType): CurveFn {
|
||||
function modN_LE(hash: Uint8Array): bigint {
|
||||
return modN(ut.bytesToNumberLE(hash));
|
||||
}
|
||||
function isHex(item: Hex, err: string) {
|
||||
if (typeof item !== 'string' && !(item instanceof Uint8Array))
|
||||
throw new Error(`${err} must be hex string or Uint8Array`);
|
||||
}
|
||||
|
||||
/** Convenience method that creates public key and other stuff. RFC8032 5.1.5 */
|
||||
function getExtendedPublicKey(key: Hex) {
|
||||
isHex(key, 'private key');
|
||||
const len = nByteLength;
|
||||
key = ensureBytes('private key', key, len);
|
||||
// Hash private key with curve's hash function to produce uniformingly random input
|
||||
// Check byte lengths: ensure(64, h(ensure(32, key)))
|
||||
const hashed = ensureBytes(cHash(ensureBytes(key, len)), 2 * len);
|
||||
const hashed = ensureBytes('hashed private key', cHash(key), 2 * len);
|
||||
const head = adjustScalarBytes(hashed.slice(0, len)); // clear first half bits, produce FE
|
||||
const prefix = hashed.slice(len, 2 * len); // second half is called key prefix (5.1.6)
|
||||
const scalar = modN_LE(head); // The actual private scalar
|
||||
@@ -420,13 +416,12 @@ export function twistedEdwards(curveDef: CurveType): CurveFn {
|
||||
// int('LE', SHA512(dom2(F, C) || msgs)) mod N
|
||||
function hashDomainToScalar(context: Hex = new Uint8Array(), ...msgs: Uint8Array[]) {
|
||||
const msg = ut.concatBytes(...msgs);
|
||||
return modN_LE(cHash(domain(msg, ensureBytes(context), !!preHash)));
|
||||
return modN_LE(cHash(domain(msg, ensureBytes('context', context), !!preHash)));
|
||||
}
|
||||
|
||||
/** Signs message with privateKey. RFC8032 5.1.6 */
|
||||
function sign(msg: Hex, privKey: Hex, context?: Hex): Uint8Array {
|
||||
isHex(msg, 'message');
|
||||
msg = ensureBytes(msg);
|
||||
msg = ensureBytes('message', msg);
|
||||
if (preHash) msg = preHash(msg); // for ed25519ph etc.
|
||||
const { prefix, scalar, pointBytes } = getExtendedPublicKey(privKey);
|
||||
const r = hashDomainToScalar(context, prefix, msg); // r = dom2(F, C) || prefix || PH(M)
|
||||
@@ -435,15 +430,13 @@ export function twistedEdwards(curveDef: CurveType): CurveFn {
|
||||
const s = modN(r + k * scalar); // S = (r + k * s) mod L
|
||||
assertGE0(s); // 0 <= s < l
|
||||
const res = ut.concatBytes(R, ut.numberToBytesLE(s, Fp.BYTES));
|
||||
return ensureBytes(res, nByteLength * 2); // 64-byte signature
|
||||
return ensureBytes('result', res, nByteLength * 2); // 64-byte signature
|
||||
}
|
||||
|
||||
function verify(sig: Hex, msg: Hex, publicKey: Hex, context?: Hex): boolean {
|
||||
isHex(sig, 'sig');
|
||||
isHex(msg, 'message');
|
||||
const len = Fp.BYTES; // Verifies EdDSA signature against message and public key. RFC8032 5.1.7.
|
||||
sig = ensureBytes(sig, 2 * len); // An extended group equation is checked.
|
||||
msg = ensureBytes(msg); // ZIP215 compliant, which means not fully RFC8032 compliant.
|
||||
sig = ensureBytes('signature', sig, 2 * len); // An extended group equation is checked.
|
||||
msg = ensureBytes('message', msg); // ZIP215 compliant, which means not fully RFC8032 compliant.
|
||||
if (preHash) msg = preHash(msg); // for ed25519ph, etc
|
||||
const A = Point.fromHex(publicKey, false); // Check for s bounds, hex validity
|
||||
const R = Point.fromHex(sig.slice(0, len), false); // 0 <= R < 2^256: ZIP215 R can be >= P
|
||||
|
||||
@@ -1,66 +1,36 @@
|
||||
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||
import type { Group, GroupConstructor, AffinePoint } from './curve.js';
|
||||
import { mod, Field } from './modular.js';
|
||||
import { CHash, Hex, concatBytes, ensureBytes } from './utils.js';
|
||||
import { bytesToNumberBE, CHash, concatBytes, utf8ToBytes, validateObject } from './utils.js';
|
||||
|
||||
/**
|
||||
* * `DST` is a domain separation tag, defined in section 2.2.5
|
||||
* * `p` characteristic of F, where F is a finite field of characteristic p and order q = p^m
|
||||
* * `m` is extension degree (1 for prime fields)
|
||||
* * `k` is the target security target in bits (e.g. 128), from section 5.1
|
||||
* * `expand` is `xmd` (SHA2, SHA3, BLAKE) or `xof` (SHAKE, BLAKE-XOF)
|
||||
* * `hash` conforming to `utils.CHash` interface, with `outputLen` / `blockLen` props
|
||||
*/
|
||||
type UnicodeOrBytes = string | Uint8Array;
|
||||
export type Opts = {
|
||||
// DST: a domain separation tag
|
||||
// defined in section 2.2.5
|
||||
DST: string;
|
||||
encodeDST: string;
|
||||
// p: the characteristic of F
|
||||
// where F is a finite field of characteristic p and order q = p^m
|
||||
DST: UnicodeOrBytes;
|
||||
p: bigint;
|
||||
// m: the extension degree of F, m >= 1
|
||||
// where F is a finite field of characteristic p and order q = p^m
|
||||
m: number;
|
||||
// k: the target security level for the suite in bits
|
||||
// defined in section 5.1
|
||||
k: number;
|
||||
// option to use a message that has already been processed by
|
||||
// expand_message_xmd
|
||||
expand?: 'xmd' | 'xof';
|
||||
// Hash functions for: expand_message_xmd is appropriate for use with a
|
||||
// wide range of hash functions, including SHA-2, SHA-3, BLAKE2, and others.
|
||||
// BBS+ uses blake2: https://github.com/hyperledger/aries-framework-go/issues/2247
|
||||
// TODO: verify that hash is shake if expand==='xof' via types
|
||||
hash: CHash;
|
||||
};
|
||||
|
||||
export function validateOpts(opts: Opts) {
|
||||
if (typeof opts.DST !== 'string') throw new Error('Invalid htf/DST');
|
||||
if (typeof opts.p !== 'bigint') throw new Error('Invalid htf/p');
|
||||
if (typeof opts.m !== 'number') throw new Error('Invalid htf/m');
|
||||
if (typeof opts.k !== 'number') throw new Error('Invalid htf/k');
|
||||
if (opts.expand !== 'xmd' && opts.expand !== 'xof' && opts.expand !== undefined)
|
||||
throw new Error('Invalid htf/expand');
|
||||
if (typeof opts.hash !== 'function' || !Number.isSafeInteger(opts.hash.outputLen))
|
||||
throw new Error('Invalid htf/hash function');
|
||||
function validateDST(dst: UnicodeOrBytes): Uint8Array {
|
||||
if (dst instanceof Uint8Array) return dst;
|
||||
if (typeof dst === 'string') return utf8ToBytes(dst);
|
||||
throw new Error('DST must be Uint8Array or string');
|
||||
}
|
||||
|
||||
// Global symbols in both browsers and Node.js since v11
|
||||
// See https://github.com/microsoft/TypeScript/issues/31535
|
||||
declare const TextEncoder: any;
|
||||
declare const TextDecoder: any;
|
||||
// Octet Stream to Integer. "spec" implementation of os2ip is 2.5x slower vs bytesToNumberBE.
|
||||
const os2ip = bytesToNumberBE;
|
||||
|
||||
export function stringToBytes(str: string): Uint8Array {
|
||||
if (typeof str !== 'string') {
|
||||
throw new Error(`utf8ToBytes expected string, got ${typeof str}`);
|
||||
}
|
||||
return new TextEncoder().encode(str);
|
||||
}
|
||||
|
||||
// Octet Stream to Integer (bytesToNumberBE)
|
||||
function os2ip(bytes: Uint8Array): bigint {
|
||||
let result = 0n;
|
||||
for (let i = 0; i < bytes.length; i++) {
|
||||
result <<= 8n;
|
||||
result += BigInt(bytes[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Integer to Octet Stream
|
||||
// Integer to Octet Stream (numberToBytesBE)
|
||||
function i2osp(value: number, length: number): Uint8Array {
|
||||
if (value < 0 || value >= 1 << (8 * length)) {
|
||||
throw new Error(`bad I2OSP call: value=${value} length=${length}`);
|
||||
@@ -81,6 +51,13 @@ function strxor(a: Uint8Array, b: Uint8Array): Uint8Array {
|
||||
return arr;
|
||||
}
|
||||
|
||||
function isBytes(item: unknown): void {
|
||||
if (!(item instanceof Uint8Array)) throw new Error('Uint8Array expected');
|
||||
}
|
||||
function isNum(item: unknown): void {
|
||||
if (!Number.isSafeInteger(item)) throw new Error('number expected');
|
||||
}
|
||||
|
||||
// Produces a uniformly random byte string using a cryptographic hash function H that outputs b bits
|
||||
// https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-11#section-5.4.1
|
||||
export function expand_message_xmd(
|
||||
@@ -89,15 +66,17 @@ export function expand_message_xmd(
|
||||
lenInBytes: number,
|
||||
H: CHash
|
||||
): Uint8Array {
|
||||
isBytes(msg);
|
||||
isBytes(DST);
|
||||
isNum(lenInBytes);
|
||||
// https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-16#section-5.3.3
|
||||
if (DST.length > 255) DST = H(concatBytes(stringToBytes('H2C-OVERSIZE-DST-'), DST));
|
||||
const b_in_bytes = H.outputLen;
|
||||
const r_in_bytes = H.blockLen;
|
||||
if (DST.length > 255) DST = H(concatBytes(utf8ToBytes('H2C-OVERSIZE-DST-'), DST));
|
||||
const { outputLen: b_in_bytes, blockLen: r_in_bytes } = H;
|
||||
const ell = Math.ceil(lenInBytes / b_in_bytes);
|
||||
if (ell > 255) throw new Error('Invalid xmd length');
|
||||
const DST_prime = concatBytes(DST, i2osp(DST.length, 1));
|
||||
const Z_pad = i2osp(0, r_in_bytes);
|
||||
const l_i_b_str = i2osp(lenInBytes, 2);
|
||||
const l_i_b_str = i2osp(lenInBytes, 2); // len_in_bytes_str
|
||||
const b = new Array<Uint8Array>(ell);
|
||||
const b_0 = H(concatBytes(Z_pad, msg, l_i_b_str, i2osp(0, 1), DST_prime));
|
||||
b[0] = H(concatBytes(b_0, i2osp(1, 1), DST_prime));
|
||||
@@ -116,11 +95,14 @@ export function expand_message_xof(
|
||||
k: number,
|
||||
H: CHash
|
||||
): Uint8Array {
|
||||
isBytes(msg);
|
||||
isBytes(DST);
|
||||
isNum(lenInBytes);
|
||||
// https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-16#section-5.3.3
|
||||
// DST = H('H2C-OVERSIZE-DST-' || a_very_long_DST, Math.ceil((lenInBytes * k) / 8));
|
||||
if (DST.length > 255) {
|
||||
const dkLen = Math.ceil((2 * k) / 8);
|
||||
DST = H.create({ dkLen }).update(stringToBytes('H2C-OVERSIZE-DST-')).update(DST).digest();
|
||||
DST = H.create({ dkLen }).update(utf8ToBytes('H2C-OVERSIZE-DST-')).update(DST).digest();
|
||||
}
|
||||
if (lenInBytes > 65535 || DST.length > 255)
|
||||
throw new Error('expand_message_xof: invalid lenInBytes');
|
||||
@@ -140,29 +122,41 @@ export function expand_message_xof(
|
||||
* https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-11#section-5.3
|
||||
* @param msg a byte string containing the message to hash
|
||||
* @param count the number of elements of F to output
|
||||
* @param options `{DST: string, p: bigint, m: number, k: number, expand: 'xmd' | 'xof', hash: H}`
|
||||
* @param options `{DST: string, p: bigint, m: number, k: number, expand: 'xmd' | 'xof', hash: H}`, see above
|
||||
* @returns [u_0, ..., u_(count - 1)], a list of field elements.
|
||||
*/
|
||||
export function hash_to_field(msg: Uint8Array, count: number, options: Opts): bigint[][] {
|
||||
// if options is provided but incomplete, fill any missing fields with the
|
||||
// value in hftDefaults (ie hash to G2).
|
||||
const log2p = options.p.toString(2).length;
|
||||
const L = Math.ceil((log2p + options.k) / 8); // section 5.1 of ietf draft link above
|
||||
const len_in_bytes = count * options.m * L;
|
||||
const DST = stringToBytes(options.DST);
|
||||
let pseudo_random_bytes = msg;
|
||||
if (options.expand === 'xmd') {
|
||||
pseudo_random_bytes = expand_message_xmd(msg, DST, len_in_bytes, options.hash);
|
||||
} else if (options.expand === 'xof') {
|
||||
pseudo_random_bytes = expand_message_xof(msg, DST, len_in_bytes, options.k, options.hash);
|
||||
validateObject(options, {
|
||||
DST: 'string',
|
||||
p: 'bigint',
|
||||
m: 'isSafeInteger',
|
||||
k: 'isSafeInteger',
|
||||
hash: 'hash',
|
||||
});
|
||||
const { p, k, m, hash, expand, DST: _DST } = options;
|
||||
isBytes(msg);
|
||||
isNum(count);
|
||||
const DST = validateDST(_DST);
|
||||
const log2p = p.toString(2).length;
|
||||
const L = Math.ceil((log2p + k) / 8); // section 5.1 of ietf draft link above
|
||||
const len_in_bytes = count * m * L;
|
||||
let prb; // pseudo_random_bytes
|
||||
if (expand === 'xmd') {
|
||||
prb = expand_message_xmd(msg, DST, len_in_bytes, hash);
|
||||
} else if (expand === 'xof') {
|
||||
prb = expand_message_xof(msg, DST, len_in_bytes, k, hash);
|
||||
} else if (expand === undefined) {
|
||||
prb = msg;
|
||||
} else {
|
||||
throw new Error('expand must be "xmd", "xof" or undefined');
|
||||
}
|
||||
const u = new Array(count);
|
||||
for (let i = 0; i < count; i++) {
|
||||
const e = new Array(options.m);
|
||||
for (let j = 0; j < options.m; j++) {
|
||||
const elm_offset = L * (j + i * options.m);
|
||||
const tv = pseudo_random_bytes.subarray(elm_offset, elm_offset + L);
|
||||
e[j] = mod(os2ip(tv), options.p);
|
||||
const e = new Array(m);
|
||||
for (let j = 0; j < m; j++) {
|
||||
const elm_offset = L * (j + i * m);
|
||||
const tv = prb.subarray(elm_offset, elm_offset + L);
|
||||
e[j] = mod(os2ip(tv), p);
|
||||
}
|
||||
u[i] = e;
|
||||
}
|
||||
@@ -195,38 +189,30 @@ export interface H2CPointConstructor<T> extends GroupConstructor<H2CPoint<T>> {
|
||||
|
||||
export type MapToCurve<T> = (scalar: bigint[]) => AffinePoint<T>;
|
||||
|
||||
// Separated from initialization opts, so users won't accidentally change per-curve parameters (changing DST is ok!)
|
||||
export type htfBasicOpts = {
|
||||
DST: string;
|
||||
};
|
||||
// Separated from initialization opts, so users won't accidentally change per-curve parameters
|
||||
// (changing DST is ok!)
|
||||
export type htfBasicOpts = { DST: UnicodeOrBytes };
|
||||
|
||||
export function hashToCurve<T>(
|
||||
export function createHasher<T>(
|
||||
Point: H2CPointConstructor<T>,
|
||||
mapToCurve: MapToCurve<T>,
|
||||
def: Opts
|
||||
def: Opts & { encodeDST?: UnicodeOrBytes }
|
||||
) {
|
||||
validateOpts(def);
|
||||
if (typeof mapToCurve !== 'function')
|
||||
throw new Error('hashToCurve: mapToCurve() has not been defined');
|
||||
|
||||
if (typeof mapToCurve !== 'function') throw new Error('mapToCurve() must be defined');
|
||||
return {
|
||||
// Encodes byte string to elliptic curve
|
||||
// https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-11#section-3
|
||||
hashToCurve(msg: Hex, options?: htfBasicOpts) {
|
||||
if (!mapToCurve) throw new Error('CURVE.mapToCurve() has not been defined');
|
||||
msg = ensureBytes(msg);
|
||||
// https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-16#section-3
|
||||
hashToCurve(msg: Uint8Array, options?: htfBasicOpts) {
|
||||
const u = hash_to_field(msg, 2, { ...def, DST: def.DST, ...options } as Opts);
|
||||
const P = Point.fromAffine(mapToCurve(u[0]))
|
||||
.add(Point.fromAffine(mapToCurve(u[1])))
|
||||
.clearCofactor();
|
||||
const u0 = Point.fromAffine(mapToCurve(u[0]));
|
||||
const u1 = Point.fromAffine(mapToCurve(u[1]));
|
||||
const P = u0.add(u1).clearCofactor();
|
||||
P.assertValidity();
|
||||
return P;
|
||||
},
|
||||
|
||||
// https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-16#section-3
|
||||
encodeToCurve(msg: Hex, options?: htfBasicOpts) {
|
||||
if (!mapToCurve) throw new Error('CURVE.mapToCurve() has not been defined');
|
||||
msg = ensureBytes(msg);
|
||||
encodeToCurve(msg: Uint8Array, options?: htfBasicOpts) {
|
||||
const u = hash_to_field(msg, 1, { ...def, DST: def.encodeDST, ...options } as Opts);
|
||||
const P = Point.fromAffine(mapToCurve(u[0])).clearCofactor();
|
||||
P.assertValidity();
|
||||
|
||||
@@ -56,6 +56,7 @@ export function invert(number: bigint, modulo: bigint): bigint {
|
||||
throw new Error(`invert: expected positive integers, got n=${number} mod=${modulo}`);
|
||||
}
|
||||
// Eucledian GCD https://brilliant.org/wiki/extended-euclidean-algorithm/
|
||||
// Fermat's little theorem "CT-like" version inv(n) = n^(m-2) mod m is 30x slower.
|
||||
let a = mod(number, modulo);
|
||||
let b = modulo;
|
||||
// prettier-ignore
|
||||
@@ -407,7 +408,7 @@ export function hashToPrivateScalar(
|
||||
groupOrder: bigint,
|
||||
isLE = false
|
||||
): bigint {
|
||||
hash = ensureBytes(hash);
|
||||
hash = ensureBytes('privateHash', hash);
|
||||
const hashLen = hash.length;
|
||||
const minLen = nLength(groupOrder).nByteLength + 8;
|
||||
if (minLen < 24 || hashLen < minLen || hashLen > 1024)
|
||||
|
||||
@@ -11,25 +11,27 @@ export type CurveType = {
|
||||
nByteLength: number;
|
||||
adjustScalarBytes?: (bytes: Uint8Array) => Uint8Array;
|
||||
domain?: (data: Uint8Array, ctx: Uint8Array, phflag: boolean) => Uint8Array;
|
||||
a24: bigint; // Related to d, but cannot be derived from it
|
||||
a: bigint;
|
||||
montgomeryBits: number;
|
||||
powPminus2?: (x: bigint) => bigint;
|
||||
xyToU?: (x: bigint, y: bigint) => bigint;
|
||||
Gu: string;
|
||||
Gu: bigint;
|
||||
randomBytes?: (bytesLength?: number) => Uint8Array;
|
||||
};
|
||||
export type CurveFn = {
|
||||
scalarMult: (scalar: Hex, u: Hex) => Uint8Array;
|
||||
scalarMultBase: (scalar: Hex) => Uint8Array;
|
||||
getSharedSecret: (privateKeyA: Hex, publicKeyB: Hex) => Uint8Array;
|
||||
getPublicKey: (privateKey: Hex) => Uint8Array;
|
||||
Gu: string;
|
||||
utils: { randomPrivateKey: () => Uint8Array };
|
||||
GuBytes: Uint8Array;
|
||||
};
|
||||
|
||||
function validateOpts(curve: CurveType) {
|
||||
validateObject(
|
||||
curve,
|
||||
{
|
||||
a24: 'bigint',
|
||||
a: 'bigint',
|
||||
},
|
||||
{
|
||||
montgomeryBits: 'isSafeInteger',
|
||||
@@ -37,7 +39,7 @@ function validateOpts(curve: CurveType) {
|
||||
adjustScalarBytes: 'function',
|
||||
domain: 'function',
|
||||
powPminus2: 'function',
|
||||
Gu: 'string',
|
||||
Gu: 'bigint',
|
||||
}
|
||||
);
|
||||
// Set defaults
|
||||
@@ -49,7 +51,7 @@ function validateOpts(curve: CurveType) {
|
||||
export function montgomery(curveDef: CurveType): CurveFn {
|
||||
const CURVE = validateOpts(curveDef);
|
||||
const { P } = CURVE;
|
||||
const modP = (a: bigint) => mod(a, P);
|
||||
const modP = (n: bigint) => mod(n, P);
|
||||
const montgomeryBits = CURVE.montgomeryBits;
|
||||
const montgomeryBytes = Math.ceil(montgomeryBits / 8);
|
||||
const fieldLen = CURVE.nByteLength;
|
||||
@@ -73,12 +75,15 @@ export function montgomery(curveDef: CurveType): CurveFn {
|
||||
return [x_2, x_3];
|
||||
}
|
||||
|
||||
// Accepts 0 as well
|
||||
function assertFieldElement(n: bigint): bigint {
|
||||
if (typeof n === 'bigint' && _0n <= n && n < P) return n;
|
||||
throw new Error('Expected valid scalar 0 < scalar < CURVE.P');
|
||||
}
|
||||
|
||||
// x25519 from 4
|
||||
// The constant a24 is (486662 - 2) / 4 = 121665 for curve25519/X25519
|
||||
const a24 = (CURVE.a - BigInt(2)) / BigInt(4);
|
||||
/**
|
||||
*
|
||||
* @param pointU u coordinate (x) on Montgomery Curve 25519
|
||||
@@ -90,8 +95,6 @@ export function montgomery(curveDef: CurveType): CurveFn {
|
||||
// Section 5: Implementations MUST accept non-canonical values and process them as
|
||||
// if they had been reduced modulo the field prime.
|
||||
const k = assertFieldElement(scalar);
|
||||
// The constant a24 is (486662 - 2) / 4 = 121665 for curve25519/X25519
|
||||
const a24 = CURVE.a24;
|
||||
const x_1 = u;
|
||||
let x_2 = _1n;
|
||||
let z_2 = _0n;
|
||||
@@ -149,13 +152,13 @@ export function montgomery(curveDef: CurveType): CurveFn {
|
||||
// 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(uEnc, montgomeryBytes);
|
||||
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
|
||||
return bytesToNumberLE(u);
|
||||
}
|
||||
function decodeScalar(n: Hex): bigint {
|
||||
const bytes = ensureBytes(n);
|
||||
const bytes = ensureBytes('scalar', n);
|
||||
if (bytes.length !== montgomeryBytes && bytes.length !== fieldLen)
|
||||
throw new Error(`Expected ${montgomeryBytes} or ${fieldLen} bytes, got ${bytes.length}`);
|
||||
return bytesToNumberLE(adjustScalarBytes(bytes));
|
||||
@@ -170,8 +173,9 @@ export function montgomery(curveDef: CurveType): CurveFn {
|
||||
return encodeUCoordinate(pu);
|
||||
}
|
||||
// Computes public key from private. By doing scalar multiplication of base point.
|
||||
const GuBytes = encodeUCoordinate(CURVE.Gu);
|
||||
function scalarMultBase(scalar: Hex): Uint8Array {
|
||||
return scalarMult(scalar, CURVE.Gu);
|
||||
return scalarMult(scalar, GuBytes);
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -179,6 +183,7 @@ export function montgomery(curveDef: CurveType): CurveFn {
|
||||
scalarMultBase,
|
||||
getSharedSecret: (privateKey: Hex, publicKey: Hex) => scalarMult(privateKey, publicKey),
|
||||
getPublicKey: (privateKey: Hex): Uint8Array => scalarMultBase(privateKey),
|
||||
Gu: CURVE.Gu,
|
||||
utils: { randomPrivateKey: () => CURVE.randomBytes!(CURVE.nByteLength) },
|
||||
GuBytes: GuBytes,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -33,14 +33,14 @@ export function numberToHexUnpadded(num: number | bigint): string {
|
||||
}
|
||||
|
||||
export function hexToNumber(hex: string): bigint {
|
||||
if (typeof hex !== 'string') throw new Error('string expected, got ' + typeof hex);
|
||||
if (typeof hex !== 'string') throw new Error('hex string expected, got ' + typeof hex);
|
||||
// Big Endian
|
||||
return BigInt(hex === '' ? '0' : `0x${hex}`);
|
||||
}
|
||||
|
||||
// Caching slows it down 2-3x
|
||||
export function hexToBytes(hex: string): Uint8Array {
|
||||
if (typeof hex !== 'string') throw new Error('string expected, got ' + typeof hex);
|
||||
if (typeof hex !== 'string') throw new Error('hex string expected, got ' + typeof hex);
|
||||
if (hex.length % 2) throw new Error('hex string is invalid: unpadded ' + hex.length);
|
||||
const array = new Uint8Array(hex.length / 2);
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
@@ -68,13 +68,25 @@ export const numberToBytesLE = (n: bigint, len: number) => numberToBytesBE(n, le
|
||||
// Returns variable number bytes (minimal bigint encoding?)
|
||||
export const numberToVarBytesBE = (n: bigint) => hexToBytes(numberToHexUnpadded(n));
|
||||
|
||||
export function ensureBytes(hex: Hex, expectedLength?: number): Uint8Array {
|
||||
// Uint8Array.from() instead of hash.slice() because node.js Buffer
|
||||
// is instance of Uint8Array, and its slice() creates **mutable** copy
|
||||
const bytes = u8a(hex) ? Uint8Array.from(hex) : hexToBytes(hex);
|
||||
if (typeof expectedLength === 'number' && bytes.length !== expectedLength)
|
||||
throw new Error(`Expected ${expectedLength} bytes`);
|
||||
return bytes;
|
||||
export function ensureBytes(title: string, hex: Hex, expectedLength?: number): Uint8Array {
|
||||
let res: Uint8Array;
|
||||
if (typeof hex === 'string') {
|
||||
try {
|
||||
res = hexToBytes(hex);
|
||||
} catch (e) {
|
||||
throw new Error(`${title} must be valid hex string, got "${hex}". Cause: ${e}`);
|
||||
}
|
||||
} else if (u8a(hex)) {
|
||||
// Uint8Array.from() instead of hash.slice() because node.js Buffer
|
||||
// is instance of Uint8Array, and its slice() creates **mutable** copy
|
||||
res = Uint8Array.from(hex);
|
||||
} else {
|
||||
throw new Error(`${title} must be hex string or Uint8Array`);
|
||||
}
|
||||
const len = res.length;
|
||||
if (typeof expectedLength === 'number' && len !== expectedLength)
|
||||
throw new Error(`${title} expected ${expectedLength} bytes, got ${len}`);
|
||||
return res;
|
||||
}
|
||||
|
||||
// Copies several Uint8Arrays into one.
|
||||
@@ -96,6 +108,16 @@ export function equalBytes(b1: Uint8Array, b2: Uint8Array) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Global symbols in both browsers and Node.js since v11
|
||||
// See https://github.com/microsoft/TypeScript/issues/31535
|
||||
declare const TextEncoder: any;
|
||||
export function utf8ToBytes(str: string): Uint8Array {
|
||||
if (typeof str !== 'string') {
|
||||
throw new Error(`utf8ToBytes expected string, got ${typeof str}`);
|
||||
}
|
||||
return new TextEncoder().encode(str);
|
||||
}
|
||||
|
||||
// Bit operations
|
||||
|
||||
// Amount of bits inside bigint (Same as n.toString(2).length)
|
||||
@@ -114,6 +136,70 @@ export const bitSet = (n: bigint, pos: number, value: boolean) =>
|
||||
// Not using ** operator with bigints for old engines.
|
||||
export const bitMask = (n: number) => (_2n << BigInt(n - 1)) - _1n;
|
||||
|
||||
// DRBG
|
||||
|
||||
const u8n = (data?: any) => new Uint8Array(data); // creates Uint8Array
|
||||
const u8fr = (arr: any) => Uint8Array.from(arr); // another shortcut
|
||||
type Pred<T> = (v: Uint8Array) => T | undefined;
|
||||
/**
|
||||
* Minimal HMAC-DRBG from NIST 800-90 for RFC6979 sigs.
|
||||
* @returns function that will call DRBG until 2nd arg returns something meaningful
|
||||
* @example
|
||||
* const drbg = createHmacDRBG<Key>(32, 32, hmac);
|
||||
* drbg(seed, bytesToKey); // bytesToKey must return Key or undefined
|
||||
*/
|
||||
export function createHmacDrbg<T>(
|
||||
hashLen: number,
|
||||
qByteLen: number,
|
||||
hmacFn: (key: Uint8Array, ...messages: Uint8Array[]) => Uint8Array
|
||||
): (seed: Uint8Array, predicate: Pred<T>) => T {
|
||||
if (typeof hashLen !== 'number' || hashLen < 2) throw new Error('hashLen must be a number');
|
||||
if (typeof qByteLen !== 'number' || qByteLen < 2) throw new Error('qByteLen must be a number');
|
||||
if (typeof hmacFn !== 'function') throw new Error('hmacFn must be a function');
|
||||
// Step B, Step C: set hashLen to 8*ceil(hlen/8)
|
||||
let v = u8n(hashLen); // Minimal non-full-spec HMAC-DRBG from NIST 800-90 for RFC6979 sigs.
|
||||
let k = u8n(hashLen); // Steps B and C of RFC6979 3.2: set hashLen, in our case always same
|
||||
let i = 0; // Iterations counter, will throw when over 1000
|
||||
const reset = () => {
|
||||
v.fill(1);
|
||||
k.fill(0);
|
||||
i = 0;
|
||||
};
|
||||
const h = (...b: Uint8Array[]) => hmacFn(k, v, ...b); // hmac(k)(v, ...values)
|
||||
const reseed = (seed = u8n()) => {
|
||||
// HMAC-DRBG reseed() function. Steps D-G
|
||||
k = h(u8fr([0x00]), seed); // k = hmac(k || v || 0x00 || seed)
|
||||
v = h(); // v = hmac(k || v)
|
||||
if (seed.length === 0) return;
|
||||
k = h(u8fr([0x01]), seed); // k = hmac(k || v || 0x01 || seed)
|
||||
v = h(); // v = hmac(k || v)
|
||||
};
|
||||
const gen = () => {
|
||||
// HMAC-DRBG generate() function
|
||||
if (i++ >= 1000) throw new Error('drbg: tried 1000 values');
|
||||
let len = 0;
|
||||
const out: Uint8Array[] = [];
|
||||
while (len < qByteLen) {
|
||||
v = h();
|
||||
const sl = v.slice();
|
||||
out.push(sl);
|
||||
len += v.length;
|
||||
}
|
||||
return concatBytes(...out);
|
||||
};
|
||||
const genUntil = (seed: Uint8Array, pred: Pred<T>): T => {
|
||||
reset();
|
||||
reseed(seed); // Steps D-G
|
||||
let res: T | undefined = undefined; // Step H: grind until k is in [1..n-1]
|
||||
while (!(res = pred(gen()))) reseed();
|
||||
reset();
|
||||
return res;
|
||||
};
|
||||
return genUntil;
|
||||
}
|
||||
|
||||
// Validating curves and fields
|
||||
|
||||
const validatorFns = {
|
||||
bigint: (val: any) => typeof val === 'bigint',
|
||||
function: (val: any) => typeof val === 'function',
|
||||
|
||||
@@ -59,9 +59,6 @@ export interface ProjPointType<T> extends Group<ProjPointType<T>> {
|
||||
readonly py: T;
|
||||
readonly pz: T;
|
||||
multiply(scalar: bigint): ProjPointType<T>;
|
||||
multiplyUnsafe(scalar: bigint): ProjPointType<T>;
|
||||
multiplyAndAddUnsafe(Q: ProjPointType<T>, a: bigint, b: bigint): ProjPointType<T> | undefined;
|
||||
_setWindowSize(windowSize: number): void;
|
||||
toAffine(iz?: T): AffinePoint<T>;
|
||||
isTorsionFree(): boolean;
|
||||
clearCofactor(): ProjPointType<T>;
|
||||
@@ -69,6 +66,10 @@ export interface ProjPointType<T> extends Group<ProjPointType<T>> {
|
||||
hasEvenY(): boolean;
|
||||
toRawBytes(isCompressed?: boolean): Uint8Array;
|
||||
toHex(isCompressed?: boolean): string;
|
||||
|
||||
multiplyUnsafe(scalar: bigint): ProjPointType<T>;
|
||||
multiplyAndAddUnsafe(Q: ProjPointType<T>, a: bigint, b: bigint): ProjPointType<T> | undefined;
|
||||
_setWindowSize(windowSize: number): void;
|
||||
}
|
||||
// Static methods for 3d XYZ points
|
||||
export interface ProjConstructor<T> extends GroupConstructor<ProjPointType<T>> {
|
||||
@@ -121,7 +122,7 @@ function validatePointOpts<T>(curve: CurvePointsType<T>) {
|
||||
|
||||
export type CurvePointsRes<T> = {
|
||||
ProjectivePoint: ProjConstructor<T>;
|
||||
normalizePrivateKey: (key: PrivKey) => bigint;
|
||||
normPrivateKeyToScalar: (key: PrivKey) => bigint;
|
||||
weierstrassEquation: (x: T) => T;
|
||||
isWithinCurveOrder: (num: bigint) => boolean;
|
||||
};
|
||||
@@ -202,8 +203,8 @@ export function weierstrassPoints<T>(opts: CurvePointsType<T>) {
|
||||
if (!isWithinCurveOrder(num)) throw new Error('Expected valid bigint: 0 < bigint < curve.n');
|
||||
}
|
||||
// Validates if priv key is valid and converts it to bigint.
|
||||
// Supports options CURVE.normalizePrivateKey and CURVE.wrapPrivateKey.
|
||||
function normalizePrivateKey(key: PrivKey): bigint {
|
||||
// Supports options allowedPrivateKeyLengths and wrapPrivateKey.
|
||||
function normPrivateKeyToScalar(key: PrivKey): bigint {
|
||||
const { allowedPrivateKeyLengths: lengths, nByteLength, wrapPrivateKey, n } = CURVE;
|
||||
if (lengths && typeof key !== 'bigint') {
|
||||
if (key instanceof Uint8Array) key = ut.bytesToHex(key);
|
||||
@@ -213,7 +214,10 @@ export function weierstrassPoints<T>(opts: CurvePointsType<T>) {
|
||||
}
|
||||
let num: bigint;
|
||||
try {
|
||||
num = typeof key === 'bigint' ? key : ut.bytesToNumberBE(ensureBytes(key, nByteLength));
|
||||
num =
|
||||
typeof key === 'bigint'
|
||||
? key
|
||||
: ut.bytesToNumberBE(ensureBytes('private key', key, nByteLength));
|
||||
} catch (error) {
|
||||
throw new Error(`private key must be ${nByteLength} bytes, hex or bigint, not ${typeof key}`);
|
||||
}
|
||||
@@ -276,14 +280,14 @@ export function weierstrassPoints<T>(opts: CurvePointsType<T>) {
|
||||
* @param hex short/long ECDSA hex
|
||||
*/
|
||||
static fromHex(hex: Hex): Point {
|
||||
const P = Point.fromAffine(CURVE.fromBytes(ensureBytes(hex)));
|
||||
const P = Point.fromAffine(CURVE.fromBytes(ensureBytes('pointHex', hex)));
|
||||
P.assertValidity();
|
||||
return P;
|
||||
}
|
||||
|
||||
// Multiplies generator point by privateKey.
|
||||
static fromPrivateKey(privateKey: PrivKey) {
|
||||
return Point.BASE.multiply(normalizePrivateKey(privateKey));
|
||||
return Point.BASE.multiply(normPrivateKeyToScalar(privateKey));
|
||||
}
|
||||
|
||||
// We calculate precomputes for elliptic curve point multiplication
|
||||
@@ -484,8 +488,9 @@ export function weierstrassPoints<T>(opts: CurvePointsType<T>) {
|
||||
* Constant time multiplication.
|
||||
* Uses wNAF method. Windowed method may be 10% faster,
|
||||
* but takes 2x longer to generate and consumes 2x memory.
|
||||
* Uses precomputes when available.
|
||||
* Uses endomorphism for Koblitz curves.
|
||||
* @param scalar by which the point would be multiplied
|
||||
* @param affinePoint optional point ot save cached precompute windows on it
|
||||
* @returns New point
|
||||
*/
|
||||
multiply(scalar: bigint): Point {
|
||||
@@ -513,6 +518,8 @@ export function weierstrassPoints<T>(opts: CurvePointsType<T>) {
|
||||
|
||||
/**
|
||||
* Efficiently calculate `aP + bQ`. Unsafe, can expose private key, if used incorrectly.
|
||||
* Not using Strauss-Shamir trick: precomputation tables are faster.
|
||||
* The trick could be useful if both P and Q are not G (not in our case).
|
||||
* @returns non-zero affine point
|
||||
*/
|
||||
multiplyAndAddUnsafe(Q: Point, a: bigint, b: bigint): Point | undefined {
|
||||
@@ -568,7 +575,7 @@ export function weierstrassPoints<T>(opts: CurvePointsType<T>) {
|
||||
|
||||
return {
|
||||
ProjectivePoint: Point as ProjConstructor<T>,
|
||||
normalizePrivateKey,
|
||||
normPrivateKeyToScalar,
|
||||
weierstrassEquation,
|
||||
isWithinCurveOrder,
|
||||
};
|
||||
@@ -636,66 +643,13 @@ export type CurveFn = {
|
||||
ProjectivePoint: ProjConstructor<bigint>;
|
||||
Signature: SignatureConstructor;
|
||||
utils: {
|
||||
_normalizePrivateKey: (key: PrivKey) => bigint;
|
||||
normPrivateKeyToScalar: (key: PrivKey) => bigint;
|
||||
isValidPrivateKey(privateKey: PrivKey): boolean;
|
||||
hashToPrivateKey: (hash: Hex) => Uint8Array;
|
||||
randomPrivateKey: () => Uint8Array;
|
||||
precompute: (windowSize?: number, point?: ProjPointType<bigint>) => ProjPointType<bigint>;
|
||||
};
|
||||
};
|
||||
|
||||
const u8n = (data?: any) => new Uint8Array(data); // creates Uint8Array
|
||||
const u8fr = (arr: any) => Uint8Array.from(arr); // another shortcut
|
||||
// Minimal HMAC-DRBG from NIST 800-90 for RFC6979 sigs.
|
||||
type Pred<T> = (v: Uint8Array) => T | undefined;
|
||||
function hmacDrbg<T>(
|
||||
hashLen: number,
|
||||
qByteLen: number,
|
||||
hmacFn: HmacFnSync
|
||||
): (seed: Uint8Array, predicate: Pred<T>) => T {
|
||||
if (typeof hashLen !== 'number' || hashLen < 2) throw new Error('hashLen must be a number');
|
||||
if (typeof qByteLen !== 'number' || qByteLen < 2) throw new Error('qByteLen must be a number');
|
||||
if (typeof hmacFn !== 'function') throw new Error('hmacFn must be a function');
|
||||
// Step B, Step C: set hashLen to 8*ceil(hlen/8)
|
||||
let v = u8n(hashLen); // Minimal non-full-spec HMAC-DRBG from NIST 800-90 for RFC6979 sigs.
|
||||
let k = u8n(hashLen); // Steps B and C of RFC6979 3.2: set hashLen, in our case always same
|
||||
let i = 0; // Iterations counter, will throw when over 1000
|
||||
const reset = () => {
|
||||
v.fill(1);
|
||||
k.fill(0);
|
||||
i = 0;
|
||||
};
|
||||
const h = (...b: Uint8Array[]) => hmacFn(k, v, ...b); // hmac(k)(v, ...values)
|
||||
const reseed = (seed = u8n()) => {
|
||||
// HMAC-DRBG reseed() function. Steps D-G
|
||||
k = h(u8fr([0x00]), seed); // k = hmac(k || v || 0x00 || seed)
|
||||
v = h(); // v = hmac(k || v)
|
||||
if (seed.length === 0) return;
|
||||
k = h(u8fr([0x01]), seed); // k = hmac(k || v || 0x01 || seed)
|
||||
v = h(); // v = hmac(k || v)
|
||||
};
|
||||
const gen = () => {
|
||||
// HMAC-DRBG generate() function
|
||||
if (i++ >= 1000) throw new Error('drbg: tried 1000 values');
|
||||
let len = 0;
|
||||
const out: Uint8Array[] = [];
|
||||
while (len < qByteLen) {
|
||||
v = h();
|
||||
const sl = v.slice();
|
||||
out.push(sl);
|
||||
len += v.length;
|
||||
}
|
||||
return ut.concatBytes(...out);
|
||||
};
|
||||
const genUntil = (seed: Uint8Array, pred: Pred<T>): T => {
|
||||
reset();
|
||||
reseed(seed); // Steps D-G
|
||||
let res: T | undefined = undefined; // Step H: grind until k is in [1..n-1]
|
||||
while (!(res = pred(gen()))) reseed();
|
||||
reset();
|
||||
return res;
|
||||
};
|
||||
return genUntil;
|
||||
}
|
||||
export function weierstrass(curveDef: CurveType): CurveFn {
|
||||
const CURVE = validateOpts(curveDef) as ReturnType<typeof validateOpts>;
|
||||
const CURVE_ORDER = CURVE.n;
|
||||
@@ -715,7 +669,7 @@ export function weierstrass(curveDef: CurveType): CurveFn {
|
||||
|
||||
const {
|
||||
ProjectivePoint: Point,
|
||||
normalizePrivateKey,
|
||||
normPrivateKeyToScalar,
|
||||
weierstrassEquation,
|
||||
isWithinCurveOrder,
|
||||
} = weierstrassPoints({
|
||||
@@ -725,7 +679,6 @@ export function weierstrass(curveDef: CurveType): CurveFn {
|
||||
const x = Fp.toBytes(a.x);
|
||||
const cat = ut.concatBytes;
|
||||
if (isCompressed) {
|
||||
// TODO: hasEvenY
|
||||
return cat(Uint8Array.from([point.hasEvenY() ? 0x02 : 0x03]), x);
|
||||
} else {
|
||||
return cat(Uint8Array.from([0x04]), x, Fp.toBytes(a.y));
|
||||
@@ -781,24 +734,22 @@ export function weierstrass(curveDef: CurveType): CurveFn {
|
||||
|
||||
// pair (bytes of r, bytes of s)
|
||||
static fromCompact(hex: Hex) {
|
||||
const gl = CURVE.nByteLength;
|
||||
hex = ensureBytes(hex, gl * 2);
|
||||
return new Signature(slcNum(hex, 0, gl), slcNum(hex, gl, 2 * gl));
|
||||
const l = CURVE.nByteLength;
|
||||
hex = ensureBytes('compactSignature', hex, l * 2);
|
||||
return new Signature(slcNum(hex, 0, l), slcNum(hex, l, 2 * l));
|
||||
}
|
||||
|
||||
// DER encoded ECDSA signature
|
||||
// https://bitcoin.stackexchange.com/questions/57644/what-are-the-parts-of-a-bitcoin-transaction-input-script
|
||||
static fromDER(hex: Hex) {
|
||||
if (typeof hex !== 'string' && !(hex instanceof Uint8Array))
|
||||
throw new Error(`Signature.fromDER: Expected string or Uint8Array`);
|
||||
const { r, s } = DER.toSig(ensureBytes(hex));
|
||||
const { r, s } = DER.toSig(ensureBytes('DER', hex));
|
||||
return new Signature(r, s);
|
||||
}
|
||||
|
||||
assertValidity(): void {
|
||||
// can use assertGE here
|
||||
if (!isWithinCurveOrder(this.r)) throw new Error('r must be 0 < r < n');
|
||||
if (!isWithinCurveOrder(this.s)) throw new Error('s must be 0 < s < n');
|
||||
if (!isWithinCurveOrder(this.r)) throw new Error('r must be 0 < r < CURVE.n');
|
||||
if (!isWithinCurveOrder(this.s)) throw new Error('s must be 0 < s < CURVE.n');
|
||||
}
|
||||
|
||||
addRecoveryBit(recovery: number) {
|
||||
@@ -806,11 +757,10 @@ export function weierstrass(curveDef: CurveType): CurveFn {
|
||||
}
|
||||
|
||||
recoverPublicKey(msgHash: Hex): typeof Point.BASE {
|
||||
const { n: N } = CURVE; // ECDSA public key recovery secg.org/sec1-v2.pdf 4.1.6
|
||||
const { r, s, recovery: rec } = this;
|
||||
const h = bits2int_modN(ensureBytes(msgHash)); // Truncate hash
|
||||
const h = bits2int_modN(ensureBytes('msgHash', msgHash)); // Truncate hash
|
||||
if (rec == null || ![0, 1, 2, 3].includes(rec)) throw new Error('recovery id invalid');
|
||||
const radj = rec === 2 || rec === 3 ? r + N : r;
|
||||
const radj = rec === 2 || rec === 3 ? r + CURVE.n : r;
|
||||
if (radj >= Fp.ORDER) throw new Error('recovery id 2 or 3 invalid');
|
||||
const prefix = (rec & 1) === 0 ? '02' : '03';
|
||||
const R = Point.fromHex(prefix + numToNByteStr(radj));
|
||||
@@ -852,37 +802,35 @@ export function weierstrass(curveDef: CurveType): CurveFn {
|
||||
const utils = {
|
||||
isValidPrivateKey(privateKey: PrivKey) {
|
||||
try {
|
||||
normalizePrivateKey(privateKey);
|
||||
normPrivateKeyToScalar(privateKey);
|
||||
return true;
|
||||
} catch (error) {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
_normalizePrivateKey: normalizePrivateKey,
|
||||
|
||||
/**
|
||||
* Converts some bytes to a valid private key. Needs at least (nBitLength+64) bytes.
|
||||
*/
|
||||
hashToPrivateKey: (hash: Hex): Uint8Array =>
|
||||
ut.numberToBytesBE(mod.hashToPrivateScalar(hash, CURVE_ORDER), CURVE.nByteLength),
|
||||
normPrivateKeyToScalar: normPrivateKeyToScalar,
|
||||
|
||||
/**
|
||||
* Produces cryptographically secure private key from random of size (nBitLength+64)
|
||||
* as per FIPS 186 B.4.1 with modulo bias being neglible.
|
||||
*/
|
||||
randomPrivateKey: (): Uint8Array => utils.hashToPrivateKey(CURVE.randomBytes(Fp.BYTES + 8)),
|
||||
randomPrivateKey: (): Uint8Array => {
|
||||
const rand = CURVE.randomBytes(Fp.BYTES + 8);
|
||||
const num = mod.hashToPrivateScalar(rand, CURVE_ORDER);
|
||||
return ut.numberToBytesBE(num, CURVE.nByteLength);
|
||||
},
|
||||
|
||||
/**
|
||||
* 1. Returns cached point which you can use to pass to `getSharedSecret` or `#multiply` by it.
|
||||
* 2. Precomputes point multiplication table. Is done by default on first `getPublicKey()` call.
|
||||
* If you want your first getPublicKey to take 0.16ms instead of 20ms, make sure to call
|
||||
* utils.precompute() somewhere without arguments first.
|
||||
* @param windowSize 2, 4, 8, 16
|
||||
* Creates precompute table for an arbitrary EC point. Makes point "cached".
|
||||
* Allows to massively speed-up `point.multiply(scalar)`.
|
||||
* @returns cached point
|
||||
* @example
|
||||
* const fast = utils.precompute(8, ProjectivePoint.fromHex(someonesPubKey));
|
||||
* fast.multiply(privKey); // much faster ECDH now
|
||||
*/
|
||||
precompute(windowSize = 8, point = Point.BASE): typeof Point.BASE {
|
||||
point._setWindowSize(windowSize);
|
||||
point.multiply(BigInt(3));
|
||||
point.multiply(BigInt(3)); // 3 is arbitrary, just need any number here
|
||||
return point;
|
||||
},
|
||||
};
|
||||
@@ -913,7 +861,8 @@ export function weierstrass(curveDef: CurveType): CurveFn {
|
||||
/**
|
||||
* ECDH (Elliptic Curve Diffie Hellman).
|
||||
* Computes shared public key from private key and public key.
|
||||
* Checks: 1) private key validity 2) shared key is on-curve
|
||||
* Checks: 1) private key validity 2) shared key is on-curve.
|
||||
* Does NOT hash the result.
|
||||
* @param privateA private key
|
||||
* @param publicB different public key
|
||||
* @param isCompressed whether to return compact (default), or full key
|
||||
@@ -923,7 +872,7 @@ export function weierstrass(curveDef: CurveType): CurveFn {
|
||||
if (isProbPub(privateA)) throw new Error('first arg must be private key');
|
||||
if (!isProbPub(publicB)) throw new Error('second arg must be public key');
|
||||
const b = Point.fromHex(publicB); // check for being on-curve
|
||||
return b.multiply(normalizePrivateKey(privateA)).toRawBytes(isCompressed);
|
||||
return b.multiply(normPrivateKeyToScalar(privateA)).toRawBytes(isCompressed);
|
||||
}
|
||||
|
||||
// RFC6979: ensure ECDSA msg is X bytes and < N. RFC suggests optional truncating via bits2octets.
|
||||
@@ -935,8 +884,8 @@ export function weierstrass(curveDef: CurveType): CurveFn {
|
||||
function (bytes: Uint8Array): bigint {
|
||||
// For curves with nBitLength % 8 !== 0: bits2octets(bits2octets(m)) !== bits2octets(m)
|
||||
// for some cases, since bytes.length * 8 is not actual bitLength.
|
||||
const delta = bytes.length * 8 - CURVE.nBitLength; // truncate to nBitLength leftmost bits
|
||||
const num = ut.bytesToNumberBE(bytes); // check for == u8 done here
|
||||
const delta = bytes.length * 8 - CURVE.nBitLength; // truncate to nBitLength leftmost bits
|
||||
return delta > 0 ? num >> BigInt(delta) : num;
|
||||
};
|
||||
const bits2int_modN =
|
||||
@@ -946,10 +895,12 @@ export function weierstrass(curveDef: CurveType): CurveFn {
|
||||
};
|
||||
// NOTE: pads output with zero as per spec
|
||||
const ORDER_MASK = ut.bitMask(CURVE.nBitLength);
|
||||
/**
|
||||
* Converts to bytes. Checks if num in `[0..ORDER_MASK-1]` e.g.: `[0..2^256-1]`.
|
||||
*/
|
||||
function int2octets(num: bigint): Uint8Array {
|
||||
if (typeof num !== 'bigint') throw new Error('bigint expected');
|
||||
if (!(_0n <= num && num < ORDER_MASK))
|
||||
// n in [0..ORDER_MASK-1]
|
||||
throw new Error(`bigint expected < 2^${CURVE.nBitLength}`);
|
||||
// works with order, can have different size than numToField!
|
||||
return ut.numberToBytesBE(num, CURVE.nByteLength);
|
||||
@@ -961,26 +912,25 @@ export function weierstrass(curveDef: CurveType): CurveFn {
|
||||
// NOTE: we cannot assume here that msgHash has same amount of bytes as curve order, this will be wrong at least for P521.
|
||||
// Also it can be bigger for P224 + SHA256
|
||||
function prepSig(msgHash: Hex, privateKey: PrivKey, opts = defaultSigOpts) {
|
||||
const { hash, randomBytes } = CURVE;
|
||||
if (msgHash == null) throw new Error(`sign: expected valid message hash, not "${msgHash}"`);
|
||||
if (['recovered', 'canonical'].some((k) => k in opts))
|
||||
// Ban legacy options
|
||||
throw new Error('sign() legacy options not supported');
|
||||
const { hash, randomBytes } = CURVE;
|
||||
let { lowS, prehash, extraEntropy: ent } = opts; // generates low-s sigs by default
|
||||
if (prehash) msgHash = hash(ensureBytes(msgHash));
|
||||
if (lowS == null) lowS = true; // RFC6979 3.2: we skip step A, because we already provide hash
|
||||
msgHash = ensureBytes('msgHash', msgHash);
|
||||
if (prehash) msgHash = ensureBytes('prehashed msgHash', hash(msgHash));
|
||||
|
||||
// We can't later call bits2octets, since nested bits2int is broken for curves
|
||||
// with nBitLength % 8 !== 0. Because of that, we unwrap it here as int2octets call.
|
||||
// const bits2octets = (bits) => int2octets(bits2int_modN(bits))
|
||||
const h1int = bits2int_modN(ensureBytes(msgHash));
|
||||
const d = normalizePrivateKey(privateKey); // validate private key, convert to bigint
|
||||
const h1int = bits2int_modN(msgHash);
|
||||
const d = normPrivateKeyToScalar(privateKey); // validate private key, convert to bigint
|
||||
const seedArgs = [int2octets(d), int2octets(h1int)];
|
||||
// extraEntropy. RFC6979 3.6: additional k' (optional).
|
||||
if (ent != null) {
|
||||
// K = HMAC_K(V || 0x00 || int2octets(x) || bits2octets(h1) || k')
|
||||
// Either pass as-is, or generate random bytes. Then validate for being ui8a of size BYTES
|
||||
seedArgs.push(ensureBytes(ent === true ? randomBytes(Fp.BYTES) : ent, Fp.BYTES));
|
||||
const e = ent === true ? randomBytes(Fp.BYTES) : ent; // generate random bytes OR pass as-is
|
||||
seedArgs.push(ensureBytes('extraEntropy', e, Fp.BYTES)); // check for being of size BYTES
|
||||
}
|
||||
const seed = ut.concatBytes(...seedArgs); // Step D of RFC6979 3.2
|
||||
const m = h1int; // NOTE: no need to call bits2int second time here, it is inside truncateHash!
|
||||
@@ -993,7 +943,10 @@ export function weierstrass(curveDef: CurveType): CurveFn {
|
||||
const q = Point.BASE.multiply(k).toAffine(); // q = Gk
|
||||
const r = modN(q.x); // r = q.x mod n
|
||||
if (r === _0n) return;
|
||||
const s = modN(ik * modN(m + modN(d * r))); // s = k^-1(m + rd) mod n
|
||||
// Can use scalar blinding b^-1(bm + bdr) where b ∈ [1,q−1] according to
|
||||
// https://tches.iacr.org/index.php/TCHES/article/view/7337/6509. We've decided against it:
|
||||
// a) dependency on CSPRNG b) 15% slowdown c) doesn't really help since bigints are not CT
|
||||
const s = modN(ik * modN(m + r * d)); // Not using blinding here
|
||||
if (s === _0n) return;
|
||||
let recovery = (q.x === r ? 0 : 2) | Number(q.y & _1n); // recovery bit (2 or 3, when q.x > n)
|
||||
let normS = s;
|
||||
@@ -1020,8 +973,8 @@ export function weierstrass(curveDef: CurveType): CurveFn {
|
||||
*/
|
||||
function sign(msgHash: Hex, privKey: PrivKey, opts = defaultSigOpts): Signature {
|
||||
const { seed, k2sig } = prepSig(msgHash, privKey, opts); // Steps A, D of RFC6979 3.2.
|
||||
const genUntil = hmacDrbg<Signature>(CURVE.hash.outputLen, CURVE.nByteLength, CURVE.hmac);
|
||||
return genUntil(seed, k2sig); // Steps B, C, D, E, F, G
|
||||
const drbg = ut.createHmacDrbg<Signature>(CURVE.hash.outputLen, CURVE.nByteLength, CURVE.hmac);
|
||||
return drbg(seed, k2sig); // Steps B, C, D, E, F, G
|
||||
}
|
||||
|
||||
// Enable precomputes. Slows down first publicKey computation by 20ms.
|
||||
@@ -1047,30 +1000,38 @@ export function weierstrass(curveDef: CurveType): CurveFn {
|
||||
publicKey: Hex,
|
||||
opts = defaultVerOpts
|
||||
): boolean {
|
||||
let P: ProjPointType<bigint>;
|
||||
const sg = signature;
|
||||
msgHash = ensureBytes('msgHash', msgHash);
|
||||
publicKey = ensureBytes('publicKey', publicKey);
|
||||
if ('strict' in opts) throw new Error('options.strict was renamed to lowS');
|
||||
const { lowS, prehash } = opts;
|
||||
|
||||
let _sig: Signature | undefined = undefined;
|
||||
if (publicKey instanceof Point) throw new Error('publicKey must be hex');
|
||||
let P: ProjPointType<bigint>;
|
||||
try {
|
||||
if (signature && typeof signature === 'object' && !(signature instanceof Uint8Array)) {
|
||||
const { r, s } = signature;
|
||||
_sig = new Signature(r, s); // assertValidity() is executed on creation
|
||||
} else {
|
||||
if (typeof sg === 'string' || sg instanceof Uint8Array) {
|
||||
// Signature can be represented in 2 ways: compact (2*nByteLength) & DER (variable-length).
|
||||
// Since DER can also be 2*nByteLength bytes, we check for it first.
|
||||
try {
|
||||
_sig = Signature.fromDER(signature as Hex);
|
||||
_sig = Signature.fromDER(sg);
|
||||
} catch (derError) {
|
||||
if (!(derError instanceof DER.Err)) throw derError;
|
||||
_sig = Signature.fromCompact(signature as Hex);
|
||||
_sig = Signature.fromCompact(sg);
|
||||
}
|
||||
} else if (typeof sg === 'object' && typeof sg.r === 'bigint' && typeof sg.s === 'bigint') {
|
||||
const { r, s } = sg;
|
||||
_sig = new Signature(r, s);
|
||||
} else {
|
||||
throw new Error('PARSE');
|
||||
}
|
||||
msgHash = ensureBytes(msgHash);
|
||||
P = Point.fromHex(publicKey);
|
||||
} catch (error) {
|
||||
if ((error as Error).message === 'PARSE')
|
||||
throw new Error(`signature must be Signature instance, Uint8Array or hex string`);
|
||||
return false;
|
||||
}
|
||||
if (opts.lowS && _sig.hasHighS()) return false;
|
||||
if (opts.prehash) msgHash = CURVE.hash(msgHash);
|
||||
if (lowS && _sig.hasHighS()) return false;
|
||||
if (prehash) msgHash = CURVE.hash(msgHash);
|
||||
const { r, s } = _sig;
|
||||
const h = bits2int_modN(msgHash); // Cannot use fields methods, since it is group element
|
||||
const is = invN(s); // s^-1
|
||||
|
||||
@@ -1,9 +1,43 @@
|
||||
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||
|
||||
// The pairing-friendly Barreto-Lynn-Scott elliptic curve construction allows to:
|
||||
// bls12-381 pairing-friendly Barreto-Lynn-Scott elliptic curve construction allows to:
|
||||
// - Construct zk-SNARKs at the 128-bit security
|
||||
// - Use threshold signatures, which allows a user to sign lots of messages with one signature and verify them swiftly in a batch, using Boneh-Lynn-Shacham signature scheme.
|
||||
// Differences from @noble/bls12-381 1.4:
|
||||
// - Use threshold signatures, which allows a user to sign lots of messages with one signature and
|
||||
// verify them swiftly in a batch, using Boneh-Lynn-Shacham signature scheme.
|
||||
//
|
||||
// The library uses G1 for public keys and G2 for signatures. Support for G1 signatures is planned.
|
||||
// Compatible with Algorand, Chia, Dfinity, Ethereum, FIL, Zcash. Matches specs
|
||||
// [pairing-curves-10](https://tools.ietf.org/html/draft-irtf-cfrg-pairing-friendly-curves-10),
|
||||
// [bls-sigs-04](https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-04),
|
||||
// [hash-to-curve-12](https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-12).
|
||||
//
|
||||
// ### Summary
|
||||
// 1. BLS Relies on Bilinear Pairing (expensive)
|
||||
// 2. Private Keys: 32 bytes
|
||||
// 3. Public Keys: 48 bytes: 381 bit affine x coordinate, encoded into 48 big-endian bytes.
|
||||
// 4. Signatures: 96 bytes: two 381 bit integers (affine x coordinate), encoded into two 48 big-endian byte arrays.
|
||||
// - The signature is a point on the G2 subgroup, which is defined over a finite field
|
||||
// with elements twice as big as the G1 curve (G2 is over Fp2 rather than Fp. Fp2 is analogous to the complex numbers).
|
||||
// 5. The 12 stands for the Embedding degree.
|
||||
//
|
||||
// ### Formulas
|
||||
// - `P = pk x G` - public keys
|
||||
// - `S = pk x H(m)` - signing
|
||||
// - `e(P, H(m)) == e(G, S)` - verification using pairings
|
||||
// - `e(G, S) = e(G, SUM(n)(Si)) = MUL(n)(e(G, Si))` - signature aggregation
|
||||
// Filecoin uses little endian byte arrays for private keys -
|
||||
// so ensure to reverse byte order if you'll use it with FIL.
|
||||
//
|
||||
// ### Resources
|
||||
// - [BLS12-381 for the rest of us](https://hackmd.io/@benjaminion/bls12-381)
|
||||
// - [Key concepts of pairings](https://medium.com/@alonmuroch_65570/bls-signatures-part-2-key-concepts-of-pairings-27a8a9533d0c)
|
||||
// - Pairing over bls12-381:
|
||||
// [part 1](https://research.nccgroup.com/2020/07/06/pairing-over-bls12-381-part-1-fields/),
|
||||
// [part 2](https://research.nccgroup.com/2020/07/13/pairing-over-bls12-381-part-2-curves/),
|
||||
// [part 3](https://research.nccgroup.com/2020/08/13/pairing-over-bls12-381-part-3-pairing/)
|
||||
// - [Estimating the bit security of pairing-friendly curves](https://research.nccgroup.com/2022/02/03/estimating-the-bit-security-of-pairing-friendly-curves/)
|
||||
//
|
||||
// ### Differences from @noble/bls12-381 1.4
|
||||
// - PointG1 -> G1.Point
|
||||
// - PointG2 -> G2.Point
|
||||
// - PointG2.fromSignature -> Signature.decode
|
||||
@@ -910,7 +944,7 @@ function G2psi2(c: ProjConstructor<Fp2>, P: ProjPointType<Fp2>) {
|
||||
// p = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab
|
||||
// m = 2 (or 1 for G1 see section 8.8.1)
|
||||
// k = 128
|
||||
const htfDefaults = {
|
||||
const htfDefaults = Object.freeze({
|
||||
// DST: a domain separation tag
|
||||
// defined in section 2.2.5
|
||||
// Use utils.getDSTLabel(), utils.setDSTLabel(value)
|
||||
@@ -932,7 +966,7 @@ const htfDefaults = {
|
||||
// wide range of hash functions, including SHA-2, SHA-3, BLAKE2, and others.
|
||||
// BBS+ uses blake2: https://github.com/hyperledger/aries-framework-go/issues/2247
|
||||
hash: sha256,
|
||||
} as const;
|
||||
} as const);
|
||||
|
||||
// Encoding utils
|
||||
// Point on G1 curve: (x, y)
|
||||
@@ -1186,7 +1220,7 @@ export const bls12_381: CurveFn<Fp, Fp2, Fp6, Fp12> = bls({
|
||||
Signature: {
|
||||
// TODO: Optimize, it's very slow because of sqrt.
|
||||
decode(hex: Hex): ProjPointType<Fp2> {
|
||||
hex = ensureBytes(hex);
|
||||
hex = ensureBytes('signatureHex', hex);
|
||||
const P = Fp.ORDER;
|
||||
const half = hex.length / 2;
|
||||
if (half !== 48 && half !== 96)
|
||||
@@ -1213,7 +1247,6 @@ export const bls12_381: CurveFn<Fp, Fp2, Fp6, Fp12> = bls({
|
||||
const isZero = y1 === 0n && (y0 * 2n) / P !== aflag1;
|
||||
if (isGreater || isZero) y = Fp2.neg(y);
|
||||
const point = bls12_381.G2.ProjectivePoint.fromAffine({ x, y });
|
||||
// console.log('Signature.decode', point);
|
||||
point.assertValidity();
|
||||
return point;
|
||||
},
|
||||
|
||||
@@ -5,14 +5,15 @@ import { twistedEdwards, ExtPointType } from './abstract/edwards.js';
|
||||
import { montgomery } from './abstract/montgomery.js';
|
||||
import { mod, pow2, isNegativeLE, Fp as Field, FpSqrtEven } from './abstract/modular.js';
|
||||
import {
|
||||
ensureBytes,
|
||||
equalBytes,
|
||||
bytesToHex,
|
||||
bytesToNumberLE,
|
||||
numberToBytesLE,
|
||||
Hex,
|
||||
ensureBytes,
|
||||
} from './abstract/utils.js';
|
||||
import * as htf from './abstract/hash-to-curve.js';
|
||||
import { AffinePoint } from './abstract/curve.js';
|
||||
|
||||
/**
|
||||
* ed25519 Twisted Edwards curve with following addons:
|
||||
@@ -138,10 +139,10 @@ export const ed25519ph = twistedEdwards({
|
||||
|
||||
export const x25519 = montgomery({
|
||||
P: ED25519_P,
|
||||
a24: BigInt('121665'),
|
||||
a: BigInt(486662),
|
||||
montgomeryBits: 255, // n is 253 bits
|
||||
nByteLength: 32,
|
||||
Gu: '0900000000000000000000000000000000000000000000000000000000000000',
|
||||
Gu: BigInt(9),
|
||||
powPminus2: (x: bigint): bigint => {
|
||||
const P = ED25519_P;
|
||||
// x^(p-2) aka x^(2^255-21)
|
||||
@@ -149,6 +150,7 @@ export const x25519 = montgomery({
|
||||
return mod(pow2(pow_p_5_8, BigInt(3), P) * b2, P);
|
||||
},
|
||||
adjustScalarBytes,
|
||||
randomBytes,
|
||||
});
|
||||
|
||||
// Hash To Curve Elligator2 Map (NOTE: different from ristretto255 elligator)
|
||||
@@ -223,7 +225,7 @@ function map_to_curve_elligator2_edwards25519(u: bigint) {
|
||||
const inv = Fp.invertBatch([xd, yd]); // batch division
|
||||
return { x: Fp.mul(xn, inv[0]), y: Fp.mul(yn, inv[1]) }; // 13. return (xn, xd, yn, yd)
|
||||
}
|
||||
const { hashToCurve, encodeToCurve } = htf.hashToCurve(
|
||||
const { hashToCurve, encodeToCurve } = htf.createHasher(
|
||||
ed25519.ExtendedPoint,
|
||||
(scalars: bigint[]) => map_to_curve_elligator2_edwards25519(scalars[0]),
|
||||
{
|
||||
@@ -308,6 +310,11 @@ export class RistrettoPoint {
|
||||
// Private property to discourage combining ExtendedPoint + RistrettoPoint
|
||||
// Always use Ristretto encoding/decoding instead.
|
||||
constructor(private readonly ep: ExtendedPoint) {}
|
||||
|
||||
static fromAffine(ap: AffinePoint<bigint>) {
|
||||
return new RistrettoPoint(ed25519.ExtendedPoint.fromAffine(ap));
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes uniform output of 64-bit hash function like sha512 and converts it to `RistrettoPoint`.
|
||||
* The hash-to-group operation applies Elligator twice and adds the results.
|
||||
@@ -316,7 +323,7 @@ export class RistrettoPoint {
|
||||
* @param hex 64-bit output of a hash function
|
||||
*/
|
||||
static hashToCurve(hex: Hex): RistrettoPoint {
|
||||
hex = ensureBytes(hex, 64);
|
||||
hex = ensureBytes('ristrettoHash', hex, 64);
|
||||
const r1 = bytes255ToNumberLE(hex.slice(0, 32));
|
||||
const R1 = calcElligatorRistrettoMap(r1);
|
||||
const r2 = bytes255ToNumberLE(hex.slice(32, 64));
|
||||
@@ -330,7 +337,7 @@ export class RistrettoPoint {
|
||||
* @param hex Ristretto-encoded 32 bytes. Not every 32-byte string is valid ristretto encoding
|
||||
*/
|
||||
static fromHex(hex: Hex): RistrettoPoint {
|
||||
hex = ensureBytes(hex, 32);
|
||||
hex = ensureBytes('ristrettoHex', hex, 32);
|
||||
const { a, d } = ed25519.CURVE;
|
||||
const P = ed25519.CURVE.Fp.ORDER;
|
||||
const mod = ed25519.CURVE.Fp.create;
|
||||
@@ -400,7 +407,7 @@ export class RistrettoPoint {
|
||||
equals(other: RistrettoPoint): boolean {
|
||||
assertRstPoint(other);
|
||||
const { ex: X1, ey: Y1 } = this.ep;
|
||||
const { ex: X2, ey: Y2 } = this.ep;
|
||||
const { ex: X2, ey: Y2 } = other.ep;
|
||||
const mod = ed25519.CURVE.Fp.create;
|
||||
// (x1 * y2 == y1 * x2) | (y1 * y2 == x1 * x2)
|
||||
const one = mod(X1 * Y2) === mod(Y1 * X2);
|
||||
@@ -426,3 +433,13 @@ export class RistrettoPoint {
|
||||
return new RistrettoPoint(this.ep.multiplyUnsafe(scalar));
|
||||
}
|
||||
}
|
||||
|
||||
// https://datatracker.ietf.org/doc/draft-irtf-cfrg-hash-to-curve/14/
|
||||
// Appendix B. Hashing to ristretto255
|
||||
export const hash_to_ristretto255 = (msg: Uint8Array, options: htf.htfBasicOpts) => {
|
||||
const d = options.DST;
|
||||
const DST = typeof d === 'string' ? utf8ToBytes(d) : d;
|
||||
const uniform_bytes = htf.expand_message_xmd(msg, DST, 64, sha512);
|
||||
const P = RistrettoPoint.hashToCurve(uniform_bytes);
|
||||
return P;
|
||||
};
|
||||
|
||||
@@ -122,11 +122,11 @@ export const ed448 = twistedEdwards(ED448_DEF);
|
||||
export const ed448ph = twistedEdwards({ ...ED448_DEF, preHash: shake256_64 });
|
||||
|
||||
export const x448 = montgomery({
|
||||
a24: BigInt(39081),
|
||||
a: BigInt(156326),
|
||||
montgomeryBits: 448,
|
||||
nByteLength: 57,
|
||||
P: ed448P,
|
||||
Gu: '0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
|
||||
Gu: BigInt(5),
|
||||
powPminus2: (x: bigint): bigint => {
|
||||
const P = ed448P;
|
||||
const Pminus3div4 = ed448_pow_Pminus3div4(x);
|
||||
@@ -134,6 +134,7 @@ export const x448 = montgomery({
|
||||
return mod(Pminus3 * x, P); // Pminus3 * x = Pminus2
|
||||
},
|
||||
adjustScalarBytes,
|
||||
randomBytes,
|
||||
// The 4-isogeny maps between the Montgomery curve and this Edwards
|
||||
// curve are:
|
||||
// (u, v) = (y^2/x^2, (2 - x^2 - y^2)*y/x^3)
|
||||
@@ -225,7 +226,7 @@ function map_to_curve_elligator2_edwards448(u: bigint) {
|
||||
return { x: Fp.mul(xEn, inv[0]), y: Fp.mul(yEn, inv[1]) }; // 38. return (xEn, xEd, yEn, yEd)
|
||||
}
|
||||
|
||||
const { hashToCurve, encodeToCurve } = htf.hashToCurve(
|
||||
const { hashToCurve, encodeToCurve } = htf.createHasher(
|
||||
ed448.ExtendedPoint,
|
||||
(scalars: bigint[]) => map_to_curve_elligator2_edwards448(scalars[0]),
|
||||
{
|
||||
|
||||
25
src/p192.ts
25
src/p192.ts
@@ -1,25 +0,0 @@
|
||||
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||
import { createCurve } from './_shortw_utils.js';
|
||||
import { sha256 } from '@noble/hashes/sha256';
|
||||
import { Fp } from './abstract/modular.js';
|
||||
|
||||
// NIST secp192r1 aka P192
|
||||
// https://www.secg.org/sec2-v2.pdf, https://neuromancer.sk/std/secg/secp192r1
|
||||
export const P192 = createCurve(
|
||||
{
|
||||
// Params: a, b
|
||||
a: BigInt('0xfffffffffffffffffffffffffffffffefffffffffffffffc'),
|
||||
b: BigInt('0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1'),
|
||||
// Field over which we'll do calculations; 2n ** 192n - 2n ** 64n - 1n
|
||||
Fp: Fp(BigInt('0xfffffffffffffffffffffffffffffffeffffffffffffffff')),
|
||||
// Curve order, total count of valid points in the field.
|
||||
n: BigInt('0xffffffffffffffffffffffff99def836146bc9b1b4d22831'),
|
||||
// Base point (x, y) aka generator point
|
||||
Gx: BigInt('0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012'),
|
||||
Gy: BigInt('0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811'),
|
||||
h: BigInt(1),
|
||||
lowS: false,
|
||||
} as const,
|
||||
sha256
|
||||
);
|
||||
export const secp192r1 = P192;
|
||||
25
src/p224.ts
25
src/p224.ts
@@ -1,25 +0,0 @@
|
||||
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||
import { createCurve } from './_shortw_utils.js';
|
||||
import { sha224 } from '@noble/hashes/sha256';
|
||||
import { Fp } from './abstract/modular.js';
|
||||
|
||||
// NIST secp224r1 aka P224
|
||||
// https://www.secg.org/sec2-v2.pdf, https://neuromancer.sk/std/nist/P-224
|
||||
export const P224 = createCurve(
|
||||
{
|
||||
// Params: a, b
|
||||
a: BigInt('0xfffffffffffffffffffffffffffffffefffffffffffffffffffffffe'),
|
||||
b: BigInt('0xb4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4'),
|
||||
// Field over which we'll do calculations;
|
||||
Fp: Fp(BigInt('0xffffffffffffffffffffffffffffffff000000000000000000000001')),
|
||||
// Curve order, total count of valid points in the field
|
||||
n: BigInt('0xffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d'),
|
||||
// Base point (x, y) aka generator point
|
||||
Gx: BigInt('0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21'),
|
||||
Gy: BigInt('0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34'),
|
||||
h: BigInt(1),
|
||||
lowS: false,
|
||||
} as const,
|
||||
sha224
|
||||
);
|
||||
export const secp224r1 = P224;
|
||||
@@ -37,7 +37,7 @@ export const P256 = createCurve(
|
||||
);
|
||||
export const secp256r1 = P256;
|
||||
|
||||
const { hashToCurve, encodeToCurve } = htf.hashToCurve(
|
||||
const { hashToCurve, encodeToCurve } = htf.createHasher(
|
||||
secp256r1.ProjectivePoint,
|
||||
(scalars: bigint[]) => mapSWU(scalars[0]),
|
||||
{
|
||||
|
||||
@@ -41,7 +41,7 @@ export const P384 = createCurve({
|
||||
);
|
||||
export const secp384r1 = P384;
|
||||
|
||||
const { hashToCurve, encodeToCurve } = htf.hashToCurve(
|
||||
const { hashToCurve, encodeToCurve } = htf.createHasher(
|
||||
secp384r1.ProjectivePoint,
|
||||
(scalars: bigint[]) => mapSWU(scalars[0]),
|
||||
{
|
||||
|
||||
@@ -41,7 +41,7 @@ export const P521 = createCurve({
|
||||
} as const, sha512);
|
||||
export const secp521r1 = P521;
|
||||
|
||||
const { hashToCurve, encodeToCurve } = htf.hashToCurve(
|
||||
const { hashToCurve, encodeToCurve } = htf.createHasher(
|
||||
secp521r1.ProjectivePoint,
|
||||
(scalars: bigint[]) => mapSWU(scalars[0]),
|
||||
{
|
||||
|
||||
136
src/secp256k1.ts
136
src/secp256k1.ts
@@ -1,26 +1,12 @@
|
||||
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||
import { sha256 } from '@noble/hashes/sha256';
|
||||
import { Fp as Field, mod, pow2 } from './abstract/modular.js';
|
||||
import { createCurve } from './_shortw_utils.js';
|
||||
import { ProjPointType as PointType, mapToCurveSimpleSWU } from './abstract/weierstrass.js';
|
||||
import {
|
||||
ensureBytes,
|
||||
concatBytes,
|
||||
Hex,
|
||||
bytesToNumberBE as bytesToInt,
|
||||
PrivKey,
|
||||
numberToBytesBE,
|
||||
} from './abstract/utils.js';
|
||||
import { randomBytes } from '@noble/hashes/utils';
|
||||
import { Fp as Field, mod, pow2 } from './abstract/modular.js';
|
||||
import { ProjPointType as PointType, mapToCurveSimpleSWU } from './abstract/weierstrass.js';
|
||||
import type { Hex, PrivKey } from './abstract/utils.js';
|
||||
import { bytesToNumberBE, concatBytes, ensureBytes, numberToBytesBE } from './abstract/utils.js';
|
||||
import * as htf from './abstract/hash-to-curve.js';
|
||||
|
||||
/**
|
||||
* secp256k1 belongs to Koblitz curves: it has efficiently computable endomorphism.
|
||||
* Endomorphism uses 2x less RAM, speeds up precomputation by 2x and ECDH / key recovery by 20%.
|
||||
* Should always be used for Projective's double-and-add multiplication.
|
||||
* For affines cached multiplication, it trades off 1/2 init time & 1/3 ram for 20% perf hit.
|
||||
* https://gist.github.com/paulmillr/eb670806793e84df628a7c434a873066
|
||||
*/
|
||||
import { createCurve } from './_shortw_utils.js';
|
||||
|
||||
const secp256k1P = BigInt('0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f');
|
||||
const secp256k1N = BigInt('0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141');
|
||||
@@ -61,23 +47,22 @@ type Fp = bigint;
|
||||
|
||||
export const secp256k1 = createCurve(
|
||||
{
|
||||
// Params: a, b
|
||||
// Seem to be rigid https://bitcointalk.org/index.php?topic=289795.msg3183975#msg3183975
|
||||
a: BigInt(0),
|
||||
b: BigInt(7),
|
||||
// Field over which we'll do calculations;
|
||||
// 2n**256n - 2n**32n - 2n**9n - 2n**8n - 2n**7n - 2n**6n - 2n**4n - 1n
|
||||
Fp,
|
||||
// Curve order, total count of valid points in the field
|
||||
n: secp256k1N,
|
||||
a: BigInt(0), // equation params: a, b
|
||||
b: BigInt(7), // Seem to be rigid: bitcointalk.org/index.php?topic=289795.msg3183975#msg3183975
|
||||
Fp, // Field's prime: 2n**256n - 2n**32n - 2n**9n - 2n**8n - 2n**7n - 2n**6n - 2n**4n - 1n
|
||||
n: secp256k1N, // Curve order, total count of valid points in the field
|
||||
// Base point (x, y) aka generator point
|
||||
Gx: BigInt('55066263022277343669578718895168534326250603453777594175500187360389116729240'),
|
||||
Gy: BigInt('32670510020758816978083085130507043184471273380659243275938904335757337482424'),
|
||||
h: BigInt(1),
|
||||
// Alllow only low-S signatures by default in sign() and verify()
|
||||
lowS: true,
|
||||
h: BigInt(1), // Cofactor
|
||||
lowS: true, // Allow only low-S signatures by default in sign() and verify()
|
||||
/**
|
||||
* secp256k1 belongs to Koblitz curves: it has efficiently computable endomorphism.
|
||||
* Endomorphism uses 2x less RAM, speeds up precomputation by 2x and ECDH / key recovery by 20%.
|
||||
* For precomputed wNAF it trades off 1/2 init time & 1/3 ram for 20% perf hit.
|
||||
* Explanation: https://gist.github.com/paulmillr/eb670806793e84df628a7c434a873066
|
||||
*/
|
||||
endo: {
|
||||
// Params taken from https://gist.github.com/paulmillr/eb670806793e84df628a7c434a873066
|
||||
beta: BigInt('0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee'),
|
||||
splitScalar: (k: bigint) => {
|
||||
const n = secp256k1N;
|
||||
@@ -105,19 +90,11 @@ export const secp256k1 = createCurve(
|
||||
sha256
|
||||
);
|
||||
|
||||
// Schnorr signatures are superior to ECDSA from above.
|
||||
// Below is Schnorr-specific code as per BIP0340.
|
||||
// Schnorr signatures are superior to ECDSA from above. Below is Schnorr-specific BIP0340 code.
|
||||
// https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki
|
||||
const _0n = BigInt(0);
|
||||
const fe = (x: bigint) => typeof x === 'bigint' && _0n < x && x < secp256k1P;
|
||||
const ge = (x: bigint) => typeof x === 'bigint' && _0n < x && x < secp256k1N;
|
||||
|
||||
const TAGS = {
|
||||
challenge: 'BIP0340/challenge',
|
||||
aux: 'BIP0340/aux',
|
||||
nonce: 'BIP0340/nonce',
|
||||
} as const;
|
||||
|
||||
/** An object mapping tags to their tagged hash prefix of [SHA256(tag) | SHA256(tag)] */
|
||||
const TAGGED_HASH_PREFIXES: { [tag: string]: Uint8Array } = {};
|
||||
function taggedHash(tag: string, ...messages: Uint8Array[]): Uint8Array {
|
||||
@@ -130,56 +107,70 @@ function taggedHash(tag: string, ...messages: Uint8Array[]): Uint8Array {
|
||||
return sha256(concatBytes(tagP, ...messages));
|
||||
}
|
||||
|
||||
// ECDSA compact points are 33-byte. Schnorr is 32: we strip first byte 0x02 or 0x03
|
||||
const pointToBytes = (point: PointType<bigint>) => point.toRawBytes(true).slice(1);
|
||||
const numTo32b = (n: bigint) => numberToBytesBE(n, 32);
|
||||
const modP = (x: bigint) => mod(x, secp256k1P);
|
||||
const modN = (x: bigint) => mod(x, secp256k1N);
|
||||
const Point = secp256k1.ProjectivePoint;
|
||||
const GmulAdd = (Q: PointType<bigint>, a: bigint, b: bigint) =>
|
||||
Point.BASE.multiplyAndAddUnsafe(Q, a, b);
|
||||
const hex32ToInt = (key: Hex) => bytesToInt(ensureBytes(key, 32));
|
||||
|
||||
// Calculate point, scalar and bytes
|
||||
function schnorrGetExtPubKey(priv: PrivKey) {
|
||||
let d = typeof priv === 'bigint' ? priv : hex32ToInt(priv);
|
||||
const point = Point.fromPrivateKey(d); // P = d'⋅G; 0 < d' < n check is done inside
|
||||
const scalar = point.hasEvenY() ? d : modN(-d); // d = d' if has_even_y(P), otherwise d = n-d'
|
||||
return { point, scalar, bytes: pointToBytes(point) };
|
||||
let d_ = secp256k1.utils.normPrivateKeyToScalar(priv); // same method executed in fromPrivateKey
|
||||
let p = Point.fromPrivateKey(d_); // P = d'⋅G; 0 < d' < n check is done inside
|
||||
const scalar = p.hasEvenY() ? d_ : modN(-d_);
|
||||
return { scalar: scalar, bytes: pointToBytes(p) };
|
||||
}
|
||||
/**
|
||||
* lift_x from BIP340. Convert 32-byte x coordinate to elliptic curve point.
|
||||
* @returns valid point checked for being on-curve
|
||||
*/
|
||||
function lift_x(x: bigint): PointType<bigint> {
|
||||
if (!fe(x)) throw new Error('bad x: need 0 < x < p'); // Fail if x ≥ p.
|
||||
const c = mod(x * x * x + BigInt(7), secp256k1P); // Let c = x³ + 7 mod p.
|
||||
const xx = modP(x * x);
|
||||
const c = modP(xx * x + BigInt(7)); // Let c = x³ + 7 mod p.
|
||||
let y = sqrtMod(c); // Let y = c^(p+1)/4 mod p.
|
||||
if (y % 2n !== 0n) y = mod(-y, secp256k1P); // Return the unique point P such that x(P) = x and
|
||||
if (y % 2n !== 0n) y = modP(-y); // Return the unique point P such that x(P) = x and
|
||||
const p = new Point(x, y, _1n); // y(P) = y if y mod 2 = 0 or y(P) = p-y otherwise.
|
||||
p.assertValidity();
|
||||
return p;
|
||||
}
|
||||
/**
|
||||
* Create tagged hash, convert it to bigint, reduce modulo-n.
|
||||
*/
|
||||
function challenge(...args: Uint8Array[]): bigint {
|
||||
return modN(bytesToInt(taggedHash(TAGS.challenge, ...args)));
|
||||
return modN(bytesToNumberBE(taggedHash('BIP0340/challenge', ...args)));
|
||||
}
|
||||
|
||||
// Schnorr's pubkey is just `x` of Point (BIP340)
|
||||
/**
|
||||
* Schnorr public key is just `x` coordinate of Point as per BIP340.
|
||||
*/
|
||||
function schnorrGetPublicKey(privateKey: Hex): Uint8Array {
|
||||
return schnorrGetExtPubKey(privateKey).bytes; // d'=int(sk). Fail if d'=0 or d'≥n. Ret bytes(d'⋅G)
|
||||
}
|
||||
|
||||
// Creates Schnorr signature as per BIP340. Verifies itself before returning anything.
|
||||
// auxRand is optional and is not the sole source of k generation: bad CSPRNG won't be dangerous
|
||||
/**
|
||||
* Creates Schnorr signature as per BIP340. Verifies itself before returning anything.
|
||||
* auxRand is optional and is not the sole source of k generation: bad CSPRNG won't be dangerous.
|
||||
*/
|
||||
function schnorrSign(
|
||||
message: Hex,
|
||||
privateKey: PrivKey,
|
||||
auxRand: Hex = randomBytes(32)
|
||||
): Uint8Array {
|
||||
if (message == null) throw new Error(`sign: Expected valid message, not "${message}"`);
|
||||
const m = ensureBytes(message); // checks for isWithinCurveOrder
|
||||
const { bytes: px, scalar: d } = schnorrGetExtPubKey(privateKey);
|
||||
const a = ensureBytes(auxRand, 32); // Auxiliary random data a: a 32-byte array
|
||||
const t = numTo32b(d ^ bytesToInt(taggedHash(TAGS.aux, a))); // Let t be the byte-wise xor of bytes(d) and hash/aux(a)
|
||||
const rand = taggedHash(TAGS.nonce, t, px, m); // Let rand = hash/nonce(t || bytes(P) || m)
|
||||
const k_ = modN(bytesToInt(rand)); // Let k' = int(rand) mod n
|
||||
const m = ensureBytes('message', message);
|
||||
const { bytes: px, scalar: d } = schnorrGetExtPubKey(privateKey); // checks for isWithinCurveOrder
|
||||
const a = ensureBytes('auxRand', auxRand, 32); // Auxiliary random data a: a 32-byte array
|
||||
const t = numTo32b(d ^ bytesToNumberBE(taggedHash('BIP0340/aux', a))); // Let t be the byte-wise xor of bytes(d) and hash/aux(a)
|
||||
const rand = taggedHash('BIP0340/nonce', t, px, m); // Let rand = hash/nonce(t || bytes(P) || m)
|
||||
const k_ = modN(bytesToNumberBE(rand)); // Let k' = int(rand) mod n
|
||||
if (k_ === _0n) throw new Error('sign failed: k is zero'); // Fail if k' = 0.
|
||||
const { point: R, bytes: rx, scalar: k } = schnorrGetExtPubKey(k_); // Let R = k'⋅G.
|
||||
const { bytes: rx, scalar: k } = schnorrGetExtPubKey(k_); // Let R = k'⋅G.
|
||||
const e = challenge(rx, px, m); // Let e = int(hash/challenge(bytes(R) || bytes(P) || m)) mod n.
|
||||
const sig = new Uint8Array(64); // Let sig = bytes(R) || bytes((k + ed) mod n).
|
||||
sig.set(numTo32b(R.px), 0);
|
||||
sig.set(rx, 0);
|
||||
sig.set(numTo32b(modN(k + e * d)), 32);
|
||||
// If Verify(bytes(P), m, sig) (see below) returns failure, abort
|
||||
if (!schnorrVerify(sig, m, px)) throw new Error('sign: Invalid signature produced');
|
||||
@@ -187,18 +178,20 @@ function schnorrSign(
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies Schnorr signature synchronously.
|
||||
* Verifies Schnorr signature.
|
||||
* Will swallow errors & return false except for initial type validation of arguments.
|
||||
*/
|
||||
function schnorrVerify(signature: Hex, message: Hex, publicKey: Hex): boolean {
|
||||
const sig = ensureBytes('signature', signature, 64);
|
||||
const m = ensureBytes('message', message);
|
||||
const pub = ensureBytes('publicKey', publicKey, 32);
|
||||
try {
|
||||
const P = lift_x(hex32ToInt(publicKey)); // P = lift_x(int(pk)); fail if that fails
|
||||
const sig = ensureBytes(signature, 64);
|
||||
const r = bytesToInt(sig.subarray(0, 32)); // Let r = int(sig[0:32]); fail if r ≥ p.
|
||||
const P = lift_x(bytesToNumberBE(pub)); // P = lift_x(int(pk)); fail if that fails
|
||||
const r = bytesToNumberBE(sig.subarray(0, 32)); // Let r = int(sig[0:32]); fail if r ≥ p.
|
||||
if (!fe(r)) return false;
|
||||
const s = bytesToInt(sig.subarray(32, 64)); // Let s = int(sig[32:64]); fail if s ≥ n.
|
||||
const s = bytesToNumberBE(sig.subarray(32, 64)); // Let s = int(sig[32:64]); fail if s ≥ n.
|
||||
if (!ge(s)) return false;
|
||||
const m = ensureBytes(message);
|
||||
const e = challenge(numTo32b(r), pointToBytes(P), m); // int(challenge(bytes(r)||bytes(P)||m)) mod n
|
||||
const e = challenge(numTo32b(r), pointToBytes(P), m); // int(challenge(bytes(r)||bytes(P)||m))%n
|
||||
const R = GmulAdd(P, s, modN(-e)); // R = s⋅G - e⋅P
|
||||
if (!R || !R.hasEvenY() || R.toAffine().x !== r) return false; // -eP == (n-e)P
|
||||
return true; // Fail if is_infinite(R) / not has_even_y(R) / x(R) ≠ r.
|
||||
@@ -212,11 +205,11 @@ export const schnorr = {
|
||||
sign: schnorrSign,
|
||||
verify: schnorrVerify,
|
||||
utils: {
|
||||
getExtendedPublicKey: schnorrGetExtPubKey,
|
||||
randomPrivateKey: secp256k1.utils.randomPrivateKey,
|
||||
lift_x,
|
||||
pointToBytes,
|
||||
numberToBytesBE,
|
||||
bytesToNumberBE: bytesToInt,
|
||||
bytesToNumberBE,
|
||||
taggedHash,
|
||||
mod,
|
||||
},
|
||||
@@ -259,7 +252,7 @@ const mapSWU = mapToCurveSimpleSWU(Fp, {
|
||||
B: BigInt('1771'),
|
||||
Z: Fp.create(BigInt('-11')),
|
||||
});
|
||||
const { hashToCurve, encodeToCurve } = htf.hashToCurve(
|
||||
export const { hashToCurve, encodeToCurve } = htf.createHasher(
|
||||
secp256k1.ProjectivePoint,
|
||||
(scalars: bigint[]) => {
|
||||
const { x, y } = mapSWU(Fp.create(scalars[0]));
|
||||
@@ -275,4 +268,3 @@ const { hashToCurve, encodeToCurve } = htf.hashToCurve(
|
||||
hash: sha256,
|
||||
}
|
||||
);
|
||||
export { hashToCurve, encodeToCurve };
|
||||
|
||||
356
src/stark.ts
356
src/stark.ts
@@ -1,356 +0,0 @@
|
||||
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||
import { keccak_256 } from '@noble/hashes/sha3';
|
||||
import { sha256 } from '@noble/hashes/sha256';
|
||||
import { weierstrass, ProjPointType } from './abstract/weierstrass.js';
|
||||
import * as cutils from './abstract/utils.js';
|
||||
import { Fp, mod, Field, validateField } from './abstract/modular.js';
|
||||
import { getHash } from './_shortw_utils.js';
|
||||
import * as poseidon from './abstract/poseidon.js';
|
||||
import { utf8ToBytes } from '@noble/hashes/utils';
|
||||
|
||||
type ProjectivePoint = ProjPointType<bigint>;
|
||||
// Stark-friendly elliptic curve
|
||||
// https://docs.starkware.co/starkex/stark-curve.html
|
||||
|
||||
const CURVE_N = BigInt(
|
||||
'3618502788666131213697322783095070105526743751716087489154079457884512865583'
|
||||
);
|
||||
const nBitLength = 252;
|
||||
// Copy-pasted from weierstrass.ts
|
||||
function bits2int(bytes: Uint8Array): bigint {
|
||||
const delta = bytes.length * 8 - nBitLength;
|
||||
const num = cutils.bytesToNumberBE(bytes);
|
||||
return delta > 0 ? num >> BigInt(delta) : num;
|
||||
}
|
||||
function bits2int_modN(bytes: Uint8Array): bigint {
|
||||
return mod(bits2int(bytes), CURVE_N);
|
||||
}
|
||||
export const starkCurve = weierstrass({
|
||||
// Params: a, b
|
||||
a: BigInt(1),
|
||||
b: BigInt('3141592653589793238462643383279502884197169399375105820974944592307816406665'),
|
||||
// Field over which we'll do calculations; 2n**251n + 17n * 2n**192n + 1n
|
||||
// There is no efficient sqrt for field (P%4==1)
|
||||
Fp: Fp(BigInt('0x800000000000011000000000000000000000000000000000000000000000001')),
|
||||
// Curve order, total count of valid points in the field.
|
||||
n: CURVE_N,
|
||||
nBitLength: nBitLength, // len(bin(N).replace('0b',''))
|
||||
// Base point (x, y) aka generator point
|
||||
Gx: BigInt('874739451078007766457464989774322083649278607533249481151382481072868806602'),
|
||||
Gy: BigInt('152666792071518830868575557812948353041420400780739481342941381225525861407'),
|
||||
h: BigInt(1),
|
||||
// Default options
|
||||
lowS: false,
|
||||
...getHash(sha256),
|
||||
// Custom truncation routines for stark curve
|
||||
bits2int: (bytes: Uint8Array): bigint => {
|
||||
while (bytes[0] === 0) bytes = bytes.subarray(1);
|
||||
return bits2int(bytes);
|
||||
},
|
||||
bits2int_modN: (bytes: Uint8Array): bigint => {
|
||||
let hashS = cutils.bytesToNumberBE(bytes).toString(16);
|
||||
if (hashS.length === 63) {
|
||||
hashS += '0';
|
||||
bytes = hexToBytes0x(hashS);
|
||||
}
|
||||
// Truncate zero bytes on left (compat with elliptic)
|
||||
while (bytes[0] === 0) bytes = bytes.subarray(1);
|
||||
return bits2int_modN(bytes);
|
||||
},
|
||||
});
|
||||
|
||||
// Custom Starknet type conversion functions that can handle 0x and unpadded hex
|
||||
function hexToBytes0x(hex: string): Uint8Array {
|
||||
if (typeof hex !== 'string') {
|
||||
throw new Error('hexToBytes: expected string, got ' + typeof hex);
|
||||
}
|
||||
hex = strip0x(hex);
|
||||
if (hex.length & 1) hex = '0' + hex; // padding
|
||||
if (hex.length % 2) throw new Error('hexToBytes: received invalid unpadded hex ' + hex.length);
|
||||
const array = new Uint8Array(hex.length / 2);
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
const j = i * 2;
|
||||
const hexByte = hex.slice(j, j + 2);
|
||||
const byte = Number.parseInt(hexByte, 16);
|
||||
if (Number.isNaN(byte) || byte < 0) throw new Error('Invalid byte sequence');
|
||||
array[i] = byte;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
function hexToNumber0x(hex: string): bigint {
|
||||
if (typeof hex !== 'string') {
|
||||
throw new Error('hexToNumber: expected string, got ' + typeof hex);
|
||||
}
|
||||
// Big Endian
|
||||
// TODO: strip vs no strip?
|
||||
return BigInt(`0x${strip0x(hex)}`);
|
||||
}
|
||||
function bytesToNumber0x(bytes: Uint8Array): bigint {
|
||||
return hexToNumber0x(cutils.bytesToHex(bytes));
|
||||
}
|
||||
function ensureBytes0x(hex: Hex): Uint8Array {
|
||||
// Uint8Array.from() instead of hash.slice() because node.js Buffer
|
||||
// is instance of Uint8Array, and its slice() creates **mutable** copy
|
||||
return hex instanceof Uint8Array ? Uint8Array.from(hex) : hexToBytes0x(hex);
|
||||
}
|
||||
|
||||
function normalizePrivateKey(privKey: Hex) {
|
||||
return cutils.bytesToHex(ensureBytes0x(privKey)).padStart(64, '0');
|
||||
}
|
||||
function getPublicKey0x(privKey: Hex, isCompressed = false) {
|
||||
return starkCurve.getPublicKey(normalizePrivateKey(privKey), isCompressed);
|
||||
}
|
||||
function getSharedSecret0x(privKeyA: Hex, pubKeyB: Hex) {
|
||||
return starkCurve.getSharedSecret(normalizePrivateKey(privKeyA), pubKeyB);
|
||||
}
|
||||
|
||||
function sign0x(msgHash: Hex, privKey: Hex, opts?: any) {
|
||||
if (typeof privKey === 'string') privKey = strip0x(privKey).padStart(64, '0');
|
||||
return starkCurve.sign(ensureBytes0x(msgHash), normalizePrivateKey(privKey), opts);
|
||||
}
|
||||
function verify0x(signature: Hex, msgHash: Hex, pubKey: Hex) {
|
||||
const sig = signature instanceof Signature ? signature : ensureBytes0x(signature);
|
||||
return starkCurve.verify(sig, ensureBytes0x(msgHash), ensureBytes0x(pubKey));
|
||||
}
|
||||
|
||||
const { CURVE, ProjectivePoint, Signature } = starkCurve;
|
||||
export const utils = starkCurve.utils;
|
||||
export {
|
||||
CURVE,
|
||||
Signature,
|
||||
ProjectivePoint,
|
||||
getPublicKey0x as getPublicKey,
|
||||
getSharedSecret0x as getSharedSecret,
|
||||
sign0x as sign,
|
||||
verify0x as verify,
|
||||
};
|
||||
|
||||
const stripLeadingZeros = (s: string) => s.replace(/^0+/gm, '');
|
||||
export const bytesToHexEth = (uint8a: Uint8Array): string =>
|
||||
`0x${stripLeadingZeros(cutils.bytesToHex(uint8a))}`;
|
||||
export const strip0x = (hex: string) => hex.replace(/^0x/i, '');
|
||||
export const numberToHexEth = (num: bigint | number) => `0x${num.toString(16)}`;
|
||||
|
||||
// We accept hex strings besides Uint8Array for simplicity
|
||||
type Hex = Uint8Array | string;
|
||||
|
||||
// 1. seed generation
|
||||
function hashKeyWithIndex(key: Uint8Array, index: number) {
|
||||
let indexHex = cutils.numberToHexUnpadded(index);
|
||||
if (indexHex.length & 1) indexHex = '0' + indexHex;
|
||||
return sha256Num(cutils.concatBytes(key, hexToBytes0x(indexHex)));
|
||||
}
|
||||
|
||||
export function grindKey(seed: Hex) {
|
||||
const _seed = ensureBytes0x(seed);
|
||||
const sha256mask = 2n ** 256n;
|
||||
|
||||
const limit = sha256mask - mod(sha256mask, CURVE_N);
|
||||
for (let i = 0; ; i++) {
|
||||
const key = hashKeyWithIndex(_seed, i);
|
||||
// key should be in [0, limit)
|
||||
if (key < limit) return mod(key, CURVE_N).toString(16);
|
||||
}
|
||||
}
|
||||
|
||||
export function getStarkKey(privateKey: Hex) {
|
||||
return bytesToHexEth(getPublicKey0x(privateKey, true).slice(1));
|
||||
}
|
||||
|
||||
export function ethSigToPrivate(signature: string) {
|
||||
signature = strip0x(signature.replace(/^0x/, ''));
|
||||
if (signature.length !== 130) throw new Error('Wrong ethereum signature');
|
||||
return grindKey(signature.substring(0, 64));
|
||||
}
|
||||
|
||||
const MASK_31 = 2n ** 31n - 1n;
|
||||
const int31 = (n: bigint) => Number(n & MASK_31);
|
||||
export function getAccountPath(
|
||||
layer: string,
|
||||
application: string,
|
||||
ethereumAddress: string,
|
||||
index: number
|
||||
) {
|
||||
const layerNum = int31(sha256Num(layer));
|
||||
const applicationNum = int31(sha256Num(application));
|
||||
const eth = hexToNumber0x(ethereumAddress);
|
||||
return `m/2645'/${layerNum}'/${applicationNum}'/${int31(eth)}'/${int31(eth >> 31n)}'/${index}`;
|
||||
}
|
||||
|
||||
// https://docs.starkware.co/starkex/pedersen-hash-function.html
|
||||
const PEDERSEN_POINTS_AFFINE = [
|
||||
new ProjectivePoint(
|
||||
2089986280348253421170679821480865132823066470938446095505822317253594081284n,
|
||||
1713931329540660377023406109199410414810705867260802078187082345529207694986n,
|
||||
1n
|
||||
),
|
||||
new ProjectivePoint(
|
||||
996781205833008774514500082376783249102396023663454813447423147977397232763n,
|
||||
1668503676786377725805489344771023921079126552019160156920634619255970485781n,
|
||||
1n
|
||||
),
|
||||
new ProjectivePoint(
|
||||
2251563274489750535117886426533222435294046428347329203627021249169616184184n,
|
||||
1798716007562728905295480679789526322175868328062420237419143593021674992973n,
|
||||
1n
|
||||
),
|
||||
new ProjectivePoint(
|
||||
2138414695194151160943305727036575959195309218611738193261179310511854807447n,
|
||||
113410276730064486255102093846540133784865286929052426931474106396135072156n,
|
||||
1n
|
||||
),
|
||||
new ProjectivePoint(
|
||||
2379962749567351885752724891227938183011949129833673362440656643086021394946n,
|
||||
776496453633298175483985398648758586525933812536653089401905292063708816422n,
|
||||
1n
|
||||
),
|
||||
];
|
||||
// for (const p of PEDERSEN_POINTS) p._setWindowSize(8);
|
||||
const PEDERSEN_POINTS = PEDERSEN_POINTS_AFFINE;
|
||||
|
||||
function pedersenPrecompute(p1: ProjectivePoint, p2: ProjectivePoint): ProjectivePoint[] {
|
||||
const out: ProjectivePoint[] = [];
|
||||
let p = p1;
|
||||
for (let i = 0; i < 248; i++) {
|
||||
out.push(p);
|
||||
p = p.double();
|
||||
}
|
||||
// NOTE: we cannot use wNAF here, because last 4 bits will require full 248 bits multiplication
|
||||
// We can add support for this to wNAF, but it will complicate wNAF.
|
||||
p = p2;
|
||||
for (let i = 0; i < 4; i++) {
|
||||
out.push(p);
|
||||
p = p.double();
|
||||
}
|
||||
return out;
|
||||
}
|
||||
const PEDERSEN_POINTS1 = pedersenPrecompute(PEDERSEN_POINTS[1], PEDERSEN_POINTS[2]);
|
||||
const PEDERSEN_POINTS2 = pedersenPrecompute(PEDERSEN_POINTS[3], PEDERSEN_POINTS[4]);
|
||||
|
||||
type PedersenArg = Hex | bigint | number;
|
||||
function pedersenArg(arg: PedersenArg): bigint {
|
||||
let value: bigint;
|
||||
if (typeof arg === 'bigint') value = arg;
|
||||
else if (typeof arg === 'number') {
|
||||
if (!Number.isSafeInteger(arg)) throw new Error(`Invalid pedersenArg: ${arg}`);
|
||||
value = BigInt(arg);
|
||||
} else value = bytesToNumber0x(ensureBytes0x(arg));
|
||||
// [0..Fp)
|
||||
if (!(0n <= value && value < starkCurve.CURVE.Fp.ORDER))
|
||||
throw new Error(`PedersenArg should be 0 <= value < CURVE.P: ${value}`);
|
||||
return value;
|
||||
}
|
||||
|
||||
function pedersenSingle(point: ProjectivePoint, value: PedersenArg, constants: ProjectivePoint[]) {
|
||||
let x = pedersenArg(value);
|
||||
for (let j = 0; j < 252; j++) {
|
||||
const pt = constants[j];
|
||||
if (pt.px === point.px) throw new Error('Same point');
|
||||
if ((x & 1n) !== 0n) point = point.add(pt);
|
||||
x >>= 1n;
|
||||
}
|
||||
return point;
|
||||
}
|
||||
|
||||
// shift_point + x_low * P_0 + x_high * P1 + y_low * P2 + y_high * P3
|
||||
export function pedersen(x: PedersenArg, y: PedersenArg) {
|
||||
let point: ProjectivePoint = PEDERSEN_POINTS[0];
|
||||
point = pedersenSingle(point, x, PEDERSEN_POINTS1);
|
||||
point = pedersenSingle(point, y, PEDERSEN_POINTS2);
|
||||
return bytesToHexEth(point.toRawBytes(true).slice(1));
|
||||
}
|
||||
|
||||
export function hashChain(data: PedersenArg[], fn = pedersen) {
|
||||
if (!Array.isArray(data) || data.length < 1)
|
||||
throw new Error('data should be array of at least 1 element');
|
||||
if (data.length === 1) return numberToHexEth(pedersenArg(data[0]));
|
||||
return Array.from(data)
|
||||
.reverse()
|
||||
.reduce((acc, i) => fn(i, acc));
|
||||
}
|
||||
// Same as hashChain, but computes hash even for single element and order is not revesed
|
||||
export const computeHashOnElements = (data: PedersenArg[], fn = pedersen) =>
|
||||
[0, ...data, data.length].reduce((x, y) => fn(x, y));
|
||||
|
||||
const MASK_250 = cutils.bitMask(250);
|
||||
export const keccak = (data: Uint8Array): bigint => bytesToNumber0x(keccak_256(data)) & MASK_250;
|
||||
const sha256Num = (data: Uint8Array | string): bigint => cutils.bytesToNumberBE(sha256(data));
|
||||
|
||||
// Poseidon hash
|
||||
export const Fp253 = Fp(
|
||||
BigInt('14474011154664525231415395255581126252639794253786371766033694892385558855681')
|
||||
); // 2^253 + 2^199 + 1
|
||||
export const Fp251 = Fp(
|
||||
BigInt('3618502788666131213697322783095070105623107215331596699973092056135872020481')
|
||||
); // 2^251 + 17 * 2^192 + 1
|
||||
|
||||
function poseidonRoundConstant(Fp: Field<bigint>, name: string, idx: number) {
|
||||
const val = Fp.fromBytes(sha256(utf8ToBytes(`${name}${idx}`)));
|
||||
return Fp.create(val);
|
||||
}
|
||||
|
||||
// NOTE: doesn't check eiginvalues and possible can create unsafe matrix. But any filtration here will break compatibility with starknet
|
||||
// Please use only if you really know what you doing.
|
||||
// https://eprint.iacr.org/2019/458.pdf Section 2.3 (Avoiding Insecure Matrices)
|
||||
export function _poseidonMDS(Fp: Field<bigint>, name: string, m: number, attempt = 0) {
|
||||
const x_values: bigint[] = [];
|
||||
const y_values: bigint[] = [];
|
||||
for (let i = 0; i < m; i++) {
|
||||
x_values.push(poseidonRoundConstant(Fp, `${name}x`, attempt * m + i));
|
||||
y_values.push(poseidonRoundConstant(Fp, `${name}y`, attempt * m + i));
|
||||
}
|
||||
if (new Set([...x_values, ...y_values]).size !== 2 * m)
|
||||
throw new Error('X and Y values are not distinct');
|
||||
return x_values.map((x) => y_values.map((y) => Fp.inv(Fp.sub(x, y))));
|
||||
}
|
||||
|
||||
const MDS_SMALL = [
|
||||
[3, 1, 1],
|
||||
[1, -1, 1],
|
||||
[1, 1, -2],
|
||||
].map((i) => i.map(BigInt));
|
||||
|
||||
export type PoseidonOpts = {
|
||||
Fp: Field<bigint>;
|
||||
rate: number;
|
||||
capacity: number;
|
||||
roundsFull: number;
|
||||
roundsPartial: number;
|
||||
};
|
||||
|
||||
export function poseidonBasic(opts: PoseidonOpts, mds: bigint[][]) {
|
||||
validateField(opts.Fp);
|
||||
if (!Number.isSafeInteger(opts.rate) || !Number.isSafeInteger(opts.capacity))
|
||||
throw new Error(`Wrong poseidon opts: ${opts}`);
|
||||
const m = opts.rate + opts.capacity;
|
||||
const rounds = opts.roundsFull + opts.roundsPartial;
|
||||
const roundConstants = [];
|
||||
for (let i = 0; i < rounds; i++) {
|
||||
const row = [];
|
||||
for (let j = 0; j < m; j++) row.push(poseidonRoundConstant(opts.Fp, 'Hades', m * i + j));
|
||||
roundConstants.push(row);
|
||||
}
|
||||
return poseidon.poseidon({
|
||||
...opts,
|
||||
t: m,
|
||||
sboxPower: 3,
|
||||
reversePartialPowIdx: true, // Why?!
|
||||
mds,
|
||||
roundConstants,
|
||||
});
|
||||
}
|
||||
|
||||
export function poseidonCreate(opts: PoseidonOpts, mdsAttempt = 0) {
|
||||
const m = opts.rate + opts.capacity;
|
||||
if (!Number.isSafeInteger(mdsAttempt)) throw new Error(`Wrong mdsAttempt=${mdsAttempt}`);
|
||||
return poseidonBasic(opts, _poseidonMDS(opts.Fp, 'HadesMDS', m, mdsAttempt));
|
||||
}
|
||||
|
||||
export const poseidonSmall = poseidonBasic(
|
||||
{ Fp: Fp251, rate: 2, capacity: 1, roundsFull: 8, roundsPartial: 83 },
|
||||
MDS_SMALL
|
||||
);
|
||||
|
||||
export function poseidonHash(x: bigint, y: bigint, fn = poseidonSmall) {
|
||||
return fn([x, y, 2n])[0];
|
||||
}
|
||||
44
test/_more-curves.helpers.js
Normal file
44
test/_more-curves.helpers.js
Normal file
@@ -0,0 +1,44 @@
|
||||
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||
import { createCurve } from '../esm/_shortw_utils.js';
|
||||
import { sha224, sha256 } from '@noble/hashes/sha256';
|
||||
import { Fp } from '../esm/abstract/modular.js';
|
||||
|
||||
// NIST secp192r1 aka P192
|
||||
// https://www.secg.org/sec2-v2.pdf, https://neuromancer.sk/std/secg/secp192r1
|
||||
export const P192 = createCurve(
|
||||
{
|
||||
// Params: a, b
|
||||
a: BigInt('0xfffffffffffffffffffffffffffffffefffffffffffffffc'),
|
||||
b: BigInt('0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1'),
|
||||
// Field over which we'll do calculations; 2n ** 192n - 2n ** 64n - 1n
|
||||
Fp: Fp(BigInt('0xfffffffffffffffffffffffffffffffeffffffffffffffff')),
|
||||
// Curve order, total count of valid points in the field.
|
||||
n: BigInt('0xffffffffffffffffffffffff99def836146bc9b1b4d22831'),
|
||||
// Base point (x, y) aka generator point
|
||||
Gx: BigInt('0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012'),
|
||||
Gy: BigInt('0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811'),
|
||||
h: BigInt(1),
|
||||
lowS: false,
|
||||
},
|
||||
sha256
|
||||
);
|
||||
export const secp192r1 = P192;
|
||||
|
||||
export const P224 = createCurve(
|
||||
{
|
||||
// Params: a, b
|
||||
a: BigInt('0xfffffffffffffffffffffffffffffffefffffffffffffffffffffffe'),
|
||||
b: BigInt('0xb4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4'),
|
||||
// Field over which we'll do calculations;
|
||||
Fp: Fp(BigInt('0xffffffffffffffffffffffffffffffff000000000000000000000001')),
|
||||
// Curve order, total count of valid points in the field
|
||||
n: BigInt('0xffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d'),
|
||||
// Base point (x, y) aka generator point
|
||||
Gx: BigInt('0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21'),
|
||||
Gy: BigInt('0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34'),
|
||||
h: BigInt(1),
|
||||
lowS: false,
|
||||
},
|
||||
sha224
|
||||
);
|
||||
export const secp224r1 = P224;
|
||||
103
test/_poseidon.helpers.js
Normal file
103
test/_poseidon.helpers.js
Normal file
@@ -0,0 +1,103 @@
|
||||
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||
import { sha256 } from '@noble/hashes/sha256';
|
||||
import { utf8ToBytes } from '@noble/hashes/utils';
|
||||
import { Fp, validateField } from '../esm/abstract/modular.js';
|
||||
import { poseidon } from '../esm/abstract/poseidon.js';
|
||||
import * as u from '../esm/abstract/utils.js';
|
||||
|
||||
// Poseidon hash https://docs.starkware.co/starkex/stark-curve.html
|
||||
export const Fp253 = Fp(
|
||||
BigInt('14474011154664525231415395255581126252639794253786371766033694892385558855681')
|
||||
); // 2^253 + 2^199 + 1
|
||||
export const Fp251 = Fp(
|
||||
BigInt('3618502788666131213697322783095070105623107215331596699973092056135872020481')
|
||||
); // 2^251 + 17 * 2^192 + 1
|
||||
|
||||
function poseidonRoundConstant(Fp, name, idx) {
|
||||
const val = Fp.fromBytes(sha256(utf8ToBytes(`${name}${idx}`)));
|
||||
return Fp.create(val);
|
||||
}
|
||||
|
||||
// NOTE: doesn't check eiginvalues and possible can create unsafe matrix. But any filtration here will break compatibility with starknet
|
||||
// Please use only if you really know what you doing.
|
||||
// https://eprint.iacr.org/2019/458.pdf Section 2.3 (Avoiding Insecure Matrices)
|
||||
export function _poseidonMDS(Fp, name, m, attempt = 0) {
|
||||
const x_values = [];
|
||||
const y_values = [];
|
||||
for (let i = 0; i < m; i++) {
|
||||
x_values.push(poseidonRoundConstant(Fp, `${name}x`, attempt * m + i));
|
||||
y_values.push(poseidonRoundConstant(Fp, `${name}y`, attempt * m + i));
|
||||
}
|
||||
if (new Set([...x_values, ...y_values]).size !== 2 * m)
|
||||
throw new Error('X and Y values are not distinct');
|
||||
return x_values.map((x) => y_values.map((y) => Fp.inv(Fp.sub(x, y))));
|
||||
}
|
||||
|
||||
const MDS_SMALL = [
|
||||
[3, 1, 1],
|
||||
[1, -1, 1],
|
||||
[1, 1, -2],
|
||||
].map((i) => i.map(BigInt));
|
||||
|
||||
export function poseidonBasic(opts, mds) {
|
||||
validateField(opts.Fp);
|
||||
if (!Number.isSafeInteger(opts.rate) || !Number.isSafeInteger(opts.capacity))
|
||||
throw new Error(`Wrong poseidon opts: ${opts}`);
|
||||
const m = opts.rate + opts.capacity;
|
||||
const rounds = opts.roundsFull + opts.roundsPartial;
|
||||
const roundConstants = [];
|
||||
for (let i = 0; i < rounds; i++) {
|
||||
const row = [];
|
||||
for (let j = 0; j < m; j++) row.push(poseidonRoundConstant(opts.Fp, 'Hades', m * i + j));
|
||||
roundConstants.push(row);
|
||||
}
|
||||
const res = poseidon({
|
||||
...opts,
|
||||
t: m,
|
||||
sboxPower: 3,
|
||||
reversePartialPowIdx: true, // Why?!
|
||||
mds,
|
||||
roundConstants,
|
||||
});
|
||||
res.m = m;
|
||||
res.rate = opts.rate;
|
||||
res.capacity = opts.capacity;
|
||||
return res;
|
||||
}
|
||||
|
||||
export function poseidonCreate(opts, mdsAttempt = 0) {
|
||||
const m = opts.rate + opts.capacity;
|
||||
if (!Number.isSafeInteger(mdsAttempt)) throw new Error(`Wrong mdsAttempt=${mdsAttempt}`);
|
||||
return poseidonBasic(opts, _poseidonMDS(opts.Fp, 'HadesMDS', m, mdsAttempt));
|
||||
}
|
||||
|
||||
export const poseidonSmall = poseidonBasic(
|
||||
{ Fp: Fp251, rate: 2, capacity: 1, roundsFull: 8, roundsPartial: 83 },
|
||||
MDS_SMALL
|
||||
);
|
||||
|
||||
export function poseidonHash(x, y, fn = poseidonSmall) {
|
||||
return fn([x, y, 2n])[0];
|
||||
}
|
||||
|
||||
export function poseidonHashFunc(x, y, fn = poseidonSmall) {
|
||||
return u.numberToVarBytesBE(poseidonHash(u.bytesToNumberBE(x), u.bytesToNumberBE(y), fn));
|
||||
}
|
||||
|
||||
export function poseidonHashSingle(x, fn = poseidonSmall) {
|
||||
return fn([x, 0n, 1n])[0];
|
||||
}
|
||||
|
||||
export function poseidonHashMany(values, fn = poseidonSmall) {
|
||||
const { m, rate } = fn;
|
||||
if (!Array.isArray(values)) throw new Error('bigint array expected in values');
|
||||
const padded = Array.from(values); // copy
|
||||
padded.push(1n);
|
||||
while (padded.length % rate !== 0) padded.push(0n);
|
||||
let state = new Array(m).fill(0n);
|
||||
for (let i = 0; i < padded.length; i += rate) {
|
||||
for (let j = 0; j < rate; j++) state[j] += padded[i + j];
|
||||
state = fn(state);
|
||||
}
|
||||
return state[0];
|
||||
}
|
||||
@@ -1,22 +1,20 @@
|
||||
import { deepStrictEqual, throws } from 'assert';
|
||||
import { should, describe } from 'micro-should';
|
||||
import * as fc from 'fast-check';
|
||||
import * as mod from '../lib/esm/abstract/modular.js';
|
||||
import { bytesToHex as toHex } from '../lib/esm/abstract/utils.js';
|
||||
import * as mod from '../esm/abstract/modular.js';
|
||||
import { bytesToHex as toHex } from '../esm/abstract/utils.js';
|
||||
// Generic tests for all curves in package
|
||||
import { secp192r1 } from '../lib/esm/p192.js';
|
||||
import { secp224r1 } from '../lib/esm/p224.js';
|
||||
import { secp256r1 } from '../lib/esm/p256.js';
|
||||
import { secp384r1 } from '../lib/esm/p384.js';
|
||||
import { secp521r1 } from '../lib/esm/p521.js';
|
||||
import { secp256k1 } from '../lib/esm/secp256k1.js';
|
||||
import { ed25519, ed25519ctx, ed25519ph, x25519 } from '../lib/esm/ed25519.js';
|
||||
import { ed448, ed448ph } from '../lib/esm/ed448.js';
|
||||
import { starkCurve } from '../lib/esm/stark.js';
|
||||
import { pallas, vesta } from '../lib/esm/pasta.js';
|
||||
import { bn254 } from '../lib/esm/bn.js';
|
||||
import { jubjub } from '../lib/esm/jubjub.js';
|
||||
import { bls12_381 } from '../lib/esm/bls12-381.js';
|
||||
import { secp192r1, secp224r1 } from './_more-curves.helpers.js';
|
||||
import { secp256r1 } from '../esm/p256.js';
|
||||
import { secp384r1 } from '../esm/p384.js';
|
||||
import { secp521r1 } from '../esm/p521.js';
|
||||
import { secp256k1 } from '../esm/secp256k1.js';
|
||||
import { ed25519, ed25519ctx, ed25519ph, x25519 } from '../esm/ed25519.js';
|
||||
import { ed448, ed448ph } from '../esm/ed448.js';
|
||||
import { pallas, vesta } from '../esm/pasta.js';
|
||||
import { bn254 } from '../esm/bn.js';
|
||||
import { jubjub } from '../esm/jubjub.js';
|
||||
import { bls12_381 } from '../esm/bls12-381.js';
|
||||
|
||||
// Fields tests
|
||||
const FIELDS = {
|
||||
@@ -25,7 +23,6 @@ const FIELDS = {
|
||||
secp256r1: { Fp: [secp256r1.CURVE.Fp] },
|
||||
secp521r1: { Fp: [secp521r1.CURVE.Fp] },
|
||||
secp256k1: { Fp: [secp256k1.CURVE.Fp] },
|
||||
stark: { Fp: [starkCurve.CURVE.Fp] },
|
||||
jubjub: { Fp: [jubjub.CURVE.Fp] },
|
||||
ed25519: { Fp: [ed25519.CURVE.Fp] },
|
||||
ed448: { Fp: [ed448.CURVE.Fp] },
|
||||
@@ -239,6 +236,11 @@ for (const c in FIELDS) {
|
||||
deepStrictEqual(isSquare(a), true);
|
||||
deepStrictEqual(Fp.eql(Fp.sqr(root), a), true, 'sqrt(a)^2 == a');
|
||||
deepStrictEqual(Fp.eql(Fp.sqr(Fp.neg(root)), a), true, '(-sqrt(a))^2 == a');
|
||||
// Returns odd/even element
|
||||
deepStrictEqual(Fp.isOdd(mod.FpSqrtOdd(Fp, a)), true);
|
||||
deepStrictEqual(Fp.isOdd(mod.FpSqrtEven(Fp, a)), false);
|
||||
deepStrictEqual(Fp.eql(Fp.sqr(mod.FpSqrtOdd(Fp, a)), a), true);
|
||||
deepStrictEqual(Fp.eql(Fp.sqr(mod.FpSqrtEven(Fp, a)), a), true);
|
||||
})
|
||||
);
|
||||
});
|
||||
@@ -261,6 +263,9 @@ for (const c in FIELDS) {
|
||||
if (Fp.eql(a, Fp.ZERO)) return; // No division by zero
|
||||
deepStrictEqual(Fp.div(a, Fp.ONE), a);
|
||||
deepStrictEqual(Fp.div(a, a), Fp.ONE);
|
||||
// FpDiv tests
|
||||
deepStrictEqual(mod.FpDiv(Fp, a, Fp.ONE), a);
|
||||
deepStrictEqual(mod.FpDiv(Fp, a, a), Fp.ONE);
|
||||
})
|
||||
);
|
||||
});
|
||||
@@ -269,6 +274,7 @@ for (const c in FIELDS) {
|
||||
fc.property(FC_BIGINT, (num) => {
|
||||
const a = create(num);
|
||||
deepStrictEqual(Fp.div(Fp.ZERO, a), Fp.ZERO);
|
||||
deepStrictEqual(mod.FpDiv(Fp, Fp.ZERO, a), Fp.ZERO);
|
||||
})
|
||||
);
|
||||
});
|
||||
@@ -279,6 +285,10 @@ for (const c in FIELDS) {
|
||||
const b = create(num2);
|
||||
const c = create(num3);
|
||||
deepStrictEqual(Fp.div(Fp.add(a, b), c), Fp.add(Fp.div(a, c), Fp.div(b, c)));
|
||||
deepStrictEqual(
|
||||
mod.FpDiv(Fp, Fp.add(a, b), c),
|
||||
Fp.add(mod.FpDiv(Fp, a, c), mod.FpDiv(Fp, b, c))
|
||||
);
|
||||
})
|
||||
);
|
||||
});
|
||||
@@ -302,7 +312,6 @@ const CURVES = {
|
||||
secp256k1,
|
||||
ed25519, ed25519ctx, ed25519ph,
|
||||
ed448, ed448ph,
|
||||
starkCurve,
|
||||
pallas, vesta,
|
||||
bn254,
|
||||
jubjub,
|
||||
@@ -521,8 +530,22 @@ for (const name in CURVES) {
|
||||
should('fromHex(toHex()) roundtrip', () => {
|
||||
fc.assert(
|
||||
fc.property(FC_BIGINT, (x) => {
|
||||
const hex = p.BASE.multiply(x).toHex();
|
||||
const point = p.BASE.multiply(x);
|
||||
const hex = point.toHex();
|
||||
const bytes = point.toRawBytes();
|
||||
deepStrictEqual(p.fromHex(hex).toHex(), hex);
|
||||
deepStrictEqual(p.fromHex(bytes).toHex(), hex);
|
||||
})
|
||||
);
|
||||
});
|
||||
should('fromHex(toHex(compressed=true)) roundtrip', () => {
|
||||
fc.assert(
|
||||
fc.property(FC_BIGINT, (x) => {
|
||||
const point = p.BASE.multiply(x);
|
||||
const hex = point.toHex(true);
|
||||
const bytes = point.toRawBytes(true);
|
||||
deepStrictEqual(p.fromHex(hex).toHex(true), hex);
|
||||
deepStrictEqual(p.fromHex(bytes).toHex(true), hex);
|
||||
})
|
||||
);
|
||||
});
|
||||
@@ -561,7 +584,7 @@ for (const name in CURVES) {
|
||||
deepStrictEqual(
|
||||
C.verify(sig, msg, pub),
|
||||
true,
|
||||
'priv=${toHex(priv)},pub=${toHex(pub)},msg=${msg}'
|
||||
`priv=${toHex(priv)},pub=${toHex(pub)},msg=${msg}`
|
||||
);
|
||||
}),
|
||||
{ numRuns: NUM_RUNS }
|
||||
@@ -605,6 +628,52 @@ for (const name in CURVES) {
|
||||
deepStrictEqual(C.verify(sig, msg, C.getPublicKey(C.utils.randomPrivateKey())), false);
|
||||
});
|
||||
});
|
||||
if (C.Signature) {
|
||||
should('Signature serialization roundtrip', () =>
|
||||
fc.assert(
|
||||
fc.property(fc.hexaString({ minLength: 64, maxLength: 64 }), (msg) => {
|
||||
const priv = C.utils.randomPrivateKey();
|
||||
const sig = C.sign(msg, priv);
|
||||
const sigRS = (sig) => ({ s: sig.s, r: sig.r });
|
||||
// Compact
|
||||
deepStrictEqual(sigRS(C.Signature.fromCompact(sig.toCompactHex())), sigRS(sig));
|
||||
deepStrictEqual(sigRS(C.Signature.fromCompact(sig.toCompactRawBytes())), sigRS(sig));
|
||||
// DER
|
||||
deepStrictEqual(sigRS(C.Signature.fromDER(sig.toDERHex())), sigRS(sig));
|
||||
deepStrictEqual(sigRS(C.Signature.fromDER(sig.toDERRawBytes())), sigRS(sig));
|
||||
}),
|
||||
{ numRuns: NUM_RUNS }
|
||||
)
|
||||
);
|
||||
should('Signature.addRecoveryBit/Signature.recoveryPublicKey', () =>
|
||||
fc.assert(
|
||||
fc.property(fc.hexaString({ minLength: 64, maxLength: 64 }), (msg) => {
|
||||
const priv = C.utils.randomPrivateKey();
|
||||
const pub = C.getPublicKey(priv);
|
||||
const sig = C.sign(msg, priv);
|
||||
deepStrictEqual(sig.recoverPublicKey(msg).toRawBytes(), pub);
|
||||
const sig2 = C.Signature.fromCompact(sig.toCompactHex());
|
||||
throws(() => sig2.recoverPublicKey(msg));
|
||||
const sig3 = sig2.addRecoveryBit(sig.recovery);
|
||||
deepStrictEqual(sig3.recoverPublicKey(msg).toRawBytes(), pub);
|
||||
}),
|
||||
{ numRuns: NUM_RUNS }
|
||||
)
|
||||
);
|
||||
should('Signature.normalizeS', () =>
|
||||
fc.assert(
|
||||
fc.property(fc.hexaString({ minLength: 64, maxLength: 64 }), (msg) => {
|
||||
const priv = C.utils.randomPrivateKey();
|
||||
const pub = C.getPublicKey(priv);
|
||||
const sig = C.sign(msg, priv);
|
||||
const sig2 = sig.normalizeS();
|
||||
deepStrictEqual(sig2.hasHighS(), false);
|
||||
}),
|
||||
{ numRuns: NUM_RUNS }
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// NOTE: fails for ed, because of empty message. Since we convert it to scalar,
|
||||
// need to check what other implementations do. Empty message != new Uint8Array([0]), but what scalar should be in that case?
|
||||
// should('should not verify signature with wrong message', () => {
|
||||
|
||||
@@ -1,18 +1,14 @@
|
||||
import { bls12_381 } from '../lib/esm/bls12-381.js';
|
||||
import { describe, should } from 'micro-should';
|
||||
import { deepStrictEqual, notDeepStrictEqual, throws } from 'assert';
|
||||
import { sha512 } from '@noble/hashes/sha512';
|
||||
import * as fc from 'fast-check';
|
||||
import { readFileSync } from 'fs';
|
||||
import { describe, should } from 'micro-should';
|
||||
import { wNAF } from '../esm/abstract/curve.js';
|
||||
import { bytesToHex, utf8ToBytes } from '../esm/abstract/utils.js';
|
||||
import { hash_to_field } from '../esm/abstract/hash-to-curve.js';
|
||||
import { bls12_381 as bls } from '../esm/bls12-381.js';
|
||||
|
||||
import zkVectors from './bls12-381/zkcrypto/converted.json' assert { type: 'json' };
|
||||
import pairingVectors from './bls12-381/go_pairing_vectors/pairing.json' assert { type: 'json' };
|
||||
import { wNAF } from '../lib/esm/abstract/curve.js';
|
||||
const bls = bls12_381;
|
||||
const { Fp2 } = bls;
|
||||
const G1Point = bls.G1.ProjectivePoint;
|
||||
const G2Point = bls.G2.ProjectivePoint;
|
||||
const G1Aff = (x, y) => G1Point.fromAffine({ x, y });
|
||||
|
||||
const G2_VECTORS = readFileSync('./test/bls12-381/bls12-381-g2-test-vectors.txt', 'utf-8')
|
||||
.trim()
|
||||
.split('\n')
|
||||
@@ -28,7 +24,10 @@ const SCALAR_VECTORS = readFileSync('./test/bls12-381/bls12-381-scalar-test-vect
|
||||
const NUM_RUNS = Number(process.env.RUNS_COUNT || 10); // reduce to 1 to shorten test time
|
||||
fc.configureGlobal({ numRuns: NUM_RUNS });
|
||||
|
||||
// @ts-ignore
|
||||
const { Fp2 } = bls;
|
||||
const G1Point = bls.G1.ProjectivePoint;
|
||||
const G2Point = bls.G2.ProjectivePoint;
|
||||
const G1Aff = (x, y) => G1Point.fromAffine({ x, y });
|
||||
const CURVE_ORDER = bls.CURVE.r;
|
||||
|
||||
const FC_MSG = fc.hexaString({ minLength: 64, maxLength: 64 });
|
||||
@@ -851,20 +850,20 @@ describe('bls12-381/basic', () => {
|
||||
for (let vector of G2_VECTORS) {
|
||||
const [priv, msg, expected] = vector;
|
||||
const sig = bls.sign(msg, priv);
|
||||
deepStrictEqual(bls.utils.bytesToHex(sig), expected);
|
||||
deepStrictEqual(bytesToHex(sig), expected);
|
||||
}
|
||||
});
|
||||
should(`produce correct scalars (${SCALAR_VECTORS.length} vectors)`, () => {
|
||||
const options = {
|
||||
p: bls.CURVE.r,
|
||||
m: 1,
|
||||
expand: false,
|
||||
expand: undefined,
|
||||
};
|
||||
for (let vector of SCALAR_VECTORS) {
|
||||
const [okmAscii, expectedHex] = vector;
|
||||
const expected = BigInt('0x' + expectedHex);
|
||||
const okm = new Uint8Array(okmAscii.split('').map((c) => c.charCodeAt(0)));
|
||||
const scalars = bls.utils.hashToField(okm, 1, options);
|
||||
const okm = utf8ToBytes(okmAscii);
|
||||
const scalars = hash_to_field(okm, 1, Object.assign({}, bls.CURVE.htfDefaults, options));
|
||||
deepStrictEqual(scalars[0][0], expected);
|
||||
}
|
||||
});
|
||||
@@ -973,25 +972,25 @@ describe('hash-to-curve', () => {
|
||||
// Point G1
|
||||
const VECTORS_G1 = [
|
||||
{
|
||||
msg: bls.utils.stringToBytes(''),
|
||||
msg: utf8ToBytes(''),
|
||||
expected:
|
||||
'0576730ab036cbac1d95b38dca905586f28d0a59048db4e8778782d89bff856ddef89277ead5a21e2975c4a6e3d8c79e' +
|
||||
'1273e568bebf1864393c517f999b87c1eaa1b8432f95aea8160cd981b5b05d8cd4a7cf00103b6ef87f728e4b547dd7ae',
|
||||
},
|
||||
{
|
||||
msg: bls.utils.stringToBytes('abc'),
|
||||
msg: utf8ToBytes('abc'),
|
||||
expected:
|
||||
'061daf0cc00d8912dac1d4cf5a7c32fca97f8b3bf3f805121888e5eb89f77f9a9f406569027ac6d0e61b1229f42c43d6' +
|
||||
'0de1601e5ba02cb637c1d35266f5700acee9850796dc88e860d022d7b9e7e3dce5950952e97861e5bb16d215c87f030d',
|
||||
},
|
||||
{
|
||||
msg: bls.utils.stringToBytes('abcdef0123456789'),
|
||||
msg: utf8ToBytes('abcdef0123456789'),
|
||||
expected:
|
||||
'0fb3455436843e76079c7cf3dfef75e5a104dfe257a29a850c145568d500ad31ccfe79be9ae0ea31a722548070cf98cd' +
|
||||
'177989f7e2c751658df1b26943ee829d3ebcf131d8f805571712f3a7527ee5334ecff8a97fc2a50cea86f5e6212e9a57',
|
||||
},
|
||||
{
|
||||
msg: bls.utils.stringToBytes(
|
||||
msg: utf8ToBytes(
|
||||
'a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
|
||||
),
|
||||
expected:
|
||||
@@ -1002,7 +1001,7 @@ describe('hash-to-curve', () => {
|
||||
for (let i = 0; i < VECTORS_G1.length; i++) {
|
||||
const t = VECTORS_G1[i];
|
||||
should(`hashToCurve/G1 Killic (${i})`, () => {
|
||||
const p = bls.hashToCurve.G1.hashToCurve(t.msg, {
|
||||
const p = bls.G1.hashToCurve(t.msg, {
|
||||
DST: 'BLS12381G1_XMD:SHA-256_SSWU_RO_TESTGEN',
|
||||
});
|
||||
deepStrictEqual(p.toHex(false), t.expected);
|
||||
@@ -1011,25 +1010,25 @@ describe('hash-to-curve', () => {
|
||||
|
||||
const VECTORS_ENCODE_G1 = [
|
||||
{
|
||||
msg: bls.utils.stringToBytes(''),
|
||||
msg: utf8ToBytes(''),
|
||||
expected:
|
||||
'1223effdbb2d38152495a864d78eee14cb0992d89a241707abb03819a91a6d2fd65854ab9a69e9aacb0cbebfd490732c' +
|
||||
'0f925d61e0b235ecd945cbf0309291878df0d06e5d80d6b84aa4ff3e00633b26f9a7cb3523ef737d90e6d71e8b98b2d5',
|
||||
},
|
||||
{
|
||||
msg: bls.utils.stringToBytes('abc'),
|
||||
msg: utf8ToBytes('abc'),
|
||||
expected:
|
||||
'179d3fd0b4fb1da43aad06cea1fb3f828806ddb1b1fa9424b1e3944dfdbab6e763c42636404017da03099af0dcca0fd6' +
|
||||
'0d037cb1c6d495c0f5f22b061d23f1be3d7fe64d3c6820cfcd99b6b36fa69f7b4c1f4addba2ae7aa46fb25901ab483e4',
|
||||
},
|
||||
{
|
||||
msg: bls.utils.stringToBytes('abcdef0123456789'),
|
||||
msg: utf8ToBytes('abcdef0123456789'),
|
||||
expected:
|
||||
'15aa66c77eded1209db694e8b1ba49daf8b686733afaa7b68c683d0b01788dfb0617a2e2d04c0856db4981921d3004af' +
|
||||
'0952bb2f61739dd1d201dd0a79d74cda3285403d47655ee886afe860593a8a4e51c5b77a22d2133e3a4280eaaaa8b788',
|
||||
},
|
||||
{
|
||||
msg: bls.utils.stringToBytes(
|
||||
msg: utf8ToBytes(
|
||||
'a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
|
||||
),
|
||||
expected:
|
||||
@@ -1040,7 +1039,7 @@ describe('hash-to-curve', () => {
|
||||
for (let i = 0; i < VECTORS_ENCODE_G1.length; i++) {
|
||||
const t = VECTORS_ENCODE_G1[i];
|
||||
should(`hashToCurve/G1 (Killic, encodeToCurve) (${i})`, () => {
|
||||
const p = bls.hashToCurve.G1.encodeToCurve(t.msg, {
|
||||
const p = bls.G1.encodeToCurve(t.msg, {
|
||||
DST: 'BLS12381G1_XMD:SHA-256_SSWU_NU_TESTGEN',
|
||||
});
|
||||
deepStrictEqual(p.toHex(false), t.expected);
|
||||
@@ -1049,7 +1048,7 @@ describe('hash-to-curve', () => {
|
||||
// Point G2
|
||||
const VECTORS_G2 = [
|
||||
{
|
||||
msg: bls.utils.stringToBytes(''),
|
||||
msg: utf8ToBytes(''),
|
||||
expected:
|
||||
'0fbdae26f9f9586a46d4b0b70390d09064ef2afe5c99348438a3c7d9756471e015cb534204c1b6824617a85024c772dc' +
|
||||
'0a650bd36ae7455cb3fe5d8bb1310594551456f5c6593aec9ee0c03d2f6cb693bd2c5e99d4e23cbaec767609314f51d3' +
|
||||
@@ -1057,7 +1056,7 @@ describe('hash-to-curve', () => {
|
||||
'0d8d49e7737d8f9fc5cef7c4b8817633103faf2613016cb86a1f3fc29968fe2413e232d9208d2d74a89bf7a48ac36f83',
|
||||
},
|
||||
{
|
||||
msg: bls.utils.stringToBytes('abc'),
|
||||
msg: utf8ToBytes('abc'),
|
||||
expected:
|
||||
'03578447618463deb106b60e609c6f7cc446dc6035f84a72801ba17c94cd800583b493b948eff0033f09086fdd7f6175' +
|
||||
'1953ce6d4267939c7360756d9cca8eb34aac4633ef35369a7dc249445069888e7d1b3f9d2e75fbd468fbcbba7110ea02' +
|
||||
@@ -1065,7 +1064,7 @@ describe('hash-to-curve', () => {
|
||||
'0882ab045b8fe4d7d557ebb59a63a35ac9f3d312581b509af0f8eaa2960cbc5e1e36bb969b6e22980b5cbdd0787fcf4e',
|
||||
},
|
||||
{
|
||||
msg: bls.utils.stringToBytes('abcdef0123456789'),
|
||||
msg: utf8ToBytes('abcdef0123456789'),
|
||||
expected:
|
||||
'195fad48982e186ce3c5c82133aefc9b26d55979b6f530992a8849d4263ec5d57f7a181553c8799bcc83da44847bdc8d' +
|
||||
'17b461fc3b96a30c2408958cbfa5f5927b6063a8ad199d5ebf2d7cdeffa9c20c85487204804fab53f950b2f87db365aa' +
|
||||
@@ -1073,7 +1072,7 @@ describe('hash-to-curve', () => {
|
||||
'174a3473a3af2d0302b9065e895ca4adba4ece6ce0b41148ba597001abb152f852dd9a96fb45c9de0a43d944746f833e',
|
||||
},
|
||||
{
|
||||
msg: bls.utils.stringToBytes(
|
||||
msg: utf8ToBytes(
|
||||
'a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
|
||||
),
|
||||
expected:
|
||||
@@ -1086,7 +1085,7 @@ describe('hash-to-curve', () => {
|
||||
for (let i = 0; i < VECTORS_G2.length; i++) {
|
||||
const t = VECTORS_G2[i];
|
||||
should(`hashToCurve/G2 Killic (${i})`, () => {
|
||||
const p = bls.hashToCurve.G2.hashToCurve(t.msg, {
|
||||
const p = bls.G2.hashToCurve(t.msg, {
|
||||
DST: 'BLS12381G2_XMD:SHA-256_SSWU_RO_TESTGEN',
|
||||
});
|
||||
deepStrictEqual(p.toHex(false), t.expected);
|
||||
@@ -1095,7 +1094,7 @@ describe('hash-to-curve', () => {
|
||||
|
||||
const VECTORS_ENCODE_G2 = [
|
||||
{
|
||||
msg: bls.utils.stringToBytes(''),
|
||||
msg: utf8ToBytes(''),
|
||||
expected:
|
||||
'0d4333b77becbf9f9dfa3ca928002233d1ecc854b1447e5a71f751c9042d000f42db91c1d6649a5e0ad22bd7bf7398b8' +
|
||||
'027e4bfada0b47f9f07e04aec463c7371e68f2fd0c738cd517932ea3801a35acf09db018deda57387b0f270f7a219e4d' +
|
||||
@@ -1103,7 +1102,7 @@ describe('hash-to-curve', () => {
|
||||
'053674cba9ef516ddc218fedb37324e6c47de27f88ab7ef123b006127d738293c0277187f7e2f80a299a24d84ed03da7',
|
||||
},
|
||||
{
|
||||
msg: bls.utils.stringToBytes('abc'),
|
||||
msg: utf8ToBytes('abc'),
|
||||
expected:
|
||||
'18f0f87b40af67c056915dbaf48534c592524e82c1c2b50c3734d02c0172c80df780a60b5683759298a3303c5d942778' +
|
||||
'09349f1cb5b2e55489dcd45a38545343451cc30a1681c57acd4fb0a6db125f8352c09f4a67eb7d1d8242cb7d3405f97b' +
|
||||
@@ -1111,7 +1110,7 @@ describe('hash-to-curve', () => {
|
||||
'02f2d9deb2c7742512f5b8230bf0fd83ea42279d7d39779543c1a43b61c885982b611f6a7a24b514995e8a098496b811',
|
||||
},
|
||||
{
|
||||
msg: bls.utils.stringToBytes('abcdef0123456789'),
|
||||
msg: utf8ToBytes('abcdef0123456789'),
|
||||
expected:
|
||||
'19808ec5930a53c7cf5912ccce1cc33f1b3dcff24a53ce1cc4cba41fd6996dbed4843ccdd2eaf6a0cd801e562718d163' +
|
||||
'149fe43777d34f0d25430dea463889bd9393bdfb4932946db23671727081c629ebb98a89604f3433fba1c67d356a4af7' +
|
||||
@@ -1119,7 +1118,7 @@ describe('hash-to-curve', () => {
|
||||
'04c0d6793a766233b2982087b5f4a254f261003ccb3262ea7c50903eecef3e871d1502c293f9e063d7d293f6384f4551',
|
||||
},
|
||||
{
|
||||
msg: bls.utils.stringToBytes(
|
||||
msg: utf8ToBytes(
|
||||
'a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
|
||||
),
|
||||
expected:
|
||||
@@ -1132,7 +1131,7 @@ describe('hash-to-curve', () => {
|
||||
for (let i = 0; i < VECTORS_ENCODE_G2.length; i++) {
|
||||
const t = VECTORS_ENCODE_G2[i];
|
||||
should(`hashToCurve/G2 (Killic, encodeToCurve) (${i})`, () => {
|
||||
const p = bls.hashToCurve.G2.encodeToCurve(t.msg, {
|
||||
const p = bls.G2.encodeToCurve(t.msg, {
|
||||
DST: 'BLS12381G2_XMD:SHA-256_SSWU_NU_TESTGEN',
|
||||
});
|
||||
deepStrictEqual(p.toHex(false), t.expected);
|
||||
@@ -1265,7 +1264,7 @@ describe('bls12-381 deterministic', () => {
|
||||
should('Killic based/Pairing', () => {
|
||||
const t = bls.pairing(G1Point.BASE, G2Point.BASE);
|
||||
deepStrictEqual(
|
||||
bls.utils.bytesToHex(Fp12.toBytes(t)),
|
||||
bytesToHex(Fp12.toBytes(t)),
|
||||
killicHex([
|
||||
'0f41e58663bf08cf068672cbd01a7ec73baca4d72ca93544deff686bfd6df543d48eaa24afe47e1efde449383b676631',
|
||||
'04c581234d086a9902249b64728ffd21a189e87935a954051c7cdba7b3872629a4fafc05066245cb9108f0242d0fe3ef',
|
||||
@@ -1287,7 +1286,7 @@ describe('bls12-381 deterministic', () => {
|
||||
let p2 = G2Point.BASE;
|
||||
for (let v of pairingVectors) {
|
||||
deepStrictEqual(
|
||||
bls.utils.bytesToHex(Fp12.toBytes(bls.pairing(p1, p2))),
|
||||
bytesToHex(Fp12.toBytes(bls.pairing(p1, p2))),
|
||||
// Reverse order
|
||||
v.match(/.{96}/g).reverse().join('')
|
||||
);
|
||||
|
||||
303
test/ed25519-addons.test.js
Normal file
303
test/ed25519-addons.test.js
Normal file
@@ -0,0 +1,303 @@
|
||||
import { sha512 } from '@noble/hashes/sha512';
|
||||
import { hexToBytes, bytesToHex, randomBytes } from '@noble/hashes/utils';
|
||||
import { deepStrictEqual, strictEqual, throws } from 'assert';
|
||||
import { describe, should } from 'micro-should';
|
||||
import { bytesToNumberLE, numberToBytesLE } from '../esm/abstract/utils.js';
|
||||
import { default as x25519vectors } from './wycheproof/x25519_test.json' assert { type: 'json' };
|
||||
import { ed25519ctx, ed25519ph, RistrettoPoint, x25519 } from '../esm/ed25519.js';
|
||||
|
||||
// const ed = ed25519;
|
||||
const hex = bytesToHex;
|
||||
// const Point = ed.ExtendedPoint;
|
||||
|
||||
const VECTORS_RFC8032_CTX = [
|
||||
{
|
||||
secretKey: '0305334e381af78f141cb666f6199f57bc3495335a256a95bd2a55bf546663f6',
|
||||
publicKey: 'dfc9425e4f968f7f0c29f0259cf5f9aed6851c2bb4ad8bfb860cfee0ab248292',
|
||||
message: 'f726936d19c800494e3fdaff20b276a8',
|
||||
context: '666f6f',
|
||||
signature:
|
||||
'55a4cc2f70a54e04288c5f4cd1e45a7b' +
|
||||
'b520b36292911876cada7323198dd87a' +
|
||||
'8b36950b95130022907a7fb7c4e9b2d5' +
|
||||
'f6cca685a587b4b21f4b888e4e7edb0d',
|
||||
},
|
||||
{
|
||||
secretKey: '0305334e381af78f141cb666f6199f57bc3495335a256a95bd2a55bf546663f6',
|
||||
publicKey: 'dfc9425e4f968f7f0c29f0259cf5f9aed6851c2bb4ad8bfb860cfee0ab248292',
|
||||
message: 'f726936d19c800494e3fdaff20b276a8',
|
||||
context: '626172',
|
||||
signature:
|
||||
'fc60d5872fc46b3aa69f8b5b4351d580' +
|
||||
'8f92bcc044606db097abab6dbcb1aee3' +
|
||||
'216c48e8b3b66431b5b186d1d28f8ee1' +
|
||||
'5a5ca2df6668346291c2043d4eb3e90d',
|
||||
},
|
||||
{
|
||||
secretKey: '0305334e381af78f141cb666f6199f57bc3495335a256a95bd2a55bf546663f6',
|
||||
publicKey: 'dfc9425e4f968f7f0c29f0259cf5f9aed6851c2bb4ad8bfb860cfee0ab248292',
|
||||
message: '508e9e6882b979fea900f62adceaca35',
|
||||
context: '666f6f',
|
||||
signature:
|
||||
'8b70c1cc8310e1de20ac53ce28ae6e72' +
|
||||
'07f33c3295e03bb5c0732a1d20dc6490' +
|
||||
'8922a8b052cf99b7c4fe107a5abb5b2c' +
|
||||
'4085ae75890d02df26269d8945f84b0b',
|
||||
},
|
||||
{
|
||||
secretKey: 'ab9c2853ce297ddab85c993b3ae14bcad39b2c682beabc27d6d4eb20711d6560',
|
||||
publicKey: '0f1d1274943b91415889152e893d80e93275a1fc0b65fd71b4b0dda10ad7d772',
|
||||
message: 'f726936d19c800494e3fdaff20b276a8',
|
||||
context: '666f6f',
|
||||
signature:
|
||||
'21655b5f1aa965996b3f97b3c849eafb' +
|
||||
'a922a0a62992f73b3d1b73106a84ad85' +
|
||||
'e9b86a7b6005ea868337ff2d20a7f5fb' +
|
||||
'd4cd10b0be49a68da2b2e0dc0ad8960f',
|
||||
},
|
||||
];
|
||||
|
||||
describe('RFC8032ctx', () => {
|
||||
for (let i = 0; i < VECTORS_RFC8032_CTX.length; i++) {
|
||||
const v = VECTORS_RFC8032_CTX[i];
|
||||
should(`${i}`, () => {
|
||||
deepStrictEqual(hex(ed25519ctx.getPublicKey(v.secretKey)), v.publicKey);
|
||||
deepStrictEqual(hex(ed25519ctx.sign(v.message, v.secretKey, v.context)), v.signature);
|
||||
deepStrictEqual(ed25519ctx.verify(v.signature, v.message, v.publicKey, v.context), true);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const VECTORS_RFC8032_PH = [
|
||||
{
|
||||
secretKey: '833fe62409237b9d62ec77587520911e9a759cec1d19755b7da901b96dca3d42',
|
||||
publicKey: 'ec172b93ad5e563bf4932c70e1245034c35467ef2efd4d64ebf819683467e2bf',
|
||||
message: '616263',
|
||||
signature:
|
||||
'98a70222f0b8121aa9d30f813d683f80' +
|
||||
'9e462b469c7ff87639499bb94e6dae41' +
|
||||
'31f85042463c2a355a2003d062adf5aa' +
|
||||
'a10b8c61e636062aaad11c2a26083406',
|
||||
},
|
||||
];
|
||||
|
||||
describe('RFC8032ph', () => {
|
||||
for (let i = 0; i < VECTORS_RFC8032_PH.length; i++) {
|
||||
const v = VECTORS_RFC8032_PH[i];
|
||||
should(`${i}`, () => {
|
||||
deepStrictEqual(hex(ed25519ph.getPublicKey(v.secretKey)), v.publicKey);
|
||||
deepStrictEqual(hex(ed25519ph.sign(v.message, v.secretKey)), v.signature);
|
||||
deepStrictEqual(ed25519ph.verify(v.signature, v.message, v.publicKey), true);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// x25519
|
||||
should('X25519 base point', () => {
|
||||
const { y } = ed25519ph.ExtendedPoint.BASE;
|
||||
const { Fp } = ed25519ph.CURVE;
|
||||
const u = Fp.create((y + 1n) * Fp.inv(1n - y));
|
||||
deepStrictEqual(numberToBytesLE(u, 32), x25519.GuBytes);
|
||||
});
|
||||
|
||||
describe('RFC7748', () => {
|
||||
const rfc7748Mul = [
|
||||
{
|
||||
scalar: 'a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4',
|
||||
u: 'e6db6867583030db3594c1a424b15f7c726624ec26b3353b10a903a6d0ab1c4c',
|
||||
outputU: 'c3da55379de9c6908e94ea4df28d084f32eccf03491c71f754b4075577a28552',
|
||||
},
|
||||
{
|
||||
scalar: '4b66e9d4d1b4673c5ad22691957d6af5c11b6421e0ea01d42ca4169e7918ba0d',
|
||||
u: 'e5210f12786811d3f4b7959d0538ae2c31dbe7106fc03c3efc4cd549c715a493',
|
||||
outputU: '95cbde9476e8907d7aade45cb4b873f88b595a68799fa152e6f8f7647aac7957',
|
||||
},
|
||||
];
|
||||
for (let i = 0; i < rfc7748Mul.length; i++) {
|
||||
const v = rfc7748Mul[i];
|
||||
should(`scalarMult (${i})`, () => {
|
||||
deepStrictEqual(hex(x25519.scalarMult(v.scalar, v.u)), v.outputU);
|
||||
});
|
||||
}
|
||||
|
||||
const rfc7748Iter = [
|
||||
{ scalar: '422c8e7a6227d7bca1350b3e2bb7279f7897b87bb6854b783c60e80311ae3079', iters: 1 },
|
||||
{ scalar: '684cf59ba83309552800ef566f2f4d3c1c3887c49360e3875f2eb94d99532c51', iters: 1000 },
|
||||
// { scalar: '7c3911e0ab2586fd864497297e575e6f3bc601c0883c30df5f4dd2d24f665424', iters: 1000000 },
|
||||
];
|
||||
for (let i = 0; i < rfc7748Iter.length; i++) {
|
||||
const { scalar, iters } = rfc7748Iter[i];
|
||||
should(`scalarMult iteration (${i})`, () => {
|
||||
let k = x25519.GuBytes;
|
||||
for (let i = 0, u = k; i < iters; i++) [k, u] = [x25519.scalarMult(k, u), k];
|
||||
deepStrictEqual(hex(k), scalar);
|
||||
});
|
||||
}
|
||||
|
||||
should('getSharedKey', () => {
|
||||
const alicePrivate = '77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a';
|
||||
const alicePublic = '8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a';
|
||||
const bobPrivate = '5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb';
|
||||
const bobPublic = 'de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f';
|
||||
const shared = '4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742';
|
||||
deepStrictEqual(alicePublic, hex(x25519.getPublicKey(alicePrivate)));
|
||||
deepStrictEqual(bobPublic, hex(x25519.getPublicKey(bobPrivate)));
|
||||
deepStrictEqual(hex(x25519.scalarMult(alicePrivate, bobPublic)), shared);
|
||||
deepStrictEqual(hex(x25519.scalarMult(bobPrivate, alicePublic)), shared);
|
||||
});
|
||||
});
|
||||
describe('Wycheproof', () => {
|
||||
const group = x25519vectors.testGroups[0];
|
||||
should(`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.private, v.public));
|
||||
deepStrictEqual(shared, v.shared, comment);
|
||||
} catch (e) {
|
||||
// We are more strict
|
||||
if (e.message.includes('Expected valid scalar')) return;
|
||||
if (e.message.includes('Invalid private or public key received')) return;
|
||||
throw e;
|
||||
}
|
||||
} else if (v.result === 'invalid') {
|
||||
let failed = false;
|
||||
try {
|
||||
x25519.scalarMult(v.private, v.public);
|
||||
} catch (error) {
|
||||
failed = true;
|
||||
}
|
||||
deepStrictEqual(failed, true, comment);
|
||||
} else throw new Error('unknown test result');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function utf8ToBytes(str) {
|
||||
if (typeof str !== 'string') {
|
||||
throw new Error(`utf8ToBytes expected string, got ${typeof str}`);
|
||||
}
|
||||
return new TextEncoder().encode(str);
|
||||
}
|
||||
|
||||
describe('ristretto255', () => {
|
||||
should('follow the byte encodings of small multiples', () => {
|
||||
const encodingsOfSmallMultiples = [
|
||||
// This is the identity point
|
||||
'0000000000000000000000000000000000000000000000000000000000000000',
|
||||
// This is the basepoint
|
||||
'e2f2ae0a6abc4e71a884a961c500515f58e30b6aa582dd8db6a65945e08d2d76',
|
||||
// These are small multiples of the basepoint
|
||||
'6a493210f7499cd17fecb510ae0cea23a110e8d5b901f8acadd3095c73a3b919',
|
||||
'94741f5d5d52755ece4f23f044ee27d5d1ea1e2bd196b462166b16152a9d0259',
|
||||
'da80862773358b466ffadfe0b3293ab3d9fd53c5ea6c955358f568322daf6a57',
|
||||
'e882b131016b52c1d3337080187cf768423efccbb517bb495ab812c4160ff44e',
|
||||
'f64746d3c92b13050ed8d80236a7f0007c3b3f962f5ba793d19a601ebb1df403',
|
||||
'44f53520926ec81fbd5a387845beb7df85a96a24ece18738bdcfa6a7822a176d',
|
||||
'903293d8f2287ebe10e2374dc1a53e0bc887e592699f02d077d5263cdd55601c',
|
||||
'02622ace8f7303a31cafc63f8fc48fdc16e1c8c8d234b2f0d6685282a9076031',
|
||||
'20706fd788b2720a1ed2a5dad4952b01f413bcf0e7564de8cdc816689e2db95f',
|
||||
'bce83f8ba5dd2fa572864c24ba1810f9522bc6004afe95877ac73241cafdab42',
|
||||
'e4549ee16b9aa03099ca208c67adafcafa4c3f3e4e5303de6026e3ca8ff84460',
|
||||
'aa52e000df2e16f55fb1032fc33bc42742dad6bd5a8fc0be0167436c5948501f',
|
||||
'46376b80f409b29dc2b5f6f0c52591990896e5716f41477cd30085ab7f10301e',
|
||||
'e0c418f7c8d9c4cdd7395b93ea124f3ad99021bb681dfc3302a9d99a2e53e64e',
|
||||
];
|
||||
let B = RistrettoPoint.BASE;
|
||||
let P = RistrettoPoint.ZERO;
|
||||
for (const encoded of encodingsOfSmallMultiples) {
|
||||
deepStrictEqual(P.toHex(), encoded);
|
||||
deepStrictEqual(RistrettoPoint.fromHex(encoded).toHex(), encoded);
|
||||
P = P.add(B);
|
||||
}
|
||||
});
|
||||
should('not convert bad bytes encoding', () => {
|
||||
const badEncodings = [
|
||||
// These are all bad because they're non-canonical field encodings.
|
||||
'00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff',
|
||||
'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f',
|
||||
'f3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f',
|
||||
'edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f',
|
||||
// These are all bad because they're negative field elements.
|
||||
'0100000000000000000000000000000000000000000000000000000000000000',
|
||||
'01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f',
|
||||
'ed57ffd8c914fb201471d1c3d245ce3c746fcbe63a3679d51b6a516ebebe0e20',
|
||||
'c34c4e1826e5d403b78e246e88aa051c36ccf0aafebffe137d148a2bf9104562',
|
||||
'c940e5a4404157cfb1628b108db051a8d439e1a421394ec4ebccb9ec92a8ac78',
|
||||
'47cfc5497c53dc8e61c91d17fd626ffb1c49e2bca94eed052281b510b1117a24',
|
||||
'f1c6165d33367351b0da8f6e4511010c68174a03b6581212c71c0e1d026c3c72',
|
||||
'87260f7a2f12495118360f02c26a470f450dadf34a413d21042b43b9d93e1309',
|
||||
// These are all bad because they give a nonsquare x².
|
||||
'26948d35ca62e643e26a83177332e6b6afeb9d08e4268b650f1f5bbd8d81d371',
|
||||
'4eac077a713c57b4f4397629a4145982c661f48044dd3f96427d40b147d9742f',
|
||||
'de6a7b00deadc788eb6b6c8d20c0ae96c2f2019078fa604fee5b87d6e989ad7b',
|
||||
'bcab477be20861e01e4a0e295284146a510150d9817763caf1a6f4b422d67042',
|
||||
'2a292df7e32cababbd9de088d1d1abec9fc0440f637ed2fba145094dc14bea08',
|
||||
'f4a9e534fc0d216c44b218fa0c42d99635a0127ee2e53c712f70609649fdff22',
|
||||
'8268436f8c4126196cf64b3c7ddbda90746a378625f9813dd9b8457077256731',
|
||||
'2810e5cbc2cc4d4eece54f61c6f69758e289aa7ab440b3cbeaa21995c2f4232b',
|
||||
// These are all bad because they give a negative xy value.
|
||||
'3eb858e78f5a7254d8c9731174a94f76755fd3941c0ac93735c07ba14579630e',
|
||||
'a45fdc55c76448c049a1ab33f17023edfb2be3581e9c7aade8a6125215e04220',
|
||||
'd483fe813c6ba647ebbfd3ec41adca1c6130c2beeee9d9bf065c8d151c5f396e',
|
||||
'8a2e1d30050198c65a54483123960ccc38aef6848e1ec8f5f780e8523769ba32',
|
||||
'32888462f8b486c68ad7dd9610be5192bbeaf3b443951ac1a8118419d9fa097b',
|
||||
'227142501b9d4355ccba290404bde41575b037693cef1f438c47f8fbf35d1165',
|
||||
'5c37cc491da847cfeb9281d407efc41e15144c876e0170b499a96a22ed31e01e',
|
||||
'445425117cb8c90edcbc7c1cc0e74f747f2c1efa5630a967c64f287792a48a4b',
|
||||
// This is s = -1, which causes y = 0.
|
||||
'ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f',
|
||||
];
|
||||
for (const badBytes of badEncodings) {
|
||||
const b = hexToBytes(badBytes);
|
||||
throws(() => RistrettoPoint.fromHex(b), badBytes);
|
||||
}
|
||||
});
|
||||
should('create right points from uniform hash', () => {
|
||||
const labels = [
|
||||
'Ristretto is traditionally a short shot of espresso coffee',
|
||||
'made with the normal amount of ground coffee but extracted with',
|
||||
'about half the amount of water in the same amount of time',
|
||||
'by using a finer grind.',
|
||||
'This produces a concentrated shot of coffee per volume.',
|
||||
'Just pulling a normal shot short will produce a weaker shot',
|
||||
'and is not a Ristretto as some believe.',
|
||||
];
|
||||
const encodedHashToPoints = [
|
||||
'3066f82a1a747d45120d1740f14358531a8f04bbffe6a819f86dfe50f44a0a46',
|
||||
'f26e5b6f7d362d2d2a94c5d0e7602cb4773c95a2e5c31a64f133189fa76ed61b',
|
||||
'006ccd2a9e6867e6a2c5cea83d3302cc9de128dd2a9a57dd8ee7b9d7ffe02826',
|
||||
'f8f0c87cf237953c5890aec3998169005dae3eca1fbb04548c635953c817f92a',
|
||||
'ae81e7dedf20a497e10c304a765c1767a42d6e06029758d2d7e8ef7cc4c41179',
|
||||
'e2705652ff9f5e44d3e841bf1c251cf7dddb77d140870d1ab2ed64f1a9ce8628',
|
||||
'80bd07262511cdde4863f8a7434cef696750681cb9510eea557088f76d9e5065',
|
||||
];
|
||||
|
||||
for (let i = 0; i < labels.length; i++) {
|
||||
const hash = sha512(utf8ToBytes(labels[i]));
|
||||
const point = RistrettoPoint.hashToCurve(hash);
|
||||
deepStrictEqual(point.toHex(), encodedHashToPoints[i]);
|
||||
}
|
||||
});
|
||||
should('have proper equality testing', () => {
|
||||
const MAX_255B = BigInt('0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff');
|
||||
const bytes255ToNumberLE = (bytes) =>
|
||||
ed25519ctx.CURVE.Fp.create(bytesToNumberLE(bytes) & MAX_255B);
|
||||
|
||||
const priv = new Uint8Array([
|
||||
198, 101, 65, 165, 93, 120, 37, 238, 16, 133, 10, 35, 253, 243, 161, 246, 229, 135, 12, 137,
|
||||
202, 114, 222, 139, 146, 123, 4, 125, 152, 173, 1, 7,
|
||||
]);
|
||||
const pub = RistrettoPoint.BASE.multiply(bytes255ToNumberLE(priv));
|
||||
deepStrictEqual(pub.equals(RistrettoPoint.ZERO), false);
|
||||
});
|
||||
});
|
||||
|
||||
// ESM is broken.
|
||||
import url from 'url';
|
||||
import { assert } from 'console';
|
||||
if (import.meta.url === url.pathToFileURL(process.argv[1]).href) {
|
||||
should.run();
|
||||
}
|
||||
1
test/ed25519.helpers.js
Normal file
1
test/ed25519.helpers.js
Normal file
@@ -0,0 +1 @@
|
||||
export { ed25519, ED25519_TORSION_SUBGROUP } from '../esm/ed25519.js';
|
||||
@@ -1,21 +1,11 @@
|
||||
import { deepEqual, deepStrictEqual, strictEqual, throws } from 'assert';
|
||||
import { describe, should } from 'micro-should';
|
||||
import * as fc from 'fast-check';
|
||||
import {
|
||||
ed25519,
|
||||
ed25519ctx,
|
||||
ed25519ph,
|
||||
x25519,
|
||||
RistrettoPoint,
|
||||
ED25519_TORSION_SUBGROUP,
|
||||
} from '../lib/esm/ed25519.js';
|
||||
import { deepStrictEqual, strictEqual, throws } from 'assert';
|
||||
import { readFileSync } from 'fs';
|
||||
import { default as zip215 } from './ed25519/zip215.json' assert { type: 'json' };
|
||||
import { hexToBytes, bytesToHex, randomBytes } from '@noble/hashes/utils';
|
||||
import { numberToBytesLE } from '../lib/esm/abstract/utils.js';
|
||||
import { sha512 } from '@noble/hashes/sha512';
|
||||
import * as fc from 'fast-check';
|
||||
import { describe, should } from 'micro-should';
|
||||
import { ed25519, ED25519_TORSION_SUBGROUP } from './ed25519.helpers.js';
|
||||
import { default as ed25519vectors } from './wycheproof/eddsa_test.json' assert { type: 'json' };
|
||||
import { default as x25519vectors } from './wycheproof/x25519_test.json' assert { type: 'json' };
|
||||
import { default as zip215 } from './ed25519/zip215.json' assert { type: 'json' };
|
||||
|
||||
describe('ed25519', () => {
|
||||
const ed = ed25519;
|
||||
@@ -292,104 +282,6 @@ describe('ed25519', () => {
|
||||
// // const signature = await ristretto25519.sign(MESSAGE, PRIVATE_KEY);
|
||||
// // expect(await ristretto25519.verify(signature, WRONG_MESSAGE, publicKey)).toBe(false);
|
||||
// // });
|
||||
should('ristretto255/should follow the byte encodings of small multiples', () => {
|
||||
const encodingsOfSmallMultiples = [
|
||||
// This is the identity point
|
||||
'0000000000000000000000000000000000000000000000000000000000000000',
|
||||
// This is the basepoint
|
||||
'e2f2ae0a6abc4e71a884a961c500515f58e30b6aa582dd8db6a65945e08d2d76',
|
||||
// These are small multiples of the basepoint
|
||||
'6a493210f7499cd17fecb510ae0cea23a110e8d5b901f8acadd3095c73a3b919',
|
||||
'94741f5d5d52755ece4f23f044ee27d5d1ea1e2bd196b462166b16152a9d0259',
|
||||
'da80862773358b466ffadfe0b3293ab3d9fd53c5ea6c955358f568322daf6a57',
|
||||
'e882b131016b52c1d3337080187cf768423efccbb517bb495ab812c4160ff44e',
|
||||
'f64746d3c92b13050ed8d80236a7f0007c3b3f962f5ba793d19a601ebb1df403',
|
||||
'44f53520926ec81fbd5a387845beb7df85a96a24ece18738bdcfa6a7822a176d',
|
||||
'903293d8f2287ebe10e2374dc1a53e0bc887e592699f02d077d5263cdd55601c',
|
||||
'02622ace8f7303a31cafc63f8fc48fdc16e1c8c8d234b2f0d6685282a9076031',
|
||||
'20706fd788b2720a1ed2a5dad4952b01f413bcf0e7564de8cdc816689e2db95f',
|
||||
'bce83f8ba5dd2fa572864c24ba1810f9522bc6004afe95877ac73241cafdab42',
|
||||
'e4549ee16b9aa03099ca208c67adafcafa4c3f3e4e5303de6026e3ca8ff84460',
|
||||
'aa52e000df2e16f55fb1032fc33bc42742dad6bd5a8fc0be0167436c5948501f',
|
||||
'46376b80f409b29dc2b5f6f0c52591990896e5716f41477cd30085ab7f10301e',
|
||||
'e0c418f7c8d9c4cdd7395b93ea124f3ad99021bb681dfc3302a9d99a2e53e64e',
|
||||
];
|
||||
let B = RistrettoPoint.BASE;
|
||||
let P = RistrettoPoint.ZERO;
|
||||
for (const encoded of encodingsOfSmallMultiples) {
|
||||
deepStrictEqual(P.toHex(), encoded);
|
||||
deepStrictEqual(RistrettoPoint.fromHex(encoded).toHex(), encoded);
|
||||
P = P.add(B);
|
||||
}
|
||||
});
|
||||
should('ristretto255/should not convert bad bytes encoding', () => {
|
||||
const badEncodings = [
|
||||
// These are all bad because they're non-canonical field encodings.
|
||||
'00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff',
|
||||
'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f',
|
||||
'f3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f',
|
||||
'edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f',
|
||||
// These are all bad because they're negative field elements.
|
||||
'0100000000000000000000000000000000000000000000000000000000000000',
|
||||
'01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f',
|
||||
'ed57ffd8c914fb201471d1c3d245ce3c746fcbe63a3679d51b6a516ebebe0e20',
|
||||
'c34c4e1826e5d403b78e246e88aa051c36ccf0aafebffe137d148a2bf9104562',
|
||||
'c940e5a4404157cfb1628b108db051a8d439e1a421394ec4ebccb9ec92a8ac78',
|
||||
'47cfc5497c53dc8e61c91d17fd626ffb1c49e2bca94eed052281b510b1117a24',
|
||||
'f1c6165d33367351b0da8f6e4511010c68174a03b6581212c71c0e1d026c3c72',
|
||||
'87260f7a2f12495118360f02c26a470f450dadf34a413d21042b43b9d93e1309',
|
||||
// These are all bad because they give a nonsquare x².
|
||||
'26948d35ca62e643e26a83177332e6b6afeb9d08e4268b650f1f5bbd8d81d371',
|
||||
'4eac077a713c57b4f4397629a4145982c661f48044dd3f96427d40b147d9742f',
|
||||
'de6a7b00deadc788eb6b6c8d20c0ae96c2f2019078fa604fee5b87d6e989ad7b',
|
||||
'bcab477be20861e01e4a0e295284146a510150d9817763caf1a6f4b422d67042',
|
||||
'2a292df7e32cababbd9de088d1d1abec9fc0440f637ed2fba145094dc14bea08',
|
||||
'f4a9e534fc0d216c44b218fa0c42d99635a0127ee2e53c712f70609649fdff22',
|
||||
'8268436f8c4126196cf64b3c7ddbda90746a378625f9813dd9b8457077256731',
|
||||
'2810e5cbc2cc4d4eece54f61c6f69758e289aa7ab440b3cbeaa21995c2f4232b',
|
||||
// These are all bad because they give a negative xy value.
|
||||
'3eb858e78f5a7254d8c9731174a94f76755fd3941c0ac93735c07ba14579630e',
|
||||
'a45fdc55c76448c049a1ab33f17023edfb2be3581e9c7aade8a6125215e04220',
|
||||
'd483fe813c6ba647ebbfd3ec41adca1c6130c2beeee9d9bf065c8d151c5f396e',
|
||||
'8a2e1d30050198c65a54483123960ccc38aef6848e1ec8f5f780e8523769ba32',
|
||||
'32888462f8b486c68ad7dd9610be5192bbeaf3b443951ac1a8118419d9fa097b',
|
||||
'227142501b9d4355ccba290404bde41575b037693cef1f438c47f8fbf35d1165',
|
||||
'5c37cc491da847cfeb9281d407efc41e15144c876e0170b499a96a22ed31e01e',
|
||||
'445425117cb8c90edcbc7c1cc0e74f747f2c1efa5630a967c64f287792a48a4b',
|
||||
// This is s = -1, which causes y = 0.
|
||||
'ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f',
|
||||
];
|
||||
for (const badBytes of badEncodings) {
|
||||
const b = hexToBytes(badBytes);
|
||||
throws(() => RistrettoPoint.fromHex(b), badBytes);
|
||||
}
|
||||
});
|
||||
should('ristretto255/should create right points from uniform hash', () => {
|
||||
const labels = [
|
||||
'Ristretto is traditionally a short shot of espresso coffee',
|
||||
'made with the normal amount of ground coffee but extracted with',
|
||||
'about half the amount of water in the same amount of time',
|
||||
'by using a finer grind.',
|
||||
'This produces a concentrated shot of coffee per volume.',
|
||||
'Just pulling a normal shot short will produce a weaker shot',
|
||||
'and is not a Ristretto as some believe.',
|
||||
];
|
||||
const encodedHashToPoints = [
|
||||
'3066f82a1a747d45120d1740f14358531a8f04bbffe6a819f86dfe50f44a0a46',
|
||||
'f26e5b6f7d362d2d2a94c5d0e7602cb4773c95a2e5c31a64f133189fa76ed61b',
|
||||
'006ccd2a9e6867e6a2c5cea83d3302cc9de128dd2a9a57dd8ee7b9d7ffe02826',
|
||||
'f8f0c87cf237953c5890aec3998169005dae3eca1fbb04548c635953c817f92a',
|
||||
'ae81e7dedf20a497e10c304a765c1767a42d6e06029758d2d7e8ef7cc4c41179',
|
||||
'e2705652ff9f5e44d3e841bf1c251cf7dddb77d140870d1ab2ed64f1a9ce8628',
|
||||
'80bd07262511cdde4863f8a7434cef696750681cb9510eea557088f76d9e5065',
|
||||
];
|
||||
|
||||
for (let i = 0; i < labels.length; i++) {
|
||||
const hash = sha512(utf8ToBytes(labels[i]));
|
||||
const point = RistrettoPoint.hashToCurve(hash);
|
||||
deepStrictEqual(point.toHex(), encodedHashToPoints[i]);
|
||||
}
|
||||
});
|
||||
|
||||
should('input immutability: sign/verify are immutable', () => {
|
||||
const privateKey = ed.utils.randomPrivateKey();
|
||||
@@ -432,51 +324,6 @@ describe('ed25519', () => {
|
||||
throws(() => ed.verify(sig, 'deadbeef', Point.BASE));
|
||||
});
|
||||
|
||||
const rfc7748Mul = [
|
||||
{
|
||||
scalar: 'a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4',
|
||||
u: 'e6db6867583030db3594c1a424b15f7c726624ec26b3353b10a903a6d0ab1c4c',
|
||||
outputU: 'c3da55379de9c6908e94ea4df28d084f32eccf03491c71f754b4075577a28552',
|
||||
},
|
||||
{
|
||||
scalar: '4b66e9d4d1b4673c5ad22691957d6af5c11b6421e0ea01d42ca4169e7918ba0d',
|
||||
u: 'e5210f12786811d3f4b7959d0538ae2c31dbe7106fc03c3efc4cd549c715a493',
|
||||
outputU: '95cbde9476e8907d7aade45cb4b873f88b595a68799fa152e6f8f7647aac7957',
|
||||
},
|
||||
];
|
||||
for (let i = 0; i < rfc7748Mul.length; i++) {
|
||||
const v = rfc7748Mul[i];
|
||||
should(`RFC7748: scalarMult (${i})`, () => {
|
||||
deepStrictEqual(hex(x25519.scalarMult(v.scalar, v.u)), v.outputU);
|
||||
});
|
||||
}
|
||||
|
||||
const rfc7748Iter = [
|
||||
{ scalar: '422c8e7a6227d7bca1350b3e2bb7279f7897b87bb6854b783c60e80311ae3079', iters: 1 },
|
||||
{ scalar: '684cf59ba83309552800ef566f2f4d3c1c3887c49360e3875f2eb94d99532c51', iters: 1000 },
|
||||
// { scalar: '7c3911e0ab2586fd864497297e575e6f3bc601c0883c30df5f4dd2d24f665424', iters: 1000000 },
|
||||
];
|
||||
for (let i = 0; i < rfc7748Iter.length; i++) {
|
||||
const { scalar, iters } = rfc7748Iter[i];
|
||||
should(`RFC7748: scalarMult iteration (${i})`, () => {
|
||||
let k = x25519.Gu;
|
||||
for (let i = 0, u = k; i < iters; i++) [k, u] = [x25519.scalarMult(k, u), k];
|
||||
deepStrictEqual(hex(k), scalar);
|
||||
});
|
||||
}
|
||||
|
||||
should('RFC7748 getSharedKey', () => {
|
||||
const alicePrivate = '77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a';
|
||||
const alicePublic = '8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a';
|
||||
const bobPrivate = '5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb';
|
||||
const bobPublic = 'de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f';
|
||||
const shared = '4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742';
|
||||
deepStrictEqual(alicePublic, hex(x25519.getPublicKey(alicePrivate)));
|
||||
deepStrictEqual(bobPublic, hex(x25519.getPublicKey(bobPrivate)));
|
||||
deepStrictEqual(hex(x25519.scalarMult(alicePrivate, bobPublic)), shared);
|
||||
deepStrictEqual(hex(x25519.scalarMult(bobPrivate, alicePublic)), shared);
|
||||
});
|
||||
|
||||
// should('X25519/getSharedSecret() should be commutative', () => {
|
||||
// for (let i = 0; i < 512; i++) {
|
||||
// const asec = ed.utils.randomPrivateKey();
|
||||
@@ -499,35 +346,6 @@ describe('ed25519', () => {
|
||||
// );
|
||||
// });
|
||||
|
||||
{
|
||||
const group = x25519vectors.testGroups[0];
|
||||
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.private, v.public));
|
||||
deepStrictEqual(shared, v.shared, comment);
|
||||
} catch (e) {
|
||||
// We are more strict
|
||||
if (e.message.includes('Expected valid scalar')) return;
|
||||
if (e.message.includes('Invalid private or public key received')) return;
|
||||
throw e;
|
||||
}
|
||||
} else if (v.result === 'invalid') {
|
||||
let failed = false;
|
||||
try {
|
||||
x25519.scalarMult(v.private, v.public);
|
||||
} catch (error) {
|
||||
failed = true;
|
||||
}
|
||||
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];
|
||||
@@ -559,91 +377,6 @@ describe('ed25519', () => {
|
||||
deepStrictEqual(ed.verify(signature, message, publicKey), true);
|
||||
});
|
||||
|
||||
const VECTORS_RFC8032_CTX = [
|
||||
{
|
||||
secretKey: '0305334e381af78f141cb666f6199f57bc3495335a256a95bd2a55bf546663f6',
|
||||
publicKey: 'dfc9425e4f968f7f0c29f0259cf5f9aed6851c2bb4ad8bfb860cfee0ab248292',
|
||||
message: 'f726936d19c800494e3fdaff20b276a8',
|
||||
context: '666f6f',
|
||||
signature:
|
||||
'55a4cc2f70a54e04288c5f4cd1e45a7b' +
|
||||
'b520b36292911876cada7323198dd87a' +
|
||||
'8b36950b95130022907a7fb7c4e9b2d5' +
|
||||
'f6cca685a587b4b21f4b888e4e7edb0d',
|
||||
},
|
||||
{
|
||||
secretKey: '0305334e381af78f141cb666f6199f57bc3495335a256a95bd2a55bf546663f6',
|
||||
publicKey: 'dfc9425e4f968f7f0c29f0259cf5f9aed6851c2bb4ad8bfb860cfee0ab248292',
|
||||
message: 'f726936d19c800494e3fdaff20b276a8',
|
||||
context: '626172',
|
||||
signature:
|
||||
'fc60d5872fc46b3aa69f8b5b4351d580' +
|
||||
'8f92bcc044606db097abab6dbcb1aee3' +
|
||||
'216c48e8b3b66431b5b186d1d28f8ee1' +
|
||||
'5a5ca2df6668346291c2043d4eb3e90d',
|
||||
},
|
||||
{
|
||||
secretKey: '0305334e381af78f141cb666f6199f57bc3495335a256a95bd2a55bf546663f6',
|
||||
publicKey: 'dfc9425e4f968f7f0c29f0259cf5f9aed6851c2bb4ad8bfb860cfee0ab248292',
|
||||
message: '508e9e6882b979fea900f62adceaca35',
|
||||
context: '666f6f',
|
||||
signature:
|
||||
'8b70c1cc8310e1de20ac53ce28ae6e72' +
|
||||
'07f33c3295e03bb5c0732a1d20dc6490' +
|
||||
'8922a8b052cf99b7c4fe107a5abb5b2c' +
|
||||
'4085ae75890d02df26269d8945f84b0b',
|
||||
},
|
||||
{
|
||||
secretKey: 'ab9c2853ce297ddab85c993b3ae14bcad39b2c682beabc27d6d4eb20711d6560',
|
||||
publicKey: '0f1d1274943b91415889152e893d80e93275a1fc0b65fd71b4b0dda10ad7d772',
|
||||
message: 'f726936d19c800494e3fdaff20b276a8',
|
||||
context: '666f6f',
|
||||
signature:
|
||||
'21655b5f1aa965996b3f97b3c849eafb' +
|
||||
'a922a0a62992f73b3d1b73106a84ad85' +
|
||||
'e9b86a7b6005ea868337ff2d20a7f5fb' +
|
||||
'd4cd10b0be49a68da2b2e0dc0ad8960f',
|
||||
},
|
||||
];
|
||||
|
||||
for (let i = 0; i < VECTORS_RFC8032_CTX.length; i++) {
|
||||
const v = VECTORS_RFC8032_CTX[i];
|
||||
should(`RFC8032ctx/${i}`, () => {
|
||||
deepStrictEqual(hex(ed25519ctx.getPublicKey(v.secretKey)), v.publicKey);
|
||||
deepStrictEqual(hex(ed25519ctx.sign(v.message, v.secretKey, v.context)), v.signature);
|
||||
deepStrictEqual(ed25519ctx.verify(v.signature, v.message, v.publicKey, v.context), true);
|
||||
});
|
||||
}
|
||||
|
||||
const VECTORS_RFC8032_PH = [
|
||||
{
|
||||
secretKey: '833fe62409237b9d62ec77587520911e9a759cec1d19755b7da901b96dca3d42',
|
||||
publicKey: 'ec172b93ad5e563bf4932c70e1245034c35467ef2efd4d64ebf819683467e2bf',
|
||||
message: '616263',
|
||||
signature:
|
||||
'98a70222f0b8121aa9d30f813d683f80' +
|
||||
'9e462b469c7ff87639499bb94e6dae41' +
|
||||
'31f85042463c2a355a2003d062adf5aa' +
|
||||
'a10b8c61e636062aaad11c2a26083406',
|
||||
},
|
||||
];
|
||||
|
||||
for (let i = 0; i < VECTORS_RFC8032_PH.length; i++) {
|
||||
const v = VECTORS_RFC8032_PH[i];
|
||||
should(`RFC8032ph/${i}`, () => {
|
||||
deepStrictEqual(hex(ed25519ph.getPublicKey(v.secretKey)), v.publicKey);
|
||||
deepStrictEqual(hex(ed25519ph.sign(v.message, v.secretKey)), v.signature);
|
||||
deepStrictEqual(ed25519ph.verify(v.signature, v.message, v.publicKey), true);
|
||||
});
|
||||
}
|
||||
|
||||
should('X25519 base point', () => {
|
||||
const { y } = ed25519.ExtendedPoint.BASE;
|
||||
const { Fp } = ed25519.CURVE;
|
||||
const u = Fp.create((y + 1n) * Fp.inv(1n - y));
|
||||
deepStrictEqual(hex(numberToBytesLE(u, 32)), x25519.Gu);
|
||||
});
|
||||
|
||||
should('isTorsionFree()', () => {
|
||||
const orig = ed.utils.getExtendedPublicKey(ed.utils.randomPrivateKey()).point;
|
||||
for (const hex of ED25519_TORSION_SUBGROUP.slice(1)) {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { deepStrictEqual, throws } from 'assert';
|
||||
import { describe, should } from 'micro-should';
|
||||
import * as fc from 'fast-check';
|
||||
import { ed448, ed448ph, x448 } from '../lib/esm/ed448.js';
|
||||
import { ed448, ed448ph, x448 } from '../esm/ed448.js';
|
||||
import { hexToBytes, bytesToHex, randomBytes } from '@noble/hashes/utils';
|
||||
import { numberToBytesLE } from '../lib/esm/abstract/utils.js';
|
||||
import { numberToBytesLE } from '../esm/abstract/utils.js';
|
||||
import { default as ed448vectors } from './wycheproof/ed448_test.json' assert { type: 'json' };
|
||||
import { default as x448vectors } from './wycheproof/x448_test.json' assert { type: 'json' };
|
||||
|
||||
@@ -509,7 +509,7 @@ describe('ed448', () => {
|
||||
for (let i = 0; i < rfc7748Iter.length; i++) {
|
||||
const { scalar, iters } = rfc7748Iter[i];
|
||||
should(`RFC7748: scalarMult iteration (${i})`, () => {
|
||||
let k = x448.Gu;
|
||||
let k = x448.GuBytes;
|
||||
for (let i = 0, u = k; i < iters; i++) [k, u] = [x448.scalarMult(k, u), k];
|
||||
deepStrictEqual(hex(k), scalar);
|
||||
});
|
||||
@@ -664,7 +664,7 @@ describe('ed448', () => {
|
||||
// const invX = Fp.invert(x * x); // x²
|
||||
const u = Fp.div(Fp.create(y * y), Fp.create(x * x)); // (y²/x²)
|
||||
// const u = Fp.create(y * y * invX);
|
||||
deepStrictEqual(hex(numberToBytesLE(u, 56)), x448.Gu);
|
||||
deepStrictEqual(numberToBytesLE(u, 56), x448.GuBytes);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -5,18 +5,15 @@ import { bytesToHex } from '@noble/hashes/utils';
|
||||
import { sha256 } from '@noble/hashes/sha256';
|
||||
import { sha512 } from '@noble/hashes/sha512';
|
||||
import { shake128, shake256 } from '@noble/hashes/sha3';
|
||||
import * as secp256r1 from '../lib/esm/p256.js';
|
||||
import * as secp384r1 from '../lib/esm/p384.js';
|
||||
import * as secp521r1 from '../lib/esm/p521.js';
|
||||
import * as ed25519 from '../lib/esm/ed25519.js';
|
||||
import * as ed448 from '../lib/esm/ed448.js';
|
||||
import * as secp256k1 from '../lib/esm/secp256k1.js';
|
||||
import { bls12_381 } from '../lib/esm/bls12-381.js';
|
||||
import {
|
||||
stringToBytes,
|
||||
expand_message_xmd,
|
||||
expand_message_xof,
|
||||
} from '../lib/esm/abstract/hash-to-curve.js';
|
||||
import * as secp256r1 from '../esm/p256.js';
|
||||
import * as secp384r1 from '../esm/p384.js';
|
||||
import * as secp521r1 from '../esm/p521.js';
|
||||
import * as ed25519 from '../esm/ed25519.js';
|
||||
import * as ed448 from '../esm/ed448.js';
|
||||
import * as secp256k1 from '../esm/secp256k1.js';
|
||||
import { bls12_381 } from '../esm/bls12-381.js';
|
||||
import { expand_message_xmd, expand_message_xof } from '../esm/abstract/hash-to-curve.js';
|
||||
import { utf8ToBytes } from '../esm/abstract/utils.js';
|
||||
// XMD
|
||||
import { default as xmd_sha256_38 } from './hash-to-curve/expand_message_xmd_SHA256_38.json' assert { type: 'json' };
|
||||
import { default as xmd_sha256_256 } from './hash-to-curve/expand_message_xmd_SHA256_256.json' assert { type: 'json' };
|
||||
@@ -56,9 +53,9 @@ function testExpandXMD(hash, vectors) {
|
||||
const t = vectors.tests[i];
|
||||
should(`${vectors.hash}/${vectors.DST.length}/${i}`, () => {
|
||||
const p = expand_message_xmd(
|
||||
stringToBytes(t.msg),
|
||||
stringToBytes(vectors.DST),
|
||||
t.len_in_bytes,
|
||||
utf8ToBytes(t.msg),
|
||||
utf8ToBytes(vectors.DST),
|
||||
Number.parseInt(t.len_in_bytes),
|
||||
hash
|
||||
);
|
||||
deepStrictEqual(bytesToHex(p), t.uniform_bytes);
|
||||
@@ -79,9 +76,9 @@ function testExpandXOF(hash, vectors) {
|
||||
const t = vectors.tests[i];
|
||||
should(`${i}`, () => {
|
||||
const p = expand_message_xof(
|
||||
stringToBytes(t.msg),
|
||||
stringToBytes(vectors.DST),
|
||||
+t.len_in_bytes,
|
||||
utf8ToBytes(t.msg),
|
||||
utf8ToBytes(vectors.DST),
|
||||
Number.parseInt(t.len_in_bytes),
|
||||
vectors.k,
|
||||
hash
|
||||
);
|
||||
@@ -112,7 +109,7 @@ function testCurve(curve, ro, nu) {
|
||||
const t = ro.vectors[i];
|
||||
should(`(${i})`, () => {
|
||||
const p = curve
|
||||
.hashToCurve(stringToBytes(t.msg), {
|
||||
.hashToCurve(utf8ToBytes(t.msg), {
|
||||
DST: ro.dst,
|
||||
})
|
||||
.toAffine();
|
||||
@@ -126,7 +123,7 @@ function testCurve(curve, ro, nu) {
|
||||
const t = nu.vectors[i];
|
||||
should(`(${i})`, () => {
|
||||
const p = curve
|
||||
.encodeToCurve(stringToBytes(t.msg), {
|
||||
.encodeToCurve(utf8ToBytes(t.msg), {
|
||||
DST: nu.dst,
|
||||
})
|
||||
.toAffine();
|
||||
@@ -140,8 +137,8 @@ function testCurve(curve, ro, nu) {
|
||||
testCurve(secp256r1, p256_ro, p256_nu);
|
||||
testCurve(secp384r1, p384_ro, p384_nu);
|
||||
testCurve(secp521r1, p521_ro, p521_nu);
|
||||
testCurve(bls12_381.hashToCurve.G1, g1_ro, g1_nu);
|
||||
testCurve(bls12_381.hashToCurve.G2, g2_ro, g2_nu);
|
||||
testCurve(bls12_381.G1, g1_ro, g1_nu);
|
||||
testCurve(bls12_381.G2, g2_ro, g2_nu);
|
||||
testCurve(secp256k1, secp256k1_ro, secp256k1_nu);
|
||||
testCurve(ed25519, ed25519_ro, ed25519_nu);
|
||||
testCurve(ed448, ed448_ro, ed448_nu);
|
||||
|
||||
@@ -6,7 +6,7 @@ import './nist.test.js';
|
||||
import './ed448.test.js';
|
||||
import './ed25519.test.js';
|
||||
import './secp256k1.test.js';
|
||||
import './stark/index.test.js';
|
||||
import './secp256k1-schnorr.test.js';
|
||||
import './jubjub.test.js';
|
||||
import './bls12-381.test.js';
|
||||
import './hash-to-curve.test.js';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { jubjub, findGroupHash } from '../lib/esm/jubjub.js';
|
||||
import { jubjub, findGroupHash } from '../esm/jubjub.js';
|
||||
import { describe, should } from 'micro-should';
|
||||
import { deepStrictEqual, throws } from 'assert';
|
||||
const Point = jubjub.ExtendedPoint;
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
import { deepStrictEqual, throws } from 'assert';
|
||||
import { deepStrictEqual } from 'assert';
|
||||
import { describe, should } from 'micro-should';
|
||||
import { secp192r1, P192 } from '../lib/esm/p192.js';
|
||||
import { secp224r1, P224 } from '../lib/esm/p224.js';
|
||||
import { secp256r1, P256 } from '../lib/esm/p256.js';
|
||||
import { secp384r1, P384 } from '../lib/esm/p384.js';
|
||||
import { secp521r1, P521 } from '../lib/esm/p521.js';
|
||||
import { secp256k1 } from '../lib/esm/secp256k1.js';
|
||||
import { hexToBytes, bytesToHex } from '../lib/esm/abstract/utils.js';
|
||||
import { secp192r1, secp224r1, P192, P224 } from './_more-curves.helpers.js';
|
||||
import { secp256r1, P256 } from '../esm/p256.js';
|
||||
import { secp384r1, P384 } from '../esm/p384.js';
|
||||
import { secp521r1, P521 } from '../esm/p521.js';
|
||||
import { secp256k1 } from '../esm/secp256k1.js';
|
||||
import { hexToBytes, bytesToHex } from '../esm/abstract/utils.js';
|
||||
import { default as ecdsa } from './wycheproof/ecdsa_test.json' assert { type: 'json' };
|
||||
import { default as ecdh } from './wycheproof/ecdh_test.json' assert { type: 'json' };
|
||||
import { default as rfc6979 } from './fixtures/rfc6979.json' assert { type: 'json' };
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { deepStrictEqual, throws } from 'assert';
|
||||
import { should, describe } from 'micro-should';
|
||||
import * as poseidon from '../lib/esm/abstract/poseidon.js';
|
||||
import * as stark from '../lib/esm/stark.js';
|
||||
import * as mod from '../lib/esm/abstract/modular.js';
|
||||
import * as poseidon from '../esm/abstract/poseidon.js';
|
||||
import * as stark from './_poseidon.helpers.js';
|
||||
import * as mod from '../esm/abstract/modular.js';
|
||||
import { default as pvectors } from './vectors/poseidon.json' assert { type: 'json' };
|
||||
const { st1, st2, st3, st4 } = pvectors;
|
||||
|
||||
|
||||
34
test/secp256k1-schnorr.test.js
Normal file
34
test/secp256k1-schnorr.test.js
Normal file
@@ -0,0 +1,34 @@
|
||||
import { deepStrictEqual, throws } from 'assert';
|
||||
import { readFileSync } from 'fs';
|
||||
import { should, describe } from 'micro-should';
|
||||
import { bytesToHex as hex } from '@noble/hashes/utils';
|
||||
import { schnorr } from '../esm/secp256k1.js';
|
||||
const schCsv = readFileSync('./test/vectors/schnorr.csv', 'utf-8');
|
||||
|
||||
describe('schnorr.sign()', () => {
|
||||
// index,secret key,public key,aux_rand,message,signature,verification result,comment
|
||||
const vectors = schCsv
|
||||
.split('\n')
|
||||
.map((line) => line.split(','))
|
||||
.slice(1, -1);
|
||||
for (let vec of vectors) {
|
||||
const [index, sec, pub, rnd, msg, expSig, passes, comment] = vec;
|
||||
should(`${comment || 'vector ' + index}`, () => {
|
||||
if (sec) {
|
||||
deepStrictEqual(hex(schnorr.getPublicKey(sec)), pub.toLowerCase());
|
||||
const sig = schnorr.sign(msg, sec, rnd);
|
||||
deepStrictEqual(hex(sig), expSig.toLowerCase());
|
||||
deepStrictEqual(schnorr.verify(sig, msg, pub), true);
|
||||
} else {
|
||||
const passed = schnorr.verify(expSig, msg, pub);
|
||||
deepStrictEqual(passed, passes === 'TRUE');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// ESM is broken.
|
||||
import url from 'url';
|
||||
if (import.meta.url === url.pathToFileURL(process.argv[1]).href) {
|
||||
should.run();
|
||||
}
|
||||
14
test/secp256k1.helpers.js
Normal file
14
test/secp256k1.helpers.js
Normal file
@@ -0,0 +1,14 @@
|
||||
// @ts-ignore
|
||||
export { secp256k1 as secp } from '../esm/secp256k1.js';
|
||||
import { secp256k1 as _secp } from '../esm/secp256k1.js';
|
||||
export { bytesToNumberBE, numberToBytesBE } from '../esm/abstract/utils.js';
|
||||
export { mod } from '../esm/abstract/modular.js';
|
||||
export const sigFromDER = (der) => {
|
||||
return _secp.Signature.fromDER(der);
|
||||
};
|
||||
export const sigToDER = (sig) => sig.toDERHex();
|
||||
export const selectHash = (secp) => secp.CURVE.hash;
|
||||
export const normVerifySig = (s) => _secp.Signature.fromDER(s);
|
||||
// export const bytesToNumberBE = secp256k1.utils.bytesToNumberBE;
|
||||
// export const numberToBytesBE = secp256k1.utils.numberToBytesBE;
|
||||
// export const mod = mod_;
|
||||
@@ -1,22 +1,21 @@
|
||||
import { hexToBytes, bytesToHex as hex } from '@noble/hashes/utils';
|
||||
import { deepStrictEqual, throws } from 'assert';
|
||||
import * as fc from 'fast-check';
|
||||
import { secp256k1, schnorr } from '../lib/esm/secp256k1.js';
|
||||
import { Fp } from '../lib/esm/abstract/modular.js';
|
||||
import { bytesToNumberBE, ensureBytes, numberToBytesBE } from '../lib/esm/abstract/utils.js';
|
||||
import { readFileSync } from 'fs';
|
||||
import { should, describe } from 'micro-should';
|
||||
// prettier-ignore
|
||||
import {
|
||||
secp, sigFromDER, sigToDER, selectHash, normVerifySig, mod, bytesToNumberBE, numberToBytesBE
|
||||
} from './secp256k1.helpers.js';
|
||||
|
||||
import { default as ecdsa } from './vectors/ecdsa.json' assert { type: 'json' };
|
||||
import { default as ecdh } from './vectors/ecdh.json' assert { type: 'json' };
|
||||
import { default as privates } from './vectors/privates.json' assert { type: 'json' };
|
||||
import { default as points } from './vectors/points.json' assert { type: 'json' };
|
||||
import { default as wp } from './vectors/wychenproof.json' assert { type: 'json' };
|
||||
import { should, describe } from 'micro-should';
|
||||
import { deepStrictEqual, throws } from 'assert';
|
||||
import { hexToBytes, bytesToHex } from '@noble/hashes/utils';
|
||||
|
||||
const hex = bytesToHex;
|
||||
const secp = secp256k1;
|
||||
const Point = secp.ProjectivePoint;
|
||||
const privatesTxt = readFileSync('./test/vectors/privates-2.txt', 'utf-8');
|
||||
const schCsv = readFileSync('./test/vectors/schnorr.csv', 'utf-8');
|
||||
|
||||
const FC_BIGINT = fc.bigInt(1n + 1n, secp.CURVE.n - 1n);
|
||||
// prettier-ignore
|
||||
@@ -193,7 +192,7 @@ describe('secp256k1', () => {
|
||||
fc.assert(
|
||||
fc.property(FC_BIGINT, FC_BIGINT, (r, s) => {
|
||||
const sig = new secp.Signature(r, s);
|
||||
deepStrictEqual(secp.Signature.fromDER(sig.toDERHex()), sig);
|
||||
deepStrictEqual(sigFromDER(sigToDER(sig)), sig);
|
||||
})
|
||||
);
|
||||
});
|
||||
@@ -241,9 +240,9 @@ describe('secp256k1', () => {
|
||||
);
|
||||
for (const [msg, exp] of CASES) {
|
||||
const res = secp.sign(msg, privKey, { extraEntropy: undefined });
|
||||
deepStrictEqual(res.toDERHex(), exp);
|
||||
const rs = secp.Signature.fromDER(res.toDERHex()).toCompactHex();
|
||||
deepStrictEqual(secp.Signature.fromCompact(rs).toDERHex(), exp);
|
||||
deepStrictEqual(sigToDER(res), exp);
|
||||
const rs = sigFromDER(sigToDER(res)).toCompactHex();
|
||||
deepStrictEqual(sigToDER(secp.Signature.fromCompact(rs)), exp);
|
||||
}
|
||||
});
|
||||
should('handle {extraData} option', () => {
|
||||
@@ -342,7 +341,7 @@ describe('secp256k1', () => {
|
||||
const s = 115792089237316195423570985008687907852837564279074904382605163141518161494334n;
|
||||
const pub = new Point(x, y, 1n).toRawBytes();
|
||||
const sig = new secp.Signature(r, s);
|
||||
deepStrictEqual(secp.verify(sig, msg, pub, { strict: false }), true);
|
||||
deepStrictEqual(secp.verify(sig, msg, pub, { lowS: false }), true);
|
||||
});
|
||||
should('not verify invalid deterministic signatures with RFC 6979', () => {
|
||||
for (const vector of ecdsa.invalid.verify) {
|
||||
@@ -351,29 +350,6 @@ describe('secp256k1', () => {
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('schnorr.sign()', () => {
|
||||
// index,secret key,public key,aux_rand,message,signature,verification result,comment
|
||||
const vectors = schCsv
|
||||
.split('\n')
|
||||
.map((line) => line.split(','))
|
||||
.slice(1, -1);
|
||||
for (let vec of vectors) {
|
||||
const [index, sec, pub, rnd, msg, expSig, passes, comment] = vec;
|
||||
should(`${comment || 'vector ' + index}`, () => {
|
||||
if (sec) {
|
||||
deepStrictEqual(hex(schnorr.getPublicKey(sec)), pub.toLowerCase());
|
||||
const sig = schnorr.sign(msg, sec, rnd);
|
||||
deepStrictEqual(hex(sig), expSig.toLowerCase());
|
||||
deepStrictEqual(schnorr.verify(sig, msg, pub), true);
|
||||
} else {
|
||||
const passed = schnorr.verify(expSig, msg, pub);
|
||||
deepStrictEqual(passed, passes === 'TRUE');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe('recoverPublicKey()', () => {
|
||||
should('recover public key from recovery bit', () => {
|
||||
const message = '00000000000000000000000000000000000000000000000000000000deadbeef';
|
||||
@@ -404,7 +380,7 @@ describe('secp256k1', () => {
|
||||
should('handle RFC 6979 vectors', () => {
|
||||
for (const vector of ecdsa.valid) {
|
||||
let usig = secp.sign(vector.m, vector.d);
|
||||
let sig = usig.toDERHex();
|
||||
let sig = sigToDER(usig);
|
||||
const vpub = secp.getPublicKey(vector.d);
|
||||
const recovered = usig.recoverPublicKey(vector.m);
|
||||
deepStrictEqual(recovered.toHex(), hex(vpub));
|
||||
@@ -459,24 +435,25 @@ describe('secp256k1', () => {
|
||||
});
|
||||
|
||||
describe('tweak utilities (legacy)', () => {
|
||||
const Fn = Fp(secp.CURVE.n);
|
||||
const normal = secp.utils._normalizePrivateKey;
|
||||
const normal = secp.utils.normPrivateKeyToScalar;
|
||||
const tweakUtils = {
|
||||
privateAdd: (privateKey, tweak) => {
|
||||
return numberToBytesBE(Fn.add(normal(privateKey), normal(tweak)), 32);
|
||||
return numberToBytesBE(mod(normal(privateKey) + normal(tweak), secp.CURVE.n), 32);
|
||||
},
|
||||
|
||||
privateNegate: (privateKey) => {
|
||||
return numberToBytesBE(Fn.neg(normal(privateKey)), 32);
|
||||
return numberToBytesBE(mod(-normal(privateKey), secp.CURVE.n), 32);
|
||||
},
|
||||
|
||||
pointAddScalar: (p, tweak, isCompressed) => {
|
||||
// Will throw if tweaked point is at infinity
|
||||
return Point.fromHex(p).add(Point.fromPrivateKey(tweak)).toRawBytes(isCompressed);
|
||||
const tweaked = Point.fromHex(p).add(Point.fromPrivateKey(tweak));
|
||||
if (tweaked.equals(Point.ZERO)) throw new Error('Tweaked point at infinity');
|
||||
return tweaked.toRawBytes(isCompressed);
|
||||
},
|
||||
|
||||
pointMultiply: (p, tweak, isCompressed) => {
|
||||
const t = bytesToNumberBE(ensureBytes(tweak));
|
||||
if (typeof tweak === 'string') tweak = hexToBytes(tweak);
|
||||
const t = bytesToNumberBE(tweak);
|
||||
return Point.fromHex(p).multiply(t).toRawBytes(isCompressed);
|
||||
},
|
||||
};
|
||||
@@ -484,20 +461,20 @@ describe('secp256k1', () => {
|
||||
should('privateAdd()', () => {
|
||||
for (const vector of privates.valid.add) {
|
||||
const { a, b, expected } = vector;
|
||||
deepStrictEqual(bytesToHex(tweakUtils.privateAdd(a, b)), expected);
|
||||
deepStrictEqual(hex(tweakUtils.privateAdd(a, b)), expected);
|
||||
}
|
||||
});
|
||||
should('privateNegate()', () => {
|
||||
for (const vector of privates.valid.negate) {
|
||||
const { a, expected } = vector;
|
||||
deepStrictEqual(bytesToHex(tweakUtils.privateNegate(a)), expected);
|
||||
deepStrictEqual(hex(tweakUtils.privateNegate(a)), expected);
|
||||
}
|
||||
});
|
||||
should('pointAddScalar()', () => {
|
||||
for (const vector of points.valid.pointAddScalar) {
|
||||
const { description, P, d, expected } = vector;
|
||||
const compressed = !!expected && expected.length === 66; // compressed === 33 bytes
|
||||
deepStrictEqual(bytesToHex(tweakUtils.pointAddScalar(P, d, compressed)), expected);
|
||||
deepStrictEqual(hex(tweakUtils.pointAddScalar(P, d, compressed)), expected);
|
||||
}
|
||||
});
|
||||
should('pointAddScalar() invalid', () => {
|
||||
@@ -509,7 +486,7 @@ describe('secp256k1', () => {
|
||||
should('pointMultiply()', () => {
|
||||
for (const vector of points.valid.pointMultiply) {
|
||||
const { P, d, expected } = vector;
|
||||
deepStrictEqual(bytesToHex(tweakUtils.pointMultiply(P, d, true)), expected);
|
||||
deepStrictEqual(hex(tweakUtils.pointMultiply(P, d, true)), expected);
|
||||
}
|
||||
});
|
||||
should('pointMultiply() invalid', () => {
|
||||
@@ -525,10 +502,12 @@ describe('secp256k1', () => {
|
||||
// const pubKey = Point.fromHex().toRawBytes();
|
||||
const pubKey = group.key.uncompressed;
|
||||
for (let test of group.tests) {
|
||||
const m = secp.CURVE.hash(hexToBytes(test.msg));
|
||||
const h = selectHash(secp);
|
||||
|
||||
const m = h(hexToBytes(test.msg));
|
||||
if (test.result === 'valid' || test.result === 'acceptable') {
|
||||
const verified = secp.verify(test.sig, m, pubKey);
|
||||
if (secp.Signature.fromDER(test.sig).hasHighS()) {
|
||||
const verified = secp.verify(normVerifySig(test.sig), m, pubKey);
|
||||
if (sigFromDER(test.sig).hasHighS()) {
|
||||
deepStrictEqual(verified, false);
|
||||
} else {
|
||||
deepStrictEqual(verified, true);
|
||||
|
||||
@@ -1,201 +0,0 @@
|
||||
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();
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
import * as microStark from '../../../lib/esm/stark.js';
|
||||
import * as starkwareCrypto from '@starkware-industries/starkware-crypto-utils';
|
||||
import * as bench from 'micro-bmark';
|
||||
const { run, mark } = bench; // or bench.mark
|
||||
|
||||
const privateKey = '2dccce1da22003777062ee0870e9881b460a8b7eca276870f57c601f182136c';
|
||||
const msgHash = 'c465dd6b1bbffdb05442eb17f5ca38ad1aa78a6f56bf4415bdee219114a47';
|
||||
const keyPair = starkwareCrypto.default.ec.keyFromPrivate(privateKey, 'hex');
|
||||
const publicKeyStark = starkwareCrypto.default.ec.keyFromPublic(
|
||||
keyPair.getPublic(true, 'hex'),
|
||||
'hex'
|
||||
);
|
||||
const publicKeyMicro = microStark.getPublicKey(privateKey);
|
||||
|
||||
const FNS = {
|
||||
pedersenHash: {
|
||||
samples: 250,
|
||||
starkware: () =>
|
||||
starkwareCrypto.default.pedersen([
|
||||
'3d937c035c878245caf64531a5756109c53068da139362728feb561405371cb',
|
||||
'208a0a10250e382e1e4bbe2880906c2791bf6275695e02fbbc6aeff9cd8b31a',
|
||||
]),
|
||||
'micro-starknet': () =>
|
||||
microStark.pedersen(
|
||||
'3d937c035c878245caf64531a5756109c53068da139362728feb561405371cb',
|
||||
'208a0a10250e382e1e4bbe2880906c2791bf6275695e02fbbc6aeff9cd8b31a'
|
||||
),
|
||||
},
|
||||
signVerify: {
|
||||
samples: 500,
|
||||
starkware: () =>
|
||||
starkwareCrypto.default.verify(
|
||||
publicKeyStark,
|
||||
msgHash,
|
||||
starkwareCrypto.default.sign(keyPair, msgHash)
|
||||
),
|
||||
'micro-starknet': () =>
|
||||
microStark.verify(microStark.sign(msgHash, privateKey), msgHash, publicKeyMicro),
|
||||
},
|
||||
};
|
||||
|
||||
const main = () =>
|
||||
run(async () => {
|
||||
for (let [k, libs] of Object.entries(FNS)) {
|
||||
console.log(`==== ${k} ====`);
|
||||
for (const [lib, fn] of Object.entries(libs)) {
|
||||
if (lib === 'samples') continue;
|
||||
let title = `${k} (${lib})`;
|
||||
await mark(title, libs.samples, () => fn());
|
||||
}
|
||||
console.log();
|
||||
}
|
||||
// Log current RAM
|
||||
bench.logMem();
|
||||
});
|
||||
|
||||
main();
|
||||
@@ -1,19 +0,0 @@
|
||||
{
|
||||
"name": "benchmark",
|
||||
"private": true,
|
||||
"version": "0.1.0",
|
||||
"description": "benchmarks",
|
||||
"main": "index.js",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"bench": "node index.js"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@starkware-industries/starkware-crypto-utils": "^0.0.2",
|
||||
"micro-bmark": "0.2.0",
|
||||
"micro-should": "0.2.0"
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,32 +0,0 @@
|
||||
{
|
||||
"0x1": "0x1ef15c18599971b7beced415a40f0c7deacfd9b0d1819e03d723d8bc943cfca",
|
||||
"0x2": "0x759ca09377679ecd535a81e83039658bf40959283187c654c5416f439403cf5",
|
||||
"0x3": "0x411494b501a98abd8262b0da1351e17899a0c4ef23dd2f96fec5ba847310b20",
|
||||
"0x4": "0xa7da05a4d664859ccd6e567b935cdfbfe3018c7771cb980892ef38878ae9bc",
|
||||
"0x5": "0x788435d61046d3eec54d77d25bd194525f4fa26ebe6575536bc6f656656b74c",
|
||||
"0x6": "0x1efc3d7c9649900fcbd03f578a8248d095bc4b6a13b3c25f9886ef971ff96fa",
|
||||
"0x7": "0x743829e0a179f8afe223fc8112dfc8d024ab6b235fd42283c4f5970259ce7b7",
|
||||
"0x8": "0x6eeee2b0c71d681692559735e08a2c3ba04e7347c0c18d4d49b83bb89771591",
|
||||
"0x9": "0x216b4f076ff47e03a05032d1c6ee17933d8de8b2b4c43eb5ad5a7e1b25d3849",
|
||||
"0x800000000000000000000000000000000000000000000000000000000000000": "0x5c79074e7f7b834c12c81a9bb0d46691a5e7517767a849d9d98cb84e2176ed2",
|
||||
"0x800000000000000000000000000000000000000000000000000000000000001": "0x1c4f24e3bd16db0e2457bc005a9d61965105a535554c6b338871e34cb8e2d3a",
|
||||
"0x800000000000000000000000000000000000000000000000000000000000002": "0xdfbb89b39288a9ddacf3942b4481b04d4fa2f8ed3c424757981cc6357f27ac",
|
||||
"0x800000000000000000000000000000000000000000000000000000000000003": "0x41bef28265fd750b102f4f2d1e0231de7f4a33900a214f191a63d4fec4e72f4",
|
||||
"0x800000000000000000000000000000000000000000000000000000000000004": "0x24de66eb164797d4b414e81ded0cfa1a592ef0a9363ebbcb440d4d03cb18af1",
|
||||
"0x800000000000000000000000000000000000000000000000000000000000005": "0x5efb18c3bc9b69003746acc85fb6ee0cfbdc6adfb982f089cc63e1e5495daad",
|
||||
"0x800000000000000000000000000000000000000000000000000000000000006": "0x10dc71f00918a8ebfe4085c834d41dd22b251b9f81eef8b9a4fab77e7e1afe9",
|
||||
"0x800000000000000000000000000000000000000000000000000000000000007": "0x4267ebfd379b1c8caae73febc5920b0c95bd6f9f3536f47c5ddad1259c332ff",
|
||||
"0x800000000000000000000000000000000000000000000000000000000000008": "0x6da515118c8e01fd5b2e96b814ee95bad7d60be4d2ba6b47e0d283f579d9671",
|
||||
"0x800000000000000000000000000000000000000000000000000000000000009": "0x7a5b4797f4e56ed1473876bc2693fbe3f2fef7e050717cbae924ff23d426052",
|
||||
"0x2e9c99d8382fa004dcbbee720aef8a97002de0e991f6a8344e6dc636a71b59e": "0x1ff6803ae740e7e596504ac5c6afbea472e53679361e214f12be0155b13e25d",
|
||||
"0x8620458785138df8722214e073a91b8f55076ea78197cf41007692dd27fd90": "0x5967da40b90d7ca1e36dc4024381d7d4b403c6ac1a0ab358b0743984934a805",
|
||||
"0x1b920e7dfb49ba5ada673882af5342e7448d3e9335e0ac37feb6280cd7289ce": "0x78c7ab46333968fbde3201cf512c1eeb5529360259072c459a158dee4449b57",
|
||||
"0x704170dbfd5dc63caef69d2ce6dfc2b2dbb2af6e75851242bbe79fb6e62a118": "0x534bd8d6ebe4bb2f6992e2d7c19ef3146247e10c2849f357e44eddd283b2af6",
|
||||
"0x4b58bf4228f39550eca59b5c96a0cb606036cc9495eef9a546f24f01b1b7829": "0x1097a8c5a46d94596f1c8e70ca66941f2bb11e3c8d4fd58fdc4589f09965be8",
|
||||
"0x2e93226c90fb7a2381a24e940a94b98433e3553dcbf745d3f54d62963c75604": "0x369f0e8c8e984f244290267393a004dba435a4df091767ad5063fece7b1884c",
|
||||
"0x4615f94598cd756ad1a551d7e57fd725916adfd0054eb773ceb482eef87d0b2": "0x1ee5b8d612102a2408cde59ce52a6498d2e38fe8789bb26d400dea310684ec9",
|
||||
"0x6ade54b7debd7ca1d4e8e932f9545f8fa4024d73be1efcc86df86367fc333f8": "0x37de3bf52412b2fb9b0030d232ca9dd921cd8f71fd67975cdc62546826e121",
|
||||
"0x618e7467dd24c2a3449c4df640439c12cdd0f8ea779afcee6e252b2cf494354": "0x71c2b578c432f2d305d3808bb645ecc46dd670cb43d4f4a076f75ccbff74fbc",
|
||||
"0x7eae185e1f41ec76d214d763f0592f194933622a9dd5f3d52d0209f71619c1a": "0x2b0160052e70176e5b0ff2a6eff90896ae07b732fc27219e36e077735abd57e",
|
||||
"0x178047D3869489C055D7EA54C014FFB834A069C9595186ABE04EA4D1223A03F": "0x1895a6a77ae14e7987b9cb51329a5adfb17bd8e7c638f92d6892d76e51cebcf"
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
{
|
||||
"private_key": "0x3c1e9550e66958296d11b60f8e8e7a7ad990d07fa65d5f7652c4a6c87d4e3cc",
|
||||
"messages": [
|
||||
{
|
||||
"hash": "0x1",
|
||||
"r": "3162358736122783857144396205516927012128897537504463716197279730251407200037",
|
||||
"s": "1447067116407676619871126378936374427636662490882969509559888874644844560850"
|
||||
},
|
||||
{
|
||||
"hash": "0x11",
|
||||
"r": "2282960348362869237018441985726545922711140064809058182483721438101695251648",
|
||||
"s": "2905868291002627709651322791912000820756370440695830310841564989426104902684"
|
||||
},
|
||||
|
||||
{
|
||||
"hash": "0x223",
|
||||
"r": "2851492577225522862152785068304516872062840835882746625971400995051610132955",
|
||||
"s": "2227464623243182122770469099770977514100002325017609907274766387592987135410"
|
||||
},
|
||||
|
||||
{
|
||||
"hash": "0x9999",
|
||||
"r": "3551214266795401081823453828727326248401688527835302880992409448142527576296",
|
||||
"s": "2580950807716503852408066180369610390914312729170066679103651110985466032285"
|
||||
},
|
||||
|
||||
{
|
||||
"hash": "0x387e76d1667c4454bfb835144120583af836f8e32a516765497d23eabe16b3f",
|
||||
"r": "3518448914047769356425227827389998721396724764083236823647519654917215164512",
|
||||
"s": "3042321032945513635364267149196358883053166552342928199041742035443537684462"
|
||||
},
|
||||
|
||||
{
|
||||
"hash": "0x3a7e76d1697c4455bfb835144120283af236f8e32a516765497d23eabe16b2",
|
||||
"r": "2261926635950780594216378185339927576862772034098248230433352748057295357217",
|
||||
"s": "2708700003762962638306717009307430364534544393269844487939098184375356178572"
|
||||
},
|
||||
|
||||
{
|
||||
"hash": "0xfa5f0cd1ebff93c9e6474379a213ba111f9e42f2f1cb361b0327e0737203",
|
||||
"r": "3016953906936760149710218073693613509330129567629289734816320774638425763370",
|
||||
"s": "306146275372136078470081798635201810092238376869367156373203048583896337506"
|
||||
},
|
||||
|
||||
{
|
||||
"hash": "0x4c1e9550e66958296d11b60f8e8e7f7ae99dd0cfa6bd5fa652c1a6c87d4e2cc",
|
||||
"r": "3562728603055564208884290243634917206833465920158600288670177317979301056463",
|
||||
"s": "1958799632261808501999574190111106370256896588537275453140683641951899459876"
|
||||
},
|
||||
|
||||
{
|
||||
"hash": "0x6362b40c218fb4c8a8bd42ca482145e8513b78e00faa0de76a98ba14fc37ae8",
|
||||
"r": "3485557127492692423490706790022678621438670833185864153640824729109010175518",
|
||||
"s": "897592218067946175671768586886915961592526001156186496738437723857225288280"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
import './basic.test.js';
|
||||
import './stark.test.js';
|
||||
import './property.test.js';
|
||||
import './poseidon.test.js';
|
||||
@@ -1,114 +0,0 @@
|
||||
import { deepStrictEqual, throws } from 'assert';
|
||||
import { describe, should } from 'micro-should';
|
||||
import * as starknet from '../../lib/esm/stark.js';
|
||||
import * as fs from 'fs';
|
||||
|
||||
function parseTest(path) {
|
||||
let data = fs.readFileSync(path, 'ascii');
|
||||
// Remove whitespaces
|
||||
data = data.replace(/[ |\t]/g, '');
|
||||
const pattern =
|
||||
'Rate=(\\d+)\n' +
|
||||
'Capacity=(\\d+)\n' +
|
||||
'FullRounds=(\\d+)\n' +
|
||||
'PartialRounds=(\\d+)\n' +
|
||||
'MDS=\\[(.+)\\]\n' +
|
||||
'RoundKeys=\\(?\n?\\[\n?(.+)\n?\\]\n?\\)?';
|
||||
const r = data.match(new RegExp(pattern, 'ms'));
|
||||
|
||||
function parseArray(s) {
|
||||
// Remove new lines
|
||||
s = s.replace(/\n/gms, '');
|
||||
return s.match(/(\[.+?\])/g).map((i) =>
|
||||
i
|
||||
.replace(/^\[(.+)\]$/, '$1')
|
||||
.split(',')
|
||||
.filter((i) => !!i)
|
||||
);
|
||||
}
|
||||
const res = {
|
||||
rate: +r[1],
|
||||
capacity: +r[2],
|
||||
roundsFull: +r[3],
|
||||
roundsPartial: +r[4],
|
||||
MDS: parseArray(r[5]).map((i) => i.map((j) => BigInt(j))),
|
||||
roundConstants: parseArray(r[6]).map((i) => i.map((j) => BigInt(j))),
|
||||
};
|
||||
return res;
|
||||
}
|
||||
|
||||
function mapPoseidon(parsed) {
|
||||
return starknet.poseidonBasic(
|
||||
{
|
||||
Fp: starknet.Fp251,
|
||||
rate: parsed.rate,
|
||||
capacity: parsed.capacity,
|
||||
roundsFull: parsed.roundsFull,
|
||||
roundsPartial: parsed.roundsPartial,
|
||||
},
|
||||
parsed.MDS
|
||||
);
|
||||
}
|
||||
|
||||
const parsed = {
|
||||
poseidon3: parseTest('./test/stark/poseidon/poseidon3.txt'),
|
||||
poseidon4: parseTest('./test/stark/poseidon/poseidon4.txt'),
|
||||
poseidon5: parseTest('./test/stark/poseidon/poseidon5.txt'),
|
||||
poseidon9: parseTest('./test/stark/poseidon/poseidon9.txt'),
|
||||
};
|
||||
|
||||
function poseidonTest(name, parsed) {
|
||||
should(`${name}`, () => {
|
||||
const fn = mapPoseidon(parsed);
|
||||
deepStrictEqual(fn.roundConstants, parsed.roundConstants);
|
||||
});
|
||||
}
|
||||
|
||||
describe('poseidon txt vectors', () => {
|
||||
poseidonTest('poseidon3', parsed.poseidon3);
|
||||
poseidonTest('poseidon4', parsed.poseidon4);
|
||||
poseidonTest('poseidon5', parsed.poseidon5);
|
||||
poseidonTest('poseidon9', parsed.poseidon9);
|
||||
});
|
||||
|
||||
should('Poseidon examples', () => {
|
||||
const p3 = mapPoseidon(parsed.poseidon3);
|
||||
deepStrictEqual(p3([0n, 0n, 0n]), [
|
||||
3446325744004048536138401612021367625846492093718951375866996507163446763827n,
|
||||
1590252087433376791875644726012779423683501236913937337746052470473806035332n,
|
||||
867921192302518434283879514999422690776342565400001269945778456016268852423n,
|
||||
]);
|
||||
const p4 = mapPoseidon(parsed.poseidon4);
|
||||
deepStrictEqual(p4([0n, 0n, 0n, 0n]), [
|
||||
535071095200566880914603862188010633478042591441142518549720701573192347548n,
|
||||
3567335813488551850156302853280844225974867890860330236555401145692518003968n,
|
||||
229995103310401763929738317978722680640995513996113588430855556460153357543n,
|
||||
3513983790849716360905369754287999509206472929684378838050290392634812839312n,
|
||||
]);
|
||||
const p5 = mapPoseidon(parsed.poseidon5);
|
||||
deepStrictEqual(p5([0n, 0n, 0n, 0n, 0n]), [
|
||||
2337689130971531876049206831496963607805116499042700598724344149414565980684n,
|
||||
3230969295497815870174763682436655274044379544854667759151474216427142025631n,
|
||||
3297330512217530111610698859408044542971696143761201570393504997742535648562n,
|
||||
2585480844700786541432072704002477919020588246983274666988914431019064343941n,
|
||||
3595308260654382824623573767385493361624474708214823462901432822513585995028n,
|
||||
]);
|
||||
const p9 = mapPoseidon(parsed.poseidon9);
|
||||
deepStrictEqual(p9([0n, 0n, 0n, 0n, 0n, 0n, 0n, 0n, 0n]), [
|
||||
1534116856660032929112709488204491699743182428465681149262739677337223235050n,
|
||||
1710856073207389764546990138116985223517553616229641666885337928044617114700n,
|
||||
3165864635055638516987240200217592641540231237468651257819894959934472989427n,
|
||||
1003007637710164252047715558598366312649052908276423203724288341354608811559n,
|
||||
68117303579957054409211824649914588822081700129416361923518488718489651489n,
|
||||
1123395637839379807713801282868237406546107732595903195840754789810160564711n,
|
||||
478590974834311070537087181212389392308746075734019180430422247431982932503n,
|
||||
835322726024358888065061514739954009068852229059154336727219387089732433787n,
|
||||
3129703030204995742174502162918848446737407262178341733578946634564864233056n,
|
||||
]);
|
||||
});
|
||||
|
||||
// ESM is broken.
|
||||
import url from 'url';
|
||||
if (import.meta.url === url.pathToFileURL(process.argv[1]).href) {
|
||||
should.run();
|
||||
}
|
||||
@@ -1,201 +0,0 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
@@ -1,35 +0,0 @@
|
||||
# StarkWare's Poseidon Hash
|
||||
|
||||
[Poseidon](https://www.poseidon-hash.info/) is a family of hash functions designed for being very efficient as algebraic circuits.
|
||||
As such, they may be very useful in ZK proving systems such as STARKs and others.
|
||||
|
||||
This repository provides the official parameters of StarkWare's Poseidon hash implementations.
|
||||
|
||||
All the instances are over the prime field:
|
||||
p = 2^251 + 17 * 2^192 + 1 = 3618502788666131213697322783095070105623107215331596699973092056135872020481
|
||||
|
||||
A few examples hash results with the different parameters:
|
||||
|
||||
```
|
||||
Poseidon3([0,0,0]) = [3446325744004048536138401612021367625846492093718951375866996507163446763827,
|
||||
1590252087433376791875644726012779423683501236913937337746052470473806035332,
|
||||
867921192302518434283879514999422690776342565400001269945778456016268852423]
|
||||
Poseidon4([0,0,0,0]) = [535071095200566880914603862188010633478042591441142518549720701573192347548,
|
||||
3567335813488551850156302853280844225974867890860330236555401145692518003968,
|
||||
229995103310401763929738317978722680640995513996113588430855556460153357543,
|
||||
3513983790849716360905369754287999509206472929684378838050290392634812839312]
|
||||
Poseidon5([0,0,0,0,0]) = [2337689130971531876049206831496963607805116499042700598724344149414565980684,
|
||||
3230969295497815870174763682436655274044379544854667759151474216427142025631,
|
||||
3297330512217530111610698859408044542971696143761201570393504997742535648562,
|
||||
2585480844700786541432072704002477919020588246983274666988914431019064343941,
|
||||
3595308260654382824623573767385493361624474708214823462901432822513585995028]
|
||||
Poseidon9([0,0,0,0,0,0,0,0,0]) = [1534116856660032929112709488204491699743182428465681149262739677337223235050,
|
||||
1710856073207389764546990138116985223517553616229641666885337928044617114700,
|
||||
3165864635055638516987240200217592641540231237468651257819894959934472989427,
|
||||
1003007637710164252047715558598366312649052908276423203724288341354608811559,
|
||||
68117303579957054409211824649914588822081700129416361923518488718489651489,
|
||||
1123395637839379807713801282868237406546107732595903195840754789810160564711,
|
||||
478590974834311070537087181212389392308746075734019180430422247431982932503,
|
||||
835322726024358888065061514739954009068852229059154336727219387089732433787,
|
||||
3129703030204995742174502162918848446737407262178341733578946634564864233056]
|
||||
```
|
||||
@@ -1,462 +0,0 @@
|
||||
Rate = 2
|
||||
Capacity = 1
|
||||
FullRounds = 8
|
||||
PartialRounds = 83
|
||||
MDS = [[3, 1, 1], [1, -1, 1], [1, 1, -2]]
|
||||
RoundKeys = [
|
||||
[
|
||||
2950795762459345168613727575620414179244544320470208355568817838579231751791,
|
||||
1587446564224215276866294500450702039420286416111469274423465069420553242820,
|
||||
1645965921169490687904413452218868659025437693527479459426157555728339600137,
|
||||
],
|
||||
[
|
||||
2782373324549879794752287702905278018819686065818504085638398966973694145741,
|
||||
3409172630025222641379726933524480516420204828329395644967085131392375707302,
|
||||
2379053116496905638239090788901387719228422033660130943198035907032739387135,
|
||||
],
|
||||
[
|
||||
2570819397480941104144008784293466051718826502582588529995520356691856497111,
|
||||
3546220846133880637977653625763703334841539452343273304410918449202580719746,
|
||||
2720682389492889709700489490056111332164748138023159726590726667539759963454,
|
||||
],
|
||||
[
|
||||
1899653471897224903834726250400246354200311275092866725547887381599836519005,
|
||||
2369443697923857319844855392163763375394720104106200469525915896159690979559,
|
||||
2354174693689535854311272135513626412848402744119855553970180659094265527996,
|
||||
],
|
||||
[
|
||||
2404084503073127963385083467393598147276436640877011103379112521338973185443,
|
||||
950320777137731763811524327595514151340412860090489448295239456547370725376,
|
||||
2121140748740143694053732746913428481442990369183417228688865837805149503386,
|
||||
],
|
||||
[
|
||||
2372065044800422557577242066480215868569521938346032514014152523102053709709,
|
||||
2618497439310693947058545060953893433487994458443568169824149550389484489896,
|
||||
3518297267402065742048564133910509847197496119850246255805075095266319996916,
|
||||
],
|
||||
[
|
||||
340529752683340505065238931581518232901634742162506851191464448040657139775,
|
||||
1954876811294863748406056845662382214841467408616109501720437541211031966538,
|
||||
813813157354633930267029888722341725864333883175521358739311868164460385261,
|
||||
],
|
||||
[
|
||||
71901595776070443337150458310956362034911936706490730914901986556638720031,
|
||||
2789761472166115462625363403490399263810962093264318361008954888847594113421,
|
||||
2628791615374802560074754031104384456692791616314774034906110098358135152410,
|
||||
],
|
||||
[
|
||||
3617032588734559635167557152518265808024917503198278888820567553943986939719,
|
||||
2624012360209966117322788103333497793082705816015202046036057821340914061980,
|
||||
149101987103211771991327927827692640556911620408176100290586418839323044234,
|
||||
],
|
||||
[
|
||||
1039927963829140138166373450440320262590862908847727961488297105916489431045,
|
||||
2213946951050724449162431068646025833746639391992751674082854766704900195669,
|
||||
2792724903541814965769131737117981991997031078369482697195201969174353468597,
|
||||
],
|
||||
[
|
||||
3212031629728871219804596347439383805499808476303618848198208101593976279441,
|
||||
3343514080098703935339621028041191631325798327656683100151836206557453199613,
|
||||
614054702436541219556958850933730254992710988573177298270089989048553060199,
|
||||
],
|
||||
[
|
||||
148148081026449726283933484730968827750202042869875329032965774667206931170,
|
||||
1158283532103191908366672518396366136968613180867652172211392033571980848414,
|
||||
1032400527342371389481069504520755916075559110755235773196747439146396688513,
|
||||
],
|
||||
[
|
||||
806900704622005851310078578853499250941978435851598088619290797134710613736,
|
||||
462498083559902778091095573017508352472262817904991134671058825705968404510,
|
||||
1003580119810278869589347418043095667699674425582646347949349245557449452503,
|
||||
],
|
||||
[
|
||||
619074932220101074089137133998298830285661916867732916607601635248249357793,
|
||||
2635090520059500019661864086615522409798872905401305311748231832709078452746,
|
||||
978252636251682252755279071140187792306115352460774007308726210405257135181,
|
||||
],
|
||||
[
|
||||
1766912167973123409669091967764158892111310474906691336473559256218048677083,
|
||||
1663265127259512472182980890707014969235283233442916350121860684522654120381,
|
||||
3532407621206959585000336211742670185380751515636605428496206887841428074250,
|
||||
],
|
||||
[
|
||||
2507023127157093845256722098502856938353143387711652912931112668310034975446,
|
||||
3321152907858462102434883844787153373036767230808678981306827073335525034593,
|
||||
3039253036806065280643845548147711477270022154459620569428286684179698125661,
|
||||
],
|
||||
[
|
||||
103480338868480851881924519768416587261556021758163719199282794248762465380,
|
||||
2394049781357087698434751577708655768465803975478348134669006211289636928495,
|
||||
2660531560345476340796109810821127229446538730404600368347902087220064379579,
|
||||
],
|
||||
[
|
||||
3603166934034556203649050570865466556260359798872408576857928196141785055563,
|
||||
1553799760191949768532188139643704561532896296986025007089826672890485412324,
|
||||
2744284717053657689091306578463476341218866418732695211367062598446038965164,
|
||||
],
|
||||
[
|
||||
320745764922149897598257794663594419839885234101078803811049904310835548856,
|
||||
979382242100682161589753881721708883681034024104145498709287731138044566302,
|
||||
1860426855810549882740147175136418997351054138609396651615467358416651354991,
|
||||
],
|
||||
[
|
||||
336173081054369235994909356892506146234495707857220254489443629387613956145,
|
||||
1632470326779699229772327605759783482411227247311431865655466227711078175883,
|
||||
921958250077481394074960433988881176409497663777043304881055317463712938502,
|
||||
],
|
||||
[
|
||||
3034358982193370602048539901033542101022185309652879937418114324899281842797,
|
||||
25626282149517463867572353922222474817434101087272320606729439087234878607,
|
||||
3002662261401575565838149305485737102400501329139562227180277188790091853682,
|
||||
],
|
||||
[
|
||||
2939684373453383817196521641512509179310654199629514917426341354023324109367,
|
||||
1076484609897998179434851570277297233169621096172424141759873688902355505136,
|
||||
2575095284833160494841112025725243274091830284746697961080467506739203605049,
|
||||
],
|
||||
[
|
||||
3565075264617591783581665711620369529657840830498005563542124551465195621851,
|
||||
2197016502533303822395077038351174326125210255869204501838837289716363437993,
|
||||
331415322883530754594261416546036195982886300052707474899691116664327869405,
|
||||
],
|
||||
[
|
||||
1935011233711290003793244296594669823169522055520303479680359990463281661839,
|
||||
3495901467168087413996941216661589517270845976538454329511167073314577412322,
|
||||
954195417117133246453562983448451025087661597543338750600301835944144520375,
|
||||
],
|
||||
[
|
||||
1271840477709992894995746871435810599280944810893784031132923384456797925777,
|
||||
2565310762274337662754531859505158700827688964841878141121196528015826671847,
|
||||
3365022288251637014588279139038152521653896670895105540140002607272936852513,
|
||||
],
|
||||
[
|
||||
1660592021628965529963974299647026602622092163312666588591285654477111176051,
|
||||
970104372286014048279296575474974982288801187216974504035759997141059513421,
|
||||
2617024574317953753849168721871770134225690844968986289121504184985993971227,
|
||||
],
|
||||
[
|
||||
999899815343607746071464113462778273556695659506865124478430189024755832262,
|
||||
2228536129413411161615629030408828764980855956560026807518714080003644769896,
|
||||
2701953891198001564547196795777701119629537795442025393867364730330476403227,
|
||||
],
|
||||
[
|
||||
837078355588159388741598313782044128527494922918203556465116291436461597853,
|
||||
2121749601840466143704862369657561429793951309962582099604848281796392359214,
|
||||
771812260179247428733132708063116523892339056677915387749121983038690154755,
|
||||
],
|
||||
[
|
||||
3317336423132806446086732225036532603224267214833263122557471741829060578219,
|
||||
481570067997721834712647566896657604857788523050900222145547508314620762046,
|
||||
242195042559343964206291740270858862066153636168162642380846129622127460192,
|
||||
],
|
||||
[
|
||||
2855462178889999218204481481614105202770810647859867354506557827319138379686,
|
||||
3525521107148375040131784770413887305850308357895464453970651672160034885202,
|
||||
1320839531502392535964065058804908871811967681250362364246430459003920305799,
|
||||
],
|
||||
[
|
||||
2514191518588387125173345107242226637171897291221681115249521904869763202419,
|
||||
2798335750958827619666318316247381695117827718387653874070218127140615157902,
|
||||
2808467767967035643407948058486565877867906577474361783201337540214875566395,
|
||||
],
|
||||
[
|
||||
3551834385992706206273955480294669176699286104229279436819137165202231595747,
|
||||
1219439673853113792340300173186247996249367102884530407862469123523013083971,
|
||||
761519904537984520554247997444508040636526566551719396202550009393012691157,
|
||||
],
|
||||
[
|
||||
3355402549169351700500518865338783382387571349497391475317206324155237401353,
|
||||
199541098009731541347317515995192175813554789571447733944970283654592727138,
|
||||
192100490643078165121235261796864975568292640203635147901612231594408079071,
|
||||
],
|
||||
[
|
||||
1187019357602953326192019968809486933768550466167033084944727938441427050581,
|
||||
189525349641911362389041124808934468936759383310282010671081989585219065700,
|
||||
2831653363992091308880573627558515686245403755586311978724025292003353336665,
|
||||
],
|
||||
[
|
||||
2052859812632218952608271535089179639890275494426396974475479657192657094698,
|
||||
1670756178709659908159049531058853320846231785448204274277900022176591811072,
|
||||
3538757242013734574731807289786598937548399719866320954894004830207085723125,
|
||||
],
|
||||
[
|
||||
710549042741321081781917034337800036872214466705318638023070812391485261299,
|
||||
2345013122330545298606028187653996682275206910242635100920038943391319595180,
|
||||
3528369671971445493932880023233332035122954362711876290904323783426765912206,
|
||||
],
|
||||
[
|
||||
1167120829038120978297497195837406760848728897181138760506162680655977700764,
|
||||
3073243357129146594530765548901087443775563058893907738967898816092270628884,
|
||||
378514724418106317738164464176041649567501099164061863402473942795977719726,
|
||||
],
|
||||
[
|
||||
333391138410406330127594722511180398159664250722328578952158227406762627796,
|
||||
1727570175639917398410201375510924114487348765559913502662122372848626931905,
|
||||
968312190621809249603425066974405725769739606059422769908547372904403793174,
|
||||
],
|
||||
[
|
||||
360659316299446405855194688051178331671817370423873014757323462844775818348,
|
||||
1386580151907705298970465943238806620109618995410132218037375811184684929291,
|
||||
3604888328937389309031638299660239238400230206645344173700074923133890528967,
|
||||
],
|
||||
[
|
||||
2496185632263372962152518155651824899299616724241852816983268163379540137546,
|
||||
486538168871046887467737983064272608432052269868418721234810979756540672990,
|
||||
1558415498960552213241704009433360128041672577274390114589014204605400783336,
|
||||
],
|
||||
[
|
||||
3512058327686147326577190314835092911156317204978509183234511559551181053926,
|
||||
2235429387083113882635494090887463486491842634403047716936833563914243946191,
|
||||
1290896777143878193192832813769470418518651727840187056683408155503813799882,
|
||||
],
|
||||
[
|
||||
1143310336918357319571079551779316654556781203013096026972411429993634080835,
|
||||
3235435208525081966062419599803346573407862428113723170955762956243193422118,
|
||||
1293239921425673430660897025143433077974838969258268884994339615096356996604,
|
||||
],
|
||||
[
|
||||
236252269127612784685426260840574970698541177557674806964960352572864382971,
|
||||
1733907592497266237374827232200506798207318263912423249709509725341212026275,
|
||||
302004309771755665128395814807589350526779835595021835389022325987048089868,
|
||||
],
|
||||
[
|
||||
3018926838139221755384801385583867283206879023218491758435446265703006270945,
|
||||
39701437664873825906031098349904330565195980985885489447836580931425171297,
|
||||
908381723021746969965674308809436059628307487140174335882627549095646509778,
|
||||
],
|
||||
[
|
||||
219062858908229855064136253265968615354041842047384625689776811853821594358,
|
||||
1283129863776453589317845316917890202859466483456216900835390291449830275503,
|
||||
418512623547417594896140369190919231877873410935689672661226540908900544012,
|
||||
],
|
||||
[
|
||||
1792181590047131972851015200157890246436013346535432437041535789841136268632,
|
||||
370546432987510607338044736824316856592558876687225326692366316978098770516,
|
||||
3323437805230586112013581113386626899534419826098235300155664022709435756946,
|
||||
],
|
||||
[
|
||||
910076621742039763058481476739499965761942516177975130656340375573185415877,
|
||||
1762188042455633427137702520675816545396284185254002959309669405982213803405,
|
||||
2186362253913140345102191078329764107619534641234549431429008219905315900520,
|
||||
],
|
||||
[
|
||||
2230647725927681765419218738218528849146504088716182944327179019215826045083,
|
||||
1069243907556644434301190076451112491469636357133398376850435321160857761825,
|
||||
2695241469149243992683268025359863087303400907336026926662328156934068747593,
|
||||
],
|
||||
[
|
||||
1361519681544413849831669554199151294308350560528931040264950307931824877035,
|
||||
1339116632207878730171031743761550901312154740800549632983325427035029084904,
|
||||
790593524918851401449292693473498591068920069246127392274811084156907468875,
|
||||
],
|
||||
[
|
||||
2723400368331924254840192318398326090089058735091724263333980290765736363637,
|
||||
3457180265095920471443772463283225391927927225993685928066766687141729456030,
|
||||
1483675376954327086153452545475557749815683871577400883707749788555424847954,
|
||||
],
|
||||
[
|
||||
2926303836265506736227240325795090239680154099205721426928300056982414025239,
|
||||
543969119775473768170832347411484329362572550684421616624136244239799475526,
|
||||
237401230683847084256617415614300816373730178313253487575312839074042461932,
|
||||
],
|
||||
[
|
||||
844568412840391587862072008674263874021460074878949862892685736454654414423,
|
||||
151922054871708336050647150237534498235916969120198637893731715254687336644,
|
||||
1299332034710622815055321547569101119597030148120309411086203580212105652312,
|
||||
],
|
||||
[
|
||||
487046922649899823989594814663418784068895385009696501386459462815688122993,
|
||||
1104883249092599185744249485896585912845784382683240114120846423960548576851,
|
||||
1458388705536282069567179348797334876446380557083422364875248475157495514484,
|
||||
],
|
||||
[
|
||||
850248109622750774031817200193861444623975329881731864752464222442574976566,
|
||||
2885843173858536690032695698009109793537724845140477446409245651176355435722,
|
||||
3027068551635372249579348422266406787688980506275086097330568993357835463816,
|
||||
],
|
||||
[
|
||||
3231892723647447539926175383213338123506134054432701323145045438168976970994,
|
||||
1719080830641935421242626784132692936776388194122314954558418655725251172826,
|
||||
1172253756541066126131022537343350498482225068791630219494878195815226839450,
|
||||
],
|
||||
[
|
||||
1619232269633026603732619978083169293258272967781186544174521481891163985093,
|
||||
3495680684841853175973173610562400042003100419811771341346135531754869014567,
|
||||
1576161515913099892951745452471618612307857113799539794680346855318958552758,
|
||||
],
|
||||
[
|
||||
2618326122974253423403350731396350223238201817594761152626832144510903048529,
|
||||
2696245132758436974032479782852265185094623165224532063951287925001108567649,
|
||||
930116505665110070247395429730201844026054810856263733273443066419816003444,
|
||||
],
|
||||
[
|
||||
2786389174502246248523918824488629229455088716707062764363111940462137404076,
|
||||
1555260846425735320214671887347115247546042526197895180675436886484523605116,
|
||||
2306241912153325247392671742757902161446877415586158295423293240351799505917,
|
||||
],
|
||||
[
|
||||
411529621724849932999694270803131456243889635467661223241617477462914950626,
|
||||
1542495485262286701469125140275904136434075186064076910329015697714211835205,
|
||||
1853045663799041100600825096887578544265580718909350942241802897995488264551,
|
||||
],
|
||||
[
|
||||
2963055259497271220202739837493041799968576111953080503132045092194513937286,
|
||||
2303806870349915764285872605046527036748108533406243381676768310692344456050,
|
||||
2622104986201990620910286730213140904984256464479840856728424375142929278875,
|
||||
],
|
||||
[
|
||||
2369987021925266811581727383184031736927816625797282287927222602539037105864,
|
||||
285070227712021899602056480426671736057274017903028992288878116056674401781,
|
||||
3034087076179360957800568733595959058628497428787907887933697691951454610691,
|
||||
],
|
||||
[
|
||||
469095854351700119980323115747590868855368701825706298740201488006320881056,
|
||||
360001976264385426746283365024817520563236378289230404095383746911725100012,
|
||||
3438709327109021347267562000879503009590697221730578667498351600602230296178,
|
||||
],
|
||||
[
|
||||
63573904800572228121671659287593650438456772568903228287754075619928214969,
|
||||
3470881855042989871434874691030920672110111605547839662680968354703074556970,
|
||||
724559311507950497340993415408274803001166693839947519425501269424891465492,
|
||||
],
|
||||
[
|
||||
880409284677518997550768549487344416321062350742831373397603704465823658986,
|
||||
6876255662475867703077362872097208259197756317287339941435193538565586230,
|
||||
2701916445133770775447884812906226786217969545216086200932273680400909154638,
|
||||
],
|
||||
[
|
||||
425152119158711585559310064242720816611629181537672850898056934507216982586,
|
||||
1475552998258917706756737045704649573088377604240716286977690565239187213744,
|
||||
2413772448122400684309006716414417978370152271397082147158000439863002593561,
|
||||
],
|
||||
[
|
||||
392160855822256520519339260245328807036619920858503984710539815951012864164,
|
||||
1075036996503791536261050742318169965707018400307026402939804424927087093987,
|
||||
2176439430328703902070742432016450246365760303014562857296722712989275658921,
|
||||
],
|
||||
[
|
||||
1413865976587623331051814207977382826721471106513581745229680113383908569693,
|
||||
4879283427490523253696177116563427032332223531862961281430108575019551814,
|
||||
3392583297537374046875199552977614390492290683707960975137418536812266544902,
|
||||
],
|
||||
[
|
||||
3600854486849487646325182927019642276644093512133907046667282144129939150983,
|
||||
2779924664161372134024229593301361846129279572186444474616319283535189797834,
|
||||
2722699960903170449291146429799738181514821447014433304730310678334403972040,
|
||||
],
|
||||
[
|
||||
819109815049226540285781191874507704729062681836086010078910930707209464699,
|
||||
3046121243742768013822760785918001632929744274211027071381357122228091333823,
|
||||
1339019590803056172509793134119156250729668216522001157582155155947567682278,
|
||||
],
|
||||
[
|
||||
1933279639657506214789316403763326578443023901555983256955812717638093967201,
|
||||
2138221547112520744699126051903811860205771600821672121643894708182292213541,
|
||||
2694713515543641924097704224170357995809887124438248292930846280951601597065,
|
||||
],
|
||||
[
|
||||
2471734202930133750093618989223585244499567111661178960753938272334153710615,
|
||||
504903761112092757611047718215309856203214372330635774577409639907729993533,
|
||||
1943979703748281357156510253941035712048221353507135074336243405478613241290,
|
||||
],
|
||||
[
|
||||
684525210957572142559049112233609445802004614280157992196913315652663518936,
|
||||
1705585400798782397786453706717059483604368413512485532079242223503960814508,
|
||||
192429517716023021556170942988476050278432319516032402725586427701913624665,
|
||||
],
|
||||
[
|
||||
1586493702243128040549584165333371192888583026298039652930372758731750166765,
|
||||
686072673323546915014972146032384917012218151266600268450347114036285993377,
|
||||
3464340397998075738891129996710075228740496767934137465519455338004332839215,
|
||||
],
|
||||
[
|
||||
2805249176617071054530589390406083958753103601524808155663551392362371834663,
|
||||
667746464250968521164727418691487653339733392025160477655836902744186489526,
|
||||
1131527712905109997177270289411406385352032457456054589588342450404257139778,
|
||||
],
|
||||
[
|
||||
1908969485750011212309284349900149072003218505891252313183123635318886241171,
|
||||
1025257076985551890132050019084873267454083056307650830147063480409707787695,
|
||||
2153175291918371429502545470578981828372846236838301412119329786849737957977,
|
||||
],
|
||||
[
|
||||
3410257749736714576487217882785226905621212230027780855361670645857085424384,
|
||||
3442969106887588154491488961893254739289120695377621434680934888062399029952,
|
||||
3029953900235731770255937704976720759948880815387104275525268727341390470237,
|
||||
],
|
||||
[
|
||||
85453456084781138713939104192561924536933417707871501802199311333127894466,
|
||||
2730629666577257820220329078741301754580009106438115341296453318350676425129,
|
||||
178242450661072967256438102630920745430303027840919213764087927763335940415,
|
||||
],
|
||||
[
|
||||
2844589222514708695700541363167856718216388819406388706818431442998498677557,
|
||||
3547876269219141094308889387292091231377253967587961309624916269569559952944,
|
||||
2525005406762984211707203144785482908331876505006839217175334833739957826850,
|
||||
],
|
||||
[
|
||||
3096397013555211396701910432830904669391580557191845136003938801598654871345,
|
||||
574424067119200181933992948252007230348512600107123873197603373898923821490,
|
||||
1714030696055067278349157346067719307863507310709155690164546226450579547098,
|
||||
],
|
||||
[
|
||||
2339895272202694698739231405357972261413383527237194045718815176814132612501,
|
||||
3562501318971895161271663840954705079797767042115717360959659475564651685069,
|
||||
69069358687197963617161747606993436483967992689488259107924379545671193749,
|
||||
],
|
||||
[
|
||||
2614502738369008850475068874731531583863538486212691941619835266611116051561,
|
||||
655247349763023251625727726218660142895322325659927266813592114640858573566,
|
||||
2305235672527595714255517865498269719545193172975330668070873705108690670678,
|
||||
],
|
||||
[
|
||||
926416070297755413261159098243058134401665060349723804040714357642180531931,
|
||||
866523735635840246543516964237513287099659681479228450791071595433217821460,
|
||||
2284334068466681424919271582037156124891004191915573957556691163266198707693,
|
||||
],
|
||||
[
|
||||
1812588309302477291425732810913354633465435706480768615104211305579383928792,
|
||||
2836899808619013605432050476764608707770404125005720004551836441247917488507,
|
||||
2989087789022865112405242078196235025698647423649950459911546051695688370523,
|
||||
],
|
||||
[
|
||||
68056284404189102136488263779598243992465747932368669388126367131855404486,
|
||||
505425339250887519581119854377342241317528319745596963584548343662758204398,
|
||||
2118963546856545068961709089296976921067035227488975882615462246481055679215,
|
||||
],
|
||||
[
|
||||
2253872596319969096156004495313034590996995209785432485705134570745135149681,
|
||||
1625090409149943603241183848936692198923183279116014478406452426158572703264,
|
||||
179139838844452470348634657368199622305888473747024389514258107503778442495,
|
||||
],
|
||||
[
|
||||
1567067018147735642071130442904093290030432522257811793540290101391210410341,
|
||||
2737301854006865242314806979738760349397411136469975337509958305470398783585,
|
||||
3002738216460904473515791428798860225499078134627026021350799206894618186256,
|
||||
],
|
||||
[
|
||||
374029488099466837453096950537275565120689146401077127482884887409712315162,
|
||||
973403256517481077805460710540468856199855789930951602150773500862180885363,
|
||||
2691967457038172130555117632010860984519926022632800605713473799739632878867,
|
||||
],
|
||||
[
|
||||
3515906794910381201365530594248181418811879320679684239326734893975752012109,
|
||||
148057579455448384062325089530558091463206199724854022070244924642222283388,
|
||||
1541588700238272710315890873051237741033408846596322948443180470429851502842,
|
||||
],
|
||||
[
|
||||
147013865879011936545137344076637170977925826031496203944786839068852795297,
|
||||
2630278389304735265620281704608245039972003761509102213752997636382302839857,
|
||||
1359048670759642844930007747955701205155822111403150159614453244477853867621,
|
||||
],
|
||||
[
|
||||
2438984569205812336319229336885480537793786558293523767186829418969842616677,
|
||||
2137792255841525507649318539501906353254503076308308692873313199435029594138,
|
||||
2262318076430740712267739371170174514379142884859595360065535117601097652755,
|
||||
],
|
||||
[
|
||||
2792703718581084537295613508201818489836796608902614779596544185252826291584,
|
||||
2294173715793292812015960640392421991604150133581218254866878921346561546149,
|
||||
2770011224727997178743274791849308200493823127651418989170761007078565678171,
|
||||
],
|
||||
]
|
||||
@@ -1,559 +0,0 @@
|
||||
Rate = 3
|
||||
Capacity = 1
|
||||
FullRounds = 8
|
||||
PartialRounds = 84
|
||||
MDS = [[2, 1, 1, 1], [1, 1, 1, 1], [1, 1, 0, 1], [1, 1, 1, -1]]
|
||||
RoundKeys = [
|
||||
[
|
||||
2950795762459345168613727575620414179244544320470208355568817838579231751791,
|
||||
1587446564224215276866294500450702039420286416111469274423465069420553242820,
|
||||
1645965921169490687904413452218868659025437693527479459426157555728339600137,
|
||||
2782373324549879794752287702905278018819686065818504085638398966973694145741,
|
||||
],
|
||||
[
|
||||
3409172630025222641379726933524480516420204828329395644967085131392375707302,
|
||||
2379053116496905638239090788901387719228422033660130943198035907032739387135,
|
||||
2570819397480941104144008784293466051718826502582588529995520356691856497111,
|
||||
3546220846133880637977653625763703334841539452343273304410918449202580719746,
|
||||
],
|
||||
[
|
||||
2720682389492889709700489490056111332164748138023159726590726667539759963454,
|
||||
1899653471897224903834726250400246354200311275092866725547887381599836519005,
|
||||
2369443697923857319844855392163763375394720104106200469525915896159690979559,
|
||||
2354174693689535854311272135513626412848402744119855553970180659094265527996,
|
||||
],
|
||||
[
|
||||
2404084503073127963385083467393598147276436640877011103379112521338973185443,
|
||||
950320777137731763811524327595514151340412860090489448295239456547370725376,
|
||||
2121140748740143694053732746913428481442990369183417228688865837805149503386,
|
||||
2372065044800422557577242066480215868569521938346032514014152523102053709709,
|
||||
],
|
||||
[
|
||||
2618497439310693947058545060953893433487994458443568169824149550389484489896,
|
||||
3518297267402065742048564133910509847197496119850246255805075095266319996916,
|
||||
340529752683340505065238931581518232901634742162506851191464448040657139775,
|
||||
1954876811294863748406056845662382214841467408616109501720437541211031966538,
|
||||
],
|
||||
[
|
||||
813813157354633930267029888722341725864333883175521358739311868164460385261,
|
||||
71901595776070443337150458310956362034911936706490730914901986556638720031,
|
||||
2789761472166115462625363403490399263810962093264318361008954888847594113421,
|
||||
2628791615374802560074754031104384456692791616314774034906110098358135152410,
|
||||
],
|
||||
[
|
||||
3617032588734559635167557152518265808024917503198278888820567553943986939719,
|
||||
2624012360209966117322788103333497793082705816015202046036057821340914061980,
|
||||
149101987103211771991327927827692640556911620408176100290586418839323044234,
|
||||
1039927963829140138166373450440320262590862908847727961488297105916489431045,
|
||||
],
|
||||
[
|
||||
2213946951050724449162431068646025833746639391992751674082854766704900195669,
|
||||
2792724903541814965769131737117981991997031078369482697195201969174353468597,
|
||||
3212031629728871219804596347439383805499808476303618848198208101593976279441,
|
||||
3343514080098703935339621028041191631325798327656683100151836206557453199613,
|
||||
],
|
||||
[
|
||||
614054702436541219556958850933730254992710988573177298270089989048553060199,
|
||||
148148081026449726283933484730968827750202042869875329032965774667206931170,
|
||||
1158283532103191908366672518396366136968613180867652172211392033571980848414,
|
||||
1032400527342371389481069504520755916075559110755235773196747439146396688513,
|
||||
],
|
||||
[
|
||||
806900704622005851310078578853499250941978435851598088619290797134710613736,
|
||||
462498083559902778091095573017508352472262817904991134671058825705968404510,
|
||||
1003580119810278869589347418043095667699674425582646347949349245557449452503,
|
||||
619074932220101074089137133998298830285661916867732916607601635248249357793,
|
||||
],
|
||||
[
|
||||
2635090520059500019661864086615522409798872905401305311748231832709078452746,
|
||||
978252636251682252755279071140187792306115352460774007308726210405257135181,
|
||||
1766912167973123409669091967764158892111310474906691336473559256218048677083,
|
||||
1663265127259512472182980890707014969235283233442916350121860684522654120381,
|
||||
],
|
||||
[
|
||||
3532407621206959585000336211742670185380751515636605428496206887841428074250,
|
||||
2507023127157093845256722098502856938353143387711652912931112668310034975446,
|
||||
3321152907858462102434883844787153373036767230808678981306827073335525034593,
|
||||
3039253036806065280643845548147711477270022154459620569428286684179698125661,
|
||||
],
|
||||
[
|
||||
103480338868480851881924519768416587261556021758163719199282794248762465380,
|
||||
2394049781357087698434751577708655768465803975478348134669006211289636928495,
|
||||
2660531560345476340796109810821127229446538730404600368347902087220064379579,
|
||||
3603166934034556203649050570865466556260359798872408576857928196141785055563,
|
||||
],
|
||||
[
|
||||
1553799760191949768532188139643704561532896296986025007089826672890485412324,
|
||||
2744284717053657689091306578463476341218866418732695211367062598446038965164,
|
||||
320745764922149897598257794663594419839885234101078803811049904310835548856,
|
||||
979382242100682161589753881721708883681034024104145498709287731138044566302,
|
||||
],
|
||||
[
|
||||
1860426855810549882740147175136418997351054138609396651615467358416651354991,
|
||||
336173081054369235994909356892506146234495707857220254489443629387613956145,
|
||||
1632470326779699229772327605759783482411227247311431865655466227711078175883,
|
||||
921958250077481394074960433988881176409497663777043304881055317463712938502,
|
||||
],
|
||||
[
|
||||
3034358982193370602048539901033542101022185309652879937418114324899281842797,
|
||||
25626282149517463867572353922222474817434101087272320606729439087234878607,
|
||||
3002662261401575565838149305485737102400501329139562227180277188790091853682,
|
||||
2939684373453383817196521641512509179310654199629514917426341354023324109367,
|
||||
],
|
||||
[
|
||||
1076484609897998179434851570277297233169621096172424141759873688902355505136,
|
||||
2575095284833160494841112025725243274091830284746697961080467506739203605049,
|
||||
3565075264617591783581665711620369529657840830498005563542124551465195621851,
|
||||
2197016502533303822395077038351174326125210255869204501838837289716363437993,
|
||||
],
|
||||
[
|
||||
331415322883530754594261416546036195982886300052707474899691116664327869405,
|
||||
1935011233711290003793244296594669823169522055520303479680359990463281661839,
|
||||
3495901467168087413996941216661589517270845976538454329511167073314577412322,
|
||||
954195417117133246453562983448451025087661597543338750600301835944144520375,
|
||||
],
|
||||
[
|
||||
1271840477709992894995746871435810599280944810893784031132923384456797925777,
|
||||
2565310762274337662754531859505158700827688964841878141121196528015826671847,
|
||||
3365022288251637014588279139038152521653896670895105540140002607272936852513,
|
||||
1660592021628965529963974299647026602622092163312666588591285654477111176051,
|
||||
],
|
||||
[
|
||||
970104372286014048279296575474974982288801187216974504035759997141059513421,
|
||||
2617024574317953753849168721871770134225690844968986289121504184985993971227,
|
||||
999899815343607746071464113462778273556695659506865124478430189024755832262,
|
||||
2228536129413411161615629030408828764980855956560026807518714080003644769896,
|
||||
],
|
||||
[
|
||||
2701953891198001564547196795777701119629537795442025393867364730330476403227,
|
||||
837078355588159388741598313782044128527494922918203556465116291436461597853,
|
||||
2121749601840466143704862369657561429793951309962582099604848281796392359214,
|
||||
771812260179247428733132708063116523892339056677915387749121983038690154755,
|
||||
],
|
||||
[
|
||||
3317336423132806446086732225036532603224267214833263122557471741829060578219,
|
||||
481570067997721834712647566896657604857788523050900222145547508314620762046,
|
||||
242195042559343964206291740270858862066153636168162642380846129622127460192,
|
||||
2855462178889999218204481481614105202770810647859867354506557827319138379686,
|
||||
],
|
||||
[
|
||||
3525521107148375040131784770413887305850308357895464453970651672160034885202,
|
||||
1320839531502392535964065058804908871811967681250362364246430459003920305799,
|
||||
2514191518588387125173345107242226637171897291221681115249521904869763202419,
|
||||
2798335750958827619666318316247381695117827718387653874070218127140615157902,
|
||||
],
|
||||
[
|
||||
2808467767967035643407948058486565877867906577474361783201337540214875566395,
|
||||
3551834385992706206273955480294669176699286104229279436819137165202231595747,
|
||||
1219439673853113792340300173186247996249367102884530407862469123523013083971,
|
||||
761519904537984520554247997444508040636526566551719396202550009393012691157,
|
||||
],
|
||||
[
|
||||
3355402549169351700500518865338783382387571349497391475317206324155237401353,
|
||||
199541098009731541347317515995192175813554789571447733944970283654592727138,
|
||||
192100490643078165121235261796864975568292640203635147901612231594408079071,
|
||||
1187019357602953326192019968809486933768550466167033084944727938441427050581,
|
||||
],
|
||||
[
|
||||
189525349641911362389041124808934468936759383310282010671081989585219065700,
|
||||
2831653363992091308880573627558515686245403755586311978724025292003353336665,
|
||||
2052859812632218952608271535089179639890275494426396974475479657192657094698,
|
||||
1670756178709659908159049531058853320846231785448204274277900022176591811072,
|
||||
],
|
||||
[
|
||||
3538757242013734574731807289786598937548399719866320954894004830207085723125,
|
||||
710549042741321081781917034337800036872214466705318638023070812391485261299,
|
||||
2345013122330545298606028187653996682275206910242635100920038943391319595180,
|
||||
3528369671971445493932880023233332035122954362711876290904323783426765912206,
|
||||
],
|
||||
[
|
||||
1167120829038120978297497195837406760848728897181138760506162680655977700764,
|
||||
3073243357129146594530765548901087443775563058893907738967898816092270628884,
|
||||
378514724418106317738164464176041649567501099164061863402473942795977719726,
|
||||
333391138410406330127594722511180398159664250722328578952158227406762627796,
|
||||
],
|
||||
[
|
||||
1727570175639917398410201375510924114487348765559913502662122372848626931905,
|
||||
968312190621809249603425066974405725769739606059422769908547372904403793174,
|
||||
360659316299446405855194688051178331671817370423873014757323462844775818348,
|
||||
1386580151907705298970465943238806620109618995410132218037375811184684929291,
|
||||
],
|
||||
[
|
||||
3604888328937389309031638299660239238400230206645344173700074923133890528967,
|
||||
2496185632263372962152518155651824899299616724241852816983268163379540137546,
|
||||
486538168871046887467737983064272608432052269868418721234810979756540672990,
|
||||
1558415498960552213241704009433360128041672577274390114589014204605400783336,
|
||||
],
|
||||
[
|
||||
3512058327686147326577190314835092911156317204978509183234511559551181053926,
|
||||
2235429387083113882635494090887463486491842634403047716936833563914243946191,
|
||||
1290896777143878193192832813769470418518651727840187056683408155503813799882,
|
||||
1143310336918357319571079551779316654556781203013096026972411429993634080835,
|
||||
],
|
||||
[
|
||||
3235435208525081966062419599803346573407862428113723170955762956243193422118,
|
||||
1293239921425673430660897025143433077974838969258268884994339615096356996604,
|
||||
236252269127612784685426260840574970698541177557674806964960352572864382971,
|
||||
1733907592497266237374827232200506798207318263912423249709509725341212026275,
|
||||
],
|
||||
[
|
||||
302004309771755665128395814807589350526779835595021835389022325987048089868,
|
||||
3018926838139221755384801385583867283206879023218491758435446265703006270945,
|
||||
39701437664873825906031098349904330565195980985885489447836580931425171297,
|
||||
908381723021746969965674308809436059628307487140174335882627549095646509778,
|
||||
],
|
||||
[
|
||||
219062858908229855064136253265968615354041842047384625689776811853821594358,
|
||||
1283129863776453589317845316917890202859466483456216900835390291449830275503,
|
||||
418512623547417594896140369190919231877873410935689672661226540908900544012,
|
||||
1792181590047131972851015200157890246436013346535432437041535789841136268632,
|
||||
],
|
||||
[
|
||||
370546432987510607338044736824316856592558876687225326692366316978098770516,
|
||||
3323437805230586112013581113386626899534419826098235300155664022709435756946,
|
||||
910076621742039763058481476739499965761942516177975130656340375573185415877,
|
||||
1762188042455633427137702520675816545396284185254002959309669405982213803405,
|
||||
],
|
||||
[
|
||||
2186362253913140345102191078329764107619534641234549431429008219905315900520,
|
||||
2230647725927681765419218738218528849146504088716182944327179019215826045083,
|
||||
1069243907556644434301190076451112491469636357133398376850435321160857761825,
|
||||
2695241469149243992683268025359863087303400907336026926662328156934068747593,
|
||||
],
|
||||
[
|
||||
1361519681544413849831669554199151294308350560528931040264950307931824877035,
|
||||
1339116632207878730171031743761550901312154740800549632983325427035029084904,
|
||||
790593524918851401449292693473498591068920069246127392274811084156907468875,
|
||||
2723400368331924254840192318398326090089058735091724263333980290765736363637,
|
||||
],
|
||||
[
|
||||
3457180265095920471443772463283225391927927225993685928066766687141729456030,
|
||||
1483675376954327086153452545475557749815683871577400883707749788555424847954,
|
||||
2926303836265506736227240325795090239680154099205721426928300056982414025239,
|
||||
543969119775473768170832347411484329362572550684421616624136244239799475526,
|
||||
],
|
||||
[
|
||||
237401230683847084256617415614300816373730178313253487575312839074042461932,
|
||||
844568412840391587862072008674263874021460074878949862892685736454654414423,
|
||||
151922054871708336050647150237534498235916969120198637893731715254687336644,
|
||||
1299332034710622815055321547569101119597030148120309411086203580212105652312,
|
||||
],
|
||||
[
|
||||
487046922649899823989594814663418784068895385009696501386459462815688122993,
|
||||
1104883249092599185744249485896585912845784382683240114120846423960548576851,
|
||||
1458388705536282069567179348797334876446380557083422364875248475157495514484,
|
||||
850248109622750774031817200193861444623975329881731864752464222442574976566,
|
||||
],
|
||||
[
|
||||
2885843173858536690032695698009109793537724845140477446409245651176355435722,
|
||||
3027068551635372249579348422266406787688980506275086097330568993357835463816,
|
||||
3231892723647447539926175383213338123506134054432701323145045438168976970994,
|
||||
1719080830641935421242626784132692936776388194122314954558418655725251172826,
|
||||
],
|
||||
[
|
||||
1172253756541066126131022537343350498482225068791630219494878195815226839450,
|
||||
1619232269633026603732619978083169293258272967781186544174521481891163985093,
|
||||
3495680684841853175973173610562400042003100419811771341346135531754869014567,
|
||||
1576161515913099892951745452471618612307857113799539794680346855318958552758,
|
||||
],
|
||||
[
|
||||
2618326122974253423403350731396350223238201817594761152626832144510903048529,
|
||||
2696245132758436974032479782852265185094623165224532063951287925001108567649,
|
||||
930116505665110070247395429730201844026054810856263733273443066419816003444,
|
||||
2786389174502246248523918824488629229455088716707062764363111940462137404076,
|
||||
],
|
||||
[
|
||||
1555260846425735320214671887347115247546042526197895180675436886484523605116,
|
||||
2306241912153325247392671742757902161446877415586158295423293240351799505917,
|
||||
411529621724849932999694270803131456243889635467661223241617477462914950626,
|
||||
1542495485262286701469125140275904136434075186064076910329015697714211835205,
|
||||
],
|
||||
[
|
||||
1853045663799041100600825096887578544265580718909350942241802897995488264551,
|
||||
2963055259497271220202739837493041799968576111953080503132045092194513937286,
|
||||
2303806870349915764285872605046527036748108533406243381676768310692344456050,
|
||||
2622104986201990620910286730213140904984256464479840856728424375142929278875,
|
||||
],
|
||||
[
|
||||
2369987021925266811581727383184031736927816625797282287927222602539037105864,
|
||||
285070227712021899602056480426671736057274017903028992288878116056674401781,
|
||||
3034087076179360957800568733595959058628497428787907887933697691951454610691,
|
||||
469095854351700119980323115747590868855368701825706298740201488006320881056,
|
||||
],
|
||||
[
|
||||
360001976264385426746283365024817520563236378289230404095383746911725100012,
|
||||
3438709327109021347267562000879503009590697221730578667498351600602230296178,
|
||||
63573904800572228121671659287593650438456772568903228287754075619928214969,
|
||||
3470881855042989871434874691030920672110111605547839662680968354703074556970,
|
||||
],
|
||||
[
|
||||
724559311507950497340993415408274803001166693839947519425501269424891465492,
|
||||
880409284677518997550768549487344416321062350742831373397603704465823658986,
|
||||
6876255662475867703077362872097208259197756317287339941435193538565586230,
|
||||
2701916445133770775447884812906226786217969545216086200932273680400909154638,
|
||||
],
|
||||
[
|
||||
425152119158711585559310064242720816611629181537672850898056934507216982586,
|
||||
1475552998258917706756737045704649573088377604240716286977690565239187213744,
|
||||
2413772448122400684309006716414417978370152271397082147158000439863002593561,
|
||||
392160855822256520519339260245328807036619920858503984710539815951012864164,
|
||||
],
|
||||
[
|
||||
1075036996503791536261050742318169965707018400307026402939804424927087093987,
|
||||
2176439430328703902070742432016450246365760303014562857296722712989275658921,
|
||||
1413865976587623331051814207977382826721471106513581745229680113383908569693,
|
||||
4879283427490523253696177116563427032332223531862961281430108575019551814,
|
||||
],
|
||||
[
|
||||
3392583297537374046875199552977614390492290683707960975137418536812266544902,
|
||||
3600854486849487646325182927019642276644093512133907046667282144129939150983,
|
||||
2779924664161372134024229593301361846129279572186444474616319283535189797834,
|
||||
2722699960903170449291146429799738181514821447014433304730310678334403972040,
|
||||
],
|
||||
[
|
||||
819109815049226540285781191874507704729062681836086010078910930707209464699,
|
||||
3046121243742768013822760785918001632929744274211027071381357122228091333823,
|
||||
1339019590803056172509793134119156250729668216522001157582155155947567682278,
|
||||
1933279639657506214789316403763326578443023901555983256955812717638093967201,
|
||||
],
|
||||
[
|
||||
2138221547112520744699126051903811860205771600821672121643894708182292213541,
|
||||
2694713515543641924097704224170357995809887124438248292930846280951601597065,
|
||||
2471734202930133750093618989223585244499567111661178960753938272334153710615,
|
||||
504903761112092757611047718215309856203214372330635774577409639907729993533,
|
||||
],
|
||||
[
|
||||
1943979703748281357156510253941035712048221353507135074336243405478613241290,
|
||||
684525210957572142559049112233609445802004614280157992196913315652663518936,
|
||||
1705585400798782397786453706717059483604368413512485532079242223503960814508,
|
||||
192429517716023021556170942988476050278432319516032402725586427701913624665,
|
||||
],
|
||||
[
|
||||
1586493702243128040549584165333371192888583026298039652930372758731750166765,
|
||||
686072673323546915014972146032384917012218151266600268450347114036285993377,
|
||||
3464340397998075738891129996710075228740496767934137465519455338004332839215,
|
||||
2805249176617071054530589390406083958753103601524808155663551392362371834663,
|
||||
],
|
||||
[
|
||||
667746464250968521164727418691487653339733392025160477655836902744186489526,
|
||||
1131527712905109997177270289411406385352032457456054589588342450404257139778,
|
||||
1908969485750011212309284349900149072003218505891252313183123635318886241171,
|
||||
1025257076985551890132050019084873267454083056307650830147063480409707787695,
|
||||
],
|
||||
[
|
||||
2153175291918371429502545470578981828372846236838301412119329786849737957977,
|
||||
3410257749736714576487217882785226905621212230027780855361670645857085424384,
|
||||
3442969106887588154491488961893254739289120695377621434680934888062399029952,
|
||||
3029953900235731770255937704976720759948880815387104275525268727341390470237,
|
||||
],
|
||||
[
|
||||
85453456084781138713939104192561924536933417707871501802199311333127894466,
|
||||
2730629666577257820220329078741301754580009106438115341296453318350676425129,
|
||||
178242450661072967256438102630920745430303027840919213764087927763335940415,
|
||||
2844589222514708695700541363167856718216388819406388706818431442998498677557,
|
||||
],
|
||||
[
|
||||
3547876269219141094308889387292091231377253967587961309624916269569559952944,
|
||||
2525005406762984211707203144785482908331876505006839217175334833739957826850,
|
||||
3096397013555211396701910432830904669391580557191845136003938801598654871345,
|
||||
574424067119200181933992948252007230348512600107123873197603373898923821490,
|
||||
],
|
||||
[
|
||||
1714030696055067278349157346067719307863507310709155690164546226450579547098,
|
||||
2339895272202694698739231405357972261413383527237194045718815176814132612501,
|
||||
3562501318971895161271663840954705079797767042115717360959659475564651685069,
|
||||
69069358687197963617161747606993436483967992689488259107924379545671193749,
|
||||
],
|
||||
[
|
||||
2614502738369008850475068874731531583863538486212691941619835266611116051561,
|
||||
655247349763023251625727726218660142895322325659927266813592114640858573566,
|
||||
2305235672527595714255517865498269719545193172975330668070873705108690670678,
|
||||
926416070297755413261159098243058134401665060349723804040714357642180531931,
|
||||
],
|
||||
[
|
||||
866523735635840246543516964237513287099659681479228450791071595433217821460,
|
||||
2284334068466681424919271582037156124891004191915573957556691163266198707693,
|
||||
1812588309302477291425732810913354633465435706480768615104211305579383928792,
|
||||
2836899808619013605432050476764608707770404125005720004551836441247917488507,
|
||||
],
|
||||
[
|
||||
2989087789022865112405242078196235025698647423649950459911546051695688370523,
|
||||
68056284404189102136488263779598243992465747932368669388126367131855404486,
|
||||
505425339250887519581119854377342241317528319745596963584548343662758204398,
|
||||
2118963546856545068961709089296976921067035227488975882615462246481055679215,
|
||||
],
|
||||
[
|
||||
2253872596319969096156004495313034590996995209785432485705134570745135149681,
|
||||
1625090409149943603241183848936692198923183279116014478406452426158572703264,
|
||||
179139838844452470348634657368199622305888473747024389514258107503778442495,
|
||||
1567067018147735642071130442904093290030432522257811793540290101391210410341,
|
||||
],
|
||||
[
|
||||
2737301854006865242314806979738760349397411136469975337509958305470398783585,
|
||||
3002738216460904473515791428798860225499078134627026021350799206894618186256,
|
||||
374029488099466837453096950537275565120689146401077127482884887409712315162,
|
||||
973403256517481077805460710540468856199855789930951602150773500862180885363,
|
||||
],
|
||||
[
|
||||
2691967457038172130555117632010860984519926022632800605713473799739632878867,
|
||||
3515906794910381201365530594248181418811879320679684239326734893975752012109,
|
||||
148057579455448384062325089530558091463206199724854022070244924642222283388,
|
||||
1541588700238272710315890873051237741033408846596322948443180470429851502842,
|
||||
],
|
||||
[
|
||||
147013865879011936545137344076637170977925826031496203944786839068852795297,
|
||||
2630278389304735265620281704608245039972003761509102213752997636382302839857,
|
||||
1359048670759642844930007747955701205155822111403150159614453244477853867621,
|
||||
2438984569205812336319229336885480537793786558293523767186829418969842616677,
|
||||
],
|
||||
[
|
||||
2137792255841525507649318539501906353254503076308308692873313199435029594138,
|
||||
2262318076430740712267739371170174514379142884859595360065535117601097652755,
|
||||
2792703718581084537295613508201818489836796608902614779596544185252826291584,
|
||||
2294173715793292812015960640392421991604150133581218254866878921346561546149,
|
||||
],
|
||||
[
|
||||
2770011224727997178743274791849308200493823127651418989170761007078565678171,
|
||||
3321642244537785916275181932172303118112488081726311374164578600576901819844,
|
||||
3522708517589950573320671158134804505970724681591943826922697952040487655044,
|
||||
3417974441436557992524691506735790206623600049454586729879955931972546347402,
|
||||
],
|
||||
[
|
||||
175039333145381316571259690443853067809784261609912638686739799135919647022,
|
||||
1930713062131033273316869231148248962041053029742760224583505092759642967464,
|
||||
2971452932574554603554350185069538580257636405419430340233233400633251319042,
|
||||
2774781903758215341037075610938953949868289195845367046186588750871862784919,
|
||||
],
|
||||
[
|
||||
666516874137869653699423537799457099346460194092311952417454613224504932738,
|
||||
1900462225013533249140457703727169176351786259991305560412832202759625668041,
|
||||
2665631186082687279121709429531834469477679375137509769347092380798929714377,
|
||||
837840745988147279235494664091280091563355097569199320366973125128366540061,
|
||||
],
|
||||
[
|
||||
3391544118305848781823721719916289805455110924839794510205940718821197620955,
|
||||
2888553035909938253628892138500390690221493345071933642853222968481016605919,
|
||||
3386241569867597612447901482685846444743718781330869478721963580925825915450,
|
||||
1205126220630896984850042596877918177217334376800874965105642874206963597698,
|
||||
],
|
||||
[
|
||||
3590072615491710252422997155203204584659171612188004116415640739580250394190,
|
||||
692469013329617220154003334549812915100479873898898958632988703738125356983,
|
||||
1623178235190707102808841905143937367808788834203621005714003335195182126335,
|
||||
1972826180775011489122426045504602288576507493792470102803637471568052321297,
|
||||
],
|
||||
[
|
||||
3415141329098504418158191749675997877417539760075593313736376750580696083073,
|
||||
587811537889727046473915684463981273175495137461951211739526104349163747811,
|
||||
2523982964351069134084525951849317400231659428055762640605248929856135518199,
|
||||
2686176526711834950207666047281383173339057216783586039351834948812568447629,
|
||||
],
|
||||
[
|
||||
983144446441739425577690449774542566745526459152966545642451764143532586964,
|
||||
171558252019175695567663688494555626159399786667979998273792882504784080805,
|
||||
332337623010057542760158225837623039780806442976079546879646069338600179518,
|
||||
1264669683963885571544813806669118319675288608634733888843804451222546848295,
|
||||
],
|
||||
[
|
||||
2426165115815723668018318268486497504249785449504758403912155206515511627681,
|
||||
11387399609384288947733630450855186629703576293221897150193655994854764608,
|
||||
2541728569046079092074077754414781968906176513081761690404588216304985421091,
|
||||
47685947554980329431290582269851186106577733250761848107645535357326439312,
|
||||
],
|
||||
[
|
||||
472176388418187405374813530639596064799362505024895746833751173199773896628,
|
||||
2764298116617383397920343358525617195195060562266243809245480210157942112738,
|
||||
486863835068754002670800862273365477867695879270721744227071001883208334054,
|
||||
2973492686137102577527656941792991264994301121122130295965761350095846874635,
|
||||
],
|
||||
[
|
||||
178385615141132702906181473263873416748818415607305319148067639744074654009,
|
||||
533624640096756667052211553746016402543259206286603356120804827761339634127,
|
||||
819406716720171922688026098737835227857400444543748198788964759773510472096,
|
||||
531851793767260921861217458033110066464894334064526987603936107947006031387,
|
||||
],
|
||||
[
|
||||
3269709072483585277009748181134917746036523619604017812342933951952104134829,
|
||||
838191718603413598040249006803464503100808192944407407147899973659013630611,
|
||||
1574561296941310904780257598780779812250055948216417844567262310524022037406,
|
||||
551394354289003977607664358739006072556227894953233419144430578080352094737,
|
||||
],
|
||||
[
|
||||
445076790942318675726839050057337819004979443030540904213920669247413907302,
|
||||
1963946696292687224902912968478695543164747600779913024040878700455222386521,
|
||||
484284614181963381509745298932402076252103342403432879800905151752488144767,
|
||||
2240507606126946994415203252302826782042951346966859379502140796364876543253,
|
||||
],
|
||||
[
|
||||
3237135638753992982179886898758938279897590886053928839613434762582576319619,
|
||||
2334333034701915027889533058426879447140084891006486138782876488162658230991,
|
||||
14411091399844539897439754491034751977136685514851444574462584316609631592,
|
||||
1264480371592407258420308876448697804787923638319277097663041109464608464284,
|
||||
],
|
||||
[
|
||||
671929312763821646360589403212798993954209530574443543917757335777610372144,
|
||||
2513909805455654095962542944994577107405216428214873444765576238504714067396,
|
||||
870121102846043786263357605823753628974859886859187558617096145653709171231,
|
||||
399132620893316356411986266679786708905730068946836982293484206366500277754,
|
||||
],
|
||||
[
|
||||
2855046250836680633532995284655778407402587437073106249445470889390454667586,
|
||||
2063679741125384345396981490971605710211281905716315529671473143278849561151,
|
||||
1433753212258929925682201698758056443128516570551146995210728194816988328337,
|
||||
3334984763425011856632257855270507440816274246647423607159847074739331865077,
|
||||
],
|
||||
[
|
||||
337911293622078184850923533628334646725451591671907148383867096651211846605,
|
||||
559587005295238702015018022040357402231957131094636365177008701077975941644,
|
||||
885963059604819264377490633589388189646118257469490919900554134369512794660,
|
||||
1957748763518471091057032383332840331641373304981058387824598000170709016333,
|
||||
],
|
||||
[
|
||||
3175295982155056798972302481564899381103533409383494814704562889625572018450,
|
||||
498987160612401618114584726510347771865331516606886613019084323862447372555,
|
||||
947374835104260364630171441676101001841507588423166778786886198914150312958,
|
||||
906933977754491302438795274167251538820934378773708095543613756654712689280,
|
||||
],
|
||||
[
|
||||
2170116291766863179909957030577284618726490893598499117272497866180009722894,
|
||||
1801335399574515889082584621772588704763181408217893911806726119813067220453,
|
||||
1942500232535842474530840356353427989892065499159260166135596750084681859966,
|
||||
62936080219825306823124060587235998278756755377419521154040408253893795176,
|
||||
],
|
||||
[
|
||||
3091993939935137795359769774909373279950941171574748645375255810204590357753,
|
||||
1283528386884634267663661033944552098742115012555712906773586466375284501324,
|
||||
1581820717639229420476069802992937438655873471854930764425841549067913106065,
|
||||
2301986095388751633126546121528329200085681648876910655269533407603441046514,
|
||||
],
|
||||
[
|
||||
2850003828037698751961753862613545302539465803982364898225617297398939302949,
|
||||
48024691078494936445046366770271288984930221238071705874025261821606393528,
|
||||
1482336297033144958942154923925185950152551534403871620222916667536030875354,
|
||||
3081177564717719643771186007689458633949181485535169123213511264603782950049,
|
||||
],
|
||||
[
|
||||
3315701127039521853279746297714590495201061397709680410650043502532250578075,
|
||||
3514407611000441301995070394422463400067690470546731164089622325748803106020,
|
||||
368970178199930154322724953487299516224498421233447528815195701420122548537,
|
||||
584353160413525267849669053228533951552602295860601556035386665117717227391,
|
||||
],
|
||||
[
|
||||
752038702160385294706011538400822066722189014251268673051846350397729870418,
|
||||
3594041683498798688197194521326299097635429790757880308152971477196489335154,
|
||||
1367902435756906062215608264424138718742854099315395230911274560900857414183,
|
||||
1828549068951502746189364466794037234789986878381694857475972053743463890779,
|
||||
],
|
||||
[
|
||||
488172495141237210878388657234137733008417573114482400652274985829148564248,
|
||||
962906242461930394022372340919543491337923491322497419797555620396501785566,
|
||||
2275418085010046236619290386129138234541669589549771944697082317642065048898,
|
||||
1966395064658902622886154686288219600816893261614483533899715888994623208964,
|
||||
],
|
||||
[
|
||||
3496095878293416917311185659829821476802828534554531050412634978086916288609,
|
||||
3368478822390537245916137403277928093536087427951052230723275731232142463388,
|
||||
3397410259276620127103231993277518800970669191016277541098821699302368873803,
|
||||
2662600899665871010006649609856695263727220473364611552472965243032255906029,
|
||||
],
|
||||
]
|
||||
@@ -1,651 +0,0 @@
|
||||
Rate = 4
|
||||
Capacity = 1
|
||||
FullRounds = 8
|
||||
PartialRounds = 84
|
||||
MDS = [[3, 1, 1, 1, 1], [1, 2, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, -1, 1], [1, 1, 1, 1, -2]]
|
||||
RoundKeys = [
|
||||
[
|
||||
2950795762459345168613727575620414179244544320470208355568817838579231751791,
|
||||
1587446564224215276866294500450702039420286416111469274423465069420553242820,
|
||||
1645965921169490687904413452218868659025437693527479459426157555728339600137,
|
||||
2782373324549879794752287702905278018819686065818504085638398966973694145741,
|
||||
3409172630025222641379726933524480516420204828329395644967085131392375707302,
|
||||
],
|
||||
[
|
||||
2379053116496905638239090788901387719228422033660130943198035907032739387135,
|
||||
2570819397480941104144008784293466051718826502582588529995520356691856497111,
|
||||
3546220846133880637977653625763703334841539452343273304410918449202580719746,
|
||||
2720682389492889709700489490056111332164748138023159726590726667539759963454,
|
||||
1899653471897224903834726250400246354200311275092866725547887381599836519005,
|
||||
],
|
||||
[
|
||||
2369443697923857319844855392163763375394720104106200469525915896159690979559,
|
||||
2354174693689535854311272135513626412848402744119855553970180659094265527996,
|
||||
2404084503073127963385083467393598147276436640877011103379112521338973185443,
|
||||
950320777137731763811524327595514151340412860090489448295239456547370725376,
|
||||
2121140748740143694053732746913428481442990369183417228688865837805149503386,
|
||||
],
|
||||
[
|
||||
2372065044800422557577242066480215868569521938346032514014152523102053709709,
|
||||
2618497439310693947058545060953893433487994458443568169824149550389484489896,
|
||||
3518297267402065742048564133910509847197496119850246255805075095266319996916,
|
||||
340529752683340505065238931581518232901634742162506851191464448040657139775,
|
||||
1954876811294863748406056845662382214841467408616109501720437541211031966538,
|
||||
],
|
||||
[
|
||||
813813157354633930267029888722341725864333883175521358739311868164460385261,
|
||||
71901595776070443337150458310956362034911936706490730914901986556638720031,
|
||||
2789761472166115462625363403490399263810962093264318361008954888847594113421,
|
||||
2628791615374802560074754031104384456692791616314774034906110098358135152410,
|
||||
3617032588734559635167557152518265808024917503198278888820567553943986939719,
|
||||
],
|
||||
[
|
||||
2624012360209966117322788103333497793082705816015202046036057821340914061980,
|
||||
149101987103211771991327927827692640556911620408176100290586418839323044234,
|
||||
1039927963829140138166373450440320262590862908847727961488297105916489431045,
|
||||
2213946951050724449162431068646025833746639391992751674082854766704900195669,
|
||||
2792724903541814965769131737117981991997031078369482697195201969174353468597,
|
||||
],
|
||||
[
|
||||
3212031629728871219804596347439383805499808476303618848198208101593976279441,
|
||||
3343514080098703935339621028041191631325798327656683100151836206557453199613,
|
||||
614054702436541219556958850933730254992710988573177298270089989048553060199,
|
||||
148148081026449726283933484730968827750202042869875329032965774667206931170,
|
||||
1158283532103191908366672518396366136968613180867652172211392033571980848414,
|
||||
],
|
||||
[
|
||||
1032400527342371389481069504520755916075559110755235773196747439146396688513,
|
||||
806900704622005851310078578853499250941978435851598088619290797134710613736,
|
||||
462498083559902778091095573017508352472262817904991134671058825705968404510,
|
||||
1003580119810278869589347418043095667699674425582646347949349245557449452503,
|
||||
619074932220101074089137133998298830285661916867732916607601635248249357793,
|
||||
],
|
||||
[
|
||||
2635090520059500019661864086615522409798872905401305311748231832709078452746,
|
||||
978252636251682252755279071140187792306115352460774007308726210405257135181,
|
||||
1766912167973123409669091967764158892111310474906691336473559256218048677083,
|
||||
1663265127259512472182980890707014969235283233442916350121860684522654120381,
|
||||
3532407621206959585000336211742670185380751515636605428496206887841428074250,
|
||||
],
|
||||
[
|
||||
2507023127157093845256722098502856938353143387711652912931112668310034975446,
|
||||
3321152907858462102434883844787153373036767230808678981306827073335525034593,
|
||||
3039253036806065280643845548147711477270022154459620569428286684179698125661,
|
||||
103480338868480851881924519768416587261556021758163719199282794248762465380,
|
||||
2394049781357087698434751577708655768465803975478348134669006211289636928495,
|
||||
],
|
||||
[
|
||||
2660531560345476340796109810821127229446538730404600368347902087220064379579,
|
||||
3603166934034556203649050570865466556260359798872408576857928196141785055563,
|
||||
1553799760191949768532188139643704561532896296986025007089826672890485412324,
|
||||
2744284717053657689091306578463476341218866418732695211367062598446038965164,
|
||||
320745764922149897598257794663594419839885234101078803811049904310835548856,
|
||||
],
|
||||
[
|
||||
979382242100682161589753881721708883681034024104145498709287731138044566302,
|
||||
1860426855810549882740147175136418997351054138609396651615467358416651354991,
|
||||
336173081054369235994909356892506146234495707857220254489443629387613956145,
|
||||
1632470326779699229772327605759783482411227247311431865655466227711078175883,
|
||||
921958250077481394074960433988881176409497663777043304881055317463712938502,
|
||||
],
|
||||
[
|
||||
3034358982193370602048539901033542101022185309652879937418114324899281842797,
|
||||
25626282149517463867572353922222474817434101087272320606729439087234878607,
|
||||
3002662261401575565838149305485737102400501329139562227180277188790091853682,
|
||||
2939684373453383817196521641512509179310654199629514917426341354023324109367,
|
||||
1076484609897998179434851570277297233169621096172424141759873688902355505136,
|
||||
],
|
||||
[
|
||||
2575095284833160494841112025725243274091830284746697961080467506739203605049,
|
||||
3565075264617591783581665711620369529657840830498005563542124551465195621851,
|
||||
2197016502533303822395077038351174326125210255869204501838837289716363437993,
|
||||
331415322883530754594261416546036195982886300052707474899691116664327869405,
|
||||
1935011233711290003793244296594669823169522055520303479680359990463281661839,
|
||||
],
|
||||
[
|
||||
3495901467168087413996941216661589517270845976538454329511167073314577412322,
|
||||
954195417117133246453562983448451025087661597543338750600301835944144520375,
|
||||
1271840477709992894995746871435810599280944810893784031132923384456797925777,
|
||||
2565310762274337662754531859505158700827688964841878141121196528015826671847,
|
||||
3365022288251637014588279139038152521653896670895105540140002607272936852513,
|
||||
],
|
||||
[
|
||||
1660592021628965529963974299647026602622092163312666588591285654477111176051,
|
||||
970104372286014048279296575474974982288801187216974504035759997141059513421,
|
||||
2617024574317953753849168721871770134225690844968986289121504184985993971227,
|
||||
999899815343607746071464113462778273556695659506865124478430189024755832262,
|
||||
2228536129413411161615629030408828764980855956560026807518714080003644769896,
|
||||
],
|
||||
[
|
||||
2701953891198001564547196795777701119629537795442025393867364730330476403227,
|
||||
837078355588159388741598313782044128527494922918203556465116291436461597853,
|
||||
2121749601840466143704862369657561429793951309962582099604848281796392359214,
|
||||
771812260179247428733132708063116523892339056677915387749121983038690154755,
|
||||
3317336423132806446086732225036532603224267214833263122557471741829060578219,
|
||||
],
|
||||
[
|
||||
481570067997721834712647566896657604857788523050900222145547508314620762046,
|
||||
242195042559343964206291740270858862066153636168162642380846129622127460192,
|
||||
2855462178889999218204481481614105202770810647859867354506557827319138379686,
|
||||
3525521107148375040131784770413887305850308357895464453970651672160034885202,
|
||||
1320839531502392535964065058804908871811967681250362364246430459003920305799,
|
||||
],
|
||||
[
|
||||
2514191518588387125173345107242226637171897291221681115249521904869763202419,
|
||||
2798335750958827619666318316247381695117827718387653874070218127140615157902,
|
||||
2808467767967035643407948058486565877867906577474361783201337540214875566395,
|
||||
3551834385992706206273955480294669176699286104229279436819137165202231595747,
|
||||
1219439673853113792340300173186247996249367102884530407862469123523013083971,
|
||||
],
|
||||
[
|
||||
761519904537984520554247997444508040636526566551719396202550009393012691157,
|
||||
3355402549169351700500518865338783382387571349497391475317206324155237401353,
|
||||
199541098009731541347317515995192175813554789571447733944970283654592727138,
|
||||
192100490643078165121235261796864975568292640203635147901612231594408079071,
|
||||
1187019357602953326192019968809486933768550466167033084944727938441427050581,
|
||||
],
|
||||
[
|
||||
189525349641911362389041124808934468936759383310282010671081989585219065700,
|
||||
2831653363992091308880573627558515686245403755586311978724025292003353336665,
|
||||
2052859812632218952608271535089179639890275494426396974475479657192657094698,
|
||||
1670756178709659908159049531058853320846231785448204274277900022176591811072,
|
||||
3538757242013734574731807289786598937548399719866320954894004830207085723125,
|
||||
],
|
||||
[
|
||||
710549042741321081781917034337800036872214466705318638023070812391485261299,
|
||||
2345013122330545298606028187653996682275206910242635100920038943391319595180,
|
||||
3528369671971445493932880023233332035122954362711876290904323783426765912206,
|
||||
1167120829038120978297497195837406760848728897181138760506162680655977700764,
|
||||
3073243357129146594530765548901087443775563058893907738967898816092270628884,
|
||||
],
|
||||
[
|
||||
378514724418106317738164464176041649567501099164061863402473942795977719726,
|
||||
333391138410406330127594722511180398159664250722328578952158227406762627796,
|
||||
1727570175639917398410201375510924114487348765559913502662122372848626931905,
|
||||
968312190621809249603425066974405725769739606059422769908547372904403793174,
|
||||
360659316299446405855194688051178331671817370423873014757323462844775818348,
|
||||
],
|
||||
[
|
||||
1386580151907705298970465943238806620109618995410132218037375811184684929291,
|
||||
3604888328937389309031638299660239238400230206645344173700074923133890528967,
|
||||
2496185632263372962152518155651824899299616724241852816983268163379540137546,
|
||||
486538168871046887467737983064272608432052269868418721234810979756540672990,
|
||||
1558415498960552213241704009433360128041672577274390114589014204605400783336,
|
||||
],
|
||||
[
|
||||
3512058327686147326577190314835092911156317204978509183234511559551181053926,
|
||||
2235429387083113882635494090887463486491842634403047716936833563914243946191,
|
||||
1290896777143878193192832813769470418518651727840187056683408155503813799882,
|
||||
1143310336918357319571079551779316654556781203013096026972411429993634080835,
|
||||
3235435208525081966062419599803346573407862428113723170955762956243193422118,
|
||||
],
|
||||
[
|
||||
1293239921425673430660897025143433077974838969258268884994339615096356996604,
|
||||
236252269127612784685426260840574970698541177557674806964960352572864382971,
|
||||
1733907592497266237374827232200506798207318263912423249709509725341212026275,
|
||||
302004309771755665128395814807589350526779835595021835389022325987048089868,
|
||||
3018926838139221755384801385583867283206879023218491758435446265703006270945,
|
||||
],
|
||||
[
|
||||
39701437664873825906031098349904330565195980985885489447836580931425171297,
|
||||
908381723021746969965674308809436059628307487140174335882627549095646509778,
|
||||
219062858908229855064136253265968615354041842047384625689776811853821594358,
|
||||
1283129863776453589317845316917890202859466483456216900835390291449830275503,
|
||||
418512623547417594896140369190919231877873410935689672661226540908900544012,
|
||||
],
|
||||
[
|
||||
1792181590047131972851015200157890246436013346535432437041535789841136268632,
|
||||
370546432987510607338044736824316856592558876687225326692366316978098770516,
|
||||
3323437805230586112013581113386626899534419826098235300155664022709435756946,
|
||||
910076621742039763058481476739499965761942516177975130656340375573185415877,
|
||||
1762188042455633427137702520675816545396284185254002959309669405982213803405,
|
||||
],
|
||||
[
|
||||
2186362253913140345102191078329764107619534641234549431429008219905315900520,
|
||||
2230647725927681765419218738218528849146504088716182944327179019215826045083,
|
||||
1069243907556644434301190076451112491469636357133398376850435321160857761825,
|
||||
2695241469149243992683268025359863087303400907336026926662328156934068747593,
|
||||
1361519681544413849831669554199151294308350560528931040264950307931824877035,
|
||||
],
|
||||
[
|
||||
1339116632207878730171031743761550901312154740800549632983325427035029084904,
|
||||
790593524918851401449292693473498591068920069246127392274811084156907468875,
|
||||
2723400368331924254840192318398326090089058735091724263333980290765736363637,
|
||||
3457180265095920471443772463283225391927927225993685928066766687141729456030,
|
||||
1483675376954327086153452545475557749815683871577400883707749788555424847954,
|
||||
],
|
||||
[
|
||||
2926303836265506736227240325795090239680154099205721426928300056982414025239,
|
||||
543969119775473768170832347411484329362572550684421616624136244239799475526,
|
||||
237401230683847084256617415614300816373730178313253487575312839074042461932,
|
||||
844568412840391587862072008674263874021460074878949862892685736454654414423,
|
||||
151922054871708336050647150237534498235916969120198637893731715254687336644,
|
||||
],
|
||||
[
|
||||
1299332034710622815055321547569101119597030148120309411086203580212105652312,
|
||||
487046922649899823989594814663418784068895385009696501386459462815688122993,
|
||||
1104883249092599185744249485896585912845784382683240114120846423960548576851,
|
||||
1458388705536282069567179348797334876446380557083422364875248475157495514484,
|
||||
850248109622750774031817200193861444623975329881731864752464222442574976566,
|
||||
],
|
||||
[
|
||||
2885843173858536690032695698009109793537724845140477446409245651176355435722,
|
||||
3027068551635372249579348422266406787688980506275086097330568993357835463816,
|
||||
3231892723647447539926175383213338123506134054432701323145045438168976970994,
|
||||
1719080830641935421242626784132692936776388194122314954558418655725251172826,
|
||||
1172253756541066126131022537343350498482225068791630219494878195815226839450,
|
||||
],
|
||||
[
|
||||
1619232269633026603732619978083169293258272967781186544174521481891163985093,
|
||||
3495680684841853175973173610562400042003100419811771341346135531754869014567,
|
||||
1576161515913099892951745452471618612307857113799539794680346855318958552758,
|
||||
2618326122974253423403350731396350223238201817594761152626832144510903048529,
|
||||
2696245132758436974032479782852265185094623165224532063951287925001108567649,
|
||||
],
|
||||
[
|
||||
930116505665110070247395429730201844026054810856263733273443066419816003444,
|
||||
2786389174502246248523918824488629229455088716707062764363111940462137404076,
|
||||
1555260846425735320214671887347115247546042526197895180675436886484523605116,
|
||||
2306241912153325247392671742757902161446877415586158295423293240351799505917,
|
||||
411529621724849932999694270803131456243889635467661223241617477462914950626,
|
||||
],
|
||||
[
|
||||
1542495485262286701469125140275904136434075186064076910329015697714211835205,
|
||||
1853045663799041100600825096887578544265580718909350942241802897995488264551,
|
||||
2963055259497271220202739837493041799968576111953080503132045092194513937286,
|
||||
2303806870349915764285872605046527036748108533406243381676768310692344456050,
|
||||
2622104986201990620910286730213140904984256464479840856728424375142929278875,
|
||||
],
|
||||
[
|
||||
2369987021925266811581727383184031736927816625797282287927222602539037105864,
|
||||
285070227712021899602056480426671736057274017903028992288878116056674401781,
|
||||
3034087076179360957800568733595959058628497428787907887933697691951454610691,
|
||||
469095854351700119980323115747590868855368701825706298740201488006320881056,
|
||||
360001976264385426746283365024817520563236378289230404095383746911725100012,
|
||||
],
|
||||
[
|
||||
3438709327109021347267562000879503009590697221730578667498351600602230296178,
|
||||
63573904800572228121671659287593650438456772568903228287754075619928214969,
|
||||
3470881855042989871434874691030920672110111605547839662680968354703074556970,
|
||||
724559311507950497340993415408274803001166693839947519425501269424891465492,
|
||||
880409284677518997550768549487344416321062350742831373397603704465823658986,
|
||||
],
|
||||
[
|
||||
6876255662475867703077362872097208259197756317287339941435193538565586230,
|
||||
2701916445133770775447884812906226786217969545216086200932273680400909154638,
|
||||
425152119158711585559310064242720816611629181537672850898056934507216982586,
|
||||
1475552998258917706756737045704649573088377604240716286977690565239187213744,
|
||||
2413772448122400684309006716414417978370152271397082147158000439863002593561,
|
||||
],
|
||||
[
|
||||
392160855822256520519339260245328807036619920858503984710539815951012864164,
|
||||
1075036996503791536261050742318169965707018400307026402939804424927087093987,
|
||||
2176439430328703902070742432016450246365760303014562857296722712989275658921,
|
||||
1413865976587623331051814207977382826721471106513581745229680113383908569693,
|
||||
4879283427490523253696177116563427032332223531862961281430108575019551814,
|
||||
],
|
||||
[
|
||||
3392583297537374046875199552977614390492290683707960975137418536812266544902,
|
||||
3600854486849487646325182927019642276644093512133907046667282144129939150983,
|
||||
2779924664161372134024229593301361846129279572186444474616319283535189797834,
|
||||
2722699960903170449291146429799738181514821447014433304730310678334403972040,
|
||||
819109815049226540285781191874507704729062681836086010078910930707209464699,
|
||||
],
|
||||
[
|
||||
3046121243742768013822760785918001632929744274211027071381357122228091333823,
|
||||
1339019590803056172509793134119156250729668216522001157582155155947567682278,
|
||||
1933279639657506214789316403763326578443023901555983256955812717638093967201,
|
||||
2138221547112520744699126051903811860205771600821672121643894708182292213541,
|
||||
2694713515543641924097704224170357995809887124438248292930846280951601597065,
|
||||
],
|
||||
[
|
||||
2471734202930133750093618989223585244499567111661178960753938272334153710615,
|
||||
504903761112092757611047718215309856203214372330635774577409639907729993533,
|
||||
1943979703748281357156510253941035712048221353507135074336243405478613241290,
|
||||
684525210957572142559049112233609445802004614280157992196913315652663518936,
|
||||
1705585400798782397786453706717059483604368413512485532079242223503960814508,
|
||||
],
|
||||
[
|
||||
192429517716023021556170942988476050278432319516032402725586427701913624665,
|
||||
1586493702243128040549584165333371192888583026298039652930372758731750166765,
|
||||
686072673323546915014972146032384917012218151266600268450347114036285993377,
|
||||
3464340397998075738891129996710075228740496767934137465519455338004332839215,
|
||||
2805249176617071054530589390406083958753103601524808155663551392362371834663,
|
||||
],
|
||||
[
|
||||
667746464250968521164727418691487653339733392025160477655836902744186489526,
|
||||
1131527712905109997177270289411406385352032457456054589588342450404257139778,
|
||||
1908969485750011212309284349900149072003218505891252313183123635318886241171,
|
||||
1025257076985551890132050019084873267454083056307650830147063480409707787695,
|
||||
2153175291918371429502545470578981828372846236838301412119329786849737957977,
|
||||
],
|
||||
[
|
||||
3410257749736714576487217882785226905621212230027780855361670645857085424384,
|
||||
3442969106887588154491488961893254739289120695377621434680934888062399029952,
|
||||
3029953900235731770255937704976720759948880815387104275525268727341390470237,
|
||||
85453456084781138713939104192561924536933417707871501802199311333127894466,
|
||||
2730629666577257820220329078741301754580009106438115341296453318350676425129,
|
||||
],
|
||||
[
|
||||
178242450661072967256438102630920745430303027840919213764087927763335940415,
|
||||
2844589222514708695700541363167856718216388819406388706818431442998498677557,
|
||||
3547876269219141094308889387292091231377253967587961309624916269569559952944,
|
||||
2525005406762984211707203144785482908331876505006839217175334833739957826850,
|
||||
3096397013555211396701910432830904669391580557191845136003938801598654871345,
|
||||
],
|
||||
[
|
||||
574424067119200181933992948252007230348512600107123873197603373898923821490,
|
||||
1714030696055067278349157346067719307863507310709155690164546226450579547098,
|
||||
2339895272202694698739231405357972261413383527237194045718815176814132612501,
|
||||
3562501318971895161271663840954705079797767042115717360959659475564651685069,
|
||||
69069358687197963617161747606993436483967992689488259107924379545671193749,
|
||||
],
|
||||
[
|
||||
2614502738369008850475068874731531583863538486212691941619835266611116051561,
|
||||
655247349763023251625727726218660142895322325659927266813592114640858573566,
|
||||
2305235672527595714255517865498269719545193172975330668070873705108690670678,
|
||||
926416070297755413261159098243058134401665060349723804040714357642180531931,
|
||||
866523735635840246543516964237513287099659681479228450791071595433217821460,
|
||||
],
|
||||
[
|
||||
2284334068466681424919271582037156124891004191915573957556691163266198707693,
|
||||
1812588309302477291425732810913354633465435706480768615104211305579383928792,
|
||||
2836899808619013605432050476764608707770404125005720004551836441247917488507,
|
||||
2989087789022865112405242078196235025698647423649950459911546051695688370523,
|
||||
68056284404189102136488263779598243992465747932368669388126367131855404486,
|
||||
],
|
||||
[
|
||||
505425339250887519581119854377342241317528319745596963584548343662758204398,
|
||||
2118963546856545068961709089296976921067035227488975882615462246481055679215,
|
||||
2253872596319969096156004495313034590996995209785432485705134570745135149681,
|
||||
1625090409149943603241183848936692198923183279116014478406452426158572703264,
|
||||
179139838844452470348634657368199622305888473747024389514258107503778442495,
|
||||
],
|
||||
[
|
||||
1567067018147735642071130442904093290030432522257811793540290101391210410341,
|
||||
2737301854006865242314806979738760349397411136469975337509958305470398783585,
|
||||
3002738216460904473515791428798860225499078134627026021350799206894618186256,
|
||||
374029488099466837453096950537275565120689146401077127482884887409712315162,
|
||||
973403256517481077805460710540468856199855789930951602150773500862180885363,
|
||||
],
|
||||
[
|
||||
2691967457038172130555117632010860984519926022632800605713473799739632878867,
|
||||
3515906794910381201365530594248181418811879320679684239326734893975752012109,
|
||||
148057579455448384062325089530558091463206199724854022070244924642222283388,
|
||||
1541588700238272710315890873051237741033408846596322948443180470429851502842,
|
||||
147013865879011936545137344076637170977925826031496203944786839068852795297,
|
||||
],
|
||||
[
|
||||
2630278389304735265620281704608245039972003761509102213752997636382302839857,
|
||||
1359048670759642844930007747955701205155822111403150159614453244477853867621,
|
||||
2438984569205812336319229336885480537793786558293523767186829418969842616677,
|
||||
2137792255841525507649318539501906353254503076308308692873313199435029594138,
|
||||
2262318076430740712267739371170174514379142884859595360065535117601097652755,
|
||||
],
|
||||
[
|
||||
2792703718581084537295613508201818489836796608902614779596544185252826291584,
|
||||
2294173715793292812015960640392421991604150133581218254866878921346561546149,
|
||||
2770011224727997178743274791849308200493823127651418989170761007078565678171,
|
||||
3321642244537785916275181932172303118112488081726311374164578600576901819844,
|
||||
3522708517589950573320671158134804505970724681591943826922697952040487655044,
|
||||
],
|
||||
[
|
||||
3417974441436557992524691506735790206623600049454586729879955931972546347402,
|
||||
175039333145381316571259690443853067809784261609912638686739799135919647022,
|
||||
1930713062131033273316869231148248962041053029742760224583505092759642967464,
|
||||
2971452932574554603554350185069538580257636405419430340233233400633251319042,
|
||||
2774781903758215341037075610938953949868289195845367046186588750871862784919,
|
||||
],
|
||||
[
|
||||
666516874137869653699423537799457099346460194092311952417454613224504932738,
|
||||
1900462225013533249140457703727169176351786259991305560412832202759625668041,
|
||||
2665631186082687279121709429531834469477679375137509769347092380798929714377,
|
||||
837840745988147279235494664091280091563355097569199320366973125128366540061,
|
||||
3391544118305848781823721719916289805455110924839794510205940718821197620955,
|
||||
],
|
||||
[
|
||||
2888553035909938253628892138500390690221493345071933642853222968481016605919,
|
||||
3386241569867597612447901482685846444743718781330869478721963580925825915450,
|
||||
1205126220630896984850042596877918177217334376800874965105642874206963597698,
|
||||
3590072615491710252422997155203204584659171612188004116415640739580250394190,
|
||||
692469013329617220154003334549812915100479873898898958632988703738125356983,
|
||||
],
|
||||
[
|
||||
1623178235190707102808841905143937367808788834203621005714003335195182126335,
|
||||
1972826180775011489122426045504602288576507493792470102803637471568052321297,
|
||||
3415141329098504418158191749675997877417539760075593313736376750580696083073,
|
||||
587811537889727046473915684463981273175495137461951211739526104349163747811,
|
||||
2523982964351069134084525951849317400231659428055762640605248929856135518199,
|
||||
],
|
||||
[
|
||||
2686176526711834950207666047281383173339057216783586039351834948812568447629,
|
||||
983144446441739425577690449774542566745526459152966545642451764143532586964,
|
||||
171558252019175695567663688494555626159399786667979998273792882504784080805,
|
||||
332337623010057542760158225837623039780806442976079546879646069338600179518,
|
||||
1264669683963885571544813806669118319675288608634733888843804451222546848295,
|
||||
],
|
||||
[
|
||||
2426165115815723668018318268486497504249785449504758403912155206515511627681,
|
||||
11387399609384288947733630450855186629703576293221897150193655994854764608,
|
||||
2541728569046079092074077754414781968906176513081761690404588216304985421091,
|
||||
47685947554980329431290582269851186106577733250761848107645535357326439312,
|
||||
472176388418187405374813530639596064799362505024895746833751173199773896628,
|
||||
],
|
||||
[
|
||||
2764298116617383397920343358525617195195060562266243809245480210157942112738,
|
||||
486863835068754002670800862273365477867695879270721744227071001883208334054,
|
||||
2973492686137102577527656941792991264994301121122130295965761350095846874635,
|
||||
178385615141132702906181473263873416748818415607305319148067639744074654009,
|
||||
533624640096756667052211553746016402543259206286603356120804827761339634127,
|
||||
],
|
||||
[
|
||||
819406716720171922688026098737835227857400444543748198788964759773510472096,
|
||||
531851793767260921861217458033110066464894334064526987603936107947006031387,
|
||||
3269709072483585277009748181134917746036523619604017812342933951952104134829,
|
||||
838191718603413598040249006803464503100808192944407407147899973659013630611,
|
||||
1574561296941310904780257598780779812250055948216417844567262310524022037406,
|
||||
],
|
||||
[
|
||||
551394354289003977607664358739006072556227894953233419144430578080352094737,
|
||||
445076790942318675726839050057337819004979443030540904213920669247413907302,
|
||||
1963946696292687224902912968478695543164747600779913024040878700455222386521,
|
||||
484284614181963381509745298932402076252103342403432879800905151752488144767,
|
||||
2240507606126946994415203252302826782042951346966859379502140796364876543253,
|
||||
],
|
||||
[
|
||||
3237135638753992982179886898758938279897590886053928839613434762582576319619,
|
||||
2334333034701915027889533058426879447140084891006486138782876488162658230991,
|
||||
14411091399844539897439754491034751977136685514851444574462584316609631592,
|
||||
1264480371592407258420308876448697804787923638319277097663041109464608464284,
|
||||
671929312763821646360589403212798993954209530574443543917757335777610372144,
|
||||
],
|
||||
[
|
||||
2513909805455654095962542944994577107405216428214873444765576238504714067396,
|
||||
870121102846043786263357605823753628974859886859187558617096145653709171231,
|
||||
399132620893316356411986266679786708905730068946836982293484206366500277754,
|
||||
2855046250836680633532995284655778407402587437073106249445470889390454667586,
|
||||
2063679741125384345396981490971605710211281905716315529671473143278849561151,
|
||||
],
|
||||
[
|
||||
1433753212258929925682201698758056443128516570551146995210728194816988328337,
|
||||
3334984763425011856632257855270507440816274246647423607159847074739331865077,
|
||||
337911293622078184850923533628334646725451591671907148383867096651211846605,
|
||||
559587005295238702015018022040357402231957131094636365177008701077975941644,
|
||||
885963059604819264377490633589388189646118257469490919900554134369512794660,
|
||||
],
|
||||
[
|
||||
1957748763518471091057032383332840331641373304981058387824598000170709016333,
|
||||
3175295982155056798972302481564899381103533409383494814704562889625572018450,
|
||||
498987160612401618114584726510347771865331516606886613019084323862447372555,
|
||||
947374835104260364630171441676101001841507588423166778786886198914150312958,
|
||||
906933977754491302438795274167251538820934378773708095543613756654712689280,
|
||||
],
|
||||
[
|
||||
2170116291766863179909957030577284618726490893598499117272497866180009722894,
|
||||
1801335399574515889082584621772588704763181408217893911806726119813067220453,
|
||||
1942500232535842474530840356353427989892065499159260166135596750084681859966,
|
||||
62936080219825306823124060587235998278756755377419521154040408253893795176,
|
||||
3091993939935137795359769774909373279950941171574748645375255810204590357753,
|
||||
],
|
||||
[
|
||||
1283528386884634267663661033944552098742115012555712906773586466375284501324,
|
||||
1581820717639229420476069802992937438655873471854930764425841549067913106065,
|
||||
2301986095388751633126546121528329200085681648876910655269533407603441046514,
|
||||
2850003828037698751961753862613545302539465803982364898225617297398939302949,
|
||||
48024691078494936445046366770271288984930221238071705874025261821606393528,
|
||||
],
|
||||
[
|
||||
1482336297033144958942154923925185950152551534403871620222916667536030875354,
|
||||
3081177564717719643771186007689458633949181485535169123213511264603782950049,
|
||||
3315701127039521853279746297714590495201061397709680410650043502532250578075,
|
||||
3514407611000441301995070394422463400067690470546731164089622325748803106020,
|
||||
368970178199930154322724953487299516224498421233447528815195701420122548537,
|
||||
],
|
||||
[
|
||||
584353160413525267849669053228533951552602295860601556035386665117717227391,
|
||||
752038702160385294706011538400822066722189014251268673051846350397729870418,
|
||||
3594041683498798688197194521326299097635429790757880308152971477196489335154,
|
||||
1367902435756906062215608264424138718742854099315395230911274560900857414183,
|
||||
1828549068951502746189364466794037234789986878381694857475972053743463890779,
|
||||
],
|
||||
[
|
||||
488172495141237210878388657234137733008417573114482400652274985829148564248,
|
||||
962906242461930394022372340919543491337923491322497419797555620396501785566,
|
||||
2275418085010046236619290386129138234541669589549771944697082317642065048898,
|
||||
1966395064658902622886154686288219600816893261614483533899715888994623208964,
|
||||
3496095878293416917311185659829821476802828534554531050412634978086916288609,
|
||||
],
|
||||
[
|
||||
3368478822390537245916137403277928093536087427951052230723275731232142463388,
|
||||
3397410259276620127103231993277518800970669191016277541098821699302368873803,
|
||||
2662600899665871010006649609856695263727220473364611552472965243032255906029,
|
||||
2854831720595596992200155718152374313555878203864206470581502555480894633975,
|
||||
2417859092561967752135741161218626374900182454089059862468108240576782064037,
|
||||
],
|
||||
[
|
||||
1064506915903089299531724594973601253341866933071158266140674053459433520889,
|
||||
243845138053687262800349059300355289745206315347524675450796070948867090098,
|
||||
1952653154963756062322124110012629666160000286707762177032475477295929736283,
|
||||
2760979128531476595658428672038276216079708408852493051222686009638650156041,
|
||||
3341178930260137001230946104398194306290005446746057811731360203227371301716,
|
||||
],
|
||||
[
|
||||
1033242545866274439991875444609632860132556714736615395036273942261573810479,
|
||||
3567973410830779135148598005871071456943945697865168835204985462698751038238,
|
||||
23014034649293369426970379738102323014738017168969687350330825050016457105,
|
||||
1146720508452451012445869043641390200263192255569203352823376998708972325392,
|
||||
2553707028642376593497768606567528232999203496079990242456254686325586089356,
|
||||
],
|
||||
[
|
||||
269729857648436699208023125596593246149228245518586029792966091405383426269,
|
||||
276912682886955358118649215147238115764108757952690361549816619060658800027,
|
||||
2367180947887796341722261610916728725977893583923967218630363334645641817362,
|
||||
2398694802751362950028137620758033447242325333923222365760836442417755445092,
|
||||
984868389243025029364428136317275892280780834039611841422502834917752411391,
|
||||
],
|
||||
[
|
||||
861353329558771468244040268521983016756775808329676883407171471251365927595,
|
||||
2498672969617384807617108262141800974986393948110233099680635130601163654234,
|
||||
1336236634145657673540555267430353130305889434115514586892320600753700983325,
|
||||
980337801407886250576371882962628290239239581416378379141354256717803603922,
|
||||
2308558359523317875952657835109605515063994805873180719205156915762120497245,
|
||||
],
|
||||
[
|
||||
2116737905426837141304542819940293184404010538896700217242374222514653607487,
|
||||
2143995283326808680518644927890182524580312777400009071739277407358043120199,
|
||||
3038758768133404431511594054950351369492648883179154555267474054094234927849,
|
||||
981824005865625678985009911415023115269386212492064371040001594972137748141,
|
||||
2427990511715778580869565219059895697855813782250850855111162965998948386792,
|
||||
],
|
||||
[
|
||||
1987498156785173719076522405088076990979859292718600184358583152317049836167,
|
||||
1633834915134208237423144264187482951766302060112099587851513525797020813799,
|
||||
2895454976388515752029424688351979030650325184941524820409482023485820781526,
|
||||
941019661238578826272324221721825852217063629464317974190162904813488515671,
|
||||
2529926057929249454763690180607677568685011502604470585585763159431333258299,
|
||||
],
|
||||
[
|
||||
2604831509257756199338105380847564711923112853239827243306562341166492672823,
|
||||
2300475954087415591738767759767032267163723345312082546282694920273655145455,
|
||||
1954000528502201000509342111010021527425422549437946241062907964768089317082,
|
||||
1179936151696782249912570883839105595634344582873818018332922940963046083567,
|
||||
3077707030301573630126144767923697288658782137457660869231140049571827937228,
|
||||
],
|
||||
[
|
||||
1062324397142900251844488719868780667589966366756786302007970554437994421840,
|
||||
353718609497993885193404630053532608155520921625518104461520254335222009911,
|
||||
770557645309607171206012551080400276506165720184677119001983749356594531977,
|
||||
3043628430985247363392058521341757139056029350680498644930013342982472853636,
|
||||
1694968537785457252742656255724723357998402478572600479401200420305593921487,
|
||||
],
|
||||
[
|
||||
539865665379093791531434211889371819368504193082947002067781562776138072582,
|
||||
3473466148775696692731190426971123680342615414200262605154732883324298196699,
|
||||
482783534456196983135936103604928650836406142744767857356485953118411089098,
|
||||
2389101033971236780034779577432189630800997581132154923233144722790749715251,
|
||||
845264223568475649981141803833883014312596504303895519674002924871878791033,
|
||||
],
|
||||
[
|
||||
3027004059915270231142566724881373969831662022738947178800901294120992473905,
|
||||
2169574859350740480088697859610203373582027214052754592019828328614087431593,
|
||||
3515527080764222354309565181793838292349410992793070639041305826153436624160,
|
||||
1817926918350512904327755405973355211358017834277255662858654992240629698587,
|
||||
1999148133619270973098477176176178514394558202995832714883251820350860287223,
|
||||
],
|
||||
[
|
||||
1203131300029280096510929599113528018338088236684405405384757591977164161039,
|
||||
336815403657101171302040383579077521911288747438919304948637997306314852594,
|
||||
986661060847815533035934253464295060766339947679669645818832311132001095573,
|
||||
2291116974939980228917916563988261327966840303336559854772343651559589512651,
|
||||
3421243089992476528970346847858594146122972226790673723411896208702859892637,
|
||||
],
|
||||
[
|
||||
1015505198663386486420800821559060487156096175034250154764824837183581949724,
|
||||
1165880582987807286271819576391581724550686829511475839624601920297855380101,
|
||||
904232961143172831178860280790910264843503022179578981166030973682571903458,
|
||||
261322216292849827900157598748641385787016033372999683866859675894253115357,
|
||||
3060676319159217735181388708455879854358158161989877552543698103915296690395,
|
||||
],
|
||||
[
|
||||
1175560144527845912984609340783959238735643215413930887771084560168082442967,
|
||||
2813871258576082360085006002528268796351819524936446195552260262614692343332,
|
||||
1841341101531851399935829271555098629075809587212843292354556374386667658235,
|
||||
3076135575511709688509914361447080149794919016880133063891720256749999834767,
|
||||
753111801049754117414662684453226478940731922961768343984187479992842213733,
|
||||
],
|
||||
[
|
||||
1405657437118503342762241742745888533114216548278983907019917904938403345580,
|
||||
3111186124713876864436867307979940633543281080828379725576742174555539054855,
|
||||
3404463650394703220454952017098727360005393139199301323890695570346564876407,
|
||||
2024087816190101179456573591359233695334184711688920998987373624570170649371,
|
||||
2770035625774572095496575568588054654502991645588385802705097377675051032967,
|
||||
],
|
||||
[
|
||||
437058215235292632621847481185406671372191763951486300610124033096831557414,
|
||||
1345792773780982398809956395232061067669190682958320579442454533085407626029,
|
||||
925357273912625669941681596445839316566672314870287993638671283923476231904,
|
||||
3288133122086768300615066039539687885053110015077924175836976549020438910830,
|
||||
666190075990703867784232802074474372379358766701681865975596503982238839889,
|
||||
],
|
||||
[
|
||||
2664898601165892062970298960258838238925231697327906221693001926762280012052,
|
||||
2075648691532387787722427044464731934171216054855867223374228487601569118337,
|
||||
3173725544188532489243684991828985285646224157242834030308807120745121062293,
|
||||
1517474443612606408422643323550409253700128234157734252330869178582583531320,
|
||||
1593950878945144789965609248470060076911813704207225832606804796819386297511,
|
||||
],
|
||||
[
|
||||
141195541167651298813588829225208004611326987855926870823948793274702167509,
|
||||
2990187949585642302497822222637786229364740008175968941859105979392907839776,
|
||||
2893807105405820282316438050347503569385510241526138409321358916388308586443,
|
||||
1379719211597875648759619903854862028510320482486109668868067715175935658353,
|
||||
2702780364788282233075255946852944970202849869091427738791947810055591218061,
|
||||
],
|
||||
[
|
||||
1825815734419326277729273926504439575157952821379179501821641713286627304656,
|
||||
1481344458867016048625916723816339719872443766684158199301690902395849166360,
|
||||
2014084774259125722186109781197998076881266739680534358898592778318128968629,
|
||||
2612744185006548312909661512508122065214170543806989291921289897662387203493,
|
||||
2486291022451231582267428921150634472835925206862678364689227838329114330247,
|
||||
],
|
||||
]
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,53 +0,0 @@
|
||||
import { deepStrictEqual, throws } from 'assert';
|
||||
import { describe, should } from 'micro-should';
|
||||
import * as starknet from '../../lib/esm/stark.js';
|
||||
import * as fc from 'fast-check';
|
||||
|
||||
const FC_BIGINT = fc.bigInt(1n + 1n, starknet.CURVE.n - 1n);
|
||||
|
||||
describe('starknet property', () => {
|
||||
should('Point#toHex() roundtrip', () => {
|
||||
fc.assert(
|
||||
fc.property(FC_BIGINT, (x) => {
|
||||
const point1 = starknet.ProjectivePoint.fromPrivateKey(x);
|
||||
const hex = point1.toHex(true);
|
||||
deepStrictEqual(starknet.ProjectivePoint.fromHex(hex).toHex(true), hex);
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
should('Signature.fromCompactHex() roundtrip', () => {
|
||||
fc.assert(
|
||||
fc.property(FC_BIGINT, FC_BIGINT, (r, s) => {
|
||||
const sig = new starknet.Signature(r, s);
|
||||
deepStrictEqual(starknet.Signature.fromCompact(sig.toCompactHex()), sig);
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
should('Signature.fromDERHex() roundtrip', () => {
|
||||
fc.assert(
|
||||
fc.property(FC_BIGINT, FC_BIGINT, (r, s) => {
|
||||
const sig = new starknet.Signature(r, s);
|
||||
deepStrictEqual(starknet.Signature.fromDER(sig.toDERHex()), sig);
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
should('verify()/should verify random signatures', () =>
|
||||
fc.assert(
|
||||
fc.property(FC_BIGINT, fc.hexaString({ minLength: 64, maxLength: 64 }), (privNum, msg) => {
|
||||
const privKey = privNum.toString(16).padStart(64, '0');
|
||||
const pub = starknet.getPublicKey(privKey);
|
||||
const sig = starknet.sign(msg, privKey);
|
||||
deepStrictEqual(starknet.verify(sig, msg, pub), true);
|
||||
})
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
// ESM is broken.
|
||||
import url from 'url';
|
||||
if (import.meta.url === url.pathToFileURL(process.argv[1]).href) {
|
||||
should.run();
|
||||
}
|
||||
@@ -1,288 +0,0 @@
|
||||
import { deepStrictEqual, throws } from 'assert';
|
||||
import { describe, should } from 'micro-should';
|
||||
import { hex, utf8 } from '@scure/base';
|
||||
import * as bip32 from '@scure/bip32';
|
||||
import * as bip39 from '@scure/bip39';
|
||||
import * as starknet from '../../lib/esm/stark.js';
|
||||
import { default as sigVec } from './fixtures/rfc6979_signature_test_vector.json' assert { type: 'json' };
|
||||
import { default as precomputedKeys } from './fixtures/keys_precomputed.json' assert { type: 'json' };
|
||||
|
||||
describe('starknet', () => {
|
||||
should('custom keccak', () => {
|
||||
const value = starknet.keccak(utf8.decode('hello'));
|
||||
deepStrictEqual(value, 0x8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8n);
|
||||
deepStrictEqual(value < 2n ** 250n, true);
|
||||
});
|
||||
|
||||
should('RFC6979', () => {
|
||||
for (const msg of sigVec.messages) {
|
||||
const { r, s } = starknet.sign(msg.hash, sigVec.private_key);
|
||||
// const { r, s } = starknet.Signature.fromDER(sig);
|
||||
deepStrictEqual(r.toString(10), msg.r);
|
||||
deepStrictEqual(s.toString(10), msg.s);
|
||||
}
|
||||
});
|
||||
|
||||
should('Signatures', () => {
|
||||
const vectors = [
|
||||
{
|
||||
// Message hash of length 61.
|
||||
msg: 'c465dd6b1bbffdb05442eb17f5ca38ad1aa78a6f56bf4415bdee219114a47',
|
||||
r: '5f496f6f210b5810b2711c74c15c05244dad43d18ecbbdbe6ed55584bc3b0a2',
|
||||
s: '4e8657b153787f741a67c0666bad6426c3741b478c8eaa3155196fc571416f3',
|
||||
},
|
||||
{
|
||||
// Message hash of length 61, with leading zeros.
|
||||
msg: '00c465dd6b1bbffdb05442eb17f5ca38ad1aa78a6f56bf4415bdee219114a47',
|
||||
r: '5f496f6f210b5810b2711c74c15c05244dad43d18ecbbdbe6ed55584bc3b0a2',
|
||||
s: '4e8657b153787f741a67c0666bad6426c3741b478c8eaa3155196fc571416f3',
|
||||
},
|
||||
{
|
||||
// Message hash of length 62.
|
||||
msg: 'c465dd6b1bbffdb05442eb17f5ca38ad1aa78a6f56bf4415bdee219114a47a',
|
||||
r: '233b88c4578f0807b4a7480c8076eca5cfefa29980dd8e2af3c46a253490e9c',
|
||||
s: '28b055e825bc507349edfb944740a35c6f22d377443c34742c04e0d82278cf1',
|
||||
},
|
||||
{
|
||||
// Message hash of length 63.
|
||||
msg: '7465dd6b1bbffdb05442eb17f5ca38ad1aa78a6f56bf4415bdee219114a47a1',
|
||||
r: 'b6bee8010f96a723f6de06b5fa06e820418712439c93850dd4e9bde43ddf',
|
||||
s: '1a3d2bc954ed77e22986f507d68d18115fa543d1901f5b4620db98e2f6efd80',
|
||||
},
|
||||
];
|
||||
const privateKey = '2dccce1da22003777062ee0870e9881b460a8b7eca276870f57c601f182136c';
|
||||
const publicKey = starknet.getPublicKey(privateKey);
|
||||
for (const v of vectors) {
|
||||
const sig = starknet.sign(v.msg, privateKey);
|
||||
const { r, s } = sig;
|
||||
// const { r, s } = starknet.Signature.fromDER(sig);
|
||||
deepStrictEqual(r.toString(16), v.r, 'r equality');
|
||||
deepStrictEqual(s.toString(16), v.s, 's equality');
|
||||
deepStrictEqual(starknet.verify(sig, v.msg, publicKey), true, 'verify');
|
||||
}
|
||||
});
|
||||
|
||||
should('Invalid signatures', () => {
|
||||
/*
|
||||
|
||||
it('should not verify invalid signature inputs lengths', () => {
|
||||
const ecOrder = starkwareCrypto.ec.n;
|
||||
const {maxEcdsaVal} = starkwareCrypto;
|
||||
const maxMsgHash = maxEcdsaVal.sub(oneBn);
|
||||
const maxR = maxEcdsaVal.sub(oneBn);
|
||||
const maxS = ecOrder.sub(oneBn).sub(oneBn);
|
||||
const maxStarkKey = maxEcdsaVal.sub(oneBn);
|
||||
|
||||
// Test invalid message length.
|
||||
expect(() =>
|
||||
starkwareCrypto.verify(maxStarkKey, maxMsgHash.add(oneBn).toString(16), {
|
||||
r: maxR,
|
||||
s: maxS
|
||||
})
|
||||
).to.throw('Message not signable, invalid msgHash length.');
|
||||
// Test invalid r length.
|
||||
expect(() =>
|
||||
starkwareCrypto.verify(maxStarkKey, maxMsgHash.toString(16), {
|
||||
r: maxR.add(oneBn),
|
||||
s: maxS
|
||||
})
|
||||
).to.throw('Message not signable, invalid r length.');
|
||||
// Test invalid w length.
|
||||
expect(() =>
|
||||
starkwareCrypto.verify(maxStarkKey, maxMsgHash.toString(16), {
|
||||
r: maxR,
|
||||
s: maxS.add(oneBn)
|
||||
})
|
||||
).to.throw('Message not signable, invalid w length.');
|
||||
// Test invalid s length.
|
||||
expect(() =>
|
||||
starkwareCrypto.verify(maxStarkKey, maxMsgHash.toString(16), {
|
||||
r: maxR,
|
||||
s: maxS.add(oneBn).add(oneBn)
|
||||
})
|
||||
).to.throw('Message not signable, invalid s length.');
|
||||
});
|
||||
|
||||
it('should not verify invalid signatures', () => {
|
||||
const privKey = generateRandomStarkPrivateKey();
|
||||
const keyPair = starkwareCrypto.ec.keyFromPrivate(privKey, 'hex');
|
||||
const keyPairPub = starkwareCrypto.ec.keyFromPublic(
|
||||
keyPair.getPublic(),
|
||||
'BN'
|
||||
);
|
||||
const msgHash = new BN(randomHexString(61));
|
||||
const msgSignature = starkwareCrypto.sign(keyPair, msgHash);
|
||||
|
||||
// Test invalid public key.
|
||||
const invalidKeyPairPub = starkwareCrypto.ec.keyFromPublic(
|
||||
{x: keyPairPub.pub.getX().add(oneBn), y: keyPairPub.pub.getY()},
|
||||
'BN'
|
||||
);
|
||||
expect(
|
||||
starkwareCrypto.verify(
|
||||
invalidKeyPairPub,
|
||||
msgHash.toString(16),
|
||||
msgSignature
|
||||
)
|
||||
).to.be.false;
|
||||
// Test invalid message.
|
||||
expect(
|
||||
starkwareCrypto.verify(
|
||||
keyPair,
|
||||
msgHash.add(oneBn).toString(16),
|
||||
msgSignature
|
||||
)
|
||||
).to.be.false;
|
||||
expect(
|
||||
starkwareCrypto.verify(
|
||||
keyPairPub,
|
||||
msgHash.add(oneBn).toString(16),
|
||||
msgSignature
|
||||
)
|
||||
).to.be.false;
|
||||
// Test invalid r.
|
||||
msgSignature.r.iadd(oneBn);
|
||||
expect(starkwareCrypto.verify(keyPair, msgHash.toString(16), msgSignature))
|
||||
.to.be.false;
|
||||
expect(
|
||||
starkwareCrypto.verify(keyPairPub, msgHash.toString(16), msgSignature)
|
||||
).to.be.false;
|
||||
// Test invalid s.
|
||||
msgSignature.r.isub(oneBn);
|
||||
msgSignature.s.iadd(oneBn);
|
||||
expect(starkwareCrypto.verify(keyPair, msgHash.toString(16), msgSignature))
|
||||
.to.be.false;
|
||||
expect(
|
||||
starkwareCrypto.verify(keyPairPub, msgHash.toString(16), msgSignature)
|
||||
).to.be.false;
|
||||
});
|
||||
});
|
||||
*/
|
||||
});
|
||||
|
||||
should('Pedersen', () => {
|
||||
deepStrictEqual(
|
||||
starknet.pedersen(
|
||||
'0x3d937c035c878245caf64531a5756109c53068da139362728feb561405371cb',
|
||||
'0x208a0a10250e382e1e4bbe2880906c2791bf6275695e02fbbc6aeff9cd8b31a'
|
||||
),
|
||||
'0x30e480bed5fe53fa909cc0f8c4d99b8f9f2c016be4c41e13a4848797979c662'
|
||||
);
|
||||
deepStrictEqual(
|
||||
starknet.pedersen(
|
||||
'0x58f580910a6ca59b28927c08fe6c43e2e303ca384badc365795fc645d479d45',
|
||||
'0x78734f65a067be9bdb39de18434d71e79f7b6466a4b66bbd979ab9e7515fe0b'
|
||||
),
|
||||
'0x68cc0b76cddd1dd4ed2301ada9b7c872b23875d5ff837b3a87993e0d9996b87'
|
||||
);
|
||||
});
|
||||
|
||||
should('Hash chain', () => {
|
||||
deepStrictEqual(starknet.hashChain([1, 2, 3]), starknet.pedersen(1, starknet.pedersen(2, 3)));
|
||||
});
|
||||
|
||||
should('Key grinding', () => {
|
||||
deepStrictEqual(
|
||||
starknet.grindKey('86F3E7293141F20A8BAFF320E8EE4ACCB9D4A4BF2B4D295E8CEE784DB46E0519'),
|
||||
'5c8c8683596c732541a59e03007b2d30dbbbb873556fe65b5fb63c16688f941'
|
||||
);
|
||||
// Loops more than once (verified manually)
|
||||
deepStrictEqual(
|
||||
starknet.grindKey('94F3E7293141F20A8BAFF320E8EE4ACCB9D4A4BF2B4D295E8CEE784DB46E0595'),
|
||||
'33880b9aba464c1c01c9f8f5b4fc1134698f9b0a8d18505cab6cdd34d93dc02'
|
||||
);
|
||||
});
|
||||
|
||||
should('Private to stark key', () => {
|
||||
deepStrictEqual(
|
||||
starknet.getStarkKey('0x178047D3869489C055D7EA54C014FFB834A069C9595186ABE04EA4D1223A03F'),
|
||||
'0x1895a6a77ae14e7987b9cb51329a5adfb17bd8e7c638f92d6892d76e51cebcf'
|
||||
);
|
||||
for (const [privKey, expectedPubKey] of Object.entries(precomputedKeys)) {
|
||||
deepStrictEqual(starknet.getStarkKey(privKey), expectedPubKey);
|
||||
}
|
||||
});
|
||||
|
||||
should('Private stark key from eth signature', () => {
|
||||
const ethSignature =
|
||||
'0x21fbf0696d5e0aa2ef41a2b4ffb623bcaf070461d61cf7251c74161f82fec3a43' +
|
||||
'70854bc0a34b3ab487c1bc021cd318c734c51ae29374f2beb0e6f2dd49b4bf41c';
|
||||
deepStrictEqual(
|
||||
starknet.ethSigToPrivate(ethSignature),
|
||||
'766f11e90cd7c7b43085b56da35c781f8c067ac0d578eabdceebc4886435bda'
|
||||
);
|
||||
});
|
||||
|
||||
should('Key derivation', () => {
|
||||
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 VECTORS = [
|
||||
{
|
||||
index: 0,
|
||||
path: "m/2645'/579218131'/891216374'/1961790679'/2135936222'/0",
|
||||
privateKey: '6cf0a8bf113352eb863157a45c5e5567abb34f8d32cddafd2c22aa803f4892c',
|
||||
},
|
||||
{
|
||||
index: 7,
|
||||
path: "m/2645'/579218131'/891216374'/1961790679'/2135936222'/7",
|
||||
privateKey: '341751bdc42841da35ab74d13a1372c1f0250617e8a2ef96034d9f46e6847af',
|
||||
},
|
||||
{
|
||||
index: 598,
|
||||
path: "m/2645'/579218131'/891216374'/1961790679'/2135936222'/598",
|
||||
privateKey: '41a4d591a868353d28b7947eb132aa4d00c4a022743689ffd20a3628d6ca28c',
|
||||
},
|
||||
];
|
||||
const hd = bip32.HDKey.fromMasterSeed(bip39.mnemonicToSeedSync(mnemonic));
|
||||
for (const { index, path, privateKey } of VECTORS) {
|
||||
const realPath = starknet.getAccountPath(layer, application, ethAddress, index);
|
||||
deepStrictEqual(realPath, path);
|
||||
deepStrictEqual(starknet.grindKey(hd.derive(realPath).privateKey), privateKey);
|
||||
}
|
||||
});
|
||||
|
||||
// Verified against starknet.js
|
||||
should('Starknet.js cross-tests', () => {
|
||||
const privateKey = '0x019800ea6a9a73f94aee6a3d2edf018fc770443e90c7ba121e8303ec6b349279';
|
||||
// NOTE: there is no compressed keys here, getPubKey returns stark-key (which is schnorr-like X coordinate)
|
||||
// But it is not used in signing/verifying
|
||||
deepStrictEqual(
|
||||
starknet.getStarkKey(privateKey),
|
||||
'0x33f45f07e1bd1a51b45fc24ec8c8c9908db9e42191be9e169bfcac0c0d99745'
|
||||
);
|
||||
const msgHash = '0x6d1706bd3d1ba7c517be2a2a335996f63d4738e2f182144d078a1dd9997062e';
|
||||
const sig = starknet.sign(msgHash, privateKey);
|
||||
const { r, s } = sig;
|
||||
|
||||
deepStrictEqual(
|
||||
r.toString(),
|
||||
'1427981024487605678086498726488552139932400435436186597196374630267616399345'
|
||||
);
|
||||
deepStrictEqual(
|
||||
s.toString(),
|
||||
'1853664302719670721837677288395394946745467311923401353018029119631574115563'
|
||||
);
|
||||
const hashMsg2 = starknet.pedersen(
|
||||
'0x33f45f07e1bd1a51b45fc24ec8c8c9908db9e42191be9e169bfcac0c0d99745',
|
||||
'1'
|
||||
);
|
||||
deepStrictEqual(hashMsg2, '0x2b0d4d43acce8ff68416f667f92ec7eab2b96f1d2224abd4d9d4d1e7fa4bb00');
|
||||
const pubKey =
|
||||
'04033f45f07e1bd1a51b45fc24ec8c8c9908db9e42191be9e169bfcac0c0d997450319d0f53f6ca077c4fa5207819144a2a4165daef6ee47a7c1d06c0dcaa3e456';
|
||||
const sig2 = new starknet.Signature(
|
||||
558858382392827003930138586379728730695763862039474863361948210004201119180n,
|
||||
2440689354481625417078677634625227600823892606910345662891037256374285369343n
|
||||
);
|
||||
deepStrictEqual(starknet.verify(sig2.toDERHex(), hashMsg2, pubKey), true);
|
||||
});
|
||||
});
|
||||
|
||||
// ESM is broken.
|
||||
import url from 'url';
|
||||
if (import.meta.url === url.pathToFileURL(process.argv[1]).href) {
|
||||
should.run();
|
||||
}
|
||||
@@ -1,11 +1,12 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"strict": true,
|
||||
"outDir": "lib/esm",
|
||||
"outDir": "esm",
|
||||
"target": "es2020",
|
||||
"module": "es6",
|
||||
"moduleResolution": "node16",
|
||||
"noUnusedLocals": true,
|
||||
"sourceMap": true,
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@noble/hashes/crypto": [ "src/crypto" ]
|
||||
@@ -16,4 +17,4 @@
|
||||
"node_modules",
|
||||
"lib",
|
||||
],
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,9 @@
|
||||
"compilerOptions": {
|
||||
"strict": true,
|
||||
"declaration": true,
|
||||
"outDir": "lib",
|
||||
"declarationMap": true,
|
||||
"sourceMap": true,
|
||||
"outDir": ".",
|
||||
"target": "es2020",
|
||||
"lib": ["es2020"], // Set explicitly to remove DOM
|
||||
"module": "commonjs",
|
||||
@@ -15,4 +17,4 @@
|
||||
"node_modules",
|
||||
"*.d.ts"
|
||||
],
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user