@noble/curves 0.9.0 → 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/abstract/edwards.d.ts +4 -0
- package/abstract/edwards.d.ts.map +1 -1
- package/abstract/edwards.js +8 -9
- package/abstract/edwards.js.map +1 -1
- package/abstract/modular.js +1 -1
- package/abstract/modular.js.map +1 -1
- package/abstract/weierstrass.d.ts +2 -0
- package/abstract/weierstrass.d.ts.map +1 -1
- package/abstract/weierstrass.js +17 -17
- package/abstract/weierstrass.js.map +1 -1
- package/bls12-381.d.ts.map +1 -1
- package/bls12-381.js +109 -106
- package/bls12-381.js.map +1 -1
- package/ed25519.js +1 -1
- package/ed25519.js.map +1 -1
- package/ed448.d.ts.map +1 -1
- package/ed448.js +3 -2
- package/ed448.js.map +1 -1
- package/esm/abstract/edwards.js +8 -9
- package/esm/abstract/edwards.js.map +1 -1
- package/esm/abstract/modular.js +1 -1
- package/esm/abstract/modular.js.map +1 -1
- package/esm/abstract/weierstrass.js +17 -17
- 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/ed25519.js +1 -1
- package/esm/ed25519.js.map +1 -1
- package/esm/ed448.js +3 -2
- package/esm/ed448.js.map +1 -1
- package/esm/secp256k1.js +1 -1
- package/esm/secp256k1.js.map +1 -1
- package/package.json +1 -1
- package/secp256k1.js +1 -1
- package/secp256k1.js.map +1 -1
- package/src/abstract/edwards.ts +12 -9
- package/src/abstract/modular.ts +1 -1
- package/src/abstract/weierstrass.ts +18 -16
- package/src/bls12-381.ts +196 -111
- package/src/ed25519.ts +1 -1
- package/src/ed448.ts +3 -2
- package/src/secp256k1.ts +1 -1
package/src/abstract/modular.ts
CHANGED
|
@@ -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;
|
|
@@ -176,9 +178,9 @@ 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);
|
|
@@ -365,7 +367,7 @@ export function weierstrassPoints<T>(opts: CurvePointsType<T>) {
|
|
|
365
367
|
// Cost: 8M + 3S + 3*a + 2*b3 + 15add.
|
|
366
368
|
double() {
|
|
367
369
|
const { a, b } = CURVE;
|
|
368
|
-
const b3 = Fp.mul(b,
|
|
370
|
+
const b3 = Fp.mul(b, _3n);
|
|
369
371
|
const { px: X1, py: Y1, pz: Z1 } = this;
|
|
370
372
|
let X3 = Fp.ZERO, Y3 = Fp.ZERO, Z3 = Fp.ZERO; // prettier-ignore
|
|
371
373
|
let t0 = Fp.mul(X1, X1); // step 1
|
|
@@ -412,7 +414,7 @@ export function weierstrassPoints<T>(opts: CurvePointsType<T>) {
|
|
|
412
414
|
const { px: X2, py: Y2, pz: Z2 } = other;
|
|
413
415
|
let X3 = Fp.ZERO, Y3 = Fp.ZERO, Z3 = Fp.ZERO; // prettier-ignore
|
|
414
416
|
const a = CURVE.a;
|
|
415
|
-
const b3 = Fp.mul(CURVE.b,
|
|
417
|
+
const b3 = Fp.mul(CURVE.b, _3n);
|
|
416
418
|
let t0 = Fp.mul(X1, X2); // step 1
|
|
417
419
|
let t1 = Fp.mul(Y1, Y2);
|
|
418
420
|
let t2 = Fp.mul(Z1, Z2);
|
|
@@ -1078,15 +1080,15 @@ export function weierstrass(curveDef: CurveType): CurveFn {
|
|
|
1078
1080
|
export function SWUFpSqrtRatio<T>(Fp: mod.IField<T>, Z: T) {
|
|
1079
1081
|
// Generic implementation
|
|
1080
1082
|
const q = Fp.ORDER;
|
|
1081
|
-
let l =
|
|
1082
|
-
for (let o = q -
|
|
1083
|
+
let l = _0n;
|
|
1084
|
+
for (let o = q - _1n; o % _2n === _0n; o /= _2n) l += _1n;
|
|
1083
1085
|
const c1 = l; // 1. c1, the largest integer such that 2^c1 divides q - 1.
|
|
1084
|
-
const c2 = (q -
|
|
1085
|
-
const c3 = (c2 -
|
|
1086
|
-
const c4 =
|
|
1087
|
-
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
|
|
1088
1090
|
const c6 = Fp.pow(Z, c2); // 6. c6 = Z^c2
|
|
1089
|
-
const c7 = Fp.pow(Z, (c2 +
|
|
1091
|
+
const c7 = Fp.pow(Z, (c2 + _1n) / _2n); // 7. c7 = Z^((c2 + 1) / 2)
|
|
1090
1092
|
let sqrtRatio = (u: T, v: T): { isValid: boolean; value: T } => {
|
|
1091
1093
|
let tv1 = c6; // 1. tv1 = c6
|
|
1092
1094
|
let tv2 = Fp.pow(v, c4); // 2. tv2 = v^c4
|
|
@@ -1106,7 +1108,7 @@ export function SWUFpSqrtRatio<T>(Fp: mod.IField<T>, Z: T) {
|
|
|
1106
1108
|
tv4 = Fp.cmov(tv5, tv4, isQR); // 16. tv4 = CMOV(tv5, tv4, isQR)
|
|
1107
1109
|
// 17. for i in (c1, c1 - 1, ..., 2):
|
|
1108
1110
|
for (let i = c1; i > 1; i--) {
|
|
1109
|
-
let tv5 =
|
|
1111
|
+
let tv5 = _2n ** (i - _2n); // 18. tv5 = i - 2; 19. tv5 = 2^tv5
|
|
1110
1112
|
let tvv5 = Fp.pow(tv4, tv5); // 20. tv5 = tv4^tv5
|
|
1111
1113
|
const e1 = Fp.eql(tvv5, Fp.ONE); // 21. e1 = tv5 == 1
|
|
1112
1114
|
tv2 = Fp.mul(tv3, tv1); // 22. tv2 = tv3 * tv1
|
|
@@ -1117,9 +1119,9 @@ export function SWUFpSqrtRatio<T>(Fp: mod.IField<T>, Z: T) {
|
|
|
1117
1119
|
}
|
|
1118
1120
|
return { isValid: isQR, value: tv3 };
|
|
1119
1121
|
};
|
|
1120
|
-
if (Fp.ORDER %
|
|
1122
|
+
if (Fp.ORDER % _4n === _3n) {
|
|
1121
1123
|
// sqrt_ratio_3mod4(u, v)
|
|
1122
|
-
const c1 = (Fp.ORDER -
|
|
1124
|
+
const c1 = (Fp.ORDER - _3n) / _4n; // 1. c1 = (q - 3) / 4 # Integer arithmetic
|
|
1123
1125
|
const c2 = Fp.sqrt(Fp.neg(Z)); // 2. c2 = sqrt(-Z)
|
|
1124
1126
|
sqrtRatio = (u: T, v: T) => {
|
|
1125
1127
|
let tv1 = Fp.sqr(v); // 1. tv1 = v^2
|
|
@@ -1135,7 +1137,7 @@ export function SWUFpSqrtRatio<T>(Fp: mod.IField<T>, Z: T) {
|
|
|
1135
1137
|
};
|
|
1136
1138
|
}
|
|
1137
1139
|
// No curves uses that
|
|
1138
|
-
// if (Fp.ORDER %
|
|
1140
|
+
// if (Fp.ORDER % _8n === _5n) // sqrt_ratio_5mod8
|
|
1139
1141
|
return sqrtRatio;
|
|
1140
1142
|
}
|
|
1141
1143
|
// From draft-irtf-cfrg-hash-to-curve-16
|
package/src/bls12-381.ts
CHANGED
|
@@ -69,16 +69,23 @@ import {
|
|
|
69
69
|
} from './abstract/weierstrass.js';
|
|
70
70
|
import { isogenyMap } from './abstract/hash-to-curve.js';
|
|
71
71
|
|
|
72
|
+
// Be friendly to bad ECMAScript parsers by not using bigint literals
|
|
73
|
+
// prettier-ignore
|
|
74
|
+
const _0n = BigInt(0), _1n = BigInt(1), _2n = BigInt(2), _3n = BigInt(3), _4n = BigInt(4);
|
|
75
|
+
const _8n = BigInt(8),
|
|
76
|
+
_16n = BigInt(16);
|
|
77
|
+
|
|
72
78
|
// CURVE FIELDS
|
|
73
79
|
// Finite field over p.
|
|
74
|
-
const Fp =
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
)
|
|
80
|
+
const Fp = mod.Field(
|
|
81
|
+
BigInt(
|
|
82
|
+
'0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab'
|
|
83
|
+
)
|
|
84
|
+
);
|
|
78
85
|
type Fp = bigint;
|
|
79
86
|
// Finite field over r.
|
|
80
87
|
// This particular field is not used anywhere in bls12-381, but it is still useful.
|
|
81
|
-
const Fr = mod.Field(
|
|
88
|
+
const Fr = mod.Field(BigInt('0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001'));
|
|
82
89
|
|
|
83
90
|
// Fp₂ over complex plane
|
|
84
91
|
type BigintTuple = [bigint, bigint];
|
|
@@ -121,8 +128,9 @@ type Fp2Utils = {
|
|
|
121
128
|
// h2q
|
|
122
129
|
// NOTE: ORDER was wrong!
|
|
123
130
|
const FP2_ORDER =
|
|
124
|
-
|
|
125
|
-
|
|
131
|
+
BigInt(
|
|
132
|
+
'0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab'
|
|
133
|
+
) ** _2n;
|
|
126
134
|
|
|
127
135
|
const Fp2: mod.IField<Fp2> & Fp2Utils = {
|
|
128
136
|
ORDER: FP2_ORDER,
|
|
@@ -175,7 +183,7 @@ const Fp2: mod.IField<Fp2> & Fp2Utils = {
|
|
|
175
183
|
// https://github.com/zkcrypto/bls12_381/blob/080eaa74ec0e394377caa1ba302c8c121df08b07/src/fp2.rs#L250
|
|
176
184
|
// https://github.com/supranational/blst/blob/aae0c7d70b799ac269ff5edf29d8191dbd357876/src/exp2.c#L1
|
|
177
185
|
// Inspired by https://github.com/dalek-cryptography/curve25519-dalek/blob/17698df9d4c834204f83a3574143abacb4fc81a5/src/field.rs#L99
|
|
178
|
-
const candidateSqrt = Fp2.pow(num, (Fp2.ORDER +
|
|
186
|
+
const candidateSqrt = Fp2.pow(num, (Fp2.ORDER + _8n) / _16n);
|
|
179
187
|
const check = Fp2.div(Fp2.sqr(candidateSqrt), num); // candidateSqrt.square().div(this);
|
|
180
188
|
const R = FP2_ROOTS_OF_UNITY;
|
|
181
189
|
const divisor = [R[0], R[2], R[4], R[6]].find((r) => Fp2.eql(r, check));
|
|
@@ -193,10 +201,10 @@ const Fp2: mod.IField<Fp2> & Fp2Utils = {
|
|
|
193
201
|
// Same as sgn0_fp2 in draft-irtf-cfrg-hash-to-curve-16
|
|
194
202
|
isOdd: (x: Fp2) => {
|
|
195
203
|
const { re: x0, im: x1 } = Fp2.reim(x);
|
|
196
|
-
const sign_0 = x0 %
|
|
197
|
-
const zero_0 = x0 ===
|
|
198
|
-
const sign_1 = x1 %
|
|
199
|
-
return BigInt(sign_0 || (zero_0 && sign_1)) ==
|
|
204
|
+
const sign_0 = x0 % _2n;
|
|
205
|
+
const zero_0 = x0 === _0n;
|
|
206
|
+
const sign_1 = x1 % _2n;
|
|
207
|
+
return BigInt(sign_0 || (zero_0 && sign_1)) == _1n;
|
|
200
208
|
},
|
|
201
209
|
// Bytes util
|
|
202
210
|
fromBytes(b: Uint8Array): Fp2 {
|
|
@@ -216,8 +224,8 @@ const Fp2: mod.IField<Fp2> & Fp2Utils = {
|
|
|
216
224
|
// multiply by u + 1
|
|
217
225
|
mulByNonresidue: ({ c0, c1 }) => ({ c0: Fp.sub(c0, c1), c1: Fp.add(c0, c1) }),
|
|
218
226
|
multiplyByB: ({ c0, c1 }) => {
|
|
219
|
-
let t0 = Fp.mul(c0,
|
|
220
|
-
let t1 = Fp.mul(c1,
|
|
227
|
+
let t0 = Fp.mul(c0, _4n); // 4 * c0
|
|
228
|
+
let t1 = Fp.mul(c1, _4n); // 4 * c1
|
|
221
229
|
// (T0-T1) + (T0+T1)*i
|
|
222
230
|
return { c0: Fp.sub(t0, t1), c1: Fp.add(t0, t1) };
|
|
223
231
|
},
|
|
@@ -234,33 +242,36 @@ const Fp2: mod.IField<Fp2> & Fp2Utils = {
|
|
|
234
242
|
// Finite extension field over irreducible polynominal.
|
|
235
243
|
// Fp(u) / (u² - β) where β = -1
|
|
236
244
|
const FP2_FROBENIUS_COEFFICIENTS = [
|
|
237
|
-
|
|
238
|
-
|
|
245
|
+
BigInt('0x1'),
|
|
246
|
+
BigInt(
|
|
247
|
+
'0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaaa'
|
|
248
|
+
),
|
|
239
249
|
].map((item) => Fp.create(item));
|
|
240
250
|
|
|
241
251
|
// For Fp2 roots of unity.
|
|
242
|
-
const rv1 =
|
|
243
|
-
|
|
252
|
+
const rv1 = BigInt(
|
|
253
|
+
'0x6af0e0437ff400b6831e36d6bd17ffe48395dabc2d3435e77f76e17009241c5ee67992f72ec05f4c81084fbede3cc09'
|
|
254
|
+
);
|
|
244
255
|
// const ev1 =
|
|
245
|
-
//
|
|
256
|
+
// BigInt('0x699be3b8c6870965e5bf892ad5d2cc7b0e85a117402dfd83b7f4a947e02d978498255a2aaec0ac627b5afbdf1bf1c90');
|
|
246
257
|
// const ev2 =
|
|
247
|
-
//
|
|
258
|
+
// BigInt('0x8157cd83046453f5dd0972b6e3949e4288020b5b8a9cc99ca07e27089a2ce2436d965026adad3ef7baba37f2183e9b5');
|
|
248
259
|
// const ev3 =
|
|
249
|
-
//
|
|
260
|
+
// BigInt('0xab1c2ffdd6c253ca155231eb3e71ba044fd562f6f72bc5bad5ec46a0b7a3b0247cf08ce6c6317f40edbc653a72dee17');
|
|
250
261
|
// const ev4 =
|
|
251
|
-
//
|
|
262
|
+
// BigInt('0xaa404866706722864480885d68ad0ccac1967c7544b447873cc37e0181271e006df72162a3d3e0287bf597fbf7f8fc1');
|
|
252
263
|
|
|
253
264
|
// Eighth roots of unity, used for computing square roots in Fp2.
|
|
254
265
|
// To verify or re-calculate:
|
|
255
266
|
// Array(8).fill(new Fp2([1n, 1n])).map((fp2, k) => fp2.pow(Fp2.ORDER * BigInt(k) / 8n))
|
|
256
267
|
const FP2_ROOTS_OF_UNITY = [
|
|
257
|
-
[
|
|
268
|
+
[_1n, _0n],
|
|
258
269
|
[rv1, -rv1],
|
|
259
|
-
[
|
|
270
|
+
[_0n, _1n],
|
|
260
271
|
[rv1, rv1],
|
|
261
|
-
[-
|
|
272
|
+
[-_1n, _0n],
|
|
262
273
|
[-rv1, rv1],
|
|
263
|
-
[
|
|
274
|
+
[_0n, -_1n],
|
|
264
275
|
[-rv1, -rv1],
|
|
265
276
|
].map((pair) => Fp2.fromBigTuple(pair));
|
|
266
277
|
// eta values, used for computing sqrt(g(X1(t)))
|
|
@@ -314,8 +325,8 @@ const Fp6Multiply = ({ c0, c1, c2 }: Fp6, rhs: Fp6 | bigint) => {
|
|
|
314
325
|
};
|
|
315
326
|
const Fp6Square = ({ c0, c1, c2 }: Fp6) => {
|
|
316
327
|
let t0 = Fp2.sqr(c0); // c0²
|
|
317
|
-
let t1 = Fp2.mul(Fp2.mul(c0, c1),
|
|
318
|
-
let t3 = Fp2.mul(Fp2.mul(c1, c2),
|
|
328
|
+
let t1 = Fp2.mul(Fp2.mul(c0, c1), _2n); // 2 * c0 * c1
|
|
329
|
+
let t3 = Fp2.mul(Fp2.mul(c1, c2), _2n); // 2 * c1 * c2
|
|
319
330
|
let t4 = Fp2.sqr(c2); // c2²
|
|
320
331
|
return {
|
|
321
332
|
c0: Fp2.add(Fp2.mulByNonresidue(t3), t0), // T3 * (u + 1) + T0
|
|
@@ -440,46 +451,64 @@ const Fp6: mod.IField<Fp6> & Fp6Utils = {
|
|
|
440
451
|
};
|
|
441
452
|
|
|
442
453
|
const FP6_FROBENIUS_COEFFICIENTS_1 = [
|
|
443
|
-
[
|
|
454
|
+
[BigInt('0x1'), BigInt('0x0')],
|
|
444
455
|
[
|
|
445
|
-
|
|
446
|
-
|
|
456
|
+
BigInt('0x0'),
|
|
457
|
+
BigInt(
|
|
458
|
+
'0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaac'
|
|
459
|
+
),
|
|
447
460
|
],
|
|
448
461
|
[
|
|
449
|
-
|
|
450
|
-
|
|
462
|
+
BigInt(
|
|
463
|
+
'0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffe'
|
|
464
|
+
),
|
|
465
|
+
BigInt('0x0'),
|
|
451
466
|
],
|
|
452
|
-
[
|
|
467
|
+
[BigInt('0x0'), BigInt('0x1')],
|
|
453
468
|
[
|
|
454
|
-
|
|
455
|
-
|
|
469
|
+
BigInt(
|
|
470
|
+
'0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaac'
|
|
471
|
+
),
|
|
472
|
+
BigInt('0x0'),
|
|
456
473
|
],
|
|
457
474
|
[
|
|
458
|
-
|
|
459
|
-
|
|
475
|
+
BigInt('0x0'),
|
|
476
|
+
BigInt(
|
|
477
|
+
'0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffe'
|
|
478
|
+
),
|
|
460
479
|
],
|
|
461
480
|
].map((pair) => Fp2.fromBigTuple(pair));
|
|
462
481
|
const FP6_FROBENIUS_COEFFICIENTS_2 = [
|
|
463
|
-
[
|
|
482
|
+
[BigInt('0x1'), BigInt('0x0')],
|
|
464
483
|
[
|
|
465
|
-
|
|
466
|
-
|
|
484
|
+
BigInt(
|
|
485
|
+
'0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaad'
|
|
486
|
+
),
|
|
487
|
+
BigInt('0x0'),
|
|
467
488
|
],
|
|
468
489
|
[
|
|
469
|
-
|
|
470
|
-
|
|
490
|
+
BigInt(
|
|
491
|
+
'0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaac'
|
|
492
|
+
),
|
|
493
|
+
BigInt('0x0'),
|
|
471
494
|
],
|
|
472
495
|
[
|
|
473
|
-
|
|
474
|
-
|
|
496
|
+
BigInt(
|
|
497
|
+
'0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaaa'
|
|
498
|
+
),
|
|
499
|
+
BigInt('0x0'),
|
|
475
500
|
],
|
|
476
501
|
[
|
|
477
|
-
|
|
478
|
-
|
|
502
|
+
BigInt(
|
|
503
|
+
'0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffe'
|
|
504
|
+
),
|
|
505
|
+
BigInt('0x0'),
|
|
479
506
|
],
|
|
480
507
|
[
|
|
481
|
-
|
|
482
|
-
|
|
508
|
+
BigInt(
|
|
509
|
+
'0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffeffff'
|
|
510
|
+
),
|
|
511
|
+
BigInt('0x0'),
|
|
483
512
|
],
|
|
484
513
|
].map((pair) => Fp2.fromBigTuple(pair));
|
|
485
514
|
|
|
@@ -488,7 +517,7 @@ const FP6_FROBENIUS_COEFFICIENTS_2 = [
|
|
|
488
517
|
// Fp₆(w) / (w² - γ) where γ = v
|
|
489
518
|
type Fp12 = { c0: Fp6; c1: Fp6 };
|
|
490
519
|
// The BLS parameter x for BLS12-381
|
|
491
|
-
const BLS_X =
|
|
520
|
+
const BLS_X = BigInt('0xd201000000010000');
|
|
492
521
|
const BLS_X_LEN = bitLen(BLS_X);
|
|
493
522
|
|
|
494
523
|
// prettier-ignore
|
|
@@ -646,14 +675,14 @@ const Fp12: mod.IField<Fp12> & Fp12Utils = {
|
|
|
646
675
|
let t9 = Fp2.mulByNonresidue(t8); // T8 * (u + 1)
|
|
647
676
|
return {
|
|
648
677
|
c0: Fp6.create({
|
|
649
|
-
c0: Fp2.add(Fp2.mul(Fp2.sub(t3, c0c0),
|
|
650
|
-
c1: Fp2.add(Fp2.mul(Fp2.sub(t5, c0c1),
|
|
651
|
-
c2: Fp2.add(Fp2.mul(Fp2.sub(t7, c0c2),
|
|
678
|
+
c0: Fp2.add(Fp2.mul(Fp2.sub(t3, c0c0), _2n), t3), // 2 * (T3 - c0c0) + T3
|
|
679
|
+
c1: Fp2.add(Fp2.mul(Fp2.sub(t5, c0c1), _2n), t5), // 2 * (T5 - c0c1) + T5
|
|
680
|
+
c2: Fp2.add(Fp2.mul(Fp2.sub(t7, c0c2), _2n), t7),
|
|
652
681
|
}), // 2 * (T7 - c0c2) + T7
|
|
653
682
|
c1: Fp6.create({
|
|
654
|
-
c0: Fp2.add(Fp2.mul(Fp2.add(t9, c1c0),
|
|
655
|
-
c1: Fp2.add(Fp2.mul(Fp2.add(t4, c1c1),
|
|
656
|
-
c2: Fp2.add(Fp2.mul(Fp2.add(t6, c1c2),
|
|
683
|
+
c0: Fp2.add(Fp2.mul(Fp2.add(t9, c1c0), _2n), t9), // 2 * (T9 + c1c0) + T9
|
|
684
|
+
c1: Fp2.add(Fp2.mul(Fp2.add(t4, c1c1), _2n), t4), // 2 * (T4 + c1c1) + T4
|
|
685
|
+
c2: Fp2.add(Fp2.mul(Fp2.add(t6, c1c2), _2n), t6),
|
|
657
686
|
}),
|
|
658
687
|
}; // 2 * (T6 + c1c2) + T6
|
|
659
688
|
},
|
|
@@ -688,50 +717,84 @@ const Fp12: mod.IField<Fp12> & Fp12Utils = {
|
|
|
688
717
|
},
|
|
689
718
|
};
|
|
690
719
|
const FP12_FROBENIUS_COEFFICIENTS = [
|
|
691
|
-
[
|
|
720
|
+
[BigInt('0x1'), BigInt('0x0')],
|
|
692
721
|
[
|
|
693
|
-
|
|
694
|
-
|
|
722
|
+
BigInt(
|
|
723
|
+
'0x1904d3bf02bb0667c231beb4202c0d1f0fd603fd3cbd5f4f7b2443d784bab9c4f67ea53d63e7813d8d0775ed92235fb8'
|
|
724
|
+
),
|
|
725
|
+
BigInt(
|
|
726
|
+
'0x00fc3e2b36c4e03288e9e902231f9fb854a14787b6c7b36fec0c8ec971f63c5f282d5ac14d6c7ec22cf78a126ddc4af3'
|
|
727
|
+
),
|
|
695
728
|
],
|
|
696
729
|
[
|
|
697
|
-
|
|
698
|
-
|
|
730
|
+
BigInt(
|
|
731
|
+
'0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffeffff'
|
|
732
|
+
),
|
|
733
|
+
BigInt('0x0'),
|
|
699
734
|
],
|
|
700
735
|
[
|
|
701
|
-
|
|
702
|
-
|
|
736
|
+
BigInt(
|
|
737
|
+
'0x135203e60180a68ee2e9c448d77a2cd91c3dedd930b1cf60ef396489f61eb45e304466cf3e67fa0af1ee7b04121bdea2'
|
|
738
|
+
),
|
|
739
|
+
BigInt(
|
|
740
|
+
'0x06af0e0437ff400b6831e36d6bd17ffe48395dabc2d3435e77f76e17009241c5ee67992f72ec05f4c81084fbede3cc09'
|
|
741
|
+
),
|
|
703
742
|
],
|
|
704
743
|
[
|
|
705
|
-
|
|
706
|
-
|
|
744
|
+
BigInt(
|
|
745
|
+
'0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffe'
|
|
746
|
+
),
|
|
747
|
+
BigInt('0x0'),
|
|
707
748
|
],
|
|
708
749
|
[
|
|
709
|
-
|
|
710
|
-
|
|
750
|
+
BigInt(
|
|
751
|
+
'0x144e4211384586c16bd3ad4afa99cc9170df3560e77982d0db45f3536814f0bd5871c1908bd478cd1ee605167ff82995'
|
|
752
|
+
),
|
|
753
|
+
BigInt(
|
|
754
|
+
'0x05b2cfd9013a5fd8df47fa6b48b1e045f39816240c0b8fee8beadf4d8e9c0566c63a3e6e257f87329b18fae980078116'
|
|
755
|
+
),
|
|
711
756
|
],
|
|
712
757
|
[
|
|
713
|
-
|
|
714
|
-
|
|
758
|
+
BigInt(
|
|
759
|
+
'0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaaa'
|
|
760
|
+
),
|
|
761
|
+
BigInt('0x0'),
|
|
715
762
|
],
|
|
716
763
|
[
|
|
717
|
-
|
|
718
|
-
|
|
764
|
+
BigInt(
|
|
765
|
+
'0x00fc3e2b36c4e03288e9e902231f9fb854a14787b6c7b36fec0c8ec971f63c5f282d5ac14d6c7ec22cf78a126ddc4af3'
|
|
766
|
+
),
|
|
767
|
+
BigInt(
|
|
768
|
+
'0x1904d3bf02bb0667c231beb4202c0d1f0fd603fd3cbd5f4f7b2443d784bab9c4f67ea53d63e7813d8d0775ed92235fb8'
|
|
769
|
+
),
|
|
719
770
|
],
|
|
720
771
|
[
|
|
721
|
-
|
|
722
|
-
|
|
772
|
+
BigInt(
|
|
773
|
+
'0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaac'
|
|
774
|
+
),
|
|
775
|
+
BigInt('0x0'),
|
|
723
776
|
],
|
|
724
777
|
[
|
|
725
|
-
|
|
726
|
-
|
|
778
|
+
BigInt(
|
|
779
|
+
'0x06af0e0437ff400b6831e36d6bd17ffe48395dabc2d3435e77f76e17009241c5ee67992f72ec05f4c81084fbede3cc09'
|
|
780
|
+
),
|
|
781
|
+
BigInt(
|
|
782
|
+
'0x135203e60180a68ee2e9c448d77a2cd91c3dedd930b1cf60ef396489f61eb45e304466cf3e67fa0af1ee7b04121bdea2'
|
|
783
|
+
),
|
|
727
784
|
],
|
|
728
785
|
[
|
|
729
|
-
|
|
730
|
-
|
|
786
|
+
BigInt(
|
|
787
|
+
'0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaad'
|
|
788
|
+
),
|
|
789
|
+
BigInt('0x0'),
|
|
731
790
|
],
|
|
732
791
|
[
|
|
733
|
-
|
|
734
|
-
|
|
792
|
+
BigInt(
|
|
793
|
+
'0x05b2cfd9013a5fd8df47fa6b48b1e045f39816240c0b8fee8beadf4d8e9c0566c63a3e6e257f87329b18fae980078116'
|
|
794
|
+
),
|
|
795
|
+
BigInt(
|
|
796
|
+
'0x144e4211384586c16bd3ad4afa99cc9170df3560e77982d0db45f3536814f0bd5871c1908bd478cd1ee605167ff82995'
|
|
797
|
+
),
|
|
735
798
|
],
|
|
736
799
|
].map((n) => Fp2.fromBigTuple(n));
|
|
737
800
|
// END OF CURVE FIELDS
|
|
@@ -887,17 +950,21 @@ const isogenyMapG1 = isogenyMap(
|
|
|
887
950
|
|
|
888
951
|
// SWU Map - Fp2 to G2': y² = x³ + 240i * x + 1012 + 1012i
|
|
889
952
|
const G2_SWU = mapToCurveSimpleSWU(Fp2, {
|
|
890
|
-
A: Fp2.create({ c0: Fp.create(
|
|
953
|
+
A: Fp2.create({ c0: Fp.create(_0n), c1: Fp.create(240n) }), // A' = 240 * I
|
|
891
954
|
B: Fp2.create({ c0: Fp.create(1012n), c1: Fp.create(1012n) }), // B' = 1012 * (1 + I)
|
|
892
955
|
Z: Fp2.create({ c0: Fp.create(-2n), c1: Fp.create(-1n) }), // Z: -(2 + I)
|
|
893
956
|
});
|
|
894
957
|
// Optimized SWU Map - Fp to G1
|
|
895
958
|
const G1_SWU = mapToCurveSimpleSWU(Fp, {
|
|
896
959
|
A: Fp.create(
|
|
897
|
-
|
|
960
|
+
BigInt(
|
|
961
|
+
'0x144698a3b8e9433d693a02c96d4982b0ea985383ee66a8d8e8981aefd881ac98936f8da0e0f97f5cf428082d584c1d'
|
|
962
|
+
)
|
|
898
963
|
),
|
|
899
964
|
B: Fp.create(
|
|
900
|
-
|
|
965
|
+
BigInt(
|
|
966
|
+
'0x12e2908d11688030018b12e8753eee3b2016c1f0f24f4070a0b9c14fcef35ef55a23215a316ceaa5d1cc48e98e172be0'
|
|
967
|
+
)
|
|
901
968
|
),
|
|
902
969
|
Z: Fp.create(11n),
|
|
903
970
|
});
|
|
@@ -922,8 +989,9 @@ function G2psi(c: ProjConstructor<Fp2>, P: ProjPointType<Fp2>) {
|
|
|
922
989
|
}
|
|
923
990
|
// Ψ²(P) endomorphism
|
|
924
991
|
// 1 / F2(2)^((p-1)/3) in GF(p²)
|
|
925
|
-
const PSI2_C1 =
|
|
926
|
-
|
|
992
|
+
const PSI2_C1 = BigInt(
|
|
993
|
+
'0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaac'
|
|
994
|
+
);
|
|
927
995
|
|
|
928
996
|
function psi2(x: Fp2, y: Fp2): [Fp2, Fp2] {
|
|
929
997
|
return [Fp2.mul(x, PSI2_C1), Fp2.neg(y)];
|
|
@@ -1000,14 +1068,18 @@ export const bls12_381: CurveFn<Fp, Fp2, Fp6, Fp12> = bls({
|
|
|
1000
1068
|
G1: {
|
|
1001
1069
|
Fp,
|
|
1002
1070
|
// cofactor; (z - 1)²/3
|
|
1003
|
-
h:
|
|
1071
|
+
h: BigInt('0x396c8c005555e1568c00aaab0000aaab'),
|
|
1004
1072
|
// generator's coordinates
|
|
1005
1073
|
// x = 3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507
|
|
1006
1074
|
// y = 1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569
|
|
1007
|
-
Gx:
|
|
1008
|
-
|
|
1075
|
+
Gx: BigInt(
|
|
1076
|
+
'0x17f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb'
|
|
1077
|
+
),
|
|
1078
|
+
Gy: BigInt(
|
|
1079
|
+
'0x08b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1'
|
|
1080
|
+
),
|
|
1009
1081
|
a: Fp.ZERO,
|
|
1010
|
-
b:
|
|
1082
|
+
b: _4n,
|
|
1011
1083
|
htfDefaults: { ...htfDefaults, m: 1 },
|
|
1012
1084
|
wrapPrivateKey: true,
|
|
1013
1085
|
allowInfinityPoint: true,
|
|
@@ -1017,8 +1089,9 @@ export const bls12_381: CurveFn<Fp, Fp2, Fp6, Fp12> = bls({
|
|
|
1017
1089
|
// https://eprint.iacr.org/2021/1130.pdf
|
|
1018
1090
|
isTorsionFree: (c, point): boolean => {
|
|
1019
1091
|
// φ endomorphism
|
|
1020
|
-
const cubicRootOfUnityModP =
|
|
1021
|
-
|
|
1092
|
+
const cubicRootOfUnityModP = BigInt(
|
|
1093
|
+
'0x5f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffe'
|
|
1094
|
+
);
|
|
1022
1095
|
const phi = new c(Fp.mul(point.px, cubicRootOfUnityModP), point.py, point.pz);
|
|
1023
1096
|
|
|
1024
1097
|
// todo: unroll
|
|
@@ -1028,7 +1101,7 @@ export const bls12_381: CurveFn<Fp, Fp2, Fp6, Fp12> = bls({
|
|
|
1028
1101
|
|
|
1029
1102
|
// https://eprint.iacr.org/2019/814.pdf
|
|
1030
1103
|
// (z² − 1)/3
|
|
1031
|
-
// const c1 =
|
|
1104
|
+
// const c1 = BigInt('0x396c8c005555e1560000000055555555');
|
|
1032
1105
|
// const P = this;
|
|
1033
1106
|
// const S = P.sigma();
|
|
1034
1107
|
// const Q = S.double();
|
|
@@ -1054,13 +1127,13 @@ export const bls12_381: CurveFn<Fp, Fp2, Fp6, Fp12> = bls({
|
|
|
1054
1127
|
const compressedValue = bytesToNumberBE(bytes);
|
|
1055
1128
|
const bflag = bitGet(compressedValue, I_BIT_POS);
|
|
1056
1129
|
// Zero
|
|
1057
|
-
if (bflag ===
|
|
1130
|
+
if (bflag === _1n) return { x: _0n, y: _0n };
|
|
1058
1131
|
const x = Fp.create(compressedValue & Fp.MASK);
|
|
1059
|
-
const right = Fp.add(Fp.pow(x,
|
|
1132
|
+
const right = Fp.add(Fp.pow(x, _3n), Fp.create(bls12_381.CURVE.G1.b)); // y² = x³ + b
|
|
1060
1133
|
let y = Fp.sqrt(right);
|
|
1061
1134
|
if (!y) throw new Error('Invalid compressed G1 point');
|
|
1062
1135
|
const aflag = bitGet(compressedValue, C_BIT_POS);
|
|
1063
|
-
if ((y *
|
|
1136
|
+
if ((y * _2n) / P !== aflag) y = Fp.neg(y);
|
|
1064
1137
|
return { x: Fp.create(x), y: Fp.create(y) };
|
|
1065
1138
|
} else if (bytes.length === 96) {
|
|
1066
1139
|
// Check if the infinity flag is set
|
|
@@ -1079,7 +1152,7 @@ export const bls12_381: CurveFn<Fp, Fp2, Fp6, Fp12> = bls({
|
|
|
1079
1152
|
if (isZero) return COMPRESSED_ZERO.slice();
|
|
1080
1153
|
const P = Fp.ORDER;
|
|
1081
1154
|
let num;
|
|
1082
|
-
num = bitSet(x, C_BIT_POS, Boolean((y *
|
|
1155
|
+
num = bitSet(x, C_BIT_POS, Boolean((y * _2n) / P)); // set aflag
|
|
1083
1156
|
num = bitSet(num, S_BIT_POS, true);
|
|
1084
1157
|
return numberToBytesBE(num, Fp.BYTES);
|
|
1085
1158
|
} else {
|
|
@@ -1100,21 +1173,33 @@ export const bls12_381: CurveFn<Fp, Fp2, Fp6, Fp12> = bls({
|
|
|
1100
1173
|
G2: {
|
|
1101
1174
|
Fp: Fp2,
|
|
1102
1175
|
// cofactor
|
|
1103
|
-
h:
|
|
1176
|
+
h: BigInt(
|
|
1177
|
+
'0x5d543a95414e7f1091d50792876a202cd91de4547085abaa68a205b2e5a7ddfa628f1cb4d9e82ef21537e293a6691ae1616ec6e786f0c70cf1c38e31c7238e5'
|
|
1178
|
+
),
|
|
1104
1179
|
Gx: Fp2.fromBigTuple([
|
|
1105
|
-
|
|
1106
|
-
|
|
1180
|
+
BigInt(
|
|
1181
|
+
'0x024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8'
|
|
1182
|
+
),
|
|
1183
|
+
BigInt(
|
|
1184
|
+
'0x13e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e'
|
|
1185
|
+
),
|
|
1107
1186
|
]),
|
|
1108
1187
|
// y =
|
|
1109
1188
|
// 927553665492332455747201965776037880757740193453592970025027978793976877002675564980949289727957565575433344219582,
|
|
1110
1189
|
// 1985150602287291935568054521177171638300868978215655730859378665066344726373823718423869104263333984641494340347905
|
|
1111
1190
|
Gy: Fp2.fromBigTuple([
|
|
1112
|
-
|
|
1113
|
-
|
|
1191
|
+
BigInt(
|
|
1192
|
+
'0x0ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801'
|
|
1193
|
+
),
|
|
1194
|
+
BigInt(
|
|
1195
|
+
'0x0606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be'
|
|
1196
|
+
),
|
|
1114
1197
|
]),
|
|
1115
1198
|
a: Fp2.ZERO,
|
|
1116
|
-
b: Fp2.fromBigTuple([4n,
|
|
1117
|
-
hEff:
|
|
1199
|
+
b: Fp2.fromBigTuple([4n, _4n]),
|
|
1200
|
+
hEff: BigInt(
|
|
1201
|
+
'0xbc69f08f2ee75b3584c6a0ea91b352888e2a8e9145ad7689986ff031508ffe1329c2f178731db956d82bf015d1212b02ec0ec69d7477c1ae954cbc06689f6a359894c0adebbf6b4e8020005aaa95551'
|
|
1202
|
+
),
|
|
1118
1203
|
htfDefaults: { ...htfDefaults },
|
|
1119
1204
|
wrapPrivateKey: true,
|
|
1120
1205
|
allowInfinityPoint: true,
|
|
@@ -1175,9 +1260,9 @@ export const bls12_381: CurveFn<Fp, Fp2, Fp6, Fp12> = bls({
|
|
|
1175
1260
|
const x_1 = slc(bytes, 0, L);
|
|
1176
1261
|
const x_0 = slc(bytes, L, 2 * L);
|
|
1177
1262
|
const x = Fp2.create({ c0: Fp.create(x_0), c1: Fp.create(x_1) });
|
|
1178
|
-
const right = Fp2.add(Fp2.pow(x,
|
|
1263
|
+
const right = Fp2.add(Fp2.pow(x, _3n), b); // y² = x³ + 4 * (u+1) = x³ + b
|
|
1179
1264
|
let y = Fp2.sqrt(right);
|
|
1180
|
-
const Y_bit = y.c1 ===
|
|
1265
|
+
const Y_bit = y.c1 === _0n ? (y.c0 * _2n) / P : (y.c1 * _2n) / P ? _1n : _0n;
|
|
1181
1266
|
y = bitS > 0 && Y_bit > 0 ? y : Fp2.neg(y);
|
|
1182
1267
|
return { x, y };
|
|
1183
1268
|
} else if (bytes.length === 192 && !bitC) {
|
|
@@ -1200,7 +1285,7 @@ export const bls12_381: CurveFn<Fp, Fp2, Fp6, Fp12> = bls({
|
|
|
1200
1285
|
if (isCompressed) {
|
|
1201
1286
|
const P = Fp.ORDER;
|
|
1202
1287
|
if (isZero) return concatB(COMPRESSED_ZERO, numberToBytesBE(0n, Fp.BYTES));
|
|
1203
|
-
const flag = Boolean(y.c1 ===
|
|
1288
|
+
const flag = Boolean(y.c1 === _0n ? (y.c0 * _2n) / P : (y.c1 * _2n) / P);
|
|
1204
1289
|
// set compressed & sign bits (looks like different offsets than for G1/Fp?)
|
|
1205
1290
|
let x_1 = bitSet(x.c1, C_BIT_POS, flag);
|
|
1206
1291
|
x_1 = bitSet(x_1, S_BIT_POS, true);
|
|
@@ -1229,12 +1314,12 @@ export const bls12_381: CurveFn<Fp, Fp2, Fp6, Fp12> = bls({
|
|
|
1229
1314
|
const z2 = bytesToNumberBE(hex.slice(half));
|
|
1230
1315
|
// Indicates the infinity point
|
|
1231
1316
|
const bflag1 = bitGet(z1, I_BIT_POS);
|
|
1232
|
-
if (bflag1 ===
|
|
1317
|
+
if (bflag1 === _1n) return bls12_381.G2.ProjectivePoint.ZERO;
|
|
1233
1318
|
|
|
1234
1319
|
const x1 = Fp.create(z1 & Fp.MASK);
|
|
1235
1320
|
const x2 = Fp.create(z2);
|
|
1236
1321
|
const x = Fp2.create({ c0: x2, c1: x1 });
|
|
1237
|
-
const y2 = Fp2.add(Fp2.pow(x,
|
|
1322
|
+
const y2 = Fp2.add(Fp2.pow(x, _3n), bls12_381.CURVE.G2.b); // y² = x³ + 4
|
|
1238
1323
|
// The slow part
|
|
1239
1324
|
let y = Fp2.sqrt(y2);
|
|
1240
1325
|
if (!y) throw new Error('Failed to find a square root');
|
|
@@ -1243,8 +1328,8 @@ export const bls12_381: CurveFn<Fp, Fp2, Fp6, Fp12> = bls({
|
|
|
1243
1328
|
// If y1 happens to be zero, then use the bit of y0
|
|
1244
1329
|
const { re: y0, im: y1 } = Fp2.reim(y);
|
|
1245
1330
|
const aflag1 = bitGet(z1, 381);
|
|
1246
|
-
const isGreater = y1 >
|
|
1247
|
-
const isZero = y1 ===
|
|
1331
|
+
const isGreater = y1 > _0n && (y1 * _2n) / P !== aflag1;
|
|
1332
|
+
const isZero = y1 === _0n && (y0 * _2n) / P !== aflag1;
|
|
1248
1333
|
if (isGreater || isZero) y = Fp2.neg(y);
|
|
1249
1334
|
const point = bls12_381.G2.ProjectivePoint.fromAffine({ x, y });
|
|
1250
1335
|
point.assertValidity();
|
|
@@ -1258,8 +1343,8 @@ export const bls12_381: CurveFn<Fp, Fp2, Fp6, Fp12> = bls({
|
|
|
1258
1343
|
const a = point.toAffine();
|
|
1259
1344
|
const { re: x0, im: x1 } = Fp2.reim(a.x);
|
|
1260
1345
|
const { re: y0, im: y1 } = Fp2.reim(a.y);
|
|
1261
|
-
const tmp = y1 >
|
|
1262
|
-
const aflag1 = Boolean((tmp / Fp.ORDER) &
|
|
1346
|
+
const tmp = y1 > _0n ? y1 * _2n : y0 * _2n;
|
|
1347
|
+
const aflag1 = Boolean((tmp / Fp.ORDER) & _1n);
|
|
1263
1348
|
const z1 = bitSet(bitSet(x1, 381, aflag1), S_BIT_POS, true);
|
|
1264
1349
|
const z2 = x0;
|
|
1265
1350
|
return concatB(numberToBytesBE(z1, Fp.BYTES), numberToBytesBE(z2, Fp.BYTES));
|