@noble/curves 0.8.3 → 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +87 -62
- package/_shortw_utils.d.ts +2 -1
- package/_shortw_utils.d.ts.map +1 -1
- package/abstract/bls.d.ts +11 -11
- package/abstract/bls.d.ts.map +1 -1
- package/abstract/bls.js.map +1 -1
- package/abstract/curve.d.ts +5 -3
- package/abstract/curve.d.ts.map +1 -1
- package/abstract/curve.js +5 -1
- package/abstract/curve.js.map +1 -1
- package/abstract/edwards.d.ts +6 -1
- package/abstract/edwards.d.ts.map +1 -1
- package/abstract/edwards.js +8 -9
- package/abstract/edwards.js.map +1 -1
- package/abstract/hash-to-curve.d.ts +2 -2
- package/abstract/hash-to-curve.d.ts.map +1 -1
- package/abstract/hash-to-curve.js.map +1 -1
- package/abstract/modular.d.ts +24 -12
- package/abstract/modular.d.ts.map +1 -1
- package/abstract/modular.js +17 -4
- package/abstract/modular.js.map +1 -1
- package/abstract/poseidon.d.ts +3 -3
- package/abstract/poseidon.d.ts.map +1 -1
- package/abstract/poseidon.js.map +1 -1
- package/abstract/weierstrass.d.ts +29 -5
- package/abstract/weierstrass.d.ts.map +1 -1
- package/abstract/weierstrass.js +37 -23
- package/abstract/weierstrass.js.map +1 -1
- package/bls12-381.d.ts +4 -4
- package/bls12-381.d.ts.map +1 -1
- package/bls12-381.js +109 -106
- package/bls12-381.js.map +1 -1
- package/bn.js +1 -1
- package/bn.js.map +1 -1
- package/ed25519.js +2 -2
- package/ed25519.js.map +1 -1
- package/ed448.d.ts.map +1 -1
- package/ed448.js +4 -3
- package/ed448.js.map +1 -1
- package/esm/abstract/bls.js.map +1 -1
- package/esm/abstract/curve.js +5 -1
- package/esm/abstract/curve.js.map +1 -1
- package/esm/abstract/edwards.js +8 -9
- package/esm/abstract/edwards.js.map +1 -1
- package/esm/abstract/hash-to-curve.js.map +1 -1
- package/esm/abstract/modular.js +15 -2
- package/esm/abstract/modular.js.map +1 -1
- package/esm/abstract/poseidon.js.map +1 -1
- package/esm/abstract/weierstrass.js +37 -23
- package/esm/abstract/weierstrass.js.map +1 -1
- package/esm/bls12-381.js +109 -106
- package/esm/bls12-381.js.map +1 -1
- package/esm/bn.js +2 -2
- package/esm/bn.js.map +1 -1
- package/esm/ed25519.js +2 -2
- package/esm/ed25519.js.map +1 -1
- package/esm/ed448.js +4 -3
- package/esm/ed448.js.map +1 -1
- package/esm/jubjub.js +2 -2
- package/esm/jubjub.js.map +1 -1
- package/esm/p256.js +1 -1
- package/esm/p256.js.map +1 -1
- package/esm/p384.js +1 -1
- package/esm/p384.js.map +1 -1
- package/esm/p521.js +1 -1
- package/esm/p521.js.map +1 -1
- package/esm/pasta.js +2 -2
- package/esm/pasta.js.map +1 -1
- package/esm/secp256k1.js +2 -2
- package/esm/secp256k1.js.map +1 -1
- package/jubjub.js +1 -1
- package/jubjub.js.map +1 -1
- package/p256.d.ts +4 -2
- package/p256.d.ts.map +1 -1
- package/p256.js +1 -1
- package/p256.js.map +1 -1
- package/p384.d.ts +4 -2
- package/p384.d.ts.map +1 -1
- package/p384.js +1 -1
- package/p384.js.map +1 -1
- package/p521.d.ts +4 -2
- package/p521.d.ts.map +1 -1
- package/p521.js +1 -1
- package/p521.js.map +1 -1
- package/package.json +5 -5
- package/pasta.js +2 -2
- package/pasta.js.map +1 -1
- package/secp256k1.d.ts +2 -1
- package/secp256k1.d.ts.map +1 -1
- package/secp256k1.js +2 -2
- package/secp256k1.js.map +1 -1
- package/src/abstract/bls.ts +11 -11
- package/src/abstract/curve.ts +7 -3
- package/src/abstract/edwards.ts +12 -9
- package/src/abstract/hash-to-curve.ts +2 -2
- package/src/abstract/modular.ts +29 -20
- package/src/abstract/poseidon.ts +2 -2
- package/src/abstract/weierstrass.ts +45 -27
- package/src/bls12-381.ts +199 -114
- package/src/bn.ts +2 -2
- package/src/ed25519.ts +2 -2
- package/src/ed448.ts +4 -3
- package/src/jubjub.ts +2 -2
- package/src/p256.ts +1 -1
- package/src/p384.ts +1 -1
- package/src/p521.ts +1 -1
- package/src/pasta.ts +2 -2
- package/src/secp256k1.ts +3 -4
package/src/abstract/modular.ts
CHANGED
|
@@ -97,7 +97,7 @@ export function tonelliShanks(P: bigint) {
|
|
|
97
97
|
// Fast-path
|
|
98
98
|
if (S === 1) {
|
|
99
99
|
const p1div4 = (P + _1n) / _4n;
|
|
100
|
-
return function tonelliFast<T>(Fp:
|
|
100
|
+
return function tonelliFast<T>(Fp: IField<T>, n: T) {
|
|
101
101
|
const root = Fp.pow(n, p1div4);
|
|
102
102
|
if (!Fp.eql(Fp.sqr(root), n)) throw new Error('Cannot find square root');
|
|
103
103
|
return root;
|
|
@@ -106,7 +106,7 @@ export function tonelliShanks(P: bigint) {
|
|
|
106
106
|
|
|
107
107
|
// Slow-path
|
|
108
108
|
const Q1div2 = (Q + _1n) / _2n;
|
|
109
|
-
return function tonelliSlow<T>(Fp:
|
|
109
|
+
return function tonelliSlow<T>(Fp: IField<T>, n: T): T {
|
|
110
110
|
// Step 0: Check that n is indeed a square: (n | p) should not be ≡ -1
|
|
111
111
|
if (Fp.pow(n, legendreC) === Fp.neg(Fp.ONE)) throw new Error('Cannot find square root');
|
|
112
112
|
let r = S;
|
|
@@ -146,7 +146,7 @@ export function FpSqrt(P: bigint) {
|
|
|
146
146
|
// 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaabn;
|
|
147
147
|
// const NUM = 72057594037927816n;
|
|
148
148
|
const p1div4 = (P + _1n) / _4n;
|
|
149
|
-
return function sqrt3mod4<T>(Fp:
|
|
149
|
+
return function sqrt3mod4<T>(Fp: IField<T>, n: T) {
|
|
150
150
|
const root = Fp.pow(n, p1div4);
|
|
151
151
|
// Throw if root**2 != n
|
|
152
152
|
if (!Fp.eql(Fp.sqr(root), n)) throw new Error('Cannot find square root');
|
|
@@ -157,7 +157,7 @@ export function FpSqrt(P: bigint) {
|
|
|
157
157
|
// Atkin algorithm for q ≡ 5 (mod 8), https://eprint.iacr.org/2012/685.pdf (page 10)
|
|
158
158
|
if (P % _8n === _5n) {
|
|
159
159
|
const c1 = (P - _5n) / _8n;
|
|
160
|
-
return function sqrt5mod8<T>(Fp:
|
|
160
|
+
return function sqrt5mod8<T>(Fp: IField<T>, n: T) {
|
|
161
161
|
const n2 = Fp.mul(n, _2n);
|
|
162
162
|
const v = Fp.pow(n2, c1);
|
|
163
163
|
const nv = Fp.mul(n, v);
|
|
@@ -203,7 +203,7 @@ export const isNegativeLE = (num: bigint, modulo: bigint) => (mod(num, modulo) &
|
|
|
203
203
|
// - unreadable mess: addition, multiply, square, squareRoot, inversion, divide, power, equals, subtract
|
|
204
204
|
|
|
205
205
|
// Field is not always over prime, Fp2 for example has ORDER(q)=p^m
|
|
206
|
-
export interface
|
|
206
|
+
export interface IField<T> {
|
|
207
207
|
ORDER: bigint;
|
|
208
208
|
BYTES: number;
|
|
209
209
|
BITS: number;
|
|
@@ -249,7 +249,7 @@ const FIELD_FIELDS = [
|
|
|
249
249
|
'eql', 'add', 'sub', 'mul', 'pow', 'div',
|
|
250
250
|
'addN', 'subN', 'mulN', 'sqrN'
|
|
251
251
|
] as const;
|
|
252
|
-
export function validateField<T>(field:
|
|
252
|
+
export function validateField<T>(field: IField<T>) {
|
|
253
253
|
const initial = {
|
|
254
254
|
ORDER: 'bigint',
|
|
255
255
|
MASK: 'bigint',
|
|
@@ -264,7 +264,7 @@ export function validateField<T>(field: Field<T>) {
|
|
|
264
264
|
}
|
|
265
265
|
|
|
266
266
|
// Generic field functions
|
|
267
|
-
export function FpPow<T>(f:
|
|
267
|
+
export function FpPow<T>(f: IField<T>, num: T, power: bigint): T {
|
|
268
268
|
// Should have same speed as pow for bigints
|
|
269
269
|
// TODO: benchmark!
|
|
270
270
|
if (power < _0n) throw new Error('Expected power > 0');
|
|
@@ -275,12 +275,13 @@ export function FpPow<T>(f: Field<T>, num: T, power: bigint): T {
|
|
|
275
275
|
while (power > _0n) {
|
|
276
276
|
if (power & _1n) p = f.mul(p, d);
|
|
277
277
|
d = f.sqr(d);
|
|
278
|
-
power >>=
|
|
278
|
+
power >>= _1n;
|
|
279
279
|
}
|
|
280
280
|
return p;
|
|
281
281
|
}
|
|
282
282
|
|
|
283
|
-
|
|
283
|
+
// 0 is non-invertible: non-batched version will throw on 0
|
|
284
|
+
export function FpInvertBatch<T>(f: IField<T>, nums: T[]): T[] {
|
|
284
285
|
const tmp = new Array(nums.length);
|
|
285
286
|
// Walk from first to last, multiply them by each other MOD p
|
|
286
287
|
const lastMultiplied = nums.reduce((acc, num, i) => {
|
|
@@ -299,12 +300,12 @@ export function FpInvertBatch<T>(f: Field<T>, nums: T[]): T[] {
|
|
|
299
300
|
return tmp;
|
|
300
301
|
}
|
|
301
302
|
|
|
302
|
-
export function FpDiv<T>(f:
|
|
303
|
+
export function FpDiv<T>(f: IField<T>, lhs: T, rhs: T | bigint): T {
|
|
303
304
|
return f.mul(lhs, typeof rhs === 'bigint' ? invert(rhs, f.ORDER) : f.inv(rhs));
|
|
304
305
|
}
|
|
305
306
|
|
|
306
307
|
// This function returns True whenever the value x is a square in the field F.
|
|
307
|
-
export function FpIsSquare<T>(f:
|
|
308
|
+
export function FpIsSquare<T>(f: IField<T>) {
|
|
308
309
|
const legendreConst = (f.ORDER - _1n) / _2n; // Integer arithmetic
|
|
309
310
|
return (x: T): boolean => {
|
|
310
311
|
const p = f.pow(x, legendreConst);
|
|
@@ -320,16 +321,24 @@ export function nLength(n: bigint, nBitLength?: number) {
|
|
|
320
321
|
return { nBitLength: _nBitLength, nByteLength };
|
|
321
322
|
}
|
|
322
323
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
324
|
+
type FpField = IField<bigint> & Required<Pick<IField<bigint>, 'isOdd'>>;
|
|
325
|
+
/**
|
|
326
|
+
* Initializes a galois field over prime. Non-primes are not supported for now.
|
|
327
|
+
* Do not init in loop: slow. Very fragile: always run a benchmark on change.
|
|
328
|
+
* Major performance gains:
|
|
329
|
+
* a) non-normalized operations like mulN instead of mul
|
|
330
|
+
* b) `Object.freeze`
|
|
331
|
+
* c) Same object shape: never add or remove keys
|
|
332
|
+
* @param ORDER prime positive bigint
|
|
333
|
+
* @param bitLen how many bits the field consumes
|
|
334
|
+
* @param isLE (def: false) if encoding / decoding should be in little-endian
|
|
335
|
+
* @param redef optional faster redefinitions of sqrt and other methods
|
|
336
|
+
*/
|
|
337
|
+
export function Field(
|
|
329
338
|
ORDER: bigint,
|
|
330
339
|
bitLen?: number,
|
|
331
340
|
isLE = false,
|
|
332
|
-
redef: Partial<
|
|
341
|
+
redef: Partial<IField<bigint>> = {}
|
|
333
342
|
): Readonly<FpField> {
|
|
334
343
|
if (ORDER <= _0n) throw new Error(`Expected Fp ORDER > 0, got ${ORDER}`);
|
|
335
344
|
const { nBitLength: BITS, nByteLength: BYTES } = nLength(ORDER, bitLen);
|
|
@@ -382,13 +391,13 @@ export function Fp(
|
|
|
382
391
|
return Object.freeze(f);
|
|
383
392
|
}
|
|
384
393
|
|
|
385
|
-
export function FpSqrtOdd<T>(Fp:
|
|
394
|
+
export function FpSqrtOdd<T>(Fp: IField<T>, elm: T) {
|
|
386
395
|
if (!Fp.isOdd) throw new Error(`Field doesn't have isOdd`);
|
|
387
396
|
const root = Fp.sqrt(elm);
|
|
388
397
|
return Fp.isOdd(root) ? root : Fp.neg(root);
|
|
389
398
|
}
|
|
390
399
|
|
|
391
|
-
export function FpSqrtEven<T>(Fp:
|
|
400
|
+
export function FpSqrtEven<T>(Fp: IField<T>, elm: T) {
|
|
392
401
|
if (!Fp.isOdd) throw new Error(`Field doesn't have isOdd`);
|
|
393
402
|
const root = Fp.sqrt(elm);
|
|
394
403
|
return Fp.isOdd(root) ? Fp.neg(root) : root;
|
package/src/abstract/poseidon.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
2
2
|
// Poseidon Hash: https://eprint.iacr.org/2019/458.pdf, https://www.poseidon-hash.info
|
|
3
|
-
import {
|
|
3
|
+
import { IField, FpPow, validateField } from './modular.js';
|
|
4
4
|
// We don't provide any constants, since different implementations use different constants.
|
|
5
5
|
// For reference constants see './test/poseidon.test.js'.
|
|
6
6
|
export type PoseidonOpts = {
|
|
7
|
-
Fp:
|
|
7
|
+
Fp: IField<bigint>;
|
|
8
8
|
t: number;
|
|
9
9
|
roundsFull: number;
|
|
10
10
|
roundsPartial: number;
|
|
@@ -58,6 +58,8 @@ export interface ProjPointType<T> extends Group<ProjPointType<T>> {
|
|
|
58
58
|
readonly px: T;
|
|
59
59
|
readonly py: T;
|
|
60
60
|
readonly pz: T;
|
|
61
|
+
get x(): T;
|
|
62
|
+
get y(): T;
|
|
61
63
|
multiply(scalar: bigint): ProjPointType<T>;
|
|
62
64
|
toAffine(iz?: T): AffinePoint<T>;
|
|
63
65
|
isTorsionFree(): boolean;
|
|
@@ -82,8 +84,8 @@ export interface ProjConstructor<T> extends GroupConstructor<ProjPointType<T>> {
|
|
|
82
84
|
|
|
83
85
|
export type CurvePointsType<T> = BasicWCurve<T> & {
|
|
84
86
|
// Bytes
|
|
85
|
-
fromBytes
|
|
86
|
-
toBytes
|
|
87
|
+
fromBytes?: (bytes: Uint8Array) => AffinePoint<T>;
|
|
88
|
+
toBytes?: (c: ProjConstructor<T>, point: ProjPointType<T>, isCompressed: boolean) => Uint8Array;
|
|
87
89
|
};
|
|
88
90
|
|
|
89
91
|
function validatePointOpts<T>(curve: CurvePointsType<T>) {
|
|
@@ -93,8 +95,6 @@ function validatePointOpts<T>(curve: CurvePointsType<T>) {
|
|
|
93
95
|
{
|
|
94
96
|
a: 'field',
|
|
95
97
|
b: 'field',
|
|
96
|
-
fromBytes: 'function',
|
|
97
|
-
toBytes: 'function',
|
|
98
98
|
},
|
|
99
99
|
{
|
|
100
100
|
allowedPrivateKeyLengths: 'array',
|
|
@@ -102,6 +102,8 @@ function validatePointOpts<T>(curve: CurvePointsType<T>) {
|
|
|
102
102
|
isTorsionFree: 'function',
|
|
103
103
|
clearCofactor: 'function',
|
|
104
104
|
allowInfinityPoint: 'boolean',
|
|
105
|
+
fromBytes: 'function',
|
|
106
|
+
toBytes: 'function',
|
|
105
107
|
}
|
|
106
108
|
);
|
|
107
109
|
const { endo, Fp, a } = opts;
|
|
@@ -176,14 +178,31 @@ const DER = {
|
|
|
176
178
|
},
|
|
177
179
|
};
|
|
178
180
|
|
|
179
|
-
// Be friendly to bad ECMAScript parsers by not using bigint literals
|
|
180
|
-
|
|
181
|
-
const _1n = BigInt(1);
|
|
181
|
+
// Be friendly to bad ECMAScript parsers by not using bigint literals
|
|
182
|
+
// prettier-ignore
|
|
183
|
+
const _0n = BigInt(0), _1n = BigInt(1), _2n = BigInt(2), _3n = BigInt(3), _4n = BigInt(4);
|
|
182
184
|
|
|
183
185
|
export function weierstrassPoints<T>(opts: CurvePointsType<T>) {
|
|
184
186
|
const CURVE = validatePointOpts(opts);
|
|
185
187
|
const { Fp } = CURVE; // All curves has same field / group length as for now, but they can differ
|
|
186
188
|
|
|
189
|
+
const toBytes =
|
|
190
|
+
CURVE.toBytes ||
|
|
191
|
+
((c: ProjConstructor<T>, point: ProjPointType<T>, isCompressed: boolean) => {
|
|
192
|
+
const a = point.toAffine();
|
|
193
|
+
return ut.concatBytes(Uint8Array.from([0x04]), Fp.toBytes(a.x), Fp.toBytes(a.y));
|
|
194
|
+
});
|
|
195
|
+
const fromBytes =
|
|
196
|
+
CURVE.fromBytes ||
|
|
197
|
+
((bytes: Uint8Array) => {
|
|
198
|
+
// const head = bytes[0];
|
|
199
|
+
const tail = bytes.subarray(1);
|
|
200
|
+
// if (head !== 0x04) throw new Error('Only non-compressed encoding is supported');
|
|
201
|
+
const x = Fp.fromBytes(tail.subarray(0, Fp.BYTES));
|
|
202
|
+
const y = Fp.fromBytes(tail.subarray(Fp.BYTES, 2 * Fp.BYTES));
|
|
203
|
+
return { x, y };
|
|
204
|
+
});
|
|
205
|
+
|
|
187
206
|
/**
|
|
188
207
|
* y² = x³ + ax + b: Short weierstrass curve formula
|
|
189
208
|
* @returns y²
|
|
@@ -280,7 +299,7 @@ export function weierstrassPoints<T>(opts: CurvePointsType<T>) {
|
|
|
280
299
|
* @param hex short/long ECDSA hex
|
|
281
300
|
*/
|
|
282
301
|
static fromHex(hex: Hex): Point {
|
|
283
|
-
const P = Point.fromAffine(
|
|
302
|
+
const P = Point.fromAffine(fromBytes(ensureBytes('pointHex', hex)));
|
|
284
303
|
P.assertValidity();
|
|
285
304
|
return P;
|
|
286
305
|
}
|
|
@@ -348,7 +367,7 @@ export function weierstrassPoints<T>(opts: CurvePointsType<T>) {
|
|
|
348
367
|
// Cost: 8M + 3S + 3*a + 2*b3 + 15add.
|
|
349
368
|
double() {
|
|
350
369
|
const { a, b } = CURVE;
|
|
351
|
-
const b3 = Fp.mul(b,
|
|
370
|
+
const b3 = Fp.mul(b, _3n);
|
|
352
371
|
const { px: X1, py: Y1, pz: Z1 } = this;
|
|
353
372
|
let X3 = Fp.ZERO, Y3 = Fp.ZERO, Z3 = Fp.ZERO; // prettier-ignore
|
|
354
373
|
let t0 = Fp.mul(X1, X1); // step 1
|
|
@@ -395,7 +414,7 @@ export function weierstrassPoints<T>(opts: CurvePointsType<T>) {
|
|
|
395
414
|
const { px: X2, py: Y2, pz: Z2 } = other;
|
|
396
415
|
let X3 = Fp.ZERO, Y3 = Fp.ZERO, Z3 = Fp.ZERO; // prettier-ignore
|
|
397
416
|
const a = CURVE.a;
|
|
398
|
-
const b3 = Fp.mul(CURVE.b,
|
|
417
|
+
const b3 = Fp.mul(CURVE.b, _3n);
|
|
399
418
|
let t0 = Fp.mul(X1, X2); // step 1
|
|
400
419
|
let t1 = Fp.mul(Y1, Y2);
|
|
401
420
|
let t2 = Fp.mul(Z1, Z2);
|
|
@@ -563,7 +582,7 @@ export function weierstrassPoints<T>(opts: CurvePointsType<T>) {
|
|
|
563
582
|
|
|
564
583
|
toRawBytes(isCompressed = true): Uint8Array {
|
|
565
584
|
this.assertValidity();
|
|
566
|
-
return
|
|
585
|
+
return toBytes(Point, this, isCompressed);
|
|
567
586
|
}
|
|
568
587
|
|
|
569
588
|
toHex(isCompressed = true): string {
|
|
@@ -574,6 +593,7 @@ export function weierstrassPoints<T>(opts: CurvePointsType<T>) {
|
|
|
574
593
|
const wnaf = wNAF(Point, CURVE.endo ? Math.ceil(_bits / 2) : _bits);
|
|
575
594
|
|
|
576
595
|
return {
|
|
596
|
+
CURVE,
|
|
577
597
|
ProjectivePoint: Point as ProjConstructor<T>,
|
|
578
598
|
normPrivateKeyToScalar,
|
|
579
599
|
weierstrassEquation,
|
|
@@ -652,8 +672,7 @@ export type CurveFn = {
|
|
|
652
672
|
|
|
653
673
|
export function weierstrass(curveDef: CurveType): CurveFn {
|
|
654
674
|
const CURVE = validateOpts(curveDef) as ReturnType<typeof validateOpts>;
|
|
655
|
-
const CURVE_ORDER = CURVE
|
|
656
|
-
const Fp = CURVE.Fp;
|
|
675
|
+
const { Fp, n: CURVE_ORDER } = CURVE;
|
|
657
676
|
const compressedLen = Fp.BYTES + 1; // e.g. 33 for 32
|
|
658
677
|
const uncompressedLen = 2 * Fp.BYTES + 1; // e.g. 65 for 32
|
|
659
678
|
|
|
@@ -1055,22 +1074,21 @@ export function weierstrass(curveDef: CurveType): CurveFn {
|
|
|
1055
1074
|
}
|
|
1056
1075
|
|
|
1057
1076
|
// Implementation of the Shallue and van de Woestijne method for any Weierstrass curve
|
|
1058
|
-
|
|
1059
1077
|
// TODO: check if there is a way to merge this with uvRatio in Edwards && move to modular?
|
|
1060
1078
|
// b = True and y = sqrt(u / v) if (u / v) is square in F, and
|
|
1061
1079
|
// b = False and y = sqrt(Z * (u / v)) otherwise.
|
|
1062
|
-
export function SWUFpSqrtRatio<T>(Fp: mod.
|
|
1080
|
+
export function SWUFpSqrtRatio<T>(Fp: mod.IField<T>, Z: T) {
|
|
1063
1081
|
// Generic implementation
|
|
1064
1082
|
const q = Fp.ORDER;
|
|
1065
|
-
let l =
|
|
1066
|
-
for (let o = q -
|
|
1083
|
+
let l = _0n;
|
|
1084
|
+
for (let o = q - _1n; o % _2n === _0n; o /= _2n) l += _1n;
|
|
1067
1085
|
const c1 = l; // 1. c1, the largest integer such that 2^c1 divides q - 1.
|
|
1068
|
-
const c2 = (q -
|
|
1069
|
-
const c3 = (c2 -
|
|
1070
|
-
const c4 =
|
|
1071
|
-
const c5 =
|
|
1086
|
+
const c2 = (q - _1n) / _2n ** c1; // 2. c2 = (q - 1) / (2^c1) # Integer arithmetic
|
|
1087
|
+
const c3 = (c2 - _1n) / _2n; // 3. c3 = (c2 - 1) / 2 # Integer arithmetic
|
|
1088
|
+
const c4 = _2n ** c1 - _1n; // 4. c4 = 2^c1 - 1 # Integer arithmetic
|
|
1089
|
+
const c5 = _2n ** (c1 - _1n); // 5. c5 = 2^(c1 - 1) # Integer arithmetic
|
|
1072
1090
|
const c6 = Fp.pow(Z, c2); // 6. c6 = Z^c2
|
|
1073
|
-
const c7 = Fp.pow(Z, (c2 +
|
|
1091
|
+
const c7 = Fp.pow(Z, (c2 + _1n) / _2n); // 7. c7 = Z^((c2 + 1) / 2)
|
|
1074
1092
|
let sqrtRatio = (u: T, v: T): { isValid: boolean; value: T } => {
|
|
1075
1093
|
let tv1 = c6; // 1. tv1 = c6
|
|
1076
1094
|
let tv2 = Fp.pow(v, c4); // 2. tv2 = v^c4
|
|
@@ -1090,7 +1108,7 @@ export function SWUFpSqrtRatio<T>(Fp: mod.Field<T>, Z: T) {
|
|
|
1090
1108
|
tv4 = Fp.cmov(tv5, tv4, isQR); // 16. tv4 = CMOV(tv5, tv4, isQR)
|
|
1091
1109
|
// 17. for i in (c1, c1 - 1, ..., 2):
|
|
1092
1110
|
for (let i = c1; i > 1; i--) {
|
|
1093
|
-
let tv5 =
|
|
1111
|
+
let tv5 = _2n ** (i - _2n); // 18. tv5 = i - 2; 19. tv5 = 2^tv5
|
|
1094
1112
|
let tvv5 = Fp.pow(tv4, tv5); // 20. tv5 = tv4^tv5
|
|
1095
1113
|
const e1 = Fp.eql(tvv5, Fp.ONE); // 21. e1 = tv5 == 1
|
|
1096
1114
|
tv2 = Fp.mul(tv3, tv1); // 22. tv2 = tv3 * tv1
|
|
@@ -1101,9 +1119,9 @@ export function SWUFpSqrtRatio<T>(Fp: mod.Field<T>, Z: T) {
|
|
|
1101
1119
|
}
|
|
1102
1120
|
return { isValid: isQR, value: tv3 };
|
|
1103
1121
|
};
|
|
1104
|
-
if (Fp.ORDER %
|
|
1122
|
+
if (Fp.ORDER % _4n === _3n) {
|
|
1105
1123
|
// sqrt_ratio_3mod4(u, v)
|
|
1106
|
-
const c1 = (Fp.ORDER -
|
|
1124
|
+
const c1 = (Fp.ORDER - _3n) / _4n; // 1. c1 = (q - 3) / 4 # Integer arithmetic
|
|
1107
1125
|
const c2 = Fp.sqrt(Fp.neg(Z)); // 2. c2 = sqrt(-Z)
|
|
1108
1126
|
sqrtRatio = (u: T, v: T) => {
|
|
1109
1127
|
let tv1 = Fp.sqr(v); // 1. tv1 = v^2
|
|
@@ -1119,12 +1137,12 @@ export function SWUFpSqrtRatio<T>(Fp: mod.Field<T>, Z: T) {
|
|
|
1119
1137
|
};
|
|
1120
1138
|
}
|
|
1121
1139
|
// No curves uses that
|
|
1122
|
-
// if (Fp.ORDER %
|
|
1140
|
+
// if (Fp.ORDER % _8n === _5n) // sqrt_ratio_5mod8
|
|
1123
1141
|
return sqrtRatio;
|
|
1124
1142
|
}
|
|
1125
1143
|
// From draft-irtf-cfrg-hash-to-curve-16
|
|
1126
1144
|
export function mapToCurveSimpleSWU<T>(
|
|
1127
|
-
Fp: mod.
|
|
1145
|
+
Fp: mod.IField<T>,
|
|
1128
1146
|
opts: {
|
|
1129
1147
|
A: T;
|
|
1130
1148
|
B: T;
|