diff --git a/README.md b/README.md index 80d0722..4a908e9 100644 --- a/README.md +++ b/README.md @@ -223,7 +223,7 @@ There are following zero-dependency algorithms: ```ts import { weierstrass } from '@noble/curves/abstract/weierstrass'; -import { Fp } from '@noble/curves/abstract/modular'; // finite field for mod arithmetics +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 @@ -233,7 +233,7 @@ const secq256k1 = weierstrass({ // https://zcash.github.io/halo2/background/curves.html#cycles-of-curves a: 0n, b: 7n, - Fp: Fp(2n ** 256n - 432420386565659656852420866394968145599n), + 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, @@ -241,6 +241,8 @@ const secq256k1 = weierstrass({ hmac: (key: Uint8Array, ...msgs: Uint8Array[]) => hmac(sha256, key, concatBytes(...msgs)), randomBytes, }); + +// weierstrassPoints can also be used if you don't need ECDSA, hash, hmac, randomBytes ``` Short Weierstrass curve's formula is `y² = x³ + ax + b`. `weierstrass` @@ -272,6 +274,7 @@ type CHash = { 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 = { @@ -379,15 +382,15 @@ fast.multiply(privKey); // much faster ECDH now ```ts import { twistedEdwards } from '@noble/curves/abstract/edwards'; -import { Fp } from '@noble/curves/abstract/modular'; +import { Field } from '@noble/curves/abstract/modular'; import { sha512 } from '@noble/hashes/sha512'; import { randomBytes } from '@noble/hashes/utils'; -const fp = Fp(2n ** 255n - 19n); +const Fp = Field(2n ** 255n - 19n); const ed25519 = twistedEdwards({ a: -1n, - d: fp.div(-121665n, 121666n), // -121665n/121666n mod p - Fp: fp, + d: Fp.div(-121665n, 121666n), // -121665n/121666n mod p + Fp: Fp, n: 2n ** 252n + 27742317777372353535851937790883648493n, h: 8n, Gx: 15112221349535400772501151409588531511454012693041857206046113283949847762202n, @@ -465,12 +468,12 @@ interface ExtPointConstructor extends GroupConstructor { ```typescript import { montgomery } from '@noble/curves/abstract/montgomery'; -import { Fp } from '@noble/curves/abstract/modular'; +import { Field } from '@noble/curves/abstract/modular'; const x25519 = montgomery({ - Fp: Fp(2n ** 255n - 19n), a: 486662n, Gu: 9n, + Fp: Field(2n ** 255n - 19n), montgomeryBits: 255, nByteLength: 32, // Optional param diff --git a/benchmark/modular.js b/benchmark/modular.js index 5ebe918..ae52522 100644 --- a/benchmark/modular.js +++ b/benchmark/modular.js @@ -1,6 +1,6 @@ import { run, mark } from 'micro-bmark'; import { secp256k1 } from '../secp256k1.js'; -import { Fp } from '../abstract/modular.js'; +import { Field as Fp } from '../abstract/modular.js'; run(async () => { console.log(`\x1b[36mmodular, secp256k1 field\x1b[0m`); diff --git a/src/abstract/bls.ts b/src/abstract/bls.ts index 42a3476..72584b8 100644 --- a/src/abstract/bls.ts +++ b/src/abstract/bls.ts @@ -12,7 +12,7 @@ * Some projects may prefer to swap this relation, it is not supported for now. */ import { AffinePoint } from './curve.js'; -import { Field, hashToPrivateScalar } from './modular.js'; +import { IField, hashToPrivateScalar } from './modular.js'; import { Hex, PrivKey, CHash, bitLen, bitGet, ensureBytes } from './utils.js'; import * as htf from './hash-to-curve.js'; import { @@ -41,15 +41,15 @@ export type CurveType = { htfDefaults: htf.Opts; }; x: bigint; - Fp: Field; - Fr: Field; - Fp2: Field & { + Fp: IField; + Fr: IField; + Fp2: IField & { reim: (num: Fp2) => { re: bigint; im: bigint }; multiplyByB: (num: Fp2) => Fp2; frobeniusMap(num: Fp2, power: number): Fp2; }; - Fp6: Field; - Fp12: Field & { + Fp6: IField; + Fp12: IField & { frobeniusMap(num: Fp12, power: number): Fp12; multiplyBy014(num: Fp12, o0: Fp2, o1: Fp2, o4: Fp2): Fp12; conjugate(num: Fp12): Fp12; @@ -62,11 +62,11 @@ export type CurveType = { export type CurveFn = { CURVE: CurveType; - Fr: Field; - Fp: Field; - Fp2: Field; - Fp6: Field; - Fp12: Field; + Fr: IField; + Fp: IField; + Fp2: IField; + Fp6: IField; + Fp12: IField; G1: CurvePointsRes & ReturnType>; G2: CurvePointsRes & ReturnType>; Signature: SignatureCoder; diff --git a/src/abstract/curve.ts b/src/abstract/curve.ts index 23a2e9f..2876377 100644 --- a/src/abstract/curve.ts +++ b/src/abstract/curve.ts @@ -1,6 +1,6 @@ /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */ // Abelian group utilities -import { Field, validateField, nLength } from './modular.js'; +import { IField, validateField, nLength } from './modular.js'; import { validateObject } from './utils.js'; const _0n = BigInt(0); const _1n = BigInt(1); @@ -168,7 +168,7 @@ export function wNAF>(c: GroupConstructor, bits: number) { // Generic BasicCurve interface: works even for polynomial fields (BLS): P, n, h would be ok. // Though generator can be different (Fp2 / Fp6 for BLS). export type BasicCurve = { - Fp: Field; // Field over which we'll do calculations (Fp) + Fp: IField; // Field over which we'll do calculations (Fp) n: bigint; // Curve order, total count of valid points in the field nBitLength?: number; // bit length of curve order nByteLength?: number; // byte length of curve order @@ -195,5 +195,9 @@ export function validateBasic(curve: BasicCurve & T) { } ); // Set defaults - return Object.freeze({ ...nLength(curve.n, curve.nBitLength), ...curve, ...{p: curve.Fp.ORDER} } as const); + return Object.freeze({ + ...nLength(curve.n, curve.nBitLength), + ...curve, + ...{ p: curve.Fp.ORDER }, + } as const); } diff --git a/src/abstract/hash-to-curve.ts b/src/abstract/hash-to-curve.ts index 40395d8..2900176 100644 --- a/src/abstract/hash-to-curve.ts +++ b/src/abstract/hash-to-curve.ts @@ -1,6 +1,6 @@ /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */ import type { Group, GroupConstructor, AffinePoint } from './curve.js'; -import { mod, Field } from './modular.js'; +import { mod, IField } from './modular.js'; import { bytesToNumberBE, CHash, concatBytes, utf8ToBytes, validateObject } from './utils.js'; /** @@ -163,7 +163,7 @@ export function hash_to_field(msg: Uint8Array, count: number, options: Opts): bi return u; } -export function isogenyMap>(field: F, map: [T[], T[], T[], T[]]) { +export function isogenyMap>(field: F, map: [T[], T[], T[], T[]]) { // Make same order as in spec const COEFF = map.map((i) => Array.from(i).reverse()); return (x: T, y: T) => { diff --git a/src/abstract/modular.ts b/src/abstract/modular.ts index 5b50a3f..84ab0fb 100644 --- a/src/abstract/modular.ts +++ b/src/abstract/modular.ts @@ -97,7 +97,7 @@ export function tonelliShanks(P: bigint) { // Fast-path if (S === 1) { const p1div4 = (P + _1n) / _4n; - return function tonelliFast(Fp: Field, n: T) { + return function tonelliFast(Fp: IField, n: T) { const root = Fp.pow(n, p1div4); if (!Fp.eql(Fp.sqr(root), n)) throw new Error('Cannot find square root'); return root; @@ -106,7 +106,7 @@ export function tonelliShanks(P: bigint) { // Slow-path const Q1div2 = (Q + _1n) / _2n; - return function tonelliSlow(Fp: Field, n: T): T { + return function tonelliSlow(Fp: IField, n: T): T { // 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; @@ -146,7 +146,7 @@ export function FpSqrt(P: bigint) { // 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaabn; // const NUM = 72057594037927816n; const p1div4 = (P + _1n) / _4n; - return function sqrt3mod4(Fp: Field, n: T) { + return function sqrt3mod4(Fp: IField, n: T) { 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'); @@ -157,7 +157,7 @@ export function FpSqrt(P: bigint) { // 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: Field, n: T) { + return function sqrt5mod8(Fp: IField, n: T) { const n2 = Fp.mul(n, _2n); const v = Fp.pow(n2, c1); const nv = Fp.mul(n, v); @@ -203,7 +203,7 @@ export const isNegativeLE = (num: bigint, modulo: bigint) => (mod(num, modulo) & // - unreadable mess: addition, multiply, square, squareRoot, inversion, divide, power, equals, subtract // Field is not always over prime, Fp2 for example has ORDER(q)=p^m -export interface Field { +export interface IField { ORDER: bigint; BYTES: number; BITS: number; @@ -249,7 +249,7 @@ const FIELD_FIELDS = [ 'eql', 'add', 'sub', 'mul', 'pow', 'div', 'addN', 'subN', 'mulN', 'sqrN' ] as const; -export function validateField(field: Field) { +export function validateField(field: IField) { const initial = { ORDER: 'bigint', MASK: 'bigint', @@ -264,7 +264,7 @@ export function validateField(field: Field) { } // Generic field functions -export function FpPow(f: Field, num: T, power: bigint): T { +export function FpPow(f: IField, num: T, power: bigint): T { // Should have same speed as pow for bigints // TODO: benchmark! if (power < _0n) throw new Error('Expected power > 0'); @@ -280,7 +280,7 @@ export function FpPow(f: Field, num: T, power: bigint): T { return p; } -export function FpInvertBatch(f: Field, nums: T[]): T[] { +export function FpInvertBatch(f: IField, nums: T[]): T[] { 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) => { @@ -299,12 +299,12 @@ export function FpInvertBatch(f: Field, nums: T[]): T[] { return tmp; } -export function FpDiv(f: Field, lhs: T, rhs: T | bigint): T { +export function FpDiv(f: IField, lhs: T, rhs: T | bigint): T { 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: Field) { +export function FpIsSquare(f: IField) { const legendreConst = (f.ORDER - _1n) / _2n; // Integer arithmetic return (x: T): boolean => { const p = f.pow(x, legendreConst); @@ -320,16 +320,24 @@ export function nLength(n: bigint, nBitLength?: number) { return { nBitLength: _nBitLength, nByteLength }; } -// NOTE: very fragile, always bench. Major performance points: -// - NonNormalized ops -// - Object.freeze -// - same shape of object (don't add/remove keys) -type FpField = Field & Required, 'isOdd'>>; -export function Fp( +type FpField = IField & Required, '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 function Field( ORDER: bigint, bitLen?: number, isLE = false, - redef: Partial> = {} + redef: Partial> = {} ): Readonly { if (ORDER <= _0n) throw new Error(`Expected Fp ORDER > 0, got ${ORDER}`); const { nBitLength: BITS, nByteLength: BYTES } = nLength(ORDER, bitLen); @@ -382,13 +390,13 @@ export function Fp( return Object.freeze(f); } -export function FpSqrtOdd(Fp: Field, elm: T) { +export function FpSqrtOdd(Fp: IField, elm: T) { 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: Field, elm: T) { +export function FpSqrtEven(Fp: IField, elm: T) { if (!Fp.isOdd) throw new Error(`Field doesn't have isOdd`); const root = Fp.sqrt(elm); return Fp.isOdd(root) ? Fp.neg(root) : root; diff --git a/src/abstract/poseidon.ts b/src/abstract/poseidon.ts index 302913f..38ab17d 100644 --- a/src/abstract/poseidon.ts +++ b/src/abstract/poseidon.ts @@ -1,10 +1,10 @@ /*! 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 { Field, FpPow, validateField } from './modular.js'; +import { IField, FpPow, validateField } from './modular.js'; // We don't provide any constants, since different implementations use different constants. // For reference constants see './test/poseidon.test.js'. export type PoseidonOpts = { - Fp: Field; + Fp: IField; t: number; roundsFull: number; roundsPartial: number; diff --git a/src/abstract/weierstrass.ts b/src/abstract/weierstrass.ts index 5428255..f3d48a4 100644 --- a/src/abstract/weierstrass.ts +++ b/src/abstract/weierstrass.ts @@ -670,8 +670,7 @@ export type CurveFn = { export function weierstrass(curveDef: CurveType): CurveFn { const CURVE = validateOpts(curveDef) as ReturnType; - const CURVE_ORDER = CURVE.n; - const Fp = CURVE.Fp; + const { Fp, n: CURVE_ORDER } = CURVE; const compressedLen = Fp.BYTES + 1; // e.g. 33 for 32 const uncompressedLen = 2 * Fp.BYTES + 1; // e.g. 65 for 32 @@ -1076,7 +1075,7 @@ export function weierstrass(curveDef: CurveType): CurveFn { // 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. -export function SWUFpSqrtRatio(Fp: mod.Field, Z: T) { +export function SWUFpSqrtRatio(Fp: mod.IField, Z: T) { // Generic implementation const q = Fp.ORDER; let l = 0n; @@ -1141,7 +1140,7 @@ export function SWUFpSqrtRatio(Fp: mod.Field, Z: T) { } // From draft-irtf-cfrg-hash-to-curve-16 export function mapToCurveSimpleSWU( - Fp: mod.Field, + Fp: mod.IField, opts: { A: T; B: T; diff --git a/src/bls12-381.ts b/src/bls12-381.ts index ed1d874..e637f7a 100644 --- a/src/bls12-381.ts +++ b/src/bls12-381.ts @@ -72,13 +72,13 @@ import { isogenyMap } from './abstract/hash-to-curve.js'; // CURVE FIELDS // Finite field over p. const Fp = - mod.Fp( + mod.Field( 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaabn ); type Fp = bigint; // Finite field over r. // This particular field is not used anywhere in bls12-381, but it is still useful. -const Fr = mod.Fp(0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001n); +const Fr = mod.Field(0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001n); // Fp₂ over complex plane type BigintTuple = [bigint, bigint]; @@ -124,7 +124,7 @@ const FP2_ORDER = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaabn ** 2n; -const Fp2: mod.Field & Fp2Utils = { +const Fp2: mod.IField & Fp2Utils = { ORDER: FP2_ORDER, BITS: bitLen(FP2_ORDER), BYTES: Math.ceil(bitLen(FP2_ORDER) / 8), @@ -333,7 +333,7 @@ type Fp6Utils = { multiplyByFp2(lhs: Fp6, rhs: Fp2): Fp6; }; -const Fp6: mod.Field & Fp6Utils = { +const Fp6: mod.IField & Fp6Utils = { ORDER: Fp2.ORDER, // TODO: unused, but need to verify BITS: 3 * Fp2.BITS, BYTES: 3 * Fp2.BYTES, @@ -545,7 +545,7 @@ type Fp12Utils = { _cyclotomicExp(num: Fp12, n: bigint): Fp12; }; -const Fp12: mod.Field & Fp12Utils = { +const Fp12: mod.IField & Fp12Utils = { ORDER: Fp2.ORDER, // TODO: unused, but need to verify BITS: 2 * Fp2.BITS, BYTES: 2 * Fp2.BYTES, diff --git a/src/bn.ts b/src/bn.ts index 09272ff..64ccfe0 100644 --- a/src/bn.ts +++ b/src/bn.ts @@ -2,7 +2,7 @@ import { sha256 } from '@noble/hashes/sha256'; import { weierstrass } from './abstract/weierstrass.js'; import { getHash } from './_shortw_utils.js'; -import { Fp } from './abstract/modular.js'; +import { Field } from './abstract/modular.js'; /** * bn254 pairing-friendly curve. * Previously known as alt_bn_128, when it had 128-bit security. @@ -12,7 +12,7 @@ import { Fp } from './abstract/modular.js'; export const bn254 = weierstrass({ a: BigInt(0), b: BigInt(3), - Fp: Fp(BigInt('0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47')), + Fp: Field(BigInt('0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47')), n: BigInt('0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001'), Gx: BigInt(1), Gy: BigInt(2), diff --git a/src/ed25519.ts b/src/ed25519.ts index 84a199f..9aaef0b 100644 --- a/src/ed25519.ts +++ b/src/ed25519.ts @@ -3,7 +3,7 @@ import { sha512 } from '@noble/hashes/sha512'; import { concatBytes, randomBytes, utf8ToBytes } from '@noble/hashes/utils'; import { twistedEdwards, ExtPointType } from './abstract/edwards.js'; import { montgomery } from './abstract/montgomery.js'; -import { mod, pow2, isNegativeLE, Fp as Field, FpSqrtEven } from './abstract/modular.js'; +import { mod, pow2, isNegativeLE, Field, FpSqrtEven } from './abstract/modular.js'; import { equalBytes, bytesToHex, diff --git a/src/ed448.ts b/src/ed448.ts index eb1cb17..a842ae3 100644 --- a/src/ed448.ts +++ b/src/ed448.ts @@ -2,7 +2,7 @@ import { shake256 } from '@noble/hashes/sha3'; import { concatBytes, randomBytes, utf8ToBytes, wrapConstructor } from '@noble/hashes/utils'; import { twistedEdwards } from './abstract/edwards.js'; -import { mod, pow2, Fp as Field } from './abstract/modular.js'; +import { mod, pow2, Field } from './abstract/modular.js'; import { montgomery } from './abstract/montgomery.js'; import * as htf from './abstract/hash-to-curve.js'; diff --git a/src/jubjub.ts b/src/jubjub.ts index 714d3c9..203cfa1 100644 --- a/src/jubjub.ts +++ b/src/jubjub.ts @@ -3,7 +3,7 @@ import { sha512 } from '@noble/hashes/sha512'; import { concatBytes, randomBytes, utf8ToBytes } from '@noble/hashes/utils'; import { twistedEdwards } from './abstract/edwards.js'; import { blake2s } from '@noble/hashes/blake2s'; -import { Fp } from './abstract/modular.js'; +import { Field } from './abstract/modular.js'; /** * jubjub Twisted Edwards curve. @@ -17,7 +17,7 @@ export const jubjub = twistedEdwards({ d: BigInt('0x2a9318e74bfa2b48f5fd9207e6bd7fd4292d7f6d37579d2601065fd6d6343eb1'), // Finite field 𝔽p over which we'll do calculations // Same value as bls12-381 Fr (not Fp) - Fp: Fp(BigInt('0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001')), + Fp: Field(BigInt('0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001')), // Subgroup order: how many points curve has n: BigInt('0xe7db4ea6533afa906673b0101343b00a6682093ccc81082d0970e5ed6f72cb7'), // Cofactor diff --git a/src/p256.ts b/src/p256.ts index 1c97652..bb30d93 100644 --- a/src/p256.ts +++ b/src/p256.ts @@ -1,7 +1,7 @@ /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */ import { createCurve } from './_shortw_utils.js'; import { sha256 } from '@noble/hashes/sha256'; -import { Fp as Field } from './abstract/modular.js'; +import { Field } from './abstract/modular.js'; import { mapToCurveSimpleSWU } from './abstract/weierstrass.js'; import * as htf from './abstract/hash-to-curve.js'; diff --git a/src/p384.ts b/src/p384.ts index ee78904..3f8db49 100644 --- a/src/p384.ts +++ b/src/p384.ts @@ -1,7 +1,7 @@ /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */ import { createCurve } from './_shortw_utils.js'; import { sha384 } from '@noble/hashes/sha512'; -import { Fp as Field } from './abstract/modular.js'; +import { Field } from './abstract/modular.js'; import { mapToCurveSimpleSWU } from './abstract/weierstrass.js'; import * as htf from './abstract/hash-to-curve.js'; diff --git a/src/p521.ts b/src/p521.ts index 7324245..999895c 100644 --- a/src/p521.ts +++ b/src/p521.ts @@ -1,7 +1,7 @@ /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */ import { createCurve } from './_shortw_utils.js'; import { sha512 } from '@noble/hashes/sha512'; -import { Fp as Field } from './abstract/modular.js'; +import { Field } from './abstract/modular.js'; import { mapToCurveSimpleSWU } from './abstract/weierstrass.js'; import * as htf from './abstract/hash-to-curve.js'; diff --git a/src/pasta.ts b/src/pasta.ts index 1f7c8e1..faed89e 100644 --- a/src/pasta.ts +++ b/src/pasta.ts @@ -11,7 +11,7 @@ export const q = BigInt('0x40000000000000000000000000000000224698fc0994a8dd8c46e export const pallas = weierstrass({ a: BigInt(0), b: BigInt(5), - Fp: mod.Fp(p), + Fp: mod.Field(p), n: q, Gx: mod.mod(BigInt(-1), p), Gy: BigInt(2), @@ -22,7 +22,7 @@ export const pallas = weierstrass({ export const vesta = weierstrass({ a: BigInt(0), b: BigInt(5), - Fp: mod.Fp(q), + Fp: mod.Field(q), n: p, Gx: mod.mod(BigInt(-1), q), Gy: BigInt(2), diff --git a/src/secp256k1.ts b/src/secp256k1.ts index 523656d..545ce89 100644 --- a/src/secp256k1.ts +++ b/src/secp256k1.ts @@ -1,7 +1,7 @@ /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */ import { sha256 } from '@noble/hashes/sha256'; import { randomBytes } from '@noble/hashes/utils'; -import { Fp as Field, mod, pow2 } from './abstract/modular.js'; +import { Field, mod, pow2 } from './abstract/modular.js'; import { ProjPointType as PointType, mapToCurveSimpleSWU } from './abstract/weierstrass.js'; import type { Hex, PrivKey } from './abstract/utils.js'; import { bytesToNumberBE, concatBytes, ensureBytes, numberToBytesBE } from './abstract/utils.js'; @@ -43,7 +43,6 @@ function sqrtMod(y: bigint): bigint { } const Fp = Field(secp256k1P, undefined, undefined, { sqrt: sqrtMod }); -type Fp = bigint; export const secp256k1 = createCurve( { @@ -245,7 +244,7 @@ const isoMap = htf.isogenyMap( '0x6484aa716545ca2cf3a70c3fa8fe337e0a3d21162f0d6299a7bf8192bfd2a76f', '0x0000000000000000000000000000000000000000000000000000000000000001', // LAST 1 ], - ].map((i) => i.map((j) => BigInt(j))) as [Fp[], Fp[], Fp[], Fp[]] + ].map((i) => i.map((j) => BigInt(j))) as [bigint[], bigint[], bigint[], bigint[]] ); const mapSWU = mapToCurveSimpleSWU(Fp, { A: BigInt('0x3f8731abdd661adca08a5558f0f5d272e953d363cb6f0e5d405447c01a444533'), diff --git a/test/_more-curves.helpers.js b/test/_more-curves.helpers.js index c218e52..634686d 100644 --- a/test/_more-curves.helpers.js +++ b/test/_more-curves.helpers.js @@ -1,7 +1,7 @@ /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */ import { createCurve } from '../esm/_shortw_utils.js'; import { sha224, sha256 } from '@noble/hashes/sha256'; -import { Fp } from '../esm/abstract/modular.js'; +import { Field as Fp } from '../esm/abstract/modular.js'; // NIST secp192r1 aka P192 // https://www.secg.org/sec2-v2.pdf, https://neuromancer.sk/std/secg/secp192r1 diff --git a/test/_poseidon.helpers.js b/test/_poseidon.helpers.js index 25adfba..e091b7b 100644 --- a/test/_poseidon.helpers.js +++ b/test/_poseidon.helpers.js @@ -1,7 +1,7 @@ /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */ import { sha256 } from '@noble/hashes/sha256'; import { utf8ToBytes } from '@noble/hashes/utils'; -import { Fp, validateField } from '../esm/abstract/modular.js'; +import { Field as Fp, validateField } from '../esm/abstract/modular.js'; import { poseidon } from '../esm/abstract/poseidon.js'; import * as u from '../esm/abstract/utils.js'; diff --git a/test/basic.test.js b/test/basic.test.js index 3faaef0..aa23467 100644 --- a/test/basic.test.js +++ b/test/basic.test.js @@ -553,6 +553,7 @@ for (const name in CURVES) { }); } describe(name, () => { + if (['bn254', 'pallas', 'vesta'].includes(name)) return; // Generic complex things (getPublicKey/sign/verify/getSharedSecret) should('.getPublicKey() type check', () => { throws(() => C.getPublicKey(0), '0'); diff --git a/test/index.test.js b/test/index.test.js index 378931f..792c8a2 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -8,7 +8,8 @@ import './ed25519.test.js'; import './secp256k1.test.js'; import './secp256k1-schnorr.test.js'; import './jubjub.test.js'; -import './bls12-381.test.js'; import './hash-to-curve.test.js'; +import './poseidon.test.js'; +import './bls12-381.test.js'; should.run(); diff --git a/test/poseidon.test.js b/test/poseidon.test.js index 3ba0df3..98bcc52 100644 --- a/test/poseidon.test.js +++ b/test/poseidon.test.js @@ -132,7 +132,9 @@ describe('Stark', () => { // Official vectors: https://extgit.iaik.tugraz.at/krypto/hadeshash/-/blob/master/code/test_vectors.txt should('poseidonperm_x5_255_3', () => { - const Fp = mod.Fp(BigInt('0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001')); + const Fp = mod.Field( + BigInt('0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001') + ); const mds = [ [ @@ -179,7 +181,7 @@ should('poseidonperm_x5_255_3', () => { }); should('poseidonperm_x5_255_5', () => { - const Fp = mod.Fp(0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001n); + const Fp = mod.Field(0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001n); const t = 5; const mds = [ @@ -250,7 +252,7 @@ should('poseidonperm_x5_255_5', () => { }); should('poseidonperm_x5_254_3', () => { - const Fp = mod.Fp(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001n); + const Fp = mod.Field(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001n); const t = 3; const mds = [ @@ -297,7 +299,7 @@ should('poseidonperm_x5_254_3', () => { }); should('poseidonperm_x5_254_5', () => { - const Fp = mod.Fp(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001n); + const Fp = mod.Field(0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001n); const t = 5; const mds = [