Add debug logging to see received auth data
This commit is contained in:
21
node_modules/@scure/base/LICENSE
generated
vendored
Normal file
21
node_modules/@scure/base/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2022 Paul Miller (https://paulmillr.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the “Software”), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
147
node_modules/@scure/base/README.md
generated
vendored
Normal file
147
node_modules/@scure/base/README.md
generated
vendored
Normal file
@@ -0,0 +1,147 @@
|
||||
# scure-base
|
||||
|
||||
Secure, [audited](#security) and 0-dep implementation of bech32, base64, base58, base32 & base16.
|
||||
|
||||
Written in [functional style](#design-rationale), uses chaining, has unique tests which ensure correctness.
|
||||
|
||||
Matches following specs:
|
||||
|
||||
- Bech32, Bech32m: [BIP173](https://en.bitcoin.it/wiki/BIP_0173), [BIP350](https://en.bitcoin.it/wiki/BIP_0350)
|
||||
- Base16, Base32, Base32Hex, Base64, Base64Url: [RFC 4648](https://datatracker.ietf.org/doc/html/rfc4648) (aka RFC 3548)
|
||||
- [Base58](https://www.ietf.org/archive/id/draft-msporny-base58-03.txt), [Base58check](https://en.bitcoin.it/wiki/Base58Check_encoding), [Base32 Crockford](https://www.crockford.com/base32.html)
|
||||
|
||||
### This library belongs to *scure*
|
||||
|
||||
> **scure** — secure audited packages for every use case.
|
||||
|
||||
- Independent security audits
|
||||
- All releases are signed with PGP keys
|
||||
- Check out all libraries:
|
||||
[base](https://github.com/paulmillr/scure-base),
|
||||
[bip32](https://github.com/paulmillr/scure-bip32),
|
||||
[bip39](https://github.com/paulmillr/scure-bip39)
|
||||
|
||||
## Usage
|
||||
|
||||
> npm install @scure/base
|
||||
|
||||
Or
|
||||
|
||||
> yarn add @scure/base
|
||||
|
||||
```js
|
||||
const { base16, base32, base64, base58 } = require('@scure/base');
|
||||
// Flavors
|
||||
const { base58xmr, base58xrp, base32hex, base32crockford, base64url } = require('@scure/base');
|
||||
|
||||
const data = Uint8Array.from([1, 2, 3]);
|
||||
base64.decode(base64.encode(data));
|
||||
|
||||
// Everything has the same API except for bech32 and base58check
|
||||
base32.encode(data);
|
||||
base16.encode(data);
|
||||
base32hex.encode(data);
|
||||
|
||||
// bech32
|
||||
const { bech32, bech32m } = require('@scure/base');
|
||||
const words = bech32.toWords(data);
|
||||
const be = bech32.encode('prefix', words);
|
||||
const { prefix, words } = bech32.decode(be);
|
||||
bech32m.encode('prefix', words);
|
||||
|
||||
// base58check is special-case
|
||||
// you need to pass sha256() function that returns Uint8Array
|
||||
const { base58check } = require('@scure/base');
|
||||
base58check(sha256).encode(data);
|
||||
|
||||
// Alternative API
|
||||
const { str, bytes } = require('@scure/base');
|
||||
const encoded = str('base64', data);
|
||||
const data = bytes('base64', encoded);
|
||||
```
|
||||
|
||||
## Design rationale
|
||||
|
||||
The code may feel unnecessarily complicated; but actually it's much easier to reason about.
|
||||
Any encoding library consists of two functions:
|
||||
|
||||
```
|
||||
encode(A) -> B
|
||||
decode(B) -> A
|
||||
where X = decode(encode(X))
|
||||
# encode(decode(X)) can be !== X!
|
||||
# because decoding can normalize input
|
||||
|
||||
e.g.
|
||||
base58checksum = {
|
||||
encode(): {
|
||||
// checksum
|
||||
// radix conversion
|
||||
// alphabet
|
||||
},
|
||||
decode(): {
|
||||
// alphabet
|
||||
// radix conversion
|
||||
// checksum
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
But instead of creating two big functions for each specific case,
|
||||
we create them from tiny composamble building blocks:
|
||||
|
||||
```
|
||||
base58checksum = chain(checksum(), radix(), alphabet())
|
||||
```
|
||||
|
||||
Which is the same as chain/pipe/sequence function in Functional Programming,
|
||||
but significantly more useful since it enforces same order of execution of encode/decode.
|
||||
Basically you only define encode (in declarative way) and get correct decode for free.
|
||||
So, instead of reasoning about two big functions you need only reason about primitives and encode chain.
|
||||
The design revealed obvious bug in older version of the lib,
|
||||
where xmr version of base58 had errors in decode's block processing.
|
||||
|
||||
Besides base-encodings, we can reuse the same approach with any encode/decode function
|
||||
(`bytes2number`, `bytes2u32`, etc).
|
||||
For example, you can easily encode entropy to mnemonic (BIP-39):
|
||||
|
||||
```ts
|
||||
export function getCoder(wordlist: string[]) {
|
||||
if (!Array.isArray(wordlist) || wordlist.length !== 2 ** 11 || typeof wordlist[0] !== 'string') {
|
||||
throw new Error('Worlist: expected array of 2048 strings');
|
||||
}
|
||||
return mbc.chain(mbu.checksum(1, checksum), mbu.radix2(11, true), mbu.alphabet(wordlist));
|
||||
}
|
||||
```
|
||||
|
||||
## base58 is O(n^2) and radixes
|
||||
|
||||
`Uint8Array` is represented as big-endian number:
|
||||
|
||||
```
|
||||
[1, 2, 3, 4, 5] -> 1*(256**4) + 2*(256**3) 3*(256**2) + 4*(256**1) + 5*(256**0)
|
||||
where 256 = 2**8 (8 bits per byte)
|
||||
```
|
||||
|
||||
which is then converted to a number in another radix/base (16/32/58/64, etc).
|
||||
|
||||
However, generic conversion between bases has [quadratic O(n^2) time complexity](https://cs.stackexchange.com/q/21799).
|
||||
|
||||
Which means base58 has quadratic time complexity too. Use base58 only when you have small
|
||||
constant sized input, because variable length sized input from user can cause DoS.
|
||||
|
||||
On the other hand, if both bases are power of same number (like `2**8 <-> 2**64`),
|
||||
there is linear algorithm. For now we have implementation for power-of-two bases only (radix2).
|
||||
|
||||
## Security
|
||||
|
||||
The library has been audited by Cure53 on Jan 5, 2022. Check out the audit [PDF](./audit/2022-01-05-cure53-audit-nbl2.pdf) & [URL](https://cure53.de/pentest-report_hashing-libs.pdf). See [changes since audit](https://github.com/paulmillr/scure-base/compare/1.0.0..main).
|
||||
|
||||
1. The library was initially developed for [js-ethereum-cryptography](https://github.com/ethereum/js-ethereum-cryptography)
|
||||
2. At commit [ae00e6d7](https://github.com/ethereum/js-ethereum-cryptography/commit/ae00e6d7d24fb3c76a1c7fe10039f6ecd120b77e), it
|
||||
was extracted to a separate package called `micro-base`
|
||||
3. After the audit we've decided to use NPM namespace for security. Since `@micro` namespace was taken, we've renamed the package to `@scure/base`
|
||||
|
||||
## License
|
||||
|
||||
MIT (c) Paul Miller [(https://paulmillr.com)](https://paulmillr.com), see LICENSE file.
|
||||
394
node_modules/@scure/base/lib/esm/index.js
generated
vendored
Normal file
394
node_modules/@scure/base/lib/esm/index.js
generated
vendored
Normal file
@@ -0,0 +1,394 @@
|
||||
/*! scure-base - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||
export function assertNumber(n) {
|
||||
if (!Number.isSafeInteger(n))
|
||||
throw new Error(`Wrong integer: ${n}`);
|
||||
}
|
||||
function chain(...args) {
|
||||
const wrap = (a, b) => (c) => a(b(c));
|
||||
const encode = Array.from(args)
|
||||
.reverse()
|
||||
.reduce((acc, i) => (acc ? wrap(acc, i.encode) : i.encode), undefined);
|
||||
const decode = args.reduce((acc, i) => (acc ? wrap(acc, i.decode) : i.decode), undefined);
|
||||
return { encode, decode };
|
||||
}
|
||||
function alphabet(alphabet) {
|
||||
return {
|
||||
encode: (digits) => {
|
||||
if (!Array.isArray(digits) || (digits.length && typeof digits[0] !== 'number'))
|
||||
throw new Error('alphabet.encode input should be an array of numbers');
|
||||
return digits.map((i) => {
|
||||
assertNumber(i);
|
||||
if (i < 0 || i >= alphabet.length)
|
||||
throw new Error(`Digit index outside alphabet: ${i} (alphabet: ${alphabet.length})`);
|
||||
return alphabet[i];
|
||||
});
|
||||
},
|
||||
decode: (input) => {
|
||||
if (!Array.isArray(input) || (input.length && typeof input[0] !== 'string'))
|
||||
throw new Error('alphabet.decode input should be array of strings');
|
||||
return input.map((letter) => {
|
||||
if (typeof letter !== 'string')
|
||||
throw new Error(`alphabet.decode: not string element=${letter}`);
|
||||
const index = alphabet.indexOf(letter);
|
||||
if (index === -1)
|
||||
throw new Error(`Unknown letter: "${letter}". Allowed: ${alphabet}`);
|
||||
return index;
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
||||
function join(separator = '') {
|
||||
if (typeof separator !== 'string')
|
||||
throw new Error('join separator should be string');
|
||||
return {
|
||||
encode: (from) => {
|
||||
if (!Array.isArray(from) || (from.length && typeof from[0] !== 'string'))
|
||||
throw new Error('join.encode input should be array of strings');
|
||||
for (let i of from)
|
||||
if (typeof i !== 'string')
|
||||
throw new Error(`join.encode: non-string input=${i}`);
|
||||
return from.join(separator);
|
||||
},
|
||||
decode: (to) => {
|
||||
if (typeof to !== 'string')
|
||||
throw new Error('join.decode input should be string');
|
||||
return to.split(separator);
|
||||
},
|
||||
};
|
||||
}
|
||||
function padding(bits, chr = '=') {
|
||||
assertNumber(bits);
|
||||
if (typeof chr !== 'string')
|
||||
throw new Error('padding chr should be string');
|
||||
return {
|
||||
encode(data) {
|
||||
if (!Array.isArray(data) || (data.length && typeof data[0] !== 'string'))
|
||||
throw new Error('padding.encode input should be array of strings');
|
||||
for (let i of data)
|
||||
if (typeof i !== 'string')
|
||||
throw new Error(`padding.encode: non-string input=${i}`);
|
||||
while ((data.length * bits) % 8)
|
||||
data.push(chr);
|
||||
return data;
|
||||
},
|
||||
decode(input) {
|
||||
if (!Array.isArray(input) || (input.length && typeof input[0] !== 'string'))
|
||||
throw new Error('padding.encode input should be array of strings');
|
||||
for (let i of input)
|
||||
if (typeof i !== 'string')
|
||||
throw new Error(`padding.decode: non-string input=${i}`);
|
||||
let end = input.length;
|
||||
if ((end * bits) % 8)
|
||||
throw new Error('Invalid padding: string should have whole number of bytes');
|
||||
for (; end > 0 && input[end - 1] === chr; end--) {
|
||||
if (!(((end - 1) * bits) % 8))
|
||||
throw new Error('Invalid padding: string has too much padding');
|
||||
}
|
||||
return input.slice(0, end);
|
||||
},
|
||||
};
|
||||
}
|
||||
function normalize(fn) {
|
||||
if (typeof fn !== 'function')
|
||||
throw new Error('normalize fn should be function');
|
||||
return { encode: (from) => from, decode: (to) => fn(to) };
|
||||
}
|
||||
function convertRadix(data, from, to) {
|
||||
if (from < 2)
|
||||
throw new Error(`convertRadix: wrong from=${from}, base cannot be less than 2`);
|
||||
if (to < 2)
|
||||
throw new Error(`convertRadix: wrong to=${to}, base cannot be less than 2`);
|
||||
if (!Array.isArray(data))
|
||||
throw new Error('convertRadix: data should be array');
|
||||
if (!data.length)
|
||||
return [];
|
||||
let pos = 0;
|
||||
const res = [];
|
||||
const digits = Array.from(data);
|
||||
digits.forEach((d) => {
|
||||
assertNumber(d);
|
||||
if (d < 0 || d >= from)
|
||||
throw new Error(`Wrong integer: ${d}`);
|
||||
});
|
||||
while (true) {
|
||||
let carry = 0;
|
||||
let done = true;
|
||||
for (let i = pos; i < digits.length; i++) {
|
||||
const digit = digits[i];
|
||||
const digitBase = from * carry + digit;
|
||||
if (!Number.isSafeInteger(digitBase) ||
|
||||
(from * carry) / from !== carry ||
|
||||
digitBase - digit !== from * carry) {
|
||||
throw new Error('convertRadix: carry overflow');
|
||||
}
|
||||
carry = digitBase % to;
|
||||
digits[i] = Math.floor(digitBase / to);
|
||||
if (!Number.isSafeInteger(digits[i]) || digits[i] * to + carry !== digitBase)
|
||||
throw new Error('convertRadix: carry overflow');
|
||||
if (!done)
|
||||
continue;
|
||||
else if (!digits[i])
|
||||
pos = i;
|
||||
else
|
||||
done = false;
|
||||
}
|
||||
res.push(carry);
|
||||
if (done)
|
||||
break;
|
||||
}
|
||||
for (let i = 0; i < data.length - 1 && data[i] === 0; i++)
|
||||
res.push(0);
|
||||
return res.reverse();
|
||||
}
|
||||
const gcd = (a, b) => (!b ? a : gcd(b, a % b));
|
||||
const radix2carry = (from, to) => from + (to - gcd(from, to));
|
||||
function convertRadix2(data, from, to, padding) {
|
||||
if (!Array.isArray(data))
|
||||
throw new Error('convertRadix2: data should be array');
|
||||
if (from <= 0 || from > 32)
|
||||
throw new Error(`convertRadix2: wrong from=${from}`);
|
||||
if (to <= 0 || to > 32)
|
||||
throw new Error(`convertRadix2: wrong to=${to}`);
|
||||
if (radix2carry(from, to) > 32) {
|
||||
throw new Error(`convertRadix2: carry overflow from=${from} to=${to} carryBits=${radix2carry(from, to)}`);
|
||||
}
|
||||
let carry = 0;
|
||||
let pos = 0;
|
||||
const mask = 2 ** to - 1;
|
||||
const res = [];
|
||||
for (const n of data) {
|
||||
assertNumber(n);
|
||||
if (n >= 2 ** from)
|
||||
throw new Error(`convertRadix2: invalid data word=${n} from=${from}`);
|
||||
carry = (carry << from) | n;
|
||||
if (pos + from > 32)
|
||||
throw new Error(`convertRadix2: carry overflow pos=${pos} from=${from}`);
|
||||
pos += from;
|
||||
for (; pos >= to; pos -= to)
|
||||
res.push(((carry >> (pos - to)) & mask) >>> 0);
|
||||
carry &= 2 ** pos - 1;
|
||||
}
|
||||
carry = (carry << (to - pos)) & mask;
|
||||
if (!padding && pos >= from)
|
||||
throw new Error('Excess padding');
|
||||
if (!padding && carry)
|
||||
throw new Error(`Non-zero padding: ${carry}`);
|
||||
if (padding && pos > 0)
|
||||
res.push(carry >>> 0);
|
||||
return res;
|
||||
}
|
||||
function radix(num) {
|
||||
assertNumber(num);
|
||||
return {
|
||||
encode: (bytes) => {
|
||||
if (!(bytes instanceof Uint8Array))
|
||||
throw new Error('radix.encode input should be Uint8Array');
|
||||
return convertRadix(Array.from(bytes), 2 ** 8, num);
|
||||
},
|
||||
decode: (digits) => {
|
||||
if (!Array.isArray(digits) || (digits.length && typeof digits[0] !== 'number'))
|
||||
throw new Error('radix.decode input should be array of strings');
|
||||
return Uint8Array.from(convertRadix(digits, num, 2 ** 8));
|
||||
},
|
||||
};
|
||||
}
|
||||
function radix2(bits, revPadding = false) {
|
||||
assertNumber(bits);
|
||||
if (bits <= 0 || bits > 32)
|
||||
throw new Error('radix2: bits should be in (0..32]');
|
||||
if (radix2carry(8, bits) > 32 || radix2carry(bits, 8) > 32)
|
||||
throw new Error('radix2: carry overflow');
|
||||
return {
|
||||
encode: (bytes) => {
|
||||
if (!(bytes instanceof Uint8Array))
|
||||
throw new Error('radix2.encode input should be Uint8Array');
|
||||
return convertRadix2(Array.from(bytes), 8, bits, !revPadding);
|
||||
},
|
||||
decode: (digits) => {
|
||||
if (!Array.isArray(digits) || (digits.length && typeof digits[0] !== 'number'))
|
||||
throw new Error('radix2.decode input should be array of strings');
|
||||
return Uint8Array.from(convertRadix2(digits, bits, 8, revPadding));
|
||||
},
|
||||
};
|
||||
}
|
||||
function unsafeWrapper(fn) {
|
||||
if (typeof fn !== 'function')
|
||||
throw new Error('unsafeWrapper fn should be function');
|
||||
return function (...args) {
|
||||
try {
|
||||
return fn.apply(null, args);
|
||||
}
|
||||
catch (e) { }
|
||||
};
|
||||
}
|
||||
function checksum(len, fn) {
|
||||
assertNumber(len);
|
||||
if (typeof fn !== 'function')
|
||||
throw new Error('checksum fn should be function');
|
||||
return {
|
||||
encode(data) {
|
||||
if (!(data instanceof Uint8Array))
|
||||
throw new Error('checksum.encode: input should be Uint8Array');
|
||||
const checksum = fn(data).slice(0, len);
|
||||
const res = new Uint8Array(data.length + len);
|
||||
res.set(data);
|
||||
res.set(checksum, data.length);
|
||||
return res;
|
||||
},
|
||||
decode(data) {
|
||||
if (!(data instanceof Uint8Array))
|
||||
throw new Error('checksum.decode: input should be Uint8Array');
|
||||
const payload = data.slice(0, -len);
|
||||
const newChecksum = fn(payload).slice(0, len);
|
||||
const oldChecksum = data.slice(-len);
|
||||
for (let i = 0; i < len; i++)
|
||||
if (newChecksum[i] !== oldChecksum[i])
|
||||
throw new Error('Invalid checksum');
|
||||
return payload;
|
||||
},
|
||||
};
|
||||
}
|
||||
export const utils = { alphabet, chain, checksum, radix, radix2, join, padding };
|
||||
export const base16 = chain(radix2(4), alphabet('0123456789ABCDEF'), join(''));
|
||||
export const base32 = chain(radix2(5), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'), padding(5), join(''));
|
||||
export const base32hex = chain(radix2(5), alphabet('0123456789ABCDEFGHIJKLMNOPQRSTUV'), padding(5), join(''));
|
||||
export const base32crockford = chain(radix2(5), alphabet('0123456789ABCDEFGHJKMNPQRSTVWXYZ'), join(''), normalize((s) => s.toUpperCase().replace(/O/g, '0').replace(/[IL]/g, '1')));
|
||||
export const base64 = chain(radix2(6), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'), padding(6), join(''));
|
||||
export const base64url = chain(radix2(6), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'), padding(6), join(''));
|
||||
const genBase58 = (abc) => chain(radix(58), alphabet(abc), join(''));
|
||||
export const base58 = genBase58('123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz');
|
||||
export const base58flickr = genBase58('123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ');
|
||||
export const base58xrp = genBase58('rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz');
|
||||
const XMR_BLOCK_LEN = [0, 2, 3, 5, 6, 7, 9, 10, 11];
|
||||
export const base58xmr = {
|
||||
encode(data) {
|
||||
let res = '';
|
||||
for (let i = 0; i < data.length; i += 8) {
|
||||
const block = data.subarray(i, i + 8);
|
||||
res += base58.encode(block).padStart(XMR_BLOCK_LEN[block.length], '1');
|
||||
}
|
||||
return res;
|
||||
},
|
||||
decode(str) {
|
||||
let res = [];
|
||||
for (let i = 0; i < str.length; i += 11) {
|
||||
const slice = str.slice(i, i + 11);
|
||||
const blockLen = XMR_BLOCK_LEN.indexOf(slice.length);
|
||||
const block = base58.decode(slice);
|
||||
for (let j = 0; j < block.length - blockLen; j++) {
|
||||
if (block[j] !== 0)
|
||||
throw new Error('base58xmr: wrong padding');
|
||||
}
|
||||
res = res.concat(Array.from(block.slice(block.length - blockLen)));
|
||||
}
|
||||
return Uint8Array.from(res);
|
||||
},
|
||||
};
|
||||
export const base58check = (sha256) => chain(checksum(4, (data) => sha256(sha256(data))), base58);
|
||||
const BECH_ALPHABET = chain(alphabet('qpzry9x8gf2tvdw0s3jn54khce6mua7l'), join(''));
|
||||
const POLYMOD_GENERATORS = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3];
|
||||
function bech32Polymod(pre) {
|
||||
const b = pre >> 25;
|
||||
let chk = (pre & 0x1ffffff) << 5;
|
||||
for (let i = 0; i < POLYMOD_GENERATORS.length; i++) {
|
||||
if (((b >> i) & 1) === 1)
|
||||
chk ^= POLYMOD_GENERATORS[i];
|
||||
}
|
||||
return chk;
|
||||
}
|
||||
function bechChecksum(prefix, words, encodingConst = 1) {
|
||||
const len = prefix.length;
|
||||
let chk = 1;
|
||||
for (let i = 0; i < len; i++) {
|
||||
const c = prefix.charCodeAt(i);
|
||||
if (c < 33 || c > 126)
|
||||
throw new Error(`Invalid prefix (${prefix})`);
|
||||
chk = bech32Polymod(chk) ^ (c >> 5);
|
||||
}
|
||||
chk = bech32Polymod(chk);
|
||||
for (let i = 0; i < len; i++)
|
||||
chk = bech32Polymod(chk) ^ (prefix.charCodeAt(i) & 0x1f);
|
||||
for (let v of words)
|
||||
chk = bech32Polymod(chk) ^ v;
|
||||
for (let i = 0; i < 6; i++)
|
||||
chk = bech32Polymod(chk);
|
||||
chk ^= encodingConst;
|
||||
return BECH_ALPHABET.encode(convertRadix2([chk % 2 ** 30], 30, 5, false));
|
||||
}
|
||||
function genBech32(encoding) {
|
||||
const ENCODING_CONST = encoding === 'bech32' ? 1 : 0x2bc830a3;
|
||||
const _words = radix2(5);
|
||||
const fromWords = _words.decode;
|
||||
const toWords = _words.encode;
|
||||
const fromWordsUnsafe = unsafeWrapper(fromWords);
|
||||
function encode(prefix, words, limit = 90) {
|
||||
if (typeof prefix !== 'string')
|
||||
throw new Error(`bech32.encode prefix should be string, not ${typeof prefix}`);
|
||||
if (!Array.isArray(words) || (words.length && typeof words[0] !== 'number'))
|
||||
throw new Error(`bech32.encode words should be array of numbers, not ${typeof words}`);
|
||||
const actualLength = prefix.length + 7 + words.length;
|
||||
if (limit !== false && actualLength > limit)
|
||||
throw new TypeError(`Length ${actualLength} exceeds limit ${limit}`);
|
||||
prefix = prefix.toLowerCase();
|
||||
return `${prefix}1${BECH_ALPHABET.encode(words)}${bechChecksum(prefix, words, ENCODING_CONST)}`;
|
||||
}
|
||||
function decode(str, limit = 90) {
|
||||
if (typeof str !== 'string')
|
||||
throw new Error(`bech32.decode input should be string, not ${typeof str}`);
|
||||
if (str.length < 8 || (limit !== false && str.length > limit))
|
||||
throw new TypeError(`Wrong string length: ${str.length} (${str}). Expected (8..${limit})`);
|
||||
const lowered = str.toLowerCase();
|
||||
if (str !== lowered && str !== str.toUpperCase())
|
||||
throw new Error(`String must be lowercase or uppercase`);
|
||||
str = lowered;
|
||||
const sepIndex = str.lastIndexOf('1');
|
||||
if (sepIndex === 0 || sepIndex === -1)
|
||||
throw new Error(`Letter "1" must be present between prefix and data only`);
|
||||
const prefix = str.slice(0, sepIndex);
|
||||
const _words = str.slice(sepIndex + 1);
|
||||
if (_words.length < 6)
|
||||
throw new Error('Data must be at least 6 characters long');
|
||||
const words = BECH_ALPHABET.decode(_words).slice(0, -6);
|
||||
const sum = bechChecksum(prefix, words, ENCODING_CONST);
|
||||
if (!_words.endsWith(sum))
|
||||
throw new Error(`Invalid checksum in ${str}: expected "${sum}"`);
|
||||
return { prefix, words };
|
||||
}
|
||||
const decodeUnsafe = unsafeWrapper(decode);
|
||||
function decodeToBytes(str) {
|
||||
const { prefix, words } = decode(str, false);
|
||||
return { prefix, words, bytes: fromWords(words) };
|
||||
}
|
||||
return { encode, decode, decodeToBytes, decodeUnsafe, fromWords, fromWordsUnsafe, toWords };
|
||||
}
|
||||
export const bech32 = genBech32('bech32');
|
||||
export const bech32m = genBech32('bech32m');
|
||||
export const utf8 = {
|
||||
encode: (data) => new TextDecoder().decode(data),
|
||||
decode: (str) => new TextEncoder().encode(str),
|
||||
};
|
||||
export const hex = chain(radix2(4), alphabet('0123456789abcdef'), join(''), normalize((s) => {
|
||||
if (typeof s !== 'string' || s.length % 2)
|
||||
throw new TypeError(`hex.decode: expected string, got ${typeof s} with length ${s.length}`);
|
||||
return s.toLowerCase();
|
||||
}));
|
||||
const CODERS = {
|
||||
utf8, hex, base16, base32, base64, base64url, base58, base58xmr
|
||||
};
|
||||
const coderTypeError = `Invalid encoding type. Available types: ${Object.keys(CODERS).join(', ')}`;
|
||||
export const bytesToString = (type, bytes) => {
|
||||
if (typeof type !== 'string' || !CODERS.hasOwnProperty(type))
|
||||
throw new TypeError(coderTypeError);
|
||||
if (!(bytes instanceof Uint8Array))
|
||||
throw new TypeError('bytesToString() expects Uint8Array');
|
||||
return CODERS[type].encode(bytes);
|
||||
};
|
||||
export const str = bytesToString;
|
||||
export const stringToBytes = (type, str) => {
|
||||
if (!CODERS.hasOwnProperty(type))
|
||||
throw new TypeError(coderTypeError);
|
||||
if (typeof str !== 'string')
|
||||
throw new TypeError('stringToBytes() expects string');
|
||||
return CODERS[type].decode(str);
|
||||
};
|
||||
export const bytes = stringToBytes;
|
||||
1
node_modules/@scure/base/lib/esm/package.json
generated
vendored
Normal file
1
node_modules/@scure/base/lib/esm/package.json
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{ "type": "module" }
|
||||
92
node_modules/@scure/base/lib/index.d.ts
generated
vendored
Normal file
92
node_modules/@scure/base/lib/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
/*! scure-base - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||
export declare function assertNumber(n: number): void;
|
||||
export interface Coder<F, T> {
|
||||
encode(from: F): T;
|
||||
decode(to: T): F;
|
||||
}
|
||||
export interface BytesCoder extends Coder<Uint8Array, string> {
|
||||
encode: (data: Uint8Array) => string;
|
||||
decode: (str: string) => Uint8Array;
|
||||
}
|
||||
declare type Chain = [Coder<any, any>, ...Coder<any, any>[]];
|
||||
declare type Input<F> = F extends Coder<infer T, any> ? T : never;
|
||||
declare type Output<F> = F extends Coder<any, infer T> ? T : never;
|
||||
declare type First<T> = T extends [infer U, ...any[]] ? U : never;
|
||||
declare type Last<T> = T extends [...any[], infer U] ? U : never;
|
||||
declare type Tail<T> = T extends [any, ...infer U] ? U : never;
|
||||
declare type AsChain<C extends Chain, Rest = Tail<C>> = {
|
||||
[K in keyof C]: Coder<Input<C[K]>, Input<K extends keyof Rest ? Rest[K] : any>>;
|
||||
};
|
||||
declare function chain<T extends Chain & AsChain<T>>(...args: T): Coder<Input<First<T>>, Output<Last<T>>>;
|
||||
declare type Alphabet = string[] | string;
|
||||
declare function alphabet(alphabet: Alphabet): Coder<number[], string[]>;
|
||||
declare function join(separator?: string): Coder<string[], string>;
|
||||
declare function padding(bits: number, chr?: string): Coder<string[], string[]>;
|
||||
declare function radix(num: number): Coder<Uint8Array, number[]>;
|
||||
declare function radix2(bits: number, revPadding?: boolean): Coder<Uint8Array, number[]>;
|
||||
declare function checksum(len: number, fn: (data: Uint8Array) => Uint8Array): Coder<Uint8Array, Uint8Array>;
|
||||
export declare const utils: {
|
||||
alphabet: typeof alphabet;
|
||||
chain: typeof chain;
|
||||
checksum: typeof checksum;
|
||||
radix: typeof radix;
|
||||
radix2: typeof radix2;
|
||||
join: typeof join;
|
||||
padding: typeof padding;
|
||||
};
|
||||
export declare const base16: BytesCoder;
|
||||
export declare const base32: BytesCoder;
|
||||
export declare const base32hex: BytesCoder;
|
||||
export declare const base32crockford: BytesCoder;
|
||||
export declare const base64: BytesCoder;
|
||||
export declare const base64url: BytesCoder;
|
||||
export declare const base58: BytesCoder;
|
||||
export declare const base58flickr: BytesCoder;
|
||||
export declare const base58xrp: BytesCoder;
|
||||
export declare const base58xmr: BytesCoder;
|
||||
export declare const base58check: (sha256: (data: Uint8Array) => Uint8Array) => BytesCoder;
|
||||
export interface Bech32Decoded {
|
||||
prefix: string;
|
||||
words: number[];
|
||||
}
|
||||
export interface Bech32DecodedWithArray {
|
||||
prefix: string;
|
||||
words: number[];
|
||||
bytes: Uint8Array;
|
||||
}
|
||||
export declare const bech32: {
|
||||
encode: (prefix: string, words: number[] | Uint8Array, limit?: number | false) => string;
|
||||
decode: (str: string, limit?: number | false) => Bech32Decoded;
|
||||
decodeToBytes: (str: string) => Bech32DecodedWithArray;
|
||||
decodeUnsafe: (str: string, limit?: number | false | undefined) => Bech32Decoded | undefined;
|
||||
fromWords: (to: number[]) => Uint8Array;
|
||||
fromWordsUnsafe: (to: number[]) => Uint8Array | undefined;
|
||||
toWords: (from: Uint8Array) => number[];
|
||||
};
|
||||
export declare const bech32m: {
|
||||
encode: (prefix: string, words: number[] | Uint8Array, limit?: number | false) => string;
|
||||
decode: (str: string, limit?: number | false) => Bech32Decoded;
|
||||
decodeToBytes: (str: string) => Bech32DecodedWithArray;
|
||||
decodeUnsafe: (str: string, limit?: number | false | undefined) => Bech32Decoded | undefined;
|
||||
fromWords: (to: number[]) => Uint8Array;
|
||||
fromWordsUnsafe: (to: number[]) => Uint8Array | undefined;
|
||||
toWords: (from: Uint8Array) => number[];
|
||||
};
|
||||
export declare const utf8: BytesCoder;
|
||||
export declare const hex: BytesCoder;
|
||||
declare const CODERS: {
|
||||
utf8: BytesCoder;
|
||||
hex: BytesCoder;
|
||||
base16: BytesCoder;
|
||||
base32: BytesCoder;
|
||||
base64: BytesCoder;
|
||||
base64url: BytesCoder;
|
||||
base58: BytesCoder;
|
||||
base58xmr: BytesCoder;
|
||||
};
|
||||
declare type CoderType = keyof typeof CODERS;
|
||||
export declare const bytesToString: (type: CoderType, bytes: Uint8Array) => string;
|
||||
export declare const str: (type: CoderType, bytes: Uint8Array) => string;
|
||||
export declare const stringToBytes: (type: CoderType, str: string) => Uint8Array;
|
||||
export declare const bytes: (type: CoderType, str: string) => Uint8Array;
|
||||
export {};
|
||||
401
node_modules/@scure/base/lib/index.js
generated
vendored
Normal file
401
node_modules/@scure/base/lib/index.js
generated
vendored
Normal file
@@ -0,0 +1,401 @@
|
||||
"use strict";
|
||||
/*! scure-base - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.bytes = exports.stringToBytes = exports.str = exports.bytesToString = exports.hex = exports.utf8 = exports.bech32m = exports.bech32 = exports.base58check = exports.base58xmr = exports.base58xrp = exports.base58flickr = exports.base58 = exports.base64url = exports.base64 = exports.base32crockford = exports.base32hex = exports.base32 = exports.base16 = exports.utils = exports.assertNumber = void 0;
|
||||
function assertNumber(n) {
|
||||
if (!Number.isSafeInteger(n))
|
||||
throw new Error(`Wrong integer: ${n}`);
|
||||
}
|
||||
exports.assertNumber = assertNumber;
|
||||
function chain(...args) {
|
||||
const wrap = (a, b) => (c) => a(b(c));
|
||||
const encode = Array.from(args)
|
||||
.reverse()
|
||||
.reduce((acc, i) => (acc ? wrap(acc, i.encode) : i.encode), undefined);
|
||||
const decode = args.reduce((acc, i) => (acc ? wrap(acc, i.decode) : i.decode), undefined);
|
||||
return { encode, decode };
|
||||
}
|
||||
function alphabet(alphabet) {
|
||||
return {
|
||||
encode: (digits) => {
|
||||
if (!Array.isArray(digits) || (digits.length && typeof digits[0] !== 'number'))
|
||||
throw new Error('alphabet.encode input should be an array of numbers');
|
||||
return digits.map((i) => {
|
||||
assertNumber(i);
|
||||
if (i < 0 || i >= alphabet.length)
|
||||
throw new Error(`Digit index outside alphabet: ${i} (alphabet: ${alphabet.length})`);
|
||||
return alphabet[i];
|
||||
});
|
||||
},
|
||||
decode: (input) => {
|
||||
if (!Array.isArray(input) || (input.length && typeof input[0] !== 'string'))
|
||||
throw new Error('alphabet.decode input should be array of strings');
|
||||
return input.map((letter) => {
|
||||
if (typeof letter !== 'string')
|
||||
throw new Error(`alphabet.decode: not string element=${letter}`);
|
||||
const index = alphabet.indexOf(letter);
|
||||
if (index === -1)
|
||||
throw new Error(`Unknown letter: "${letter}". Allowed: ${alphabet}`);
|
||||
return index;
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
||||
function join(separator = '') {
|
||||
if (typeof separator !== 'string')
|
||||
throw new Error('join separator should be string');
|
||||
return {
|
||||
encode: (from) => {
|
||||
if (!Array.isArray(from) || (from.length && typeof from[0] !== 'string'))
|
||||
throw new Error('join.encode input should be array of strings');
|
||||
for (let i of from)
|
||||
if (typeof i !== 'string')
|
||||
throw new Error(`join.encode: non-string input=${i}`);
|
||||
return from.join(separator);
|
||||
},
|
||||
decode: (to) => {
|
||||
if (typeof to !== 'string')
|
||||
throw new Error('join.decode input should be string');
|
||||
return to.split(separator);
|
||||
},
|
||||
};
|
||||
}
|
||||
function padding(bits, chr = '=') {
|
||||
assertNumber(bits);
|
||||
if (typeof chr !== 'string')
|
||||
throw new Error('padding chr should be string');
|
||||
return {
|
||||
encode(data) {
|
||||
if (!Array.isArray(data) || (data.length && typeof data[0] !== 'string'))
|
||||
throw new Error('padding.encode input should be array of strings');
|
||||
for (let i of data)
|
||||
if (typeof i !== 'string')
|
||||
throw new Error(`padding.encode: non-string input=${i}`);
|
||||
while ((data.length * bits) % 8)
|
||||
data.push(chr);
|
||||
return data;
|
||||
},
|
||||
decode(input) {
|
||||
if (!Array.isArray(input) || (input.length && typeof input[0] !== 'string'))
|
||||
throw new Error('padding.encode input should be array of strings');
|
||||
for (let i of input)
|
||||
if (typeof i !== 'string')
|
||||
throw new Error(`padding.decode: non-string input=${i}`);
|
||||
let end = input.length;
|
||||
if ((end * bits) % 8)
|
||||
throw new Error('Invalid padding: string should have whole number of bytes');
|
||||
for (; end > 0 && input[end - 1] === chr; end--) {
|
||||
if (!(((end - 1) * bits) % 8))
|
||||
throw new Error('Invalid padding: string has too much padding');
|
||||
}
|
||||
return input.slice(0, end);
|
||||
},
|
||||
};
|
||||
}
|
||||
function normalize(fn) {
|
||||
if (typeof fn !== 'function')
|
||||
throw new Error('normalize fn should be function');
|
||||
return { encode: (from) => from, decode: (to) => fn(to) };
|
||||
}
|
||||
function convertRadix(data, from, to) {
|
||||
if (from < 2)
|
||||
throw new Error(`convertRadix: wrong from=${from}, base cannot be less than 2`);
|
||||
if (to < 2)
|
||||
throw new Error(`convertRadix: wrong to=${to}, base cannot be less than 2`);
|
||||
if (!Array.isArray(data))
|
||||
throw new Error('convertRadix: data should be array');
|
||||
if (!data.length)
|
||||
return [];
|
||||
let pos = 0;
|
||||
const res = [];
|
||||
const digits = Array.from(data);
|
||||
digits.forEach((d) => {
|
||||
assertNumber(d);
|
||||
if (d < 0 || d >= from)
|
||||
throw new Error(`Wrong integer: ${d}`);
|
||||
});
|
||||
while (true) {
|
||||
let carry = 0;
|
||||
let done = true;
|
||||
for (let i = pos; i < digits.length; i++) {
|
||||
const digit = digits[i];
|
||||
const digitBase = from * carry + digit;
|
||||
if (!Number.isSafeInteger(digitBase) ||
|
||||
(from * carry) / from !== carry ||
|
||||
digitBase - digit !== from * carry) {
|
||||
throw new Error('convertRadix: carry overflow');
|
||||
}
|
||||
carry = digitBase % to;
|
||||
digits[i] = Math.floor(digitBase / to);
|
||||
if (!Number.isSafeInteger(digits[i]) || digits[i] * to + carry !== digitBase)
|
||||
throw new Error('convertRadix: carry overflow');
|
||||
if (!done)
|
||||
continue;
|
||||
else if (!digits[i])
|
||||
pos = i;
|
||||
else
|
||||
done = false;
|
||||
}
|
||||
res.push(carry);
|
||||
if (done)
|
||||
break;
|
||||
}
|
||||
for (let i = 0; i < data.length - 1 && data[i] === 0; i++)
|
||||
res.push(0);
|
||||
return res.reverse();
|
||||
}
|
||||
const gcd = (a, b) => (!b ? a : gcd(b, a % b));
|
||||
const radix2carry = (from, to) => from + (to - gcd(from, to));
|
||||
function convertRadix2(data, from, to, padding) {
|
||||
if (!Array.isArray(data))
|
||||
throw new Error('convertRadix2: data should be array');
|
||||
if (from <= 0 || from > 32)
|
||||
throw new Error(`convertRadix2: wrong from=${from}`);
|
||||
if (to <= 0 || to > 32)
|
||||
throw new Error(`convertRadix2: wrong to=${to}`);
|
||||
if (radix2carry(from, to) > 32) {
|
||||
throw new Error(`convertRadix2: carry overflow from=${from} to=${to} carryBits=${radix2carry(from, to)}`);
|
||||
}
|
||||
let carry = 0;
|
||||
let pos = 0;
|
||||
const mask = 2 ** to - 1;
|
||||
const res = [];
|
||||
for (const n of data) {
|
||||
assertNumber(n);
|
||||
if (n >= 2 ** from)
|
||||
throw new Error(`convertRadix2: invalid data word=${n} from=${from}`);
|
||||
carry = (carry << from) | n;
|
||||
if (pos + from > 32)
|
||||
throw new Error(`convertRadix2: carry overflow pos=${pos} from=${from}`);
|
||||
pos += from;
|
||||
for (; pos >= to; pos -= to)
|
||||
res.push(((carry >> (pos - to)) & mask) >>> 0);
|
||||
carry &= 2 ** pos - 1;
|
||||
}
|
||||
carry = (carry << (to - pos)) & mask;
|
||||
if (!padding && pos >= from)
|
||||
throw new Error('Excess padding');
|
||||
if (!padding && carry)
|
||||
throw new Error(`Non-zero padding: ${carry}`);
|
||||
if (padding && pos > 0)
|
||||
res.push(carry >>> 0);
|
||||
return res;
|
||||
}
|
||||
function radix(num) {
|
||||
assertNumber(num);
|
||||
return {
|
||||
encode: (bytes) => {
|
||||
if (!(bytes instanceof Uint8Array))
|
||||
throw new Error('radix.encode input should be Uint8Array');
|
||||
return convertRadix(Array.from(bytes), 2 ** 8, num);
|
||||
},
|
||||
decode: (digits) => {
|
||||
if (!Array.isArray(digits) || (digits.length && typeof digits[0] !== 'number'))
|
||||
throw new Error('radix.decode input should be array of strings');
|
||||
return Uint8Array.from(convertRadix(digits, num, 2 ** 8));
|
||||
},
|
||||
};
|
||||
}
|
||||
function radix2(bits, revPadding = false) {
|
||||
assertNumber(bits);
|
||||
if (bits <= 0 || bits > 32)
|
||||
throw new Error('radix2: bits should be in (0..32]');
|
||||
if (radix2carry(8, bits) > 32 || radix2carry(bits, 8) > 32)
|
||||
throw new Error('radix2: carry overflow');
|
||||
return {
|
||||
encode: (bytes) => {
|
||||
if (!(bytes instanceof Uint8Array))
|
||||
throw new Error('radix2.encode input should be Uint8Array');
|
||||
return convertRadix2(Array.from(bytes), 8, bits, !revPadding);
|
||||
},
|
||||
decode: (digits) => {
|
||||
if (!Array.isArray(digits) || (digits.length && typeof digits[0] !== 'number'))
|
||||
throw new Error('radix2.decode input should be array of strings');
|
||||
return Uint8Array.from(convertRadix2(digits, bits, 8, revPadding));
|
||||
},
|
||||
};
|
||||
}
|
||||
function unsafeWrapper(fn) {
|
||||
if (typeof fn !== 'function')
|
||||
throw new Error('unsafeWrapper fn should be function');
|
||||
return function (...args) {
|
||||
try {
|
||||
return fn.apply(null, args);
|
||||
}
|
||||
catch (e) { }
|
||||
};
|
||||
}
|
||||
function checksum(len, fn) {
|
||||
assertNumber(len);
|
||||
if (typeof fn !== 'function')
|
||||
throw new Error('checksum fn should be function');
|
||||
return {
|
||||
encode(data) {
|
||||
if (!(data instanceof Uint8Array))
|
||||
throw new Error('checksum.encode: input should be Uint8Array');
|
||||
const checksum = fn(data).slice(0, len);
|
||||
const res = new Uint8Array(data.length + len);
|
||||
res.set(data);
|
||||
res.set(checksum, data.length);
|
||||
return res;
|
||||
},
|
||||
decode(data) {
|
||||
if (!(data instanceof Uint8Array))
|
||||
throw new Error('checksum.decode: input should be Uint8Array');
|
||||
const payload = data.slice(0, -len);
|
||||
const newChecksum = fn(payload).slice(0, len);
|
||||
const oldChecksum = data.slice(-len);
|
||||
for (let i = 0; i < len; i++)
|
||||
if (newChecksum[i] !== oldChecksum[i])
|
||||
throw new Error('Invalid checksum');
|
||||
return payload;
|
||||
},
|
||||
};
|
||||
}
|
||||
exports.utils = { alphabet, chain, checksum, radix, radix2, join, padding };
|
||||
exports.base16 = chain(radix2(4), alphabet('0123456789ABCDEF'), join(''));
|
||||
exports.base32 = chain(radix2(5), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'), padding(5), join(''));
|
||||
exports.base32hex = chain(radix2(5), alphabet('0123456789ABCDEFGHIJKLMNOPQRSTUV'), padding(5), join(''));
|
||||
exports.base32crockford = chain(radix2(5), alphabet('0123456789ABCDEFGHJKMNPQRSTVWXYZ'), join(''), normalize((s) => s.toUpperCase().replace(/O/g, '0').replace(/[IL]/g, '1')));
|
||||
exports.base64 = chain(radix2(6), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'), padding(6), join(''));
|
||||
exports.base64url = chain(radix2(6), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'), padding(6), join(''));
|
||||
const genBase58 = (abc) => chain(radix(58), alphabet(abc), join(''));
|
||||
exports.base58 = genBase58('123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz');
|
||||
exports.base58flickr = genBase58('123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ');
|
||||
exports.base58xrp = genBase58('rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz');
|
||||
const XMR_BLOCK_LEN = [0, 2, 3, 5, 6, 7, 9, 10, 11];
|
||||
exports.base58xmr = {
|
||||
encode(data) {
|
||||
let res = '';
|
||||
for (let i = 0; i < data.length; i += 8) {
|
||||
const block = data.subarray(i, i + 8);
|
||||
res += exports.base58.encode(block).padStart(XMR_BLOCK_LEN[block.length], '1');
|
||||
}
|
||||
return res;
|
||||
},
|
||||
decode(str) {
|
||||
let res = [];
|
||||
for (let i = 0; i < str.length; i += 11) {
|
||||
const slice = str.slice(i, i + 11);
|
||||
const blockLen = XMR_BLOCK_LEN.indexOf(slice.length);
|
||||
const block = exports.base58.decode(slice);
|
||||
for (let j = 0; j < block.length - blockLen; j++) {
|
||||
if (block[j] !== 0)
|
||||
throw new Error('base58xmr: wrong padding');
|
||||
}
|
||||
res = res.concat(Array.from(block.slice(block.length - blockLen)));
|
||||
}
|
||||
return Uint8Array.from(res);
|
||||
},
|
||||
};
|
||||
const base58check = (sha256) => chain(checksum(4, (data) => sha256(sha256(data))), exports.base58);
|
||||
exports.base58check = base58check;
|
||||
const BECH_ALPHABET = chain(alphabet('qpzry9x8gf2tvdw0s3jn54khce6mua7l'), join(''));
|
||||
const POLYMOD_GENERATORS = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3];
|
||||
function bech32Polymod(pre) {
|
||||
const b = pre >> 25;
|
||||
let chk = (pre & 0x1ffffff) << 5;
|
||||
for (let i = 0; i < POLYMOD_GENERATORS.length; i++) {
|
||||
if (((b >> i) & 1) === 1)
|
||||
chk ^= POLYMOD_GENERATORS[i];
|
||||
}
|
||||
return chk;
|
||||
}
|
||||
function bechChecksum(prefix, words, encodingConst = 1) {
|
||||
const len = prefix.length;
|
||||
let chk = 1;
|
||||
for (let i = 0; i < len; i++) {
|
||||
const c = prefix.charCodeAt(i);
|
||||
if (c < 33 || c > 126)
|
||||
throw new Error(`Invalid prefix (${prefix})`);
|
||||
chk = bech32Polymod(chk) ^ (c >> 5);
|
||||
}
|
||||
chk = bech32Polymod(chk);
|
||||
for (let i = 0; i < len; i++)
|
||||
chk = bech32Polymod(chk) ^ (prefix.charCodeAt(i) & 0x1f);
|
||||
for (let v of words)
|
||||
chk = bech32Polymod(chk) ^ v;
|
||||
for (let i = 0; i < 6; i++)
|
||||
chk = bech32Polymod(chk);
|
||||
chk ^= encodingConst;
|
||||
return BECH_ALPHABET.encode(convertRadix2([chk % 2 ** 30], 30, 5, false));
|
||||
}
|
||||
function genBech32(encoding) {
|
||||
const ENCODING_CONST = encoding === 'bech32' ? 1 : 0x2bc830a3;
|
||||
const _words = radix2(5);
|
||||
const fromWords = _words.decode;
|
||||
const toWords = _words.encode;
|
||||
const fromWordsUnsafe = unsafeWrapper(fromWords);
|
||||
function encode(prefix, words, limit = 90) {
|
||||
if (typeof prefix !== 'string')
|
||||
throw new Error(`bech32.encode prefix should be string, not ${typeof prefix}`);
|
||||
if (!Array.isArray(words) || (words.length && typeof words[0] !== 'number'))
|
||||
throw new Error(`bech32.encode words should be array of numbers, not ${typeof words}`);
|
||||
const actualLength = prefix.length + 7 + words.length;
|
||||
if (limit !== false && actualLength > limit)
|
||||
throw new TypeError(`Length ${actualLength} exceeds limit ${limit}`);
|
||||
prefix = prefix.toLowerCase();
|
||||
return `${prefix}1${BECH_ALPHABET.encode(words)}${bechChecksum(prefix, words, ENCODING_CONST)}`;
|
||||
}
|
||||
function decode(str, limit = 90) {
|
||||
if (typeof str !== 'string')
|
||||
throw new Error(`bech32.decode input should be string, not ${typeof str}`);
|
||||
if (str.length < 8 || (limit !== false && str.length > limit))
|
||||
throw new TypeError(`Wrong string length: ${str.length} (${str}). Expected (8..${limit})`);
|
||||
const lowered = str.toLowerCase();
|
||||
if (str !== lowered && str !== str.toUpperCase())
|
||||
throw new Error(`String must be lowercase or uppercase`);
|
||||
str = lowered;
|
||||
const sepIndex = str.lastIndexOf('1');
|
||||
if (sepIndex === 0 || sepIndex === -1)
|
||||
throw new Error(`Letter "1" must be present between prefix and data only`);
|
||||
const prefix = str.slice(0, sepIndex);
|
||||
const _words = str.slice(sepIndex + 1);
|
||||
if (_words.length < 6)
|
||||
throw new Error('Data must be at least 6 characters long');
|
||||
const words = BECH_ALPHABET.decode(_words).slice(0, -6);
|
||||
const sum = bechChecksum(prefix, words, ENCODING_CONST);
|
||||
if (!_words.endsWith(sum))
|
||||
throw new Error(`Invalid checksum in ${str}: expected "${sum}"`);
|
||||
return { prefix, words };
|
||||
}
|
||||
const decodeUnsafe = unsafeWrapper(decode);
|
||||
function decodeToBytes(str) {
|
||||
const { prefix, words } = decode(str, false);
|
||||
return { prefix, words, bytes: fromWords(words) };
|
||||
}
|
||||
return { encode, decode, decodeToBytes, decodeUnsafe, fromWords, fromWordsUnsafe, toWords };
|
||||
}
|
||||
exports.bech32 = genBech32('bech32');
|
||||
exports.bech32m = genBech32('bech32m');
|
||||
exports.utf8 = {
|
||||
encode: (data) => new TextDecoder().decode(data),
|
||||
decode: (str) => new TextEncoder().encode(str),
|
||||
};
|
||||
exports.hex = chain(radix2(4), alphabet('0123456789abcdef'), join(''), normalize((s) => {
|
||||
if (typeof s !== 'string' || s.length % 2)
|
||||
throw new TypeError(`hex.decode: expected string, got ${typeof s} with length ${s.length}`);
|
||||
return s.toLowerCase();
|
||||
}));
|
||||
const CODERS = {
|
||||
utf8: exports.utf8, hex: exports.hex, base16: exports.base16, base32: exports.base32, base64: exports.base64, base64url: exports.base64url, base58: exports.base58, base58xmr: exports.base58xmr
|
||||
};
|
||||
const coderTypeError = `Invalid encoding type. Available types: ${Object.keys(CODERS).join(', ')}`;
|
||||
const bytesToString = (type, bytes) => {
|
||||
if (typeof type !== 'string' || !CODERS.hasOwnProperty(type))
|
||||
throw new TypeError(coderTypeError);
|
||||
if (!(bytes instanceof Uint8Array))
|
||||
throw new TypeError('bytesToString() expects Uint8Array');
|
||||
return CODERS[type].encode(bytes);
|
||||
};
|
||||
exports.bytesToString = bytesToString;
|
||||
exports.str = exports.bytesToString;
|
||||
const stringToBytes = (type, str) => {
|
||||
if (!CODERS.hasOwnProperty(type))
|
||||
throw new TypeError(coderTypeError);
|
||||
if (typeof str !== 'string')
|
||||
throw new TypeError('stringToBytes() expects string');
|
||||
return CODERS[type].decode(str);
|
||||
};
|
||||
exports.stringToBytes = stringToBytes;
|
||||
exports.bytes = exports.stringToBytes;
|
||||
60
node_modules/@scure/base/package.json
generated
vendored
Normal file
60
node_modules/@scure/base/package.json
generated
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
{
|
||||
"name": "@scure/base",
|
||||
"version": "1.1.1",
|
||||
"description": "Secure, audited & 0-dep implementation of bech32, base64, base58, base32 & base16",
|
||||
"files": [
|
||||
"lib/index.js",
|
||||
"lib/esm/index.js",
|
||||
"lib/esm/package.json",
|
||||
"lib/index.d.ts"
|
||||
],
|
||||
"main": "lib/index.js",
|
||||
"module": "lib/esm/index.js",
|
||||
"types": "lib/index.d.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"import": "./lib/esm/index.js",
|
||||
"default": "./lib/index.js"
|
||||
},
|
||||
"./index.d.ts": "./lib/index.d.ts"
|
||||
},
|
||||
"scripts": {
|
||||
"bench": "node test/benchmark/index.js",
|
||||
"build": "tsc -d && tsc -p tsconfig.esm.json",
|
||||
"lint": "prettier --check index.ts",
|
||||
"test": "node test/index.js"
|
||||
},
|
||||
"author": "Paul Miller (https://paulmillr.com)",
|
||||
"license": "MIT",
|
||||
"homepage": "https://github.com/paulmillr/scure-base",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/paulmillr/scure-base.git"
|
||||
},
|
||||
"devDependencies": {
|
||||
"micro-should": "0.2.0",
|
||||
"prettier": "2.6.2",
|
||||
"typescript": "4.7.3"
|
||||
},
|
||||
"keywords": [
|
||||
"bech32",
|
||||
"bech32m",
|
||||
"base64",
|
||||
"base58",
|
||||
"base32",
|
||||
"base16",
|
||||
"rfc4648",
|
||||
"rfc3548",
|
||||
"crockford",
|
||||
"encode",
|
||||
"encoder",
|
||||
"base-x",
|
||||
"base"
|
||||
],
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
]
|
||||
}
|
||||
21
node_modules/@scure/bip32/LICENSE
generated
vendored
Normal file
21
node_modules/@scure/bip32/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2022 Patricio Palladino, Paul Miller (paulmillr.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the “Software”), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
107
node_modules/@scure/bip32/README.md
generated
vendored
Normal file
107
node_modules/@scure/bip32/README.md
generated
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
# scure-bip32
|
||||
|
||||
Secure, [audited](#security) & minimal implementation of BIP32 hierarchical deterministic (HD) wallets over secp256k1.
|
||||
|
||||
Compared to popular `hdkey` package, scure-bip32:
|
||||
|
||||
- Supports ESM and common.js
|
||||
- Is 418KB all-bundled instead of 5.9MB
|
||||
- Uses 3 dependencies instead of 24
|
||||
- Had an external security [audit](#security) by Cure53
|
||||
|
||||
Check out [scure-bip39](https://github.com/paulmillr/scure-bip39) if you need mnemonic phrases. See [ed25519-keygen](https://github.com/paulmillr/ed25519-keygen) if you need SLIP-0010/BIP32 ed25519 hdkey implementation.
|
||||
|
||||
### This library belongs to *scure*
|
||||
|
||||
> **scure** — secure, independently audited packages for every use case.
|
||||
|
||||
- Audited by a third-party
|
||||
- Releases are signed with PGP keys and built transparently with NPM provenance
|
||||
- Check out all libraries:
|
||||
[base](https://github.com/paulmillr/scure-base),
|
||||
[bip32](https://github.com/paulmillr/scure-bip32),
|
||||
[bip39](https://github.com/paulmillr/scure-bip39),
|
||||
[btc-signer](https://github.com/paulmillr/scure-btc-signer)
|
||||
|
||||
## Usage
|
||||
|
||||
> npm install @scure/bip32
|
||||
|
||||
This module exports a single class `HDKey`, which should be used like this:
|
||||
|
||||
```ts
|
||||
const { HDKey } = require("@scure/bip32");
|
||||
const hdkey1 = HDKey.fromMasterSeed(seed);
|
||||
const hdkey2 = HDKey.fromExtendedKey(base58key);
|
||||
const hdkey3 = HDKey.fromJSON({ xpriv: string });
|
||||
|
||||
// props
|
||||
[hdkey1.depth, hdkey1.index, hdkey1.chainCode];
|
||||
console.log(hdkey2.privateKey, hdkey2.publicKey);
|
||||
console.log(hdkey3.derive("m/0/2147483647'/1"));
|
||||
const sig = hdkey3.sign(hash);
|
||||
hdkey3.verify(hash, sig);
|
||||
```
|
||||
|
||||
Note: `chainCode` property is essentially a private part
|
||||
of a secret "master" key, it should be guarded from unauthorized access.
|
||||
|
||||
The full API is:
|
||||
|
||||
```ts
|
||||
class HDKey {
|
||||
public static HARDENED_OFFSET: number;
|
||||
public static fromMasterSeed(seed: Uint8Array, versions: Versions): HDKey;
|
||||
public static fromExtendedKey(base58key: string, versions: Versions): HDKey;
|
||||
public static fromJSON(json: { xpriv: string }): HDKey;
|
||||
|
||||
readonly versions: Versions;
|
||||
readonly depth: number = 0;
|
||||
readonly index: number = 0;
|
||||
readonly chainCode: Uint8Array | null = null;
|
||||
readonly parentFingerprint: number = 0;
|
||||
|
||||
get fingerprint(): number;
|
||||
get identifier(): Uint8Array | undefined;
|
||||
get pubKeyHash(): Uint8Array | undefined;
|
||||
get privateKey(): Uint8Array | null;
|
||||
get publicKey(): Uint8Array | null;
|
||||
get privateExtendedKey(): string;
|
||||
get publicExtendedKey(): string;
|
||||
|
||||
derive(path: string): HDKey;
|
||||
deriveChild(index: number): HDKey;
|
||||
sign(hash: Uint8Array): Uint8Array;
|
||||
verify(hash: Uint8Array, signature: Uint8Array): boolean;
|
||||
wipePrivateData(): this;
|
||||
}
|
||||
|
||||
interface Versions {
|
||||
private: number;
|
||||
public: number;
|
||||
}
|
||||
```
|
||||
|
||||
The `hdkey` submodule provides a library for keys derivation according to
|
||||
[BIP32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki).
|
||||
|
||||
It has almost the exact same API than the version `1.x` of
|
||||
[`hdkey` from cryptocoinjs](https://github.com/cryptocoinjs/hdkey),
|
||||
but it's backed by this package's primitives, and has built-in TypeScript types.
|
||||
Its only difference is that it has to be be used with a named import.
|
||||
The implementation is [loosely based on hdkey, which has MIT License](#LICENSE).
|
||||
|
||||
## Security
|
||||
|
||||
The library has been audited by Cure53 on Jan 5, 2022. Check out the audit [PDF](./audit/2022-01-05-cure53-audit-nbl2.pdf) & [URL](https://cure53.de/pentest-report_hashing-libs.pdf). See [changes since audit](https://github.com/paulmillr/scure-bip32/compare/1.0.1..main).
|
||||
|
||||
1. The library was initially developed for [js-ethereum-cryptography](https://github.com/ethereum/js-ethereum-cryptography)
|
||||
2. At commit [ae00e6d7](https://github.com/ethereum/js-ethereum-cryptography/commit/ae00e6d7d24fb3c76a1c7fe10039f6ecd120b77e), it
|
||||
was extracted to a separate package called `micro-bip32`
|
||||
3. After the audit we've decided to use NPM namespace for security. Since `@micro` namespace was taken, we've renamed the package to `@scure/bip32`
|
||||
|
||||
## License
|
||||
|
||||
[MIT License](./LICENSE)
|
||||
|
||||
Copyright (c) 2022 Patricio Palladino, Paul Miller (paulmillr.com)
|
||||
307
node_modules/@scure/bip32/index.ts
generated
vendored
Normal file
307
node_modules/@scure/bip32/index.ts
generated
vendored
Normal file
@@ -0,0 +1,307 @@
|
||||
/*! scure-bip32 - MIT License (c) 2022 Patricio Palladino, Paul Miller (paulmillr.com) */
|
||||
import { hmac } from '@noble/hashes/hmac';
|
||||
import { ripemd160 } from '@noble/hashes/ripemd160';
|
||||
import { sha256 } from '@noble/hashes/sha256';
|
||||
import { sha512 } from '@noble/hashes/sha512';
|
||||
import { bytes as assertBytes } from '@noble/hashes/_assert';
|
||||
import { bytesToHex, concatBytes, createView, hexToBytes, utf8ToBytes } from '@noble/hashes/utils';
|
||||
import { secp256k1 as secp } from '@noble/curves/secp256k1';
|
||||
import { mod } from '@noble/curves/abstract/modular';
|
||||
import { base58check as base58checker } from '@scure/base';
|
||||
|
||||
const Point = secp.ProjectivePoint;
|
||||
const base58check = base58checker(sha256);
|
||||
|
||||
function bytesToNumber(bytes: Uint8Array): bigint {
|
||||
return BigInt(`0x${bytesToHex(bytes)}`);
|
||||
}
|
||||
|
||||
function numberToBytes(num: bigint): Uint8Array {
|
||||
return hexToBytes(num.toString(16).padStart(64, '0'));
|
||||
}
|
||||
|
||||
const MASTER_SECRET = utf8ToBytes('Bitcoin seed');
|
||||
// Bitcoin hardcoded by default
|
||||
const BITCOIN_VERSIONS: Versions = { private: 0x0488ade4, public: 0x0488b21e };
|
||||
export const HARDENED_OFFSET: number = 0x80000000;
|
||||
|
||||
export interface Versions {
|
||||
private: number;
|
||||
public: number;
|
||||
}
|
||||
|
||||
const hash160 = (data: Uint8Array) => ripemd160(sha256(data));
|
||||
const fromU32 = (data: Uint8Array) => createView(data).getUint32(0, false);
|
||||
const toU32 = (n: number) => {
|
||||
if (!Number.isSafeInteger(n) || n < 0 || n > 2 ** 32 - 1) {
|
||||
throw new Error(`Invalid number=${n}. Should be from 0 to 2 ** 32 - 1`);
|
||||
}
|
||||
const buf = new Uint8Array(4);
|
||||
createView(buf).setUint32(0, n, false);
|
||||
return buf;
|
||||
};
|
||||
|
||||
interface HDKeyOpt {
|
||||
versions: Versions;
|
||||
depth?: number;
|
||||
index?: number;
|
||||
parentFingerprint?: number;
|
||||
chainCode: Uint8Array;
|
||||
publicKey?: Uint8Array;
|
||||
privateKey?: Uint8Array | bigint;
|
||||
}
|
||||
|
||||
export class HDKey {
|
||||
get fingerprint(): number {
|
||||
if (!this.pubHash) {
|
||||
throw new Error('No publicKey set!');
|
||||
}
|
||||
return fromU32(this.pubHash);
|
||||
}
|
||||
get identifier(): Uint8Array | undefined {
|
||||
return this.pubHash;
|
||||
}
|
||||
get pubKeyHash(): Uint8Array | undefined {
|
||||
return this.pubHash;
|
||||
}
|
||||
get privateKey(): Uint8Array | null {
|
||||
return this.privKeyBytes || null;
|
||||
}
|
||||
get publicKey(): Uint8Array | null {
|
||||
return this.pubKey || null;
|
||||
}
|
||||
get privateExtendedKey(): string {
|
||||
const priv = this.privateKey;
|
||||
if (!priv) {
|
||||
throw new Error('No private key');
|
||||
}
|
||||
return base58check.encode(
|
||||
this.serialize(this.versions.private, concatBytes(new Uint8Array([0]), priv))
|
||||
);
|
||||
}
|
||||
get publicExtendedKey(): string {
|
||||
if (!this.pubKey) {
|
||||
throw new Error('No public key');
|
||||
}
|
||||
return base58check.encode(this.serialize(this.versions.public, this.pubKey));
|
||||
}
|
||||
|
||||
public static fromMasterSeed(seed: Uint8Array, versions: Versions = BITCOIN_VERSIONS): HDKey {
|
||||
assertBytes(seed);
|
||||
if (8 * seed.length < 128 || 8 * seed.length > 512) {
|
||||
throw new Error(
|
||||
`HDKey: wrong seed length=${seed.length}. Should be between 128 and 512 bits; 256 bits is advised)`
|
||||
);
|
||||
}
|
||||
const I = hmac(sha512, MASTER_SECRET, seed);
|
||||
return new HDKey({
|
||||
versions,
|
||||
chainCode: I.slice(32),
|
||||
privateKey: I.slice(0, 32),
|
||||
});
|
||||
}
|
||||
|
||||
public static fromExtendedKey(base58key: string, versions: Versions = BITCOIN_VERSIONS): HDKey {
|
||||
// => version(4) || depth(1) || fingerprint(4) || index(4) || chain(32) || key(33)
|
||||
const keyBuffer: Uint8Array = base58check.decode(base58key);
|
||||
const keyView = createView(keyBuffer);
|
||||
const version = keyView.getUint32(0, false);
|
||||
const opt = {
|
||||
versions,
|
||||
depth: keyBuffer[4],
|
||||
parentFingerprint: keyView.getUint32(5, false),
|
||||
index: keyView.getUint32(9, false),
|
||||
chainCode: keyBuffer.slice(13, 45),
|
||||
};
|
||||
const key = keyBuffer.slice(45);
|
||||
const isPriv = key[0] === 0;
|
||||
if (version !== versions[isPriv ? 'private' : 'public']) {
|
||||
throw new Error('Version mismatch');
|
||||
}
|
||||
if (isPriv) {
|
||||
return new HDKey({ ...opt, privateKey: key.slice(1) });
|
||||
} else {
|
||||
return new HDKey({ ...opt, publicKey: key });
|
||||
}
|
||||
}
|
||||
|
||||
public static fromJSON(json: { xpriv: string }): HDKey {
|
||||
return HDKey.fromExtendedKey(json.xpriv);
|
||||
}
|
||||
public readonly versions: Versions;
|
||||
public readonly depth: number = 0;
|
||||
public readonly index: number = 0;
|
||||
public readonly chainCode: Uint8Array | null = null;
|
||||
public readonly parentFingerprint: number = 0;
|
||||
private privKey?: bigint;
|
||||
private privKeyBytes?: Uint8Array;
|
||||
private pubKey?: Uint8Array;
|
||||
private pubHash: Uint8Array | undefined;
|
||||
|
||||
constructor(opt: HDKeyOpt) {
|
||||
if (!opt || typeof opt !== 'object') {
|
||||
throw new Error('HDKey.constructor must not be called directly');
|
||||
}
|
||||
this.versions = opt.versions || BITCOIN_VERSIONS;
|
||||
this.depth = opt.depth || 0;
|
||||
this.chainCode = opt.chainCode;
|
||||
this.index = opt.index || 0;
|
||||
this.parentFingerprint = opt.parentFingerprint || 0;
|
||||
if (!this.depth) {
|
||||
if (this.parentFingerprint || this.index) {
|
||||
throw new Error('HDKey: zero depth with non-zero index/parent fingerprint');
|
||||
}
|
||||
}
|
||||
if (opt.publicKey && opt.privateKey) {
|
||||
throw new Error('HDKey: publicKey and privateKey at same time.');
|
||||
}
|
||||
if (opt.privateKey) {
|
||||
if (!secp.utils.isValidPrivateKey(opt.privateKey)) {
|
||||
throw new Error('Invalid private key');
|
||||
}
|
||||
this.privKey =
|
||||
typeof opt.privateKey === 'bigint' ? opt.privateKey : bytesToNumber(opt.privateKey);
|
||||
this.privKeyBytes = numberToBytes(this.privKey);
|
||||
this.pubKey = secp.getPublicKey(opt.privateKey, true);
|
||||
} else if (opt.publicKey) {
|
||||
this.pubKey = Point.fromHex(opt.publicKey).toRawBytes(true); // force compressed point
|
||||
} else {
|
||||
throw new Error('HDKey: no public or private key provided');
|
||||
}
|
||||
this.pubHash = hash160(this.pubKey);
|
||||
}
|
||||
|
||||
public derive(path: string): HDKey {
|
||||
if (!/^[mM]'?/.test(path)) {
|
||||
throw new Error('Path must start with "m" or "M"');
|
||||
}
|
||||
if (/^[mM]'?$/.test(path)) {
|
||||
return this;
|
||||
}
|
||||
const parts = path.replace(/^[mM]'?\//, '').split('/');
|
||||
// tslint:disable-next-line
|
||||
let child: HDKey = this;
|
||||
for (const c of parts) {
|
||||
const m = /^(\d+)('?)$/.exec(c);
|
||||
if (!m || m.length !== 3) {
|
||||
throw new Error(`Invalid child index: ${c}`);
|
||||
}
|
||||
let idx = +m[1];
|
||||
if (!Number.isSafeInteger(idx) || idx >= HARDENED_OFFSET) {
|
||||
throw new Error('Invalid index');
|
||||
}
|
||||
// hardened key
|
||||
if (m[2] === "'") {
|
||||
idx += HARDENED_OFFSET;
|
||||
}
|
||||
child = child.deriveChild(idx);
|
||||
}
|
||||
return child;
|
||||
}
|
||||
|
||||
public deriveChild(index: number): HDKey {
|
||||
if (!this.pubKey || !this.chainCode) {
|
||||
throw new Error('No publicKey or chainCode set');
|
||||
}
|
||||
let data = toU32(index);
|
||||
if (index >= HARDENED_OFFSET) {
|
||||
// Hardened
|
||||
const priv = this.privateKey;
|
||||
if (!priv) {
|
||||
throw new Error('Could not derive hardened child key');
|
||||
}
|
||||
// Hardened child: 0x00 || ser256(kpar) || ser32(index)
|
||||
data = concatBytes(new Uint8Array([0]), priv, data);
|
||||
} else {
|
||||
// Normal child: serP(point(kpar)) || ser32(index)
|
||||
data = concatBytes(this.pubKey, data);
|
||||
}
|
||||
const I = hmac(sha512, this.chainCode, data);
|
||||
const childTweak = bytesToNumber(I.slice(0, 32));
|
||||
const chainCode = I.slice(32);
|
||||
if (!secp.utils.isValidPrivateKey(childTweak)) {
|
||||
throw new Error('Tweak bigger than curve order');
|
||||
}
|
||||
const opt: HDKeyOpt = {
|
||||
versions: this.versions,
|
||||
chainCode,
|
||||
depth: this.depth + 1,
|
||||
parentFingerprint: this.fingerprint,
|
||||
index,
|
||||
};
|
||||
try {
|
||||
// Private parent key -> private child key
|
||||
if (this.privateKey) {
|
||||
const added = mod(this.privKey! + childTweak, secp.CURVE.n);
|
||||
if (!secp.utils.isValidPrivateKey(added)) {
|
||||
throw new Error('The tweak was out of range or the resulted private key is invalid');
|
||||
}
|
||||
opt.privateKey = added;
|
||||
} else {
|
||||
const added = Point.fromHex(this.pubKey).add(Point.fromPrivateKey(childTweak));
|
||||
// Cryptographically impossible: hmac-sha512 preimage would need to be found
|
||||
if (added.equals(Point.ZERO)) {
|
||||
throw new Error('The tweak was equal to negative P, which made the result key invalid');
|
||||
}
|
||||
opt.publicKey = added.toRawBytes(true);
|
||||
}
|
||||
return new HDKey(opt);
|
||||
} catch (err) {
|
||||
return this.deriveChild(index + 1);
|
||||
}
|
||||
}
|
||||
|
||||
public sign(hash: Uint8Array): Uint8Array {
|
||||
if (!this.privateKey) {
|
||||
throw new Error('No privateKey set!');
|
||||
}
|
||||
assertBytes(hash, 32);
|
||||
return secp.sign(hash, this.privKey!).toCompactRawBytes();
|
||||
}
|
||||
|
||||
public verify(hash: Uint8Array, signature: Uint8Array): boolean {
|
||||
assertBytes(hash, 32);
|
||||
assertBytes(signature, 64);
|
||||
if (!this.publicKey) {
|
||||
throw new Error('No publicKey set!');
|
||||
}
|
||||
let sig;
|
||||
try {
|
||||
sig = secp.Signature.fromCompact(signature);
|
||||
} catch (error) {
|
||||
return false;
|
||||
}
|
||||
return secp.verify(sig, hash, this.publicKey);
|
||||
}
|
||||
|
||||
public wipePrivateData(): this {
|
||||
this.privKey = undefined;
|
||||
if (this.privKeyBytes) {
|
||||
this.privKeyBytes.fill(0);
|
||||
this.privKeyBytes = undefined;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
public toJSON(): { xpriv: string; xpub: string } {
|
||||
return {
|
||||
xpriv: this.privateExtendedKey,
|
||||
xpub: this.publicExtendedKey,
|
||||
};
|
||||
}
|
||||
|
||||
private serialize(version: number, key: Uint8Array) {
|
||||
if (!this.chainCode) {
|
||||
throw new Error('No chainCode set');
|
||||
}
|
||||
assertBytes(key, 33);
|
||||
// version(4) || depth(1) || fingerprint(4) || index(4) || chain(32) || key(33)
|
||||
return concatBytes(
|
||||
toU32(version),
|
||||
new Uint8Array([this.depth]),
|
||||
toU32(this.parentFingerprint),
|
||||
toU32(this.index),
|
||||
this.chainCode,
|
||||
key
|
||||
);
|
||||
}
|
||||
}
|
||||
257
node_modules/@scure/bip32/lib/esm/index.js
generated
vendored
Normal file
257
node_modules/@scure/bip32/lib/esm/index.js
generated
vendored
Normal file
@@ -0,0 +1,257 @@
|
||||
import { hmac } from '@noble/hashes/hmac';
|
||||
import { ripemd160 } from '@noble/hashes/ripemd160';
|
||||
import { sha256 } from '@noble/hashes/sha256';
|
||||
import { sha512 } from '@noble/hashes/sha512';
|
||||
import { bytes as assertBytes } from '@noble/hashes/_assert';
|
||||
import { bytesToHex, concatBytes, createView, hexToBytes, utf8ToBytes } from '@noble/hashes/utils';
|
||||
import { secp256k1 as secp } from '@noble/curves/secp256k1';
|
||||
import { mod } from '@noble/curves/abstract/modular';
|
||||
import { base58check as base58checker } from '@scure/base';
|
||||
const Point = secp.ProjectivePoint;
|
||||
const base58check = base58checker(sha256);
|
||||
function bytesToNumber(bytes) {
|
||||
return BigInt(`0x${bytesToHex(bytes)}`);
|
||||
}
|
||||
function numberToBytes(num) {
|
||||
return hexToBytes(num.toString(16).padStart(64, '0'));
|
||||
}
|
||||
const MASTER_SECRET = utf8ToBytes('Bitcoin seed');
|
||||
const BITCOIN_VERSIONS = { private: 0x0488ade4, public: 0x0488b21e };
|
||||
export const HARDENED_OFFSET = 0x80000000;
|
||||
const hash160 = (data) => ripemd160(sha256(data));
|
||||
const fromU32 = (data) => createView(data).getUint32(0, false);
|
||||
const toU32 = (n) => {
|
||||
if (!Number.isSafeInteger(n) || n < 0 || n > 2 ** 32 - 1) {
|
||||
throw new Error(`Invalid number=${n}. Should be from 0 to 2 ** 32 - 1`);
|
||||
}
|
||||
const buf = new Uint8Array(4);
|
||||
createView(buf).setUint32(0, n, false);
|
||||
return buf;
|
||||
};
|
||||
export class HDKey {
|
||||
get fingerprint() {
|
||||
if (!this.pubHash) {
|
||||
throw new Error('No publicKey set!');
|
||||
}
|
||||
return fromU32(this.pubHash);
|
||||
}
|
||||
get identifier() {
|
||||
return this.pubHash;
|
||||
}
|
||||
get pubKeyHash() {
|
||||
return this.pubHash;
|
||||
}
|
||||
get privateKey() {
|
||||
return this.privKeyBytes || null;
|
||||
}
|
||||
get publicKey() {
|
||||
return this.pubKey || null;
|
||||
}
|
||||
get privateExtendedKey() {
|
||||
const priv = this.privateKey;
|
||||
if (!priv) {
|
||||
throw new Error('No private key');
|
||||
}
|
||||
return base58check.encode(this.serialize(this.versions.private, concatBytes(new Uint8Array([0]), priv)));
|
||||
}
|
||||
get publicExtendedKey() {
|
||||
if (!this.pubKey) {
|
||||
throw new Error('No public key');
|
||||
}
|
||||
return base58check.encode(this.serialize(this.versions.public, this.pubKey));
|
||||
}
|
||||
static fromMasterSeed(seed, versions = BITCOIN_VERSIONS) {
|
||||
assertBytes(seed);
|
||||
if (8 * seed.length < 128 || 8 * seed.length > 512) {
|
||||
throw new Error(`HDKey: wrong seed length=${seed.length}. Should be between 128 and 512 bits; 256 bits is advised)`);
|
||||
}
|
||||
const I = hmac(sha512, MASTER_SECRET, seed);
|
||||
return new HDKey({
|
||||
versions,
|
||||
chainCode: I.slice(32),
|
||||
privateKey: I.slice(0, 32),
|
||||
});
|
||||
}
|
||||
static fromExtendedKey(base58key, versions = BITCOIN_VERSIONS) {
|
||||
const keyBuffer = base58check.decode(base58key);
|
||||
const keyView = createView(keyBuffer);
|
||||
const version = keyView.getUint32(0, false);
|
||||
const opt = {
|
||||
versions,
|
||||
depth: keyBuffer[4],
|
||||
parentFingerprint: keyView.getUint32(5, false),
|
||||
index: keyView.getUint32(9, false),
|
||||
chainCode: keyBuffer.slice(13, 45),
|
||||
};
|
||||
const key = keyBuffer.slice(45);
|
||||
const isPriv = key[0] === 0;
|
||||
if (version !== versions[isPriv ? 'private' : 'public']) {
|
||||
throw new Error('Version mismatch');
|
||||
}
|
||||
if (isPriv) {
|
||||
return new HDKey({ ...opt, privateKey: key.slice(1) });
|
||||
}
|
||||
else {
|
||||
return new HDKey({ ...opt, publicKey: key });
|
||||
}
|
||||
}
|
||||
static fromJSON(json) {
|
||||
return HDKey.fromExtendedKey(json.xpriv);
|
||||
}
|
||||
constructor(opt) {
|
||||
this.depth = 0;
|
||||
this.index = 0;
|
||||
this.chainCode = null;
|
||||
this.parentFingerprint = 0;
|
||||
if (!opt || typeof opt !== 'object') {
|
||||
throw new Error('HDKey.constructor must not be called directly');
|
||||
}
|
||||
this.versions = opt.versions || BITCOIN_VERSIONS;
|
||||
this.depth = opt.depth || 0;
|
||||
this.chainCode = opt.chainCode;
|
||||
this.index = opt.index || 0;
|
||||
this.parentFingerprint = opt.parentFingerprint || 0;
|
||||
if (!this.depth) {
|
||||
if (this.parentFingerprint || this.index) {
|
||||
throw new Error('HDKey: zero depth with non-zero index/parent fingerprint');
|
||||
}
|
||||
}
|
||||
if (opt.publicKey && opt.privateKey) {
|
||||
throw new Error('HDKey: publicKey and privateKey at same time.');
|
||||
}
|
||||
if (opt.privateKey) {
|
||||
if (!secp.utils.isValidPrivateKey(opt.privateKey)) {
|
||||
throw new Error('Invalid private key');
|
||||
}
|
||||
this.privKey =
|
||||
typeof opt.privateKey === 'bigint' ? opt.privateKey : bytesToNumber(opt.privateKey);
|
||||
this.privKeyBytes = numberToBytes(this.privKey);
|
||||
this.pubKey = secp.getPublicKey(opt.privateKey, true);
|
||||
}
|
||||
else if (opt.publicKey) {
|
||||
this.pubKey = Point.fromHex(opt.publicKey).toRawBytes(true);
|
||||
}
|
||||
else {
|
||||
throw new Error('HDKey: no public or private key provided');
|
||||
}
|
||||
this.pubHash = hash160(this.pubKey);
|
||||
}
|
||||
derive(path) {
|
||||
if (!/^[mM]'?/.test(path)) {
|
||||
throw new Error('Path must start with "m" or "M"');
|
||||
}
|
||||
if (/^[mM]'?$/.test(path)) {
|
||||
return this;
|
||||
}
|
||||
const parts = path.replace(/^[mM]'?\//, '').split('/');
|
||||
let child = this;
|
||||
for (const c of parts) {
|
||||
const m = /^(\d+)('?)$/.exec(c);
|
||||
if (!m || m.length !== 3) {
|
||||
throw new Error(`Invalid child index: ${c}`);
|
||||
}
|
||||
let idx = +m[1];
|
||||
if (!Number.isSafeInteger(idx) || idx >= HARDENED_OFFSET) {
|
||||
throw new Error('Invalid index');
|
||||
}
|
||||
if (m[2] === "'") {
|
||||
idx += HARDENED_OFFSET;
|
||||
}
|
||||
child = child.deriveChild(idx);
|
||||
}
|
||||
return child;
|
||||
}
|
||||
deriveChild(index) {
|
||||
if (!this.pubKey || !this.chainCode) {
|
||||
throw new Error('No publicKey or chainCode set');
|
||||
}
|
||||
let data = toU32(index);
|
||||
if (index >= HARDENED_OFFSET) {
|
||||
const priv = this.privateKey;
|
||||
if (!priv) {
|
||||
throw new Error('Could not derive hardened child key');
|
||||
}
|
||||
data = concatBytes(new Uint8Array([0]), priv, data);
|
||||
}
|
||||
else {
|
||||
data = concatBytes(this.pubKey, data);
|
||||
}
|
||||
const I = hmac(sha512, this.chainCode, data);
|
||||
const childTweak = bytesToNumber(I.slice(0, 32));
|
||||
const chainCode = I.slice(32);
|
||||
if (!secp.utils.isValidPrivateKey(childTweak)) {
|
||||
throw new Error('Tweak bigger than curve order');
|
||||
}
|
||||
const opt = {
|
||||
versions: this.versions,
|
||||
chainCode,
|
||||
depth: this.depth + 1,
|
||||
parentFingerprint: this.fingerprint,
|
||||
index,
|
||||
};
|
||||
try {
|
||||
if (this.privateKey) {
|
||||
const added = mod(this.privKey + childTweak, secp.CURVE.n);
|
||||
if (!secp.utils.isValidPrivateKey(added)) {
|
||||
throw new Error('The tweak was out of range or the resulted private key is invalid');
|
||||
}
|
||||
opt.privateKey = added;
|
||||
}
|
||||
else {
|
||||
const added = Point.fromHex(this.pubKey).add(Point.fromPrivateKey(childTweak));
|
||||
if (added.equals(Point.ZERO)) {
|
||||
throw new Error('The tweak was equal to negative P, which made the result key invalid');
|
||||
}
|
||||
opt.publicKey = added.toRawBytes(true);
|
||||
}
|
||||
return new HDKey(opt);
|
||||
}
|
||||
catch (err) {
|
||||
return this.deriveChild(index + 1);
|
||||
}
|
||||
}
|
||||
sign(hash) {
|
||||
if (!this.privateKey) {
|
||||
throw new Error('No privateKey set!');
|
||||
}
|
||||
assertBytes(hash, 32);
|
||||
return secp.sign(hash, this.privKey).toCompactRawBytes();
|
||||
}
|
||||
verify(hash, signature) {
|
||||
assertBytes(hash, 32);
|
||||
assertBytes(signature, 64);
|
||||
if (!this.publicKey) {
|
||||
throw new Error('No publicKey set!');
|
||||
}
|
||||
let sig;
|
||||
try {
|
||||
sig = secp.Signature.fromCompact(signature);
|
||||
}
|
||||
catch (error) {
|
||||
return false;
|
||||
}
|
||||
return secp.verify(sig, hash, this.publicKey);
|
||||
}
|
||||
wipePrivateData() {
|
||||
this.privKey = undefined;
|
||||
if (this.privKeyBytes) {
|
||||
this.privKeyBytes.fill(0);
|
||||
this.privKeyBytes = undefined;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
toJSON() {
|
||||
return {
|
||||
xpriv: this.privateExtendedKey,
|
||||
xpub: this.publicExtendedKey,
|
||||
};
|
||||
}
|
||||
serialize(version, key) {
|
||||
if (!this.chainCode) {
|
||||
throw new Error('No chainCode set');
|
||||
}
|
||||
assertBytes(key, 33);
|
||||
return concatBytes(toU32(version), new Uint8Array([this.depth]), toU32(this.parentFingerprint), toU32(this.index), this.chainCode, key);
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=index.js.map
|
||||
1
node_modules/@scure/bip32/lib/esm/index.js.map
generated
vendored
Normal file
1
node_modules/@scure/bip32/lib/esm/index.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
6
node_modules/@scure/bip32/lib/esm/package.json
generated
vendored
Normal file
6
node_modules/@scure/bip32/lib/esm/package.json
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"type": "module",
|
||||
"browser": {
|
||||
"crypto": false
|
||||
}
|
||||
}
|
||||
49
node_modules/@scure/bip32/lib/index.d.ts
generated
vendored
Normal file
49
node_modules/@scure/bip32/lib/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
export declare const HARDENED_OFFSET: number;
|
||||
export interface Versions {
|
||||
private: number;
|
||||
public: number;
|
||||
}
|
||||
interface HDKeyOpt {
|
||||
versions: Versions;
|
||||
depth?: number;
|
||||
index?: number;
|
||||
parentFingerprint?: number;
|
||||
chainCode: Uint8Array;
|
||||
publicKey?: Uint8Array;
|
||||
privateKey?: Uint8Array | bigint;
|
||||
}
|
||||
export declare class HDKey {
|
||||
get fingerprint(): number;
|
||||
get identifier(): Uint8Array | undefined;
|
||||
get pubKeyHash(): Uint8Array | undefined;
|
||||
get privateKey(): Uint8Array | null;
|
||||
get publicKey(): Uint8Array | null;
|
||||
get privateExtendedKey(): string;
|
||||
get publicExtendedKey(): string;
|
||||
static fromMasterSeed(seed: Uint8Array, versions?: Versions): HDKey;
|
||||
static fromExtendedKey(base58key: string, versions?: Versions): HDKey;
|
||||
static fromJSON(json: {
|
||||
xpriv: string;
|
||||
}): HDKey;
|
||||
readonly versions: Versions;
|
||||
readonly depth: number;
|
||||
readonly index: number;
|
||||
readonly chainCode: Uint8Array | null;
|
||||
readonly parentFingerprint: number;
|
||||
private privKey?;
|
||||
private privKeyBytes?;
|
||||
private pubKey?;
|
||||
private pubHash;
|
||||
constructor(opt: HDKeyOpt);
|
||||
derive(path: string): HDKey;
|
||||
deriveChild(index: number): HDKey;
|
||||
sign(hash: Uint8Array): Uint8Array;
|
||||
verify(hash: Uint8Array, signature: Uint8Array): boolean;
|
||||
wipePrivateData(): this;
|
||||
toJSON(): {
|
||||
xpriv: string;
|
||||
xpub: string;
|
||||
};
|
||||
private serialize;
|
||||
}
|
||||
export {};
|
||||
261
node_modules/@scure/bip32/lib/index.js
generated
vendored
Normal file
261
node_modules/@scure/bip32/lib/index.js
generated
vendored
Normal file
@@ -0,0 +1,261 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.HDKey = exports.HARDENED_OFFSET = void 0;
|
||||
const hmac_1 = require("@noble/hashes/hmac");
|
||||
const ripemd160_1 = require("@noble/hashes/ripemd160");
|
||||
const sha256_1 = require("@noble/hashes/sha256");
|
||||
const sha512_1 = require("@noble/hashes/sha512");
|
||||
const _assert_1 = require("@noble/hashes/_assert");
|
||||
const utils_1 = require("@noble/hashes/utils");
|
||||
const secp256k1_1 = require("@noble/curves/secp256k1");
|
||||
const modular_1 = require("@noble/curves/abstract/modular");
|
||||
const base_1 = require("@scure/base");
|
||||
const Point = secp256k1_1.secp256k1.ProjectivePoint;
|
||||
const base58check = (0, base_1.base58check)(sha256_1.sha256);
|
||||
function bytesToNumber(bytes) {
|
||||
return BigInt(`0x${(0, utils_1.bytesToHex)(bytes)}`);
|
||||
}
|
||||
function numberToBytes(num) {
|
||||
return (0, utils_1.hexToBytes)(num.toString(16).padStart(64, '0'));
|
||||
}
|
||||
const MASTER_SECRET = (0, utils_1.utf8ToBytes)('Bitcoin seed');
|
||||
const BITCOIN_VERSIONS = { private: 0x0488ade4, public: 0x0488b21e };
|
||||
exports.HARDENED_OFFSET = 0x80000000;
|
||||
const hash160 = (data) => (0, ripemd160_1.ripemd160)((0, sha256_1.sha256)(data));
|
||||
const fromU32 = (data) => (0, utils_1.createView)(data).getUint32(0, false);
|
||||
const toU32 = (n) => {
|
||||
if (!Number.isSafeInteger(n) || n < 0 || n > 2 ** 32 - 1) {
|
||||
throw new Error(`Invalid number=${n}. Should be from 0 to 2 ** 32 - 1`);
|
||||
}
|
||||
const buf = new Uint8Array(4);
|
||||
(0, utils_1.createView)(buf).setUint32(0, n, false);
|
||||
return buf;
|
||||
};
|
||||
class HDKey {
|
||||
get fingerprint() {
|
||||
if (!this.pubHash) {
|
||||
throw new Error('No publicKey set!');
|
||||
}
|
||||
return fromU32(this.pubHash);
|
||||
}
|
||||
get identifier() {
|
||||
return this.pubHash;
|
||||
}
|
||||
get pubKeyHash() {
|
||||
return this.pubHash;
|
||||
}
|
||||
get privateKey() {
|
||||
return this.privKeyBytes || null;
|
||||
}
|
||||
get publicKey() {
|
||||
return this.pubKey || null;
|
||||
}
|
||||
get privateExtendedKey() {
|
||||
const priv = this.privateKey;
|
||||
if (!priv) {
|
||||
throw new Error('No private key');
|
||||
}
|
||||
return base58check.encode(this.serialize(this.versions.private, (0, utils_1.concatBytes)(new Uint8Array([0]), priv)));
|
||||
}
|
||||
get publicExtendedKey() {
|
||||
if (!this.pubKey) {
|
||||
throw new Error('No public key');
|
||||
}
|
||||
return base58check.encode(this.serialize(this.versions.public, this.pubKey));
|
||||
}
|
||||
static fromMasterSeed(seed, versions = BITCOIN_VERSIONS) {
|
||||
(0, _assert_1.bytes)(seed);
|
||||
if (8 * seed.length < 128 || 8 * seed.length > 512) {
|
||||
throw new Error(`HDKey: wrong seed length=${seed.length}. Should be between 128 and 512 bits; 256 bits is advised)`);
|
||||
}
|
||||
const I = (0, hmac_1.hmac)(sha512_1.sha512, MASTER_SECRET, seed);
|
||||
return new HDKey({
|
||||
versions,
|
||||
chainCode: I.slice(32),
|
||||
privateKey: I.slice(0, 32),
|
||||
});
|
||||
}
|
||||
static fromExtendedKey(base58key, versions = BITCOIN_VERSIONS) {
|
||||
const keyBuffer = base58check.decode(base58key);
|
||||
const keyView = (0, utils_1.createView)(keyBuffer);
|
||||
const version = keyView.getUint32(0, false);
|
||||
const opt = {
|
||||
versions,
|
||||
depth: keyBuffer[4],
|
||||
parentFingerprint: keyView.getUint32(5, false),
|
||||
index: keyView.getUint32(9, false),
|
||||
chainCode: keyBuffer.slice(13, 45),
|
||||
};
|
||||
const key = keyBuffer.slice(45);
|
||||
const isPriv = key[0] === 0;
|
||||
if (version !== versions[isPriv ? 'private' : 'public']) {
|
||||
throw new Error('Version mismatch');
|
||||
}
|
||||
if (isPriv) {
|
||||
return new HDKey({ ...opt, privateKey: key.slice(1) });
|
||||
}
|
||||
else {
|
||||
return new HDKey({ ...opt, publicKey: key });
|
||||
}
|
||||
}
|
||||
static fromJSON(json) {
|
||||
return HDKey.fromExtendedKey(json.xpriv);
|
||||
}
|
||||
constructor(opt) {
|
||||
this.depth = 0;
|
||||
this.index = 0;
|
||||
this.chainCode = null;
|
||||
this.parentFingerprint = 0;
|
||||
if (!opt || typeof opt !== 'object') {
|
||||
throw new Error('HDKey.constructor must not be called directly');
|
||||
}
|
||||
this.versions = opt.versions || BITCOIN_VERSIONS;
|
||||
this.depth = opt.depth || 0;
|
||||
this.chainCode = opt.chainCode;
|
||||
this.index = opt.index || 0;
|
||||
this.parentFingerprint = opt.parentFingerprint || 0;
|
||||
if (!this.depth) {
|
||||
if (this.parentFingerprint || this.index) {
|
||||
throw new Error('HDKey: zero depth with non-zero index/parent fingerprint');
|
||||
}
|
||||
}
|
||||
if (opt.publicKey && opt.privateKey) {
|
||||
throw new Error('HDKey: publicKey and privateKey at same time.');
|
||||
}
|
||||
if (opt.privateKey) {
|
||||
if (!secp256k1_1.secp256k1.utils.isValidPrivateKey(opt.privateKey)) {
|
||||
throw new Error('Invalid private key');
|
||||
}
|
||||
this.privKey =
|
||||
typeof opt.privateKey === 'bigint' ? opt.privateKey : bytesToNumber(opt.privateKey);
|
||||
this.privKeyBytes = numberToBytes(this.privKey);
|
||||
this.pubKey = secp256k1_1.secp256k1.getPublicKey(opt.privateKey, true);
|
||||
}
|
||||
else if (opt.publicKey) {
|
||||
this.pubKey = Point.fromHex(opt.publicKey).toRawBytes(true);
|
||||
}
|
||||
else {
|
||||
throw new Error('HDKey: no public or private key provided');
|
||||
}
|
||||
this.pubHash = hash160(this.pubKey);
|
||||
}
|
||||
derive(path) {
|
||||
if (!/^[mM]'?/.test(path)) {
|
||||
throw new Error('Path must start with "m" or "M"');
|
||||
}
|
||||
if (/^[mM]'?$/.test(path)) {
|
||||
return this;
|
||||
}
|
||||
const parts = path.replace(/^[mM]'?\//, '').split('/');
|
||||
let child = this;
|
||||
for (const c of parts) {
|
||||
const m = /^(\d+)('?)$/.exec(c);
|
||||
if (!m || m.length !== 3) {
|
||||
throw new Error(`Invalid child index: ${c}`);
|
||||
}
|
||||
let idx = +m[1];
|
||||
if (!Number.isSafeInteger(idx) || idx >= exports.HARDENED_OFFSET) {
|
||||
throw new Error('Invalid index');
|
||||
}
|
||||
if (m[2] === "'") {
|
||||
idx += exports.HARDENED_OFFSET;
|
||||
}
|
||||
child = child.deriveChild(idx);
|
||||
}
|
||||
return child;
|
||||
}
|
||||
deriveChild(index) {
|
||||
if (!this.pubKey || !this.chainCode) {
|
||||
throw new Error('No publicKey or chainCode set');
|
||||
}
|
||||
let data = toU32(index);
|
||||
if (index >= exports.HARDENED_OFFSET) {
|
||||
const priv = this.privateKey;
|
||||
if (!priv) {
|
||||
throw new Error('Could not derive hardened child key');
|
||||
}
|
||||
data = (0, utils_1.concatBytes)(new Uint8Array([0]), priv, data);
|
||||
}
|
||||
else {
|
||||
data = (0, utils_1.concatBytes)(this.pubKey, data);
|
||||
}
|
||||
const I = (0, hmac_1.hmac)(sha512_1.sha512, this.chainCode, data);
|
||||
const childTweak = bytesToNumber(I.slice(0, 32));
|
||||
const chainCode = I.slice(32);
|
||||
if (!secp256k1_1.secp256k1.utils.isValidPrivateKey(childTweak)) {
|
||||
throw new Error('Tweak bigger than curve order');
|
||||
}
|
||||
const opt = {
|
||||
versions: this.versions,
|
||||
chainCode,
|
||||
depth: this.depth + 1,
|
||||
parentFingerprint: this.fingerprint,
|
||||
index,
|
||||
};
|
||||
try {
|
||||
if (this.privateKey) {
|
||||
const added = (0, modular_1.mod)(this.privKey + childTweak, secp256k1_1.secp256k1.CURVE.n);
|
||||
if (!secp256k1_1.secp256k1.utils.isValidPrivateKey(added)) {
|
||||
throw new Error('The tweak was out of range or the resulted private key is invalid');
|
||||
}
|
||||
opt.privateKey = added;
|
||||
}
|
||||
else {
|
||||
const added = Point.fromHex(this.pubKey).add(Point.fromPrivateKey(childTweak));
|
||||
if (added.equals(Point.ZERO)) {
|
||||
throw new Error('The tweak was equal to negative P, which made the result key invalid');
|
||||
}
|
||||
opt.publicKey = added.toRawBytes(true);
|
||||
}
|
||||
return new HDKey(opt);
|
||||
}
|
||||
catch (err) {
|
||||
return this.deriveChild(index + 1);
|
||||
}
|
||||
}
|
||||
sign(hash) {
|
||||
if (!this.privateKey) {
|
||||
throw new Error('No privateKey set!');
|
||||
}
|
||||
(0, _assert_1.bytes)(hash, 32);
|
||||
return secp256k1_1.secp256k1.sign(hash, this.privKey).toCompactRawBytes();
|
||||
}
|
||||
verify(hash, signature) {
|
||||
(0, _assert_1.bytes)(hash, 32);
|
||||
(0, _assert_1.bytes)(signature, 64);
|
||||
if (!this.publicKey) {
|
||||
throw new Error('No publicKey set!');
|
||||
}
|
||||
let sig;
|
||||
try {
|
||||
sig = secp256k1_1.secp256k1.Signature.fromCompact(signature);
|
||||
}
|
||||
catch (error) {
|
||||
return false;
|
||||
}
|
||||
return secp256k1_1.secp256k1.verify(sig, hash, this.publicKey);
|
||||
}
|
||||
wipePrivateData() {
|
||||
this.privKey = undefined;
|
||||
if (this.privKeyBytes) {
|
||||
this.privKeyBytes.fill(0);
|
||||
this.privKeyBytes = undefined;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
toJSON() {
|
||||
return {
|
||||
xpriv: this.privateExtendedKey,
|
||||
xpub: this.publicExtendedKey,
|
||||
};
|
||||
}
|
||||
serialize(version, key) {
|
||||
if (!this.chainCode) {
|
||||
throw new Error('No chainCode set');
|
||||
}
|
||||
(0, _assert_1.bytes)(key, 33);
|
||||
return (0, utils_1.concatBytes)(toU32(version), new Uint8Array([this.depth]), toU32(this.parentFingerprint), toU32(this.index), this.chainCode, key);
|
||||
}
|
||||
}
|
||||
exports.HDKey = HDKey;
|
||||
//# sourceMappingURL=index.js.map
|
||||
1
node_modules/@scure/bip32/lib/index.js.map
generated
vendored
Normal file
1
node_modules/@scure/bip32/lib/index.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
21
node_modules/@scure/bip32/node_modules/@noble/curves/LICENSE
generated
vendored
Normal file
21
node_modules/@scure/bip32/node_modules/@noble/curves/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2022 Paul Miller (https://paulmillr.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the “Software”), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
971
node_modules/@scure/bip32/node_modules/@noble/curves/README.md
generated
vendored
Normal file
971
node_modules/@scure/bip32/node_modules/@noble/curves/README.md
generated
vendored
Normal file
@@ -0,0 +1,971 @@
|
||||
# noble-curves
|
||||
|
||||
Audited & minimal JS implementation of elliptic curve cryptography.
|
||||
|
||||
- 🔒 [**Audited**](#security) by an independent security firm
|
||||
- 🔻 Tree-shaking-friendly: use only what's necessary, other code won't be included
|
||||
- 🏎 Ultra-fast, hand-optimized for caveats of JS engines
|
||||
- 🔍 Unique tests ensure correctness: property-based, cross-library and Wycheproof vectors, fuzzing
|
||||
- ➰ Short Weierstrass, Edwards, Montgomery curves
|
||||
- ✍️ ECDSA, EdDSA, Schnorr, BLS signature schemes, ECDH key agreement
|
||||
- 🔖 SUF-CMA and SBS (non-repudiation) for ed25519, ed448 and others
|
||||
- #️⃣ Hash-to-curve
|
||||
for encoding or hashing an arbitrary string to an elliptic curve point
|
||||
- 🧜♂️ Poseidon ZK-friendly hash
|
||||
|
||||
Check out [Upgrading](#upgrading) if you've previously used single-feature noble
|
||||
packages. See [Resources](#resources) for articles and real-world software that uses curves.
|
||||
|
||||
### This library belongs to _noble_ crypto
|
||||
|
||||
> **noble-crypto** — high-security, easily auditable set of contained cryptographic libraries and tools.
|
||||
|
||||
- No dependencies, protection against supply chain attacks
|
||||
- Auditable TypeScript / JS code
|
||||
- Supported in all major browsers and stable node.js versions
|
||||
- All releases are signed with PGP keys
|
||||
- Check out [homepage](https://paulmillr.com/noble/) & all libraries:
|
||||
[curves](https://github.com/paulmillr/noble-curves)
|
||||
(4kb versions [secp256k1](https://github.com/paulmillr/noble-secp256k1),
|
||||
[ed25519](https://github.com/paulmillr/noble-ed25519)),
|
||||
[hashes](https://github.com/paulmillr/noble-hashes)
|
||||
|
||||
## Usage
|
||||
|
||||
> npm install @noble/curves
|
||||
|
||||
We support all major platforms and runtimes.
|
||||
For [Deno](https://deno.land), ensure to use [npm specifier](https://deno.land/manual@v1.28.0/node/npm_specifiers).
|
||||
For React Native, you may need a [polyfill for crypto.getRandomValues](https://github.com/LinusU/react-native-get-random-values).
|
||||
If you don't like NPM, a standalone [noble-curves.js](https://github.com/paulmillr/noble-curves/releases) is also available.
|
||||
|
||||
The library is tree-shaking-friendly and does not expose root entry point as
|
||||
`@noble/curves`. Instead, you need to import specific primitives.
|
||||
This is done to ensure small size of your apps.
|
||||
|
||||
The package consists of two parts:
|
||||
|
||||
* [Implementations](#implementations), utilizing one dependency [noble-hashes](https://github.com/paulmillr/noble-hashes),
|
||||
providing ready-to-use:
|
||||
- NIST curves secp256r1 / p256, secp384r1 / p384, secp521r1 / p521
|
||||
- SECG curve secp256k1
|
||||
- ed25519 / curve25519 / x25519 / ristretto255, edwards448 / curve448 / x448
|
||||
- pairing-friendly curves bls12-381, bn254
|
||||
- [pasta](https://electriccoin.co/blog/the-pasta-curves-for-halo-2-and-beyond/) curves
|
||||
2. [Abstract](#abstract-api), zero-dependency elliptic curve algorithms
|
||||
|
||||
### Implementations
|
||||
|
||||
#### Generic example for all curves, secp256k1
|
||||
|
||||
```ts
|
||||
// Each curve has similar methods
|
||||
import { secp256k1 } from '@noble/curves/secp256k1'; // ESM and Common.js
|
||||
// import { secp256k1 } from 'npm:@noble/curves@1.2.0/secp256k1'; // Deno
|
||||
const priv = secp256k1.utils.randomPrivateKey();
|
||||
const pub = secp256k1.getPublicKey(priv);
|
||||
const msg = new Uint8Array(32).fill(1);
|
||||
const sig = secp256k1.sign(msg, priv);
|
||||
const isValid = secp256k1.verify(sig, msg, pub) === true;
|
||||
|
||||
// hex strings are also supported besides Uint8Arrays:
|
||||
const privHex = '46c930bc7bb4db7f55da20798697421b98c4175a52c630294d75a84b9c126236';
|
||||
const pub2 = secp256k1.getPublicKey(privHex);
|
||||
```
|
||||
|
||||
#### All imports
|
||||
|
||||
```typescript
|
||||
import { secp256k1, schnorr } from '@noble/curves/secp256k1';
|
||||
import { ed25519, ed25519ph, ed25519ctx, x25519, RistrettoPoint } from '@noble/curves/ed25519';
|
||||
import { ed448, ed448ph, ed448ctx, x448 } from '@noble/curves/ed448';
|
||||
import { p256 } from '@noble/curves/p256';
|
||||
import { p384 } from '@noble/curves/p384';
|
||||
import { p521 } from '@noble/curves/p521';
|
||||
import { pallas, vesta } from '@noble/curves/pasta';
|
||||
import { bls12_381 } from '@noble/curves/bls12-381';
|
||||
import { bn254 } from '@noble/curves/bn254';
|
||||
import { jubjub } from '@noble/curves/jubjub';
|
||||
```
|
||||
|
||||
#### ECDSA public key recovery & ECDH
|
||||
|
||||
```ts
|
||||
// extraEntropy https://moderncrypto.org/mail-archive/curves/2017/000925.html
|
||||
const sigImprovedSecurity = secp256k1.sign(msg, priv, { extraEntropy: true });
|
||||
sig.recoverPublicKey(msg) === pub; // public key recovery
|
||||
const someonesPub = secp256k1.getPublicKey(secp256k1.utils.randomPrivateKey());
|
||||
const shared = secp256k1.getSharedSecret(priv, someonesPub); // ECDH
|
||||
```
|
||||
|
||||
#### Schnorr signatures over secp256k1 (BIP340)
|
||||
|
||||
```ts
|
||||
import { schnorr } from '@noble/curves/secp256k1';
|
||||
const priv = schnorr.utils.randomPrivateKey();
|
||||
const pub = schnorr.getPublicKey(priv);
|
||||
const msg = new TextEncoder().encode('hello');
|
||||
const sig = schnorr.sign(msg, priv);
|
||||
const isValid = schnorr.verify(sig, msg, pub);
|
||||
```
|
||||
|
||||
#### ed25519, X25519, ristretto255
|
||||
|
||||
```ts
|
||||
import { ed25519 } from '@noble/curves/ed25519';
|
||||
const priv = ed25519.utils.randomPrivateKey();
|
||||
const pub = ed25519.getPublicKey(priv);
|
||||
const msg = new TextEncoder().encode('hello');
|
||||
const sig = ed25519.sign(msg, priv);
|
||||
ed25519.verify(sig, msg, pub); // Default mode: follows ZIP215
|
||||
ed25519.verify(sig, msg, pub, { zip215: false }); // RFC8032 / FIPS 186-5
|
||||
```
|
||||
|
||||
Default `verify` behavior follows [ZIP215](https://zips.z.cash/zip-0215) and
|
||||
[can be used in consensus-critical applications](https://hdevalence.ca/blog/2020-10-04-its-25519am).
|
||||
It has SUF-CMA (strong unforgeability under chosen message attacks).
|
||||
`zip215: false` option switches verification criteria to strict
|
||||
[RFC8032](https://www.rfc-editor.org/rfc/rfc8032) / [FIPS 186-5](https://csrc.nist.gov/publications/detail/fips/186/5/final)
|
||||
and additionally provides non-repudiation with SBS [(Strongly Binding Signatures)](https://eprint.iacr.org/2020/1244).
|
||||
|
||||
X25519 follows [RFC7748](https://www.rfc-editor.org/rfc/rfc7748).
|
||||
ristretto255 follows [irtf draft](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-ristretto255-decaf448).
|
||||
|
||||
```ts
|
||||
// Variants from RFC8032: with context, prehashed
|
||||
import { ed25519ctx, ed25519ph } from '@noble/curves/ed25519';
|
||||
|
||||
// ECDH using curve25519 aka x25519
|
||||
import { x25519 } from '@noble/curves/ed25519';
|
||||
const priv = 'a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4';
|
||||
const pub = 'e6db6867583030db3594c1a424b15f7c726624ec26b3353b10a903a6d0ab1c4c';
|
||||
x25519.getSharedSecret(priv, pub) === x25519.scalarMult(priv, pub); // aliases
|
||||
x25519.getPublicKey(priv) === x25519.scalarMultBase(priv);
|
||||
x25519.getPublicKey(x25519.utils.randomPrivateKey());
|
||||
|
||||
// ed25519 => x25519 conversion
|
||||
import { edwardsToMontgomeryPub, edwardsToMontgomeryPriv } from '@noble/curves/ed25519';
|
||||
edwardsToMontgomeryPub(ed25519.getPublicKey(ed25519.utils.randomPrivateKey()));
|
||||
edwardsToMontgomeryPriv(ed25519.utils.randomPrivateKey());
|
||||
|
||||
// hash-to-curve, ristretto255
|
||||
import { hashToCurve, encodeToCurve, RistrettoPoint } from '@noble/curves/ed25519';
|
||||
const rp = RistrettoPoint.fromHex(
|
||||
'6a493210f7499cd17fecb510ae0cea23a110e8d5b901f8acadd3095c73a3b919'
|
||||
);
|
||||
RistrettoPoint.hashToCurve('Ristretto is traditionally a short shot of espresso coffee');
|
||||
// also has add(), equals(), multiply(), toRawBytes() methods
|
||||
```
|
||||
|
||||
#### ed448, X448
|
||||
|
||||
```ts
|
||||
import { ed448 } from '@noble/curves/ed448';
|
||||
const priv = ed448.utils.randomPrivateKey();
|
||||
const pub = ed448.getPublicKey(priv);
|
||||
const msg = new TextEncoder().encode('whatsup');
|
||||
const sig = ed448.sign(msg, priv);
|
||||
ed448.verify(sig, msg, pub);
|
||||
|
||||
import { ed448ph, ed448ctx, x448, hashToCurve, encodeToCurve } from '@noble/curves/ed448';
|
||||
x448.getSharedSecret(priv, pub) === x448.scalarMult(priv, pub); // aliases
|
||||
x448.getPublicKey(priv) === x448.scalarMultBase(priv);
|
||||
```
|
||||
|
||||
Same RFC7748 / RFC8032 are followed.
|
||||
|
||||
#### bls12-381
|
||||
|
||||
See [abstract/bls](#abstractbls-barreto-lynn-scott-curves).
|
||||
|
||||
#### Accessing a curve's variables
|
||||
|
||||
```ts
|
||||
import { secp256k1 } from '@noble/curves/secp256k1';
|
||||
// Every curve has `CURVE` object that contains its parameters, field, and others
|
||||
console.log(secp256k1.CURVE.p); // field modulus
|
||||
console.log(secp256k1.CURVE.n); // curve order
|
||||
console.log(secp256k1.CURVE.a, secp256k1.CURVE.b); // equation params
|
||||
console.log(secp256k1.CURVE.Gx, secp256k1.CURVE.Gy); // base point coordinates
|
||||
```
|
||||
|
||||
## Abstract API
|
||||
|
||||
Abstract API allows to define custom curves. All arithmetics is done with JS
|
||||
bigints over finite fields, which is defined from `modular` sub-module. For
|
||||
scalar multiplication, we use
|
||||
[precomputed tables with w-ary non-adjacent form (wNAF)](https://paulmillr.com/posts/noble-secp256k1-fast-ecc/).
|
||||
Precomputes are enabled for weierstrass and edwards BASE points of a curve. You
|
||||
could precompute any other point (e.g. for ECDH) using `utils.precompute()`
|
||||
method: check out examples.
|
||||
|
||||
There are following zero-dependency algorithms:
|
||||
|
||||
- [abstract/weierstrass: Short Weierstrass curve](#abstractweierstrass-short-weierstrass-curve)
|
||||
- [abstract/edwards: Twisted Edwards curve](#abstractedwards-twisted-edwards-curve)
|
||||
- [abstract/montgomery: Montgomery curve](#abstractmontgomery-montgomery-curve)
|
||||
- [abstract/bls: Barreto-Lynn-Scott curves](#abstractbls-barreto-lynn-scott-curves)
|
||||
- [abstract/hash-to-curve: Hashing strings to curve points](#abstracthash-to-curve-hashing-strings-to-curve-points)
|
||||
- [abstract/poseidon: Poseidon hash](#abstractposeidon-poseidon-hash)
|
||||
- [abstract/modular: Modular arithmetics utilities](#abstractmodular-modular-arithmetics-utilities)
|
||||
- [abstract/utils: General utilities](#abstractutils-general-utilities)
|
||||
|
||||
### abstract/weierstrass: Short Weierstrass curve
|
||||
|
||||
```ts
|
||||
import { weierstrass } from '@noble/curves/abstract/weierstrass';
|
||||
import { Field } from '@noble/curves/abstract/modular'; // finite field for mod arithmetics
|
||||
import { sha256 } from '@noble/hashes/sha256'; // 3rd-party sha256() of type utils.CHash
|
||||
import { hmac } from '@noble/hashes/hmac'; // 3rd-party hmac() that will accept sha256()
|
||||
import { concatBytes, randomBytes } from '@noble/hashes/utils'; // 3rd-party utilities
|
||||
const secq256k1 = weierstrass({
|
||||
// secq256k1: cycle of secp256k1 with Fp/N flipped.
|
||||
// https://personaelabs.org/posts/spartan-ecdsa
|
||||
// https://zcash.github.io/halo2/background/curves.html#cycles-of-curves
|
||||
a: 0n,
|
||||
b: 7n,
|
||||
Fp: Field(2n ** 256n - 432420386565659656852420866394968145599n),
|
||||
n: 2n ** 256n - 2n ** 32n - 2n ** 9n - 2n ** 8n - 2n ** 7n - 2n ** 6n - 2n ** 4n - 1n,
|
||||
Gx: 55066263022277343669578718895168534326250603453777594175500187360389116729240n,
|
||||
Gy: 32670510020758816978083085130507043184471273380659243275938904335757337482424n,
|
||||
hash: sha256,
|
||||
hmac: (key: Uint8Array, ...msgs: Uint8Array[]) => hmac(sha256, key, concatBytes(...msgs)),
|
||||
randomBytes,
|
||||
});
|
||||
|
||||
// Replace weierstrass with weierstrassPoints if you don't need ECDSA, hash, hmac, randomBytes
|
||||
```
|
||||
|
||||
Short Weierstrass curve's formula is `y² = x³ + ax + b`. `weierstrass`
|
||||
expects arguments `a`, `b`, field `Fp`, curve order `n`, cofactor `h`
|
||||
and coordinates `Gx`, `Gy` of generator point.
|
||||
|
||||
**`k` generation** is done deterministically, following
|
||||
[RFC6979](https://www.rfc-editor.org/rfc/rfc6979). For this you will need
|
||||
`hmac` & `hash`, which in our implementations is provided by noble-hashes. If
|
||||
you're using different hashing library, make sure to wrap it in the following interface:
|
||||
|
||||
```ts
|
||||
type CHash = {
|
||||
(message: Uint8Array): Uint8Array;
|
||||
blockLen: number;
|
||||
outputLen: number;
|
||||
create(): any;
|
||||
};
|
||||
```
|
||||
|
||||
**Weierstrass points:**
|
||||
|
||||
1. Exported as `ProjectivePoint`
|
||||
2. Represented in projective (homogeneous) coordinates: (x, y, z) ∋ (x=x/z, y=y/z)
|
||||
3. Use complete exception-free formulas for addition and doubling
|
||||
4. Can be decoded/encoded from/to Uint8Array / hex strings using
|
||||
`ProjectivePoint.fromHex` and `ProjectivePoint#toRawBytes()`
|
||||
5. Have `assertValidity()` which checks for being on-curve
|
||||
6. Have `toAffine()` and `x` / `y` getters which convert to 2d xy affine coordinates
|
||||
|
||||
```ts
|
||||
// `weierstrassPoints()` returns `CURVE` and `ProjectivePoint`
|
||||
// `weierstrass()` returns `CurveFn`
|
||||
type SignOpts = { lowS?: boolean; prehash?: boolean; extraEntropy: boolean | Uint8Array };
|
||||
type CurveFn = {
|
||||
CURVE: ReturnType<typeof validateOpts>;
|
||||
getPublicKey: (privateKey: PrivKey, isCompressed?: boolean) => Uint8Array;
|
||||
getSharedSecret: (privateA: PrivKey, publicB: Hex, isCompressed?: boolean) => Uint8Array;
|
||||
sign: (msgHash: Hex, privKey: PrivKey, opts?: SignOpts) => SignatureType;
|
||||
verify: (
|
||||
signature: Hex | SignatureType,
|
||||
msgHash: Hex,
|
||||
publicKey: Hex,
|
||||
opts?: { lowS?: boolean; prehash?: boolean }
|
||||
) => boolean;
|
||||
ProjectivePoint: ProjectivePointConstructor;
|
||||
Signature: SignatureConstructor;
|
||||
utils: {
|
||||
normPrivateKeyToScalar: (key: PrivKey) => bigint;
|
||||
isValidPrivateKey(key: PrivKey): boolean;
|
||||
randomPrivateKey: () => Uint8Array;
|
||||
precompute: (windowSize?: number, point?: ProjPointType<bigint>) => ProjPointType<bigint>;
|
||||
};
|
||||
};
|
||||
|
||||
// T is usually bigint, but can be something else like complex numbers in BLS curves
|
||||
interface ProjPointType<T> extends Group<ProjPointType<T>> {
|
||||
readonly px: T;
|
||||
readonly py: T;
|
||||
readonly pz: T;
|
||||
get x(): bigint;
|
||||
get y(): bigint;
|
||||
multiply(scalar: bigint): ProjPointType<T>;
|
||||
multiplyUnsafe(scalar: bigint): ProjPointType<T>;
|
||||
multiplyAndAddUnsafe(Q: ProjPointType<T>, a: bigint, b: bigint): ProjPointType<T> | undefined;
|
||||
toAffine(iz?: T): AffinePoint<T>;
|
||||
isTorsionFree(): boolean;
|
||||
clearCofactor(): ProjPointType<T>;
|
||||
assertValidity(): void;
|
||||
hasEvenY(): boolean;
|
||||
toRawBytes(isCompressed?: boolean): Uint8Array;
|
||||
toHex(isCompressed?: boolean): string;
|
||||
}
|
||||
// Static methods for 3d XYZ points
|
||||
interface ProjConstructor<T> extends GroupConstructor<ProjPointType<T>> {
|
||||
new (x: T, y: T, z: T): ProjPointType<T>;
|
||||
fromAffine(p: AffinePoint<T>): ProjPointType<T>;
|
||||
fromHex(hex: Hex): ProjPointType<T>;
|
||||
fromPrivateKey(privateKey: PrivKey): ProjPointType<T>;
|
||||
}
|
||||
```
|
||||
|
||||
**ECDSA signatures** are represented by `Signature` instances and can be
|
||||
described by the interface:
|
||||
|
||||
```ts
|
||||
interface SignatureType {
|
||||
readonly r: bigint;
|
||||
readonly s: bigint;
|
||||
readonly recovery?: number;
|
||||
assertValidity(): void;
|
||||
addRecoveryBit(recovery: number): SignatureType;
|
||||
hasHighS(): boolean;
|
||||
normalizeS(): SignatureType;
|
||||
recoverPublicKey(msgHash: Hex): ProjPointType<bigint>;
|
||||
toCompactRawBytes(): Uint8Array;
|
||||
toCompactHex(): string;
|
||||
// DER-encoded
|
||||
toDERRawBytes(): Uint8Array;
|
||||
toDERHex(): string;
|
||||
}
|
||||
type SignatureConstructor = {
|
||||
new (r: bigint, s: bigint): SignatureType;
|
||||
fromCompact(hex: Hex): SignatureType;
|
||||
fromDER(hex: Hex): SignatureType;
|
||||
};
|
||||
```
|
||||
|
||||
More examples:
|
||||
|
||||
```typescript
|
||||
// All curves expose same generic interface.
|
||||
const priv = secq256k1.utils.randomPrivateKey();
|
||||
secq256k1.getPublicKey(priv); // Convert private key to public.
|
||||
const sig = secq256k1.sign(msg, priv); // Sign msg with private key.
|
||||
secq256k1.verify(sig, msg, priv); // Verify if sig is correct.
|
||||
|
||||
const Point = secq256k1.ProjectivePoint;
|
||||
const point = Point.BASE; // Elliptic curve Point class and BASE point static var.
|
||||
point.add(point).equals(point.double()); // add(), equals(), double() methods
|
||||
point.subtract(point).equals(Point.ZERO); // subtract() method, ZERO static var
|
||||
point.negate(); // Flips point over x/y coordinate.
|
||||
point.multiply(31415n); // Multiplication of Point by scalar.
|
||||
|
||||
point.assertValidity(); // Checks for being on-curve
|
||||
point.toAffine(); // Converts to 2d affine xy coordinates
|
||||
|
||||
secq256k1.CURVE.n;
|
||||
secq256k1.CURVE.p;
|
||||
secq256k1.CURVE.Fp.mod();
|
||||
secq256k1.CURVE.hash();
|
||||
|
||||
// precomputes
|
||||
const fast = secq256k1.utils.precompute(8, Point.fromHex(someonesPubKey));
|
||||
fast.multiply(privKey); // much faster ECDH now
|
||||
```
|
||||
|
||||
### abstract/edwards: Twisted Edwards curve
|
||||
|
||||
```ts
|
||||
import { twistedEdwards } from '@noble/curves/abstract/edwards';
|
||||
import { Field } from '@noble/curves/abstract/modular';
|
||||
import { sha512 } from '@noble/hashes/sha512';
|
||||
import { randomBytes } from '@noble/hashes/utils';
|
||||
|
||||
const Fp = Field(2n ** 255n - 19n);
|
||||
const ed25519 = twistedEdwards({
|
||||
a: Fp.create(-1n),
|
||||
d: Fp.div(-121665n, 121666n), // -121665n/121666n mod p
|
||||
Fp: Fp,
|
||||
n: 2n ** 252n + 27742317777372353535851937790883648493n,
|
||||
h: 8n,
|
||||
Gx: 15112221349535400772501151409588531511454012693041857206046113283949847762202n,
|
||||
Gy: 46316835694926478169428394003475163141307993866256225615783033603165251855960n,
|
||||
hash: sha512,
|
||||
randomBytes,
|
||||
adjustScalarBytes(bytes) {
|
||||
// optional; but mandatory in ed25519
|
||||
bytes[0] &= 248;
|
||||
bytes[31] &= 127;
|
||||
bytes[31] |= 64;
|
||||
return bytes;
|
||||
},
|
||||
} as const);
|
||||
```
|
||||
|
||||
Twisted Edwards curve's formula is `ax² + y² = 1 + dx²y²`. You must specify `a`, `d`, field `Fp`, order `n`, cofactor `h`
|
||||
and coordinates `Gx`, `Gy` of generator point.
|
||||
|
||||
For EdDSA signatures, `hash` param required. `adjustScalarBytes` which instructs how to change private scalars could be specified.
|
||||
|
||||
**Edwards points:**
|
||||
|
||||
1. Exported as `ExtendedPoint`
|
||||
2. Represented in extended coordinates: (x, y, z, t) ∋ (x=x/z, y=y/z)
|
||||
3. Use complete exception-free formulas for addition and doubling
|
||||
4. Can be decoded/encoded from/to Uint8Array / hex strings using `ExtendedPoint.fromHex` and `ExtendedPoint#toRawBytes()`
|
||||
5. Have `assertValidity()` which checks for being on-curve
|
||||
6. Have `toAffine()` and `x` / `y` getters which convert to 2d xy affine coordinates
|
||||
7. Have `isTorsionFree()`, `clearCofactor()` and `isSmallOrder()` utilities to handle torsions
|
||||
|
||||
```ts
|
||||
// `twistedEdwards()` returns `CurveFn` of following type:
|
||||
type CurveFn = {
|
||||
CURVE: ReturnType<typeof validateOpts>;
|
||||
getPublicKey: (privateKey: Hex) => Uint8Array;
|
||||
sign: (message: Hex, privateKey: Hex, context?: Hex) => Uint8Array;
|
||||
verify: (sig: SigType, message: Hex, publicKey: Hex, context?: Hex) => boolean;
|
||||
ExtendedPoint: ExtPointConstructor;
|
||||
utils: {
|
||||
randomPrivateKey: () => Uint8Array;
|
||||
getExtendedPublicKey: (key: PrivKey) => {
|
||||
head: Uint8Array;
|
||||
prefix: Uint8Array;
|
||||
scalar: bigint;
|
||||
point: PointType;
|
||||
pointBytes: Uint8Array;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
interface ExtPointType extends Group<ExtPointType> {
|
||||
readonly ex: bigint;
|
||||
readonly ey: bigint;
|
||||
readonly ez: bigint;
|
||||
readonly et: bigint;
|
||||
get x(): bigint;
|
||||
get y(): bigint;
|
||||
assertValidity(): void;
|
||||
multiply(scalar: bigint): ExtPointType;
|
||||
multiplyUnsafe(scalar: bigint): ExtPointType;
|
||||
isSmallOrder(): boolean;
|
||||
isTorsionFree(): boolean;
|
||||
clearCofactor(): ExtPointType;
|
||||
toAffine(iz?: bigint): AffinePoint<bigint>;
|
||||
toRawBytes(isCompressed?: boolean): Uint8Array;
|
||||
toHex(isCompressed?: boolean): string;
|
||||
}
|
||||
// Static methods of Extended Point with coordinates in X, Y, Z, T
|
||||
interface ExtPointConstructor extends GroupConstructor<ExtPointType> {
|
||||
new (x: bigint, y: bigint, z: bigint, t: bigint): ExtPointType;
|
||||
fromAffine(p: AffinePoint<bigint>): ExtPointType;
|
||||
fromHex(hex: Hex): ExtPointType;
|
||||
fromPrivateKey(privateKey: Hex): ExtPointType;
|
||||
}
|
||||
```
|
||||
|
||||
### abstract/montgomery: Montgomery curve
|
||||
|
||||
```typescript
|
||||
import { montgomery } from '@noble/curves/abstract/montgomery';
|
||||
import { Field } from '@noble/curves/abstract/modular';
|
||||
|
||||
const x25519 = montgomery({
|
||||
a: 486662n,
|
||||
Gu: 9n,
|
||||
Fp: Field(2n ** 255n - 19n),
|
||||
montgomeryBits: 255,
|
||||
nByteLength: 32,
|
||||
// Optional param
|
||||
adjustScalarBytes(bytes) {
|
||||
bytes[0] &= 248;
|
||||
bytes[31] &= 127;
|
||||
bytes[31] |= 64;
|
||||
return bytes;
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
The module contains methods for x-only ECDH on Curve25519 / Curve448 from RFC7748.
|
||||
Proper Elliptic Curve Points are not implemented yet.
|
||||
|
||||
You must specify curve params `Fp`, `a`, `Gu` coordinate of u, `montgomeryBits` and `nByteLength`.
|
||||
|
||||
### abstract/bls: Barreto-Lynn-Scott curves
|
||||
|
||||
The module abstracts BLS (Barreto-Lynn-Scott) pairing-friendly elliptic curve construction.
|
||||
They allow to construct [zk-SNARKs](https://z.cash/technology/zksnarks/) and
|
||||
use aggregated, batch-verifiable
|
||||
[threshold signatures](https://medium.com/snigirev.stepan/bls-signatures-better-than-schnorr-5a7fe30ea716),
|
||||
using Boneh-Lynn-Shacham signature scheme.
|
||||
|
||||
Main methods and properties are:
|
||||
|
||||
- `getPublicKey(privateKey)`
|
||||
- `sign(message, privateKey)`
|
||||
- `verify(signature, message, publicKey)`
|
||||
- `aggregatePublicKeys(publicKeys)`
|
||||
- `aggregateSignatures(signatures)`
|
||||
- `G1` and `G2` curves containing `CURVE` and `ProjectivePoint`
|
||||
- `Signature` property with `fromHex`, `toHex` methods
|
||||
- `fields` containing `Fp`, `Fp2`, `Fp6`, `Fp12`, `Fr`
|
||||
|
||||
Right now we only implement BLS12-381 (compatible with ETH and others),
|
||||
but in theory defining BLS12-377, BLS24 should be straightforward. An example:
|
||||
|
||||
```ts
|
||||
import { bls12_381 as bls } from '@noble/curves/bls12-381';
|
||||
const privateKey = '67d53f170b908cabb9eb326c3c337762d59289a8fec79f7bc9254b584b73265c';
|
||||
const message = '64726e3da8';
|
||||
const publicKey = bls.getPublicKey(privateKey);
|
||||
const signature = bls.sign(message, privateKey);
|
||||
const isValid = bls.verify(signature, message, publicKey);
|
||||
console.log({ publicKey, signature, isValid });
|
||||
|
||||
// Sign 1 msg with 3 keys
|
||||
const privateKeys = [
|
||||
'18f020b98eb798752a50ed0563b079c125b0db5dd0b1060d1c1b47d4a193e1e4',
|
||||
'ed69a8c50cf8c9836be3b67c7eeff416612d45ba39a5c099d48fa668bf558c9c',
|
||||
'16ae669f3be7a2121e17d0c68c05a8f3d6bef21ec0f2315f1d7aec12484e4cf5',
|
||||
];
|
||||
const messages = ['d2', '0d98', '05caf3'];
|
||||
const publicKeys = privateKeys.map(bls.getPublicKey);
|
||||
const signatures2 = privateKeys.map((p) => bls.sign(message, p));
|
||||
const aggPubKey2 = bls.aggregatePublicKeys(publicKeys);
|
||||
const aggSignature2 = bls.aggregateSignatures(signatures2);
|
||||
const isValid2 = bls.verify(aggSignature2, message, aggPubKey2);
|
||||
console.log({ signatures2, aggSignature2, isValid2 });
|
||||
|
||||
// Sign 3 msgs with 3 keys
|
||||
const signatures3 = privateKeys.map((p, i) => bls.sign(messages[i], p));
|
||||
const aggSignature3 = bls.aggregateSignatures(signatures3);
|
||||
const isValid3 = bls.verifyBatch(aggSignature3, messages, publicKeys);
|
||||
console.log({ publicKeys, signatures3, aggSignature3, isValid3 });
|
||||
|
||||
// bls.pairing(PointG1, PointG2) // pairings
|
||||
// bls.G1.ProjectivePoint.BASE, bls.G2.ProjectivePoint.BASE
|
||||
// bls.fields.Fp, bls.fields.Fp2, bls.fields.Fp12, bls.fields.Fr
|
||||
|
||||
// hash-to-curve examples can be seen below
|
||||
```
|
||||
|
||||
Full types:
|
||||
|
||||
```ts
|
||||
getPublicKey: (privateKey: PrivKey) => Uint8Array;
|
||||
sign: {
|
||||
(message: Hex, privateKey: PrivKey): Uint8Array;
|
||||
(message: ProjPointType<Fp2>, privateKey: PrivKey): ProjPointType<Fp2>;
|
||||
};
|
||||
verify: (
|
||||
signature: Hex | ProjPointType<Fp2>,
|
||||
message: Hex | ProjPointType<Fp2>,
|
||||
publicKey: Hex | ProjPointType<Fp>
|
||||
) => boolean;
|
||||
verifyBatch: (
|
||||
signature: Hex | ProjPointType<Fp2>,
|
||||
messages: (Hex | ProjPointType<Fp2>)[],
|
||||
publicKeys: (Hex | ProjPointType<Fp>)[]
|
||||
) => boolean;
|
||||
aggregatePublicKeys: {
|
||||
(publicKeys: Hex[]): Uint8Array;
|
||||
(publicKeys: ProjPointType<Fp>[]): ProjPointType<Fp>;
|
||||
};
|
||||
aggregateSignatures: {
|
||||
(signatures: Hex[]): Uint8Array;
|
||||
(signatures: ProjPointType<Fp2>[]): ProjPointType<Fp2>;
|
||||
};
|
||||
millerLoop: (ell: [Fp2, Fp2, Fp2][], g1: [Fp, Fp]) => Fp12;
|
||||
pairing: (P: ProjPointType<Fp>, Q: ProjPointType<Fp2>, withFinalExponent?: boolean) => Fp12;
|
||||
G1: CurvePointsRes<Fp> & ReturnType<typeof htf.createHasher<Fp>>;
|
||||
G2: CurvePointsRes<Fp2> & ReturnType<typeof htf.createHasher<Fp2>>;
|
||||
Signature: SignatureCoder<Fp2>;
|
||||
params: {
|
||||
x: bigint;
|
||||
r: bigint;
|
||||
G1b: bigint;
|
||||
G2b: Fp2;
|
||||
};
|
||||
fields: {
|
||||
Fp: IField<Fp>;
|
||||
Fp2: IField<Fp2>;
|
||||
Fp6: IField<Fp6>;
|
||||
Fp12: IField<Fp12>;
|
||||
Fr: IField<bigint>;
|
||||
};
|
||||
utils: {
|
||||
randomPrivateKey: () => Uint8Array;
|
||||
calcPairingPrecomputes: (p: AffinePoint<Fp2>) => [Fp2, Fp2, Fp2][];
|
||||
};
|
||||
```
|
||||
|
||||
### abstract/hash-to-curve: Hashing strings to curve points
|
||||
|
||||
The module allows to hash arbitrary strings to elliptic curve points. Implements [hash-to-curve v16](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-16).
|
||||
|
||||
Every curve has exported `hashToCurve` and `encodeToCurve` methods. You should always prefer `hashToCurve` for security:
|
||||
|
||||
```ts
|
||||
import { hashToCurve, encodeToCurve } from '@noble/curves/secp256k1';
|
||||
import { randomBytes } from '@noble/hashes/utils';
|
||||
hashToCurve('0102abcd');
|
||||
console.log(hashToCurve(randomBytes()));
|
||||
console.log(encodeToCurve(randomBytes()));
|
||||
|
||||
import { bls12_381 } from '@noble/curves/bls12-381';
|
||||
bls12_381.G1.hashToCurve(randomBytes(), { DST: 'another' });
|
||||
bls12_381.G2.hashToCurve(randomBytes(), { DST: 'custom' });
|
||||
```
|
||||
|
||||
If you need low-level methods from spec:
|
||||
|
||||
`expand_message_xmd` [(spec)](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-11#section-5.4.1) produces a uniformly random byte string using a cryptographic hash function H that outputs b bits.
|
||||
|
||||
Hash must conform to `CHash` interface (see [weierstrass section](#abstractweierstrass-short-weierstrass-curve)).
|
||||
|
||||
```ts
|
||||
function expand_message_xmd(
|
||||
msg: Uint8Array,
|
||||
DST: Uint8Array,
|
||||
lenInBytes: number,
|
||||
H: CHash
|
||||
): Uint8Array;
|
||||
function expand_message_xof(
|
||||
msg: Uint8Array,
|
||||
DST: Uint8Array,
|
||||
lenInBytes: number,
|
||||
k: number,
|
||||
H: CHash
|
||||
): Uint8Array;
|
||||
```
|
||||
|
||||
`hash_to_field(msg, count, options)`
|
||||
[(spec)](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-11#section-5.3)
|
||||
hashes arbitrary-length byte strings to a list of one or more elements of a finite field F.
|
||||
|
||||
```ts
|
||||
/**
|
||||
* * `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;
|
||||
type Opts = {
|
||||
DST: UnicodeOrBytes;
|
||||
p: bigint;
|
||||
m: number;
|
||||
k: number;
|
||||
expand?: 'xmd' | 'xof';
|
||||
hash: CHash;
|
||||
};
|
||||
|
||||
/**
|
||||
* Hashes arbitrary-length byte strings to a list of one or more elements of a finite field F
|
||||
* 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}`, see above
|
||||
* @returns [u_0, ..., u_(count - 1)], a list of field elements.
|
||||
*/
|
||||
function hash_to_field(msg: Uint8Array, count: number, options: Opts): bigint[][];
|
||||
```
|
||||
|
||||
### abstract/poseidon: Poseidon hash
|
||||
|
||||
Implements [Poseidon](https://www.poseidon-hash.info) ZK-friendly hash.
|
||||
|
||||
There are many poseidon variants with different constants.
|
||||
We don't provide them: you should construct them manually.
|
||||
Check out [micro-starknet](https://github.com/paulmillr/micro-starknet) package for a proper example.
|
||||
|
||||
```ts
|
||||
import { poseidon } from '@noble/curves/abstract/poseidon';
|
||||
|
||||
type PoseidonOpts = {
|
||||
Fp: Field<bigint>;
|
||||
t: number;
|
||||
roundsFull: number;
|
||||
roundsPartial: number;
|
||||
sboxPower?: number;
|
||||
reversePartialPowIdx?: boolean;
|
||||
mds: bigint[][];
|
||||
roundConstants: bigint[][];
|
||||
};
|
||||
const instance = poseidon(opts: PoseidonOpts);
|
||||
```
|
||||
|
||||
### abstract/modular: Modular arithmetics utilities
|
||||
|
||||
```ts
|
||||
import * as mod from '@noble/curves/abstract/modular';
|
||||
const fp = mod.Field(2n ** 255n - 19n); // Finite field over 2^255-19
|
||||
fp.mul(591n, 932n); // multiplication
|
||||
fp.pow(481n, 11024858120n); // exponentiation
|
||||
fp.div(5n, 17n); // division: 5/17 mod 2^255-19 == 5 * invert(17)
|
||||
fp.sqrt(21n); // square root
|
||||
|
||||
// Generic non-FP utils are also available
|
||||
mod.mod(21n, 10n); // 21 mod 10 == 1n; fixed version of 21 % 10
|
||||
mod.invert(17n, 10n); // invert(17) mod 10; modular multiplicative inverse
|
||||
mod.invertBatch([1n, 2n, 4n], 21n); // => [1n, 11n, 16n] in one inversion
|
||||
```
|
||||
|
||||
#### Creating private keys from hashes
|
||||
|
||||
Suppose you have `sha256(something)` (e.g. from HMAC) and you want to make a private key from it.
|
||||
Even though p256 or secp256k1 may have 32-byte private keys,
|
||||
and sha256 output is also 32-byte, you can't just use it and reduce it modulo `CURVE.n`.
|
||||
|
||||
Doing so will make the result key [biased](https://research.kudelskisecurity.com/2020/07/28/the-definitive-guide-to-modulo-bias-and-how-to-avoid-it/).
|
||||
|
||||
To avoid the bias, we implement FIPS 186 B.4.1, which allows to take arbitrary
|
||||
byte array and produce valid scalars / private keys with bias being neglible.
|
||||
|
||||
Use [hash-to-curve](#abstracthash-to-curve-hashing-strings-to-curve-points) if you need
|
||||
hashing to **public keys**; the function in the module instead operates on **private keys**.
|
||||
|
||||
```ts
|
||||
import { p256 } from '@noble/curves/p256';
|
||||
import { sha256 } from '@noble/hashes/sha256';
|
||||
import { hkdf } from '@noble/hashes/hkdf';
|
||||
const someKey = new Uint8Array(32).fill(2); // Needs to actually be random, not .fill(2)
|
||||
const derived = hkdf(sha256, someKey, undefined, 'application', 40); // 40 bytes
|
||||
const validPrivateKey = mod.hashToPrivateScalar(derived, p256.CURVE.n);
|
||||
```
|
||||
|
||||
### abstract/utils: General utilities
|
||||
|
||||
```ts
|
||||
import * as utils from '@noble/curves/abstract/utils';
|
||||
|
||||
utils.bytesToHex(Uint8Array.from([0xde, 0xad, 0xbe, 0xef]));
|
||||
utils.hexToBytes('deadbeef');
|
||||
utils.numberToHexUnpadded(123n);
|
||||
utils.hexToNumber();
|
||||
|
||||
utils.bytesToNumberBE(Uint8Array.from([0xde, 0xad, 0xbe, 0xef]));
|
||||
utils.bytesToNumberLE(Uint8Array.from([0xde, 0xad, 0xbe, 0xef]));
|
||||
utils.numberToBytesBE(123n, 32);
|
||||
utils.numberToBytesLE(123n, 64);
|
||||
|
||||
utils.concatBytes(Uint8Array.from([0xde, 0xad]), Uint8Array.from([0xbe, 0xef]));
|
||||
utils.nLength(255n);
|
||||
utils.equalBytes(Uint8Array.from([0xde]), Uint8Array.from([0xde]));
|
||||
```
|
||||
|
||||
## Security
|
||||
|
||||
1. The library has been audited in 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](https://www.shea.io). 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).
|
||||
2. The library has been fuzzed by [Guido Vranken's cryptofuzz](https://github.com/guidovranken/cryptofuzz). You can run the fuzzer by yourself to check it.
|
||||
3. [Timing attack](https://en.wikipedia.org/wiki/Timing_attack) considerations: _JIT-compiler_ and _Garbage Collector_ make "constant time" extremely hard to achieve in a scripting language. Which means _any other JS library can't have constant-timeness_. Even statically typed Rust, a language without GC, [makes it harder to achieve constant-time](https://www.chosenplaintext.ca/open-source/rust-timing-shield/security) for some cases. If your goal is absolute security, don't use any JS lib — including bindings to native ones. Use low-level libraries & languages. Nonetheless we're targetting algorithmic constant time.
|
||||
|
||||
We consider infrastructure attacks like rogue NPM modules very important; that's why it's crucial to minimize the amount of 3rd-party dependencies & native bindings. If your app uses 500 dependencies, any dep could get hacked and you'll be downloading malware with every `npm install`. Our goal is to minimize this attack vector. As for devDependencies used by the library:
|
||||
|
||||
- `@scure` base, bip32, bip39 (used in tests), micro-bmark (benchmark), micro-should (testing) are developed by us
|
||||
and follow the same practices such as: minimal library size, auditability, signed releases
|
||||
- prettier (linter), fast-check (property-based testing),
|
||||
typescript versions are locked and rarely updated. Every update is checked with `npm-diff`.
|
||||
The packages are big, which makes it hard to audit their source code thoroughly and fully.
|
||||
- They are only used if you clone the git repo and want to add some feature to it. End-users won't use them.
|
||||
|
||||
As for key generation, we're deferring to built-in
|
||||
[crypto.getRandomValues](https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues)
|
||||
which is considered cryptographically secure (CSPRNG).
|
||||
|
||||
## Speed
|
||||
|
||||
Benchmark results on Apple M2 with node v20:
|
||||
|
||||
```
|
||||
secp256k1
|
||||
init x 68 ops/sec @ 14ms/op
|
||||
getPublicKey x 6,750 ops/sec @ 148μs/op
|
||||
sign x 5,206 ops/sec @ 192μs/op
|
||||
verify x 880 ops/sec @ 1ms/op
|
||||
getSharedSecret x 536 ops/sec @ 1ms/op
|
||||
recoverPublicKey x 852 ops/sec @ 1ms/op
|
||||
schnorr.sign x 685 ops/sec @ 1ms/op
|
||||
schnorr.verify x 908 ops/sec @ 1ms/op
|
||||
|
||||
p256
|
||||
init x 38 ops/sec @ 26ms/op
|
||||
getPublicKey x 6,530 ops/sec @ 153μs/op
|
||||
sign x 5,074 ops/sec @ 197μs/op
|
||||
verify x 626 ops/sec @ 1ms/op
|
||||
|
||||
p384
|
||||
init x 17 ops/sec @ 57ms/op
|
||||
getPublicKey x 2,883 ops/sec @ 346μs/op
|
||||
sign x 2,358 ops/sec @ 424μs/op
|
||||
verify x 245 ops/sec @ 4ms/op
|
||||
|
||||
p521
|
||||
init x 9 ops/sec @ 109ms/op
|
||||
getPublicKey x 1,516 ops/sec @ 659μs/op
|
||||
sign x 1,271 ops/sec @ 786μs/op
|
||||
verify x 123 ops/sec @ 8ms/op
|
||||
|
||||
ed25519
|
||||
init x 54 ops/sec @ 18ms/op
|
||||
getPublicKey x 10,269 ops/sec @ 97μs/op
|
||||
sign x 5,110 ops/sec @ 195μs/op
|
||||
verify x 1,049 ops/sec @ 952μs/op
|
||||
|
||||
ed448
|
||||
init x 19 ops/sec @ 51ms/op
|
||||
getPublicKey x 3,775 ops/sec @ 264μs/op
|
||||
sign x 1,771 ops/sec @ 564μs/op
|
||||
verify x 351 ops/sec @ 2ms/op
|
||||
|
||||
ecdh
|
||||
├─x25519 x 1,466 ops/sec @ 682μs/op
|
||||
├─secp256k1 x 539 ops/sec @ 1ms/op
|
||||
├─p256 x 511 ops/sec @ 1ms/op
|
||||
├─p384 x 199 ops/sec @ 5ms/op
|
||||
├─p521 x 103 ops/sec @ 9ms/op
|
||||
└─x448 x 548 ops/sec @ 1ms/op
|
||||
|
||||
bls12-381
|
||||
init x 36 ops/sec @ 27ms/op
|
||||
getPublicKey 1-bit x 973 ops/sec @ 1ms/op
|
||||
getPublicKey x 970 ops/sec @ 1ms/op
|
||||
sign x 55 ops/sec @ 17ms/op
|
||||
verify x 39 ops/sec @ 25ms/op
|
||||
pairing x 106 ops/sec @ 9ms/op
|
||||
aggregatePublicKeys/8 x 129 ops/sec @ 7ms/op
|
||||
aggregatePublicKeys/32 x 34 ops/sec @ 28ms/op
|
||||
aggregatePublicKeys/128 x 8 ops/sec @ 112ms/op
|
||||
aggregatePublicKeys/512 x 2 ops/sec @ 446ms/op
|
||||
aggregatePublicKeys/2048 x 0 ops/sec @ 1778ms/op
|
||||
aggregateSignatures/8 x 50 ops/sec @ 19ms/op
|
||||
aggregateSignatures/32 x 13 ops/sec @ 74ms/op
|
||||
aggregateSignatures/128 x 3 ops/sec @ 296ms/op
|
||||
aggregateSignatures/512 x 0 ops/sec @ 1180ms/op
|
||||
aggregateSignatures/2048 x 0 ops/sec @ 4715ms/op
|
||||
|
||||
hash-to-curve
|
||||
hash_to_field x 91,600 ops/sec @ 10μs/op
|
||||
secp256k1 x 2,373 ops/sec @ 421μs/op
|
||||
p256 x 4,310 ops/sec @ 231μs/op
|
||||
p384 x 1,664 ops/sec @ 600μs/op
|
||||
p521 x 807 ops/sec @ 1ms/op
|
||||
ed25519 x 3,088 ops/sec @ 323μs/op
|
||||
ed448 x 1,247 ops/sec @ 801μs/op
|
||||
```
|
||||
|
||||
## Contributing & testing
|
||||
|
||||
1. Clone the repository
|
||||
2. `npm install` to install build dependencies like TypeScript
|
||||
3. `npm run build` to compile TypeScript code
|
||||
4. `npm run test` will execute all main tests
|
||||
|
||||
## Upgrading
|
||||
|
||||
Previously, the library was split into single-feature packages
|
||||
noble-secp256k1, noble-ed25519 and noble-bls12-381.
|
||||
|
||||
Curves continue their original work. The single-feature packages changed their
|
||||
direction towards providing minimal 4kb implementations of cryptography,
|
||||
which means they have less features.
|
||||
|
||||
Upgrading from @noble/secp256k1 2.0 or @noble/ed25519 2.0: no changes, libraries are compatible.
|
||||
|
||||
Upgrading from [@noble/secp256k1](https://github.com/paulmillr/noble-secp256k1) 1.7:
|
||||
|
||||
- `getPublicKey`
|
||||
- now produce 33-byte compressed signatures by default
|
||||
- to use old behavior, which produced 65-byte uncompressed keys, set
|
||||
argument `isCompressed` to `false`: `getPublicKey(priv, false)`
|
||||
- `sign`
|
||||
- is now sync; use `signAsync` for async version
|
||||
- now returns `Signature` instance with `{ r, s, recovery }` properties
|
||||
- `canonical` option was renamed to `lowS`
|
||||
- `recovered` option has been removed because recovery bit is always returned now
|
||||
- `der` option has been removed. There are 2 options:
|
||||
1. Use compact encoding: `fromCompact`, `toCompactRawBytes`, `toCompactHex`.
|
||||
Compact encoding is simply a concatenation of 32-byte r and 32-byte s.
|
||||
2. If you must use DER encoding, switch to noble-curves (see above).
|
||||
- `verify`
|
||||
- `strict` option was renamed to `lowS`
|
||||
- `getSharedSecret`
|
||||
- now produce 33-byte compressed signatures by default
|
||||
- to use old behavior, which produced 65-byte uncompressed keys, set
|
||||
argument `isCompressed` to `false`: `getSharedSecret(a, b, false)`
|
||||
- `recoverPublicKey(msg, sig, rec)` was changed to `sig.recoverPublicKey(msg)`
|
||||
- `number` type for private keys have been removed: use `bigint` instead
|
||||
- `Point` (2d xy) has been changed to `ProjectivePoint` (3d xyz)
|
||||
- `utils` were split into `utils` (same api as in noble-curves) and
|
||||
`etc` (`hmacSha256Sync` and others)
|
||||
|
||||
Upgrading from [@noble/ed25519](https://github.com/paulmillr/noble-ed25519) 1.7:
|
||||
|
||||
- Methods are now sync by default
|
||||
- `bigint` is no longer allowed in `getPublicKey`, `sign`, `verify`. Reason: ed25519 is LE, can lead to bugs
|
||||
- `Point` (2d xy) has been changed to `ExtendedPoint` (xyzt)
|
||||
- `Signature` was removed: just use raw bytes or hex now
|
||||
- `utils` were split into `utils` (same api as in noble-curves) and
|
||||
`etc` (`sha512Sync` and others)
|
||||
- `getSharedSecret` was moved to `x25519` module
|
||||
- `toX25519` has been moved to `edwardsToMontgomeryPub` and `edwardsToMontgomeryPriv` methods
|
||||
|
||||
Upgrading from [@noble/bls12-381](https://github.com/paulmillr/noble-bls12-381):
|
||||
|
||||
- Methods and classes were renamed:
|
||||
- PointG1 -> G1.Point, PointG2 -> G2.Point
|
||||
- PointG2.fromSignature -> Signature.decode, PointG2.toSignature -> Signature.encode
|
||||
- Fp2 ORDER was corrected
|
||||
|
||||
## Resources
|
||||
|
||||
Useful documentation and articles about the library or its primitives:
|
||||
|
||||
- [Learning fast elliptic-curve cryptography](https://paulmillr.com/posts/noble-secp256k1-fast-ecc/)
|
||||
- [Taming the many EdDSAs](https://csrc.nist.gov/csrc/media/Presentations/2023/crclub-2023-03-08/images-media/20230308-crypto-club-slides--taming-the-many-EdDSAs.pdf)
|
||||
that describes concepts of Strong UnForgeability under Chosen Message Attacks and Strongly Binding Signatures
|
||||
- Pairings and BLS
|
||||
- [BLS signatures for busy people](https://gist.github.com/paulmillr/18b802ad219b1aee34d773d08ec26ca2)
|
||||
- [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/)
|
||||
|
||||
Online demos:
|
||||
|
||||
- [Elliptic Curve Calculator](https://paulmillr.com/noble): add / multiply points, sign messages
|
||||
- [BLS threshold signatures](https://genthresh.com)
|
||||
|
||||
Projects using noble-curves:
|
||||
|
||||
- [scure-bip32](https://github.com/paulmillr/scure-bip32) and separate [bip32](https://github.com/bitcoinjs/bip32) HDkey libraries
|
||||
- Ethereum libraries:
|
||||
- [ethereum-cryptography](https://github.com/ethereum/js-ethereum-cryptography)
|
||||
- [@ethereumjs](https://github.com/ethereumjs/ethereumjs-monorepo)
|
||||
- [micro-eth-signer](https://github.com/paulmillr/micro-eth-signer)
|
||||
- [ethers](https://github.com/ethers-io/ethers.js) (old noble-secp256k1 for now)
|
||||
- [viem.sh](https://viem.sh)
|
||||
- [metamask's eth-sig-util](https://github.com/MetaMask/eth-sig-util)
|
||||
- [gridplus lattice sdk](https://github.com/GridPlus/lattice-eth2-utils)
|
||||
- Bitcoin libraries: [scure-btc-signer](https://github.com/paulmillr/scure-btc-signer)
|
||||
- Solana libraries: [micro-sol-signer](https://github.com/paulmillr/micro-sol-signer), [solana-web3.js](https://github.com/solana-labs/solana-web3.js)
|
||||
- [polkadot.js](https://github.com/polkadot-js/common), [micro-starknet](https://github.com/paulmillr/micro-starknet)
|
||||
- [protonmail](https://github.com/ProtonMail/WebClients) (old noble-ed25519 for now)
|
||||
- [did-jwt](https://github.com/decentralized-identity/did-jwt), [hpke-js](https://github.com/dajiaji/hpke-js), [nostr-tools](https://github.com/nbd-wtf/nostr-tools)
|
||||
- [ed25519-keygen](https://github.com/paulmillr/ed25519-keygen) SSH, PGP, TOR key generation
|
||||
- [secp256k1 compatibility layer](https://github.com/ethereum/js-ethereum-cryptography/blob/2.0.0/src/secp256k1-compat.ts)
|
||||
for users who want to switch from secp256k1-node or tiny-secp256k1. Allows to see which methods map to corresponding noble code.
|
||||
- [BLS BBS signatures](https://github.com/Wind4Greg/BBS-Draft-Checks) following [draft-irtf-cfrg-bbs-signatures-latest](https://identity.foundation/bbs-signature/draft-irtf-cfrg-bbs-signatures.html)
|
||||
- [KZG trusted setup ceremony](https://github.com/dsrvlabs/czg-keremony)
|
||||
|
||||
## License
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2022 Paul Miller [(https://paulmillr.com)](https://paulmillr.com)
|
||||
|
||||
See LICENSE file.
|
||||
62
node_modules/@scure/bip32/node_modules/@noble/curves/_shortw_utils.d.ts
generated
vendored
Normal file
62
node_modules/@scure/bip32/node_modules/@noble/curves/_shortw_utils.d.ts
generated
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
import { randomBytes } from '@noble/hashes/utils';
|
||||
import { CurveType } from './abstract/weierstrass.js';
|
||||
import { CHash } from './abstract/utils.js';
|
||||
export declare function getHash(hash: CHash): {
|
||||
hash: CHash;
|
||||
hmac: (key: Uint8Array, ...msgs: Uint8Array[]) => Uint8Array;
|
||||
randomBytes: typeof randomBytes;
|
||||
};
|
||||
type CurveDef = Readonly<Omit<CurveType, 'hash' | 'hmac' | 'randomBytes'>>;
|
||||
export declare function createCurve(curveDef: CurveDef, defHash: CHash): Readonly<{
|
||||
create: (hash: CHash) => import("./abstract/weierstrass.js").CurveFn;
|
||||
CURVE: Readonly<{
|
||||
readonly nBitLength: number;
|
||||
readonly nByteLength: number;
|
||||
readonly Fp: import("./abstract/modular.js").IField<bigint>;
|
||||
readonly n: bigint;
|
||||
readonly h: bigint;
|
||||
readonly hEff?: bigint | undefined;
|
||||
readonly Gx: bigint;
|
||||
readonly Gy: bigint;
|
||||
readonly allowInfinityPoint?: boolean | undefined;
|
||||
readonly a: bigint;
|
||||
readonly b: bigint;
|
||||
readonly allowedPrivateKeyLengths?: readonly number[] | undefined;
|
||||
readonly wrapPrivateKey?: boolean | undefined;
|
||||
readonly endo?: {
|
||||
beta: bigint;
|
||||
splitScalar: (k: bigint) => {
|
||||
k1neg: boolean;
|
||||
k1: bigint;
|
||||
k2neg: boolean;
|
||||
k2: bigint;
|
||||
};
|
||||
} | undefined;
|
||||
readonly isTorsionFree?: ((c: import("./abstract/weierstrass.js").ProjConstructor<bigint>, point: import("./abstract/weierstrass.js").ProjPointType<bigint>) => boolean) | undefined;
|
||||
readonly clearCofactor?: ((c: import("./abstract/weierstrass.js").ProjConstructor<bigint>, point: import("./abstract/weierstrass.js").ProjPointType<bigint>) => import("./abstract/weierstrass.js").ProjPointType<bigint>) | undefined;
|
||||
readonly hash: CHash;
|
||||
readonly hmac: (key: Uint8Array, ...messages: Uint8Array[]) => Uint8Array;
|
||||
readonly randomBytes: (bytesLength?: number | undefined) => Uint8Array;
|
||||
lowS: boolean;
|
||||
readonly bits2int?: ((bytes: Uint8Array) => bigint) | undefined;
|
||||
readonly bits2int_modN?: ((bytes: Uint8Array) => bigint) | undefined;
|
||||
readonly p: bigint;
|
||||
}>;
|
||||
getPublicKey: (privateKey: import("./abstract/utils.js").PrivKey, isCompressed?: boolean | undefined) => Uint8Array;
|
||||
getSharedSecret: (privateA: import("./abstract/utils.js").PrivKey, publicB: import("./abstract/utils.js").Hex, isCompressed?: boolean | undefined) => Uint8Array;
|
||||
sign: (msgHash: import("./abstract/utils.js").Hex, privKey: import("./abstract/utils.js").PrivKey, opts?: import("./abstract/weierstrass.js").SignOpts | undefined) => import("./abstract/weierstrass.js").RecoveredSignatureType;
|
||||
verify: (signature: import("./abstract/utils.js").Hex | {
|
||||
r: bigint;
|
||||
s: bigint;
|
||||
}, msgHash: import("./abstract/utils.js").Hex, publicKey: import("./abstract/utils.js").Hex, opts?: import("./abstract/weierstrass.js").VerOpts | undefined) => boolean;
|
||||
ProjectivePoint: import("./abstract/weierstrass.js").ProjConstructor<bigint>;
|
||||
Signature: import("./abstract/weierstrass.js").SignatureConstructor;
|
||||
utils: {
|
||||
normPrivateKeyToScalar: (key: import("./abstract/utils.js").PrivKey) => bigint;
|
||||
isValidPrivateKey(privateKey: import("./abstract/utils.js").PrivKey): boolean;
|
||||
randomPrivateKey: () => Uint8Array;
|
||||
precompute: (windowSize?: number | undefined, point?: import("./abstract/weierstrass.js").ProjPointType<bigint> | undefined) => import("./abstract/weierstrass.js").ProjPointType<bigint>;
|
||||
};
|
||||
}>;
|
||||
export {};
|
||||
//# sourceMappingURL=_shortw_utils.d.ts.map
|
||||
1
node_modules/@scure/bip32/node_modules/@noble/curves/_shortw_utils.d.ts.map
generated
vendored
Normal file
1
node_modules/@scure/bip32/node_modules/@noble/curves/_shortw_utils.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"_shortw_utils.d.ts","sourceRoot":"","sources":["src/_shortw_utils.ts"],"names":[],"mappings":"AAEA,OAAO,EAAe,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAe,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACnE,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAG5C,wBAAgB,OAAO,CAAC,IAAI,EAAE,KAAK;;gBAGnB,UAAU,WAAW,UAAU,EAAE;;EAGhD;AAED,KAAK,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,aAAa,CAAC,CAAC,CAAC;AAC3E,wBAAgB,WAAW,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK;mBACtC,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAE5B"}
|
||||
22
node_modules/@scure/bip32/node_modules/@noble/curves/_shortw_utils.js
generated
vendored
Normal file
22
node_modules/@scure/bip32/node_modules/@noble/curves/_shortw_utils.js
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.createCurve = exports.getHash = void 0;
|
||||
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||
const hmac_1 = require("@noble/hashes/hmac");
|
||||
const utils_1 = require("@noble/hashes/utils");
|
||||
const weierstrass_js_1 = require("./abstract/weierstrass.js");
|
||||
// connects noble-curves to noble-hashes
|
||||
function getHash(hash) {
|
||||
return {
|
||||
hash,
|
||||
hmac: (key, ...msgs) => (0, hmac_1.hmac)(hash, key, (0, utils_1.concatBytes)(...msgs)),
|
||||
randomBytes: utils_1.randomBytes,
|
||||
};
|
||||
}
|
||||
exports.getHash = getHash;
|
||||
function createCurve(curveDef, defHash) {
|
||||
const create = (hash) => (0, weierstrass_js_1.weierstrass)({ ...curveDef, ...getHash(hash) });
|
||||
return Object.freeze({ ...create(defHash), create });
|
||||
}
|
||||
exports.createCurve = createCurve;
|
||||
//# sourceMappingURL=_shortw_utils.js.map
|
||||
1
node_modules/@scure/bip32/node_modules/@noble/curves/_shortw_utils.js.map
generated
vendored
Normal file
1
node_modules/@scure/bip32/node_modules/@noble/curves/_shortw_utils.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"_shortw_utils.js","sourceRoot":"","sources":["src/_shortw_utils.ts"],"names":[],"mappings":";;;AAAA,sEAAsE;AACtE,6CAA0C;AAC1C,+CAA+D;AAC/D,8DAAmE;AAGnE,wCAAwC;AACxC,SAAgB,OAAO,CAAC,IAAW;IACjC,OAAO;QACL,IAAI;QACJ,IAAI,EAAE,CAAC,GAAe,EAAE,GAAG,IAAkB,EAAE,EAAE,CAAC,IAAA,WAAI,EAAC,IAAI,EAAE,GAAG,EAAE,IAAA,mBAAW,EAAC,GAAG,IAAI,CAAC,CAAC;QACvF,WAAW,EAAX,mBAAW;KACZ,CAAC;AACJ,CAAC;AAND,0BAMC;AAGD,SAAgB,WAAW,CAAC,QAAkB,EAAE,OAAc;IAC5D,MAAM,MAAM,GAAG,CAAC,IAAW,EAAE,EAAE,CAAC,IAAA,4BAAW,EAAC,EAAE,GAAG,QAAQ,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC/E,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;AACvD,CAAC;AAHD,kCAGC"}
|
||||
103
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/bls.d.ts
generated
vendored
Normal file
103
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/bls.d.ts
generated
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||
/**
|
||||
* BLS (Barreto-Lynn-Scott) family of pairing-friendly curves.
|
||||
* Implements BLS (Boneh-Lynn-Shacham) signatures.
|
||||
* Consists of two curves: G1 and G2:
|
||||
* - G1 is a subgroup of (x, y) E(Fq) over y² = x³ + 4.
|
||||
* - G2 is a subgroup of ((x₁, x₂+i), (y₁, y₂+i)) E(Fq²) over y² = x³ + 4(1 + i) where i is √-1
|
||||
* - Gt, created by bilinear (ate) pairing e(G1, G2), consists of p-th roots of unity in
|
||||
* Fq^k where k is embedding degree. Only degree 12 is currently supported, 24 is not.
|
||||
* Pairing is used to aggregate and verify signatures.
|
||||
* We are using Fp for private keys (shorter) and Fp₂ for signatures (longer).
|
||||
* Some projects may prefer to swap this relation, it is not supported for now.
|
||||
*/
|
||||
import { AffinePoint } from './curve.js';
|
||||
import { IField } from './modular.js';
|
||||
import { Hex, PrivKey, CHash } from './utils.js';
|
||||
import * as htf from './hash-to-curve.js';
|
||||
import { CurvePointsType, ProjPointType as ProjPointType, CurvePointsRes } from './weierstrass.js';
|
||||
type Fp = bigint;
|
||||
export type SignatureCoder<Fp2> = {
|
||||
fromHex(hex: Hex): ProjPointType<Fp2>;
|
||||
toRawBytes(point: ProjPointType<Fp2>): Uint8Array;
|
||||
toHex(point: ProjPointType<Fp2>): string;
|
||||
};
|
||||
export type CurveType<Fp, Fp2, Fp6, Fp12> = {
|
||||
G1: Omit<CurvePointsType<Fp>, 'n'> & {
|
||||
mapToCurve: htf.MapToCurve<Fp>;
|
||||
htfDefaults: htf.Opts;
|
||||
};
|
||||
G2: Omit<CurvePointsType<Fp2>, 'n'> & {
|
||||
Signature: SignatureCoder<Fp2>;
|
||||
mapToCurve: htf.MapToCurve<Fp2>;
|
||||
htfDefaults: htf.Opts;
|
||||
};
|
||||
fields: {
|
||||
Fp: IField<Fp>;
|
||||
Fr: IField<bigint>;
|
||||
Fp2: IField<Fp2> & {
|
||||
reim: (num: Fp2) => {
|
||||
re: bigint;
|
||||
im: bigint;
|
||||
};
|
||||
multiplyByB: (num: Fp2) => Fp2;
|
||||
frobeniusMap(num: Fp2, power: number): Fp2;
|
||||
};
|
||||
Fp6: IField<Fp6>;
|
||||
Fp12: IField<Fp12> & {
|
||||
frobeniusMap(num: Fp12, power: number): Fp12;
|
||||
multiplyBy014(num: Fp12, o0: Fp2, o1: Fp2, o4: Fp2): Fp12;
|
||||
conjugate(num: Fp12): Fp12;
|
||||
finalExponentiate(num: Fp12): Fp12;
|
||||
};
|
||||
};
|
||||
params: {
|
||||
x: bigint;
|
||||
r: bigint;
|
||||
};
|
||||
htfDefaults: htf.Opts;
|
||||
hash: CHash;
|
||||
randomBytes: (bytesLength?: number) => Uint8Array;
|
||||
};
|
||||
export type CurveFn<Fp, Fp2, Fp6, Fp12> = {
|
||||
getPublicKey: (privateKey: PrivKey) => Uint8Array;
|
||||
sign: {
|
||||
(message: Hex, privateKey: PrivKey): Uint8Array;
|
||||
(message: ProjPointType<Fp2>, privateKey: PrivKey): ProjPointType<Fp2>;
|
||||
};
|
||||
verify: (signature: Hex | ProjPointType<Fp2>, message: Hex | ProjPointType<Fp2>, publicKey: Hex | ProjPointType<Fp>) => boolean;
|
||||
verifyBatch: (signature: Hex | ProjPointType<Fp2>, messages: (Hex | ProjPointType<Fp2>)[], publicKeys: (Hex | ProjPointType<Fp>)[]) => boolean;
|
||||
aggregatePublicKeys: {
|
||||
(publicKeys: Hex[]): Uint8Array;
|
||||
(publicKeys: ProjPointType<Fp>[]): ProjPointType<Fp>;
|
||||
};
|
||||
aggregateSignatures: {
|
||||
(signatures: Hex[]): Uint8Array;
|
||||
(signatures: ProjPointType<Fp2>[]): ProjPointType<Fp2>;
|
||||
};
|
||||
millerLoop: (ell: [Fp2, Fp2, Fp2][], g1: [Fp, Fp]) => Fp12;
|
||||
pairing: (P: ProjPointType<Fp>, Q: ProjPointType<Fp2>, withFinalExponent?: boolean) => Fp12;
|
||||
G1: CurvePointsRes<Fp> & ReturnType<typeof htf.createHasher<Fp>>;
|
||||
G2: CurvePointsRes<Fp2> & ReturnType<typeof htf.createHasher<Fp2>>;
|
||||
Signature: SignatureCoder<Fp2>;
|
||||
params: {
|
||||
x: bigint;
|
||||
r: bigint;
|
||||
G1b: bigint;
|
||||
G2b: Fp2;
|
||||
};
|
||||
fields: {
|
||||
Fp: IField<Fp>;
|
||||
Fp2: IField<Fp2>;
|
||||
Fp6: IField<Fp6>;
|
||||
Fp12: IField<Fp12>;
|
||||
Fr: IField<bigint>;
|
||||
};
|
||||
utils: {
|
||||
randomPrivateKey: () => Uint8Array;
|
||||
calcPairingPrecomputes: (p: AffinePoint<Fp2>) => [Fp2, Fp2, Fp2][];
|
||||
};
|
||||
};
|
||||
export declare function bls<Fp2, Fp6, Fp12>(CURVE: CurveType<Fp, Fp2, Fp6, Fp12>): CurveFn<Fp, Fp2, Fp6, Fp12>;
|
||||
export {};
|
||||
//# sourceMappingURL=bls.d.ts.map
|
||||
1
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/bls.d.ts.map
generated
vendored
Normal file
1
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/bls.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"bls.d.ts","sourceRoot":"","sources":["../src/abstract/bls.ts"],"names":[],"mappings":"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"}
|
||||
239
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/bls.js
generated
vendored
Normal file
239
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/bls.js
generated
vendored
Normal file
@@ -0,0 +1,239 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.bls = void 0;
|
||||
const modular_js_1 = require("./modular.js");
|
||||
const utils_js_1 = require("./utils.js");
|
||||
const htf = require("./hash-to-curve.js");
|
||||
const weierstrass_js_1 = require("./weierstrass.js");
|
||||
// prettier-ignore
|
||||
const _2n = BigInt(2), _3n = BigInt(3);
|
||||
function bls(CURVE) {
|
||||
// Fields are specific for curve, so for now we'll need to pass them with opts
|
||||
const { Fp, Fr, Fp2, Fp6, Fp12 } = CURVE.fields;
|
||||
const BLS_X_LEN = (0, utils_js_1.bitLen)(CURVE.params.x);
|
||||
const groupLen = 32; // TODO: calculate; hardcoded for now
|
||||
// Pre-compute coefficients for sparse multiplication
|
||||
// Point addition and point double calculations is reused for coefficients
|
||||
function calcPairingPrecomputes(p) {
|
||||
const { x, y } = p;
|
||||
// prettier-ignore
|
||||
const Qx = x, Qy = y, Qz = Fp2.ONE;
|
||||
// prettier-ignore
|
||||
let Rx = Qx, Ry = Qy, Rz = Qz;
|
||||
let ell_coeff = [];
|
||||
for (let i = BLS_X_LEN - 2; i >= 0; i--) {
|
||||
// Double
|
||||
let t0 = Fp2.sqr(Ry); // Ry²
|
||||
let t1 = Fp2.sqr(Rz); // Rz²
|
||||
let t2 = Fp2.multiplyByB(Fp2.mul(t1, _3n)); // 3 * T1 * B
|
||||
let t3 = Fp2.mul(t2, _3n); // 3 * T2
|
||||
let t4 = Fp2.sub(Fp2.sub(Fp2.sqr(Fp2.add(Ry, Rz)), t1), t0); // (Ry + Rz)² - T1 - T0
|
||||
ell_coeff.push([
|
||||
Fp2.sub(t2, t0),
|
||||
Fp2.mul(Fp2.sqr(Rx), _3n),
|
||||
Fp2.neg(t4), // -T4
|
||||
]);
|
||||
Rx = Fp2.div(Fp2.mul(Fp2.mul(Fp2.sub(t0, t3), Rx), Ry), _2n); // ((T0 - T3) * Rx * Ry) / 2
|
||||
Ry = Fp2.sub(Fp2.sqr(Fp2.div(Fp2.add(t0, t3), _2n)), Fp2.mul(Fp2.sqr(t2), _3n)); // ((T0 + T3) / 2)² - 3 * T2²
|
||||
Rz = Fp2.mul(t0, t4); // T0 * T4
|
||||
if ((0, utils_js_1.bitGet)(CURVE.params.x, i)) {
|
||||
// Addition
|
||||
let t0 = Fp2.sub(Ry, Fp2.mul(Qy, Rz)); // Ry - Qy * Rz
|
||||
let t1 = Fp2.sub(Rx, Fp2.mul(Qx, Rz)); // Rx - Qx * Rz
|
||||
ell_coeff.push([
|
||||
Fp2.sub(Fp2.mul(t0, Qx), Fp2.mul(t1, Qy)),
|
||||
Fp2.neg(t0),
|
||||
t1, // T1
|
||||
]);
|
||||
let t2 = Fp2.sqr(t1); // T1²
|
||||
let t3 = Fp2.mul(t2, t1); // T2 * T1
|
||||
let t4 = Fp2.mul(t2, Rx); // T2 * Rx
|
||||
let t5 = Fp2.add(Fp2.sub(t3, Fp2.mul(t4, _2n)), Fp2.mul(Fp2.sqr(t0), Rz)); // T3 - 2 * T4 + T0² * Rz
|
||||
Rx = Fp2.mul(t1, t5); // T1 * T5
|
||||
Ry = Fp2.sub(Fp2.mul(Fp2.sub(t4, t5), t0), Fp2.mul(t3, Ry)); // (T4 - T5) * T0 - T3 * Ry
|
||||
Rz = Fp2.mul(Rz, t3); // Rz * T3
|
||||
}
|
||||
}
|
||||
return ell_coeff;
|
||||
}
|
||||
function millerLoop(ell, g1) {
|
||||
const { x } = CURVE.params;
|
||||
const Px = g1[0];
|
||||
const Py = g1[1];
|
||||
let f12 = Fp12.ONE;
|
||||
for (let j = 0, i = BLS_X_LEN - 2; i >= 0; i--, j++) {
|
||||
const E = ell[j];
|
||||
f12 = Fp12.multiplyBy014(f12, E[0], Fp2.mul(E[1], Px), Fp2.mul(E[2], Py));
|
||||
if ((0, utils_js_1.bitGet)(x, i)) {
|
||||
j += 1;
|
||||
const F = ell[j];
|
||||
f12 = Fp12.multiplyBy014(f12, F[0], Fp2.mul(F[1], Px), Fp2.mul(F[2], Py));
|
||||
}
|
||||
if (i !== 0)
|
||||
f12 = Fp12.sqr(f12);
|
||||
}
|
||||
return Fp12.conjugate(f12);
|
||||
}
|
||||
const utils = {
|
||||
randomPrivateKey: () => {
|
||||
return Fr.toBytes((0, modular_js_1.hashToPrivateScalar)(CURVE.randomBytes(groupLen + 8), CURVE.params.r));
|
||||
},
|
||||
calcPairingPrecomputes,
|
||||
};
|
||||
// Point on G1 curve: (x, y)
|
||||
const G1_ = (0, weierstrass_js_1.weierstrassPoints)({ n: Fr.ORDER, ...CURVE.G1 });
|
||||
const G1 = Object.assign(G1_, htf.createHasher(G1_.ProjectivePoint, CURVE.G1.mapToCurve, {
|
||||
...CURVE.htfDefaults,
|
||||
...CURVE.G1.htfDefaults,
|
||||
}));
|
||||
function pairingPrecomputes(point) {
|
||||
const p = point;
|
||||
if (p._PPRECOMPUTES)
|
||||
return p._PPRECOMPUTES;
|
||||
p._PPRECOMPUTES = calcPairingPrecomputes(point.toAffine());
|
||||
return p._PPRECOMPUTES;
|
||||
}
|
||||
// TODO: export
|
||||
// function clearPairingPrecomputes(point: G2) {
|
||||
// const p = point as G2 & withPairingPrecomputes;
|
||||
// p._PPRECOMPUTES = undefined;
|
||||
// }
|
||||
// Point on G2 curve (complex numbers): (x₁, x₂+i), (y₁, y₂+i)
|
||||
const G2_ = (0, weierstrass_js_1.weierstrassPoints)({ n: Fr.ORDER, ...CURVE.G2 });
|
||||
const G2 = Object.assign(G2_, htf.createHasher(G2_.ProjectivePoint, CURVE.G2.mapToCurve, {
|
||||
...CURVE.htfDefaults,
|
||||
...CURVE.G2.htfDefaults,
|
||||
}));
|
||||
const { Signature } = CURVE.G2;
|
||||
// Calculates bilinear pairing
|
||||
function pairing(Q, P, withFinalExponent = true) {
|
||||
if (Q.equals(G1.ProjectivePoint.ZERO) || P.equals(G2.ProjectivePoint.ZERO))
|
||||
throw new Error('pairing is not available for ZERO point');
|
||||
Q.assertValidity();
|
||||
P.assertValidity();
|
||||
// Performance: 9ms for millerLoop and ~14ms for exp.
|
||||
const Qa = Q.toAffine();
|
||||
const looped = millerLoop(pairingPrecomputes(P), [Qa.x, Qa.y]);
|
||||
return withFinalExponent ? Fp12.finalExponentiate(looped) : looped;
|
||||
}
|
||||
function normP1(point) {
|
||||
return point instanceof G1.ProjectivePoint ? point : G1.ProjectivePoint.fromHex(point);
|
||||
}
|
||||
function normP2(point) {
|
||||
return point instanceof G2.ProjectivePoint ? point : Signature.fromHex(point);
|
||||
}
|
||||
function normP2Hash(point, htfOpts) {
|
||||
return point instanceof G2.ProjectivePoint
|
||||
? point
|
||||
: G2.hashToCurve((0, utils_js_1.ensureBytes)('point', point), htfOpts);
|
||||
}
|
||||
// Multiplies generator by private key.
|
||||
// P = pk x G
|
||||
function getPublicKey(privateKey) {
|
||||
return G1.ProjectivePoint.fromPrivateKey(privateKey).toRawBytes(true);
|
||||
}
|
||||
function sign(message, privateKey, htfOpts) {
|
||||
const msgPoint = normP2Hash(message, htfOpts);
|
||||
msgPoint.assertValidity();
|
||||
const sigPoint = msgPoint.multiply(G1.normPrivateKeyToScalar(privateKey));
|
||||
if (message instanceof G2.ProjectivePoint)
|
||||
return sigPoint;
|
||||
return Signature.toRawBytes(sigPoint);
|
||||
}
|
||||
// Checks if pairing of public key & hash is equal to pairing of generator & signature.
|
||||
// e(P, H(m)) == e(G, S)
|
||||
function verify(signature, message, publicKey, htfOpts) {
|
||||
const P = normP1(publicKey);
|
||||
const Hm = normP2Hash(message, htfOpts);
|
||||
const G = G1.ProjectivePoint.BASE;
|
||||
const S = normP2(signature);
|
||||
// Instead of doing 2 exponentiations, we use property of billinear maps
|
||||
// and do one exp after multiplying 2 points.
|
||||
const ePHm = pairing(P.negate(), Hm, false);
|
||||
const eGS = pairing(G, S, false);
|
||||
const exp = Fp12.finalExponentiate(Fp12.mul(eGS, ePHm));
|
||||
return Fp12.eql(exp, Fp12.ONE);
|
||||
}
|
||||
function aggregatePublicKeys(publicKeys) {
|
||||
if (!publicKeys.length)
|
||||
throw new Error('Expected non-empty array');
|
||||
const agg = publicKeys.map(normP1).reduce((sum, p) => sum.add(p), G1.ProjectivePoint.ZERO);
|
||||
const aggAffine = agg; //.toAffine();
|
||||
if (publicKeys[0] instanceof G1.ProjectivePoint) {
|
||||
aggAffine.assertValidity();
|
||||
return aggAffine;
|
||||
}
|
||||
// toRawBytes ensures point validity
|
||||
return aggAffine.toRawBytes(true);
|
||||
}
|
||||
function aggregateSignatures(signatures) {
|
||||
if (!signatures.length)
|
||||
throw new Error('Expected non-empty array');
|
||||
const agg = signatures.map(normP2).reduce((sum, s) => sum.add(s), G2.ProjectivePoint.ZERO);
|
||||
const aggAffine = agg; //.toAffine();
|
||||
if (signatures[0] instanceof G2.ProjectivePoint) {
|
||||
aggAffine.assertValidity();
|
||||
return aggAffine;
|
||||
}
|
||||
return Signature.toRawBytes(aggAffine);
|
||||
}
|
||||
// https://ethresear.ch/t/fast-verification-of-multiple-bls-signatures/5407
|
||||
// e(G, S) = e(G, SUM(n)(Si)) = MUL(n)(e(G, Si))
|
||||
function verifyBatch(signature, messages, publicKeys, htfOpts) {
|
||||
// @ts-ignore
|
||||
// console.log('verifyBatch', bytesToHex(signature as any), messages, publicKeys.map(bytesToHex));
|
||||
if (!messages.length)
|
||||
throw new Error('Expected non-empty messages array');
|
||||
if (publicKeys.length !== messages.length)
|
||||
throw new Error('Pubkey count should equal msg count');
|
||||
const sig = normP2(signature);
|
||||
const nMessages = messages.map((i) => normP2Hash(i, htfOpts));
|
||||
const nPublicKeys = publicKeys.map(normP1);
|
||||
try {
|
||||
const paired = [];
|
||||
for (const message of new Set(nMessages)) {
|
||||
const groupPublicKey = nMessages.reduce((groupPublicKey, subMessage, i) => subMessage === message ? groupPublicKey.add(nPublicKeys[i]) : groupPublicKey, G1.ProjectivePoint.ZERO);
|
||||
// const msg = message instanceof PointG2 ? message : await PointG2.hashToCurve(message);
|
||||
// Possible to batch pairing for same msg with different groupPublicKey here
|
||||
paired.push(pairing(groupPublicKey, message, false));
|
||||
}
|
||||
paired.push(pairing(G1.ProjectivePoint.BASE.negate(), sig, false));
|
||||
const product = paired.reduce((a, b) => Fp12.mul(a, b), Fp12.ONE);
|
||||
const exp = Fp12.finalExponentiate(product);
|
||||
return Fp12.eql(exp, Fp12.ONE);
|
||||
}
|
||||
catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
G1.ProjectivePoint.BASE._setWindowSize(4);
|
||||
return {
|
||||
getPublicKey,
|
||||
sign,
|
||||
verify,
|
||||
verifyBatch,
|
||||
aggregatePublicKeys,
|
||||
aggregateSignatures,
|
||||
millerLoop,
|
||||
pairing,
|
||||
G1,
|
||||
G2,
|
||||
Signature,
|
||||
fields: {
|
||||
Fr,
|
||||
Fp,
|
||||
Fp2,
|
||||
Fp6,
|
||||
Fp12,
|
||||
},
|
||||
params: {
|
||||
x: CURVE.params.x,
|
||||
r: CURVE.params.r,
|
||||
G1b: CURVE.G1.b,
|
||||
G2b: CURVE.G2.b,
|
||||
},
|
||||
utils,
|
||||
};
|
||||
}
|
||||
exports.bls = bls;
|
||||
//# sourceMappingURL=bls.js.map
|
||||
1
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/bls.js.map
generated
vendored
Normal file
1
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/bls.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
70
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/curve.d.ts
generated
vendored
Normal file
70
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/curve.d.ts
generated
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||
import { IField } from './modular.js';
|
||||
export type AffinePoint<T> = {
|
||||
x: T;
|
||||
y: T;
|
||||
} & {
|
||||
z?: never;
|
||||
t?: never;
|
||||
};
|
||||
export interface Group<T extends Group<T>> {
|
||||
double(): T;
|
||||
negate(): T;
|
||||
add(other: T): T;
|
||||
subtract(other: T): T;
|
||||
equals(other: T): boolean;
|
||||
multiply(scalar: bigint): T;
|
||||
}
|
||||
export type GroupConstructor<T> = {
|
||||
BASE: T;
|
||||
ZERO: T;
|
||||
};
|
||||
export type Mapper<T> = (i: T[]) => T[];
|
||||
export declare function wNAF<T extends Group<T>>(c: GroupConstructor<T>, bits: number): {
|
||||
constTimeNegate: (condition: boolean, item: T) => T;
|
||||
unsafeLadder(elm: T, n: bigint): T;
|
||||
/**
|
||||
* Creates a wNAF precomputation window. Used for caching.
|
||||
* Default window size is set by `utils.precompute()` and is equal to 8.
|
||||
* 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>[];
|
||||
/**
|
||||
* Implements ec multiplication using precomputed tables and w-ary non-adjacent form.
|
||||
* @param W window size
|
||||
* @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;
|
||||
};
|
||||
wNAFCached(P: T, precomputesMap: Map<T, T[]>, n: bigint, transform: Mapper<T>): {
|
||||
p: T;
|
||||
f: T;
|
||||
};
|
||||
};
|
||||
export type BasicCurve<T> = {
|
||||
Fp: IField<T>;
|
||||
n: bigint;
|
||||
nBitLength?: number;
|
||||
nByteLength?: number;
|
||||
h: bigint;
|
||||
hEff?: bigint;
|
||||
Gx: T;
|
||||
Gy: T;
|
||||
allowInfinityPoint?: boolean;
|
||||
};
|
||||
export declare function validateBasic<FP, T>(curve: BasicCurve<FP> & T): Readonly<{
|
||||
readonly nBitLength: number;
|
||||
readonly nByteLength: number;
|
||||
} & BasicCurve<FP> & T & {
|
||||
p: bigint;
|
||||
}>;
|
||||
//# sourceMappingURL=curve.d.ts.map
|
||||
1
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/curve.d.ts.map
generated
vendored
Normal file
1
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/curve.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"curve.d.ts","sourceRoot":"","sources":["../src/abstract/curve.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAEtE,OAAO,EAAE,MAAM,EAA0B,MAAM,cAAc,CAAC;AAK9D,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI;IAC3B,CAAC,EAAE,CAAC,CAAC;IACL,CAAC,EAAE,CAAC,CAAC;CACN,GAAG;IAAE,CAAC,CAAC,EAAE,KAAK,CAAC;IAAC,CAAC,CAAC,EAAE,KAAK,CAAA;CAAE,CAAC;AAE7B,MAAM,WAAW,KAAK,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC;IACvC,MAAM,IAAI,CAAC,CAAC;IACZ,MAAM,IAAI,CAAC,CAAC;IACZ,GAAG,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC;IACjB,QAAQ,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC;IACtB,MAAM,CAAC,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,CAAC,CAAC;CAC7B;AAED,MAAM,MAAM,gBAAgB,CAAC,CAAC,IAAI;IAChC,IAAI,EAAE,CAAC,CAAC;IACR,IAAI,EAAE,CAAC,CAAC;CACT,CAAC;AACF,MAAM,MAAM,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,EAAE,CAAC;AAaxC,wBAAgB,IAAI,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,gBAAgB,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM;iCACvC,OAAO,QAAQ,CAAC,KAAG,CAAC;sBAYpC,CAAC,KAAK,MAAM;IAW9B;;;;;;;;;OASG;0BACmB,CAAC,KAAK,MAAM,GAAG,MAAM,CAAC,CAAC,EAAE;IAkB/C;;;;;;OAMG;YACK,MAAM,eAAe,CAAC,EAAE,KAAK,MAAM;WAAQ,CAAC;WAAK,CAAC;;kBAsD5C,CAAC,kBAAkB,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,MAAM,aAAa,OAAO,CAAC,CAAC,GAAG;QAAE,CAAC,EAAE,CAAC,CAAC;QAAC,CAAC,EAAE,CAAC,CAAA;KAAE;EAcjG;AAID,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI;IAC1B,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;IACd,CAAC,EAAE,MAAM,CAAC;IACV,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,CAAC,EAAE,MAAM,CAAC;IACV,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,CAAC,CAAC;IACN,EAAE,EAAE,CAAC,CAAC;IACN,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B,CAAC;AAEF,wBAAgB,aAAa,CAAC,EAAE,EAAE,CAAC,EAAE,KAAK,EAAE,UAAU,CAAC,EAAE,CAAC,GAAG,CAAC;;;;;GAqB7D"}
|
||||
161
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/curve.js
generated
vendored
Normal file
161
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/curve.js
generated
vendored
Normal file
@@ -0,0 +1,161 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.validateBasic = exports.wNAF = void 0;
|
||||
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||
// Abelian group utilities
|
||||
const modular_js_1 = require("./modular.js");
|
||||
const utils_js_1 = require("./utils.js");
|
||||
const _0n = BigInt(0);
|
||||
const _1n = BigInt(1);
|
||||
// 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
|
||||
function wNAF(c, bits) {
|
||||
const constTimeNegate = (condition, item) => {
|
||||
const neg = item.negate();
|
||||
return condition ? neg : item;
|
||||
};
|
||||
const opts = (W) => {
|
||||
const windows = Math.ceil(bits / W) + 1; // +1, because
|
||||
const windowSize = 2 ** (W - 1); // -1 because we skip zero
|
||||
return { windows, windowSize };
|
||||
};
|
||||
return {
|
||||
constTimeNegate,
|
||||
// non-const time multiplication ladder
|
||||
unsafeLadder(elm, n) {
|
||||
let p = c.ZERO;
|
||||
let d = elm;
|
||||
while (n > _0n) {
|
||||
if (n & _1n)
|
||||
p = p.add(d);
|
||||
d = d.double();
|
||||
n >>= _1n;
|
||||
}
|
||||
return p;
|
||||
},
|
||||
/**
|
||||
* Creates a wNAF precomputation window. Used for caching.
|
||||
* Default window size is set by `utils.precompute()` and is equal to 8.
|
||||
* 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, W) {
|
||||
const { windows, windowSize } = opts(W);
|
||||
const points = [];
|
||||
let p = elm;
|
||||
let base = p;
|
||||
for (let window = 0; window < windows; window++) {
|
||||
base = p;
|
||||
points.push(base);
|
||||
// =1, because we skip zero
|
||||
for (let i = 1; i < windowSize; i++) {
|
||||
base = base.add(p);
|
||||
points.push(base);
|
||||
}
|
||||
p = base.double();
|
||||
}
|
||||
return points;
|
||||
},
|
||||
/**
|
||||
* Implements ec multiplication using precomputed tables and w-ary non-adjacent form.
|
||||
* @param W window size
|
||||
* @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, precomputes, n) {
|
||||
// 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);
|
||||
let p = c.ZERO;
|
||||
let f = c.BASE;
|
||||
const mask = BigInt(2 ** W - 1); // Create mask with W ones: 0b1111 for W=4 etc.
|
||||
const maxNumber = 2 ** W;
|
||||
const shiftBy = BigInt(W);
|
||||
for (let window = 0; window < windows; window++) {
|
||||
const offset = window * windowSize;
|
||||
// Extract W bits.
|
||||
let wbits = Number(n & mask);
|
||||
// Shift number by W bits.
|
||||
n >>= shiftBy;
|
||||
// If the bits are bigger than max size, we'll split those.
|
||||
// +224 => 256 - 32
|
||||
if (wbits > windowSize) {
|
||||
wbits -= maxNumber;
|
||||
n += _1n;
|
||||
}
|
||||
// This code was first written with assumption that 'f' and 'p' will never be infinity point:
|
||||
// since each addition is multiplied by 2 ** W, it cannot cancel each other. However,
|
||||
// there is negate now: it is possible that negated element from low value
|
||||
// would be the same as high element, which will create carry into next window.
|
||||
// It's not obvious how this can fail, but still worth investigating later.
|
||||
// Check if we're onto Zero point.
|
||||
// Add random point inside current window to f.
|
||||
const offset1 = offset;
|
||||
const offset2 = offset + Math.abs(wbits) - 1; // -1 because we skip zero
|
||||
const cond1 = window % 2 !== 0;
|
||||
const cond2 = wbits < 0;
|
||||
if (wbits === 0) {
|
||||
// The most important part for const-time getPublicKey
|
||||
f = f.add(constTimeNegate(cond1, precomputes[offset1]));
|
||||
}
|
||||
else {
|
||||
p = p.add(constTimeNegate(cond2, precomputes[offset2]));
|
||||
}
|
||||
}
|
||||
// JIT-compiler should not eliminate f here, since it will later be used in normalizeZ()
|
||||
// Even if the variable is still unused, there are some checks which will
|
||||
// throw an exception, so compiler needs to prove they won't happen, which is hard.
|
||||
// At this point there is a way to F be infinity-point even if p is not,
|
||||
// which makes it less const-time: around 1 bigint multiply.
|
||||
return { p, f };
|
||||
},
|
||||
wNAFCached(P, precomputesMap, n, transform) {
|
||||
// @ts-ignore
|
||||
const W = P._WINDOW_SIZE || 1;
|
||||
// Calculate precomputes on a first run, reuse them after
|
||||
let comp = precomputesMap.get(P);
|
||||
if (!comp) {
|
||||
comp = this.precomputeWindow(P, W);
|
||||
if (W !== 1) {
|
||||
precomputesMap.set(P, transform(comp));
|
||||
}
|
||||
}
|
||||
return this.wNAF(W, comp, n);
|
||||
},
|
||||
};
|
||||
}
|
||||
exports.wNAF = wNAF;
|
||||
function validateBasic(curve) {
|
||||
(0, modular_js_1.validateField)(curve.Fp);
|
||||
(0, utils_js_1.validateObject)(curve, {
|
||||
n: 'bigint',
|
||||
h: 'bigint',
|
||||
Gx: 'field',
|
||||
Gy: 'field',
|
||||
}, {
|
||||
nBitLength: 'isSafeInteger',
|
||||
nByteLength: 'isSafeInteger',
|
||||
});
|
||||
// Set defaults
|
||||
return Object.freeze({
|
||||
...(0, modular_js_1.nLength)(curve.n, curve.nBitLength),
|
||||
...curve,
|
||||
...{ p: curve.Fp.ORDER },
|
||||
});
|
||||
}
|
||||
exports.validateBasic = validateBasic;
|
||||
//# sourceMappingURL=curve.js.map
|
||||
1
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/curve.js.map
generated
vendored
Normal file
1
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/curve.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"curve.js","sourceRoot":"","sources":["../src/abstract/curve.ts"],"names":[],"mappings":"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"}
|
||||
89
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/edwards.d.ts
generated
vendored
Normal file
89
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/edwards.d.ts
generated
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
import * as ut from './utils.js';
|
||||
import { FHash, Hex } from './utils.js';
|
||||
import { Group, GroupConstructor, BasicCurve, AffinePoint } from './curve.js';
|
||||
export type CurveType = BasicCurve<bigint> & {
|
||||
a: bigint;
|
||||
d: bigint;
|
||||
hash: FHash;
|
||||
randomBytes: (bytesLength?: number) => Uint8Array;
|
||||
adjustScalarBytes?: (bytes: Uint8Array) => Uint8Array;
|
||||
domain?: (data: Uint8Array, ctx: Uint8Array, phflag: boolean) => Uint8Array;
|
||||
uvRatio?: (u: bigint, v: bigint) => {
|
||||
isValid: boolean;
|
||||
value: bigint;
|
||||
};
|
||||
prehash?: FHash;
|
||||
mapToCurve?: (scalar: bigint[]) => AffinePoint<bigint>;
|
||||
};
|
||||
declare function validateOpts(curve: CurveType): Readonly<{
|
||||
readonly nBitLength: number;
|
||||
readonly nByteLength: number;
|
||||
readonly Fp: import("./modular.js").IField<bigint>;
|
||||
readonly n: bigint;
|
||||
readonly h: bigint;
|
||||
readonly hEff?: bigint | undefined;
|
||||
readonly Gx: bigint;
|
||||
readonly Gy: bigint;
|
||||
readonly allowInfinityPoint?: boolean | undefined;
|
||||
readonly a: bigint;
|
||||
readonly d: bigint;
|
||||
readonly hash: ut.FHash;
|
||||
readonly randomBytes: (bytesLength?: number | undefined) => Uint8Array;
|
||||
readonly adjustScalarBytes?: ((bytes: Uint8Array) => Uint8Array) | undefined;
|
||||
readonly domain?: ((data: Uint8Array, ctx: Uint8Array, phflag: boolean) => Uint8Array) | undefined;
|
||||
readonly uvRatio?: ((u: bigint, v: bigint) => {
|
||||
isValid: boolean;
|
||||
value: bigint;
|
||||
}) | undefined;
|
||||
readonly prehash?: ut.FHash | undefined;
|
||||
readonly mapToCurve?: ((scalar: bigint[]) => AffinePoint<bigint>) | undefined;
|
||||
readonly p: bigint;
|
||||
}>;
|
||||
export interface ExtPointType extends Group<ExtPointType> {
|
||||
readonly ex: bigint;
|
||||
readonly ey: bigint;
|
||||
readonly ez: bigint;
|
||||
readonly et: bigint;
|
||||
get x(): bigint;
|
||||
get y(): bigint;
|
||||
assertValidity(): void;
|
||||
multiply(scalar: bigint): ExtPointType;
|
||||
multiplyUnsafe(scalar: bigint): ExtPointType;
|
||||
isSmallOrder(): boolean;
|
||||
isTorsionFree(): boolean;
|
||||
clearCofactor(): ExtPointType;
|
||||
toAffine(iz?: bigint): AffinePoint<bigint>;
|
||||
toRawBytes(isCompressed?: boolean): Uint8Array;
|
||||
toHex(isCompressed?: boolean): string;
|
||||
}
|
||||
export interface ExtPointConstructor extends GroupConstructor<ExtPointType> {
|
||||
new (x: bigint, y: bigint, z: bigint, t: bigint): ExtPointType;
|
||||
fromAffine(p: AffinePoint<bigint>): ExtPointType;
|
||||
fromHex(hex: Hex): ExtPointType;
|
||||
fromPrivateKey(privateKey: Hex): ExtPointType;
|
||||
}
|
||||
export type CurveFn = {
|
||||
CURVE: ReturnType<typeof validateOpts>;
|
||||
getPublicKey: (privateKey: Hex) => Uint8Array;
|
||||
sign: (message: Hex, privateKey: Hex, options?: {
|
||||
context?: Hex;
|
||||
}) => Uint8Array;
|
||||
verify: (sig: Hex, message: Hex, publicKey: Hex, options?: {
|
||||
context?: Hex;
|
||||
zip215: boolean;
|
||||
}) => boolean;
|
||||
ExtendedPoint: ExtPointConstructor;
|
||||
utils: {
|
||||
randomPrivateKey: () => Uint8Array;
|
||||
getExtendedPublicKey: (key: Hex) => {
|
||||
head: Uint8Array;
|
||||
prefix: Uint8Array;
|
||||
scalar: bigint;
|
||||
point: ExtPointType;
|
||||
pointBytes: Uint8Array;
|
||||
};
|
||||
};
|
||||
};
|
||||
export declare function twistedEdwards(curveDef: CurveType): CurveFn;
|
||||
export {};
|
||||
//# sourceMappingURL=edwards.d.ts.map
|
||||
1
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/edwards.d.ts.map
generated
vendored
Normal file
1
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/edwards.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"edwards.d.ts","sourceRoot":"","sources":["../src/abstract/edwards.ts"],"names":[],"mappings":"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"}
|
||||
429
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/edwards.js
generated
vendored
Normal file
429
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/edwards.js
generated
vendored
Normal file
@@ -0,0 +1,429 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.twistedEdwards = void 0;
|
||||
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||
// Twisted Edwards curve. The formula is: ax² + y² = 1 + dx²y²
|
||||
const modular_js_1 = require("./modular.js");
|
||||
const ut = require("./utils.js");
|
||||
const utils_js_1 = require("./utils.js");
|
||||
const curve_js_1 = require("./curve.js");
|
||||
// Be friendly to bad ECMAScript parsers by not using bigint literals
|
||||
// prettier-ignore
|
||||
const _0n = BigInt(0), _1n = BigInt(1), _2n = BigInt(2), _8n = BigInt(8);
|
||||
// verification rule is either zip215 or rfc8032 / nist186-5. Consult fromHex:
|
||||
const VERIFY_DEFAULT = { zip215: true };
|
||||
function validateOpts(curve) {
|
||||
const opts = (0, curve_js_1.validateBasic)(curve);
|
||||
ut.validateObject(curve, {
|
||||
hash: 'function',
|
||||
a: 'bigint',
|
||||
d: 'bigint',
|
||||
randomBytes: 'function',
|
||||
}, {
|
||||
adjustScalarBytes: 'function',
|
||||
domain: 'function',
|
||||
uvRatio: 'function',
|
||||
mapToCurve: 'function',
|
||||
});
|
||||
// Set defaults
|
||||
return Object.freeze({ ...opts });
|
||||
}
|
||||
// It is not generic twisted curve for now, but ed25519/ed448 generic implementation
|
||||
function twistedEdwards(curveDef) {
|
||||
const CURVE = validateOpts(curveDef);
|
||||
const { Fp, n: CURVE_ORDER, prehash: prehash, hash: cHash, randomBytes, nByteLength, h: cofactor, } = CURVE;
|
||||
const MASK = _2n << (BigInt(nByteLength * 8) - _1n);
|
||||
const modP = Fp.create; // Function overrides
|
||||
// sqrt(u/v)
|
||||
const uvRatio = CURVE.uvRatio ||
|
||||
((u, v) => {
|
||||
try {
|
||||
return { isValid: true, value: Fp.sqrt(u * Fp.inv(v)) };
|
||||
}
|
||||
catch (e) {
|
||||
return { isValid: false, value: _0n };
|
||||
}
|
||||
});
|
||||
const adjustScalarBytes = CURVE.adjustScalarBytes || ((bytes) => bytes); // NOOP
|
||||
const domain = CURVE.domain ||
|
||||
((data, ctx, phflag) => {
|
||||
if (ctx.length || phflag)
|
||||
throw new Error('Contexts/pre-hash are not supported');
|
||||
return data;
|
||||
}); // NOOP
|
||||
const inBig = (n) => typeof n === 'bigint' && _0n < n; // n in [1..]
|
||||
const inRange = (n, max) => inBig(n) && inBig(max) && n < max; // n in [1..max-1]
|
||||
const in0MaskRange = (n) => n === _0n || inRange(n, MASK); // n in [0..MASK-1]
|
||||
function assertInRange(n, max) {
|
||||
// n in [1..max-1]
|
||||
if (inRange(n, max))
|
||||
return n;
|
||||
throw new Error(`Expected valid scalar < ${max}, got ${typeof n} ${n}`);
|
||||
}
|
||||
function assertGE0(n) {
|
||||
// n in [0..CURVE_ORDER-1]
|
||||
return n === _0n ? n : assertInRange(n, CURVE_ORDER); // GE = prime subgroup, not full group
|
||||
}
|
||||
const pointPrecomputes = new Map();
|
||||
function isPoint(other) {
|
||||
if (!(other instanceof Point))
|
||||
throw new Error('ExtendedPoint expected');
|
||||
}
|
||||
// Extended Point works in extended coordinates: (x, y, z, t) ∋ (x=x/z, y=y/z, t=xy).
|
||||
// https://en.wikipedia.org/wiki/Twisted_Edwards_curve#Extended_coordinates
|
||||
class Point {
|
||||
constructor(ex, ey, ez, et) {
|
||||
this.ex = ex;
|
||||
this.ey = ey;
|
||||
this.ez = ez;
|
||||
this.et = et;
|
||||
if (!in0MaskRange(ex))
|
||||
throw new Error('x required');
|
||||
if (!in0MaskRange(ey))
|
||||
throw new Error('y required');
|
||||
if (!in0MaskRange(ez))
|
||||
throw new Error('z required');
|
||||
if (!in0MaskRange(et))
|
||||
throw new Error('t required');
|
||||
}
|
||||
get x() {
|
||||
return this.toAffine().x;
|
||||
}
|
||||
get y() {
|
||||
return this.toAffine().y;
|
||||
}
|
||||
static fromAffine(p) {
|
||||
if (p instanceof Point)
|
||||
throw new Error('extended point not allowed');
|
||||
const { x, y } = p || {};
|
||||
if (!in0MaskRange(x) || !in0MaskRange(y))
|
||||
throw new Error('invalid affine point');
|
||||
return new Point(x, y, _1n, modP(x * y));
|
||||
}
|
||||
static normalizeZ(points) {
|
||||
const toInv = Fp.invertBatch(points.map((p) => p.ez));
|
||||
return points.map((p, i) => p.toAffine(toInv[i])).map(Point.fromAffine);
|
||||
}
|
||||
// "Private method", don't use it directly
|
||||
_setWindowSize(windowSize) {
|
||||
this._WINDOW_SIZE = windowSize;
|
||||
pointPrecomputes.delete(this);
|
||||
}
|
||||
// Not required for fromHex(), which always creates valid points.
|
||||
// Could be useful for fromAffine().
|
||||
assertValidity() {
|
||||
const { a, d } = CURVE;
|
||||
if (this.is0())
|
||||
throw new Error('bad point: ZERO'); // TODO: optimize, with vars below?
|
||||
// Equation in affine coordinates: ax² + y² = 1 + dx²y²
|
||||
// Equation in projective coordinates (X/Z, Y/Z, Z): (aX² + Y²)Z² = Z⁴ + dX²Y²
|
||||
const { ex: X, ey: Y, ez: Z, et: T } = this;
|
||||
const X2 = modP(X * X); // X²
|
||||
const Y2 = modP(Y * Y); // Y²
|
||||
const Z2 = modP(Z * Z); // Z²
|
||||
const Z4 = modP(Z2 * Z2); // Z⁴
|
||||
const aX2 = modP(X2 * a); // aX²
|
||||
const left = modP(Z2 * modP(aX2 + Y2)); // (aX² + Y²)Z²
|
||||
const right = modP(Z4 + modP(d * modP(X2 * Y2))); // Z⁴ + dX²Y²
|
||||
if (left !== right)
|
||||
throw new Error('bad point: equation left != right (1)');
|
||||
// In Extended coordinates we also have T, which is x*y=T/Z: check X*Y == Z*T
|
||||
const XY = modP(X * Y);
|
||||
const ZT = modP(Z * T);
|
||||
if (XY !== ZT)
|
||||
throw new Error('bad point: equation left != right (2)');
|
||||
}
|
||||
// Compare one point to another.
|
||||
equals(other) {
|
||||
isPoint(other);
|
||||
const { ex: X1, ey: Y1, ez: Z1 } = this;
|
||||
const { ex: X2, ey: Y2, ez: Z2 } = other;
|
||||
const X1Z2 = modP(X1 * Z2);
|
||||
const X2Z1 = modP(X2 * Z1);
|
||||
const Y1Z2 = modP(Y1 * Z2);
|
||||
const Y2Z1 = modP(Y2 * Z1);
|
||||
return X1Z2 === X2Z1 && Y1Z2 === Y2Z1;
|
||||
}
|
||||
is0() {
|
||||
return this.equals(Point.ZERO);
|
||||
}
|
||||
negate() {
|
||||
// Flips point sign to a negative one (-x, y in affine coords)
|
||||
return new Point(modP(-this.ex), this.ey, this.ez, modP(-this.et));
|
||||
}
|
||||
// Fast algo for doubling Extended Point.
|
||||
// https://hyperelliptic.org/EFD/g1p/auto-twisted-extended.html#doubling-dbl-2008-hwcd
|
||||
// Cost: 4M + 4S + 1*a + 6add + 1*2.
|
||||
double() {
|
||||
const { a } = CURVE;
|
||||
const { ex: X1, ey: Y1, ez: Z1 } = this;
|
||||
const A = modP(X1 * X1); // A = X12
|
||||
const B = modP(Y1 * Y1); // B = Y12
|
||||
const C = modP(_2n * modP(Z1 * Z1)); // C = 2*Z12
|
||||
const D = modP(a * A); // D = a*A
|
||||
const x1y1 = X1 + Y1;
|
||||
const E = modP(modP(x1y1 * x1y1) - A - B); // E = (X1+Y1)2-A-B
|
||||
const G = D + B; // G = D+B
|
||||
const F = G - C; // F = G-C
|
||||
const H = D - B; // H = D-B
|
||||
const X3 = modP(E * F); // X3 = E*F
|
||||
const Y3 = modP(G * H); // Y3 = G*H
|
||||
const T3 = modP(E * H); // T3 = E*H
|
||||
const Z3 = modP(F * G); // Z3 = F*G
|
||||
return new Point(X3, Y3, Z3, T3);
|
||||
}
|
||||
// Fast algo for adding 2 Extended Points.
|
||||
// https://hyperelliptic.org/EFD/g1p/auto-twisted-extended.html#addition-add-2008-hwcd
|
||||
// Cost: 9M + 1*a + 1*d + 7add.
|
||||
add(other) {
|
||||
isPoint(other);
|
||||
const { a, d } = CURVE;
|
||||
const { ex: X1, ey: Y1, ez: Z1, et: T1 } = this;
|
||||
const { ex: X2, ey: Y2, ez: Z2, et: T2 } = other;
|
||||
// Faster algo for adding 2 Extended Points when curve's a=-1.
|
||||
// http://hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html#addition-add-2008-hwcd-4
|
||||
// Cost: 8M + 8add + 2*2.
|
||||
// Note: It does not check whether the `other` point is valid.
|
||||
if (a === BigInt(-1)) {
|
||||
const A = modP((Y1 - X1) * (Y2 + X2));
|
||||
const B = modP((Y1 + X1) * (Y2 - X2));
|
||||
const F = modP(B - A);
|
||||
if (F === _0n)
|
||||
return this.double(); // Same point. Tests say it doesn't affect timing
|
||||
const C = modP(Z1 * _2n * T2);
|
||||
const D = modP(T1 * _2n * Z2);
|
||||
const E = D + C;
|
||||
const G = B + A;
|
||||
const H = D - C;
|
||||
const X3 = modP(E * F);
|
||||
const Y3 = modP(G * H);
|
||||
const T3 = modP(E * H);
|
||||
const Z3 = modP(F * G);
|
||||
return new Point(X3, Y3, Z3, T3);
|
||||
}
|
||||
const A = modP(X1 * X2); // A = X1*X2
|
||||
const B = modP(Y1 * Y2); // B = Y1*Y2
|
||||
const C = modP(T1 * d * T2); // C = T1*d*T2
|
||||
const D = modP(Z1 * Z2); // D = Z1*Z2
|
||||
const E = modP((X1 + Y1) * (X2 + Y2) - A - B); // E = (X1+Y1)*(X2+Y2)-A-B
|
||||
const F = D - C; // F = D-C
|
||||
const G = D + C; // G = D+C
|
||||
const H = modP(B - a * A); // H = B-a*A
|
||||
const X3 = modP(E * F); // X3 = E*F
|
||||
const Y3 = modP(G * H); // Y3 = G*H
|
||||
const T3 = modP(E * H); // T3 = E*H
|
||||
const Z3 = modP(F * G); // Z3 = F*G
|
||||
return new Point(X3, Y3, Z3, T3);
|
||||
}
|
||||
subtract(other) {
|
||||
return this.add(other.negate());
|
||||
}
|
||||
wNAF(n) {
|
||||
return wnaf.wNAFCached(this, pointPrecomputes, n, Point.normalizeZ);
|
||||
}
|
||||
// Constant-time multiplication.
|
||||
multiply(scalar) {
|
||||
const { p, f } = this.wNAF(assertInRange(scalar, CURVE_ORDER));
|
||||
return Point.normalizeZ([p, f])[0];
|
||||
}
|
||||
// Non-constant-time multiplication. Uses double-and-add algorithm.
|
||||
// It's faster, but should only be used when you don't care about
|
||||
// an exposed private key e.g. sig verification.
|
||||
// Does NOT allow scalars higher than CURVE.n.
|
||||
multiplyUnsafe(scalar) {
|
||||
let n = assertGE0(scalar); // 0 <= scalar < CURVE.n
|
||||
if (n === _0n)
|
||||
return I;
|
||||
if (this.equals(I) || n === _1n)
|
||||
return this;
|
||||
if (this.equals(G))
|
||||
return this.wNAF(n).p;
|
||||
return wnaf.unsafeLadder(this, n);
|
||||
}
|
||||
// Checks if point is of small order.
|
||||
// If you add something to small order point, you will have "dirty"
|
||||
// point with torsion component.
|
||||
// Multiplies point by cofactor and checks if the result is 0.
|
||||
isSmallOrder() {
|
||||
return this.multiplyUnsafe(cofactor).is0();
|
||||
}
|
||||
// Multiplies point by curve order and checks if the result is 0.
|
||||
// Returns `false` is the point is dirty.
|
||||
isTorsionFree() {
|
||||
return wnaf.unsafeLadder(this, CURVE_ORDER).is0();
|
||||
}
|
||||
// Converts Extended point to default (x, y) coordinates.
|
||||
// Can accept precomputed Z^-1 - for example, from invertBatch.
|
||||
toAffine(iz) {
|
||||
const { ex: x, ey: y, ez: z } = this;
|
||||
const is0 = this.is0();
|
||||
if (iz == null)
|
||||
iz = is0 ? _8n : Fp.inv(z); // 8 was chosen arbitrarily
|
||||
const ax = modP(x * iz);
|
||||
const ay = modP(y * iz);
|
||||
const zz = modP(z * iz);
|
||||
if (is0)
|
||||
return { x: _0n, y: _1n };
|
||||
if (zz !== _1n)
|
||||
throw new Error('invZ was invalid');
|
||||
return { x: ax, y: ay };
|
||||
}
|
||||
clearCofactor() {
|
||||
const { h: cofactor } = CURVE;
|
||||
if (cofactor === _1n)
|
||||
return this;
|
||||
return this.multiplyUnsafe(cofactor);
|
||||
}
|
||||
// Converts hash string or Uint8Array to Point.
|
||||
// Uses algo from RFC8032 5.1.3.
|
||||
static fromHex(hex, zip215 = false) {
|
||||
const { d, a } = CURVE;
|
||||
const len = Fp.BYTES;
|
||||
hex = (0, utils_js_1.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
|
||||
const y = ut.bytesToNumberLE(normed);
|
||||
if (y === _0n) {
|
||||
// y=0 is allowed
|
||||
}
|
||||
else {
|
||||
// RFC8032 prohibits >= p, but ZIP215 doesn't
|
||||
if (zip215)
|
||||
assertInRange(y, MASK); // zip215=true [1..P-1] (2^255-19-1 for ed25519)
|
||||
else
|
||||
assertInRange(y, Fp.ORDER); // zip215=false [1..MASK-1] (2^256-1 for ed25519)
|
||||
}
|
||||
// Ed25519: x² = (y²-1)/(dy²+1) mod p. Ed448: x² = (y²-1)/(dy²-1) mod p. Generic case:
|
||||
// ax²+y²=1+dx²y² => y²-1=dx²y²-ax² => y²-1=x²(dy²-a) => x²=(y²-1)/(dy²-a)
|
||||
const y2 = modP(y * y); // denominator is always non-0 mod p.
|
||||
const u = modP(y2 - _1n); // u = y² - 1
|
||||
const v = modP(d * y2 - a); // v = d y² + 1.
|
||||
let { isValid, value: x } = uvRatio(u, v); // √(u/v)
|
||||
if (!isValid)
|
||||
throw new Error('Point.fromHex: invalid y coordinate');
|
||||
const isXOdd = (x & _1n) === _1n; // There are 2 square roots. Use x_0 bit to select proper
|
||||
const isLastByteOdd = (lastByte & 0x80) !== 0; // x_0, last bit
|
||||
if (!zip215 && x === _0n && isLastByteOdd)
|
||||
// if x=0 and x_0 = 1, fail
|
||||
throw new Error('Point.fromHex: x=0 and x_0=1');
|
||||
if (isLastByteOdd !== isXOdd)
|
||||
x = modP(-x); // if x_0 != x mod 2, set x = p-x
|
||||
return Point.fromAffine({ x, y });
|
||||
}
|
||||
static fromPrivateKey(privKey) {
|
||||
return getExtendedPublicKey(privKey).point;
|
||||
}
|
||||
toRawBytes() {
|
||||
const { x, y } = this.toAffine();
|
||||
const bytes = ut.numberToBytesLE(y, Fp.BYTES); // each y has 2 x values (x, -y)
|
||||
bytes[bytes.length - 1] |= x & _1n ? 0x80 : 0; // when compressing, it's enough to store y
|
||||
return bytes; // and use the last byte to encode sign of x
|
||||
}
|
||||
toHex() {
|
||||
return ut.bytesToHex(this.toRawBytes()); // Same as toRawBytes, but returns string.
|
||||
}
|
||||
}
|
||||
Point.BASE = new Point(CURVE.Gx, CURVE.Gy, _1n, modP(CURVE.Gx * CURVE.Gy));
|
||||
Point.ZERO = new Point(_0n, _1n, _1n, _0n); // 0, 1, 1, 0
|
||||
const { BASE: G, ZERO: I } = Point;
|
||||
const wnaf = (0, curve_js_1.wNAF)(Point, nByteLength * 8);
|
||||
function modN(a) {
|
||||
return (0, modular_js_1.mod)(a, CURVE_ORDER);
|
||||
}
|
||||
// Little-endian SHA512 with modulo n
|
||||
function modN_LE(hash) {
|
||||
return modN(ut.bytesToNumberLE(hash));
|
||||
}
|
||||
/** Convenience method that creates public key and other stuff. RFC8032 5.1.5 */
|
||||
function getExtendedPublicKey(key) {
|
||||
const len = nByteLength;
|
||||
key = (0, utils_js_1.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 = (0, utils_js_1.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
|
||||
const point = G.multiply(scalar); // Point on Edwards curve aka public key
|
||||
const pointBytes = point.toRawBytes(); // Uint8Array representation
|
||||
return { head, prefix, scalar, point, pointBytes };
|
||||
}
|
||||
// Calculates EdDSA pub key. RFC8032 5.1.5. Privkey is hashed. Use first half with 3 bits cleared
|
||||
function getPublicKey(privKey) {
|
||||
return getExtendedPublicKey(privKey).pointBytes;
|
||||
}
|
||||
// int('LE', SHA512(dom2(F, C) || msgs)) mod N
|
||||
function hashDomainToScalar(context = new Uint8Array(), ...msgs) {
|
||||
const msg = ut.concatBytes(...msgs);
|
||||
return modN_LE(cHash(domain(msg, (0, utils_js_1.ensureBytes)('context', context), !!prehash)));
|
||||
}
|
||||
/** Signs message with privateKey. RFC8032 5.1.6 */
|
||||
function sign(msg, privKey, options = {}) {
|
||||
msg = (0, utils_js_1.ensureBytes)('message', msg);
|
||||
if (prehash)
|
||||
msg = prehash(msg); // for ed25519ph etc.
|
||||
const { prefix, scalar, pointBytes } = getExtendedPublicKey(privKey);
|
||||
const r = hashDomainToScalar(options.context, prefix, msg); // r = dom2(F, C) || prefix || PH(M)
|
||||
const R = G.multiply(r).toRawBytes(); // R = rG
|
||||
const k = hashDomainToScalar(options.context, R, pointBytes, msg); // R || A || PH(M)
|
||||
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 (0, utils_js_1.ensureBytes)('result', res, nByteLength * 2); // 64-byte signature
|
||||
}
|
||||
const verifyOpts = VERIFY_DEFAULT;
|
||||
function verify(sig, msg, publicKey, options = verifyOpts) {
|
||||
const { context, zip215 } = options;
|
||||
const len = Fp.BYTES; // Verifies EdDSA signature against message and public key. RFC8032 5.1.7.
|
||||
sig = (0, utils_js_1.ensureBytes)('signature', sig, 2 * len); // An extended group equation is checked.
|
||||
msg = (0, utils_js_1.ensureBytes)('message', msg);
|
||||
if (prehash)
|
||||
msg = prehash(msg); // for ed25519ph, etc
|
||||
const s = ut.bytesToNumberLE(sig.slice(len, 2 * len));
|
||||
// zip215: true is good for consensus-critical apps and allows points < 2^256
|
||||
// zip215: false follows RFC8032 / NIST186-5 and restricts points to CURVE.p
|
||||
let A, R, SB;
|
||||
try {
|
||||
A = Point.fromHex(publicKey, zip215);
|
||||
R = Point.fromHex(sig.slice(0, len), zip215);
|
||||
SB = G.multiplyUnsafe(s); // 0 <= s < l is done inside
|
||||
}
|
||||
catch (error) {
|
||||
return false;
|
||||
}
|
||||
if (!zip215 && A.isSmallOrder())
|
||||
return false;
|
||||
const k = hashDomainToScalar(context, R.toRawBytes(), A.toRawBytes(), msg);
|
||||
const RkA = R.add(A.multiplyUnsafe(k));
|
||||
// [8][S]B = [8]R + [8][k]A'
|
||||
return RkA.subtract(SB).clearCofactor().equals(Point.ZERO);
|
||||
}
|
||||
G._setWindowSize(8); // Enable precomputes. Slows down first publicKey computation by 20ms.
|
||||
const utils = {
|
||||
getExtendedPublicKey,
|
||||
// ed25519 private keys are uniform 32b. No need to check for modulo bias, like in secp256k1.
|
||||
randomPrivateKey: () => randomBytes(Fp.BYTES),
|
||||
/**
|
||||
* We're doing scalar multiplication (used in getPublicKey etc) with precomputed BASE_POINT
|
||||
* values. This slows down first getPublicKey() by milliseconds (see Speed section),
|
||||
* but allows to speed-up subsequent getPublicKey() calls up to 20x.
|
||||
* @param windowSize 2, 4, 8, 16
|
||||
*/
|
||||
precompute(windowSize = 8, point = Point.BASE) {
|
||||
point._setWindowSize(windowSize);
|
||||
point.multiply(BigInt(3));
|
||||
return point;
|
||||
},
|
||||
};
|
||||
return {
|
||||
CURVE,
|
||||
getPublicKey,
|
||||
sign,
|
||||
verify,
|
||||
ExtendedPoint: Point,
|
||||
utils,
|
||||
};
|
||||
}
|
||||
exports.twistedEdwards = twistedEdwards;
|
||||
//# sourceMappingURL=edwards.js.map
|
||||
1
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/edwards.js.map
generated
vendored
Normal file
1
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/edwards.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
57
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/hash-to-curve.d.ts
generated
vendored
Normal file
57
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/hash-to-curve.d.ts
generated
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||
import type { Group, GroupConstructor, AffinePoint } from './curve.js';
|
||||
import { IField } from './modular.js';
|
||||
import { CHash } 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: UnicodeOrBytes;
|
||||
p: bigint;
|
||||
m: number;
|
||||
k: number;
|
||||
expand: 'xmd' | 'xof';
|
||||
hash: CHash;
|
||||
};
|
||||
export declare function expand_message_xmd(msg: Uint8Array, DST: Uint8Array, lenInBytes: number, H: CHash): Uint8Array;
|
||||
export declare function expand_message_xof(msg: Uint8Array, DST: Uint8Array, lenInBytes: number, k: number, H: CHash): Uint8Array;
|
||||
/**
|
||||
* Hashes arbitrary-length byte strings to a list of one or more elements of a finite field F
|
||||
* 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}`, see above
|
||||
* @returns [u_0, ..., u_(count - 1)], a list of field elements.
|
||||
*/
|
||||
export declare function hash_to_field(msg: Uint8Array, count: number, options: Opts): bigint[][];
|
||||
export declare function isogenyMap<T, F extends IField<T>>(field: F, map: [T[], T[], T[], T[]]): (x: T, y: T) => {
|
||||
x: T;
|
||||
y: T;
|
||||
};
|
||||
export interface H2CPoint<T> extends Group<H2CPoint<T>> {
|
||||
add(rhs: H2CPoint<T>): H2CPoint<T>;
|
||||
toAffine(iz?: bigint): AffinePoint<T>;
|
||||
clearCofactor(): H2CPoint<T>;
|
||||
assertValidity(): void;
|
||||
}
|
||||
export interface H2CPointConstructor<T> extends GroupConstructor<H2CPoint<T>> {
|
||||
fromAffine(ap: AffinePoint<T>): H2CPoint<T>;
|
||||
}
|
||||
export type MapToCurve<T> = (scalar: bigint[]) => AffinePoint<T>;
|
||||
export type htfBasicOpts = {
|
||||
DST: UnicodeOrBytes;
|
||||
};
|
||||
export declare function createHasher<T>(Point: H2CPointConstructor<T>, mapToCurve: MapToCurve<T>, def: Opts & {
|
||||
encodeDST?: UnicodeOrBytes;
|
||||
}): {
|
||||
hashToCurve(msg: Uint8Array, options?: htfBasicOpts): H2CPoint<T>;
|
||||
encodeToCurve(msg: Uint8Array, options?: htfBasicOpts): H2CPoint<T>;
|
||||
};
|
||||
export {};
|
||||
//# sourceMappingURL=hash-to-curve.d.ts.map
|
||||
1
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/hash-to-curve.d.ts.map
generated
vendored
Normal file
1
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/hash-to-curve.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"hash-to-curve.d.ts","sourceRoot":"","sources":["../src/abstract/hash-to-curve.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,OAAO,KAAK,EAAE,KAAK,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACvE,OAAO,EAAO,MAAM,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAmB,KAAK,EAA4C,MAAM,YAAY,CAAC;AAE9F;;;;;;;GAOG;AACH,KAAK,cAAc,GAAG,MAAM,GAAG,UAAU,CAAC;AAC1C,MAAM,MAAM,IAAI,GAAG;IACjB,GAAG,EAAE,cAAc,CAAC;IACpB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,MAAM,EAAE,KAAK,GAAG,KAAK,CAAC;IACtB,IAAI,EAAE,KAAK,CAAC;CACb,CAAC;AAyCF,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,UAAU,EACf,GAAG,EAAE,UAAU,EACf,UAAU,EAAE,MAAM,EAClB,CAAC,EAAE,KAAK,GACP,UAAU,CAqBZ;AAED,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,UAAU,EACf,GAAG,EAAE,UAAU,EACf,UAAU,EAAE,MAAM,EAClB,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,KAAK,GACP,UAAU,CAqBZ;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,GAAG,MAAM,EAAE,EAAE,CAqCvF;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,OAGzE,CAAC,KAAK,CAAC;;;EAQnB;AAED,MAAM,WAAW,QAAQ,CAAC,CAAC,CAAE,SAAQ,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IACrD,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IACnC,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;IACtC,aAAa,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAC;IAC7B,cAAc,IAAI,IAAI,CAAC;CACxB;AAED,MAAM,WAAW,mBAAmB,CAAC,CAAC,CAAE,SAAQ,gBAAgB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAC3E,UAAU,CAAC,EAAE,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;CAC7C;AAED,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,WAAW,CAAC,CAAC,CAAC,CAAC;AAIjE,MAAM,MAAM,YAAY,GAAG;IAAE,GAAG,EAAE,cAAc,CAAA;CAAE,CAAC;AAEnD,wBAAgB,YAAY,CAAC,CAAC,EAC5B,KAAK,EAAE,mBAAmB,CAAC,CAAC,CAAC,EAC7B,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,EACzB,GAAG,EAAE,IAAI,GAAG;IAAE,SAAS,CAAC,EAAE,cAAc,CAAA;CAAE;qBAMvB,UAAU,YAAY,YAAY;uBAUhC,UAAU,YAAY,YAAY;EAOxD"}
|
||||
175
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/hash-to-curve.js
generated
vendored
Normal file
175
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/hash-to-curve.js
generated
vendored
Normal file
@@ -0,0 +1,175 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.createHasher = exports.isogenyMap = exports.hash_to_field = exports.expand_message_xof = exports.expand_message_xmd = void 0;
|
||||
const modular_js_1 = require("./modular.js");
|
||||
const utils_js_1 = require("./utils.js");
|
||||
function validateDST(dst) {
|
||||
if (dst instanceof Uint8Array)
|
||||
return dst;
|
||||
if (typeof dst === 'string')
|
||||
return (0, utils_js_1.utf8ToBytes)(dst);
|
||||
throw new Error('DST must be Uint8Array or string');
|
||||
}
|
||||
// Octet Stream to Integer. "spec" implementation of os2ip is 2.5x slower vs bytesToNumberBE.
|
||||
const os2ip = utils_js_1.bytesToNumberBE;
|
||||
// Integer to Octet Stream (numberToBytesBE)
|
||||
function i2osp(value, length) {
|
||||
if (value < 0 || value >= 1 << (8 * length)) {
|
||||
throw new Error(`bad I2OSP call: value=${value} length=${length}`);
|
||||
}
|
||||
const res = Array.from({ length }).fill(0);
|
||||
for (let i = length - 1; i >= 0; i--) {
|
||||
res[i] = value & 0xff;
|
||||
value >>>= 8;
|
||||
}
|
||||
return new Uint8Array(res);
|
||||
}
|
||||
function strxor(a, b) {
|
||||
const arr = new Uint8Array(a.length);
|
||||
for (let i = 0; i < a.length; i++) {
|
||||
arr[i] = a[i] ^ b[i];
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
function isBytes(item) {
|
||||
if (!(item instanceof Uint8Array))
|
||||
throw new Error('Uint8Array expected');
|
||||
}
|
||||
function isNum(item) {
|
||||
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
|
||||
function expand_message_xmd(msg, DST, lenInBytes, H) {
|
||||
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((0, utils_js_1.concatBytes)((0, utils_js_1.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 = (0, utils_js_1.concatBytes)(DST, i2osp(DST.length, 1));
|
||||
const Z_pad = i2osp(0, r_in_bytes);
|
||||
const l_i_b_str = i2osp(lenInBytes, 2); // len_in_bytes_str
|
||||
const b = new Array(ell);
|
||||
const b_0 = H((0, utils_js_1.concatBytes)(Z_pad, msg, l_i_b_str, i2osp(0, 1), DST_prime));
|
||||
b[0] = H((0, utils_js_1.concatBytes)(b_0, i2osp(1, 1), DST_prime));
|
||||
for (let i = 1; i <= ell; i++) {
|
||||
const args = [strxor(b_0, b[i - 1]), i2osp(i + 1, 1), DST_prime];
|
||||
b[i] = H((0, utils_js_1.concatBytes)(...args));
|
||||
}
|
||||
const pseudo_random_bytes = (0, utils_js_1.concatBytes)(...b);
|
||||
return pseudo_random_bytes.slice(0, lenInBytes);
|
||||
}
|
||||
exports.expand_message_xmd = expand_message_xmd;
|
||||
function expand_message_xof(msg, DST, lenInBytes, k, H) {
|
||||
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((0, utils_js_1.utf8ToBytes)('H2C-OVERSIZE-DST-')).update(DST).digest();
|
||||
}
|
||||
if (lenInBytes > 65535 || DST.length > 255)
|
||||
throw new Error('expand_message_xof: invalid lenInBytes');
|
||||
return (H.create({ dkLen: lenInBytes })
|
||||
.update(msg)
|
||||
.update(i2osp(lenInBytes, 2))
|
||||
// 2. DST_prime = DST || I2OSP(len(DST), 1)
|
||||
.update(DST)
|
||||
.update(i2osp(DST.length, 1))
|
||||
.digest());
|
||||
}
|
||||
exports.expand_message_xof = expand_message_xof;
|
||||
/**
|
||||
* Hashes arbitrary-length byte strings to a list of one or more elements of a finite field F
|
||||
* 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}`, see above
|
||||
* @returns [u_0, ..., u_(count - 1)], a list of field elements.
|
||||
*/
|
||||
function hash_to_field(msg, count, options) {
|
||||
(0, utils_js_1.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 === '_internal_pass') {
|
||||
// for internal tests only
|
||||
prb = msg;
|
||||
}
|
||||
else {
|
||||
throw new Error('expand must be "xmd" or "xof"');
|
||||
}
|
||||
const u = new Array(count);
|
||||
for (let i = 0; i < count; i++) {
|
||||
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] = (0, modular_js_1.mod)(os2ip(tv), p);
|
||||
}
|
||||
u[i] = e;
|
||||
}
|
||||
return u;
|
||||
}
|
||||
exports.hash_to_field = hash_to_field;
|
||||
function isogenyMap(field, map) {
|
||||
// Make same order as in spec
|
||||
const COEFF = map.map((i) => Array.from(i).reverse());
|
||||
return (x, y) => {
|
||||
const [xNum, xDen, yNum, yDen] = COEFF.map((val) => val.reduce((acc, i) => field.add(field.mul(acc, x), i)));
|
||||
x = field.div(xNum, xDen); // xNum / xDen
|
||||
y = field.mul(y, field.div(yNum, yDen)); // y * (yNum / yDev)
|
||||
return { x, y };
|
||||
};
|
||||
}
|
||||
exports.isogenyMap = isogenyMap;
|
||||
function createHasher(Point, mapToCurve, def) {
|
||||
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-16#section-3
|
||||
hashToCurve(msg, options) {
|
||||
const u = hash_to_field(msg, 2, { ...def, DST: def.DST, ...options });
|
||||
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, options) {
|
||||
const u = hash_to_field(msg, 1, { ...def, DST: def.encodeDST, ...options });
|
||||
const P = Point.fromAffine(mapToCurve(u[0])).clearCofactor();
|
||||
P.assertValidity();
|
||||
return P;
|
||||
},
|
||||
};
|
||||
}
|
||||
exports.createHasher = createHasher;
|
||||
//# sourceMappingURL=hash-to-curve.js.map
|
||||
1
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/hash-to-curve.js.map
generated
vendored
Normal file
1
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/hash-to-curve.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
83
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/modular.d.ts
generated
vendored
Normal file
83
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/modular.d.ts
generated
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
export declare function mod(a: bigint, b: bigint): bigint;
|
||||
/**
|
||||
* Efficiently raise num to power and do modular division.
|
||||
* Unsafe in some contexts: uses ladder, so can expose bigint bits.
|
||||
* @example
|
||||
* pow(2n, 6n, 11n) // 64n % 11n == 9n
|
||||
*/
|
||||
export declare function pow(num: bigint, power: bigint, modulo: bigint): bigint;
|
||||
export declare function pow2(x: bigint, power: bigint, modulo: bigint): bigint;
|
||||
export declare function invert(number: bigint, modulo: bigint): bigint;
|
||||
export declare function tonelliShanks(P: bigint): <T>(Fp: IField<T>, n: T) => T;
|
||||
export declare function FpSqrt(P: bigint): <T>(Fp: IField<T>, n: T) => T;
|
||||
export declare const isNegativeLE: (num: bigint, modulo: bigint) => boolean;
|
||||
export interface IField<T> {
|
||||
ORDER: bigint;
|
||||
BYTES: number;
|
||||
BITS: number;
|
||||
MASK: bigint;
|
||||
ZERO: T;
|
||||
ONE: T;
|
||||
create: (num: T) => T;
|
||||
isValid: (num: T) => boolean;
|
||||
is0: (num: T) => boolean;
|
||||
neg(num: T): T;
|
||||
inv(num: T): T;
|
||||
sqrt(num: T): T;
|
||||
sqr(num: T): T;
|
||||
eql(lhs: T, rhs: T): boolean;
|
||||
add(lhs: T, rhs: T): T;
|
||||
sub(lhs: T, rhs: T): T;
|
||||
mul(lhs: T, rhs: T | bigint): T;
|
||||
pow(lhs: T, power: bigint): T;
|
||||
div(lhs: T, rhs: T | bigint): T;
|
||||
addN(lhs: T, rhs: T): T;
|
||||
subN(lhs: T, rhs: T): T;
|
||||
mulN(lhs: T, rhs: T | bigint): T;
|
||||
sqrN(num: T): T;
|
||||
isOdd?(num: T): boolean;
|
||||
pow(lhs: T, power: bigint): T;
|
||||
invertBatch: (lst: T[]) => T[];
|
||||
toBytes(num: T): Uint8Array;
|
||||
fromBytes(bytes: Uint8Array): T;
|
||||
cmov(a: T, b: T, c: boolean): T;
|
||||
}
|
||||
export declare function validateField<T>(field: IField<T>): IField<T>;
|
||||
export declare function FpPow<T>(f: IField<T>, num: T, power: bigint): T;
|
||||
export declare function FpInvertBatch<T>(f: IField<T>, nums: T[]): T[];
|
||||
export declare function FpDiv<T>(f: IField<T>, lhs: T, rhs: T | bigint): T;
|
||||
export declare function FpIsSquare<T>(f: IField<T>): (x: T) => boolean;
|
||||
export declare function nLength(n: bigint, nBitLength?: number): {
|
||||
nBitLength: number;
|
||||
nByteLength: number;
|
||||
};
|
||||
type FpField = IField<bigint> & Required<Pick<IField<bigint>, 'isOdd'>>;
|
||||
/**
|
||||
* Initializes a galois field over prime. Non-primes are not supported for now.
|
||||
* Do not init in loop: slow. Very fragile: always run a benchmark on change.
|
||||
* Major performance gains:
|
||||
* a) non-normalized operations like mulN instead of mul
|
||||
* b) `Object.freeze`
|
||||
* c) Same object shape: never add or remove keys
|
||||
* @param ORDER prime positive bigint
|
||||
* @param bitLen how many bits the field consumes
|
||||
* @param isLE (def: false) if encoding / decoding should be in little-endian
|
||||
* @param redef optional faster redefinitions of sqrt and other methods
|
||||
*/
|
||||
export declare function Field(ORDER: bigint, bitLen?: number, isLE?: boolean, redef?: Partial<IField<bigint>>): Readonly<FpField>;
|
||||
export declare function FpSqrtOdd<T>(Fp: IField<T>, elm: T): T;
|
||||
export declare function FpSqrtEven<T>(Fp: IField<T>, elm: T): T;
|
||||
/**
|
||||
* FIPS 186 B.4.1-compliant "constant-time" private key generation utility.
|
||||
* Can take (n+8) or more bytes of uniform input e.g. from CSPRNG or KDF
|
||||
* and convert them into private scalar, with the modulo bias being negligible.
|
||||
* Needs at least 40 bytes of input for 32-byte private key.
|
||||
* https://research.kudelskisecurity.com/2020/07/28/the-definitive-guide-to-modulo-bias-and-how-to-avoid-it/
|
||||
* @param hash hash output from SHA3 or a similar function
|
||||
* @param groupOrder size of subgroup - (e.g. curveFn.CURVE.n)
|
||||
* @param isLE interpret hash bytes as LE num
|
||||
* @returns valid private scalar
|
||||
*/
|
||||
export declare function hashToPrivateScalar(hash: string | Uint8Array, groupOrder: bigint, isLE?: boolean): bigint;
|
||||
export {};
|
||||
//# sourceMappingURL=modular.d.ts.map
|
||||
1
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/modular.d.ts.map
generated
vendored
Normal file
1
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/modular.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"modular.d.ts","sourceRoot":"","sources":["../src/abstract/modular.ts"],"names":[],"mappings":"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"}
|
||||
381
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/modular.js
generated
vendored
Normal file
381
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/modular.js
generated
vendored
Normal file
@@ -0,0 +1,381 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.hashToPrivateScalar = exports.FpSqrtEven = exports.FpSqrtOdd = exports.Field = exports.nLength = exports.FpIsSquare = exports.FpDiv = exports.FpInvertBatch = exports.FpPow = exports.validateField = exports.isNegativeLE = exports.FpSqrt = exports.tonelliShanks = exports.invert = exports.pow2 = exports.pow = exports.mod = void 0;
|
||||
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||
// Utilities for modular arithmetics and finite fields
|
||||
const utils_js_1 = require("./utils.js");
|
||||
// prettier-ignore
|
||||
const _0n = BigInt(0), _1n = BigInt(1), _2n = BigInt(2), _3n = BigInt(3);
|
||||
// prettier-ignore
|
||||
const _4n = BigInt(4), _5n = BigInt(5), _8n = BigInt(8);
|
||||
// prettier-ignore
|
||||
const _9n = BigInt(9), _16n = BigInt(16);
|
||||
// Calculates a modulo b
|
||||
function mod(a, b) {
|
||||
const result = a % b;
|
||||
return result >= _0n ? result : b + result;
|
||||
}
|
||||
exports.mod = mod;
|
||||
/**
|
||||
* Efficiently raise num to power and do modular division.
|
||||
* Unsafe in some contexts: uses ladder, so can expose bigint bits.
|
||||
* @example
|
||||
* pow(2n, 6n, 11n) // 64n % 11n == 9n
|
||||
*/
|
||||
// TODO: use field version && remove
|
||||
function pow(num, power, modulo) {
|
||||
if (modulo <= _0n || power < _0n)
|
||||
throw new Error('Expected power/modulo > 0');
|
||||
if (modulo === _1n)
|
||||
return _0n;
|
||||
let res = _1n;
|
||||
while (power > _0n) {
|
||||
if (power & _1n)
|
||||
res = (res * num) % modulo;
|
||||
num = (num * num) % modulo;
|
||||
power >>= _1n;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
exports.pow = pow;
|
||||
// Does x ^ (2 ^ power) mod p. pow2(30, 4) == 30 ^ (2 ^ 4)
|
||||
function pow2(x, power, modulo) {
|
||||
let res = x;
|
||||
while (power-- > _0n) {
|
||||
res *= res;
|
||||
res %= modulo;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
exports.pow2 = pow2;
|
||||
// Inverses number over modulo
|
||||
function invert(number, modulo) {
|
||||
if (number === _0n || modulo <= _0n) {
|
||||
throw new Error(`invert: expected positive integers, got n=${number} mod=${modulo}`);
|
||||
}
|
||||
// Euclidean 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
|
||||
let x = _0n, y = _1n, u = _1n, v = _0n;
|
||||
while (a !== _0n) {
|
||||
// JIT applies optimization if those two lines follow each other
|
||||
const q = b / a;
|
||||
const r = b % a;
|
||||
const m = x - u * q;
|
||||
const n = y - v * q;
|
||||
// prettier-ignore
|
||||
b = a, a = r, x = u, y = v, u = m, v = n;
|
||||
}
|
||||
const gcd = b;
|
||||
if (gcd !== _1n)
|
||||
throw new Error('invert: does not exist');
|
||||
return mod(x, modulo);
|
||||
}
|
||||
exports.invert = invert;
|
||||
// Tonelli-Shanks algorithm
|
||||
// Paper 1: https://eprint.iacr.org/2012/685.pdf (page 12)
|
||||
// Paper 2: Square Roots from 1; 24, 51, 10 to Dan Shanks
|
||||
function tonelliShanks(P) {
|
||||
// Legendre constant: used to calculate Legendre symbol (a | p),
|
||||
// which denotes the value of a^((p-1)/2) (mod p).
|
||||
// (a | p) ≡ 1 if a is a square (mod p)
|
||||
// (a | p) ≡ -1 if a is not a square (mod p)
|
||||
// (a | p) ≡ 0 if a ≡ 0 (mod p)
|
||||
const legendreC = (P - _1n) / _2n;
|
||||
let Q, S, Z;
|
||||
// Step 1: By factoring out powers of 2 from p - 1,
|
||||
// find q and s such that p - 1 = q*(2^s) with q odd
|
||||
for (Q = P - _1n, S = 0; Q % _2n === _0n; Q /= _2n, S++)
|
||||
;
|
||||
// Step 2: Select a non-square z such that (z | p) ≡ -1 and set c ≡ zq
|
||||
for (Z = _2n; Z < P && pow(Z, legendreC, P) !== P - _1n; Z++)
|
||||
;
|
||||
// Fast-path
|
||||
if (S === 1) {
|
||||
const p1div4 = (P + _1n) / _4n;
|
||||
return function tonelliFast(Fp, n) {
|
||||
const root = Fp.pow(n, p1div4);
|
||||
if (!Fp.eql(Fp.sqr(root), n))
|
||||
throw new Error('Cannot find square root');
|
||||
return root;
|
||||
};
|
||||
}
|
||||
// Slow-path
|
||||
const Q1div2 = (Q + _1n) / _2n;
|
||||
return function tonelliSlow(Fp, n) {
|
||||
// Step 0: Check that n is indeed a square: (n | p) should not be ≡ -1
|
||||
if (Fp.pow(n, legendreC) === Fp.neg(Fp.ONE))
|
||||
throw new Error('Cannot find square root');
|
||||
let r = S;
|
||||
// TODO: will fail at Fp2/etc
|
||||
let g = Fp.pow(Fp.mul(Fp.ONE, Z), Q); // will update both x and b
|
||||
let x = Fp.pow(n, Q1div2); // first guess at the square root
|
||||
let b = Fp.pow(n, Q); // first guess at the fudge factor
|
||||
while (!Fp.eql(b, Fp.ONE)) {
|
||||
if (Fp.eql(b, Fp.ZERO))
|
||||
return Fp.ZERO; // https://en.wikipedia.org/wiki/Tonelli%E2%80%93Shanks_algorithm (4. If t = 0, return r = 0)
|
||||
// Find m such b^(2^m)==1
|
||||
let m = 1;
|
||||
for (let t2 = Fp.sqr(b); m < r; m++) {
|
||||
if (Fp.eql(t2, Fp.ONE))
|
||||
break;
|
||||
t2 = Fp.sqr(t2); // t2 *= t2
|
||||
}
|
||||
// NOTE: r-m-1 can be bigger than 32, need to convert to bigint before shift, otherwise there will be overflow
|
||||
const ge = Fp.pow(g, _1n << BigInt(r - m - 1)); // ge = 2^(r-m-1)
|
||||
g = Fp.sqr(ge); // g = ge * ge
|
||||
x = Fp.mul(x, ge); // x *= ge
|
||||
b = Fp.mul(b, g); // b *= g
|
||||
r = m;
|
||||
}
|
||||
return x;
|
||||
};
|
||||
}
|
||||
exports.tonelliShanks = tonelliShanks;
|
||||
function FpSqrt(P) {
|
||||
// NOTE: different algorithms can give different roots, it is up to user to decide which one they want.
|
||||
// For example there is FpSqrtOdd/FpSqrtEven to choice root based on oddness (used for hash-to-curve).
|
||||
// P ≡ 3 (mod 4)
|
||||
// √n = n^((P+1)/4)
|
||||
if (P % _4n === _3n) {
|
||||
// Not all roots possible!
|
||||
// const ORDER =
|
||||
// 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaabn;
|
||||
// const NUM = 72057594037927816n;
|
||||
const p1div4 = (P + _1n) / _4n;
|
||||
return function sqrt3mod4(Fp, n) {
|
||||
const root = Fp.pow(n, p1div4);
|
||||
// Throw if root**2 != n
|
||||
if (!Fp.eql(Fp.sqr(root), n))
|
||||
throw new Error('Cannot find square root');
|
||||
return root;
|
||||
};
|
||||
}
|
||||
// Atkin algorithm for q ≡ 5 (mod 8), https://eprint.iacr.org/2012/685.pdf (page 10)
|
||||
if (P % _8n === _5n) {
|
||||
const c1 = (P - _5n) / _8n;
|
||||
return function sqrt5mod8(Fp, n) {
|
||||
const n2 = Fp.mul(n, _2n);
|
||||
const v = Fp.pow(n2, c1);
|
||||
const nv = Fp.mul(n, v);
|
||||
const i = Fp.mul(Fp.mul(nv, _2n), v);
|
||||
const root = Fp.mul(nv, Fp.sub(i, Fp.ONE));
|
||||
if (!Fp.eql(Fp.sqr(root), n))
|
||||
throw new Error('Cannot find square root');
|
||||
return root;
|
||||
};
|
||||
}
|
||||
// P ≡ 9 (mod 16)
|
||||
if (P % _16n === _9n) {
|
||||
// NOTE: tonelli is too slow for bls-Fp2 calculations even on start
|
||||
// Means we cannot use sqrt for constants at all!
|
||||
//
|
||||
// const c1 = Fp.sqrt(Fp.negate(Fp.ONE)); // 1. c1 = sqrt(-1) in F, i.e., (c1^2) == -1 in F
|
||||
// const c2 = Fp.sqrt(c1); // 2. c2 = sqrt(c1) in F, i.e., (c2^2) == c1 in F
|
||||
// const c3 = Fp.sqrt(Fp.negate(c1)); // 3. c3 = sqrt(-c1) in F, i.e., (c3^2) == -c1 in F
|
||||
// const c4 = (P + _7n) / _16n; // 4. c4 = (q + 7) / 16 # Integer arithmetic
|
||||
// sqrt = (x) => {
|
||||
// let tv1 = Fp.pow(x, c4); // 1. tv1 = x^c4
|
||||
// let tv2 = Fp.mul(c1, tv1); // 2. tv2 = c1 * tv1
|
||||
// const tv3 = Fp.mul(c2, tv1); // 3. tv3 = c2 * tv1
|
||||
// let tv4 = Fp.mul(c3, tv1); // 4. tv4 = c3 * tv1
|
||||
// const e1 = Fp.equals(Fp.square(tv2), x); // 5. e1 = (tv2^2) == x
|
||||
// const e2 = Fp.equals(Fp.square(tv3), x); // 6. e2 = (tv3^2) == x
|
||||
// tv1 = Fp.cmov(tv1, tv2, e1); // 7. tv1 = CMOV(tv1, tv2, e1) # Select tv2 if (tv2^2) == x
|
||||
// tv2 = Fp.cmov(tv4, tv3, e2); // 8. tv2 = CMOV(tv4, tv3, e2) # Select tv3 if (tv3^2) == x
|
||||
// const e3 = Fp.equals(Fp.square(tv2), x); // 9. e3 = (tv2^2) == x
|
||||
// return Fp.cmov(tv1, tv2, e3); // 10. z = CMOV(tv1, tv2, e3) # Select the sqrt from tv1 and tv2
|
||||
// }
|
||||
}
|
||||
// Other cases: Tonelli-Shanks algorithm
|
||||
return tonelliShanks(P);
|
||||
}
|
||||
exports.FpSqrt = FpSqrt;
|
||||
// Little-endian check for first LE bit (last BE bit);
|
||||
const isNegativeLE = (num, modulo) => (mod(num, modulo) & _1n) === _1n;
|
||||
exports.isNegativeLE = isNegativeLE;
|
||||
// prettier-ignore
|
||||
const FIELD_FIELDS = [
|
||||
'create', 'isValid', 'is0', 'neg', 'inv', 'sqrt', 'sqr',
|
||||
'eql', 'add', 'sub', 'mul', 'pow', 'div',
|
||||
'addN', 'subN', 'mulN', 'sqrN'
|
||||
];
|
||||
function validateField(field) {
|
||||
const initial = {
|
||||
ORDER: 'bigint',
|
||||
MASK: 'bigint',
|
||||
BYTES: 'isSafeInteger',
|
||||
BITS: 'isSafeInteger',
|
||||
};
|
||||
const opts = FIELD_FIELDS.reduce((map, val) => {
|
||||
map[val] = 'function';
|
||||
return map;
|
||||
}, initial);
|
||||
return (0, utils_js_1.validateObject)(field, opts);
|
||||
}
|
||||
exports.validateField = validateField;
|
||||
// Generic field functions
|
||||
function FpPow(f, num, power) {
|
||||
// Should have same speed as pow for bigints
|
||||
// TODO: benchmark!
|
||||
if (power < _0n)
|
||||
throw new Error('Expected power > 0');
|
||||
if (power === _0n)
|
||||
return f.ONE;
|
||||
if (power === _1n)
|
||||
return num;
|
||||
let p = f.ONE;
|
||||
let d = num;
|
||||
while (power > _0n) {
|
||||
if (power & _1n)
|
||||
p = f.mul(p, d);
|
||||
d = f.sqr(d);
|
||||
power >>= _1n;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
exports.FpPow = FpPow;
|
||||
// 0 is non-invertible: non-batched version will throw on 0
|
||||
function FpInvertBatch(f, nums) {
|
||||
const tmp = new Array(nums.length);
|
||||
// Walk from first to last, multiply them by each other MOD p
|
||||
const lastMultiplied = nums.reduce((acc, num, i) => {
|
||||
if (f.is0(num))
|
||||
return acc;
|
||||
tmp[i] = acc;
|
||||
return f.mul(acc, num);
|
||||
}, f.ONE);
|
||||
// Invert last element
|
||||
const inverted = f.inv(lastMultiplied);
|
||||
// Walk from last to first, multiply them by inverted each other MOD p
|
||||
nums.reduceRight((acc, num, i) => {
|
||||
if (f.is0(num))
|
||||
return acc;
|
||||
tmp[i] = f.mul(acc, tmp[i]);
|
||||
return f.mul(acc, num);
|
||||
}, inverted);
|
||||
return tmp;
|
||||
}
|
||||
exports.FpInvertBatch = FpInvertBatch;
|
||||
function FpDiv(f, lhs, rhs) {
|
||||
return f.mul(lhs, typeof rhs === 'bigint' ? invert(rhs, f.ORDER) : f.inv(rhs));
|
||||
}
|
||||
exports.FpDiv = FpDiv;
|
||||
// This function returns True whenever the value x is a square in the field F.
|
||||
function FpIsSquare(f) {
|
||||
const legendreConst = (f.ORDER - _1n) / _2n; // Integer arithmetic
|
||||
return (x) => {
|
||||
const p = f.pow(x, legendreConst);
|
||||
return f.eql(p, f.ZERO) || f.eql(p, f.ONE);
|
||||
};
|
||||
}
|
||||
exports.FpIsSquare = FpIsSquare;
|
||||
// CURVE.n lengths
|
||||
function nLength(n, nBitLength) {
|
||||
// Bit size, byte size of CURVE.n
|
||||
const _nBitLength = nBitLength !== undefined ? nBitLength : n.toString(2).length;
|
||||
const nByteLength = Math.ceil(_nBitLength / 8);
|
||||
return { nBitLength: _nBitLength, nByteLength };
|
||||
}
|
||||
exports.nLength = nLength;
|
||||
/**
|
||||
* Initializes a galois field over prime. Non-primes are not supported for now.
|
||||
* Do not init in loop: slow. Very fragile: always run a benchmark on change.
|
||||
* Major performance gains:
|
||||
* a) non-normalized operations like mulN instead of mul
|
||||
* b) `Object.freeze`
|
||||
* c) Same object shape: never add or remove keys
|
||||
* @param ORDER prime positive bigint
|
||||
* @param bitLen how many bits the field consumes
|
||||
* @param isLE (def: false) if encoding / decoding should be in little-endian
|
||||
* @param redef optional faster redefinitions of sqrt and other methods
|
||||
*/
|
||||
function Field(ORDER, bitLen, isLE = false, redef = {}) {
|
||||
if (ORDER <= _0n)
|
||||
throw new Error(`Expected Fp ORDER > 0, got ${ORDER}`);
|
||||
const { nBitLength: BITS, nByteLength: BYTES } = nLength(ORDER, bitLen);
|
||||
if (BYTES > 2048)
|
||||
throw new Error('Field lengths over 2048 bytes are not supported');
|
||||
const sqrtP = FpSqrt(ORDER);
|
||||
const f = Object.freeze({
|
||||
ORDER,
|
||||
BITS,
|
||||
BYTES,
|
||||
MASK: (0, utils_js_1.bitMask)(BITS),
|
||||
ZERO: _0n,
|
||||
ONE: _1n,
|
||||
create: (num) => mod(num, ORDER),
|
||||
isValid: (num) => {
|
||||
if (typeof num !== 'bigint')
|
||||
throw new Error(`Invalid field element: expected bigint, got ${typeof num}`);
|
||||
return _0n <= num && num < ORDER; // 0 is valid element, but it's not invertible
|
||||
},
|
||||
is0: (num) => num === _0n,
|
||||
isOdd: (num) => (num & _1n) === _1n,
|
||||
neg: (num) => mod(-num, ORDER),
|
||||
eql: (lhs, rhs) => lhs === rhs,
|
||||
sqr: (num) => mod(num * num, ORDER),
|
||||
add: (lhs, rhs) => mod(lhs + rhs, ORDER),
|
||||
sub: (lhs, rhs) => mod(lhs - rhs, ORDER),
|
||||
mul: (lhs, rhs) => mod(lhs * rhs, ORDER),
|
||||
pow: (num, power) => FpPow(f, num, power),
|
||||
div: (lhs, rhs) => mod(lhs * invert(rhs, ORDER), ORDER),
|
||||
// Same as above, but doesn't normalize
|
||||
sqrN: (num) => num * num,
|
||||
addN: (lhs, rhs) => lhs + rhs,
|
||||
subN: (lhs, rhs) => lhs - rhs,
|
||||
mulN: (lhs, rhs) => lhs * rhs,
|
||||
inv: (num) => invert(num, ORDER),
|
||||
sqrt: redef.sqrt || ((n) => sqrtP(f, n)),
|
||||
invertBatch: (lst) => FpInvertBatch(f, lst),
|
||||
// TODO: do we really need constant cmov?
|
||||
// We don't have const-time bigints anyway, so probably will be not very useful
|
||||
cmov: (a, b, c) => (c ? b : a),
|
||||
toBytes: (num) => (isLE ? (0, utils_js_1.numberToBytesLE)(num, BYTES) : (0, utils_js_1.numberToBytesBE)(num, BYTES)),
|
||||
fromBytes: (bytes) => {
|
||||
if (bytes.length !== BYTES)
|
||||
throw new Error(`Fp.fromBytes: expected ${BYTES}, got ${bytes.length}`);
|
||||
return isLE ? (0, utils_js_1.bytesToNumberLE)(bytes) : (0, utils_js_1.bytesToNumberBE)(bytes);
|
||||
},
|
||||
});
|
||||
return Object.freeze(f);
|
||||
}
|
||||
exports.Field = Field;
|
||||
function FpSqrtOdd(Fp, elm) {
|
||||
if (!Fp.isOdd)
|
||||
throw new Error(`Field doesn't have isOdd`);
|
||||
const root = Fp.sqrt(elm);
|
||||
return Fp.isOdd(root) ? root : Fp.neg(root);
|
||||
}
|
||||
exports.FpSqrtOdd = FpSqrtOdd;
|
||||
function FpSqrtEven(Fp, elm) {
|
||||
if (!Fp.isOdd)
|
||||
throw new Error(`Field doesn't have isOdd`);
|
||||
const root = Fp.sqrt(elm);
|
||||
return Fp.isOdd(root) ? Fp.neg(root) : root;
|
||||
}
|
||||
exports.FpSqrtEven = FpSqrtEven;
|
||||
/**
|
||||
* FIPS 186 B.4.1-compliant "constant-time" private key generation utility.
|
||||
* Can take (n+8) or more bytes of uniform input e.g. from CSPRNG or KDF
|
||||
* and convert them into private scalar, with the modulo bias being negligible.
|
||||
* Needs at least 40 bytes of input for 32-byte private key.
|
||||
* https://research.kudelskisecurity.com/2020/07/28/the-definitive-guide-to-modulo-bias-and-how-to-avoid-it/
|
||||
* @param hash hash output from SHA3 or a similar function
|
||||
* @param groupOrder size of subgroup - (e.g. curveFn.CURVE.n)
|
||||
* @param isLE interpret hash bytes as LE num
|
||||
* @returns valid private scalar
|
||||
*/
|
||||
function hashToPrivateScalar(hash, groupOrder, isLE = false) {
|
||||
hash = (0, utils_js_1.ensureBytes)('privateHash', hash);
|
||||
const hashLen = hash.length;
|
||||
const minLen = nLength(groupOrder).nByteLength + 8;
|
||||
if (minLen < 24 || hashLen < minLen || hashLen > 1024)
|
||||
throw new Error(`hashToPrivateScalar: expected ${minLen}-1024 bytes of input, got ${hashLen}`);
|
||||
const num = isLE ? (0, utils_js_1.bytesToNumberLE)(hash) : (0, utils_js_1.bytesToNumberBE)(hash);
|
||||
return mod(num, groupOrder - _1n) + _1n;
|
||||
}
|
||||
exports.hashToPrivateScalar = hashToPrivateScalar;
|
||||
//# sourceMappingURL=modular.js.map
|
||||
1
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/modular.js.map
generated
vendored
Normal file
1
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/modular.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
26
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/montgomery.d.ts
generated
vendored
Normal file
26
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/montgomery.d.ts
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
type Hex = string | Uint8Array;
|
||||
export type CurveType = {
|
||||
P: bigint;
|
||||
nByteLength: number;
|
||||
adjustScalarBytes?: (bytes: Uint8Array) => Uint8Array;
|
||||
domain?: (data: Uint8Array, ctx: Uint8Array, phflag: boolean) => Uint8Array;
|
||||
a: bigint;
|
||||
montgomeryBits: number;
|
||||
powPminus2?: (x: bigint) => bigint;
|
||||
xyToU?: (x: bigint, y: bigint) => bigint;
|
||||
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;
|
||||
utils: {
|
||||
randomPrivateKey: () => Uint8Array;
|
||||
};
|
||||
GuBytes: Uint8Array;
|
||||
};
|
||||
export declare function montgomery(curveDef: CurveType): CurveFn;
|
||||
export {};
|
||||
//# sourceMappingURL=montgomery.d.ts.map
|
||||
1
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/montgomery.d.ts.map
generated
vendored
Normal file
1
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/montgomery.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"montgomery.d.ts","sourceRoot":"","sources":["../src/abstract/montgomery.ts"],"names":[],"mappings":"AAMA,KAAK,GAAG,GAAG,MAAM,GAAG,UAAU,CAAC;AAE/B,MAAM,MAAM,SAAS,GAAG;IACtB,CAAC,EAAE,MAAM,CAAC;IACV,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,UAAU,CAAC;IACtD,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,KAAK,UAAU,CAAC;IAC5E,CAAC,EAAE,MAAM,CAAC;IACV,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IACnC,KAAK,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IACzC,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,CAAC,EAAE,CAAC,WAAW,CAAC,EAAE,MAAM,KAAK,UAAU,CAAC;CACpD,CAAC;AACF,MAAM,MAAM,OAAO,GAAG;IACpB,UAAU,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,KAAK,UAAU,CAAC;IAChD,cAAc,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,UAAU,CAAC;IAC5C,eAAe,EAAE,CAAC,WAAW,EAAE,GAAG,EAAE,UAAU,EAAE,GAAG,KAAK,UAAU,CAAC;IACnE,YAAY,EAAE,CAAC,UAAU,EAAE,GAAG,KAAK,UAAU,CAAC;IAC9C,KAAK,EAAE;QAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA;KAAE,CAAC;IAC9C,OAAO,EAAE,UAAU,CAAC;CACrB,CAAC;AAuBF,wBAAgB,UAAU,CAAC,QAAQ,EAAE,SAAS,GAAG,OAAO,CA0IvD"}
|
||||
161
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/montgomery.js
generated
vendored
Normal file
161
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/montgomery.js
generated
vendored
Normal file
@@ -0,0 +1,161 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.montgomery = void 0;
|
||||
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||
const modular_js_1 = require("./modular.js");
|
||||
const utils_js_1 = require("./utils.js");
|
||||
const _0n = BigInt(0);
|
||||
const _1n = BigInt(1);
|
||||
function validateOpts(curve) {
|
||||
(0, utils_js_1.validateObject)(curve, {
|
||||
a: 'bigint',
|
||||
}, {
|
||||
montgomeryBits: 'isSafeInteger',
|
||||
nByteLength: 'isSafeInteger',
|
||||
adjustScalarBytes: 'function',
|
||||
domain: 'function',
|
||||
powPminus2: 'function',
|
||||
Gu: 'bigint',
|
||||
});
|
||||
// Set defaults
|
||||
return Object.freeze({ ...curve });
|
||||
}
|
||||
// NOTE: not really montgomery curve, just bunch of very specific methods for X25519/X448 (RFC 7748, https://www.rfc-editor.org/rfc/rfc7748)
|
||||
// Uses only one coordinate instead of two
|
||||
function montgomery(curveDef) {
|
||||
const CURVE = validateOpts(curveDef);
|
||||
const { P } = CURVE;
|
||||
const modP = (n) => (0, modular_js_1.mod)(n, P);
|
||||
const montgomeryBits = CURVE.montgomeryBits;
|
||||
const montgomeryBytes = Math.ceil(montgomeryBits / 8);
|
||||
const fieldLen = CURVE.nByteLength;
|
||||
const adjustScalarBytes = CURVE.adjustScalarBytes || ((bytes) => bytes);
|
||||
const powPminus2 = CURVE.powPminus2 || ((x) => (0, modular_js_1.pow)(x, P - BigInt(2), P));
|
||||
// cswap from RFC7748. But it is not from RFC7748!
|
||||
/*
|
||||
cswap(swap, x_2, x_3):
|
||||
dummy = mask(swap) AND (x_2 XOR x_3)
|
||||
x_2 = x_2 XOR dummy
|
||||
x_3 = x_3 XOR dummy
|
||||
Return (x_2, x_3)
|
||||
Where mask(swap) is the all-1 or all-0 word of the same length as x_2
|
||||
and x_3, computed, e.g., as mask(swap) = 0 - swap.
|
||||
*/
|
||||
function cswap(swap, x_2, x_3) {
|
||||
const dummy = modP(swap * (x_2 - x_3));
|
||||
x_2 = modP(x_2 - dummy);
|
||||
x_3 = modP(x_3 + dummy);
|
||||
return [x_2, x_3];
|
||||
}
|
||||
// Accepts 0 as well
|
||||
function assertFieldElement(n) {
|
||||
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
|
||||
* @param scalar by which the point would be multiplied
|
||||
* @returns new Point on Montgomery curve
|
||||
*/
|
||||
function montgomeryLadder(pointU, scalar) {
|
||||
const u = assertFieldElement(pointU);
|
||||
// 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);
|
||||
const x_1 = u;
|
||||
let x_2 = _1n;
|
||||
let z_2 = _0n;
|
||||
let x_3 = u;
|
||||
let z_3 = _1n;
|
||||
let swap = _0n;
|
||||
let sw;
|
||||
for (let t = BigInt(montgomeryBits - 1); t >= _0n; t--) {
|
||||
const k_t = (k >> t) & _1n;
|
||||
swap ^= k_t;
|
||||
sw = cswap(swap, x_2, x_3);
|
||||
x_2 = sw[0];
|
||||
x_3 = sw[1];
|
||||
sw = cswap(swap, z_2, z_3);
|
||||
z_2 = sw[0];
|
||||
z_3 = sw[1];
|
||||
swap = k_t;
|
||||
const A = x_2 + z_2;
|
||||
const AA = modP(A * A);
|
||||
const B = x_2 - z_2;
|
||||
const BB = modP(B * B);
|
||||
const E = AA - BB;
|
||||
const C = x_3 + z_3;
|
||||
const D = x_3 - z_3;
|
||||
const DA = modP(D * A);
|
||||
const CB = modP(C * B);
|
||||
const dacb = DA + CB;
|
||||
const da_cb = DA - CB;
|
||||
x_3 = modP(dacb * dacb);
|
||||
z_3 = modP(x_1 * modP(da_cb * da_cb));
|
||||
x_2 = modP(AA * BB);
|
||||
z_2 = modP(E * (AA + modP(a24 * E)));
|
||||
}
|
||||
// (x_2, x_3) = cswap(swap, x_2, x_3)
|
||||
sw = cswap(swap, x_2, x_3);
|
||||
x_2 = sw[0];
|
||||
x_3 = sw[1];
|
||||
// (z_2, z_3) = cswap(swap, z_2, z_3)
|
||||
sw = cswap(swap, z_2, z_3);
|
||||
z_2 = sw[0];
|
||||
z_3 = sw[1];
|
||||
// z_2^(p - 2)
|
||||
const z2 = powPminus2(z_2);
|
||||
// Return x_2 * (z_2^(p - 2))
|
||||
return modP(x_2 * z2);
|
||||
}
|
||||
function encodeUCoordinate(u) {
|
||||
return (0, utils_js_1.numberToBytesLE)(modP(u), montgomeryBytes);
|
||||
}
|
||||
function decodeUCoordinate(uEnc) {
|
||||
// Section 5: When receiving such an array, implementations of X25519
|
||||
// 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 = (0, utils_js_1.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 (0, utils_js_1.bytesToNumberLE)(u);
|
||||
}
|
||||
function decodeScalar(n) {
|
||||
const bytes = (0, utils_js_1.ensureBytes)('scalar', n);
|
||||
if (bytes.length !== montgomeryBytes && bytes.length !== fieldLen)
|
||||
throw new Error(`Expected ${montgomeryBytes} or ${fieldLen} bytes, got ${bytes.length}`);
|
||||
return (0, utils_js_1.bytesToNumberLE)(adjustScalarBytes(bytes));
|
||||
}
|
||||
function scalarMult(scalar, u) {
|
||||
const pointU = decodeUCoordinate(u);
|
||||
const _scalar = decodeScalar(scalar);
|
||||
const pu = montgomeryLadder(pointU, _scalar);
|
||||
// The result was not contributory
|
||||
// https://cr.yp.to/ecdh.html#validate
|
||||
if (pu === _0n)
|
||||
throw new Error('Invalid private or public key received');
|
||||
return encodeUCoordinate(pu);
|
||||
}
|
||||
// Computes public key from private. By doing scalar multiplication of base point.
|
||||
const GuBytes = encodeUCoordinate(CURVE.Gu);
|
||||
function scalarMultBase(scalar) {
|
||||
return scalarMult(scalar, GuBytes);
|
||||
}
|
||||
return {
|
||||
scalarMult,
|
||||
scalarMultBase,
|
||||
getSharedSecret: (privateKey, publicKey) => scalarMult(privateKey, publicKey),
|
||||
getPublicKey: (privateKey) => scalarMultBase(privateKey),
|
||||
utils: { randomPrivateKey: () => CURVE.randomBytes(CURVE.nByteLength) },
|
||||
GuBytes: GuBytes,
|
||||
};
|
||||
}
|
||||
exports.montgomery = montgomery;
|
||||
//# sourceMappingURL=montgomery.js.map
|
||||
1
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/montgomery.js.map
generated
vendored
Normal file
1
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/montgomery.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
30
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/poseidon.d.ts
generated
vendored
Normal file
30
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/poseidon.d.ts
generated
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||
import { IField } from './modular.js';
|
||||
export type PoseidonOpts = {
|
||||
Fp: IField<bigint>;
|
||||
t: number;
|
||||
roundsFull: number;
|
||||
roundsPartial: number;
|
||||
sboxPower?: number;
|
||||
reversePartialPowIdx?: boolean;
|
||||
mds: bigint[][];
|
||||
roundConstants: bigint[][];
|
||||
};
|
||||
export declare function validateOpts(opts: PoseidonOpts): Readonly<{
|
||||
rounds: number;
|
||||
sboxFn: (n: bigint) => bigint;
|
||||
roundConstants: bigint[][];
|
||||
mds: bigint[][];
|
||||
Fp: IField<bigint>;
|
||||
t: number;
|
||||
roundsFull: number;
|
||||
roundsPartial: number;
|
||||
sboxPower?: number | undefined;
|
||||
reversePartialPowIdx?: boolean | undefined;
|
||||
}>;
|
||||
export declare function splitConstants(rc: bigint[], t: number): bigint[][];
|
||||
export declare function poseidon(opts: PoseidonOpts): {
|
||||
(values: bigint[]): bigint[];
|
||||
roundConstants: bigint[][];
|
||||
};
|
||||
//# sourceMappingURL=poseidon.d.ts.map
|
||||
1
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/poseidon.d.ts.map
generated
vendored
Normal file
1
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/poseidon.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"poseidon.d.ts","sourceRoot":"","sources":["../src/abstract/poseidon.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAEtE,OAAO,EAAE,MAAM,EAAwB,MAAM,cAAc,CAAC;AAG5D,MAAM,MAAM,YAAY,GAAG;IACzB,EAAE,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IACnB,CAAC,EAAE,MAAM,CAAC;IACV,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,GAAG,EAAE,MAAM,EAAE,EAAE,CAAC;IAChB,cAAc,EAAE,MAAM,EAAE,EAAE,CAAC;CAC5B,CAAC;AAEF,wBAAgB,YAAY,CAAC,IAAI,EAAE,YAAY;;gBAgB5B,MAAM;;;;;;;;;GAgCxB;AAED,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,cAarD;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,YAAY;aAeU,MAAM,EAAE;;EAsB5D"}
|
||||
116
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/poseidon.js
generated
vendored
Normal file
116
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/poseidon.js
generated
vendored
Normal file
@@ -0,0 +1,116 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.poseidon = exports.splitConstants = exports.validateOpts = void 0;
|
||||
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||
// Poseidon Hash: https://eprint.iacr.org/2019/458.pdf, https://www.poseidon-hash.info
|
||||
const modular_js_1 = require("./modular.js");
|
||||
function validateOpts(opts) {
|
||||
const { Fp } = opts;
|
||||
(0, modular_js_1.validateField)(Fp);
|
||||
for (const i of ['t', 'roundsFull', 'roundsPartial']) {
|
||||
if (typeof opts[i] !== 'number' || !Number.isSafeInteger(opts[i]))
|
||||
throw new Error(`Poseidon: invalid param ${i}=${opts[i]} (${typeof opts[i]})`);
|
||||
}
|
||||
if (opts.reversePartialPowIdx !== undefined && typeof opts.reversePartialPowIdx !== 'boolean')
|
||||
throw new Error(`Poseidon: invalid param reversePartialPowIdx=${opts.reversePartialPowIdx}`);
|
||||
// Default is 5, but by some reasons stark uses 3
|
||||
let sboxPower = opts.sboxPower;
|
||||
if (sboxPower === undefined)
|
||||
sboxPower = 5;
|
||||
if (typeof sboxPower !== 'number' || !Number.isSafeInteger(sboxPower))
|
||||
throw new Error(`Poseidon wrong sboxPower=${sboxPower}`);
|
||||
const _sboxPower = BigInt(sboxPower);
|
||||
let sboxFn = (n) => (0, modular_js_1.FpPow)(Fp, n, _sboxPower);
|
||||
// Unwrapped sbox power for common cases (195->142μs)
|
||||
if (sboxPower === 3)
|
||||
sboxFn = (n) => Fp.mul(Fp.sqrN(n), n);
|
||||
else if (sboxPower === 5)
|
||||
sboxFn = (n) => Fp.mul(Fp.sqrN(Fp.sqrN(n)), n);
|
||||
if (opts.roundsFull % 2 !== 0)
|
||||
throw new Error(`Poseidon roundsFull is not even: ${opts.roundsFull}`);
|
||||
const rounds = opts.roundsFull + opts.roundsPartial;
|
||||
if (!Array.isArray(opts.roundConstants) || opts.roundConstants.length !== rounds)
|
||||
throw new Error('Poseidon: wrong round constants');
|
||||
const roundConstants = opts.roundConstants.map((rc) => {
|
||||
if (!Array.isArray(rc) || rc.length !== opts.t)
|
||||
throw new Error(`Poseidon wrong round constants: ${rc}`);
|
||||
return rc.map((i) => {
|
||||
if (typeof i !== 'bigint' || !Fp.isValid(i))
|
||||
throw new Error(`Poseidon wrong round constant=${i}`);
|
||||
return Fp.create(i);
|
||||
});
|
||||
});
|
||||
// MDS is TxT matrix
|
||||
if (!Array.isArray(opts.mds) || opts.mds.length !== opts.t)
|
||||
throw new Error('Poseidon: wrong MDS matrix');
|
||||
const mds = opts.mds.map((mdsRow) => {
|
||||
if (!Array.isArray(mdsRow) || mdsRow.length !== opts.t)
|
||||
throw new Error(`Poseidon MDS matrix row: ${mdsRow}`);
|
||||
return mdsRow.map((i) => {
|
||||
if (typeof i !== 'bigint')
|
||||
throw new Error(`Poseidon MDS matrix value=${i}`);
|
||||
return Fp.create(i);
|
||||
});
|
||||
});
|
||||
return Object.freeze({ ...opts, rounds, sboxFn, roundConstants, mds });
|
||||
}
|
||||
exports.validateOpts = validateOpts;
|
||||
function splitConstants(rc, t) {
|
||||
if (typeof t !== 'number')
|
||||
throw new Error('poseidonSplitConstants: wrong t');
|
||||
if (!Array.isArray(rc) || rc.length % t)
|
||||
throw new Error('poseidonSplitConstants: wrong rc');
|
||||
const res = [];
|
||||
let tmp = [];
|
||||
for (let i = 0; i < rc.length; i++) {
|
||||
tmp.push(rc[i]);
|
||||
if (tmp.length === t) {
|
||||
res.push(tmp);
|
||||
tmp = [];
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
exports.splitConstants = splitConstants;
|
||||
function poseidon(opts) {
|
||||
const { t, Fp, rounds, sboxFn, reversePartialPowIdx } = validateOpts(opts);
|
||||
const halfRoundsFull = Math.floor(opts.roundsFull / 2);
|
||||
const partialIdx = reversePartialPowIdx ? t - 1 : 0;
|
||||
const poseidonRound = (values, isFull, idx) => {
|
||||
values = values.map((i, j) => Fp.add(i, opts.roundConstants[idx][j]));
|
||||
if (isFull)
|
||||
values = values.map((i) => sboxFn(i));
|
||||
else
|
||||
values[partialIdx] = sboxFn(values[partialIdx]);
|
||||
// Matrix multiplication
|
||||
values = opts.mds.map((i) => i.reduce((acc, i, j) => Fp.add(acc, Fp.mulN(i, values[j])), Fp.ZERO));
|
||||
return values;
|
||||
};
|
||||
const poseidonHash = function poseidonHash(values) {
|
||||
if (!Array.isArray(values) || values.length !== t)
|
||||
throw new Error(`Poseidon: wrong values (expected array of bigints with length ${t})`);
|
||||
values = values.map((i) => {
|
||||
if (typeof i !== 'bigint')
|
||||
throw new Error(`Poseidon: wrong value=${i} (${typeof i})`);
|
||||
return Fp.create(i);
|
||||
});
|
||||
let round = 0;
|
||||
// Apply r_f/2 full rounds.
|
||||
for (let i = 0; i < halfRoundsFull; i++)
|
||||
values = poseidonRound(values, true, round++);
|
||||
// Apply r_p partial rounds.
|
||||
for (let i = 0; i < opts.roundsPartial; i++)
|
||||
values = poseidonRound(values, false, round++);
|
||||
// Apply r_f/2 full rounds.
|
||||
for (let i = 0; i < halfRoundsFull; i++)
|
||||
values = poseidonRound(values, true, round++);
|
||||
if (round !== rounds)
|
||||
throw new Error(`Poseidon: wrong number of rounds: last round=${round}, total=${rounds}`);
|
||||
return values;
|
||||
};
|
||||
// For verification in tests
|
||||
poseidonHash.roundConstants = opts.roundConstants;
|
||||
return poseidonHash;
|
||||
}
|
||||
exports.poseidon = poseidon;
|
||||
//# sourceMappingURL=poseidon.js.map
|
||||
1
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/poseidon.js.map
generated
vendored
Normal file
1
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/poseidon.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
91
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/utils.d.ts
generated
vendored
Normal file
91
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/utils.d.ts
generated
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
export type Hex = Uint8Array | string;
|
||||
export type PrivKey = Hex | bigint;
|
||||
export type CHash = {
|
||||
(message: Uint8Array | string): Uint8Array;
|
||||
blockLen: number;
|
||||
outputLen: number;
|
||||
create(opts?: {
|
||||
dkLen?: number;
|
||||
}): any;
|
||||
};
|
||||
export type FHash = (message: Uint8Array | string) => Uint8Array;
|
||||
/**
|
||||
* @example bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])) // 'cafe0123'
|
||||
*/
|
||||
export declare function bytesToHex(bytes: Uint8Array): string;
|
||||
export declare function numberToHexUnpadded(num: number | bigint): string;
|
||||
export declare function hexToNumber(hex: string): bigint;
|
||||
/**
|
||||
* @example hexToBytes('cafe0123') // Uint8Array.from([0xca, 0xfe, 0x01, 0x23])
|
||||
*/
|
||||
export declare function hexToBytes(hex: string): Uint8Array;
|
||||
export declare function bytesToNumberBE(bytes: Uint8Array): bigint;
|
||||
export declare function bytesToNumberLE(bytes: Uint8Array): bigint;
|
||||
export declare function numberToBytesBE(n: number | bigint, len: number): Uint8Array;
|
||||
export declare function numberToBytesLE(n: number | bigint, len: number): Uint8Array;
|
||||
export declare function numberToVarBytesBE(n: number | bigint): Uint8Array;
|
||||
/**
|
||||
* Takes hex string or Uint8Array, converts to Uint8Array.
|
||||
* Validates output length.
|
||||
* Will throw error for other types.
|
||||
* @param title descriptive title for an error e.g. 'private key'
|
||||
* @param hex hex string or Uint8Array
|
||||
* @param expectedLength optional, will compare to result array's length
|
||||
* @returns
|
||||
*/
|
||||
export declare function ensureBytes(title: string, hex: Hex, expectedLength?: number): Uint8Array;
|
||||
/**
|
||||
* Copies several Uint8Arrays into one.
|
||||
*/
|
||||
export declare function concatBytes(...arrays: Uint8Array[]): Uint8Array;
|
||||
export declare function equalBytes(b1: Uint8Array, b2: Uint8Array): boolean;
|
||||
/**
|
||||
* @example utf8ToBytes('abc') // new Uint8Array([97, 98, 99])
|
||||
*/
|
||||
export declare function utf8ToBytes(str: string): Uint8Array;
|
||||
/**
|
||||
* Calculates amount of bits in a bigint.
|
||||
* Same as `n.toString(2).length`
|
||||
*/
|
||||
export declare function bitLen(n: bigint): number;
|
||||
/**
|
||||
* Gets single bit at position.
|
||||
* NOTE: first bit position is 0 (same as arrays)
|
||||
* Same as `!!+Array.from(n.toString(2)).reverse()[pos]`
|
||||
*/
|
||||
export declare function bitGet(n: bigint, pos: number): bigint;
|
||||
/**
|
||||
* Sets single bit at position.
|
||||
*/
|
||||
export declare const bitSet: (n: bigint, pos: number, value: boolean) => bigint;
|
||||
/**
|
||||
* Calculate mask for N bits. Not using ** operator with bigints because of old engines.
|
||||
* Same as BigInt(`0b${Array(i).fill('1').join('')}`)
|
||||
*/
|
||||
export declare const bitMask: (n: number) => bigint;
|
||||
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 declare function createHmacDrbg<T>(hashLen: number, qByteLen: number, hmacFn: (key: Uint8Array, ...messages: Uint8Array[]) => Uint8Array): (seed: Uint8Array, predicate: Pred<T>) => T;
|
||||
declare const validatorFns: {
|
||||
readonly bigint: (val: any) => boolean;
|
||||
readonly function: (val: any) => boolean;
|
||||
readonly boolean: (val: any) => boolean;
|
||||
readonly string: (val: any) => boolean;
|
||||
readonly isSafeInteger: (val: any) => boolean;
|
||||
readonly array: (val: any) => boolean;
|
||||
readonly field: (val: any, object: any) => any;
|
||||
readonly hash: (val: any) => boolean;
|
||||
};
|
||||
type Validator = keyof typeof validatorFns;
|
||||
type ValMap<T extends Record<string, any>> = {
|
||||
[K in keyof T]?: Validator;
|
||||
};
|
||||
export declare function validateObject<T extends Record<string, any>>(object: T, validators: ValMap<T>, optValidators?: ValMap<T>): T;
|
||||
export {};
|
||||
//# sourceMappingURL=utils.d.ts.map
|
||||
1
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/utils.d.ts.map
generated
vendored
Normal file
1
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/utils.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/abstract/utils.ts"],"names":[],"mappings":"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"}
|
||||
287
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/utils.js
generated
vendored
Normal file
287
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/utils.js
generated
vendored
Normal file
@@ -0,0 +1,287 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.validateObject = exports.createHmacDrbg = exports.bitMask = exports.bitSet = exports.bitGet = exports.bitLen = exports.utf8ToBytes = exports.equalBytes = exports.concatBytes = exports.ensureBytes = exports.numberToVarBytesBE = exports.numberToBytesLE = exports.numberToBytesBE = exports.bytesToNumberLE = exports.bytesToNumberBE = exports.hexToBytes = exports.hexToNumber = exports.numberToHexUnpadded = exports.bytesToHex = void 0;
|
||||
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||
// 100 lines of code in the file are duplicated from noble-hashes (utils).
|
||||
// This is OK: `abstract` directory does not use noble-hashes.
|
||||
// User may opt-in into using different hashing library. This way, noble-hashes
|
||||
// won't be included into their bundle.
|
||||
const _0n = BigInt(0);
|
||||
const _1n = BigInt(1);
|
||||
const _2n = BigInt(2);
|
||||
const u8a = (a) => a instanceof Uint8Array;
|
||||
const hexes = Array.from({ length: 256 }, (v, i) => i.toString(16).padStart(2, '0'));
|
||||
/**
|
||||
* @example bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])) // 'cafe0123'
|
||||
*/
|
||||
function bytesToHex(bytes) {
|
||||
if (!u8a(bytes))
|
||||
throw new Error('Uint8Array expected');
|
||||
// pre-caching improves the speed 6x
|
||||
let hex = '';
|
||||
for (let i = 0; i < bytes.length; i++) {
|
||||
hex += hexes[bytes[i]];
|
||||
}
|
||||
return hex;
|
||||
}
|
||||
exports.bytesToHex = bytesToHex;
|
||||
function numberToHexUnpadded(num) {
|
||||
const hex = num.toString(16);
|
||||
return hex.length & 1 ? `0${hex}` : hex;
|
||||
}
|
||||
exports.numberToHexUnpadded = numberToHexUnpadded;
|
||||
function hexToNumber(hex) {
|
||||
if (typeof hex !== 'string')
|
||||
throw new Error('hex string expected, got ' + typeof hex);
|
||||
// Big Endian
|
||||
return BigInt(hex === '' ? '0' : `0x${hex}`);
|
||||
}
|
||||
exports.hexToNumber = hexToNumber;
|
||||
/**
|
||||
* @example hexToBytes('cafe0123') // Uint8Array.from([0xca, 0xfe, 0x01, 0x23])
|
||||
*/
|
||||
function hexToBytes(hex) {
|
||||
if (typeof hex !== 'string')
|
||||
throw new Error('hex string expected, got ' + typeof hex);
|
||||
const len = hex.length;
|
||||
if (len % 2)
|
||||
throw new Error('padded hex string expected, got unpadded hex of length ' + len);
|
||||
const array = new Uint8Array(len / 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;
|
||||
}
|
||||
exports.hexToBytes = hexToBytes;
|
||||
// BE: Big Endian, LE: Little Endian
|
||||
function bytesToNumberBE(bytes) {
|
||||
return hexToNumber(bytesToHex(bytes));
|
||||
}
|
||||
exports.bytesToNumberBE = bytesToNumberBE;
|
||||
function bytesToNumberLE(bytes) {
|
||||
if (!u8a(bytes))
|
||||
throw new Error('Uint8Array expected');
|
||||
return hexToNumber(bytesToHex(Uint8Array.from(bytes).reverse()));
|
||||
}
|
||||
exports.bytesToNumberLE = bytesToNumberLE;
|
||||
function numberToBytesBE(n, len) {
|
||||
return hexToBytes(n.toString(16).padStart(len * 2, '0'));
|
||||
}
|
||||
exports.numberToBytesBE = numberToBytesBE;
|
||||
function numberToBytesLE(n, len) {
|
||||
return numberToBytesBE(n, len).reverse();
|
||||
}
|
||||
exports.numberToBytesLE = numberToBytesLE;
|
||||
// Unpadded, rarely used
|
||||
function numberToVarBytesBE(n) {
|
||||
return hexToBytes(numberToHexUnpadded(n));
|
||||
}
|
||||
exports.numberToVarBytesBE = numberToVarBytesBE;
|
||||
/**
|
||||
* Takes hex string or Uint8Array, converts to Uint8Array.
|
||||
* Validates output length.
|
||||
* Will throw error for other types.
|
||||
* @param title descriptive title for an error e.g. 'private key'
|
||||
* @param hex hex string or Uint8Array
|
||||
* @param expectedLength optional, will compare to result array's length
|
||||
* @returns
|
||||
*/
|
||||
function ensureBytes(title, hex, expectedLength) {
|
||||
let res;
|
||||
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;
|
||||
}
|
||||
exports.ensureBytes = ensureBytes;
|
||||
/**
|
||||
* Copies several Uint8Arrays into one.
|
||||
*/
|
||||
function concatBytes(...arrays) {
|
||||
const r = new Uint8Array(arrays.reduce((sum, a) => sum + a.length, 0));
|
||||
let pad = 0; // walk through each item, ensure they have proper type
|
||||
arrays.forEach((a) => {
|
||||
if (!u8a(a))
|
||||
throw new Error('Uint8Array expected');
|
||||
r.set(a, pad);
|
||||
pad += a.length;
|
||||
});
|
||||
return r;
|
||||
}
|
||||
exports.concatBytes = concatBytes;
|
||||
function equalBytes(b1, b2) {
|
||||
// We don't care about timing attacks here
|
||||
if (b1.length !== b2.length)
|
||||
return false;
|
||||
for (let i = 0; i < b1.length; i++)
|
||||
if (b1[i] !== b2[i])
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
exports.equalBytes = equalBytes;
|
||||
/**
|
||||
* @example utf8ToBytes('abc') // new Uint8Array([97, 98, 99])
|
||||
*/
|
||||
function utf8ToBytes(str) {
|
||||
if (typeof str !== 'string')
|
||||
throw new Error(`utf8ToBytes expected string, got ${typeof str}`);
|
||||
return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809
|
||||
}
|
||||
exports.utf8ToBytes = utf8ToBytes;
|
||||
// Bit operations
|
||||
/**
|
||||
* Calculates amount of bits in a bigint.
|
||||
* Same as `n.toString(2).length`
|
||||
*/
|
||||
function bitLen(n) {
|
||||
let len;
|
||||
for (len = 0; n > _0n; n >>= _1n, len += 1)
|
||||
;
|
||||
return len;
|
||||
}
|
||||
exports.bitLen = bitLen;
|
||||
/**
|
||||
* Gets single bit at position.
|
||||
* NOTE: first bit position is 0 (same as arrays)
|
||||
* Same as `!!+Array.from(n.toString(2)).reverse()[pos]`
|
||||
*/
|
||||
function bitGet(n, pos) {
|
||||
return (n >> BigInt(pos)) & _1n;
|
||||
}
|
||||
exports.bitGet = bitGet;
|
||||
/**
|
||||
* Sets single bit at position.
|
||||
*/
|
||||
const bitSet = (n, pos, value) => {
|
||||
return n | ((value ? _1n : _0n) << BigInt(pos));
|
||||
};
|
||||
exports.bitSet = bitSet;
|
||||
/**
|
||||
* Calculate mask for N bits. Not using ** operator with bigints because of old engines.
|
||||
* Same as BigInt(`0b${Array(i).fill('1').join('')}`)
|
||||
*/
|
||||
const bitMask = (n) => (_2n << BigInt(n - 1)) - _1n;
|
||||
exports.bitMask = bitMask;
|
||||
// DRBG
|
||||
const u8n = (data) => new Uint8Array(data); // creates Uint8Array
|
||||
const u8fr = (arr) => Uint8Array.from(arr); // another shortcut
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
function createHmacDrbg(hashLen, qByteLen, hmacFn) {
|
||||
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) => 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 = [];
|
||||
while (len < qByteLen) {
|
||||
v = h();
|
||||
const sl = v.slice();
|
||||
out.push(sl);
|
||||
len += v.length;
|
||||
}
|
||||
return concatBytes(...out);
|
||||
};
|
||||
const genUntil = (seed, pred) => {
|
||||
reset();
|
||||
reseed(seed); // Steps D-G
|
||||
let res = undefined; // Step H: grind until k is in [1..n-1]
|
||||
while (!(res = pred(gen())))
|
||||
reseed();
|
||||
reset();
|
||||
return res;
|
||||
};
|
||||
return genUntil;
|
||||
}
|
||||
exports.createHmacDrbg = createHmacDrbg;
|
||||
// Validating curves and fields
|
||||
const validatorFns = {
|
||||
bigint: (val) => typeof val === 'bigint',
|
||||
function: (val) => typeof val === 'function',
|
||||
boolean: (val) => typeof val === 'boolean',
|
||||
string: (val) => typeof val === 'string',
|
||||
isSafeInteger: (val) => Number.isSafeInteger(val),
|
||||
array: (val) => Array.isArray(val),
|
||||
field: (val, object) => object.Fp.isValid(val),
|
||||
hash: (val) => typeof val === 'function' && Number.isSafeInteger(val.outputLen),
|
||||
};
|
||||
// type Record<K extends string | number | symbol, T> = { [P in K]: T; }
|
||||
function validateObject(object, validators, optValidators = {}) {
|
||||
const checkField = (fieldName, type, isOptional) => {
|
||||
const checkVal = validatorFns[type];
|
||||
if (typeof checkVal !== 'function')
|
||||
throw new Error(`Invalid validator "${type}", expected function`);
|
||||
const val = object[fieldName];
|
||||
if (isOptional && val === undefined)
|
||||
return;
|
||||
if (!checkVal(val, object)) {
|
||||
throw new Error(`Invalid param ${String(fieldName)}=${val} (${typeof val}), expected ${type}`);
|
||||
}
|
||||
};
|
||||
for (const [fieldName, type] of Object.entries(validators))
|
||||
checkField(fieldName, type, false);
|
||||
for (const [fieldName, type] of Object.entries(optValidators))
|
||||
checkField(fieldName, type, true);
|
||||
return object;
|
||||
}
|
||||
exports.validateObject = validateObject;
|
||||
// validate type tests
|
||||
// const o: { a: number; b: number; c: number } = { a: 1, b: 5, c: 6 };
|
||||
// const z0 = validateObject(o, { a: 'isSafeInteger' }, { c: 'bigint' }); // Ok!
|
||||
// // Should fail type-check
|
||||
// const z1 = validateObject(o, { a: 'tmp' }, { c: 'zz' });
|
||||
// const z2 = validateObject(o, { a: 'isSafeInteger' }, { c: 'zz' });
|
||||
// const z3 = validateObject(o, { test: 'boolean', z: 'bug' });
|
||||
// const z4 = validateObject(o, { a: 'boolean', z: 'bug' });
|
||||
//# sourceMappingURL=utils.js.map
|
||||
1
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/utils.js.map
generated
vendored
Normal file
1
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/utils.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
240
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/weierstrass.d.ts
generated
vendored
Normal file
240
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/weierstrass.d.ts
generated
vendored
Normal file
@@ -0,0 +1,240 @@
|
||||
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||
import * as mod from './modular.js';
|
||||
import * as ut from './utils.js';
|
||||
import { CHash, Hex, PrivKey } from './utils.js';
|
||||
import { Group, GroupConstructor, BasicCurve, AffinePoint } from './curve.js';
|
||||
export type { AffinePoint };
|
||||
type HmacFnSync = (key: Uint8Array, ...messages: Uint8Array[]) => Uint8Array;
|
||||
type EndomorphismOpts = {
|
||||
beta: bigint;
|
||||
splitScalar: (k: bigint) => {
|
||||
k1neg: boolean;
|
||||
k1: bigint;
|
||||
k2neg: boolean;
|
||||
k2: bigint;
|
||||
};
|
||||
};
|
||||
export type BasicWCurve<T> = BasicCurve<T> & {
|
||||
a: T;
|
||||
b: T;
|
||||
allowedPrivateKeyLengths?: readonly number[];
|
||||
wrapPrivateKey?: boolean;
|
||||
endo?: EndomorphismOpts;
|
||||
isTorsionFree?: (c: ProjConstructor<T>, point: ProjPointType<T>) => boolean;
|
||||
clearCofactor?: (c: ProjConstructor<T>, point: ProjPointType<T>) => ProjPointType<T>;
|
||||
};
|
||||
type Entropy = Hex | true;
|
||||
export type SignOpts = {
|
||||
lowS?: boolean;
|
||||
extraEntropy?: Entropy;
|
||||
prehash?: boolean;
|
||||
};
|
||||
export type VerOpts = {
|
||||
lowS?: boolean;
|
||||
prehash?: boolean;
|
||||
};
|
||||
/**
|
||||
* ### Design rationale for types
|
||||
*
|
||||
* * Interaction between classes from different curves should fail:
|
||||
* `k256.Point.BASE.add(p256.Point.BASE)`
|
||||
* * For this purpose we want to use `instanceof` operator, which is fast and works during runtime
|
||||
* * Different calls of `curve()` would return different classes -
|
||||
* `curve(params) !== curve(params)`: if somebody decided to monkey-patch their curve,
|
||||
* it won't affect others
|
||||
*
|
||||
* TypeScript can't infer types for classes created inside a function. Classes is one instance of nominative types in TypeScript and interfaces only check for shape, so it's hard to create unique type for every function call.
|
||||
*
|
||||
* We can use generic types via some param, like curve opts, but that would:
|
||||
* 1. Enable interaction between `curve(params)` and `curve(params)` (curves of same params)
|
||||
* which is hard to debug.
|
||||
* 2. Params can be generic and we can't enforce them to be constant value:
|
||||
* if somebody creates curve from non-constant params,
|
||||
* it would be allowed to interact with other curves with non-constant params
|
||||
*
|
||||
* TODO: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-7.html#unique-symbol
|
||||
*/
|
||||
export interface ProjPointType<T> extends Group<ProjPointType<T>> {
|
||||
readonly px: T;
|
||||
readonly py: T;
|
||||
readonly pz: T;
|
||||
get x(): T;
|
||||
get y(): T;
|
||||
multiply(scalar: bigint): ProjPointType<T>;
|
||||
toAffine(iz?: T): AffinePoint<T>;
|
||||
isTorsionFree(): boolean;
|
||||
clearCofactor(): ProjPointType<T>;
|
||||
assertValidity(): void;
|
||||
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;
|
||||
}
|
||||
export interface ProjConstructor<T> extends GroupConstructor<ProjPointType<T>> {
|
||||
new (x: T, y: T, z: T): ProjPointType<T>;
|
||||
fromAffine(p: AffinePoint<T>): ProjPointType<T>;
|
||||
fromHex(hex: Hex): ProjPointType<T>;
|
||||
fromPrivateKey(privateKey: PrivKey): ProjPointType<T>;
|
||||
normalizeZ(points: ProjPointType<T>[]): ProjPointType<T>[];
|
||||
}
|
||||
export type CurvePointsType<T> = BasicWCurve<T> & {
|
||||
fromBytes?: (bytes: Uint8Array) => AffinePoint<T>;
|
||||
toBytes?: (c: ProjConstructor<T>, point: ProjPointType<T>, isCompressed: boolean) => Uint8Array;
|
||||
};
|
||||
export type CurvePointsRes<T> = {
|
||||
ProjectivePoint: ProjConstructor<T>;
|
||||
normPrivateKeyToScalar: (key: PrivKey) => bigint;
|
||||
weierstrassEquation: (x: T) => T;
|
||||
isWithinCurveOrder: (num: bigint) => boolean;
|
||||
};
|
||||
export declare const DER: {
|
||||
Err: {
|
||||
new (m?: string): {
|
||||
name: string;
|
||||
message: string;
|
||||
stack?: string | undefined;
|
||||
};
|
||||
};
|
||||
_parseInt(data: Uint8Array): {
|
||||
d: bigint;
|
||||
l: Uint8Array;
|
||||
};
|
||||
toSig(hex: string | Uint8Array): {
|
||||
r: bigint;
|
||||
s: bigint;
|
||||
};
|
||||
hexFromSig(sig: {
|
||||
r: bigint;
|
||||
s: bigint;
|
||||
}): string;
|
||||
};
|
||||
export declare function weierstrassPoints<T>(opts: CurvePointsType<T>): {
|
||||
CURVE: Readonly<{
|
||||
readonly nBitLength: number;
|
||||
readonly nByteLength: number;
|
||||
readonly Fp: mod.IField<T>;
|
||||
readonly n: bigint;
|
||||
readonly h: bigint;
|
||||
readonly hEff?: bigint | undefined;
|
||||
readonly Gx: T;
|
||||
readonly Gy: T;
|
||||
readonly allowInfinityPoint?: boolean | undefined;
|
||||
readonly a: T;
|
||||
readonly b: T;
|
||||
readonly allowedPrivateKeyLengths?: readonly number[] | undefined;
|
||||
readonly wrapPrivateKey?: boolean | undefined;
|
||||
readonly endo?: EndomorphismOpts | undefined;
|
||||
readonly isTorsionFree?: ((c: ProjConstructor<T>, point: ProjPointType<T>) => boolean) | undefined;
|
||||
readonly clearCofactor?: ((c: ProjConstructor<T>, point: ProjPointType<T>) => ProjPointType<T>) | undefined;
|
||||
readonly fromBytes?: ((bytes: Uint8Array) => AffinePoint<T>) | undefined;
|
||||
readonly toBytes?: ((c: ProjConstructor<T>, point: ProjPointType<T>, isCompressed: boolean) => Uint8Array) | undefined;
|
||||
readonly p: bigint;
|
||||
}>;
|
||||
ProjectivePoint: ProjConstructor<T>;
|
||||
normPrivateKeyToScalar: (key: PrivKey) => bigint;
|
||||
weierstrassEquation: (x: T) => T;
|
||||
isWithinCurveOrder: (num: bigint) => boolean;
|
||||
};
|
||||
export interface SignatureType {
|
||||
readonly r: bigint;
|
||||
readonly s: bigint;
|
||||
readonly recovery?: number;
|
||||
assertValidity(): void;
|
||||
addRecoveryBit(recovery: number): RecoveredSignatureType;
|
||||
hasHighS(): boolean;
|
||||
normalizeS(): SignatureType;
|
||||
recoverPublicKey(msgHash: Hex): ProjPointType<bigint>;
|
||||
toCompactRawBytes(): Uint8Array;
|
||||
toCompactHex(): string;
|
||||
toDERRawBytes(isCompressed?: boolean): Uint8Array;
|
||||
toDERHex(isCompressed?: boolean): string;
|
||||
}
|
||||
export type RecoveredSignatureType = SignatureType & {
|
||||
readonly recovery: number;
|
||||
};
|
||||
export type SignatureConstructor = {
|
||||
new (r: bigint, s: bigint): SignatureType;
|
||||
fromCompact(hex: Hex): SignatureType;
|
||||
fromDER(hex: Hex): SignatureType;
|
||||
};
|
||||
type SignatureLike = {
|
||||
r: bigint;
|
||||
s: bigint;
|
||||
};
|
||||
export type PubKey = Hex | ProjPointType<bigint>;
|
||||
export type CurveType = BasicWCurve<bigint> & {
|
||||
hash: CHash;
|
||||
hmac: HmacFnSync;
|
||||
randomBytes: (bytesLength?: number) => Uint8Array;
|
||||
lowS?: boolean;
|
||||
bits2int?: (bytes: Uint8Array) => bigint;
|
||||
bits2int_modN?: (bytes: Uint8Array) => bigint;
|
||||
};
|
||||
declare function validateOpts(curve: CurveType): Readonly<{
|
||||
readonly nBitLength: number;
|
||||
readonly nByteLength: number;
|
||||
readonly Fp: mod.IField<bigint>;
|
||||
readonly n: bigint;
|
||||
readonly h: bigint;
|
||||
readonly hEff?: bigint | undefined;
|
||||
readonly Gx: bigint;
|
||||
readonly Gy: bigint;
|
||||
readonly allowInfinityPoint?: boolean | undefined;
|
||||
readonly a: bigint;
|
||||
readonly b: bigint;
|
||||
readonly allowedPrivateKeyLengths?: readonly number[] | undefined;
|
||||
readonly wrapPrivateKey?: boolean | undefined;
|
||||
readonly endo?: EndomorphismOpts | undefined;
|
||||
readonly isTorsionFree?: ((c: ProjConstructor<bigint>, point: ProjPointType<bigint>) => boolean) | undefined;
|
||||
readonly clearCofactor?: ((c: ProjConstructor<bigint>, point: ProjPointType<bigint>) => ProjPointType<bigint>) | undefined;
|
||||
readonly hash: ut.CHash;
|
||||
readonly hmac: HmacFnSync;
|
||||
readonly randomBytes: (bytesLength?: number | undefined) => Uint8Array;
|
||||
lowS: boolean;
|
||||
readonly bits2int?: ((bytes: Uint8Array) => bigint) | undefined;
|
||||
readonly bits2int_modN?: ((bytes: Uint8Array) => bigint) | undefined;
|
||||
readonly p: bigint;
|
||||
}>;
|
||||
export type CurveFn = {
|
||||
CURVE: ReturnType<typeof validateOpts>;
|
||||
getPublicKey: (privateKey: PrivKey, isCompressed?: boolean) => Uint8Array;
|
||||
getSharedSecret: (privateA: PrivKey, publicB: Hex, isCompressed?: boolean) => Uint8Array;
|
||||
sign: (msgHash: Hex, privKey: PrivKey, opts?: SignOpts) => RecoveredSignatureType;
|
||||
verify: (signature: Hex | SignatureLike, msgHash: Hex, publicKey: Hex, opts?: VerOpts) => boolean;
|
||||
ProjectivePoint: ProjConstructor<bigint>;
|
||||
Signature: SignatureConstructor;
|
||||
utils: {
|
||||
normPrivateKeyToScalar: (key: PrivKey) => bigint;
|
||||
isValidPrivateKey(privateKey: PrivKey): boolean;
|
||||
randomPrivateKey: () => Uint8Array;
|
||||
precompute: (windowSize?: number, point?: ProjPointType<bigint>) => ProjPointType<bigint>;
|
||||
};
|
||||
};
|
||||
export declare function weierstrass(curveDef: CurveType): CurveFn;
|
||||
/**
|
||||
* Implementation of the Shallue and van de Woestijne method for any weierstrass curve.
|
||||
* TODO: check if there is a way to merge this with uvRatio in Edwards; move to modular.
|
||||
* b = True and y = sqrt(u / v) if (u / v) is square in F, and
|
||||
* b = False and y = sqrt(Z * (u / v)) otherwise.
|
||||
* @param Fp
|
||||
* @param Z
|
||||
* @returns
|
||||
*/
|
||||
export declare function SWUFpSqrtRatio<T>(Fp: mod.IField<T>, Z: T): (u: T, v: T) => {
|
||||
isValid: boolean;
|
||||
value: T;
|
||||
};
|
||||
/**
|
||||
* From draft-irtf-cfrg-hash-to-curve-16
|
||||
*/
|
||||
export declare function mapToCurveSimpleSWU<T>(Fp: mod.IField<T>, opts: {
|
||||
A: T;
|
||||
B: T;
|
||||
Z: T;
|
||||
}): (u: T) => {
|
||||
x: T;
|
||||
y: T;
|
||||
};
|
||||
//# sourceMappingURL=weierstrass.d.ts.map
|
||||
1
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/weierstrass.d.ts.map
generated
vendored
Normal file
1
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/weierstrass.d.ts.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
1061
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/weierstrass.js
generated
vendored
Normal file
1061
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/weierstrass.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/weierstrass.js.map
generated
vendored
Normal file
1
node_modules/@scure/bip32/node_modules/@noble/curves/abstract/weierstrass.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
68
node_modules/@scure/bip32/node_modules/@noble/curves/bls12-381.d.ts
generated
vendored
Normal file
68
node_modules/@scure/bip32/node_modules/@noble/curves/bls12-381.d.ts
generated
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||
import { CurveFn } from './abstract/bls.js';
|
||||
import * as mod from './abstract/modular.js';
|
||||
declare const Fp: Readonly<mod.IField<bigint> & Required<Pick<mod.IField<bigint>, "isOdd">>>;
|
||||
type Fp = bigint;
|
||||
type BigintTuple = [bigint, bigint];
|
||||
type Fp2 = {
|
||||
c0: bigint;
|
||||
c1: bigint;
|
||||
};
|
||||
type Fp2Utils = {
|
||||
fromBigTuple: (tuple: BigintTuple | bigint[]) => Fp2;
|
||||
reim: (num: Fp2) => {
|
||||
re: bigint;
|
||||
im: bigint;
|
||||
};
|
||||
mulByNonresidue: (num: Fp2) => Fp2;
|
||||
multiplyByB: (num: Fp2) => Fp2;
|
||||
frobeniusMap(num: Fp2, power: number): Fp2;
|
||||
};
|
||||
declare const Fp2: mod.IField<Fp2> & Fp2Utils;
|
||||
type BigintSix = [bigint, bigint, bigint, bigint, bigint, bigint];
|
||||
type Fp6 = {
|
||||
c0: Fp2;
|
||||
c1: Fp2;
|
||||
c2: Fp2;
|
||||
};
|
||||
type Fp6Utils = {
|
||||
fromBigSix: (tuple: BigintSix) => Fp6;
|
||||
mulByNonresidue: (num: Fp6) => Fp6;
|
||||
frobeniusMap(num: Fp6, power: number): Fp6;
|
||||
multiplyBy1(num: Fp6, b1: Fp2): Fp6;
|
||||
multiplyBy01(num: Fp6, b0: Fp2, b1: Fp2): Fp6;
|
||||
multiplyByFp2(lhs: Fp6, rhs: Fp2): Fp6;
|
||||
};
|
||||
declare const Fp6: mod.IField<Fp6> & Fp6Utils;
|
||||
type Fp12 = {
|
||||
c0: Fp6;
|
||||
c1: Fp6;
|
||||
};
|
||||
type BigintTwelve = [
|
||||
bigint,
|
||||
bigint,
|
||||
bigint,
|
||||
bigint,
|
||||
bigint,
|
||||
bigint,
|
||||
bigint,
|
||||
bigint,
|
||||
bigint,
|
||||
bigint,
|
||||
bigint,
|
||||
bigint
|
||||
];
|
||||
type Fp12Utils = {
|
||||
fromBigTwelve: (t: BigintTwelve) => Fp12;
|
||||
frobeniusMap(num: Fp12, power: number): Fp12;
|
||||
multiplyBy014(num: Fp12, o0: Fp2, o1: Fp2, o4: Fp2): Fp12;
|
||||
multiplyByFp2(lhs: Fp12, rhs: Fp2): Fp12;
|
||||
conjugate(num: Fp12): Fp12;
|
||||
finalExponentiate(num: Fp12): Fp12;
|
||||
_cyclotomicSquare(num: Fp12): Fp12;
|
||||
_cyclotomicExp(num: Fp12, n: bigint): Fp12;
|
||||
};
|
||||
declare const Fp12: mod.IField<Fp12> & Fp12Utils;
|
||||
export declare const bls12_381: CurveFn<Fp, Fp2, Fp6, Fp12>;
|
||||
export {};
|
||||
//# sourceMappingURL=bls12-381.d.ts.map
|
||||
1
node_modules/@scure/bip32/node_modules/@noble/curves/bls12-381.d.ts.map
generated
vendored
Normal file
1
node_modules/@scure/bip32/node_modules/@noble/curves/bls12-381.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"bls12-381.d.ts","sourceRoot":"","sources":["src/bls12-381.ts"],"names":[],"mappings":"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"}
|
||||
1176
node_modules/@scure/bip32/node_modules/@noble/curves/bls12-381.js
generated
vendored
Normal file
1176
node_modules/@scure/bip32/node_modules/@noble/curves/bls12-381.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
node_modules/@scure/bip32/node_modules/@noble/curves/bls12-381.js.map
generated
vendored
Normal file
1
node_modules/@scure/bip32/node_modules/@noble/curves/bls12-381.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
8
node_modules/@scure/bip32/node_modules/@noble/curves/bn254.d.ts
generated
vendored
Normal file
8
node_modules/@scure/bip32/node_modules/@noble/curves/bn254.d.ts
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* bn254 pairing-friendly curve.
|
||||
* Previously known as alt_bn_128, when it had 128-bit security.
|
||||
* Recent research shown it's weaker, the naming has been adjusted to its prime bit count.
|
||||
* https://github.com/zcash/zcash/issues/2502
|
||||
*/
|
||||
export declare const bn254: import("./abstract/weierstrass.js").CurveFn;
|
||||
//# sourceMappingURL=bn254.d.ts.map
|
||||
1
node_modules/@scure/bip32/node_modules/@noble/curves/bn254.d.ts.map
generated
vendored
Normal file
1
node_modules/@scure/bip32/node_modules/@noble/curves/bn254.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"bn254.d.ts","sourceRoot":"","sources":["src/bn254.ts"],"names":[],"mappings":"AAKA;;;;;GAKG;AACH,eAAO,MAAM,KAAK,6CAShB,CAAC"}
|
||||
25
node_modules/@scure/bip32/node_modules/@noble/curves/bn254.js
generated
vendored
Normal file
25
node_modules/@scure/bip32/node_modules/@noble/curves/bn254.js
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.bn254 = void 0;
|
||||
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||
const sha256_1 = require("@noble/hashes/sha256");
|
||||
const weierstrass_js_1 = require("./abstract/weierstrass.js");
|
||||
const _shortw_utils_js_1 = require("./_shortw_utils.js");
|
||||
const modular_js_1 = require("./abstract/modular.js");
|
||||
/**
|
||||
* bn254 pairing-friendly curve.
|
||||
* Previously known as alt_bn_128, when it had 128-bit security.
|
||||
* Recent research shown it's weaker, the naming has been adjusted to its prime bit count.
|
||||
* https://github.com/zcash/zcash/issues/2502
|
||||
*/
|
||||
exports.bn254 = (0, weierstrass_js_1.weierstrass)({
|
||||
a: BigInt(0),
|
||||
b: BigInt(3),
|
||||
Fp: (0, modular_js_1.Field)(BigInt('0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47')),
|
||||
n: BigInt('0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001'),
|
||||
Gx: BigInt(1),
|
||||
Gy: BigInt(2),
|
||||
h: BigInt(1),
|
||||
...(0, _shortw_utils_js_1.getHash)(sha256_1.sha256),
|
||||
});
|
||||
//# sourceMappingURL=bn254.js.map
|
||||
1
node_modules/@scure/bip32/node_modules/@noble/curves/bn254.js.map
generated
vendored
Normal file
1
node_modules/@scure/bip32/node_modules/@noble/curves/bn254.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"bn254.js","sourceRoot":"","sources":["src/bn254.ts"],"names":[],"mappings":";;;AAAA,sEAAsE;AACtE,iDAA8C;AAC9C,8DAAwD;AACxD,yDAA6C;AAC7C,sDAA8C;AAC9C;;;;;GAKG;AACU,QAAA,KAAK,GAAG,IAAA,4BAAW,EAAC;IAC/B,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;IACZ,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;IACZ,EAAE,EAAE,IAAA,kBAAK,EAAC,MAAM,CAAC,oEAAoE,CAAC,CAAC;IACvF,CAAC,EAAE,MAAM,CAAC,oEAAoE,CAAC;IAC/E,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC;IACb,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC;IACb,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;IACZ,GAAG,IAAA,0BAAO,EAAC,eAAM,CAAC;CACnB,CAAC,CAAC"}
|
||||
75
node_modules/@scure/bip32/node_modules/@noble/curves/ed25519.d.ts
generated
vendored
Normal file
75
node_modules/@scure/bip32/node_modules/@noble/curves/ed25519.d.ts
generated
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
import { ExtPointType } from './abstract/edwards.js';
|
||||
import { Hex } from './abstract/utils.js';
|
||||
import { htfBasicOpts } from './abstract/hash-to-curve.js';
|
||||
import { AffinePoint } from './abstract/curve.js';
|
||||
export declare const ED25519_TORSION_SUBGROUP: string[];
|
||||
export declare const ed25519: import("./abstract/edwards.js").CurveFn;
|
||||
export declare const ed25519ctx: import("./abstract/edwards.js").CurveFn;
|
||||
export declare const ed25519ph: import("./abstract/edwards.js").CurveFn;
|
||||
export declare const x25519: import("./abstract/montgomery.js").CurveFn;
|
||||
/**
|
||||
* Converts ed25519 public key to x25519 public key. Uses formula:
|
||||
* * `(u, v) = ((1+y)/(1-y), sqrt(-486664)*u/x)`
|
||||
* * `(x, y) = (sqrt(-486664)*u/v, (u-1)/(u+1))`
|
||||
* @example
|
||||
* const someonesPub = ed25519.getPublicKey(ed25519.utils.randomPrivateKey());
|
||||
* const aPriv = x25519.utils.randomPrivateKey();
|
||||
* x25519.getSharedSecret(aPriv, edwardsToMontgomeryPub(someonesPub))
|
||||
*/
|
||||
export declare function edwardsToMontgomeryPub(edwardsPub: Hex): Uint8Array;
|
||||
export declare const edwardsToMontgomery: typeof edwardsToMontgomeryPub;
|
||||
/**
|
||||
* Converts ed25519 secret key to x25519 secret key.
|
||||
* @example
|
||||
* const someonesPub = x25519.getPublicKey(x25519.utils.randomPrivateKey());
|
||||
* const aPriv = ed25519.utils.randomPrivateKey();
|
||||
* x25519.getSharedSecret(edwardsToMontgomeryPriv(aPriv), someonesPub)
|
||||
*/
|
||||
export declare function edwardsToMontgomeryPriv(edwardsPriv: Uint8Array): Uint8Array;
|
||||
export declare const hashToCurve: (msg: Uint8Array, options?: htfBasicOpts | undefined) => import("./abstract/hash-to-curve.js").H2CPoint<bigint>;
|
||||
export declare const encodeToCurve: (msg: Uint8Array, options?: htfBasicOpts | undefined) => import("./abstract/hash-to-curve.js").H2CPoint<bigint>;
|
||||
type ExtendedPoint = ExtPointType;
|
||||
/**
|
||||
* Each ed25519/ExtendedPoint has 8 different equivalent points. This can be
|
||||
* a source of bugs for protocols like ring signatures. Ristretto was created to solve this.
|
||||
* Ristretto point operates in X:Y:Z:T extended coordinates like ExtendedPoint,
|
||||
* but it should work in its own namespace: do not combine those two.
|
||||
* https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-ristretto255-decaf448
|
||||
*/
|
||||
declare class RistPoint {
|
||||
private readonly ep;
|
||||
static BASE: RistPoint;
|
||||
static ZERO: RistPoint;
|
||||
constructor(ep: ExtendedPoint);
|
||||
static fromAffine(ap: AffinePoint<bigint>): RistPoint;
|
||||
/**
|
||||
* Takes uniform output of 64-byte hash function like sha512 and converts it to `RistrettoPoint`.
|
||||
* The hash-to-group operation applies Elligator twice and adds the results.
|
||||
* **Note:** this is one-way map, there is no conversion from point to hash.
|
||||
* https://ristretto.group/formulas/elligator.html
|
||||
* @param hex 64-byte output of a hash function
|
||||
*/
|
||||
static hashToCurve(hex: Hex): RistPoint;
|
||||
/**
|
||||
* Converts ristretto-encoded string to ristretto point.
|
||||
* https://ristretto.group/formulas/decoding.html
|
||||
* @param hex Ristretto-encoded 32 bytes. Not every 32-byte string is valid ristretto encoding
|
||||
*/
|
||||
static fromHex(hex: Hex): RistPoint;
|
||||
/**
|
||||
* Encodes ristretto point to Uint8Array.
|
||||
* https://ristretto.group/formulas/encoding.html
|
||||
*/
|
||||
toRawBytes(): Uint8Array;
|
||||
toHex(): string;
|
||||
toString(): string;
|
||||
equals(other: RistPoint): boolean;
|
||||
add(other: RistPoint): RistPoint;
|
||||
subtract(other: RistPoint): RistPoint;
|
||||
multiply(scalar: bigint): RistPoint;
|
||||
multiplyUnsafe(scalar: bigint): RistPoint;
|
||||
}
|
||||
export declare const RistrettoPoint: typeof RistPoint;
|
||||
export declare const hash_to_ristretto255: (msg: Uint8Array, options: htfBasicOpts) => RistPoint;
|
||||
export {};
|
||||
//# sourceMappingURL=ed25519.d.ts.map
|
||||
1
node_modules/@scure/bip32/node_modules/@noble/curves/ed25519.d.ts.map
generated
vendored
Normal file
1
node_modules/@scure/bip32/node_modules/@noble/curves/ed25519.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"ed25519.d.ts","sourceRoot":"","sources":["src/ed25519.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAkB,MAAM,uBAAuB,CAAC;AAGrE,OAAO,EAKL,GAAG,EAEJ,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAgB,YAAY,EAAsB,MAAM,6BAA6B,CAAC;AAC7F,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAwElD,eAAO,MAAM,wBAAwB,UASpC,CAAC;AA6BF,eAAO,MAAM,OAAO,yCAAkC,CAAC;AAYvD,eAAO,MAAM,UAAU,yCAAiE,CAAC;AACzF,eAAO,MAAM,SAAS,yCAIpB,CAAC;AAEH,eAAO,MAAM,MAAM,4CAeZ,CAAC;AAER;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,GAAG,GAAG,UAAU,CAIlE;AACD,eAAO,MAAM,mBAAmB,+BAAyB,CAAC;AAE1D;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,UAAU,GAAG,UAAU,CAG3E;AA0FD,eAAO,MAAM,WAAW,iHAA4C,CAAC;AACrE,eAAO,MAAM,aAAa,iHAA8C,CAAC;AA+BzE,KAAK,aAAa,GAAG,YAAY,CAAC;AA0BlC;;;;;;GAMG;AACH,cAAM,SAAS;IAKD,OAAO,CAAC,QAAQ,CAAC,EAAE;IAJ/B,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC;IACvB,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC;gBAGM,EAAE,EAAE,aAAa;IAE9C,MAAM,CAAC,UAAU,CAAC,EAAE,EAAE,WAAW,CAAC,MAAM,CAAC;IAIzC;;;;;;OAMG;IACH,MAAM,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,GAAG,SAAS;IASvC;;;;OAIG;IACH,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,GAAG,SAAS;IA2BnC;;;OAGG;IACH,UAAU,IAAI,UAAU;IA4BxB,KAAK,IAAI,MAAM;IAIf,QAAQ,IAAI,MAAM;IAKlB,MAAM,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO;IAWjC,GAAG,CAAC,KAAK,EAAE,SAAS,GAAG,SAAS;IAKhC,QAAQ,CAAC,KAAK,EAAE,SAAS,GAAG,SAAS;IAKrC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS;IAInC,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS;CAG1C;AACD,eAAO,MAAM,cAAc,kBAIvB,CAAC;AAIL,eAAO,MAAM,oBAAoB,QAAS,UAAU,WAAW,YAAY,cAM1E,CAAC"}
|
||||
436
node_modules/@scure/bip32/node_modules/@noble/curves/ed25519.js
generated
vendored
Normal file
436
node_modules/@scure/bip32/node_modules/@noble/curves/ed25519.js
generated
vendored
Normal file
@@ -0,0 +1,436 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.hash_to_ristretto255 = exports.RistrettoPoint = exports.encodeToCurve = exports.hashToCurve = exports.edwardsToMontgomeryPriv = exports.edwardsToMontgomery = exports.edwardsToMontgomeryPub = exports.x25519 = exports.ed25519ph = exports.ed25519ctx = exports.ed25519 = exports.ED25519_TORSION_SUBGROUP = void 0;
|
||||
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||
const sha512_1 = require("@noble/hashes/sha512");
|
||||
const utils_1 = require("@noble/hashes/utils");
|
||||
const edwards_js_1 = require("./abstract/edwards.js");
|
||||
const montgomery_js_1 = require("./abstract/montgomery.js");
|
||||
const modular_js_1 = require("./abstract/modular.js");
|
||||
const utils_js_1 = require("./abstract/utils.js");
|
||||
const hash_to_curve_js_1 = require("./abstract/hash-to-curve.js");
|
||||
/**
|
||||
* ed25519 Twisted Edwards curve with following addons:
|
||||
* - X25519 ECDH
|
||||
* - Ristretto cofactor elimination
|
||||
* - Elligator hash-to-group / point indistinguishability
|
||||
*/
|
||||
const ED25519_P = BigInt('57896044618658097711785492504343953926634992332820282019728792003956564819949');
|
||||
// √(-1) aka √(a) aka 2^((p-1)/4)
|
||||
const ED25519_SQRT_M1 = BigInt('19681161376707505956807079304988542015446066515923890162744021073123829784752');
|
||||
// prettier-ignore
|
||||
const _0n = BigInt(0), _1n = BigInt(1), _2n = BigInt(2), _5n = BigInt(5);
|
||||
// prettier-ignore
|
||||
const _10n = BigInt(10), _20n = BigInt(20), _40n = BigInt(40), _80n = BigInt(80);
|
||||
function ed25519_pow_2_252_3(x) {
|
||||
const P = ED25519_P;
|
||||
const x2 = (x * x) % P;
|
||||
const b2 = (x2 * x) % P; // x^3, 11
|
||||
const b4 = ((0, modular_js_1.pow2)(b2, _2n, P) * b2) % P; // x^15, 1111
|
||||
const b5 = ((0, modular_js_1.pow2)(b4, _1n, P) * x) % P; // x^31
|
||||
const b10 = ((0, modular_js_1.pow2)(b5, _5n, P) * b5) % P;
|
||||
const b20 = ((0, modular_js_1.pow2)(b10, _10n, P) * b10) % P;
|
||||
const b40 = ((0, modular_js_1.pow2)(b20, _20n, P) * b20) % P;
|
||||
const b80 = ((0, modular_js_1.pow2)(b40, _40n, P) * b40) % P;
|
||||
const b160 = ((0, modular_js_1.pow2)(b80, _80n, P) * b80) % P;
|
||||
const b240 = ((0, modular_js_1.pow2)(b160, _80n, P) * b80) % P;
|
||||
const b250 = ((0, modular_js_1.pow2)(b240, _10n, P) * b10) % P;
|
||||
const pow_p_5_8 = ((0, modular_js_1.pow2)(b250, _2n, P) * x) % P;
|
||||
// ^ To pow to (p+3)/8, multiply it by x.
|
||||
return { pow_p_5_8, b2 };
|
||||
}
|
||||
function adjustScalarBytes(bytes) {
|
||||
// Section 5: For X25519, in order to decode 32 random bytes as an integer scalar,
|
||||
// set the three least significant bits of the first byte
|
||||
bytes[0] &= 248; // 0b1111_1000
|
||||
// and the most significant bit of the last to zero,
|
||||
bytes[31] &= 127; // 0b0111_1111
|
||||
// set the second most significant bit of the last byte to 1
|
||||
bytes[31] |= 64; // 0b0100_0000
|
||||
return bytes;
|
||||
}
|
||||
// sqrt(u/v)
|
||||
function uvRatio(u, v) {
|
||||
const P = ED25519_P;
|
||||
const v3 = (0, modular_js_1.mod)(v * v * v, P); // v³
|
||||
const v7 = (0, modular_js_1.mod)(v3 * v3 * v, P); // v⁷
|
||||
// (p+3)/8 and (p-5)/8
|
||||
const pow = ed25519_pow_2_252_3(u * v7).pow_p_5_8;
|
||||
let x = (0, modular_js_1.mod)(u * v3 * pow, P); // (uv³)(uv⁷)^(p-5)/8
|
||||
const vx2 = (0, modular_js_1.mod)(v * x * x, P); // vx²
|
||||
const root1 = x; // First root candidate
|
||||
const root2 = (0, modular_js_1.mod)(x * ED25519_SQRT_M1, P); // Second root candidate
|
||||
const useRoot1 = vx2 === u; // If vx² = u (mod p), x is a square root
|
||||
const useRoot2 = vx2 === (0, modular_js_1.mod)(-u, P); // If vx² = -u, set x <-- x * 2^((p-1)/4)
|
||||
const noRoot = vx2 === (0, modular_js_1.mod)(-u * ED25519_SQRT_M1, P); // There is no valid root, vx² = -u√(-1)
|
||||
if (useRoot1)
|
||||
x = root1;
|
||||
if (useRoot2 || noRoot)
|
||||
x = root2; // We return root2 anyway, for const-time
|
||||
if ((0, modular_js_1.isNegativeLE)(x, P))
|
||||
x = (0, modular_js_1.mod)(-x, P);
|
||||
return { isValid: useRoot1 || useRoot2, value: x };
|
||||
}
|
||||
// Just in case
|
||||
exports.ED25519_TORSION_SUBGROUP = [
|
||||
'0100000000000000000000000000000000000000000000000000000000000000',
|
||||
'c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac037a',
|
||||
'0000000000000000000000000000000000000000000000000000000000000080',
|
||||
'26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc05',
|
||||
'ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f',
|
||||
'26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc85',
|
||||
'0000000000000000000000000000000000000000000000000000000000000000',
|
||||
'c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac03fa',
|
||||
];
|
||||
const Fp = (0, modular_js_1.Field)(ED25519_P, undefined, true);
|
||||
const ed25519Defaults = {
|
||||
// Param: a
|
||||
a: BigInt(-1),
|
||||
// d is equal to -121665/121666 over finite field.
|
||||
// Negative number is P - number, and division is invert(number, P)
|
||||
d: BigInt('37095705934669439343138083508754565189542113879843219016388785533085940283555'),
|
||||
// Finite field 𝔽p over which we'll do calculations; 2n**255n - 19n
|
||||
Fp,
|
||||
// Subgroup order: how many points curve has
|
||||
// 2n**252n + 27742317777372353535851937790883648493n;
|
||||
n: BigInt('7237005577332262213973186563042994240857116359379907606001950938285454250989'),
|
||||
// Cofactor
|
||||
h: BigInt(8),
|
||||
// Base point (x, y) aka generator point
|
||||
Gx: BigInt('15112221349535400772501151409588531511454012693041857206046113283949847762202'),
|
||||
Gy: BigInt('46316835694926478169428394003475163141307993866256225615783033603165251855960'),
|
||||
hash: sha512_1.sha512,
|
||||
randomBytes: utils_1.randomBytes,
|
||||
adjustScalarBytes,
|
||||
// dom2
|
||||
// Ratio of u to v. Allows us to combine inversion and square root. Uses algo from RFC8032 5.1.3.
|
||||
// Constant-time, u/√v
|
||||
uvRatio,
|
||||
};
|
||||
exports.ed25519 = (0, edwards_js_1.twistedEdwards)(ed25519Defaults);
|
||||
function ed25519_domain(data, ctx, phflag) {
|
||||
if (ctx.length > 255)
|
||||
throw new Error('Context is too big');
|
||||
return (0, utils_1.concatBytes)((0, utils_1.utf8ToBytes)('SigEd25519 no Ed25519 collisions'), new Uint8Array([phflag ? 1 : 0, ctx.length]), ctx, data);
|
||||
}
|
||||
exports.ed25519ctx = (0, edwards_js_1.twistedEdwards)({ ...ed25519Defaults, domain: ed25519_domain });
|
||||
exports.ed25519ph = (0, edwards_js_1.twistedEdwards)({
|
||||
...ed25519Defaults,
|
||||
domain: ed25519_domain,
|
||||
prehash: sha512_1.sha512,
|
||||
});
|
||||
exports.x25519 = (() => (0, montgomery_js_1.montgomery)({
|
||||
P: ED25519_P,
|
||||
a: BigInt(486662),
|
||||
montgomeryBits: 255,
|
||||
nByteLength: 32,
|
||||
Gu: BigInt(9),
|
||||
powPminus2: (x) => {
|
||||
const P = ED25519_P;
|
||||
// x^(p-2) aka x^(2^255-21)
|
||||
const { pow_p_5_8, b2 } = ed25519_pow_2_252_3(x);
|
||||
return (0, modular_js_1.mod)((0, modular_js_1.pow2)(pow_p_5_8, BigInt(3), P) * b2, P);
|
||||
},
|
||||
adjustScalarBytes,
|
||||
randomBytes: utils_1.randomBytes,
|
||||
}))();
|
||||
/**
|
||||
* Converts ed25519 public key to x25519 public key. Uses formula:
|
||||
* * `(u, v) = ((1+y)/(1-y), sqrt(-486664)*u/x)`
|
||||
* * `(x, y) = (sqrt(-486664)*u/v, (u-1)/(u+1))`
|
||||
* @example
|
||||
* const someonesPub = ed25519.getPublicKey(ed25519.utils.randomPrivateKey());
|
||||
* const aPriv = x25519.utils.randomPrivateKey();
|
||||
* x25519.getSharedSecret(aPriv, edwardsToMontgomeryPub(someonesPub))
|
||||
*/
|
||||
function edwardsToMontgomeryPub(edwardsPub) {
|
||||
const { y } = exports.ed25519.ExtendedPoint.fromHex(edwardsPub);
|
||||
const _1n = BigInt(1);
|
||||
return Fp.toBytes(Fp.create((_1n + y) * Fp.inv(_1n - y)));
|
||||
}
|
||||
exports.edwardsToMontgomeryPub = edwardsToMontgomeryPub;
|
||||
exports.edwardsToMontgomery = edwardsToMontgomeryPub; // deprecated
|
||||
/**
|
||||
* Converts ed25519 secret key to x25519 secret key.
|
||||
* @example
|
||||
* const someonesPub = x25519.getPublicKey(x25519.utils.randomPrivateKey());
|
||||
* const aPriv = ed25519.utils.randomPrivateKey();
|
||||
* x25519.getSharedSecret(edwardsToMontgomeryPriv(aPriv), someonesPub)
|
||||
*/
|
||||
function edwardsToMontgomeryPriv(edwardsPriv) {
|
||||
const hashed = ed25519Defaults.hash(edwardsPriv.subarray(0, 32));
|
||||
return ed25519Defaults.adjustScalarBytes(hashed).subarray(0, 32);
|
||||
}
|
||||
exports.edwardsToMontgomeryPriv = edwardsToMontgomeryPriv;
|
||||
// Hash To Curve Elligator2 Map (NOTE: different from ristretto255 elligator)
|
||||
// NOTE: very important part is usage of FpSqrtEven for ELL2_C1_EDWARDS, since
|
||||
// SageMath returns different root first and everything falls apart
|
||||
const ELL2_C1 = (Fp.ORDER + BigInt(3)) / BigInt(8); // 1. c1 = (q + 3) / 8 # Integer arithmetic
|
||||
const ELL2_C2 = Fp.pow(_2n, ELL2_C1); // 2. c2 = 2^c1
|
||||
const ELL2_C3 = Fp.sqrt(Fp.neg(Fp.ONE)); // 3. c3 = sqrt(-1)
|
||||
const ELL2_C4 = (Fp.ORDER - BigInt(5)) / BigInt(8); // 4. c4 = (q - 5) / 8 # Integer arithmetic
|
||||
const ELL2_J = BigInt(486662);
|
||||
// prettier-ignore
|
||||
function map_to_curve_elligator2_curve25519(u) {
|
||||
let tv1 = Fp.sqr(u); // 1. tv1 = u^2
|
||||
tv1 = Fp.mul(tv1, _2n); // 2. tv1 = 2 * tv1
|
||||
let xd = Fp.add(tv1, Fp.ONE); // 3. xd = tv1 + 1 # Nonzero: -1 is square (mod p), tv1 is not
|
||||
let x1n = Fp.neg(ELL2_J); // 4. x1n = -J # x1 = x1n / xd = -J / (1 + 2 * u^2)
|
||||
let tv2 = Fp.sqr(xd); // 5. tv2 = xd^2
|
||||
let gxd = Fp.mul(tv2, xd); // 6. gxd = tv2 * xd # gxd = xd^3
|
||||
let gx1 = Fp.mul(tv1, ELL2_J); // 7. gx1 = J * tv1 # x1n + J * xd
|
||||
gx1 = Fp.mul(gx1, x1n); // 8. gx1 = gx1 * x1n # x1n^2 + J * x1n * xd
|
||||
gx1 = Fp.add(gx1, tv2); // 9. gx1 = gx1 + tv2 # x1n^2 + J * x1n * xd + xd^2
|
||||
gx1 = Fp.mul(gx1, x1n); // 10. gx1 = gx1 * x1n # x1n^3 + J * x1n^2 * xd + x1n * xd^2
|
||||
let tv3 = Fp.sqr(gxd); // 11. tv3 = gxd^2
|
||||
tv2 = Fp.sqr(tv3); // 12. tv2 = tv3^2 # gxd^4
|
||||
tv3 = Fp.mul(tv3, gxd); // 13. tv3 = tv3 * gxd # gxd^3
|
||||
tv3 = Fp.mul(tv3, gx1); // 14. tv3 = tv3 * gx1 # gx1 * gxd^3
|
||||
tv2 = Fp.mul(tv2, tv3); // 15. tv2 = tv2 * tv3 # gx1 * gxd^7
|
||||
let y11 = Fp.pow(tv2, ELL2_C4); // 16. y11 = tv2^c4 # (gx1 * gxd^7)^((p - 5) / 8)
|
||||
y11 = Fp.mul(y11, tv3); // 17. y11 = y11 * tv3 # gx1*gxd^3*(gx1*gxd^7)^((p-5)/8)
|
||||
let y12 = Fp.mul(y11, ELL2_C3); // 18. y12 = y11 * c3
|
||||
tv2 = Fp.sqr(y11); // 19. tv2 = y11^2
|
||||
tv2 = Fp.mul(tv2, gxd); // 20. tv2 = tv2 * gxd
|
||||
let e1 = Fp.eql(tv2, gx1); // 21. e1 = tv2 == gx1
|
||||
let y1 = Fp.cmov(y12, y11, e1); // 22. y1 = CMOV(y12, y11, e1) # If g(x1) is square, this is its sqrt
|
||||
let x2n = Fp.mul(x1n, tv1); // 23. x2n = x1n * tv1 # x2 = x2n / xd = 2 * u^2 * x1n / xd
|
||||
let y21 = Fp.mul(y11, u); // 24. y21 = y11 * u
|
||||
y21 = Fp.mul(y21, ELL2_C2); // 25. y21 = y21 * c2
|
||||
let y22 = Fp.mul(y21, ELL2_C3); // 26. y22 = y21 * c3
|
||||
let gx2 = Fp.mul(gx1, tv1); // 27. gx2 = gx1 * tv1 # g(x2) = gx2 / gxd = 2 * u^2 * g(x1)
|
||||
tv2 = Fp.sqr(y21); // 28. tv2 = y21^2
|
||||
tv2 = Fp.mul(tv2, gxd); // 29. tv2 = tv2 * gxd
|
||||
let e2 = Fp.eql(tv2, gx2); // 30. e2 = tv2 == gx2
|
||||
let y2 = Fp.cmov(y22, y21, e2); // 31. y2 = CMOV(y22, y21, e2) # If g(x2) is square, this is its sqrt
|
||||
tv2 = Fp.sqr(y1); // 32. tv2 = y1^2
|
||||
tv2 = Fp.mul(tv2, gxd); // 33. tv2 = tv2 * gxd
|
||||
let e3 = Fp.eql(tv2, gx1); // 34. e3 = tv2 == gx1
|
||||
let xn = Fp.cmov(x2n, x1n, e3); // 35. xn = CMOV(x2n, x1n, e3) # If e3, x = x1, else x = x2
|
||||
let y = Fp.cmov(y2, y1, e3); // 36. y = CMOV(y2, y1, e3) # If e3, y = y1, else y = y2
|
||||
let e4 = Fp.isOdd(y); // 37. e4 = sgn0(y) == 1 # Fix sign of y
|
||||
y = Fp.cmov(y, Fp.neg(y), e3 !== e4); // 38. y = CMOV(y, -y, e3 XOR e4)
|
||||
return { xMn: xn, xMd: xd, yMn: y, yMd: _1n }; // 39. return (xn, xd, y, 1)
|
||||
}
|
||||
const ELL2_C1_EDWARDS = (0, modular_js_1.FpSqrtEven)(Fp, Fp.neg(BigInt(486664))); // sgn0(c1) MUST equal 0
|
||||
function map_to_curve_elligator2_edwards25519(u) {
|
||||
const { xMn, xMd, yMn, yMd } = map_to_curve_elligator2_curve25519(u); // 1. (xMn, xMd, yMn, yMd) =
|
||||
// map_to_curve_elligator2_curve25519(u)
|
||||
let xn = Fp.mul(xMn, yMd); // 2. xn = xMn * yMd
|
||||
xn = Fp.mul(xn, ELL2_C1_EDWARDS); // 3. xn = xn * c1
|
||||
let xd = Fp.mul(xMd, yMn); // 4. xd = xMd * yMn # xn / xd = c1 * xM / yM
|
||||
let yn = Fp.sub(xMn, xMd); // 5. yn = xMn - xMd
|
||||
let yd = Fp.add(xMn, xMd); // 6. yd = xMn + xMd # (n / d - 1) / (n / d + 1) = (n - d) / (n + d)
|
||||
let tv1 = Fp.mul(xd, yd); // 7. tv1 = xd * yd
|
||||
let e = Fp.eql(tv1, Fp.ZERO); // 8. e = tv1 == 0
|
||||
xn = Fp.cmov(xn, Fp.ZERO, e); // 9. xn = CMOV(xn, 0, e)
|
||||
xd = Fp.cmov(xd, Fp.ONE, e); // 10. xd = CMOV(xd, 1, e)
|
||||
yn = Fp.cmov(yn, Fp.ONE, e); // 11. yn = CMOV(yn, 1, e)
|
||||
yd = Fp.cmov(yd, Fp.ONE, e); // 12. yd = CMOV(yd, 1, e)
|
||||
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 htf = /* @__PURE__ */ (() => (0, hash_to_curve_js_1.createHasher)(exports.ed25519.ExtendedPoint, (scalars) => map_to_curve_elligator2_edwards25519(scalars[0]), {
|
||||
DST: 'edwards25519_XMD:SHA-512_ELL2_RO_',
|
||||
encodeDST: 'edwards25519_XMD:SHA-512_ELL2_NU_',
|
||||
p: Fp.ORDER,
|
||||
m: 1,
|
||||
k: 128,
|
||||
expand: 'xmd',
|
||||
hash: sha512_1.sha512,
|
||||
}))();
|
||||
exports.hashToCurve = (() => htf.hashToCurve)();
|
||||
exports.encodeToCurve = (() => htf.encodeToCurve)();
|
||||
function assertRstPoint(other) {
|
||||
if (!(other instanceof RistPoint))
|
||||
throw new Error('RistrettoPoint expected');
|
||||
}
|
||||
// √(-1) aka √(a) aka 2^((p-1)/4)
|
||||
const SQRT_M1 = ED25519_SQRT_M1;
|
||||
// √(ad - 1)
|
||||
const SQRT_AD_MINUS_ONE = BigInt('25063068953384623474111414158702152701244531502492656460079210482610430750235');
|
||||
// 1 / √(a-d)
|
||||
const INVSQRT_A_MINUS_D = BigInt('54469307008909316920995813868745141605393597292927456921205312896311721017578');
|
||||
// 1-d²
|
||||
const ONE_MINUS_D_SQ = BigInt('1159843021668779879193775521855586647937357759715417654439879720876111806838');
|
||||
// (d-1)²
|
||||
const D_MINUS_ONE_SQ = BigInt('40440834346308536858101042469323190826248399146238708352240133220865137265952');
|
||||
// Calculates 1/√(number)
|
||||
const invertSqrt = (number) => uvRatio(_1n, number);
|
||||
const MAX_255B = BigInt('0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff');
|
||||
const bytes255ToNumberLE = (bytes) => exports.ed25519.CURVE.Fp.create((0, utils_js_1.bytesToNumberLE)(bytes) & MAX_255B);
|
||||
// Computes Elligator map for Ristretto
|
||||
// https://ristretto.group/formulas/elligator.html
|
||||
function calcElligatorRistrettoMap(r0) {
|
||||
const { d } = exports.ed25519.CURVE;
|
||||
const P = exports.ed25519.CURVE.Fp.ORDER;
|
||||
const mod = exports.ed25519.CURVE.Fp.create;
|
||||
const r = mod(SQRT_M1 * r0 * r0); // 1
|
||||
const Ns = mod((r + _1n) * ONE_MINUS_D_SQ); // 2
|
||||
let c = BigInt(-1); // 3
|
||||
const D = mod((c - d * r) * mod(r + d)); // 4
|
||||
let { isValid: Ns_D_is_sq, value: s } = uvRatio(Ns, D); // 5
|
||||
let s_ = mod(s * r0); // 6
|
||||
if (!(0, modular_js_1.isNegativeLE)(s_, P))
|
||||
s_ = mod(-s_);
|
||||
if (!Ns_D_is_sq)
|
||||
s = s_; // 7
|
||||
if (!Ns_D_is_sq)
|
||||
c = r; // 8
|
||||
const Nt = mod(c * (r - _1n) * D_MINUS_ONE_SQ - D); // 9
|
||||
const s2 = s * s;
|
||||
const W0 = mod((s + s) * D); // 10
|
||||
const W1 = mod(Nt * SQRT_AD_MINUS_ONE); // 11
|
||||
const W2 = mod(_1n - s2); // 12
|
||||
const W3 = mod(_1n + s2); // 13
|
||||
return new exports.ed25519.ExtendedPoint(mod(W0 * W3), mod(W2 * W1), mod(W1 * W3), mod(W0 * W2));
|
||||
}
|
||||
/**
|
||||
* Each ed25519/ExtendedPoint has 8 different equivalent points. This can be
|
||||
* a source of bugs for protocols like ring signatures. Ristretto was created to solve this.
|
||||
* Ristretto point operates in X:Y:Z:T extended coordinates like ExtendedPoint,
|
||||
* but it should work in its own namespace: do not combine those two.
|
||||
* https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-ristretto255-decaf448
|
||||
*/
|
||||
class RistPoint {
|
||||
// Private property to discourage combining ExtendedPoint + RistrettoPoint
|
||||
// Always use Ristretto encoding/decoding instead.
|
||||
constructor(ep) {
|
||||
this.ep = ep;
|
||||
}
|
||||
static fromAffine(ap) {
|
||||
return new RistPoint(exports.ed25519.ExtendedPoint.fromAffine(ap));
|
||||
}
|
||||
/**
|
||||
* Takes uniform output of 64-byte hash function like sha512 and converts it to `RistrettoPoint`.
|
||||
* The hash-to-group operation applies Elligator twice and adds the results.
|
||||
* **Note:** this is one-way map, there is no conversion from point to hash.
|
||||
* https://ristretto.group/formulas/elligator.html
|
||||
* @param hex 64-byte output of a hash function
|
||||
*/
|
||||
static hashToCurve(hex) {
|
||||
hex = (0, utils_js_1.ensureBytes)('ristrettoHash', hex, 64);
|
||||
const r1 = bytes255ToNumberLE(hex.slice(0, 32));
|
||||
const R1 = calcElligatorRistrettoMap(r1);
|
||||
const r2 = bytes255ToNumberLE(hex.slice(32, 64));
|
||||
const R2 = calcElligatorRistrettoMap(r2);
|
||||
return new RistPoint(R1.add(R2));
|
||||
}
|
||||
/**
|
||||
* Converts ristretto-encoded string to ristretto point.
|
||||
* https://ristretto.group/formulas/decoding.html
|
||||
* @param hex Ristretto-encoded 32 bytes. Not every 32-byte string is valid ristretto encoding
|
||||
*/
|
||||
static fromHex(hex) {
|
||||
hex = (0, utils_js_1.ensureBytes)('ristrettoHex', hex, 32);
|
||||
const { a, d } = exports.ed25519.CURVE;
|
||||
const P = exports.ed25519.CURVE.Fp.ORDER;
|
||||
const mod = exports.ed25519.CURVE.Fp.create;
|
||||
const emsg = 'RistrettoPoint.fromHex: the hex is not valid encoding of RistrettoPoint';
|
||||
const s = bytes255ToNumberLE(hex);
|
||||
// 1. Check that s_bytes is the canonical encoding of a field element, or else abort.
|
||||
// 3. Check that s is non-negative, or else abort
|
||||
if (!(0, utils_js_1.equalBytes)((0, utils_js_1.numberToBytesLE)(s, 32), hex) || (0, modular_js_1.isNegativeLE)(s, P))
|
||||
throw new Error(emsg);
|
||||
const s2 = mod(s * s);
|
||||
const u1 = mod(_1n + a * s2); // 4 (a is -1)
|
||||
const u2 = mod(_1n - a * s2); // 5
|
||||
const u1_2 = mod(u1 * u1);
|
||||
const u2_2 = mod(u2 * u2);
|
||||
const v = mod(a * d * u1_2 - u2_2); // 6
|
||||
const { isValid, value: I } = invertSqrt(mod(v * u2_2)); // 7
|
||||
const Dx = mod(I * u2); // 8
|
||||
const Dy = mod(I * Dx * v); // 9
|
||||
let x = mod((s + s) * Dx); // 10
|
||||
if ((0, modular_js_1.isNegativeLE)(x, P))
|
||||
x = mod(-x); // 10
|
||||
const y = mod(u1 * Dy); // 11
|
||||
const t = mod(x * y); // 12
|
||||
if (!isValid || (0, modular_js_1.isNegativeLE)(t, P) || y === _0n)
|
||||
throw new Error(emsg);
|
||||
return new RistPoint(new exports.ed25519.ExtendedPoint(x, y, _1n, t));
|
||||
}
|
||||
/**
|
||||
* Encodes ristretto point to Uint8Array.
|
||||
* https://ristretto.group/formulas/encoding.html
|
||||
*/
|
||||
toRawBytes() {
|
||||
let { ex: x, ey: y, ez: z, et: t } = this.ep;
|
||||
const P = exports.ed25519.CURVE.Fp.ORDER;
|
||||
const mod = exports.ed25519.CURVE.Fp.create;
|
||||
const u1 = mod(mod(z + y) * mod(z - y)); // 1
|
||||
const u2 = mod(x * y); // 2
|
||||
// Square root always exists
|
||||
const u2sq = mod(u2 * u2);
|
||||
const { value: invsqrt } = invertSqrt(mod(u1 * u2sq)); // 3
|
||||
const D1 = mod(invsqrt * u1); // 4
|
||||
const D2 = mod(invsqrt * u2); // 5
|
||||
const zInv = mod(D1 * D2 * t); // 6
|
||||
let D; // 7
|
||||
if ((0, modular_js_1.isNegativeLE)(t * zInv, P)) {
|
||||
let _x = mod(y * SQRT_M1);
|
||||
let _y = mod(x * SQRT_M1);
|
||||
x = _x;
|
||||
y = _y;
|
||||
D = mod(D1 * INVSQRT_A_MINUS_D);
|
||||
}
|
||||
else {
|
||||
D = D2; // 8
|
||||
}
|
||||
if ((0, modular_js_1.isNegativeLE)(x * zInv, P))
|
||||
y = mod(-y); // 9
|
||||
let s = mod((z - y) * D); // 10 (check footer's note, no sqrt(-a))
|
||||
if ((0, modular_js_1.isNegativeLE)(s, P))
|
||||
s = mod(-s);
|
||||
return (0, utils_js_1.numberToBytesLE)(s, 32); // 11
|
||||
}
|
||||
toHex() {
|
||||
return (0, utils_js_1.bytesToHex)(this.toRawBytes());
|
||||
}
|
||||
toString() {
|
||||
return this.toHex();
|
||||
}
|
||||
// Compare one point to another.
|
||||
equals(other) {
|
||||
assertRstPoint(other);
|
||||
const { ex: X1, ey: Y1 } = this.ep;
|
||||
const { ex: X2, ey: Y2 } = other.ep;
|
||||
const mod = exports.ed25519.CURVE.Fp.create;
|
||||
// (x1 * y2 == y1 * x2) | (y1 * y2 == x1 * x2)
|
||||
const one = mod(X1 * Y2) === mod(Y1 * X2);
|
||||
const two = mod(Y1 * Y2) === mod(X1 * X2);
|
||||
return one || two;
|
||||
}
|
||||
add(other) {
|
||||
assertRstPoint(other);
|
||||
return new RistPoint(this.ep.add(other.ep));
|
||||
}
|
||||
subtract(other) {
|
||||
assertRstPoint(other);
|
||||
return new RistPoint(this.ep.subtract(other.ep));
|
||||
}
|
||||
multiply(scalar) {
|
||||
return new RistPoint(this.ep.multiply(scalar));
|
||||
}
|
||||
multiplyUnsafe(scalar) {
|
||||
return new RistPoint(this.ep.multiplyUnsafe(scalar));
|
||||
}
|
||||
}
|
||||
exports.RistrettoPoint = (() => {
|
||||
if (!RistPoint.BASE)
|
||||
RistPoint.BASE = new RistPoint(exports.ed25519.ExtendedPoint.BASE);
|
||||
if (!RistPoint.ZERO)
|
||||
RistPoint.ZERO = new RistPoint(exports.ed25519.ExtendedPoint.ZERO);
|
||||
return RistPoint;
|
||||
})();
|
||||
// https://datatracker.ietf.org/doc/draft-irtf-cfrg-hash-to-curve/14/
|
||||
// Appendix B. Hashing to ristretto255
|
||||
const hash_to_ristretto255 = (msg, options) => {
|
||||
const d = options.DST;
|
||||
const DST = typeof d === 'string' ? (0, utils_1.utf8ToBytes)(d) : d;
|
||||
const uniform_bytes = (0, hash_to_curve_js_1.expand_message_xmd)(msg, DST, 64, sha512_1.sha512);
|
||||
const P = RistPoint.hashToCurve(uniform_bytes);
|
||||
return P;
|
||||
};
|
||||
exports.hash_to_ristretto255 = hash_to_ristretto255;
|
||||
//# sourceMappingURL=ed25519.js.map
|
||||
1
node_modules/@scure/bip32/node_modules/@noble/curves/ed25519.js.map
generated
vendored
Normal file
1
node_modules/@scure/bip32/node_modules/@noble/curves/ed25519.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
16
node_modules/@scure/bip32/node_modules/@noble/curves/ed448.d.ts
generated
vendored
Normal file
16
node_modules/@scure/bip32/node_modules/@noble/curves/ed448.d.ts
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
export declare const ed448: import("./abstract/edwards.js").CurveFn;
|
||||
export declare const ed448ph: import("./abstract/edwards.js").CurveFn;
|
||||
export declare const x448: import("./abstract/montgomery.js").CurveFn;
|
||||
/**
|
||||
* Converts edwards448 public key to x448 public key. Uses formula:
|
||||
* * `(u, v) = ((y-1)/(y+1), sqrt(156324)*u/x)`
|
||||
* * `(x, y) = (sqrt(156324)*u/v, (1+u)/(1-u))`
|
||||
* @example
|
||||
* const aPub = ed448.getPublicKey(utils.randomPrivateKey());
|
||||
* x448.getSharedSecret(edwardsToMontgomery(aPub), edwardsToMontgomery(someonesPub))
|
||||
*/
|
||||
export declare function edwardsToMontgomeryPub(edwardsPub: string | Uint8Array): Uint8Array;
|
||||
export declare const edwardsToMontgomery: typeof edwardsToMontgomeryPub;
|
||||
export declare const hashToCurve: (msg: Uint8Array, options?: import("./abstract/hash-to-curve.js").htfBasicOpts | undefined) => import("./abstract/hash-to-curve.js").H2CPoint<bigint>;
|
||||
export declare const encodeToCurve: (msg: Uint8Array, options?: import("./abstract/hash-to-curve.js").htfBasicOpts | undefined) => import("./abstract/hash-to-curve.js").H2CPoint<bigint>;
|
||||
//# sourceMappingURL=ed448.d.ts.map
|
||||
1
node_modules/@scure/bip32/node_modules/@noble/curves/ed448.d.ts.map
generated
vendored
Normal file
1
node_modules/@scure/bip32/node_modules/@noble/curves/ed448.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"ed448.d.ts","sourceRoot":"","sources":["src/ed448.ts"],"names":[],"mappings":"AAwHA,eAAO,MAAM,KAAK,yCAA4B,CAAC;AAE/C,eAAO,MAAM,OAAO,yCAAyD,CAAC;AAE9E,eAAO,MAAM,IAAI,4CAeV,CAAC;AAER;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,MAAM,GAAG,UAAU,GAAG,UAAU,CAIlF;AACD,eAAO,MAAM,mBAAmB,+BAAyB,CAAC;AA2F1D,eAAO,MAAM,WAAW,uJAA4C,CAAC;AACrE,eAAO,MAAM,aAAa,uJAA8C,CAAC"}
|
||||
219
node_modules/@scure/bip32/node_modules/@noble/curves/ed448.js
generated
vendored
Normal file
219
node_modules/@scure/bip32/node_modules/@noble/curves/ed448.js
generated
vendored
Normal file
@@ -0,0 +1,219 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.encodeToCurve = exports.hashToCurve = exports.edwardsToMontgomery = exports.edwardsToMontgomeryPub = exports.x448 = exports.ed448ph = exports.ed448 = void 0;
|
||||
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||
const sha3_1 = require("@noble/hashes/sha3");
|
||||
const utils_1 = require("@noble/hashes/utils");
|
||||
const edwards_js_1 = require("./abstract/edwards.js");
|
||||
const modular_js_1 = require("./abstract/modular.js");
|
||||
const montgomery_js_1 = require("./abstract/montgomery.js");
|
||||
const hash_to_curve_js_1 = require("./abstract/hash-to-curve.js");
|
||||
/**
|
||||
* Edwards448 (not Ed448-Goldilocks) curve with following addons:
|
||||
* * X448 ECDH
|
||||
* Conforms to RFC 8032 https://www.rfc-editor.org/rfc/rfc8032.html#section-5.2
|
||||
*/
|
||||
const shake256_114 = (0, utils_1.wrapConstructor)(() => sha3_1.shake256.create({ dkLen: 114 }));
|
||||
const shake256_64 = (0, utils_1.wrapConstructor)(() => sha3_1.shake256.create({ dkLen: 64 }));
|
||||
const ed448P = BigInt('726838724295606890549323807888004534353641360687318060281490199180612328166730772686396383698676545930088884461843637361053498018365439');
|
||||
// powPminus3div4 calculates z = x^k mod p, where k = (p-3)/4.
|
||||
// Used for efficient square root calculation.
|
||||
// ((P-3)/4).toString(2) would produce bits [223x 1, 0, 222x 1]
|
||||
function ed448_pow_Pminus3div4(x) {
|
||||
const P = ed448P;
|
||||
// prettier-ignore
|
||||
const _1n = BigInt(1), _2n = BigInt(2), _3n = BigInt(3), _11n = BigInt(11);
|
||||
// prettier-ignore
|
||||
const _22n = BigInt(22), _44n = BigInt(44), _88n = BigInt(88), _223n = BigInt(223);
|
||||
const b2 = (x * x * x) % P;
|
||||
const b3 = (b2 * b2 * x) % P;
|
||||
const b6 = ((0, modular_js_1.pow2)(b3, _3n, P) * b3) % P;
|
||||
const b9 = ((0, modular_js_1.pow2)(b6, _3n, P) * b3) % P;
|
||||
const b11 = ((0, modular_js_1.pow2)(b9, _2n, P) * b2) % P;
|
||||
const b22 = ((0, modular_js_1.pow2)(b11, _11n, P) * b11) % P;
|
||||
const b44 = ((0, modular_js_1.pow2)(b22, _22n, P) * b22) % P;
|
||||
const b88 = ((0, modular_js_1.pow2)(b44, _44n, P) * b44) % P;
|
||||
const b176 = ((0, modular_js_1.pow2)(b88, _88n, P) * b88) % P;
|
||||
const b220 = ((0, modular_js_1.pow2)(b176, _44n, P) * b44) % P;
|
||||
const b222 = ((0, modular_js_1.pow2)(b220, _2n, P) * b2) % P;
|
||||
const b223 = ((0, modular_js_1.pow2)(b222, _1n, P) * x) % P;
|
||||
return ((0, modular_js_1.pow2)(b223, _223n, P) * b222) % P;
|
||||
}
|
||||
function adjustScalarBytes(bytes) {
|
||||
// Section 5: Likewise, for X448, set the two least significant bits of the first byte to 0, and the most
|
||||
// significant bit of the last byte to 1.
|
||||
bytes[0] &= 252; // 0b11111100
|
||||
// and the most significant bit of the last byte to 1.
|
||||
bytes[55] |= 128; // 0b10000000
|
||||
// NOTE: is is NOOP for 56 bytes scalars (X25519/X448)
|
||||
bytes[56] = 0; // Byte outside of group (456 buts vs 448 bits)
|
||||
return bytes;
|
||||
}
|
||||
const Fp = (0, modular_js_1.Field)(ed448P, 456, true);
|
||||
const _4n = BigInt(4);
|
||||
const ED448_DEF = {
|
||||
// Param: a
|
||||
a: BigInt(1),
|
||||
// -39081. Negative number is P - number
|
||||
d: BigInt('726838724295606890549323807888004534353641360687318060281490199180612328166730772686396383698676545930088884461843637361053498018326358'),
|
||||
// Finite field 𝔽p over which we'll do calculations; 2n**448n - 2n**224n - 1n
|
||||
Fp,
|
||||
// Subgroup order: how many points curve has;
|
||||
// 2n**446n - 13818066809895115352007386748515426880336692474882178609894547503885n
|
||||
n: BigInt('181709681073901722637330951972001133588410340171829515070372549795146003961539585716195755291692375963310293709091662304773755859649779'),
|
||||
nBitLength: 456,
|
||||
// Cofactor
|
||||
h: BigInt(4),
|
||||
// Base point (x, y) aka generator point
|
||||
Gx: BigInt('224580040295924300187604334099896036246789641632564134246125461686950415467406032909029192869357953282578032075146446173674602635247710'),
|
||||
Gy: BigInt('298819210078481492676017930443930673437544040154080242095928241372331506189835876003536878655418784733982303233503462500531545062832660'),
|
||||
// SHAKE256(dom4(phflag,context)||x, 114)
|
||||
hash: shake256_114,
|
||||
randomBytes: utils_1.randomBytes,
|
||||
adjustScalarBytes,
|
||||
// dom4
|
||||
domain: (data, ctx, phflag) => {
|
||||
if (ctx.length > 255)
|
||||
throw new Error(`Context is too big: ${ctx.length}`);
|
||||
return (0, utils_1.concatBytes)((0, utils_1.utf8ToBytes)('SigEd448'), new Uint8Array([phflag ? 1 : 0, ctx.length]), ctx, data);
|
||||
},
|
||||
// Constant-time ratio of u to v. Allows to combine inversion and square root u/√v.
|
||||
// Uses algo from RFC8032 5.1.3.
|
||||
uvRatio: (u, v) => {
|
||||
const P = ed448P;
|
||||
// https://datatracker.ietf.org/doc/html/rfc8032#section-5.2.3
|
||||
// To compute the square root of (u/v), the first step is to compute the
|
||||
// candidate root x = (u/v)^((p+1)/4). This can be done using the
|
||||
// following trick, to use a single modular powering for both the
|
||||
// inversion of v and the square root:
|
||||
// x = (u/v)^((p+1)/4) = u³v(u⁵v³)^((p-3)/4) (mod p)
|
||||
const u2v = (0, modular_js_1.mod)(u * u * v, P); // u²v
|
||||
const u3v = (0, modular_js_1.mod)(u2v * u, P); // u³v
|
||||
const u5v3 = (0, modular_js_1.mod)(u3v * u2v * v, P); // u⁵v³
|
||||
const root = ed448_pow_Pminus3div4(u5v3);
|
||||
const x = (0, modular_js_1.mod)(u3v * root, P);
|
||||
// Verify that root is exists
|
||||
const x2 = (0, modular_js_1.mod)(x * x, P); // x²
|
||||
// If vx² = u, the recovered x-coordinate is x. Otherwise, no
|
||||
// square root exists, and the decoding fails.
|
||||
return { isValid: (0, modular_js_1.mod)(x2 * v, P) === u, value: x };
|
||||
},
|
||||
};
|
||||
exports.ed448 = (0, edwards_js_1.twistedEdwards)(ED448_DEF);
|
||||
// NOTE: there is no ed448ctx, since ed448 supports ctx by default
|
||||
exports.ed448ph = (0, edwards_js_1.twistedEdwards)({ ...ED448_DEF, prehash: shake256_64 });
|
||||
exports.x448 = (() => (0, montgomery_js_1.montgomery)({
|
||||
a: BigInt(156326),
|
||||
montgomeryBits: 448,
|
||||
nByteLength: 57,
|
||||
P: ed448P,
|
||||
Gu: BigInt(5),
|
||||
powPminus2: (x) => {
|
||||
const P = ed448P;
|
||||
const Pminus3div4 = ed448_pow_Pminus3div4(x);
|
||||
const Pminus3 = (0, modular_js_1.pow2)(Pminus3div4, BigInt(2), P);
|
||||
return (0, modular_js_1.mod)(Pminus3 * x, P); // Pminus3 * x = Pminus2
|
||||
},
|
||||
adjustScalarBytes,
|
||||
randomBytes: utils_1.randomBytes,
|
||||
}))();
|
||||
/**
|
||||
* Converts edwards448 public key to x448 public key. Uses formula:
|
||||
* * `(u, v) = ((y-1)/(y+1), sqrt(156324)*u/x)`
|
||||
* * `(x, y) = (sqrt(156324)*u/v, (1+u)/(1-u))`
|
||||
* @example
|
||||
* const aPub = ed448.getPublicKey(utils.randomPrivateKey());
|
||||
* x448.getSharedSecret(edwardsToMontgomery(aPub), edwardsToMontgomery(someonesPub))
|
||||
*/
|
||||
function edwardsToMontgomeryPub(edwardsPub) {
|
||||
const { y } = exports.ed448.ExtendedPoint.fromHex(edwardsPub);
|
||||
const _1n = BigInt(1);
|
||||
return Fp.toBytes(Fp.create((y - _1n) * Fp.inv(y + _1n)));
|
||||
}
|
||||
exports.edwardsToMontgomeryPub = edwardsToMontgomeryPub;
|
||||
exports.edwardsToMontgomery = edwardsToMontgomeryPub; // deprecated
|
||||
// Hash To Curve Elligator2 Map
|
||||
const ELL2_C1 = (Fp.ORDER - BigInt(3)) / BigInt(4); // 1. c1 = (q - 3) / 4 # Integer arithmetic
|
||||
const ELL2_J = BigInt(156326);
|
||||
function map_to_curve_elligator2_curve448(u) {
|
||||
let tv1 = Fp.sqr(u); // 1. tv1 = u^2
|
||||
let e1 = Fp.eql(tv1, Fp.ONE); // 2. e1 = tv1 == 1
|
||||
tv1 = Fp.cmov(tv1, Fp.ZERO, e1); // 3. tv1 = CMOV(tv1, 0, e1) # If Z * u^2 == -1, set tv1 = 0
|
||||
let xd = Fp.sub(Fp.ONE, tv1); // 4. xd = 1 - tv1
|
||||
let x1n = Fp.neg(ELL2_J); // 5. x1n = -J
|
||||
let tv2 = Fp.sqr(xd); // 6. tv2 = xd^2
|
||||
let gxd = Fp.mul(tv2, xd); // 7. gxd = tv2 * xd # gxd = xd^3
|
||||
let gx1 = Fp.mul(tv1, Fp.neg(ELL2_J)); // 8. gx1 = -J * tv1 # x1n + J * xd
|
||||
gx1 = Fp.mul(gx1, x1n); // 9. gx1 = gx1 * x1n # x1n^2 + J * x1n * xd
|
||||
gx1 = Fp.add(gx1, tv2); // 10. gx1 = gx1 + tv2 # x1n^2 + J * x1n * xd + xd^2
|
||||
gx1 = Fp.mul(gx1, x1n); // 11. gx1 = gx1 * x1n # x1n^3 + J * x1n^2 * xd + x1n * xd^2
|
||||
let tv3 = Fp.sqr(gxd); // 12. tv3 = gxd^2
|
||||
tv2 = Fp.mul(gx1, gxd); // 13. tv2 = gx1 * gxd # gx1 * gxd
|
||||
tv3 = Fp.mul(tv3, tv2); // 14. tv3 = tv3 * tv2 # gx1 * gxd^3
|
||||
let y1 = Fp.pow(tv3, ELL2_C1); // 15. y1 = tv3^c1 # (gx1 * gxd^3)^((p - 3) / 4)
|
||||
y1 = Fp.mul(y1, tv2); // 16. y1 = y1 * tv2 # gx1 * gxd * (gx1 * gxd^3)^((p - 3) / 4)
|
||||
let x2n = Fp.mul(x1n, Fp.neg(tv1)); // 17. x2n = -tv1 * x1n # x2 = x2n / xd = -1 * u^2 * x1n / xd
|
||||
let y2 = Fp.mul(y1, u); // 18. y2 = y1 * u
|
||||
y2 = Fp.cmov(y2, Fp.ZERO, e1); // 19. y2 = CMOV(y2, 0, e1)
|
||||
tv2 = Fp.sqr(y1); // 20. tv2 = y1^2
|
||||
tv2 = Fp.mul(tv2, gxd); // 21. tv2 = tv2 * gxd
|
||||
let e2 = Fp.eql(tv2, gx1); // 22. e2 = tv2 == gx1
|
||||
let xn = Fp.cmov(x2n, x1n, e2); // 23. xn = CMOV(x2n, x1n, e2) # If e2, x = x1, else x = x2
|
||||
let y = Fp.cmov(y2, y1, e2); // 24. y = CMOV(y2, y1, e2) # If e2, y = y1, else y = y2
|
||||
let e3 = Fp.isOdd(y); // 25. e3 = sgn0(y) == 1 # Fix sign of y
|
||||
y = Fp.cmov(y, Fp.neg(y), e2 !== e3); // 26. y = CMOV(y, -y, e2 XOR e3)
|
||||
return { xn, xd, yn: y, yd: Fp.ONE }; // 27. return (xn, xd, y, 1)
|
||||
}
|
||||
function map_to_curve_elligator2_edwards448(u) {
|
||||
let { xn, xd, yn, yd } = map_to_curve_elligator2_curve448(u); // 1. (xn, xd, yn, yd) = map_to_curve_elligator2_curve448(u)
|
||||
let xn2 = Fp.sqr(xn); // 2. xn2 = xn^2
|
||||
let xd2 = Fp.sqr(xd); // 3. xd2 = xd^2
|
||||
let xd4 = Fp.sqr(xd2); // 4. xd4 = xd2^2
|
||||
let yn2 = Fp.sqr(yn); // 5. yn2 = yn^2
|
||||
let yd2 = Fp.sqr(yd); // 6. yd2 = yd^2
|
||||
let xEn = Fp.sub(xn2, xd2); // 7. xEn = xn2 - xd2
|
||||
let tv2 = Fp.sub(xEn, xd2); // 8. tv2 = xEn - xd2
|
||||
xEn = Fp.mul(xEn, xd2); // 9. xEn = xEn * xd2
|
||||
xEn = Fp.mul(xEn, yd); // 10. xEn = xEn * yd
|
||||
xEn = Fp.mul(xEn, yn); // 11. xEn = xEn * yn
|
||||
xEn = Fp.mul(xEn, _4n); // 12. xEn = xEn * 4
|
||||
tv2 = Fp.mul(tv2, xn2); // 13. tv2 = tv2 * xn2
|
||||
tv2 = Fp.mul(tv2, yd2); // 14. tv2 = tv2 * yd2
|
||||
let tv3 = Fp.mul(yn2, _4n); // 15. tv3 = 4 * yn2
|
||||
let tv1 = Fp.add(tv3, yd2); // 16. tv1 = tv3 + yd2
|
||||
tv1 = Fp.mul(tv1, xd4); // 17. tv1 = tv1 * xd4
|
||||
let xEd = Fp.add(tv1, tv2); // 18. xEd = tv1 + tv2
|
||||
tv2 = Fp.mul(tv2, xn); // 19. tv2 = tv2 * xn
|
||||
let tv4 = Fp.mul(xn, xd4); // 20. tv4 = xn * xd4
|
||||
let yEn = Fp.sub(tv3, yd2); // 21. yEn = tv3 - yd2
|
||||
yEn = Fp.mul(yEn, tv4); // 22. yEn = yEn * tv4
|
||||
yEn = Fp.sub(yEn, tv2); // 23. yEn = yEn - tv2
|
||||
tv1 = Fp.add(xn2, xd2); // 24. tv1 = xn2 + xd2
|
||||
tv1 = Fp.mul(tv1, xd2); // 25. tv1 = tv1 * xd2
|
||||
tv1 = Fp.mul(tv1, xd); // 26. tv1 = tv1 * xd
|
||||
tv1 = Fp.mul(tv1, yn2); // 27. tv1 = tv1 * yn2
|
||||
tv1 = Fp.mul(tv1, BigInt(-2)); // 28. tv1 = -2 * tv1
|
||||
let yEd = Fp.add(tv2, tv1); // 29. yEd = tv2 + tv1
|
||||
tv4 = Fp.mul(tv4, yd2); // 30. tv4 = tv4 * yd2
|
||||
yEd = Fp.add(yEd, tv4); // 31. yEd = yEd + tv4
|
||||
tv1 = Fp.mul(xEd, yEd); // 32. tv1 = xEd * yEd
|
||||
let e = Fp.eql(tv1, Fp.ZERO); // 33. e = tv1 == 0
|
||||
xEn = Fp.cmov(xEn, Fp.ZERO, e); // 34. xEn = CMOV(xEn, 0, e)
|
||||
xEd = Fp.cmov(xEd, Fp.ONE, e); // 35. xEd = CMOV(xEd, 1, e)
|
||||
yEn = Fp.cmov(yEn, Fp.ONE, e); // 36. yEn = CMOV(yEn, 1, e)
|
||||
yEd = Fp.cmov(yEd, Fp.ONE, e); // 37. yEd = CMOV(yEd, 1, e)
|
||||
const inv = Fp.invertBatch([xEd, yEd]); // batch division
|
||||
return { x: Fp.mul(xEn, inv[0]), y: Fp.mul(yEn, inv[1]) }; // 38. return (xEn, xEd, yEn, yEd)
|
||||
}
|
||||
const htf = /* @__PURE__ */ (() => (0, hash_to_curve_js_1.createHasher)(exports.ed448.ExtendedPoint, (scalars) => map_to_curve_elligator2_edwards448(scalars[0]), {
|
||||
DST: 'edwards448_XOF:SHAKE256_ELL2_RO_',
|
||||
encodeDST: 'edwards448_XOF:SHAKE256_ELL2_NU_',
|
||||
p: Fp.ORDER,
|
||||
m: 1,
|
||||
k: 224,
|
||||
expand: 'xof',
|
||||
hash: sha3_1.shake256,
|
||||
}))();
|
||||
exports.hashToCurve = (() => htf.hashToCurve)();
|
||||
exports.encodeToCurve = (() => htf.encodeToCurve)();
|
||||
//# sourceMappingURL=ed448.js.map
|
||||
1
node_modules/@scure/bip32/node_modules/@noble/curves/ed448.js.map
generated
vendored
Normal file
1
node_modules/@scure/bip32/node_modules/@noble/curves/ed448.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
17
node_modules/@scure/bip32/node_modules/@noble/curves/esm/_shortw_utils.js
generated
vendored
Normal file
17
node_modules/@scure/bip32/node_modules/@noble/curves/esm/_shortw_utils.js
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||
import { hmac } from '@noble/hashes/hmac';
|
||||
import { concatBytes, randomBytes } from '@noble/hashes/utils';
|
||||
import { weierstrass } from './abstract/weierstrass.js';
|
||||
// connects noble-curves to noble-hashes
|
||||
export function getHash(hash) {
|
||||
return {
|
||||
hash,
|
||||
hmac: (key, ...msgs) => hmac(hash, key, concatBytes(...msgs)),
|
||||
randomBytes,
|
||||
};
|
||||
}
|
||||
export function createCurve(curveDef, defHash) {
|
||||
const create = (hash) => weierstrass({ ...curveDef, ...getHash(hash) });
|
||||
return Object.freeze({ ...create(defHash), create });
|
||||
}
|
||||
//# sourceMappingURL=_shortw_utils.js.map
|
||||
1
node_modules/@scure/bip32/node_modules/@noble/curves/esm/_shortw_utils.js.map
generated
vendored
Normal file
1
node_modules/@scure/bip32/node_modules/@noble/curves/esm/_shortw_utils.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"_shortw_utils.js","sourceRoot":"","sources":["../src/_shortw_utils.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAa,MAAM,2BAA2B,CAAC;AAGnE,wCAAwC;AACxC,MAAM,UAAU,OAAO,CAAC,IAAW;IACjC,OAAO;QACL,IAAI;QACJ,IAAI,EAAE,CAAC,GAAe,EAAE,GAAG,IAAkB,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,WAAW,CAAC,GAAG,IAAI,CAAC,CAAC;QACvF,WAAW;KACZ,CAAC;AACJ,CAAC;AAGD,MAAM,UAAU,WAAW,CAAC,QAAkB,EAAE,OAAc;IAC5D,MAAM,MAAM,GAAG,CAAC,IAAW,EAAE,EAAE,CAAC,WAAW,CAAC,EAAE,GAAG,QAAQ,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC/E,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;AACvD,CAAC"}
|
||||
235
node_modules/@scure/bip32/node_modules/@noble/curves/esm/abstract/bls.js
generated
vendored
Normal file
235
node_modules/@scure/bip32/node_modules/@noble/curves/esm/abstract/bls.js
generated
vendored
Normal file
@@ -0,0 +1,235 @@
|
||||
import { hashToPrivateScalar } from './modular.js';
|
||||
import { bitLen, bitGet, ensureBytes } from './utils.js';
|
||||
import * as htf from './hash-to-curve.js';
|
||||
import { weierstrassPoints, } from './weierstrass.js';
|
||||
// prettier-ignore
|
||||
const _2n = BigInt(2), _3n = BigInt(3);
|
||||
export function bls(CURVE) {
|
||||
// Fields are specific for curve, so for now we'll need to pass them with opts
|
||||
const { Fp, Fr, Fp2, Fp6, Fp12 } = CURVE.fields;
|
||||
const BLS_X_LEN = bitLen(CURVE.params.x);
|
||||
const groupLen = 32; // TODO: calculate; hardcoded for now
|
||||
// Pre-compute coefficients for sparse multiplication
|
||||
// Point addition and point double calculations is reused for coefficients
|
||||
function calcPairingPrecomputes(p) {
|
||||
const { x, y } = p;
|
||||
// prettier-ignore
|
||||
const Qx = x, Qy = y, Qz = Fp2.ONE;
|
||||
// prettier-ignore
|
||||
let Rx = Qx, Ry = Qy, Rz = Qz;
|
||||
let ell_coeff = [];
|
||||
for (let i = BLS_X_LEN - 2; i >= 0; i--) {
|
||||
// Double
|
||||
let t0 = Fp2.sqr(Ry); // Ry²
|
||||
let t1 = Fp2.sqr(Rz); // Rz²
|
||||
let t2 = Fp2.multiplyByB(Fp2.mul(t1, _3n)); // 3 * T1 * B
|
||||
let t3 = Fp2.mul(t2, _3n); // 3 * T2
|
||||
let t4 = Fp2.sub(Fp2.sub(Fp2.sqr(Fp2.add(Ry, Rz)), t1), t0); // (Ry + Rz)² - T1 - T0
|
||||
ell_coeff.push([
|
||||
Fp2.sub(t2, t0),
|
||||
Fp2.mul(Fp2.sqr(Rx), _3n),
|
||||
Fp2.neg(t4), // -T4
|
||||
]);
|
||||
Rx = Fp2.div(Fp2.mul(Fp2.mul(Fp2.sub(t0, t3), Rx), Ry), _2n); // ((T0 - T3) * Rx * Ry) / 2
|
||||
Ry = Fp2.sub(Fp2.sqr(Fp2.div(Fp2.add(t0, t3), _2n)), Fp2.mul(Fp2.sqr(t2), _3n)); // ((T0 + T3) / 2)² - 3 * T2²
|
||||
Rz = Fp2.mul(t0, t4); // T0 * T4
|
||||
if (bitGet(CURVE.params.x, i)) {
|
||||
// Addition
|
||||
let t0 = Fp2.sub(Ry, Fp2.mul(Qy, Rz)); // Ry - Qy * Rz
|
||||
let t1 = Fp2.sub(Rx, Fp2.mul(Qx, Rz)); // Rx - Qx * Rz
|
||||
ell_coeff.push([
|
||||
Fp2.sub(Fp2.mul(t0, Qx), Fp2.mul(t1, Qy)),
|
||||
Fp2.neg(t0),
|
||||
t1, // T1
|
||||
]);
|
||||
let t2 = Fp2.sqr(t1); // T1²
|
||||
let t3 = Fp2.mul(t2, t1); // T2 * T1
|
||||
let t4 = Fp2.mul(t2, Rx); // T2 * Rx
|
||||
let t5 = Fp2.add(Fp2.sub(t3, Fp2.mul(t4, _2n)), Fp2.mul(Fp2.sqr(t0), Rz)); // T3 - 2 * T4 + T0² * Rz
|
||||
Rx = Fp2.mul(t1, t5); // T1 * T5
|
||||
Ry = Fp2.sub(Fp2.mul(Fp2.sub(t4, t5), t0), Fp2.mul(t3, Ry)); // (T4 - T5) * T0 - T3 * Ry
|
||||
Rz = Fp2.mul(Rz, t3); // Rz * T3
|
||||
}
|
||||
}
|
||||
return ell_coeff;
|
||||
}
|
||||
function millerLoop(ell, g1) {
|
||||
const { x } = CURVE.params;
|
||||
const Px = g1[0];
|
||||
const Py = g1[1];
|
||||
let f12 = Fp12.ONE;
|
||||
for (let j = 0, i = BLS_X_LEN - 2; i >= 0; i--, j++) {
|
||||
const E = ell[j];
|
||||
f12 = Fp12.multiplyBy014(f12, E[0], Fp2.mul(E[1], Px), Fp2.mul(E[2], Py));
|
||||
if (bitGet(x, i)) {
|
||||
j += 1;
|
||||
const F = ell[j];
|
||||
f12 = Fp12.multiplyBy014(f12, F[0], Fp2.mul(F[1], Px), Fp2.mul(F[2], Py));
|
||||
}
|
||||
if (i !== 0)
|
||||
f12 = Fp12.sqr(f12);
|
||||
}
|
||||
return Fp12.conjugate(f12);
|
||||
}
|
||||
const utils = {
|
||||
randomPrivateKey: () => {
|
||||
return Fr.toBytes(hashToPrivateScalar(CURVE.randomBytes(groupLen + 8), CURVE.params.r));
|
||||
},
|
||||
calcPairingPrecomputes,
|
||||
};
|
||||
// Point on G1 curve: (x, y)
|
||||
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,
|
||||
}));
|
||||
function pairingPrecomputes(point) {
|
||||
const p = point;
|
||||
if (p._PPRECOMPUTES)
|
||||
return p._PPRECOMPUTES;
|
||||
p._PPRECOMPUTES = calcPairingPrecomputes(point.toAffine());
|
||||
return p._PPRECOMPUTES;
|
||||
}
|
||||
// TODO: export
|
||||
// function clearPairingPrecomputes(point: G2) {
|
||||
// const p = point as G2 & withPairingPrecomputes;
|
||||
// p._PPRECOMPUTES = undefined;
|
||||
// }
|
||||
// Point on G2 curve (complex numbers): (x₁, x₂+i), (y₁, y₂+i)
|
||||
const G2_ = weierstrassPoints({ n: Fr.ORDER, ...CURVE.G2 });
|
||||
const G2 = Object.assign(G2_, htf.createHasher(G2_.ProjectivePoint, CURVE.G2.mapToCurve, {
|
||||
...CURVE.htfDefaults,
|
||||
...CURVE.G2.htfDefaults,
|
||||
}));
|
||||
const { Signature } = CURVE.G2;
|
||||
// Calculates bilinear pairing
|
||||
function pairing(Q, P, withFinalExponent = true) {
|
||||
if (Q.equals(G1.ProjectivePoint.ZERO) || P.equals(G2.ProjectivePoint.ZERO))
|
||||
throw new Error('pairing is not available for ZERO point');
|
||||
Q.assertValidity();
|
||||
P.assertValidity();
|
||||
// Performance: 9ms for millerLoop and ~14ms for exp.
|
||||
const Qa = Q.toAffine();
|
||||
const looped = millerLoop(pairingPrecomputes(P), [Qa.x, Qa.y]);
|
||||
return withFinalExponent ? Fp12.finalExponentiate(looped) : looped;
|
||||
}
|
||||
function normP1(point) {
|
||||
return point instanceof G1.ProjectivePoint ? point : G1.ProjectivePoint.fromHex(point);
|
||||
}
|
||||
function normP2(point) {
|
||||
return point instanceof G2.ProjectivePoint ? point : Signature.fromHex(point);
|
||||
}
|
||||
function normP2Hash(point, htfOpts) {
|
||||
return point instanceof G2.ProjectivePoint
|
||||
? point
|
||||
: G2.hashToCurve(ensureBytes('point', point), htfOpts);
|
||||
}
|
||||
// Multiplies generator by private key.
|
||||
// P = pk x G
|
||||
function getPublicKey(privateKey) {
|
||||
return G1.ProjectivePoint.fromPrivateKey(privateKey).toRawBytes(true);
|
||||
}
|
||||
function sign(message, privateKey, htfOpts) {
|
||||
const msgPoint = normP2Hash(message, htfOpts);
|
||||
msgPoint.assertValidity();
|
||||
const sigPoint = msgPoint.multiply(G1.normPrivateKeyToScalar(privateKey));
|
||||
if (message instanceof G2.ProjectivePoint)
|
||||
return sigPoint;
|
||||
return Signature.toRawBytes(sigPoint);
|
||||
}
|
||||
// Checks if pairing of public key & hash is equal to pairing of generator & signature.
|
||||
// e(P, H(m)) == e(G, S)
|
||||
function verify(signature, message, publicKey, htfOpts) {
|
||||
const P = normP1(publicKey);
|
||||
const Hm = normP2Hash(message, htfOpts);
|
||||
const G = G1.ProjectivePoint.BASE;
|
||||
const S = normP2(signature);
|
||||
// Instead of doing 2 exponentiations, we use property of billinear maps
|
||||
// and do one exp after multiplying 2 points.
|
||||
const ePHm = pairing(P.negate(), Hm, false);
|
||||
const eGS = pairing(G, S, false);
|
||||
const exp = Fp12.finalExponentiate(Fp12.mul(eGS, ePHm));
|
||||
return Fp12.eql(exp, Fp12.ONE);
|
||||
}
|
||||
function aggregatePublicKeys(publicKeys) {
|
||||
if (!publicKeys.length)
|
||||
throw new Error('Expected non-empty array');
|
||||
const agg = publicKeys.map(normP1).reduce((sum, p) => sum.add(p), G1.ProjectivePoint.ZERO);
|
||||
const aggAffine = agg; //.toAffine();
|
||||
if (publicKeys[0] instanceof G1.ProjectivePoint) {
|
||||
aggAffine.assertValidity();
|
||||
return aggAffine;
|
||||
}
|
||||
// toRawBytes ensures point validity
|
||||
return aggAffine.toRawBytes(true);
|
||||
}
|
||||
function aggregateSignatures(signatures) {
|
||||
if (!signatures.length)
|
||||
throw new Error('Expected non-empty array');
|
||||
const agg = signatures.map(normP2).reduce((sum, s) => sum.add(s), G2.ProjectivePoint.ZERO);
|
||||
const aggAffine = agg; //.toAffine();
|
||||
if (signatures[0] instanceof G2.ProjectivePoint) {
|
||||
aggAffine.assertValidity();
|
||||
return aggAffine;
|
||||
}
|
||||
return Signature.toRawBytes(aggAffine);
|
||||
}
|
||||
// https://ethresear.ch/t/fast-verification-of-multiple-bls-signatures/5407
|
||||
// e(G, S) = e(G, SUM(n)(Si)) = MUL(n)(e(G, Si))
|
||||
function verifyBatch(signature, messages, publicKeys, htfOpts) {
|
||||
// @ts-ignore
|
||||
// console.log('verifyBatch', bytesToHex(signature as any), messages, publicKeys.map(bytesToHex));
|
||||
if (!messages.length)
|
||||
throw new Error('Expected non-empty messages array');
|
||||
if (publicKeys.length !== messages.length)
|
||||
throw new Error('Pubkey count should equal msg count');
|
||||
const sig = normP2(signature);
|
||||
const nMessages = messages.map((i) => normP2Hash(i, htfOpts));
|
||||
const nPublicKeys = publicKeys.map(normP1);
|
||||
try {
|
||||
const paired = [];
|
||||
for (const message of new Set(nMessages)) {
|
||||
const groupPublicKey = nMessages.reduce((groupPublicKey, subMessage, i) => subMessage === message ? groupPublicKey.add(nPublicKeys[i]) : groupPublicKey, G1.ProjectivePoint.ZERO);
|
||||
// const msg = message instanceof PointG2 ? message : await PointG2.hashToCurve(message);
|
||||
// Possible to batch pairing for same msg with different groupPublicKey here
|
||||
paired.push(pairing(groupPublicKey, message, false));
|
||||
}
|
||||
paired.push(pairing(G1.ProjectivePoint.BASE.negate(), sig, false));
|
||||
const product = paired.reduce((a, b) => Fp12.mul(a, b), Fp12.ONE);
|
||||
const exp = Fp12.finalExponentiate(product);
|
||||
return Fp12.eql(exp, Fp12.ONE);
|
||||
}
|
||||
catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
G1.ProjectivePoint.BASE._setWindowSize(4);
|
||||
return {
|
||||
getPublicKey,
|
||||
sign,
|
||||
verify,
|
||||
verifyBatch,
|
||||
aggregatePublicKeys,
|
||||
aggregateSignatures,
|
||||
millerLoop,
|
||||
pairing,
|
||||
G1,
|
||||
G2,
|
||||
Signature,
|
||||
fields: {
|
||||
Fr,
|
||||
Fp,
|
||||
Fp2,
|
||||
Fp6,
|
||||
Fp12,
|
||||
},
|
||||
params: {
|
||||
x: CURVE.params.x,
|
||||
r: CURVE.params.r,
|
||||
G1b: CURVE.G1.b,
|
||||
G2b: CURVE.G2.b,
|
||||
},
|
||||
utils,
|
||||
};
|
||||
}
|
||||
//# sourceMappingURL=bls.js.map
|
||||
1
node_modules/@scure/bip32/node_modules/@noble/curves/esm/abstract/bls.js.map
generated
vendored
Normal file
1
node_modules/@scure/bip32/node_modules/@noble/curves/esm/abstract/bls.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
156
node_modules/@scure/bip32/node_modules/@noble/curves/esm/abstract/curve.js
generated
vendored
Normal file
156
node_modules/@scure/bip32/node_modules/@noble/curves/esm/abstract/curve.js
generated
vendored
Normal file
@@ -0,0 +1,156 @@
|
||||
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||
// Abelian group utilities
|
||||
import { validateField, nLength } from './modular.js';
|
||||
import { validateObject } from './utils.js';
|
||||
const _0n = BigInt(0);
|
||||
const _1n = BigInt(1);
|
||||
// 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(c, bits) {
|
||||
const constTimeNegate = (condition, item) => {
|
||||
const neg = item.negate();
|
||||
return condition ? neg : item;
|
||||
};
|
||||
const opts = (W) => {
|
||||
const windows = Math.ceil(bits / W) + 1; // +1, because
|
||||
const windowSize = 2 ** (W - 1); // -1 because we skip zero
|
||||
return { windows, windowSize };
|
||||
};
|
||||
return {
|
||||
constTimeNegate,
|
||||
// non-const time multiplication ladder
|
||||
unsafeLadder(elm, n) {
|
||||
let p = c.ZERO;
|
||||
let d = elm;
|
||||
while (n > _0n) {
|
||||
if (n & _1n)
|
||||
p = p.add(d);
|
||||
d = d.double();
|
||||
n >>= _1n;
|
||||
}
|
||||
return p;
|
||||
},
|
||||
/**
|
||||
* Creates a wNAF precomputation window. Used for caching.
|
||||
* Default window size is set by `utils.precompute()` and is equal to 8.
|
||||
* 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, W) {
|
||||
const { windows, windowSize } = opts(W);
|
||||
const points = [];
|
||||
let p = elm;
|
||||
let base = p;
|
||||
for (let window = 0; window < windows; window++) {
|
||||
base = p;
|
||||
points.push(base);
|
||||
// =1, because we skip zero
|
||||
for (let i = 1; i < windowSize; i++) {
|
||||
base = base.add(p);
|
||||
points.push(base);
|
||||
}
|
||||
p = base.double();
|
||||
}
|
||||
return points;
|
||||
},
|
||||
/**
|
||||
* Implements ec multiplication using precomputed tables and w-ary non-adjacent form.
|
||||
* @param W window size
|
||||
* @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, precomputes, n) {
|
||||
// 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);
|
||||
let p = c.ZERO;
|
||||
let f = c.BASE;
|
||||
const mask = BigInt(2 ** W - 1); // Create mask with W ones: 0b1111 for W=4 etc.
|
||||
const maxNumber = 2 ** W;
|
||||
const shiftBy = BigInt(W);
|
||||
for (let window = 0; window < windows; window++) {
|
||||
const offset = window * windowSize;
|
||||
// Extract W bits.
|
||||
let wbits = Number(n & mask);
|
||||
// Shift number by W bits.
|
||||
n >>= shiftBy;
|
||||
// If the bits are bigger than max size, we'll split those.
|
||||
// +224 => 256 - 32
|
||||
if (wbits > windowSize) {
|
||||
wbits -= maxNumber;
|
||||
n += _1n;
|
||||
}
|
||||
// This code was first written with assumption that 'f' and 'p' will never be infinity point:
|
||||
// since each addition is multiplied by 2 ** W, it cannot cancel each other. However,
|
||||
// there is negate now: it is possible that negated element from low value
|
||||
// would be the same as high element, which will create carry into next window.
|
||||
// It's not obvious how this can fail, but still worth investigating later.
|
||||
// Check if we're onto Zero point.
|
||||
// Add random point inside current window to f.
|
||||
const offset1 = offset;
|
||||
const offset2 = offset + Math.abs(wbits) - 1; // -1 because we skip zero
|
||||
const cond1 = window % 2 !== 0;
|
||||
const cond2 = wbits < 0;
|
||||
if (wbits === 0) {
|
||||
// The most important part for const-time getPublicKey
|
||||
f = f.add(constTimeNegate(cond1, precomputes[offset1]));
|
||||
}
|
||||
else {
|
||||
p = p.add(constTimeNegate(cond2, precomputes[offset2]));
|
||||
}
|
||||
}
|
||||
// JIT-compiler should not eliminate f here, since it will later be used in normalizeZ()
|
||||
// Even if the variable is still unused, there are some checks which will
|
||||
// throw an exception, so compiler needs to prove they won't happen, which is hard.
|
||||
// At this point there is a way to F be infinity-point even if p is not,
|
||||
// which makes it less const-time: around 1 bigint multiply.
|
||||
return { p, f };
|
||||
},
|
||||
wNAFCached(P, precomputesMap, n, transform) {
|
||||
// @ts-ignore
|
||||
const W = P._WINDOW_SIZE || 1;
|
||||
// Calculate precomputes on a first run, reuse them after
|
||||
let comp = precomputesMap.get(P);
|
||||
if (!comp) {
|
||||
comp = this.precomputeWindow(P, W);
|
||||
if (W !== 1) {
|
||||
precomputesMap.set(P, transform(comp));
|
||||
}
|
||||
}
|
||||
return this.wNAF(W, comp, n);
|
||||
},
|
||||
};
|
||||
}
|
||||
export function validateBasic(curve) {
|
||||
validateField(curve.Fp);
|
||||
validateObject(curve, {
|
||||
n: 'bigint',
|
||||
h: 'bigint',
|
||||
Gx: 'field',
|
||||
Gy: 'field',
|
||||
}, {
|
||||
nBitLength: 'isSafeInteger',
|
||||
nByteLength: 'isSafeInteger',
|
||||
});
|
||||
// Set defaults
|
||||
return Object.freeze({
|
||||
...nLength(curve.n, curve.nBitLength),
|
||||
...curve,
|
||||
...{ p: curve.Fp.ORDER },
|
||||
});
|
||||
}
|
||||
//# sourceMappingURL=curve.js.map
|
||||
1
node_modules/@scure/bip32/node_modules/@noble/curves/esm/abstract/curve.js.map
generated
vendored
Normal file
1
node_modules/@scure/bip32/node_modules/@noble/curves/esm/abstract/curve.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"curve.js","sourceRoot":"","sources":["../../src/abstract/curve.ts"],"names":[],"mappings":"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"}
|
||||
425
node_modules/@scure/bip32/node_modules/@noble/curves/esm/abstract/edwards.js
generated
vendored
Normal file
425
node_modules/@scure/bip32/node_modules/@noble/curves/esm/abstract/edwards.js
generated
vendored
Normal file
@@ -0,0 +1,425 @@
|
||||
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||
// Twisted Edwards curve. The formula is: ax² + y² = 1 + dx²y²
|
||||
import { mod } from './modular.js';
|
||||
import * as ut from './utils.js';
|
||||
import { ensureBytes } from './utils.js';
|
||||
import { wNAF, validateBasic } from './curve.js';
|
||||
// Be friendly to bad ECMAScript parsers by not using bigint literals
|
||||
// prettier-ignore
|
||||
const _0n = BigInt(0), _1n = BigInt(1), _2n = BigInt(2), _8n = BigInt(8);
|
||||
// verification rule is either zip215 or rfc8032 / nist186-5. Consult fromHex:
|
||||
const VERIFY_DEFAULT = { zip215: true };
|
||||
function validateOpts(curve) {
|
||||
const opts = validateBasic(curve);
|
||||
ut.validateObject(curve, {
|
||||
hash: 'function',
|
||||
a: 'bigint',
|
||||
d: 'bigint',
|
||||
randomBytes: 'function',
|
||||
}, {
|
||||
adjustScalarBytes: 'function',
|
||||
domain: 'function',
|
||||
uvRatio: 'function',
|
||||
mapToCurve: 'function',
|
||||
});
|
||||
// Set defaults
|
||||
return Object.freeze({ ...opts });
|
||||
}
|
||||
// It is not generic twisted curve for now, but ed25519/ed448 generic implementation
|
||||
export function twistedEdwards(curveDef) {
|
||||
const CURVE = validateOpts(curveDef);
|
||||
const { Fp, n: CURVE_ORDER, prehash: prehash, hash: cHash, randomBytes, nByteLength, h: cofactor, } = CURVE;
|
||||
const MASK = _2n << (BigInt(nByteLength * 8) - _1n);
|
||||
const modP = Fp.create; // Function overrides
|
||||
// sqrt(u/v)
|
||||
const uvRatio = CURVE.uvRatio ||
|
||||
((u, v) => {
|
||||
try {
|
||||
return { isValid: true, value: Fp.sqrt(u * Fp.inv(v)) };
|
||||
}
|
||||
catch (e) {
|
||||
return { isValid: false, value: _0n };
|
||||
}
|
||||
});
|
||||
const adjustScalarBytes = CURVE.adjustScalarBytes || ((bytes) => bytes); // NOOP
|
||||
const domain = CURVE.domain ||
|
||||
((data, ctx, phflag) => {
|
||||
if (ctx.length || phflag)
|
||||
throw new Error('Contexts/pre-hash are not supported');
|
||||
return data;
|
||||
}); // NOOP
|
||||
const inBig = (n) => typeof n === 'bigint' && _0n < n; // n in [1..]
|
||||
const inRange = (n, max) => inBig(n) && inBig(max) && n < max; // n in [1..max-1]
|
||||
const in0MaskRange = (n) => n === _0n || inRange(n, MASK); // n in [0..MASK-1]
|
||||
function assertInRange(n, max) {
|
||||
// n in [1..max-1]
|
||||
if (inRange(n, max))
|
||||
return n;
|
||||
throw new Error(`Expected valid scalar < ${max}, got ${typeof n} ${n}`);
|
||||
}
|
||||
function assertGE0(n) {
|
||||
// n in [0..CURVE_ORDER-1]
|
||||
return n === _0n ? n : assertInRange(n, CURVE_ORDER); // GE = prime subgroup, not full group
|
||||
}
|
||||
const pointPrecomputes = new Map();
|
||||
function isPoint(other) {
|
||||
if (!(other instanceof Point))
|
||||
throw new Error('ExtendedPoint expected');
|
||||
}
|
||||
// Extended Point works in extended coordinates: (x, y, z, t) ∋ (x=x/z, y=y/z, t=xy).
|
||||
// https://en.wikipedia.org/wiki/Twisted_Edwards_curve#Extended_coordinates
|
||||
class Point {
|
||||
constructor(ex, ey, ez, et) {
|
||||
this.ex = ex;
|
||||
this.ey = ey;
|
||||
this.ez = ez;
|
||||
this.et = et;
|
||||
if (!in0MaskRange(ex))
|
||||
throw new Error('x required');
|
||||
if (!in0MaskRange(ey))
|
||||
throw new Error('y required');
|
||||
if (!in0MaskRange(ez))
|
||||
throw new Error('z required');
|
||||
if (!in0MaskRange(et))
|
||||
throw new Error('t required');
|
||||
}
|
||||
get x() {
|
||||
return this.toAffine().x;
|
||||
}
|
||||
get y() {
|
||||
return this.toAffine().y;
|
||||
}
|
||||
static fromAffine(p) {
|
||||
if (p instanceof Point)
|
||||
throw new Error('extended point not allowed');
|
||||
const { x, y } = p || {};
|
||||
if (!in0MaskRange(x) || !in0MaskRange(y))
|
||||
throw new Error('invalid affine point');
|
||||
return new Point(x, y, _1n, modP(x * y));
|
||||
}
|
||||
static normalizeZ(points) {
|
||||
const toInv = Fp.invertBatch(points.map((p) => p.ez));
|
||||
return points.map((p, i) => p.toAffine(toInv[i])).map(Point.fromAffine);
|
||||
}
|
||||
// "Private method", don't use it directly
|
||||
_setWindowSize(windowSize) {
|
||||
this._WINDOW_SIZE = windowSize;
|
||||
pointPrecomputes.delete(this);
|
||||
}
|
||||
// Not required for fromHex(), which always creates valid points.
|
||||
// Could be useful for fromAffine().
|
||||
assertValidity() {
|
||||
const { a, d } = CURVE;
|
||||
if (this.is0())
|
||||
throw new Error('bad point: ZERO'); // TODO: optimize, with vars below?
|
||||
// Equation in affine coordinates: ax² + y² = 1 + dx²y²
|
||||
// Equation in projective coordinates (X/Z, Y/Z, Z): (aX² + Y²)Z² = Z⁴ + dX²Y²
|
||||
const { ex: X, ey: Y, ez: Z, et: T } = this;
|
||||
const X2 = modP(X * X); // X²
|
||||
const Y2 = modP(Y * Y); // Y²
|
||||
const Z2 = modP(Z * Z); // Z²
|
||||
const Z4 = modP(Z2 * Z2); // Z⁴
|
||||
const aX2 = modP(X2 * a); // aX²
|
||||
const left = modP(Z2 * modP(aX2 + Y2)); // (aX² + Y²)Z²
|
||||
const right = modP(Z4 + modP(d * modP(X2 * Y2))); // Z⁴ + dX²Y²
|
||||
if (left !== right)
|
||||
throw new Error('bad point: equation left != right (1)');
|
||||
// In Extended coordinates we also have T, which is x*y=T/Z: check X*Y == Z*T
|
||||
const XY = modP(X * Y);
|
||||
const ZT = modP(Z * T);
|
||||
if (XY !== ZT)
|
||||
throw new Error('bad point: equation left != right (2)');
|
||||
}
|
||||
// Compare one point to another.
|
||||
equals(other) {
|
||||
isPoint(other);
|
||||
const { ex: X1, ey: Y1, ez: Z1 } = this;
|
||||
const { ex: X2, ey: Y2, ez: Z2 } = other;
|
||||
const X1Z2 = modP(X1 * Z2);
|
||||
const X2Z1 = modP(X2 * Z1);
|
||||
const Y1Z2 = modP(Y1 * Z2);
|
||||
const Y2Z1 = modP(Y2 * Z1);
|
||||
return X1Z2 === X2Z1 && Y1Z2 === Y2Z1;
|
||||
}
|
||||
is0() {
|
||||
return this.equals(Point.ZERO);
|
||||
}
|
||||
negate() {
|
||||
// Flips point sign to a negative one (-x, y in affine coords)
|
||||
return new Point(modP(-this.ex), this.ey, this.ez, modP(-this.et));
|
||||
}
|
||||
// Fast algo for doubling Extended Point.
|
||||
// https://hyperelliptic.org/EFD/g1p/auto-twisted-extended.html#doubling-dbl-2008-hwcd
|
||||
// Cost: 4M + 4S + 1*a + 6add + 1*2.
|
||||
double() {
|
||||
const { a } = CURVE;
|
||||
const { ex: X1, ey: Y1, ez: Z1 } = this;
|
||||
const A = modP(X1 * X1); // A = X12
|
||||
const B = modP(Y1 * Y1); // B = Y12
|
||||
const C = modP(_2n * modP(Z1 * Z1)); // C = 2*Z12
|
||||
const D = modP(a * A); // D = a*A
|
||||
const x1y1 = X1 + Y1;
|
||||
const E = modP(modP(x1y1 * x1y1) - A - B); // E = (X1+Y1)2-A-B
|
||||
const G = D + B; // G = D+B
|
||||
const F = G - C; // F = G-C
|
||||
const H = D - B; // H = D-B
|
||||
const X3 = modP(E * F); // X3 = E*F
|
||||
const Y3 = modP(G * H); // Y3 = G*H
|
||||
const T3 = modP(E * H); // T3 = E*H
|
||||
const Z3 = modP(F * G); // Z3 = F*G
|
||||
return new Point(X3, Y3, Z3, T3);
|
||||
}
|
||||
// Fast algo for adding 2 Extended Points.
|
||||
// https://hyperelliptic.org/EFD/g1p/auto-twisted-extended.html#addition-add-2008-hwcd
|
||||
// Cost: 9M + 1*a + 1*d + 7add.
|
||||
add(other) {
|
||||
isPoint(other);
|
||||
const { a, d } = CURVE;
|
||||
const { ex: X1, ey: Y1, ez: Z1, et: T1 } = this;
|
||||
const { ex: X2, ey: Y2, ez: Z2, et: T2 } = other;
|
||||
// Faster algo for adding 2 Extended Points when curve's a=-1.
|
||||
// http://hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html#addition-add-2008-hwcd-4
|
||||
// Cost: 8M + 8add + 2*2.
|
||||
// Note: It does not check whether the `other` point is valid.
|
||||
if (a === BigInt(-1)) {
|
||||
const A = modP((Y1 - X1) * (Y2 + X2));
|
||||
const B = modP((Y1 + X1) * (Y2 - X2));
|
||||
const F = modP(B - A);
|
||||
if (F === _0n)
|
||||
return this.double(); // Same point. Tests say it doesn't affect timing
|
||||
const C = modP(Z1 * _2n * T2);
|
||||
const D = modP(T1 * _2n * Z2);
|
||||
const E = D + C;
|
||||
const G = B + A;
|
||||
const H = D - C;
|
||||
const X3 = modP(E * F);
|
||||
const Y3 = modP(G * H);
|
||||
const T3 = modP(E * H);
|
||||
const Z3 = modP(F * G);
|
||||
return new Point(X3, Y3, Z3, T3);
|
||||
}
|
||||
const A = modP(X1 * X2); // A = X1*X2
|
||||
const B = modP(Y1 * Y2); // B = Y1*Y2
|
||||
const C = modP(T1 * d * T2); // C = T1*d*T2
|
||||
const D = modP(Z1 * Z2); // D = Z1*Z2
|
||||
const E = modP((X1 + Y1) * (X2 + Y2) - A - B); // E = (X1+Y1)*(X2+Y2)-A-B
|
||||
const F = D - C; // F = D-C
|
||||
const G = D + C; // G = D+C
|
||||
const H = modP(B - a * A); // H = B-a*A
|
||||
const X3 = modP(E * F); // X3 = E*F
|
||||
const Y3 = modP(G * H); // Y3 = G*H
|
||||
const T3 = modP(E * H); // T3 = E*H
|
||||
const Z3 = modP(F * G); // Z3 = F*G
|
||||
return new Point(X3, Y3, Z3, T3);
|
||||
}
|
||||
subtract(other) {
|
||||
return this.add(other.negate());
|
||||
}
|
||||
wNAF(n) {
|
||||
return wnaf.wNAFCached(this, pointPrecomputes, n, Point.normalizeZ);
|
||||
}
|
||||
// Constant-time multiplication.
|
||||
multiply(scalar) {
|
||||
const { p, f } = this.wNAF(assertInRange(scalar, CURVE_ORDER));
|
||||
return Point.normalizeZ([p, f])[0];
|
||||
}
|
||||
// Non-constant-time multiplication. Uses double-and-add algorithm.
|
||||
// It's faster, but should only be used when you don't care about
|
||||
// an exposed private key e.g. sig verification.
|
||||
// Does NOT allow scalars higher than CURVE.n.
|
||||
multiplyUnsafe(scalar) {
|
||||
let n = assertGE0(scalar); // 0 <= scalar < CURVE.n
|
||||
if (n === _0n)
|
||||
return I;
|
||||
if (this.equals(I) || n === _1n)
|
||||
return this;
|
||||
if (this.equals(G))
|
||||
return this.wNAF(n).p;
|
||||
return wnaf.unsafeLadder(this, n);
|
||||
}
|
||||
// Checks if point is of small order.
|
||||
// If you add something to small order point, you will have "dirty"
|
||||
// point with torsion component.
|
||||
// Multiplies point by cofactor and checks if the result is 0.
|
||||
isSmallOrder() {
|
||||
return this.multiplyUnsafe(cofactor).is0();
|
||||
}
|
||||
// Multiplies point by curve order and checks if the result is 0.
|
||||
// Returns `false` is the point is dirty.
|
||||
isTorsionFree() {
|
||||
return wnaf.unsafeLadder(this, CURVE_ORDER).is0();
|
||||
}
|
||||
// Converts Extended point to default (x, y) coordinates.
|
||||
// Can accept precomputed Z^-1 - for example, from invertBatch.
|
||||
toAffine(iz) {
|
||||
const { ex: x, ey: y, ez: z } = this;
|
||||
const is0 = this.is0();
|
||||
if (iz == null)
|
||||
iz = is0 ? _8n : Fp.inv(z); // 8 was chosen arbitrarily
|
||||
const ax = modP(x * iz);
|
||||
const ay = modP(y * iz);
|
||||
const zz = modP(z * iz);
|
||||
if (is0)
|
||||
return { x: _0n, y: _1n };
|
||||
if (zz !== _1n)
|
||||
throw new Error('invZ was invalid');
|
||||
return { x: ax, y: ay };
|
||||
}
|
||||
clearCofactor() {
|
||||
const { h: cofactor } = CURVE;
|
||||
if (cofactor === _1n)
|
||||
return this;
|
||||
return this.multiplyUnsafe(cofactor);
|
||||
}
|
||||
// Converts hash string or Uint8Array to Point.
|
||||
// Uses algo from RFC8032 5.1.3.
|
||||
static fromHex(hex, zip215 = false) {
|
||||
const { d, a } = CURVE;
|
||||
const len = Fp.BYTES;
|
||||
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
|
||||
const y = ut.bytesToNumberLE(normed);
|
||||
if (y === _0n) {
|
||||
// y=0 is allowed
|
||||
}
|
||||
else {
|
||||
// RFC8032 prohibits >= p, but ZIP215 doesn't
|
||||
if (zip215)
|
||||
assertInRange(y, MASK); // zip215=true [1..P-1] (2^255-19-1 for ed25519)
|
||||
else
|
||||
assertInRange(y, Fp.ORDER); // zip215=false [1..MASK-1] (2^256-1 for ed25519)
|
||||
}
|
||||
// Ed25519: x² = (y²-1)/(dy²+1) mod p. Ed448: x² = (y²-1)/(dy²-1) mod p. Generic case:
|
||||
// ax²+y²=1+dx²y² => y²-1=dx²y²-ax² => y²-1=x²(dy²-a) => x²=(y²-1)/(dy²-a)
|
||||
const y2 = modP(y * y); // denominator is always non-0 mod p.
|
||||
const u = modP(y2 - _1n); // u = y² - 1
|
||||
const v = modP(d * y2 - a); // v = d y² + 1.
|
||||
let { isValid, value: x } = uvRatio(u, v); // √(u/v)
|
||||
if (!isValid)
|
||||
throw new Error('Point.fromHex: invalid y coordinate');
|
||||
const isXOdd = (x & _1n) === _1n; // There are 2 square roots. Use x_0 bit to select proper
|
||||
const isLastByteOdd = (lastByte & 0x80) !== 0; // x_0, last bit
|
||||
if (!zip215 && x === _0n && isLastByteOdd)
|
||||
// if x=0 and x_0 = 1, fail
|
||||
throw new Error('Point.fromHex: x=0 and x_0=1');
|
||||
if (isLastByteOdd !== isXOdd)
|
||||
x = modP(-x); // if x_0 != x mod 2, set x = p-x
|
||||
return Point.fromAffine({ x, y });
|
||||
}
|
||||
static fromPrivateKey(privKey) {
|
||||
return getExtendedPublicKey(privKey).point;
|
||||
}
|
||||
toRawBytes() {
|
||||
const { x, y } = this.toAffine();
|
||||
const bytes = ut.numberToBytesLE(y, Fp.BYTES); // each y has 2 x values (x, -y)
|
||||
bytes[bytes.length - 1] |= x & _1n ? 0x80 : 0; // when compressing, it's enough to store y
|
||||
return bytes; // and use the last byte to encode sign of x
|
||||
}
|
||||
toHex() {
|
||||
return ut.bytesToHex(this.toRawBytes()); // Same as toRawBytes, but returns string.
|
||||
}
|
||||
}
|
||||
Point.BASE = new Point(CURVE.Gx, CURVE.Gy, _1n, modP(CURVE.Gx * CURVE.Gy));
|
||||
Point.ZERO = new Point(_0n, _1n, _1n, _0n); // 0, 1, 1, 0
|
||||
const { BASE: G, ZERO: I } = Point;
|
||||
const wnaf = wNAF(Point, nByteLength * 8);
|
||||
function modN(a) {
|
||||
return mod(a, CURVE_ORDER);
|
||||
}
|
||||
// Little-endian SHA512 with modulo n
|
||||
function modN_LE(hash) {
|
||||
return modN(ut.bytesToNumberLE(hash));
|
||||
}
|
||||
/** Convenience method that creates public key and other stuff. RFC8032 5.1.5 */
|
||||
function getExtendedPublicKey(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('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
|
||||
const point = G.multiply(scalar); // Point on Edwards curve aka public key
|
||||
const pointBytes = point.toRawBytes(); // Uint8Array representation
|
||||
return { head, prefix, scalar, point, pointBytes };
|
||||
}
|
||||
// Calculates EdDSA pub key. RFC8032 5.1.5. Privkey is hashed. Use first half with 3 bits cleared
|
||||
function getPublicKey(privKey) {
|
||||
return getExtendedPublicKey(privKey).pointBytes;
|
||||
}
|
||||
// int('LE', SHA512(dom2(F, C) || msgs)) mod N
|
||||
function hashDomainToScalar(context = new Uint8Array(), ...msgs) {
|
||||
const msg = ut.concatBytes(...msgs);
|
||||
return modN_LE(cHash(domain(msg, ensureBytes('context', context), !!prehash)));
|
||||
}
|
||||
/** Signs message with privateKey. RFC8032 5.1.6 */
|
||||
function sign(msg, privKey, options = {}) {
|
||||
msg = ensureBytes('message', msg);
|
||||
if (prehash)
|
||||
msg = prehash(msg); // for ed25519ph etc.
|
||||
const { prefix, scalar, pointBytes } = getExtendedPublicKey(privKey);
|
||||
const r = hashDomainToScalar(options.context, prefix, msg); // r = dom2(F, C) || prefix || PH(M)
|
||||
const R = G.multiply(r).toRawBytes(); // R = rG
|
||||
const k = hashDomainToScalar(options.context, R, pointBytes, msg); // R || A || PH(M)
|
||||
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('result', res, nByteLength * 2); // 64-byte signature
|
||||
}
|
||||
const verifyOpts = VERIFY_DEFAULT;
|
||||
function verify(sig, msg, publicKey, options = verifyOpts) {
|
||||
const { context, zip215 } = options;
|
||||
const len = Fp.BYTES; // Verifies EdDSA signature against message and public key. RFC8032 5.1.7.
|
||||
sig = ensureBytes('signature', sig, 2 * len); // An extended group equation is checked.
|
||||
msg = ensureBytes('message', msg);
|
||||
if (prehash)
|
||||
msg = prehash(msg); // for ed25519ph, etc
|
||||
const s = ut.bytesToNumberLE(sig.slice(len, 2 * len));
|
||||
// zip215: true is good for consensus-critical apps and allows points < 2^256
|
||||
// zip215: false follows RFC8032 / NIST186-5 and restricts points to CURVE.p
|
||||
let A, R, SB;
|
||||
try {
|
||||
A = Point.fromHex(publicKey, zip215);
|
||||
R = Point.fromHex(sig.slice(0, len), zip215);
|
||||
SB = G.multiplyUnsafe(s); // 0 <= s < l is done inside
|
||||
}
|
||||
catch (error) {
|
||||
return false;
|
||||
}
|
||||
if (!zip215 && A.isSmallOrder())
|
||||
return false;
|
||||
const k = hashDomainToScalar(context, R.toRawBytes(), A.toRawBytes(), msg);
|
||||
const RkA = R.add(A.multiplyUnsafe(k));
|
||||
// [8][S]B = [8]R + [8][k]A'
|
||||
return RkA.subtract(SB).clearCofactor().equals(Point.ZERO);
|
||||
}
|
||||
G._setWindowSize(8); // Enable precomputes. Slows down first publicKey computation by 20ms.
|
||||
const utils = {
|
||||
getExtendedPublicKey,
|
||||
// ed25519 private keys are uniform 32b. No need to check for modulo bias, like in secp256k1.
|
||||
randomPrivateKey: () => randomBytes(Fp.BYTES),
|
||||
/**
|
||||
* We're doing scalar multiplication (used in getPublicKey etc) with precomputed BASE_POINT
|
||||
* values. This slows down first getPublicKey() by milliseconds (see Speed section),
|
||||
* but allows to speed-up subsequent getPublicKey() calls up to 20x.
|
||||
* @param windowSize 2, 4, 8, 16
|
||||
*/
|
||||
precompute(windowSize = 8, point = Point.BASE) {
|
||||
point._setWindowSize(windowSize);
|
||||
point.multiply(BigInt(3));
|
||||
return point;
|
||||
},
|
||||
};
|
||||
return {
|
||||
CURVE,
|
||||
getPublicKey,
|
||||
sign,
|
||||
verify,
|
||||
ExtendedPoint: Point,
|
||||
utils,
|
||||
};
|
||||
}
|
||||
//# sourceMappingURL=edwards.js.map
|
||||
1
node_modules/@scure/bip32/node_modules/@noble/curves/esm/abstract/edwards.js.map
generated
vendored
Normal file
1
node_modules/@scure/bip32/node_modules/@noble/curves/esm/abstract/edwards.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
167
node_modules/@scure/bip32/node_modules/@noble/curves/esm/abstract/hash-to-curve.js
generated
vendored
Normal file
167
node_modules/@scure/bip32/node_modules/@noble/curves/esm/abstract/hash-to-curve.js
generated
vendored
Normal file
@@ -0,0 +1,167 @@
|
||||
import { mod } from './modular.js';
|
||||
import { bytesToNumberBE, concatBytes, utf8ToBytes, validateObject } from './utils.js';
|
||||
function validateDST(dst) {
|
||||
if (dst instanceof Uint8Array)
|
||||
return dst;
|
||||
if (typeof dst === 'string')
|
||||
return utf8ToBytes(dst);
|
||||
throw new Error('DST must be Uint8Array or string');
|
||||
}
|
||||
// Octet Stream to Integer. "spec" implementation of os2ip is 2.5x slower vs bytesToNumberBE.
|
||||
const os2ip = bytesToNumberBE;
|
||||
// Integer to Octet Stream (numberToBytesBE)
|
||||
function i2osp(value, length) {
|
||||
if (value < 0 || value >= 1 << (8 * length)) {
|
||||
throw new Error(`bad I2OSP call: value=${value} length=${length}`);
|
||||
}
|
||||
const res = Array.from({ length }).fill(0);
|
||||
for (let i = length - 1; i >= 0; i--) {
|
||||
res[i] = value & 0xff;
|
||||
value >>>= 8;
|
||||
}
|
||||
return new Uint8Array(res);
|
||||
}
|
||||
function strxor(a, b) {
|
||||
const arr = new Uint8Array(a.length);
|
||||
for (let i = 0; i < a.length; i++) {
|
||||
arr[i] = a[i] ^ b[i];
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
function isBytes(item) {
|
||||
if (!(item instanceof Uint8Array))
|
||||
throw new Error('Uint8Array expected');
|
||||
}
|
||||
function isNum(item) {
|
||||
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(msg, DST, lenInBytes, H) {
|
||||
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(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); // len_in_bytes_str
|
||||
const b = new Array(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));
|
||||
for (let i = 1; i <= ell; i++) {
|
||||
const args = [strxor(b_0, b[i - 1]), i2osp(i + 1, 1), DST_prime];
|
||||
b[i] = H(concatBytes(...args));
|
||||
}
|
||||
const pseudo_random_bytes = concatBytes(...b);
|
||||
return pseudo_random_bytes.slice(0, lenInBytes);
|
||||
}
|
||||
export function expand_message_xof(msg, DST, lenInBytes, k, H) {
|
||||
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(utf8ToBytes('H2C-OVERSIZE-DST-')).update(DST).digest();
|
||||
}
|
||||
if (lenInBytes > 65535 || DST.length > 255)
|
||||
throw new Error('expand_message_xof: invalid lenInBytes');
|
||||
return (H.create({ dkLen: lenInBytes })
|
||||
.update(msg)
|
||||
.update(i2osp(lenInBytes, 2))
|
||||
// 2. DST_prime = DST || I2OSP(len(DST), 1)
|
||||
.update(DST)
|
||||
.update(i2osp(DST.length, 1))
|
||||
.digest());
|
||||
}
|
||||
/**
|
||||
* Hashes arbitrary-length byte strings to a list of one or more elements of a finite field F
|
||||
* 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}`, see above
|
||||
* @returns [u_0, ..., u_(count - 1)], a list of field elements.
|
||||
*/
|
||||
export function hash_to_field(msg, count, options) {
|
||||
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 === '_internal_pass') {
|
||||
// for internal tests only
|
||||
prb = msg;
|
||||
}
|
||||
else {
|
||||
throw new Error('expand must be "xmd" or "xof"');
|
||||
}
|
||||
const u = new Array(count);
|
||||
for (let i = 0; i < count; i++) {
|
||||
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;
|
||||
}
|
||||
return u;
|
||||
}
|
||||
export function isogenyMap(field, map) {
|
||||
// Make same order as in spec
|
||||
const COEFF = map.map((i) => Array.from(i).reverse());
|
||||
return (x, y) => {
|
||||
const [xNum, xDen, yNum, yDen] = COEFF.map((val) => val.reduce((acc, i) => field.add(field.mul(acc, x), i)));
|
||||
x = field.div(xNum, xDen); // xNum / xDen
|
||||
y = field.mul(y, field.div(yNum, yDen)); // y * (yNum / yDev)
|
||||
return { x, y };
|
||||
};
|
||||
}
|
||||
export function createHasher(Point, mapToCurve, def) {
|
||||
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-16#section-3
|
||||
hashToCurve(msg, options) {
|
||||
const u = hash_to_field(msg, 2, { ...def, DST: def.DST, ...options });
|
||||
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, options) {
|
||||
const u = hash_to_field(msg, 1, { ...def, DST: def.encodeDST, ...options });
|
||||
const P = Point.fromAffine(mapToCurve(u[0])).clearCofactor();
|
||||
P.assertValidity();
|
||||
return P;
|
||||
},
|
||||
};
|
||||
}
|
||||
//# sourceMappingURL=hash-to-curve.js.map
|
||||
1
node_modules/@scure/bip32/node_modules/@noble/curves/esm/abstract/hash-to-curve.js.map
generated
vendored
Normal file
1
node_modules/@scure/bip32/node_modules/@noble/curves/esm/abstract/hash-to-curve.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
361
node_modules/@scure/bip32/node_modules/@noble/curves/esm/abstract/modular.js
generated
vendored
Normal file
361
node_modules/@scure/bip32/node_modules/@noble/curves/esm/abstract/modular.js
generated
vendored
Normal file
@@ -0,0 +1,361 @@
|
||||
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||
// Utilities for modular arithmetics and finite fields
|
||||
import { bitMask, numberToBytesBE, numberToBytesLE, bytesToNumberBE, bytesToNumberLE, ensureBytes, validateObject, } from './utils.js';
|
||||
// prettier-ignore
|
||||
const _0n = BigInt(0), _1n = BigInt(1), _2n = BigInt(2), _3n = BigInt(3);
|
||||
// prettier-ignore
|
||||
const _4n = BigInt(4), _5n = BigInt(5), _8n = BigInt(8);
|
||||
// prettier-ignore
|
||||
const _9n = BigInt(9), _16n = BigInt(16);
|
||||
// Calculates a modulo b
|
||||
export function mod(a, b) {
|
||||
const result = a % b;
|
||||
return result >= _0n ? result : b + result;
|
||||
}
|
||||
/**
|
||||
* Efficiently raise num to power and do modular division.
|
||||
* Unsafe in some contexts: uses ladder, so can expose bigint bits.
|
||||
* @example
|
||||
* pow(2n, 6n, 11n) // 64n % 11n == 9n
|
||||
*/
|
||||
// TODO: use field version && remove
|
||||
export function pow(num, power, modulo) {
|
||||
if (modulo <= _0n || power < _0n)
|
||||
throw new Error('Expected power/modulo > 0');
|
||||
if (modulo === _1n)
|
||||
return _0n;
|
||||
let res = _1n;
|
||||
while (power > _0n) {
|
||||
if (power & _1n)
|
||||
res = (res * num) % modulo;
|
||||
num = (num * num) % modulo;
|
||||
power >>= _1n;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
// Does x ^ (2 ^ power) mod p. pow2(30, 4) == 30 ^ (2 ^ 4)
|
||||
export function pow2(x, power, modulo) {
|
||||
let res = x;
|
||||
while (power-- > _0n) {
|
||||
res *= res;
|
||||
res %= modulo;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
// Inverses number over modulo
|
||||
export function invert(number, modulo) {
|
||||
if (number === _0n || modulo <= _0n) {
|
||||
throw new Error(`invert: expected positive integers, got n=${number} mod=${modulo}`);
|
||||
}
|
||||
// Euclidean 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
|
||||
let x = _0n, y = _1n, u = _1n, v = _0n;
|
||||
while (a !== _0n) {
|
||||
// JIT applies optimization if those two lines follow each other
|
||||
const q = b / a;
|
||||
const r = b % a;
|
||||
const m = x - u * q;
|
||||
const n = y - v * q;
|
||||
// prettier-ignore
|
||||
b = a, a = r, x = u, y = v, u = m, v = n;
|
||||
}
|
||||
const gcd = b;
|
||||
if (gcd !== _1n)
|
||||
throw new Error('invert: does not exist');
|
||||
return mod(x, modulo);
|
||||
}
|
||||
// Tonelli-Shanks algorithm
|
||||
// Paper 1: https://eprint.iacr.org/2012/685.pdf (page 12)
|
||||
// Paper 2: Square Roots from 1; 24, 51, 10 to Dan Shanks
|
||||
export function tonelliShanks(P) {
|
||||
// Legendre constant: used to calculate Legendre symbol (a | p),
|
||||
// which denotes the value of a^((p-1)/2) (mod p).
|
||||
// (a | p) ≡ 1 if a is a square (mod p)
|
||||
// (a | p) ≡ -1 if a is not a square (mod p)
|
||||
// (a | p) ≡ 0 if a ≡ 0 (mod p)
|
||||
const legendreC = (P - _1n) / _2n;
|
||||
let Q, S, Z;
|
||||
// Step 1: By factoring out powers of 2 from p - 1,
|
||||
// find q and s such that p - 1 = q*(2^s) with q odd
|
||||
for (Q = P - _1n, S = 0; Q % _2n === _0n; Q /= _2n, S++)
|
||||
;
|
||||
// Step 2: Select a non-square z such that (z | p) ≡ -1 and set c ≡ zq
|
||||
for (Z = _2n; Z < P && pow(Z, legendreC, P) !== P - _1n; Z++)
|
||||
;
|
||||
// Fast-path
|
||||
if (S === 1) {
|
||||
const p1div4 = (P + _1n) / _4n;
|
||||
return function tonelliFast(Fp, n) {
|
||||
const root = Fp.pow(n, p1div4);
|
||||
if (!Fp.eql(Fp.sqr(root), n))
|
||||
throw new Error('Cannot find square root');
|
||||
return root;
|
||||
};
|
||||
}
|
||||
// Slow-path
|
||||
const Q1div2 = (Q + _1n) / _2n;
|
||||
return function tonelliSlow(Fp, n) {
|
||||
// Step 0: Check that n is indeed a square: (n | p) should not be ≡ -1
|
||||
if (Fp.pow(n, legendreC) === Fp.neg(Fp.ONE))
|
||||
throw new Error('Cannot find square root');
|
||||
let r = S;
|
||||
// TODO: will fail at Fp2/etc
|
||||
let g = Fp.pow(Fp.mul(Fp.ONE, Z), Q); // will update both x and b
|
||||
let x = Fp.pow(n, Q1div2); // first guess at the square root
|
||||
let b = Fp.pow(n, Q); // first guess at the fudge factor
|
||||
while (!Fp.eql(b, Fp.ONE)) {
|
||||
if (Fp.eql(b, Fp.ZERO))
|
||||
return Fp.ZERO; // https://en.wikipedia.org/wiki/Tonelli%E2%80%93Shanks_algorithm (4. If t = 0, return r = 0)
|
||||
// Find m such b^(2^m)==1
|
||||
let m = 1;
|
||||
for (let t2 = Fp.sqr(b); m < r; m++) {
|
||||
if (Fp.eql(t2, Fp.ONE))
|
||||
break;
|
||||
t2 = Fp.sqr(t2); // t2 *= t2
|
||||
}
|
||||
// NOTE: r-m-1 can be bigger than 32, need to convert to bigint before shift, otherwise there will be overflow
|
||||
const ge = Fp.pow(g, _1n << BigInt(r - m - 1)); // ge = 2^(r-m-1)
|
||||
g = Fp.sqr(ge); // g = ge * ge
|
||||
x = Fp.mul(x, ge); // x *= ge
|
||||
b = Fp.mul(b, g); // b *= g
|
||||
r = m;
|
||||
}
|
||||
return x;
|
||||
};
|
||||
}
|
||||
export function FpSqrt(P) {
|
||||
// NOTE: different algorithms can give different roots, it is up to user to decide which one they want.
|
||||
// For example there is FpSqrtOdd/FpSqrtEven to choice root based on oddness (used for hash-to-curve).
|
||||
// P ≡ 3 (mod 4)
|
||||
// √n = n^((P+1)/4)
|
||||
if (P % _4n === _3n) {
|
||||
// Not all roots possible!
|
||||
// const ORDER =
|
||||
// 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaabn;
|
||||
// const NUM = 72057594037927816n;
|
||||
const p1div4 = (P + _1n) / _4n;
|
||||
return function sqrt3mod4(Fp, n) {
|
||||
const root = Fp.pow(n, p1div4);
|
||||
// Throw if root**2 != n
|
||||
if (!Fp.eql(Fp.sqr(root), n))
|
||||
throw new Error('Cannot find square root');
|
||||
return root;
|
||||
};
|
||||
}
|
||||
// Atkin algorithm for q ≡ 5 (mod 8), https://eprint.iacr.org/2012/685.pdf (page 10)
|
||||
if (P % _8n === _5n) {
|
||||
const c1 = (P - _5n) / _8n;
|
||||
return function sqrt5mod8(Fp, n) {
|
||||
const n2 = Fp.mul(n, _2n);
|
||||
const v = Fp.pow(n2, c1);
|
||||
const nv = Fp.mul(n, v);
|
||||
const i = Fp.mul(Fp.mul(nv, _2n), v);
|
||||
const root = Fp.mul(nv, Fp.sub(i, Fp.ONE));
|
||||
if (!Fp.eql(Fp.sqr(root), n))
|
||||
throw new Error('Cannot find square root');
|
||||
return root;
|
||||
};
|
||||
}
|
||||
// P ≡ 9 (mod 16)
|
||||
if (P % _16n === _9n) {
|
||||
// NOTE: tonelli is too slow for bls-Fp2 calculations even on start
|
||||
// Means we cannot use sqrt for constants at all!
|
||||
//
|
||||
// const c1 = Fp.sqrt(Fp.negate(Fp.ONE)); // 1. c1 = sqrt(-1) in F, i.e., (c1^2) == -1 in F
|
||||
// const c2 = Fp.sqrt(c1); // 2. c2 = sqrt(c1) in F, i.e., (c2^2) == c1 in F
|
||||
// const c3 = Fp.sqrt(Fp.negate(c1)); // 3. c3 = sqrt(-c1) in F, i.e., (c3^2) == -c1 in F
|
||||
// const c4 = (P + _7n) / _16n; // 4. c4 = (q + 7) / 16 # Integer arithmetic
|
||||
// sqrt = (x) => {
|
||||
// let tv1 = Fp.pow(x, c4); // 1. tv1 = x^c4
|
||||
// let tv2 = Fp.mul(c1, tv1); // 2. tv2 = c1 * tv1
|
||||
// const tv3 = Fp.mul(c2, tv1); // 3. tv3 = c2 * tv1
|
||||
// let tv4 = Fp.mul(c3, tv1); // 4. tv4 = c3 * tv1
|
||||
// const e1 = Fp.equals(Fp.square(tv2), x); // 5. e1 = (tv2^2) == x
|
||||
// const e2 = Fp.equals(Fp.square(tv3), x); // 6. e2 = (tv3^2) == x
|
||||
// tv1 = Fp.cmov(tv1, tv2, e1); // 7. tv1 = CMOV(tv1, tv2, e1) # Select tv2 if (tv2^2) == x
|
||||
// tv2 = Fp.cmov(tv4, tv3, e2); // 8. tv2 = CMOV(tv4, tv3, e2) # Select tv3 if (tv3^2) == x
|
||||
// const e3 = Fp.equals(Fp.square(tv2), x); // 9. e3 = (tv2^2) == x
|
||||
// return Fp.cmov(tv1, tv2, e3); // 10. z = CMOV(tv1, tv2, e3) # Select the sqrt from tv1 and tv2
|
||||
// }
|
||||
}
|
||||
// Other cases: Tonelli-Shanks algorithm
|
||||
return tonelliShanks(P);
|
||||
}
|
||||
// Little-endian check for first LE bit (last BE bit);
|
||||
export const isNegativeLE = (num, modulo) => (mod(num, modulo) & _1n) === _1n;
|
||||
// prettier-ignore
|
||||
const FIELD_FIELDS = [
|
||||
'create', 'isValid', 'is0', 'neg', 'inv', 'sqrt', 'sqr',
|
||||
'eql', 'add', 'sub', 'mul', 'pow', 'div',
|
||||
'addN', 'subN', 'mulN', 'sqrN'
|
||||
];
|
||||
export function validateField(field) {
|
||||
const initial = {
|
||||
ORDER: 'bigint',
|
||||
MASK: 'bigint',
|
||||
BYTES: 'isSafeInteger',
|
||||
BITS: 'isSafeInteger',
|
||||
};
|
||||
const opts = FIELD_FIELDS.reduce((map, val) => {
|
||||
map[val] = 'function';
|
||||
return map;
|
||||
}, initial);
|
||||
return validateObject(field, opts);
|
||||
}
|
||||
// Generic field functions
|
||||
export function FpPow(f, num, power) {
|
||||
// Should have same speed as pow for bigints
|
||||
// TODO: benchmark!
|
||||
if (power < _0n)
|
||||
throw new Error('Expected power > 0');
|
||||
if (power === _0n)
|
||||
return f.ONE;
|
||||
if (power === _1n)
|
||||
return num;
|
||||
let p = f.ONE;
|
||||
let d = num;
|
||||
while (power > _0n) {
|
||||
if (power & _1n)
|
||||
p = f.mul(p, d);
|
||||
d = f.sqr(d);
|
||||
power >>= _1n;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
// 0 is non-invertible: non-batched version will throw on 0
|
||||
export function FpInvertBatch(f, nums) {
|
||||
const tmp = new Array(nums.length);
|
||||
// Walk from first to last, multiply them by each other MOD p
|
||||
const lastMultiplied = nums.reduce((acc, num, i) => {
|
||||
if (f.is0(num))
|
||||
return acc;
|
||||
tmp[i] = acc;
|
||||
return f.mul(acc, num);
|
||||
}, f.ONE);
|
||||
// Invert last element
|
||||
const inverted = f.inv(lastMultiplied);
|
||||
// Walk from last to first, multiply them by inverted each other MOD p
|
||||
nums.reduceRight((acc, num, i) => {
|
||||
if (f.is0(num))
|
||||
return acc;
|
||||
tmp[i] = f.mul(acc, tmp[i]);
|
||||
return f.mul(acc, num);
|
||||
}, inverted);
|
||||
return tmp;
|
||||
}
|
||||
export function FpDiv(f, lhs, rhs) {
|
||||
return f.mul(lhs, typeof rhs === 'bigint' ? invert(rhs, f.ORDER) : f.inv(rhs));
|
||||
}
|
||||
// This function returns True whenever the value x is a square in the field F.
|
||||
export function FpIsSquare(f) {
|
||||
const legendreConst = (f.ORDER - _1n) / _2n; // Integer arithmetic
|
||||
return (x) => {
|
||||
const p = f.pow(x, legendreConst);
|
||||
return f.eql(p, f.ZERO) || f.eql(p, f.ONE);
|
||||
};
|
||||
}
|
||||
// CURVE.n lengths
|
||||
export function nLength(n, nBitLength) {
|
||||
// Bit size, byte size of CURVE.n
|
||||
const _nBitLength = nBitLength !== undefined ? nBitLength : n.toString(2).length;
|
||||
const nByteLength = Math.ceil(_nBitLength / 8);
|
||||
return { nBitLength: _nBitLength, nByteLength };
|
||||
}
|
||||
/**
|
||||
* Initializes a galois field over prime. Non-primes are not supported for now.
|
||||
* Do not init in loop: slow. Very fragile: always run a benchmark on change.
|
||||
* Major performance gains:
|
||||
* a) non-normalized operations like mulN instead of mul
|
||||
* b) `Object.freeze`
|
||||
* c) Same object shape: never add or remove keys
|
||||
* @param ORDER prime positive bigint
|
||||
* @param bitLen how many bits the field consumes
|
||||
* @param isLE (def: false) if encoding / decoding should be in little-endian
|
||||
* @param redef optional faster redefinitions of sqrt and other methods
|
||||
*/
|
||||
export function Field(ORDER, bitLen, isLE = false, redef = {}) {
|
||||
if (ORDER <= _0n)
|
||||
throw new Error(`Expected Fp ORDER > 0, got ${ORDER}`);
|
||||
const { nBitLength: BITS, nByteLength: BYTES } = nLength(ORDER, bitLen);
|
||||
if (BYTES > 2048)
|
||||
throw new Error('Field lengths over 2048 bytes are not supported');
|
||||
const sqrtP = FpSqrt(ORDER);
|
||||
const f = Object.freeze({
|
||||
ORDER,
|
||||
BITS,
|
||||
BYTES,
|
||||
MASK: bitMask(BITS),
|
||||
ZERO: _0n,
|
||||
ONE: _1n,
|
||||
create: (num) => mod(num, ORDER),
|
||||
isValid: (num) => {
|
||||
if (typeof num !== 'bigint')
|
||||
throw new Error(`Invalid field element: expected bigint, got ${typeof num}`);
|
||||
return _0n <= num && num < ORDER; // 0 is valid element, but it's not invertible
|
||||
},
|
||||
is0: (num) => num === _0n,
|
||||
isOdd: (num) => (num & _1n) === _1n,
|
||||
neg: (num) => mod(-num, ORDER),
|
||||
eql: (lhs, rhs) => lhs === rhs,
|
||||
sqr: (num) => mod(num * num, ORDER),
|
||||
add: (lhs, rhs) => mod(lhs + rhs, ORDER),
|
||||
sub: (lhs, rhs) => mod(lhs - rhs, ORDER),
|
||||
mul: (lhs, rhs) => mod(lhs * rhs, ORDER),
|
||||
pow: (num, power) => FpPow(f, num, power),
|
||||
div: (lhs, rhs) => mod(lhs * invert(rhs, ORDER), ORDER),
|
||||
// Same as above, but doesn't normalize
|
||||
sqrN: (num) => num * num,
|
||||
addN: (lhs, rhs) => lhs + rhs,
|
||||
subN: (lhs, rhs) => lhs - rhs,
|
||||
mulN: (lhs, rhs) => lhs * rhs,
|
||||
inv: (num) => invert(num, ORDER),
|
||||
sqrt: redef.sqrt || ((n) => sqrtP(f, n)),
|
||||
invertBatch: (lst) => FpInvertBatch(f, lst),
|
||||
// TODO: do we really need constant cmov?
|
||||
// We don't have const-time bigints anyway, so probably will be not very useful
|
||||
cmov: (a, b, c) => (c ? b : a),
|
||||
toBytes: (num) => (isLE ? numberToBytesLE(num, BYTES) : numberToBytesBE(num, BYTES)),
|
||||
fromBytes: (bytes) => {
|
||||
if (bytes.length !== BYTES)
|
||||
throw new Error(`Fp.fromBytes: expected ${BYTES}, got ${bytes.length}`);
|
||||
return isLE ? bytesToNumberLE(bytes) : bytesToNumberBE(bytes);
|
||||
},
|
||||
});
|
||||
return Object.freeze(f);
|
||||
}
|
||||
export function FpSqrtOdd(Fp, elm) {
|
||||
if (!Fp.isOdd)
|
||||
throw new Error(`Field doesn't have isOdd`);
|
||||
const root = Fp.sqrt(elm);
|
||||
return Fp.isOdd(root) ? root : Fp.neg(root);
|
||||
}
|
||||
export function FpSqrtEven(Fp, elm) {
|
||||
if (!Fp.isOdd)
|
||||
throw new Error(`Field doesn't have isOdd`);
|
||||
const root = Fp.sqrt(elm);
|
||||
return Fp.isOdd(root) ? Fp.neg(root) : root;
|
||||
}
|
||||
/**
|
||||
* FIPS 186 B.4.1-compliant "constant-time" private key generation utility.
|
||||
* Can take (n+8) or more bytes of uniform input e.g. from CSPRNG or KDF
|
||||
* and convert them into private scalar, with the modulo bias being negligible.
|
||||
* Needs at least 40 bytes of input for 32-byte private key.
|
||||
* https://research.kudelskisecurity.com/2020/07/28/the-definitive-guide-to-modulo-bias-and-how-to-avoid-it/
|
||||
* @param hash hash output from SHA3 or a similar function
|
||||
* @param groupOrder size of subgroup - (e.g. curveFn.CURVE.n)
|
||||
* @param isLE interpret hash bytes as LE num
|
||||
* @returns valid private scalar
|
||||
*/
|
||||
export function hashToPrivateScalar(hash, groupOrder, isLE = false) {
|
||||
hash = ensureBytes('privateHash', hash);
|
||||
const hashLen = hash.length;
|
||||
const minLen = nLength(groupOrder).nByteLength + 8;
|
||||
if (minLen < 24 || hashLen < minLen || hashLen > 1024)
|
||||
throw new Error(`hashToPrivateScalar: expected ${minLen}-1024 bytes of input, got ${hashLen}`);
|
||||
const num = isLE ? bytesToNumberLE(hash) : bytesToNumberBE(hash);
|
||||
return mod(num, groupOrder - _1n) + _1n;
|
||||
}
|
||||
//# sourceMappingURL=modular.js.map
|
||||
1
node_modules/@scure/bip32/node_modules/@noble/curves/esm/abstract/modular.js.map
generated
vendored
Normal file
1
node_modules/@scure/bip32/node_modules/@noble/curves/esm/abstract/modular.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
157
node_modules/@scure/bip32/node_modules/@noble/curves/esm/abstract/montgomery.js
generated
vendored
Normal file
157
node_modules/@scure/bip32/node_modules/@noble/curves/esm/abstract/montgomery.js
generated
vendored
Normal file
@@ -0,0 +1,157 @@
|
||||
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||
import { mod, pow } from './modular.js';
|
||||
import { bytesToNumberLE, ensureBytes, numberToBytesLE, validateObject } from './utils.js';
|
||||
const _0n = BigInt(0);
|
||||
const _1n = BigInt(1);
|
||||
function validateOpts(curve) {
|
||||
validateObject(curve, {
|
||||
a: 'bigint',
|
||||
}, {
|
||||
montgomeryBits: 'isSafeInteger',
|
||||
nByteLength: 'isSafeInteger',
|
||||
adjustScalarBytes: 'function',
|
||||
domain: 'function',
|
||||
powPminus2: 'function',
|
||||
Gu: 'bigint',
|
||||
});
|
||||
// Set defaults
|
||||
return Object.freeze({ ...curve });
|
||||
}
|
||||
// NOTE: not really montgomery curve, just bunch of very specific methods for X25519/X448 (RFC 7748, https://www.rfc-editor.org/rfc/rfc7748)
|
||||
// Uses only one coordinate instead of two
|
||||
export function montgomery(curveDef) {
|
||||
const CURVE = validateOpts(curveDef);
|
||||
const { P } = CURVE;
|
||||
const modP = (n) => mod(n, P);
|
||||
const montgomeryBits = CURVE.montgomeryBits;
|
||||
const montgomeryBytes = Math.ceil(montgomeryBits / 8);
|
||||
const fieldLen = CURVE.nByteLength;
|
||||
const adjustScalarBytes = CURVE.adjustScalarBytes || ((bytes) => bytes);
|
||||
const powPminus2 = CURVE.powPminus2 || ((x) => pow(x, P - BigInt(2), P));
|
||||
// cswap from RFC7748. But it is not from RFC7748!
|
||||
/*
|
||||
cswap(swap, x_2, x_3):
|
||||
dummy = mask(swap) AND (x_2 XOR x_3)
|
||||
x_2 = x_2 XOR dummy
|
||||
x_3 = x_3 XOR dummy
|
||||
Return (x_2, x_3)
|
||||
Where mask(swap) is the all-1 or all-0 word of the same length as x_2
|
||||
and x_3, computed, e.g., as mask(swap) = 0 - swap.
|
||||
*/
|
||||
function cswap(swap, x_2, x_3) {
|
||||
const dummy = modP(swap * (x_2 - x_3));
|
||||
x_2 = modP(x_2 - dummy);
|
||||
x_3 = modP(x_3 + dummy);
|
||||
return [x_2, x_3];
|
||||
}
|
||||
// Accepts 0 as well
|
||||
function assertFieldElement(n) {
|
||||
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
|
||||
* @param scalar by which the point would be multiplied
|
||||
* @returns new Point on Montgomery curve
|
||||
*/
|
||||
function montgomeryLadder(pointU, scalar) {
|
||||
const u = assertFieldElement(pointU);
|
||||
// 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);
|
||||
const x_1 = u;
|
||||
let x_2 = _1n;
|
||||
let z_2 = _0n;
|
||||
let x_3 = u;
|
||||
let z_3 = _1n;
|
||||
let swap = _0n;
|
||||
let sw;
|
||||
for (let t = BigInt(montgomeryBits - 1); t >= _0n; t--) {
|
||||
const k_t = (k >> t) & _1n;
|
||||
swap ^= k_t;
|
||||
sw = cswap(swap, x_2, x_3);
|
||||
x_2 = sw[0];
|
||||
x_3 = sw[1];
|
||||
sw = cswap(swap, z_2, z_3);
|
||||
z_2 = sw[0];
|
||||
z_3 = sw[1];
|
||||
swap = k_t;
|
||||
const A = x_2 + z_2;
|
||||
const AA = modP(A * A);
|
||||
const B = x_2 - z_2;
|
||||
const BB = modP(B * B);
|
||||
const E = AA - BB;
|
||||
const C = x_3 + z_3;
|
||||
const D = x_3 - z_3;
|
||||
const DA = modP(D * A);
|
||||
const CB = modP(C * B);
|
||||
const dacb = DA + CB;
|
||||
const da_cb = DA - CB;
|
||||
x_3 = modP(dacb * dacb);
|
||||
z_3 = modP(x_1 * modP(da_cb * da_cb));
|
||||
x_2 = modP(AA * BB);
|
||||
z_2 = modP(E * (AA + modP(a24 * E)));
|
||||
}
|
||||
// (x_2, x_3) = cswap(swap, x_2, x_3)
|
||||
sw = cswap(swap, x_2, x_3);
|
||||
x_2 = sw[0];
|
||||
x_3 = sw[1];
|
||||
// (z_2, z_3) = cswap(swap, z_2, z_3)
|
||||
sw = cswap(swap, z_2, z_3);
|
||||
z_2 = sw[0];
|
||||
z_3 = sw[1];
|
||||
// z_2^(p - 2)
|
||||
const z2 = powPminus2(z_2);
|
||||
// Return x_2 * (z_2^(p - 2))
|
||||
return modP(x_2 * z2);
|
||||
}
|
||||
function encodeUCoordinate(u) {
|
||||
return numberToBytesLE(modP(u), montgomeryBytes);
|
||||
}
|
||||
function decodeUCoordinate(uEnc) {
|
||||
// Section 5: When receiving such an array, implementations of X25519
|
||||
// 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('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) {
|
||||
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));
|
||||
}
|
||||
function scalarMult(scalar, u) {
|
||||
const pointU = decodeUCoordinate(u);
|
||||
const _scalar = decodeScalar(scalar);
|
||||
const pu = montgomeryLadder(pointU, _scalar);
|
||||
// The result was not contributory
|
||||
// https://cr.yp.to/ecdh.html#validate
|
||||
if (pu === _0n)
|
||||
throw new Error('Invalid private or public key received');
|
||||
return encodeUCoordinate(pu);
|
||||
}
|
||||
// Computes public key from private. By doing scalar multiplication of base point.
|
||||
const GuBytes = encodeUCoordinate(CURVE.Gu);
|
||||
function scalarMultBase(scalar) {
|
||||
return scalarMult(scalar, GuBytes);
|
||||
}
|
||||
return {
|
||||
scalarMult,
|
||||
scalarMultBase,
|
||||
getSharedSecret: (privateKey, publicKey) => scalarMult(privateKey, publicKey),
|
||||
getPublicKey: (privateKey) => scalarMultBase(privateKey),
|
||||
utils: { randomPrivateKey: () => CURVE.randomBytes(CURVE.nByteLength) },
|
||||
GuBytes: GuBytes,
|
||||
};
|
||||
}
|
||||
//# sourceMappingURL=montgomery.js.map
|
||||
1
node_modules/@scure/bip32/node_modules/@noble/curves/esm/abstract/montgomery.js.map
generated
vendored
Normal file
1
node_modules/@scure/bip32/node_modules/@noble/curves/esm/abstract/montgomery.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
110
node_modules/@scure/bip32/node_modules/@noble/curves/esm/abstract/poseidon.js
generated
vendored
Normal file
110
node_modules/@scure/bip32/node_modules/@noble/curves/esm/abstract/poseidon.js
generated
vendored
Normal file
@@ -0,0 +1,110 @@
|
||||
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||
// Poseidon Hash: https://eprint.iacr.org/2019/458.pdf, https://www.poseidon-hash.info
|
||||
import { FpPow, validateField } from './modular.js';
|
||||
export function validateOpts(opts) {
|
||||
const { Fp } = opts;
|
||||
validateField(Fp);
|
||||
for (const i of ['t', 'roundsFull', 'roundsPartial']) {
|
||||
if (typeof opts[i] !== 'number' || !Number.isSafeInteger(opts[i]))
|
||||
throw new Error(`Poseidon: invalid param ${i}=${opts[i]} (${typeof opts[i]})`);
|
||||
}
|
||||
if (opts.reversePartialPowIdx !== undefined && typeof opts.reversePartialPowIdx !== 'boolean')
|
||||
throw new Error(`Poseidon: invalid param reversePartialPowIdx=${opts.reversePartialPowIdx}`);
|
||||
// Default is 5, but by some reasons stark uses 3
|
||||
let sboxPower = opts.sboxPower;
|
||||
if (sboxPower === undefined)
|
||||
sboxPower = 5;
|
||||
if (typeof sboxPower !== 'number' || !Number.isSafeInteger(sboxPower))
|
||||
throw new Error(`Poseidon wrong sboxPower=${sboxPower}`);
|
||||
const _sboxPower = BigInt(sboxPower);
|
||||
let sboxFn = (n) => FpPow(Fp, n, _sboxPower);
|
||||
// Unwrapped sbox power for common cases (195->142μs)
|
||||
if (sboxPower === 3)
|
||||
sboxFn = (n) => Fp.mul(Fp.sqrN(n), n);
|
||||
else if (sboxPower === 5)
|
||||
sboxFn = (n) => Fp.mul(Fp.sqrN(Fp.sqrN(n)), n);
|
||||
if (opts.roundsFull % 2 !== 0)
|
||||
throw new Error(`Poseidon roundsFull is not even: ${opts.roundsFull}`);
|
||||
const rounds = opts.roundsFull + opts.roundsPartial;
|
||||
if (!Array.isArray(opts.roundConstants) || opts.roundConstants.length !== rounds)
|
||||
throw new Error('Poseidon: wrong round constants');
|
||||
const roundConstants = opts.roundConstants.map((rc) => {
|
||||
if (!Array.isArray(rc) || rc.length !== opts.t)
|
||||
throw new Error(`Poseidon wrong round constants: ${rc}`);
|
||||
return rc.map((i) => {
|
||||
if (typeof i !== 'bigint' || !Fp.isValid(i))
|
||||
throw new Error(`Poseidon wrong round constant=${i}`);
|
||||
return Fp.create(i);
|
||||
});
|
||||
});
|
||||
// MDS is TxT matrix
|
||||
if (!Array.isArray(opts.mds) || opts.mds.length !== opts.t)
|
||||
throw new Error('Poseidon: wrong MDS matrix');
|
||||
const mds = opts.mds.map((mdsRow) => {
|
||||
if (!Array.isArray(mdsRow) || mdsRow.length !== opts.t)
|
||||
throw new Error(`Poseidon MDS matrix row: ${mdsRow}`);
|
||||
return mdsRow.map((i) => {
|
||||
if (typeof i !== 'bigint')
|
||||
throw new Error(`Poseidon MDS matrix value=${i}`);
|
||||
return Fp.create(i);
|
||||
});
|
||||
});
|
||||
return Object.freeze({ ...opts, rounds, sboxFn, roundConstants, mds });
|
||||
}
|
||||
export function splitConstants(rc, t) {
|
||||
if (typeof t !== 'number')
|
||||
throw new Error('poseidonSplitConstants: wrong t');
|
||||
if (!Array.isArray(rc) || rc.length % t)
|
||||
throw new Error('poseidonSplitConstants: wrong rc');
|
||||
const res = [];
|
||||
let tmp = [];
|
||||
for (let i = 0; i < rc.length; i++) {
|
||||
tmp.push(rc[i]);
|
||||
if (tmp.length === t) {
|
||||
res.push(tmp);
|
||||
tmp = [];
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
export function poseidon(opts) {
|
||||
const { t, Fp, rounds, sboxFn, reversePartialPowIdx } = validateOpts(opts);
|
||||
const halfRoundsFull = Math.floor(opts.roundsFull / 2);
|
||||
const partialIdx = reversePartialPowIdx ? t - 1 : 0;
|
||||
const poseidonRound = (values, isFull, idx) => {
|
||||
values = values.map((i, j) => Fp.add(i, opts.roundConstants[idx][j]));
|
||||
if (isFull)
|
||||
values = values.map((i) => sboxFn(i));
|
||||
else
|
||||
values[partialIdx] = sboxFn(values[partialIdx]);
|
||||
// Matrix multiplication
|
||||
values = opts.mds.map((i) => i.reduce((acc, i, j) => Fp.add(acc, Fp.mulN(i, values[j])), Fp.ZERO));
|
||||
return values;
|
||||
};
|
||||
const poseidonHash = function poseidonHash(values) {
|
||||
if (!Array.isArray(values) || values.length !== t)
|
||||
throw new Error(`Poseidon: wrong values (expected array of bigints with length ${t})`);
|
||||
values = values.map((i) => {
|
||||
if (typeof i !== 'bigint')
|
||||
throw new Error(`Poseidon: wrong value=${i} (${typeof i})`);
|
||||
return Fp.create(i);
|
||||
});
|
||||
let round = 0;
|
||||
// Apply r_f/2 full rounds.
|
||||
for (let i = 0; i < halfRoundsFull; i++)
|
||||
values = poseidonRound(values, true, round++);
|
||||
// Apply r_p partial rounds.
|
||||
for (let i = 0; i < opts.roundsPartial; i++)
|
||||
values = poseidonRound(values, false, round++);
|
||||
// Apply r_f/2 full rounds.
|
||||
for (let i = 0; i < halfRoundsFull; i++)
|
||||
values = poseidonRound(values, true, round++);
|
||||
if (round !== rounds)
|
||||
throw new Error(`Poseidon: wrong number of rounds: last round=${round}, total=${rounds}`);
|
||||
return values;
|
||||
};
|
||||
// For verification in tests
|
||||
poseidonHash.roundConstants = opts.roundConstants;
|
||||
return poseidonHash;
|
||||
}
|
||||
//# sourceMappingURL=poseidon.js.map
|
||||
1
node_modules/@scure/bip32/node_modules/@noble/curves/esm/abstract/poseidon.js.map
generated
vendored
Normal file
1
node_modules/@scure/bip32/node_modules/@noble/curves/esm/abstract/poseidon.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
265
node_modules/@scure/bip32/node_modules/@noble/curves/esm/abstract/utils.js
generated
vendored
Normal file
265
node_modules/@scure/bip32/node_modules/@noble/curves/esm/abstract/utils.js
generated
vendored
Normal file
@@ -0,0 +1,265 @@
|
||||
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||
// 100 lines of code in the file are duplicated from noble-hashes (utils).
|
||||
// This is OK: `abstract` directory does not use noble-hashes.
|
||||
// User may opt-in into using different hashing library. This way, noble-hashes
|
||||
// won't be included into their bundle.
|
||||
const _0n = BigInt(0);
|
||||
const _1n = BigInt(1);
|
||||
const _2n = BigInt(2);
|
||||
const u8a = (a) => a instanceof Uint8Array;
|
||||
const hexes = Array.from({ length: 256 }, (v, i) => i.toString(16).padStart(2, '0'));
|
||||
/**
|
||||
* @example bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])) // 'cafe0123'
|
||||
*/
|
||||
export function bytesToHex(bytes) {
|
||||
if (!u8a(bytes))
|
||||
throw new Error('Uint8Array expected');
|
||||
// pre-caching improves the speed 6x
|
||||
let hex = '';
|
||||
for (let i = 0; i < bytes.length; i++) {
|
||||
hex += hexes[bytes[i]];
|
||||
}
|
||||
return hex;
|
||||
}
|
||||
export function numberToHexUnpadded(num) {
|
||||
const hex = num.toString(16);
|
||||
return hex.length & 1 ? `0${hex}` : hex;
|
||||
}
|
||||
export function hexToNumber(hex) {
|
||||
if (typeof hex !== 'string')
|
||||
throw new Error('hex string expected, got ' + typeof hex);
|
||||
// Big Endian
|
||||
return BigInt(hex === '' ? '0' : `0x${hex}`);
|
||||
}
|
||||
/**
|
||||
* @example hexToBytes('cafe0123') // Uint8Array.from([0xca, 0xfe, 0x01, 0x23])
|
||||
*/
|
||||
export function hexToBytes(hex) {
|
||||
if (typeof hex !== 'string')
|
||||
throw new Error('hex string expected, got ' + typeof hex);
|
||||
const len = hex.length;
|
||||
if (len % 2)
|
||||
throw new Error('padded hex string expected, got unpadded hex of length ' + len);
|
||||
const array = new Uint8Array(len / 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;
|
||||
}
|
||||
// BE: Big Endian, LE: Little Endian
|
||||
export function bytesToNumberBE(bytes) {
|
||||
return hexToNumber(bytesToHex(bytes));
|
||||
}
|
||||
export function bytesToNumberLE(bytes) {
|
||||
if (!u8a(bytes))
|
||||
throw new Error('Uint8Array expected');
|
||||
return hexToNumber(bytesToHex(Uint8Array.from(bytes).reverse()));
|
||||
}
|
||||
export function numberToBytesBE(n, len) {
|
||||
return hexToBytes(n.toString(16).padStart(len * 2, '0'));
|
||||
}
|
||||
export function numberToBytesLE(n, len) {
|
||||
return numberToBytesBE(n, len).reverse();
|
||||
}
|
||||
// Unpadded, rarely used
|
||||
export function numberToVarBytesBE(n) {
|
||||
return hexToBytes(numberToHexUnpadded(n));
|
||||
}
|
||||
/**
|
||||
* Takes hex string or Uint8Array, converts to Uint8Array.
|
||||
* Validates output length.
|
||||
* Will throw error for other types.
|
||||
* @param title descriptive title for an error e.g. 'private key'
|
||||
* @param hex hex string or Uint8Array
|
||||
* @param expectedLength optional, will compare to result array's length
|
||||
* @returns
|
||||
*/
|
||||
export function ensureBytes(title, hex, expectedLength) {
|
||||
let res;
|
||||
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.
|
||||
*/
|
||||
export function concatBytes(...arrays) {
|
||||
const r = new Uint8Array(arrays.reduce((sum, a) => sum + a.length, 0));
|
||||
let pad = 0; // walk through each item, ensure they have proper type
|
||||
arrays.forEach((a) => {
|
||||
if (!u8a(a))
|
||||
throw new Error('Uint8Array expected');
|
||||
r.set(a, pad);
|
||||
pad += a.length;
|
||||
});
|
||||
return r;
|
||||
}
|
||||
export function equalBytes(b1, b2) {
|
||||
// We don't care about timing attacks here
|
||||
if (b1.length !== b2.length)
|
||||
return false;
|
||||
for (let i = 0; i < b1.length; i++)
|
||||
if (b1[i] !== b2[i])
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* @example utf8ToBytes('abc') // new Uint8Array([97, 98, 99])
|
||||
*/
|
||||
export function utf8ToBytes(str) {
|
||||
if (typeof str !== 'string')
|
||||
throw new Error(`utf8ToBytes expected string, got ${typeof str}`);
|
||||
return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809
|
||||
}
|
||||
// Bit operations
|
||||
/**
|
||||
* Calculates amount of bits in a bigint.
|
||||
* Same as `n.toString(2).length`
|
||||
*/
|
||||
export function bitLen(n) {
|
||||
let len;
|
||||
for (len = 0; n > _0n; n >>= _1n, len += 1)
|
||||
;
|
||||
return len;
|
||||
}
|
||||
/**
|
||||
* Gets single bit at position.
|
||||
* NOTE: first bit position is 0 (same as arrays)
|
||||
* Same as `!!+Array.from(n.toString(2)).reverse()[pos]`
|
||||
*/
|
||||
export function bitGet(n, pos) {
|
||||
return (n >> BigInt(pos)) & _1n;
|
||||
}
|
||||
/**
|
||||
* Sets single bit at position.
|
||||
*/
|
||||
export const bitSet = (n, pos, value) => {
|
||||
return n | ((value ? _1n : _0n) << BigInt(pos));
|
||||
};
|
||||
/**
|
||||
* Calculate mask for N bits. Not using ** operator with bigints because of old engines.
|
||||
* Same as BigInt(`0b${Array(i).fill('1').join('')}`)
|
||||
*/
|
||||
export const bitMask = (n) => (_2n << BigInt(n - 1)) - _1n;
|
||||
// DRBG
|
||||
const u8n = (data) => new Uint8Array(data); // creates Uint8Array
|
||||
const u8fr = (arr) => Uint8Array.from(arr); // another shortcut
|
||||
/**
|
||||
* 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(hashLen, qByteLen, hmacFn) {
|
||||
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) => 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 = [];
|
||||
while (len < qByteLen) {
|
||||
v = h();
|
||||
const sl = v.slice();
|
||||
out.push(sl);
|
||||
len += v.length;
|
||||
}
|
||||
return concatBytes(...out);
|
||||
};
|
||||
const genUntil = (seed, pred) => {
|
||||
reset();
|
||||
reseed(seed); // Steps D-G
|
||||
let res = 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) => typeof val === 'bigint',
|
||||
function: (val) => typeof val === 'function',
|
||||
boolean: (val) => typeof val === 'boolean',
|
||||
string: (val) => typeof val === 'string',
|
||||
isSafeInteger: (val) => Number.isSafeInteger(val),
|
||||
array: (val) => Array.isArray(val),
|
||||
field: (val, object) => object.Fp.isValid(val),
|
||||
hash: (val) => typeof val === 'function' && Number.isSafeInteger(val.outputLen),
|
||||
};
|
||||
// type Record<K extends string | number | symbol, T> = { [P in K]: T; }
|
||||
export function validateObject(object, validators, optValidators = {}) {
|
||||
const checkField = (fieldName, type, isOptional) => {
|
||||
const checkVal = validatorFns[type];
|
||||
if (typeof checkVal !== 'function')
|
||||
throw new Error(`Invalid validator "${type}", expected function`);
|
||||
const val = object[fieldName];
|
||||
if (isOptional && val === undefined)
|
||||
return;
|
||||
if (!checkVal(val, object)) {
|
||||
throw new Error(`Invalid param ${String(fieldName)}=${val} (${typeof val}), expected ${type}`);
|
||||
}
|
||||
};
|
||||
for (const [fieldName, type] of Object.entries(validators))
|
||||
checkField(fieldName, type, false);
|
||||
for (const [fieldName, type] of Object.entries(optValidators))
|
||||
checkField(fieldName, type, true);
|
||||
return object;
|
||||
}
|
||||
// validate type tests
|
||||
// const o: { a: number; b: number; c: number } = { a: 1, b: 5, c: 6 };
|
||||
// const z0 = validateObject(o, { a: 'isSafeInteger' }, { c: 'bigint' }); // Ok!
|
||||
// // Should fail type-check
|
||||
// const z1 = validateObject(o, { a: 'tmp' }, { c: 'zz' });
|
||||
// const z2 = validateObject(o, { a: 'isSafeInteger' }, { c: 'zz' });
|
||||
// const z3 = validateObject(o, { test: 'boolean', z: 'bug' });
|
||||
// const z4 = validateObject(o, { a: 'boolean', z: 'bug' });
|
||||
//# sourceMappingURL=utils.js.map
|
||||
1
node_modules/@scure/bip32/node_modules/@noble/curves/esm/abstract/utils.js.map
generated
vendored
Normal file
1
node_modules/@scure/bip32/node_modules/@noble/curves/esm/abstract/utils.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
1054
node_modules/@scure/bip32/node_modules/@noble/curves/esm/abstract/weierstrass.js
generated
vendored
Normal file
1054
node_modules/@scure/bip32/node_modules/@noble/curves/esm/abstract/weierstrass.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
node_modules/@scure/bip32/node_modules/@noble/curves/esm/abstract/weierstrass.js.map
generated
vendored
Normal file
1
node_modules/@scure/bip32/node_modules/@noble/curves/esm/abstract/weierstrass.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
1173
node_modules/@scure/bip32/node_modules/@noble/curves/esm/bls12-381.js
generated
vendored
Normal file
1173
node_modules/@scure/bip32/node_modules/@noble/curves/esm/bls12-381.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
node_modules/@scure/bip32/node_modules/@noble/curves/esm/bls12-381.js.map
generated
vendored
Normal file
1
node_modules/@scure/bip32/node_modules/@noble/curves/esm/bls12-381.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
22
node_modules/@scure/bip32/node_modules/@noble/curves/esm/bn254.js
generated
vendored
Normal file
22
node_modules/@scure/bip32/node_modules/@noble/curves/esm/bn254.js
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||
import { sha256 } from '@noble/hashes/sha256';
|
||||
import { weierstrass } from './abstract/weierstrass.js';
|
||||
import { getHash } from './_shortw_utils.js';
|
||||
import { Field } from './abstract/modular.js';
|
||||
/**
|
||||
* bn254 pairing-friendly curve.
|
||||
* Previously known as alt_bn_128, when it had 128-bit security.
|
||||
* Recent research shown it's weaker, the naming has been adjusted to its prime bit count.
|
||||
* https://github.com/zcash/zcash/issues/2502
|
||||
*/
|
||||
export const bn254 = weierstrass({
|
||||
a: BigInt(0),
|
||||
b: BigInt(3),
|
||||
Fp: Field(BigInt('0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47')),
|
||||
n: BigInt('0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001'),
|
||||
Gx: BigInt(1),
|
||||
Gy: BigInt(2),
|
||||
h: BigInt(1),
|
||||
...getHash(sha256),
|
||||
});
|
||||
//# sourceMappingURL=bn254.js.map
|
||||
1
node_modules/@scure/bip32/node_modules/@noble/curves/esm/bn254.js.map
generated
vendored
Normal file
1
node_modules/@scure/bip32/node_modules/@noble/curves/esm/bn254.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"bn254.js","sourceRoot":"","sources":["../src/bn254.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C;;;;;GAKG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG,WAAW,CAAC;IAC/B,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;IACZ,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;IACZ,EAAE,EAAE,KAAK,CAAC,MAAM,CAAC,oEAAoE,CAAC,CAAC;IACvF,CAAC,EAAE,MAAM,CAAC,oEAAoE,CAAC;IAC/E,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC;IACb,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC;IACb,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;IACZ,GAAG,OAAO,CAAC,MAAM,CAAC;CACnB,CAAC,CAAC"}
|
||||
430
node_modules/@scure/bip32/node_modules/@noble/curves/esm/ed25519.js
generated
vendored
Normal file
430
node_modules/@scure/bip32/node_modules/@noble/curves/esm/ed25519.js
generated
vendored
Normal file
@@ -0,0 +1,430 @@
|
||||
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||
import { sha512 } from '@noble/hashes/sha512';
|
||||
import { concatBytes, randomBytes, utf8ToBytes } from '@noble/hashes/utils';
|
||||
import { twistedEdwards } from './abstract/edwards.js';
|
||||
import { montgomery } from './abstract/montgomery.js';
|
||||
import { Field, FpSqrtEven, isNegativeLE, mod, pow2 } from './abstract/modular.js';
|
||||
import { bytesToHex, bytesToNumberLE, ensureBytes, equalBytes, numberToBytesLE, } from './abstract/utils.js';
|
||||
import { createHasher, expand_message_xmd } from './abstract/hash-to-curve.js';
|
||||
/**
|
||||
* ed25519 Twisted Edwards curve with following addons:
|
||||
* - X25519 ECDH
|
||||
* - Ristretto cofactor elimination
|
||||
* - Elligator hash-to-group / point indistinguishability
|
||||
*/
|
||||
const ED25519_P = BigInt('57896044618658097711785492504343953926634992332820282019728792003956564819949');
|
||||
// √(-1) aka √(a) aka 2^((p-1)/4)
|
||||
const ED25519_SQRT_M1 = BigInt('19681161376707505956807079304988542015446066515923890162744021073123829784752');
|
||||
// prettier-ignore
|
||||
const _0n = BigInt(0), _1n = BigInt(1), _2n = BigInt(2), _5n = BigInt(5);
|
||||
// prettier-ignore
|
||||
const _10n = BigInt(10), _20n = BigInt(20), _40n = BigInt(40), _80n = BigInt(80);
|
||||
function ed25519_pow_2_252_3(x) {
|
||||
const P = ED25519_P;
|
||||
const x2 = (x * x) % P;
|
||||
const b2 = (x2 * x) % P; // x^3, 11
|
||||
const b4 = (pow2(b2, _2n, P) * b2) % P; // x^15, 1111
|
||||
const b5 = (pow2(b4, _1n, P) * x) % P; // x^31
|
||||
const b10 = (pow2(b5, _5n, P) * b5) % P;
|
||||
const b20 = (pow2(b10, _10n, P) * b10) % P;
|
||||
const b40 = (pow2(b20, _20n, P) * b20) % P;
|
||||
const b80 = (pow2(b40, _40n, P) * b40) % P;
|
||||
const b160 = (pow2(b80, _80n, P) * b80) % P;
|
||||
const b240 = (pow2(b160, _80n, P) * b80) % P;
|
||||
const b250 = (pow2(b240, _10n, P) * b10) % P;
|
||||
const pow_p_5_8 = (pow2(b250, _2n, P) * x) % P;
|
||||
// ^ To pow to (p+3)/8, multiply it by x.
|
||||
return { pow_p_5_8, b2 };
|
||||
}
|
||||
function adjustScalarBytes(bytes) {
|
||||
// Section 5: For X25519, in order to decode 32 random bytes as an integer scalar,
|
||||
// set the three least significant bits of the first byte
|
||||
bytes[0] &= 248; // 0b1111_1000
|
||||
// and the most significant bit of the last to zero,
|
||||
bytes[31] &= 127; // 0b0111_1111
|
||||
// set the second most significant bit of the last byte to 1
|
||||
bytes[31] |= 64; // 0b0100_0000
|
||||
return bytes;
|
||||
}
|
||||
// sqrt(u/v)
|
||||
function uvRatio(u, v) {
|
||||
const P = ED25519_P;
|
||||
const v3 = mod(v * v * v, P); // v³
|
||||
const v7 = mod(v3 * v3 * v, P); // v⁷
|
||||
// (p+3)/8 and (p-5)/8
|
||||
const pow = ed25519_pow_2_252_3(u * v7).pow_p_5_8;
|
||||
let x = mod(u * v3 * pow, P); // (uv³)(uv⁷)^(p-5)/8
|
||||
const vx2 = mod(v * x * x, P); // vx²
|
||||
const root1 = x; // First root candidate
|
||||
const root2 = mod(x * ED25519_SQRT_M1, P); // Second root candidate
|
||||
const useRoot1 = vx2 === u; // If vx² = u (mod p), x is a square root
|
||||
const useRoot2 = vx2 === mod(-u, P); // If vx² = -u, set x <-- x * 2^((p-1)/4)
|
||||
const noRoot = vx2 === mod(-u * ED25519_SQRT_M1, P); // There is no valid root, vx² = -u√(-1)
|
||||
if (useRoot1)
|
||||
x = root1;
|
||||
if (useRoot2 || noRoot)
|
||||
x = root2; // We return root2 anyway, for const-time
|
||||
if (isNegativeLE(x, P))
|
||||
x = mod(-x, P);
|
||||
return { isValid: useRoot1 || useRoot2, value: x };
|
||||
}
|
||||
// Just in case
|
||||
export const ED25519_TORSION_SUBGROUP = [
|
||||
'0100000000000000000000000000000000000000000000000000000000000000',
|
||||
'c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac037a',
|
||||
'0000000000000000000000000000000000000000000000000000000000000080',
|
||||
'26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc05',
|
||||
'ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f',
|
||||
'26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc85',
|
||||
'0000000000000000000000000000000000000000000000000000000000000000',
|
||||
'c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac03fa',
|
||||
];
|
||||
const Fp = Field(ED25519_P, undefined, true);
|
||||
const ed25519Defaults = {
|
||||
// Param: a
|
||||
a: BigInt(-1),
|
||||
// d is equal to -121665/121666 over finite field.
|
||||
// Negative number is P - number, and division is invert(number, P)
|
||||
d: BigInt('37095705934669439343138083508754565189542113879843219016388785533085940283555'),
|
||||
// Finite field 𝔽p over which we'll do calculations; 2n**255n - 19n
|
||||
Fp,
|
||||
// Subgroup order: how many points curve has
|
||||
// 2n**252n + 27742317777372353535851937790883648493n;
|
||||
n: BigInt('7237005577332262213973186563042994240857116359379907606001950938285454250989'),
|
||||
// Cofactor
|
||||
h: BigInt(8),
|
||||
// Base point (x, y) aka generator point
|
||||
Gx: BigInt('15112221349535400772501151409588531511454012693041857206046113283949847762202'),
|
||||
Gy: BigInt('46316835694926478169428394003475163141307993866256225615783033603165251855960'),
|
||||
hash: sha512,
|
||||
randomBytes,
|
||||
adjustScalarBytes,
|
||||
// dom2
|
||||
// Ratio of u to v. Allows us to combine inversion and square root. Uses algo from RFC8032 5.1.3.
|
||||
// Constant-time, u/√v
|
||||
uvRatio,
|
||||
};
|
||||
export const ed25519 = twistedEdwards(ed25519Defaults);
|
||||
function ed25519_domain(data, ctx, phflag) {
|
||||
if (ctx.length > 255)
|
||||
throw new Error('Context is too big');
|
||||
return concatBytes(utf8ToBytes('SigEd25519 no Ed25519 collisions'), new Uint8Array([phflag ? 1 : 0, ctx.length]), ctx, data);
|
||||
}
|
||||
export const ed25519ctx = twistedEdwards({ ...ed25519Defaults, domain: ed25519_domain });
|
||||
export const ed25519ph = twistedEdwards({
|
||||
...ed25519Defaults,
|
||||
domain: ed25519_domain,
|
||||
prehash: sha512,
|
||||
});
|
||||
export const x25519 = /* @__PURE__ */ (() => montgomery({
|
||||
P: ED25519_P,
|
||||
a: BigInt(486662),
|
||||
montgomeryBits: 255,
|
||||
nByteLength: 32,
|
||||
Gu: BigInt(9),
|
||||
powPminus2: (x) => {
|
||||
const P = ED25519_P;
|
||||
// x^(p-2) aka x^(2^255-21)
|
||||
const { pow_p_5_8, b2 } = ed25519_pow_2_252_3(x);
|
||||
return mod(pow2(pow_p_5_8, BigInt(3), P) * b2, P);
|
||||
},
|
||||
adjustScalarBytes,
|
||||
randomBytes,
|
||||
}))();
|
||||
/**
|
||||
* Converts ed25519 public key to x25519 public key. Uses formula:
|
||||
* * `(u, v) = ((1+y)/(1-y), sqrt(-486664)*u/x)`
|
||||
* * `(x, y) = (sqrt(-486664)*u/v, (u-1)/(u+1))`
|
||||
* @example
|
||||
* const someonesPub = ed25519.getPublicKey(ed25519.utils.randomPrivateKey());
|
||||
* const aPriv = x25519.utils.randomPrivateKey();
|
||||
* x25519.getSharedSecret(aPriv, edwardsToMontgomeryPub(someonesPub))
|
||||
*/
|
||||
export function edwardsToMontgomeryPub(edwardsPub) {
|
||||
const { y } = ed25519.ExtendedPoint.fromHex(edwardsPub);
|
||||
const _1n = BigInt(1);
|
||||
return Fp.toBytes(Fp.create((_1n + y) * Fp.inv(_1n - y)));
|
||||
}
|
||||
export const edwardsToMontgomery = edwardsToMontgomeryPub; // deprecated
|
||||
/**
|
||||
* Converts ed25519 secret key to x25519 secret key.
|
||||
* @example
|
||||
* const someonesPub = x25519.getPublicKey(x25519.utils.randomPrivateKey());
|
||||
* const aPriv = ed25519.utils.randomPrivateKey();
|
||||
* x25519.getSharedSecret(edwardsToMontgomeryPriv(aPriv), someonesPub)
|
||||
*/
|
||||
export function edwardsToMontgomeryPriv(edwardsPriv) {
|
||||
const hashed = ed25519Defaults.hash(edwardsPriv.subarray(0, 32));
|
||||
return ed25519Defaults.adjustScalarBytes(hashed).subarray(0, 32);
|
||||
}
|
||||
// Hash To Curve Elligator2 Map (NOTE: different from ristretto255 elligator)
|
||||
// NOTE: very important part is usage of FpSqrtEven for ELL2_C1_EDWARDS, since
|
||||
// SageMath returns different root first and everything falls apart
|
||||
const ELL2_C1 = (Fp.ORDER + BigInt(3)) / BigInt(8); // 1. c1 = (q + 3) / 8 # Integer arithmetic
|
||||
const ELL2_C2 = Fp.pow(_2n, ELL2_C1); // 2. c2 = 2^c1
|
||||
const ELL2_C3 = Fp.sqrt(Fp.neg(Fp.ONE)); // 3. c3 = sqrt(-1)
|
||||
const ELL2_C4 = (Fp.ORDER - BigInt(5)) / BigInt(8); // 4. c4 = (q - 5) / 8 # Integer arithmetic
|
||||
const ELL2_J = BigInt(486662);
|
||||
// prettier-ignore
|
||||
function map_to_curve_elligator2_curve25519(u) {
|
||||
let tv1 = Fp.sqr(u); // 1. tv1 = u^2
|
||||
tv1 = Fp.mul(tv1, _2n); // 2. tv1 = 2 * tv1
|
||||
let xd = Fp.add(tv1, Fp.ONE); // 3. xd = tv1 + 1 # Nonzero: -1 is square (mod p), tv1 is not
|
||||
let x1n = Fp.neg(ELL2_J); // 4. x1n = -J # x1 = x1n / xd = -J / (1 + 2 * u^2)
|
||||
let tv2 = Fp.sqr(xd); // 5. tv2 = xd^2
|
||||
let gxd = Fp.mul(tv2, xd); // 6. gxd = tv2 * xd # gxd = xd^3
|
||||
let gx1 = Fp.mul(tv1, ELL2_J); // 7. gx1 = J * tv1 # x1n + J * xd
|
||||
gx1 = Fp.mul(gx1, x1n); // 8. gx1 = gx1 * x1n # x1n^2 + J * x1n * xd
|
||||
gx1 = Fp.add(gx1, tv2); // 9. gx1 = gx1 + tv2 # x1n^2 + J * x1n * xd + xd^2
|
||||
gx1 = Fp.mul(gx1, x1n); // 10. gx1 = gx1 * x1n # x1n^3 + J * x1n^2 * xd + x1n * xd^2
|
||||
let tv3 = Fp.sqr(gxd); // 11. tv3 = gxd^2
|
||||
tv2 = Fp.sqr(tv3); // 12. tv2 = tv3^2 # gxd^4
|
||||
tv3 = Fp.mul(tv3, gxd); // 13. tv3 = tv3 * gxd # gxd^3
|
||||
tv3 = Fp.mul(tv3, gx1); // 14. tv3 = tv3 * gx1 # gx1 * gxd^3
|
||||
tv2 = Fp.mul(tv2, tv3); // 15. tv2 = tv2 * tv3 # gx1 * gxd^7
|
||||
let y11 = Fp.pow(tv2, ELL2_C4); // 16. y11 = tv2^c4 # (gx1 * gxd^7)^((p - 5) / 8)
|
||||
y11 = Fp.mul(y11, tv3); // 17. y11 = y11 * tv3 # gx1*gxd^3*(gx1*gxd^7)^((p-5)/8)
|
||||
let y12 = Fp.mul(y11, ELL2_C3); // 18. y12 = y11 * c3
|
||||
tv2 = Fp.sqr(y11); // 19. tv2 = y11^2
|
||||
tv2 = Fp.mul(tv2, gxd); // 20. tv2 = tv2 * gxd
|
||||
let e1 = Fp.eql(tv2, gx1); // 21. e1 = tv2 == gx1
|
||||
let y1 = Fp.cmov(y12, y11, e1); // 22. y1 = CMOV(y12, y11, e1) # If g(x1) is square, this is its sqrt
|
||||
let x2n = Fp.mul(x1n, tv1); // 23. x2n = x1n * tv1 # x2 = x2n / xd = 2 * u^2 * x1n / xd
|
||||
let y21 = Fp.mul(y11, u); // 24. y21 = y11 * u
|
||||
y21 = Fp.mul(y21, ELL2_C2); // 25. y21 = y21 * c2
|
||||
let y22 = Fp.mul(y21, ELL2_C3); // 26. y22 = y21 * c3
|
||||
let gx2 = Fp.mul(gx1, tv1); // 27. gx2 = gx1 * tv1 # g(x2) = gx2 / gxd = 2 * u^2 * g(x1)
|
||||
tv2 = Fp.sqr(y21); // 28. tv2 = y21^2
|
||||
tv2 = Fp.mul(tv2, gxd); // 29. tv2 = tv2 * gxd
|
||||
let e2 = Fp.eql(tv2, gx2); // 30. e2 = tv2 == gx2
|
||||
let y2 = Fp.cmov(y22, y21, e2); // 31. y2 = CMOV(y22, y21, e2) # If g(x2) is square, this is its sqrt
|
||||
tv2 = Fp.sqr(y1); // 32. tv2 = y1^2
|
||||
tv2 = Fp.mul(tv2, gxd); // 33. tv2 = tv2 * gxd
|
||||
let e3 = Fp.eql(tv2, gx1); // 34. e3 = tv2 == gx1
|
||||
let xn = Fp.cmov(x2n, x1n, e3); // 35. xn = CMOV(x2n, x1n, e3) # If e3, x = x1, else x = x2
|
||||
let y = Fp.cmov(y2, y1, e3); // 36. y = CMOV(y2, y1, e3) # If e3, y = y1, else y = y2
|
||||
let e4 = Fp.isOdd(y); // 37. e4 = sgn0(y) == 1 # Fix sign of y
|
||||
y = Fp.cmov(y, Fp.neg(y), e3 !== e4); // 38. y = CMOV(y, -y, e3 XOR e4)
|
||||
return { xMn: xn, xMd: xd, yMn: y, yMd: _1n }; // 39. return (xn, xd, y, 1)
|
||||
}
|
||||
const ELL2_C1_EDWARDS = FpSqrtEven(Fp, Fp.neg(BigInt(486664))); // sgn0(c1) MUST equal 0
|
||||
function map_to_curve_elligator2_edwards25519(u) {
|
||||
const { xMn, xMd, yMn, yMd } = map_to_curve_elligator2_curve25519(u); // 1. (xMn, xMd, yMn, yMd) =
|
||||
// map_to_curve_elligator2_curve25519(u)
|
||||
let xn = Fp.mul(xMn, yMd); // 2. xn = xMn * yMd
|
||||
xn = Fp.mul(xn, ELL2_C1_EDWARDS); // 3. xn = xn * c1
|
||||
let xd = Fp.mul(xMd, yMn); // 4. xd = xMd * yMn # xn / xd = c1 * xM / yM
|
||||
let yn = Fp.sub(xMn, xMd); // 5. yn = xMn - xMd
|
||||
let yd = Fp.add(xMn, xMd); // 6. yd = xMn + xMd # (n / d - 1) / (n / d + 1) = (n - d) / (n + d)
|
||||
let tv1 = Fp.mul(xd, yd); // 7. tv1 = xd * yd
|
||||
let e = Fp.eql(tv1, Fp.ZERO); // 8. e = tv1 == 0
|
||||
xn = Fp.cmov(xn, Fp.ZERO, e); // 9. xn = CMOV(xn, 0, e)
|
||||
xd = Fp.cmov(xd, Fp.ONE, e); // 10. xd = CMOV(xd, 1, e)
|
||||
yn = Fp.cmov(yn, Fp.ONE, e); // 11. yn = CMOV(yn, 1, e)
|
||||
yd = Fp.cmov(yd, Fp.ONE, e); // 12. yd = CMOV(yd, 1, e)
|
||||
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 htf = /* @__PURE__ */ (() => createHasher(ed25519.ExtendedPoint, (scalars) => map_to_curve_elligator2_edwards25519(scalars[0]), {
|
||||
DST: 'edwards25519_XMD:SHA-512_ELL2_RO_',
|
||||
encodeDST: 'edwards25519_XMD:SHA-512_ELL2_NU_',
|
||||
p: Fp.ORDER,
|
||||
m: 1,
|
||||
k: 128,
|
||||
expand: 'xmd',
|
||||
hash: sha512,
|
||||
}))();
|
||||
export const hashToCurve = /* @__PURE__ */ (() => htf.hashToCurve)();
|
||||
export const encodeToCurve = /* @__PURE__ */ (() => htf.encodeToCurve)();
|
||||
function assertRstPoint(other) {
|
||||
if (!(other instanceof RistPoint))
|
||||
throw new Error('RistrettoPoint expected');
|
||||
}
|
||||
// √(-1) aka √(a) aka 2^((p-1)/4)
|
||||
const SQRT_M1 = ED25519_SQRT_M1;
|
||||
// √(ad - 1)
|
||||
const SQRT_AD_MINUS_ONE = BigInt('25063068953384623474111414158702152701244531502492656460079210482610430750235');
|
||||
// 1 / √(a-d)
|
||||
const INVSQRT_A_MINUS_D = BigInt('54469307008909316920995813868745141605393597292927456921205312896311721017578');
|
||||
// 1-d²
|
||||
const ONE_MINUS_D_SQ = BigInt('1159843021668779879193775521855586647937357759715417654439879720876111806838');
|
||||
// (d-1)²
|
||||
const D_MINUS_ONE_SQ = BigInt('40440834346308536858101042469323190826248399146238708352240133220865137265952');
|
||||
// Calculates 1/√(number)
|
||||
const invertSqrt = (number) => uvRatio(_1n, number);
|
||||
const MAX_255B = BigInt('0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff');
|
||||
const bytes255ToNumberLE = (bytes) => ed25519.CURVE.Fp.create(bytesToNumberLE(bytes) & MAX_255B);
|
||||
// Computes Elligator map for Ristretto
|
||||
// https://ristretto.group/formulas/elligator.html
|
||||
function calcElligatorRistrettoMap(r0) {
|
||||
const { d } = ed25519.CURVE;
|
||||
const P = ed25519.CURVE.Fp.ORDER;
|
||||
const mod = ed25519.CURVE.Fp.create;
|
||||
const r = mod(SQRT_M1 * r0 * r0); // 1
|
||||
const Ns = mod((r + _1n) * ONE_MINUS_D_SQ); // 2
|
||||
let c = BigInt(-1); // 3
|
||||
const D = mod((c - d * r) * mod(r + d)); // 4
|
||||
let { isValid: Ns_D_is_sq, value: s } = uvRatio(Ns, D); // 5
|
||||
let s_ = mod(s * r0); // 6
|
||||
if (!isNegativeLE(s_, P))
|
||||
s_ = mod(-s_);
|
||||
if (!Ns_D_is_sq)
|
||||
s = s_; // 7
|
||||
if (!Ns_D_is_sq)
|
||||
c = r; // 8
|
||||
const Nt = mod(c * (r - _1n) * D_MINUS_ONE_SQ - D); // 9
|
||||
const s2 = s * s;
|
||||
const W0 = mod((s + s) * D); // 10
|
||||
const W1 = mod(Nt * SQRT_AD_MINUS_ONE); // 11
|
||||
const W2 = mod(_1n - s2); // 12
|
||||
const W3 = mod(_1n + s2); // 13
|
||||
return new ed25519.ExtendedPoint(mod(W0 * W3), mod(W2 * W1), mod(W1 * W3), mod(W0 * W2));
|
||||
}
|
||||
/**
|
||||
* Each ed25519/ExtendedPoint has 8 different equivalent points. This can be
|
||||
* a source of bugs for protocols like ring signatures. Ristretto was created to solve this.
|
||||
* Ristretto point operates in X:Y:Z:T extended coordinates like ExtendedPoint,
|
||||
* but it should work in its own namespace: do not combine those two.
|
||||
* https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-ristretto255-decaf448
|
||||
*/
|
||||
class RistPoint {
|
||||
// Private property to discourage combining ExtendedPoint + RistrettoPoint
|
||||
// Always use Ristretto encoding/decoding instead.
|
||||
constructor(ep) {
|
||||
this.ep = ep;
|
||||
}
|
||||
static fromAffine(ap) {
|
||||
return new RistPoint(ed25519.ExtendedPoint.fromAffine(ap));
|
||||
}
|
||||
/**
|
||||
* Takes uniform output of 64-byte hash function like sha512 and converts it to `RistrettoPoint`.
|
||||
* The hash-to-group operation applies Elligator twice and adds the results.
|
||||
* **Note:** this is one-way map, there is no conversion from point to hash.
|
||||
* https://ristretto.group/formulas/elligator.html
|
||||
* @param hex 64-byte output of a hash function
|
||||
*/
|
||||
static hashToCurve(hex) {
|
||||
hex = ensureBytes('ristrettoHash', hex, 64);
|
||||
const r1 = bytes255ToNumberLE(hex.slice(0, 32));
|
||||
const R1 = calcElligatorRistrettoMap(r1);
|
||||
const r2 = bytes255ToNumberLE(hex.slice(32, 64));
|
||||
const R2 = calcElligatorRistrettoMap(r2);
|
||||
return new RistPoint(R1.add(R2));
|
||||
}
|
||||
/**
|
||||
* Converts ristretto-encoded string to ristretto point.
|
||||
* https://ristretto.group/formulas/decoding.html
|
||||
* @param hex Ristretto-encoded 32 bytes. Not every 32-byte string is valid ristretto encoding
|
||||
*/
|
||||
static fromHex(hex) {
|
||||
hex = ensureBytes('ristrettoHex', hex, 32);
|
||||
const { a, d } = ed25519.CURVE;
|
||||
const P = ed25519.CURVE.Fp.ORDER;
|
||||
const mod = ed25519.CURVE.Fp.create;
|
||||
const emsg = 'RistrettoPoint.fromHex: the hex is not valid encoding of RistrettoPoint';
|
||||
const s = bytes255ToNumberLE(hex);
|
||||
// 1. Check that s_bytes is the canonical encoding of a field element, or else abort.
|
||||
// 3. Check that s is non-negative, or else abort
|
||||
if (!equalBytes(numberToBytesLE(s, 32), hex) || isNegativeLE(s, P))
|
||||
throw new Error(emsg);
|
||||
const s2 = mod(s * s);
|
||||
const u1 = mod(_1n + a * s2); // 4 (a is -1)
|
||||
const u2 = mod(_1n - a * s2); // 5
|
||||
const u1_2 = mod(u1 * u1);
|
||||
const u2_2 = mod(u2 * u2);
|
||||
const v = mod(a * d * u1_2 - u2_2); // 6
|
||||
const { isValid, value: I } = invertSqrt(mod(v * u2_2)); // 7
|
||||
const Dx = mod(I * u2); // 8
|
||||
const Dy = mod(I * Dx * v); // 9
|
||||
let x = mod((s + s) * Dx); // 10
|
||||
if (isNegativeLE(x, P))
|
||||
x = mod(-x); // 10
|
||||
const y = mod(u1 * Dy); // 11
|
||||
const t = mod(x * y); // 12
|
||||
if (!isValid || isNegativeLE(t, P) || y === _0n)
|
||||
throw new Error(emsg);
|
||||
return new RistPoint(new ed25519.ExtendedPoint(x, y, _1n, t));
|
||||
}
|
||||
/**
|
||||
* Encodes ristretto point to Uint8Array.
|
||||
* https://ristretto.group/formulas/encoding.html
|
||||
*/
|
||||
toRawBytes() {
|
||||
let { ex: x, ey: y, ez: z, et: t } = this.ep;
|
||||
const P = ed25519.CURVE.Fp.ORDER;
|
||||
const mod = ed25519.CURVE.Fp.create;
|
||||
const u1 = mod(mod(z + y) * mod(z - y)); // 1
|
||||
const u2 = mod(x * y); // 2
|
||||
// Square root always exists
|
||||
const u2sq = mod(u2 * u2);
|
||||
const { value: invsqrt } = invertSqrt(mod(u1 * u2sq)); // 3
|
||||
const D1 = mod(invsqrt * u1); // 4
|
||||
const D2 = mod(invsqrt * u2); // 5
|
||||
const zInv = mod(D1 * D2 * t); // 6
|
||||
let D; // 7
|
||||
if (isNegativeLE(t * zInv, P)) {
|
||||
let _x = mod(y * SQRT_M1);
|
||||
let _y = mod(x * SQRT_M1);
|
||||
x = _x;
|
||||
y = _y;
|
||||
D = mod(D1 * INVSQRT_A_MINUS_D);
|
||||
}
|
||||
else {
|
||||
D = D2; // 8
|
||||
}
|
||||
if (isNegativeLE(x * zInv, P))
|
||||
y = mod(-y); // 9
|
||||
let s = mod((z - y) * D); // 10 (check footer's note, no sqrt(-a))
|
||||
if (isNegativeLE(s, P))
|
||||
s = mod(-s);
|
||||
return numberToBytesLE(s, 32); // 11
|
||||
}
|
||||
toHex() {
|
||||
return bytesToHex(this.toRawBytes());
|
||||
}
|
||||
toString() {
|
||||
return this.toHex();
|
||||
}
|
||||
// Compare one point to another.
|
||||
equals(other) {
|
||||
assertRstPoint(other);
|
||||
const { ex: X1, ey: Y1 } = 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);
|
||||
const two = mod(Y1 * Y2) === mod(X1 * X2);
|
||||
return one || two;
|
||||
}
|
||||
add(other) {
|
||||
assertRstPoint(other);
|
||||
return new RistPoint(this.ep.add(other.ep));
|
||||
}
|
||||
subtract(other) {
|
||||
assertRstPoint(other);
|
||||
return new RistPoint(this.ep.subtract(other.ep));
|
||||
}
|
||||
multiply(scalar) {
|
||||
return new RistPoint(this.ep.multiply(scalar));
|
||||
}
|
||||
multiplyUnsafe(scalar) {
|
||||
return new RistPoint(this.ep.multiplyUnsafe(scalar));
|
||||
}
|
||||
}
|
||||
export const RistrettoPoint = /* @__PURE__ */ (() => {
|
||||
if (!RistPoint.BASE)
|
||||
RistPoint.BASE = new RistPoint(ed25519.ExtendedPoint.BASE);
|
||||
if (!RistPoint.ZERO)
|
||||
RistPoint.ZERO = new RistPoint(ed25519.ExtendedPoint.ZERO);
|
||||
return RistPoint;
|
||||
})();
|
||||
// https://datatracker.ietf.org/doc/draft-irtf-cfrg-hash-to-curve/14/
|
||||
// Appendix B. Hashing to ristretto255
|
||||
export const hash_to_ristretto255 = (msg, options) => {
|
||||
const d = options.DST;
|
||||
const DST = typeof d === 'string' ? utf8ToBytes(d) : d;
|
||||
const uniform_bytes = expand_message_xmd(msg, DST, 64, sha512);
|
||||
const P = RistPoint.hashToCurve(uniform_bytes);
|
||||
return P;
|
||||
};
|
||||
//# sourceMappingURL=ed25519.js.map
|
||||
1
node_modules/@scure/bip32/node_modules/@noble/curves/esm/ed25519.js.map
generated
vendored
Normal file
1
node_modules/@scure/bip32/node_modules/@noble/curves/esm/ed25519.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user