forked from tornado-packages/noble-curves
Add some comments, refactor a bit
This commit is contained in:
parent
458cddcc7f
commit
7a34c16c2b
@ -7,22 +7,15 @@ Elliptic curves implementations. `@noble/curves` is zero-dependency library for
|
||||
- NIST curves: P192, P224, P256, P384, P521 (ECDSA)
|
||||
- secp256k1 (ECDSA, without Schnorr)
|
||||
- stark curve
|
||||
- bls12-381
|
||||
- bn254
|
||||
|
||||
Pairings are not implemented.
|
||||
|
||||
## Usage
|
||||
|
||||
```sh
|
||||
npm install micro-curve-definitions
|
||||
```
|
||||
|
||||
```ts
|
||||
import * as nist from 'micro-curve-definitions';
|
||||
|
||||
// P192, P224, P256, P384, P521, bn254
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT (c) Paul Miller [(https://paulmillr.com)](https://paulmillr.com), see LICENSE file.
|
||||
|
@ -17,6 +17,7 @@
|
||||
"dependencies": {
|
||||
"@noble/bls12-381": "^1.4.0",
|
||||
"@noble/ed25519": "^1.7.1",
|
||||
"@noble/hashes": "^1.1.5",
|
||||
"@noble/secp256k1": "^1.7.0",
|
||||
"@starkware-industries/starkware-crypto-utils": "^0.0.2"
|
||||
}
|
||||
|
@ -18,13 +18,14 @@ const ed448P = BigInt(
|
||||
);
|
||||
|
||||
// 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: bigint): bigint {
|
||||
const P = ed448P;
|
||||
// prettier-ignore
|
||||
let [_1n, _2n, _3n, _11n, _22n, _44n, _88n, _223n] = [1, 2, 3, 11, 22, 44, 88, 223]
|
||||
.map(n => BigInt(n));
|
||||
// x ** ((P - 3n)/4n) % P
|
||||
// [223 of 1, 0, 222 of 1], almost same as secp!
|
||||
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 = (pow2(b3, _3n, P) * b3) % P;
|
||||
@ -88,6 +89,7 @@ const ED448_DEF = {
|
||||
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: bigint, v: bigint): { isValid: boolean; value: bigint } => {
|
||||
@ -97,16 +99,15 @@ const ED448_DEF = {
|
||||
// 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:
|
||||
// (p+1)/4 3 (p-3)/4
|
||||
// x = (u/v) = u v (u^5 v^3) (mod p)
|
||||
const u2v = mod(u * u * v, P);
|
||||
const u3v = mod(u2v * u, P); // u^2v
|
||||
const u5v3 = mod(u3v * u2v * v, P); // u^5v^3
|
||||
// x = (u/v)^((p+1)/4) = u³v(u⁵v³)^((p-3)/4) (mod p)
|
||||
const u2v = mod(u * u * v, P); // u²v
|
||||
const u3v = mod(u2v * u, P); // u³v
|
||||
const u5v3 = mod(u3v * u2v * v, P); // u⁵v³
|
||||
const root = ed448_pow_Pminus3div4(u5v3);
|
||||
const x = mod(u3v * root, P);
|
||||
// Verify that root is exists
|
||||
const x2 = mod(x * x, P); // x^2
|
||||
// If v * x^2 = u, the recovered x-coordinate is x. Otherwise, no
|
||||
const x2 = 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: mod(x2 * v, P) === u, value: x };
|
||||
},
|
||||
|
@ -21,6 +21,9 @@ export const P521 = createCurve({
|
||||
Gy: BigInt('0x011839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650'),
|
||||
h: BigInt(1),
|
||||
lowS: false,
|
||||
// P521 keys could be 130, 131, 132 bytes - which doesn't play nicely.
|
||||
// We ensure all keys are 132 bytes.
|
||||
// Does not replace validation; invalid keys would still be rejected.
|
||||
normalizePrivateKey(key: PrivKey) {
|
||||
if (typeof key === 'bigint') return key;
|
||||
if (key instanceof Uint8Array) key = bytesToHex(key);
|
||||
|
@ -4,8 +4,8 @@ import { weierstrass } from '@noble/curves/weierstrass';
|
||||
import { getHash } from './_shortw_utils.js';
|
||||
import * as mod from '@noble/curves/modular';
|
||||
|
||||
const p = BigInt('0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001');
|
||||
const q = BigInt('0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001');
|
||||
export const p = BigInt('0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001');
|
||||
export const q = BigInt('0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001');
|
||||
|
||||
// https://neuromancer.sk/std/other/Pallas
|
||||
export const pallas = weierstrass({
|
||||
|
@ -36,10 +36,11 @@ const divNearest = (a: bigint, b: bigint) => (a + b / _2n) / b;
|
||||
* We are unwrapping the loop and multiplying it bit-by-bit.
|
||||
* (P+1n/4n).toString(2) would produce bits [223x 1, 0, 22x 1, 4x 0, 11, 00]
|
||||
*/
|
||||
// prettier-ignore
|
||||
function sqrtMod(y: bigint): bigint {
|
||||
const P = secp256k1P;
|
||||
const _3n = BigInt(3), _6n = BigInt(6), _11n = BigInt(11); const _22n = BigInt(22);
|
||||
// prettier-ignore
|
||||
const _3n = BigInt(3), _6n = BigInt(6), _11n = BigInt(11), _22n = BigInt(22);
|
||||
// prettier-ignore
|
||||
const _23n = BigInt(23), _44n = BigInt(44), _88n = BigInt(88);
|
||||
const b2 = (y * y * y) % P; // x^3, 11
|
||||
const b3 = (b2 * b2 * y) % P; // x^7
|
||||
|
@ -346,7 +346,7 @@ should('ristretto255/should not convert bad bytes encoding', () => {
|
||||
'47cfc5497c53dc8e61c91d17fd626ffb1c49e2bca94eed052281b510b1117a24',
|
||||
'f1c6165d33367351b0da8f6e4511010c68174a03b6581212c71c0e1d026c3c72',
|
||||
'87260f7a2f12495118360f02c26a470f450dadf34a413d21042b43b9d93e1309',
|
||||
// These are all bad because they give a nonsquare x^2.
|
||||
// These are all bad because they give a nonsquare x².
|
||||
'26948d35ca62e643e26a83177332e6b6afeb9d08e4268b650f1f5bbd8d81d371',
|
||||
'4eac077a713c57b4f4397629a4145982c661f48044dd3f96427d40b147d9742f',
|
||||
'de6a7b00deadc788eb6b6c8d20c0ae96c2f2019078fa604fee5b87d6e989ad7b',
|
||||
|
@ -652,8 +652,8 @@ for (let i = 0; i < VECTORS_RFC8032_PH.length; i++) {
|
||||
should('X448 base point', () => {
|
||||
const { x, y } = ed448.Point.BASE;
|
||||
const { P } = ed448.CURVE;
|
||||
const invX = ed448.utils.invert(x * x, P); // x^2
|
||||
const u = ed448.utils.mod(y * y * invX, P); // (y^2/x^2)
|
||||
const invX = ed448.utils.invert(x * x, P); // x²
|
||||
const u = ed448.utils.mod(y * y * invX, P); // (y²/x²)
|
||||
deepStrictEqual(hex(numberToBytesLE(u, 56)), x448.Gu);
|
||||
});
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||
// Barreto-Lynn-Scott Curves. A family of pairing friendly curves, with embedding degree = 12 or 24
|
||||
// NOTE: only 12 supported for now
|
||||
// Constructed from pair of weierstrass curves, based pairing logic
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||
// Implementation of Twisted Edwards curve. The formula is: ax² + y² = 1 + dx²y²
|
||||
// Twisted Edwards curve. The formula is: ax² + y² = 1 + dx²y²
|
||||
|
||||
// Differences from @noble/ed25519 1.7:
|
||||
// 1. Different field element lengths in ed448:
|
||||
|
@ -1,4 +1,4 @@
|
||||
/*! @noble/curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||
// Default group related functions
|
||||
const _0n = BigInt(0);
|
||||
const _1n = BigInt(1);
|
||||
|
@ -1,3 +1,4 @@
|
||||
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||
import { CHash, concatBytes } from './utils.js';
|
||||
import * as mod from './modular.js';
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/*! @noble/curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||
import * as utils from './utils.js';
|
||||
// Utilities for modular arithmetics
|
||||
const _0n = BigInt(0);
|
||||
@ -75,6 +75,7 @@ export function legendre(num: bigint, fieldPrime: bigint): bigint {
|
||||
|
||||
/**
|
||||
* Calculates square root of a number in a finite field.
|
||||
* √a mod P
|
||||
*/
|
||||
// TODO: rewrite as generic Fp function && remove bls versions
|
||||
export function sqrt(number: bigint, modulo: bigint): bigint {
|
||||
@ -85,7 +86,7 @@ export function sqrt(number: bigint, modulo: bigint): bigint {
|
||||
const p1div4 = (P + _1n) / _4n;
|
||||
|
||||
// P ≡ 3 (mod 4)
|
||||
// sqrt n = n^((P+1)/4)
|
||||
// √n = n^((P+1)/4)
|
||||
if (P % _4n === _3n) {
|
||||
// Not all roots possible!
|
||||
// const ORDER =
|
||||
|
@ -1,3 +1,4 @@
|
||||
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||
import * as mod from './modular.js';
|
||||
import {
|
||||
ensureBytes,
|
||||
@ -86,7 +87,7 @@ export function montgomery(curveDef: CurveType): CurveFn {
|
||||
|
||||
// cswap from RFC7748
|
||||
// NOTE: cswap 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
|
||||
|
@ -1,4 +1,4 @@
|
||||
/*! @noble/curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||
import * as mod from './modular.js';
|
||||
const _0n = BigInt(0);
|
||||
const _1n = BigInt(1);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||
// Implementation of Short Weierstrass curve. The formula is: y² = x³ + ax + b
|
||||
// Short Weierstrass curve. The formula is: y² = x³ + ax + b
|
||||
|
||||
// TODO: sync vs async naming
|
||||
// TODO: default randomBytes
|
||||
|
Loading…
Reference in New Issue
Block a user