@noble/curves 0.5.1 → 0.6.0

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.
Files changed (60) hide show
  1. package/README.md +49 -8
  2. package/lib/_shortw_utils.d.ts +11 -26
  3. package/lib/abstract/bls.d.ts +51 -35
  4. package/lib/abstract/bls.js +77 -139
  5. package/lib/abstract/{group.d.ts → curve.d.ts} +31 -1
  6. package/lib/abstract/{group.js → curve.js} +39 -2
  7. package/lib/abstract/edwards.d.ts +30 -81
  8. package/lib/abstract/edwards.js +225 -420
  9. package/lib/abstract/hash-to-curve.d.ts +25 -6
  10. package/lib/abstract/hash-to-curve.js +40 -12
  11. package/lib/abstract/modular.d.ts +20 -7
  12. package/lib/abstract/modular.js +80 -51
  13. package/lib/abstract/montgomery.js +3 -4
  14. package/lib/abstract/poseidon.d.ts +29 -0
  15. package/lib/abstract/poseidon.js +115 -0
  16. package/lib/abstract/utils.d.ts +5 -34
  17. package/lib/abstract/utils.js +23 -63
  18. package/lib/abstract/weierstrass.d.ts +56 -79
  19. package/lib/abstract/weierstrass.js +509 -641
  20. package/lib/bls12-381.d.ts +1 -0
  21. package/lib/bls12-381.js +75 -65
  22. package/lib/bn.js +1 -1
  23. package/lib/ed25519.d.ts +7 -5
  24. package/lib/ed25519.js +87 -84
  25. package/lib/ed448.d.ts +3 -0
  26. package/lib/ed448.js +88 -84
  27. package/lib/esm/abstract/bls.js +77 -139
  28. package/lib/esm/abstract/{group.js → curve.js} +37 -1
  29. package/lib/esm/abstract/edwards.js +223 -418
  30. package/lib/esm/abstract/hash-to-curve.js +38 -11
  31. package/lib/esm/abstract/modular.js +77 -50
  32. package/lib/esm/abstract/montgomery.js +4 -7
  33. package/lib/esm/abstract/poseidon.js +109 -0
  34. package/lib/esm/abstract/utils.js +21 -59
  35. package/lib/esm/abstract/weierstrass.js +508 -640
  36. package/lib/esm/bls12-381.js +86 -76
  37. package/lib/esm/bn.js +1 -1
  38. package/lib/esm/ed25519.js +85 -83
  39. package/lib/esm/ed448.js +86 -83
  40. package/lib/esm/jubjub.js +6 -5
  41. package/lib/esm/p256.js +11 -9
  42. package/lib/esm/p384.js +11 -9
  43. package/lib/esm/p521.js +13 -12
  44. package/lib/esm/secp256k1.js +118 -157
  45. package/lib/esm/stark.js +104 -39
  46. package/lib/jubjub.d.ts +3 -2
  47. package/lib/jubjub.js +6 -5
  48. package/lib/p192.d.ts +22 -52
  49. package/lib/p224.d.ts +22 -52
  50. package/lib/p256.d.ts +25 -52
  51. package/lib/p256.js +13 -10
  52. package/lib/p384.d.ts +25 -52
  53. package/lib/p384.js +13 -10
  54. package/lib/p521.d.ts +25 -52
  55. package/lib/p521.js +15 -13
  56. package/lib/secp256k1.d.ts +26 -42
  57. package/lib/secp256k1.js +118 -157
  58. package/lib/stark.d.ts +36 -21
  59. package/lib/stark.js +107 -39
  60. package/package.json +14 -9
package/lib/ed25519.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.RistrettoPoint = exports.x25519 = exports.ed25519ph = exports.ed25519ctx = exports.ed25519 = exports.ED25519_TORSION_SUBGROUP = void 0;
3
+ exports.RistrettoPoint = exports.encodeToCurve = exports.hashToCurve = exports.x25519 = exports.ed25519ph = exports.ed25519ctx = exports.ed25519 = exports.ED25519_TORSION_SUBGROUP = void 0;
4
4
  /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
5
5
  const sha512_1 = require("@noble/hashes/sha512");
6
6
  const utils_1 = require("@noble/hashes/utils");
@@ -8,6 +8,7 @@ const edwards_js_1 = require("./abstract/edwards.js");
8
8
  const montgomery_js_1 = require("./abstract/montgomery.js");
9
9
  const modular_js_1 = require("./abstract/modular.js");
10
10
  const utils_js_1 = require("./abstract/utils.js");
11
+ const htf = require("./abstract/hash-to-curve.js");
11
12
  /**
12
13
  * ed25519 Twisted Edwards curve with following addons:
13
14
  * - X25519 ECDH
@@ -82,57 +83,107 @@ exports.ED25519_TORSION_SUBGROUP = [
82
83
  'c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac03fa',
83
84
  ];
84
85
  const Fp = (0, modular_js_1.Fp)(ED25519_P, undefined, true);
86
+ const ED25519_DEF = {
87
+ // Param: a
88
+ a: BigInt(-1),
89
+ // Equal to -121665/121666 over finite field.
90
+ // Negative number is P - number, and division is invert(number, P)
91
+ d: BigInt('37095705934669439343138083508754565189542113879843219016388785533085940283555'),
92
+ // Finite field 𝔽p over which we'll do calculations; 2n ** 255n - 19n
93
+ Fp,
94
+ // Subgroup order: how many points ed25519 has
95
+ // 2n ** 252n + 27742317777372353535851937790883648493n;
96
+ n: BigInt('7237005577332262213973186563042994240857116359379907606001950938285454250989'),
97
+ // Cofactor
98
+ h: BigInt(8),
99
+ // Base point (x, y) aka generator point
100
+ Gx: BigInt('15112221349535400772501151409588531511454012693041857206046113283949847762202'),
101
+ Gy: BigInt('46316835694926478169428394003475163141307993866256225615783033603165251855960'),
102
+ hash: sha512_1.sha512,
103
+ randomBytes: utils_1.randomBytes,
104
+ adjustScalarBytes,
105
+ // dom2
106
+ // Ratio of u to v. Allows us to combine inversion and square root. Uses algo from RFC8032 5.1.3.
107
+ // Constant-time, u/√v
108
+ uvRatio,
109
+ };
110
+ exports.ed25519 = (0, edwards_js_1.twistedEdwards)(ED25519_DEF);
111
+ function ed25519_domain(data, ctx, phflag) {
112
+ if (ctx.length > 255)
113
+ throw new Error('Context is too big');
114
+ return (0, utils_1.concatBytes)((0, utils_1.utf8ToBytes)('SigEd25519 no Ed25519 collisions'), new Uint8Array([phflag ? 1 : 0, ctx.length]), ctx, data);
115
+ }
116
+ exports.ed25519ctx = (0, edwards_js_1.twistedEdwards)({ ...ED25519_DEF, domain: ed25519_domain });
117
+ exports.ed25519ph = (0, edwards_js_1.twistedEdwards)({
118
+ ...ED25519_DEF,
119
+ domain: ed25519_domain,
120
+ preHash: sha512_1.sha512,
121
+ });
122
+ exports.x25519 = (0, montgomery_js_1.montgomery)({
123
+ P: ED25519_P,
124
+ a24: BigInt('121665'),
125
+ montgomeryBits: 255,
126
+ nByteLength: 32,
127
+ Gu: '0900000000000000000000000000000000000000000000000000000000000000',
128
+ powPminus2: (x) => {
129
+ const P = ED25519_P;
130
+ // x^(p-2) aka x^(2^255-21)
131
+ const { pow_p_5_8, b2 } = ed25519_pow_2_252_3(x);
132
+ return (0, modular_js_1.mod)((0, modular_js_1.pow2)(pow_p_5_8, BigInt(3), P) * b2, P);
133
+ },
134
+ adjustScalarBytes,
135
+ });
85
136
  // Hash To Curve Elligator2 Map (NOTE: different from ristretto255 elligator)
86
137
  // NOTE: very important part is usage of FpSqrtEven for ELL2_C1_EDWARDS, since
87
138
  // SageMath returns different root first and everything falls apart
88
139
  const ELL2_C1 = (Fp.ORDER + BigInt(3)) / BigInt(8); // 1. c1 = (q + 3) / 8 # Integer arithmetic
89
140
  const ELL2_C2 = Fp.pow(_2n, ELL2_C1); // 2. c2 = 2^c1
90
- const ELL2_C3 = Fp.sqrt(Fp.negate(Fp.ONE)); // 3. c3 = sqrt(-1)
141
+ const ELL2_C3 = Fp.sqrt(Fp.neg(Fp.ONE)); // 3. c3 = sqrt(-1)
91
142
  const ELL2_C4 = (Fp.ORDER - BigInt(5)) / BigInt(8); // 4. c4 = (q - 5) / 8 # Integer arithmetic
92
143
  const ELL2_J = BigInt(486662);
93
144
  // prettier-ignore
94
145
  function map_to_curve_elligator2_curve25519(u) {
95
- let tv1 = Fp.square(u); // 1. tv1 = u^2
146
+ let tv1 = Fp.sqr(u); // 1. tv1 = u^2
96
147
  tv1 = Fp.mul(tv1, _2n); // 2. tv1 = 2 * tv1
97
148
  let xd = Fp.add(tv1, Fp.ONE); // 3. xd = tv1 + 1 # Nonzero: -1 is square (mod p), tv1 is not
98
- let x1n = Fp.negate(ELL2_J); // 4. x1n = -J # x1 = x1n / xd = -J / (1 + 2 * u^2)
99
- let tv2 = Fp.square(xd); // 5. tv2 = xd^2
149
+ let x1n = Fp.neg(ELL2_J); // 4. x1n = -J # x1 = x1n / xd = -J / (1 + 2 * u^2)
150
+ let tv2 = Fp.sqr(xd); // 5. tv2 = xd^2
100
151
  let gxd = Fp.mul(tv2, xd); // 6. gxd = tv2 * xd # gxd = xd^3
101
152
  let gx1 = Fp.mul(tv1, ELL2_J); // 7. gx1 = J * tv1 # x1n + J * xd
102
153
  gx1 = Fp.mul(gx1, x1n); // 8. gx1 = gx1 * x1n # x1n^2 + J * x1n * xd
103
154
  gx1 = Fp.add(gx1, tv2); // 9. gx1 = gx1 + tv2 # x1n^2 + J * x1n * xd + xd^2
104
155
  gx1 = Fp.mul(gx1, x1n); // 10. gx1 = gx1 * x1n # x1n^3 + J * x1n^2 * xd + x1n * xd^2
105
- let tv3 = Fp.square(gxd); // 11. tv3 = gxd^2
106
- tv2 = Fp.square(tv3); // 12. tv2 = tv3^2 # gxd^4
156
+ let tv3 = Fp.sqr(gxd); // 11. tv3 = gxd^2
157
+ tv2 = Fp.sqr(tv3); // 12. tv2 = tv3^2 # gxd^4
107
158
  tv3 = Fp.mul(tv3, gxd); // 13. tv3 = tv3 * gxd # gxd^3
108
159
  tv3 = Fp.mul(tv3, gx1); // 14. tv3 = tv3 * gx1 # gx1 * gxd^3
109
160
  tv2 = Fp.mul(tv2, tv3); // 15. tv2 = tv2 * tv3 # gx1 * gxd^7
110
161
  let y11 = Fp.pow(tv2, ELL2_C4); // 16. y11 = tv2^c4 # (gx1 * gxd^7)^((p - 5) / 8)
111
162
  y11 = Fp.mul(y11, tv3); // 17. y11 = y11 * tv3 # gx1*gxd^3*(gx1*gxd^7)^((p-5)/8)
112
163
  let y12 = Fp.mul(y11, ELL2_C3); // 18. y12 = y11 * c3
113
- tv2 = Fp.square(y11); // 19. tv2 = y11^2
164
+ tv2 = Fp.sqr(y11); // 19. tv2 = y11^2
114
165
  tv2 = Fp.mul(tv2, gxd); // 20. tv2 = tv2 * gxd
115
- let e1 = Fp.equals(tv2, gx1); // 21. e1 = tv2 == gx1
166
+ let e1 = Fp.eql(tv2, gx1); // 21. e1 = tv2 == gx1
116
167
  let y1 = Fp.cmov(y12, y11, e1); // 22. y1 = CMOV(y12, y11, e1) # If g(x1) is square, this is its sqrt
117
168
  let x2n = Fp.mul(x1n, tv1); // 23. x2n = x1n * tv1 # x2 = x2n / xd = 2 * u^2 * x1n / xd
118
169
  let y21 = Fp.mul(y11, u); // 24. y21 = y11 * u
119
170
  y21 = Fp.mul(y21, ELL2_C2); // 25. y21 = y21 * c2
120
171
  let y22 = Fp.mul(y21, ELL2_C3); // 26. y22 = y21 * c3
121
172
  let gx2 = Fp.mul(gx1, tv1); // 27. gx2 = gx1 * tv1 # g(x2) = gx2 / gxd = 2 * u^2 * g(x1)
122
- tv2 = Fp.square(y21); // 28. tv2 = y21^2
173
+ tv2 = Fp.sqr(y21); // 28. tv2 = y21^2
123
174
  tv2 = Fp.mul(tv2, gxd); // 29. tv2 = tv2 * gxd
124
- let e2 = Fp.equals(tv2, gx2); // 30. e2 = tv2 == gx2
175
+ let e2 = Fp.eql(tv2, gx2); // 30. e2 = tv2 == gx2
125
176
  let y2 = Fp.cmov(y22, y21, e2); // 31. y2 = CMOV(y22, y21, e2) # If g(x2) is square, this is its sqrt
126
- tv2 = Fp.square(y1); // 32. tv2 = y1^2
177
+ tv2 = Fp.sqr(y1); // 32. tv2 = y1^2
127
178
  tv2 = Fp.mul(tv2, gxd); // 33. tv2 = tv2 * gxd
128
- let e3 = Fp.equals(tv2, gx1); // 34. e3 = tv2 == gx1
179
+ let e3 = Fp.eql(tv2, gx1); // 34. e3 = tv2 == gx1
129
180
  let xn = Fp.cmov(x2n, x1n, e3); // 35. xn = CMOV(x2n, x1n, e3) # If e3, x = x1, else x = x2
130
181
  let y = Fp.cmov(y2, y1, e3); // 36. y = CMOV(y2, y1, e3) # If e3, y = y1, else y = y2
131
182
  let e4 = Fp.isOdd(y); // 37. e4 = sgn0(y) == 1 # Fix sign of y
132
- y = Fp.cmov(y, Fp.negate(y), e3 !== e4); // 38. y = CMOV(y, -y, e3 XOR e4)
183
+ y = Fp.cmov(y, Fp.neg(y), e3 !== e4); // 38. y = CMOV(y, -y, e3 XOR e4)
133
184
  return { xMn: xn, xMd: xd, yMn: y, yMd: 1n }; // 39. return (xn, xd, y, 1)
134
185
  }
135
- const ELL2_C1_EDWARDS = (0, modular_js_1.FpSqrtEven)(Fp, Fp.negate(BigInt(486664))); // sgn0(c1) MUST equal 0
186
+ const ELL2_C1_EDWARDS = (0, modular_js_1.FpSqrtEven)(Fp, Fp.neg(BigInt(486664))); // sgn0(c1) MUST equal 0
136
187
  function map_to_curve_elligator2_edwards25519(u) {
137
188
  const { xMn, xMd, yMn, yMd } = map_to_curve_elligator2_curve25519(u); // 1. (xMn, xMd, yMn, yMd) = map_to_curve_elligator2_curve25519(u)
138
189
  let xn = Fp.mul(xMn, yMd); // 2. xn = xMn * yMd
@@ -141,7 +192,7 @@ function map_to_curve_elligator2_edwards25519(u) {
141
192
  let yn = Fp.sub(xMn, xMd); // 5. yn = xMn - xMd
142
193
  let yd = Fp.add(xMn, xMd); // 6. yd = xMn + xMd # (n / d - 1) / (n / d + 1) = (n - d) / (n + d)
143
194
  let tv1 = Fp.mul(xd, yd); // 7. tv1 = xd * yd
144
- let e = Fp.equals(tv1, Fp.ZERO); // 8. e = tv1 == 0
195
+ let e = Fp.eql(tv1, Fp.ZERO); // 8. e = tv1 == 0
145
196
  xn = Fp.cmov(xn, Fp.ZERO, e); // 9. xn = CMOV(xn, 0, e)
146
197
  xd = Fp.cmov(xd, Fp.ONE, e); // 10. xd = CMOV(xd, 1, e)
147
198
  yn = Fp.cmov(yn, Fp.ONE, e); // 11. yn = CMOV(yn, 1, e)
@@ -149,68 +200,20 @@ function map_to_curve_elligator2_edwards25519(u) {
149
200
  const inv = Fp.invertBatch([xd, yd]); // batch division
150
201
  return { x: Fp.mul(xn, inv[0]), y: Fp.mul(yn, inv[1]) }; // 13. return (xn, xd, yn, yd)
151
202
  }
152
- const ED25519_DEF = {
153
- // Param: a
154
- a: BigInt(-1),
155
- // Equal to -121665/121666 over finite field.
156
- // Negative number is P - number, and division is invert(number, P)
157
- d: BigInt('37095705934669439343138083508754565189542113879843219016388785533085940283555'),
158
- // Finite field 𝔽p over which we'll do calculations; 2n ** 255n - 19n
159
- Fp,
160
- // Subgroup order: how many points ed25519 has
161
- // 2n ** 252n + 27742317777372353535851937790883648493n;
162
- n: BigInt('7237005577332262213973186563042994240857116359379907606001950938285454250989'),
163
- // Cofactor
164
- h: BigInt(8),
165
- // Base point (x, y) aka generator point
166
- Gx: BigInt('15112221349535400772501151409588531511454012693041857206046113283949847762202'),
167
- Gy: BigInt('46316835694926478169428394003475163141307993866256225615783033603165251855960'),
203
+ const { hashToCurve, encodeToCurve } = htf.hashToCurve(exports.ed25519.ExtendedPoint, (scalars) => map_to_curve_elligator2_edwards25519(scalars[0]), {
204
+ DST: 'edwards25519_XMD:SHA-512_ELL2_RO_',
205
+ encodeDST: 'edwards25519_XMD:SHA-512_ELL2_NU_',
206
+ p: Fp.ORDER,
207
+ m: 1,
208
+ k: 128,
209
+ expand: 'xmd',
168
210
  hash: sha512_1.sha512,
169
- randomBytes: utils_1.randomBytes,
170
- adjustScalarBytes,
171
- // dom2
172
- // Ratio of u to v. Allows us to combine inversion and square root. Uses algo from RFC8032 5.1.3.
173
- // Constant-time, u/√v
174
- uvRatio,
175
- htfDefaults: {
176
- DST: 'edwards25519_XMD:SHA-512_ELL2_RO_',
177
- p: Fp.ORDER,
178
- m: 1,
179
- k: 128,
180
- expand: 'xmd',
181
- hash: sha512_1.sha512,
182
- },
183
- mapToCurve: (scalars) => map_to_curve_elligator2_edwards25519(scalars[0]),
184
- };
185
- exports.ed25519 = (0, edwards_js_1.twistedEdwards)(ED25519_DEF);
186
- function ed25519_domain(data, ctx, phflag) {
187
- if (ctx.length > 255)
188
- throw new Error('Context is too big');
189
- return (0, utils_1.concatBytes)((0, utils_1.utf8ToBytes)('SigEd25519 no Ed25519 collisions'), new Uint8Array([phflag ? 1 : 0, ctx.length]), ctx, data);
190
- }
191
- exports.ed25519ctx = (0, edwards_js_1.twistedEdwards)({ ...ED25519_DEF, domain: ed25519_domain });
192
- exports.ed25519ph = (0, edwards_js_1.twistedEdwards)({
193
- ...ED25519_DEF,
194
- domain: ed25519_domain,
195
- preHash: sha512_1.sha512,
196
- });
197
- exports.x25519 = (0, montgomery_js_1.montgomery)({
198
- P: ED25519_P,
199
- a24: BigInt('121665'),
200
- montgomeryBits: 255,
201
- nByteLength: 32,
202
- Gu: '0900000000000000000000000000000000000000000000000000000000000000',
203
- powPminus2: (x) => {
204
- const P = ED25519_P;
205
- // x^(p-2) aka x^(2^255-21)
206
- const { pow_p_5_8, b2 } = ed25519_pow_2_252_3(x);
207
- return (0, modular_js_1.mod)((0, modular_js_1.pow2)(pow_p_5_8, BigInt(3), P) * b2, P);
208
- },
209
- adjustScalarBytes,
210
211
  });
212
+ exports.hashToCurve = hashToCurve;
213
+ exports.encodeToCurve = encodeToCurve;
211
214
  function assertRstPoint(other) {
212
215
  if (!(other instanceof RistrettoPoint))
213
- throw new TypeError('RistrettoPoint expected');
216
+ throw new Error('RistrettoPoint expected');
214
217
  }
215
218
  // √(-1) aka √(a) aka 2^((p-1)/4)
216
219
  const SQRT_M1 = BigInt('19681161376707505956807079304988542015446066515923890162744021073123829784752');
@@ -225,13 +228,13 @@ const D_MINUS_ONE_SQ = BigInt('4044083434630853685810104246932319082624839914623
225
228
  // Calculates 1/√(number)
226
229
  const invertSqrt = (number) => uvRatio(_1n, number);
227
230
  const MAX_255B = BigInt('0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff');
228
- const bytes255ToNumberLE = (bytes) => exports.ed25519.utils.mod((0, utils_js_1.bytesToNumberLE)(bytes) & MAX_255B);
231
+ const bytes255ToNumberLE = (bytes) => exports.ed25519.CURVE.Fp.create((0, utils_js_1.bytesToNumberLE)(bytes) & MAX_255B);
229
232
  // Computes Elligator map for Ristretto
230
233
  // https://ristretto.group/formulas/elligator.html
231
234
  function calcElligatorRistrettoMap(r0) {
232
235
  const { d } = exports.ed25519.CURVE;
233
236
  const P = exports.ed25519.CURVE.Fp.ORDER;
234
- const { mod } = exports.ed25519.utils;
237
+ const mod = exports.ed25519.CURVE.Fp.create;
235
238
  const r = mod(SQRT_M1 * r0 * r0); // 1
236
239
  const Ns = mod((r + _1n) * ONE_MINUS_D_SQ); // 2
237
240
  let c = BigInt(-1); // 3
@@ -289,7 +292,7 @@ class RistrettoPoint {
289
292
  hex = (0, utils_js_1.ensureBytes)(hex, 32);
290
293
  const { a, d } = exports.ed25519.CURVE;
291
294
  const P = exports.ed25519.CURVE.Fp.ORDER;
292
- const { mod } = exports.ed25519.utils;
295
+ const mod = exports.ed25519.CURVE.Fp.create;
293
296
  const emsg = 'RistrettoPoint.fromHex: the hex is not valid encoding of RistrettoPoint';
294
297
  const s = bytes255ToNumberLE(hex);
295
298
  // 1. Check that s_bytes is the canonical encoding of a field element, or else abort.
@@ -319,9 +322,9 @@ class RistrettoPoint {
319
322
  * https://ristretto.group/formulas/encoding.html
320
323
  */
321
324
  toRawBytes() {
322
- let { x, y, z, t } = this.ep;
325
+ let { ex: x, ey: y, ez: z, et: t } = this.ep;
323
326
  const P = exports.ed25519.CURVE.Fp.ORDER;
324
- const { mod } = exports.ed25519.utils;
327
+ const mod = exports.ed25519.CURVE.Fp.create;
325
328
  const u1 = mod(mod(z + y) * mod(z - y)); // 1
326
329
  const u2 = mod(x * y); // 2
327
330
  // Square root always exists
@@ -357,12 +360,12 @@ class RistrettoPoint {
357
360
  // Compare one point to another.
358
361
  equals(other) {
359
362
  assertRstPoint(other);
360
- const a = this.ep;
361
- const b = other.ep;
362
- const { mod } = exports.ed25519.utils;
363
+ const { ex: X1, ey: Y1 } = this.ep;
364
+ const { ex: X2, ey: Y2 } = this.ep;
365
+ const mod = exports.ed25519.CURVE.Fp.create;
363
366
  // (x1 * y2 == y1 * x2) | (y1 * y2 == x1 * x2)
364
- const one = mod(a.x * b.y) === mod(a.y * b.x);
365
- const two = mod(a.y * b.y) === mod(a.x * b.x);
367
+ const one = mod(X1 * Y2) === mod(Y1 * X2);
368
+ const two = mod(Y1 * Y2) === mod(X1 * X2);
366
369
  return one || two;
367
370
  }
368
371
  add(other) {
package/lib/ed448.d.ts CHANGED
@@ -1,3 +1,6 @@
1
+ import * as htf from './abstract/hash-to-curve.js';
1
2
  export declare const ed448: import("./abstract/edwards.js").CurveFn;
2
3
  export declare const ed448ph: import("./abstract/edwards.js").CurveFn;
3
4
  export declare const x448: import("./abstract/montgomery.js").CurveFn;
5
+ declare const hashToCurve: (msg: import("./abstract/utils.js").Hex, options?: htf.htfBasicOpts | undefined) => htf.H2CPoint<bigint>, encodeToCurve: (msg: import("./abstract/utils.js").Hex, options?: htf.htfBasicOpts | undefined) => htf.H2CPoint<bigint>;
6
+ export { hashToCurve, encodeToCurve };
package/lib/ed448.js CHANGED
@@ -1,12 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.x448 = exports.ed448ph = exports.ed448 = void 0;
3
+ exports.encodeToCurve = exports.hashToCurve = exports.x448 = exports.ed448ph = exports.ed448 = void 0;
4
4
  /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
5
5
  const sha3_1 = require("@noble/hashes/sha3");
6
6
  const utils_1 = require("@noble/hashes/utils");
7
7
  const edwards_js_1 = require("./abstract/edwards.js");
8
8
  const modular_js_1 = require("./abstract/modular.js");
9
9
  const montgomery_js_1 = require("./abstract/montgomery.js");
10
+ const htf = require("./abstract/hash-to-curve.js");
10
11
  /**
11
12
  * Edwards448 (not Ed448-Goldilocks) curve with following addons:
12
13
  * * X448 ECDH
@@ -49,79 +50,6 @@ function adjustScalarBytes(bytes) {
49
50
  return bytes;
50
51
  }
51
52
  const Fp = (0, modular_js_1.Fp)(ed448P, 456, true);
52
- // Hash To Curve Elligator2 Map
53
- const ELL2_C1 = (Fp.ORDER - BigInt(3)) / BigInt(4); // 1. c1 = (q - 3) / 4 # Integer arithmetic
54
- const ELL2_J = BigInt(156326);
55
- function map_to_curve_elligator2_curve448(u) {
56
- let tv1 = Fp.square(u); // 1. tv1 = u^2
57
- let e1 = Fp.equals(tv1, Fp.ONE); // 2. e1 = tv1 == 1
58
- tv1 = Fp.cmov(tv1, Fp.ZERO, e1); // 3. tv1 = CMOV(tv1, 0, e1) # If Z * u^2 == -1, set tv1 = 0
59
- let xd = Fp.sub(Fp.ONE, tv1); // 4. xd = 1 - tv1
60
- let x1n = Fp.negate(ELL2_J); // 5. x1n = -J
61
- let tv2 = Fp.square(xd); // 6. tv2 = xd^2
62
- let gxd = Fp.mul(tv2, xd); // 7. gxd = tv2 * xd # gxd = xd^3
63
- let gx1 = Fp.mul(tv1, Fp.negate(ELL2_J)); // 8. gx1 = -J * tv1 # x1n + J * xd
64
- gx1 = Fp.mul(gx1, x1n); // 9. gx1 = gx1 * x1n # x1n^2 + J * x1n * xd
65
- gx1 = Fp.add(gx1, tv2); // 10. gx1 = gx1 + tv2 # x1n^2 + J * x1n * xd + xd^2
66
- gx1 = Fp.mul(gx1, x1n); // 11. gx1 = gx1 * x1n # x1n^3 + J * x1n^2 * xd + x1n * xd^2
67
- let tv3 = Fp.square(gxd); // 12. tv3 = gxd^2
68
- tv2 = Fp.mul(gx1, gxd); // 13. tv2 = gx1 * gxd # gx1 * gxd
69
- tv3 = Fp.mul(tv3, tv2); // 14. tv3 = tv3 * tv2 # gx1 * gxd^3
70
- let y1 = Fp.pow(tv3, ELL2_C1); // 15. y1 = tv3^c1 # (gx1 * gxd^3)^((p - 3) / 4)
71
- y1 = Fp.mul(y1, tv2); // 16. y1 = y1 * tv2 # gx1 * gxd * (gx1 * gxd^3)^((p - 3) / 4)
72
- let x2n = Fp.mul(x1n, Fp.negate(tv1)); // 17. x2n = -tv1 * x1n # x2 = x2n / xd = -1 * u^2 * x1n / xd
73
- let y2 = Fp.mul(y1, u); // 18. y2 = y1 * u
74
- y2 = Fp.cmov(y2, Fp.ZERO, e1); // 19. y2 = CMOV(y2, 0, e1)
75
- tv2 = Fp.square(y1); // 20. tv2 = y1^2
76
- tv2 = Fp.mul(tv2, gxd); // 21. tv2 = tv2 * gxd
77
- let e2 = Fp.equals(tv2, gx1); // 22. e2 = tv2 == gx1
78
- let xn = Fp.cmov(x2n, x1n, e2); // 23. xn = CMOV(x2n, x1n, e2) # If e2, x = x1, else x = x2
79
- let y = Fp.cmov(y2, y1, e2); // 24. y = CMOV(y2, y1, e2) # If e2, y = y1, else y = y2
80
- let e3 = Fp.isOdd(y); // 25. e3 = sgn0(y) == 1 # Fix sign of y
81
- y = Fp.cmov(y, Fp.negate(y), e2 !== e3); // 26. y = CMOV(y, -y, e2 XOR e3)
82
- return { xn, xd, yn: y, yd: Fp.ONE }; // 27. return (xn, xd, y, 1)
83
- }
84
- function map_to_curve_elligator2_edwards448(u) {
85
- let { xn, xd, yn, yd } = map_to_curve_elligator2_curve448(u); // 1. (xn, xd, yn, yd) = map_to_curve_elligator2_curve448(u)
86
- let xn2 = Fp.square(xn); // 2. xn2 = xn^2
87
- let xd2 = Fp.square(xd); // 3. xd2 = xd^2
88
- let xd4 = Fp.square(xd2); // 4. xd4 = xd2^2
89
- let yn2 = Fp.square(yn); // 5. yn2 = yn^2
90
- let yd2 = Fp.square(yd); // 6. yd2 = yd^2
91
- let xEn = Fp.sub(xn2, xd2); // 7. xEn = xn2 - xd2
92
- let tv2 = Fp.sub(xEn, xd2); // 8. tv2 = xEn - xd2
93
- xEn = Fp.mul(xEn, xd2); // 9. xEn = xEn * xd2
94
- xEn = Fp.mul(xEn, yd); // 10. xEn = xEn * yd
95
- xEn = Fp.mul(xEn, yn); // 11. xEn = xEn * yn
96
- xEn = Fp.mul(xEn, 4n); // 12. xEn = xEn * 4
97
- tv2 = Fp.mul(tv2, xn2); // 13. tv2 = tv2 * xn2
98
- tv2 = Fp.mul(tv2, yd2); // 14. tv2 = tv2 * yd2
99
- let tv3 = Fp.mul(yn2, 4n); // 15. tv3 = 4 * yn2
100
- let tv1 = Fp.add(tv3, yd2); // 16. tv1 = tv3 + yd2
101
- tv1 = Fp.mul(tv1, xd4); // 17. tv1 = tv1 * xd4
102
- let xEd = Fp.add(tv1, tv2); // 18. xEd = tv1 + tv2
103
- tv2 = Fp.mul(tv2, xn); // 19. tv2 = tv2 * xn
104
- let tv4 = Fp.mul(xn, xd4); // 20. tv4 = xn * xd4
105
- let yEn = Fp.sub(tv3, yd2); // 21. yEn = tv3 - yd2
106
- yEn = Fp.mul(yEn, tv4); // 22. yEn = yEn * tv4
107
- yEn = Fp.sub(yEn, tv2); // 23. yEn = yEn - tv2
108
- tv1 = Fp.add(xn2, xd2); // 24. tv1 = xn2 + xd2
109
- tv1 = Fp.mul(tv1, xd2); // 25. tv1 = tv1 * xd2
110
- tv1 = Fp.mul(tv1, xd); // 26. tv1 = tv1 * xd
111
- tv1 = Fp.mul(tv1, yn2); // 27. tv1 = tv1 * yn2
112
- tv1 = Fp.mul(tv1, BigInt(-2)); // 28. tv1 = -2 * tv1
113
- let yEd = Fp.add(tv2, tv1); // 29. yEd = tv2 + tv1
114
- tv4 = Fp.mul(tv4, yd2); // 30. tv4 = tv4 * yd2
115
- yEd = Fp.add(yEd, tv4); // 31. yEd = yEd + tv4
116
- tv1 = Fp.mul(xEd, yEd); // 32. tv1 = xEd * yEd
117
- let e = Fp.equals(tv1, Fp.ZERO); // 33. e = tv1 == 0
118
- xEn = Fp.cmov(xEn, Fp.ZERO, e); // 34. xEn = CMOV(xEn, 0, e)
119
- xEd = Fp.cmov(xEd, Fp.ONE, e); // 35. xEd = CMOV(xEd, 1, e)
120
- yEn = Fp.cmov(yEn, Fp.ONE, e); // 36. yEn = CMOV(yEn, 1, e)
121
- yEd = Fp.cmov(yEd, Fp.ONE, e); // 37. yEd = CMOV(yEd, 1, e)
122
- const inv = Fp.invertBatch([xEd, yEd]); // batch division
123
- return { x: Fp.mul(xEn, inv[0]), y: Fp.mul(yEn, inv[1]) }; // 38. return (xEn, xEd, yEn, yEd)
124
- }
125
53
  const ED448_DEF = {
126
54
  // Param: a
127
55
  a: BigInt(1),
@@ -129,7 +57,8 @@ const ED448_DEF = {
129
57
  d: BigInt('726838724295606890549323807888004534353641360687318060281490199180612328166730772686396383698676545930088884461843637361053498018326358'),
130
58
  // Finite field 𝔽p over which we'll do calculations; 2n ** 448n - 2n ** 224n - 1n
131
59
  Fp,
132
- // Subgroup order: how many points ed448 has; 2n**446n - 13818066809895115352007386748515426880336692474882178609894547503885n
60
+ // Subgroup order: how many points curve has;
61
+ // 2n**446n - 13818066809895115352007386748515426880336692474882178609894547503885n
133
62
  n: BigInt('181709681073901722637330951972001133588410340171829515070372549795146003961539585716195755291692375963310293709091662304773755859649779'),
134
63
  nBitLength: 456,
135
64
  // Cofactor
@@ -168,15 +97,6 @@ const ED448_DEF = {
168
97
  // square root exists, and the decoding fails.
169
98
  return { isValid: (0, modular_js_1.mod)(x2 * v, P) === u, value: x };
170
99
  },
171
- htfDefaults: {
172
- DST: 'edwards448_XOF:SHAKE256_ELL2_RO_',
173
- p: Fp.ORDER,
174
- m: 1,
175
- k: 224,
176
- expand: 'xof',
177
- hash: sha3_1.shake256,
178
- },
179
- mapToCurve: (scalars) => map_to_curve_elligator2_edwards448(scalars[0]),
180
100
  };
181
101
  exports.ed448 = (0, edwards_js_1.twistedEdwards)(ED448_DEF);
182
102
  // NOTE: there is no ed448ctx, since ed448 supports ctx by default
@@ -209,3 +129,87 @@ exports.x448 = (0, montgomery_js_1.montgomery)({
209
129
  // return numberToBytesLE(u, 56);
210
130
  // },
211
131
  });
132
+ // Hash To Curve Elligator2 Map
133
+ const ELL2_C1 = (Fp.ORDER - BigInt(3)) / BigInt(4); // 1. c1 = (q - 3) / 4 # Integer arithmetic
134
+ const ELL2_J = BigInt(156326);
135
+ function map_to_curve_elligator2_curve448(u) {
136
+ let tv1 = Fp.sqr(u); // 1. tv1 = u^2
137
+ let e1 = Fp.eql(tv1, Fp.ONE); // 2. e1 = tv1 == 1
138
+ tv1 = Fp.cmov(tv1, Fp.ZERO, e1); // 3. tv1 = CMOV(tv1, 0, e1) # If Z * u^2 == -1, set tv1 = 0
139
+ let xd = Fp.sub(Fp.ONE, tv1); // 4. xd = 1 - tv1
140
+ let x1n = Fp.neg(ELL2_J); // 5. x1n = -J
141
+ let tv2 = Fp.sqr(xd); // 6. tv2 = xd^2
142
+ let gxd = Fp.mul(tv2, xd); // 7. gxd = tv2 * xd # gxd = xd^3
143
+ let gx1 = Fp.mul(tv1, Fp.neg(ELL2_J)); // 8. gx1 = -J * tv1 # x1n + J * xd
144
+ gx1 = Fp.mul(gx1, x1n); // 9. gx1 = gx1 * x1n # x1n^2 + J * x1n * xd
145
+ gx1 = Fp.add(gx1, tv2); // 10. gx1 = gx1 + tv2 # x1n^2 + J * x1n * xd + xd^2
146
+ gx1 = Fp.mul(gx1, x1n); // 11. gx1 = gx1 * x1n # x1n^3 + J * x1n^2 * xd + x1n * xd^2
147
+ let tv3 = Fp.sqr(gxd); // 12. tv3 = gxd^2
148
+ tv2 = Fp.mul(gx1, gxd); // 13. tv2 = gx1 * gxd # gx1 * gxd
149
+ tv3 = Fp.mul(tv3, tv2); // 14. tv3 = tv3 * tv2 # gx1 * gxd^3
150
+ let y1 = Fp.pow(tv3, ELL2_C1); // 15. y1 = tv3^c1 # (gx1 * gxd^3)^((p - 3) / 4)
151
+ y1 = Fp.mul(y1, tv2); // 16. y1 = y1 * tv2 # gx1 * gxd * (gx1 * gxd^3)^((p - 3) / 4)
152
+ let x2n = Fp.mul(x1n, Fp.neg(tv1)); // 17. x2n = -tv1 * x1n # x2 = x2n / xd = -1 * u^2 * x1n / xd
153
+ let y2 = Fp.mul(y1, u); // 18. y2 = y1 * u
154
+ y2 = Fp.cmov(y2, Fp.ZERO, e1); // 19. y2 = CMOV(y2, 0, e1)
155
+ tv2 = Fp.sqr(y1); // 20. tv2 = y1^2
156
+ tv2 = Fp.mul(tv2, gxd); // 21. tv2 = tv2 * gxd
157
+ let e2 = Fp.eql(tv2, gx1); // 22. e2 = tv2 == gx1
158
+ let xn = Fp.cmov(x2n, x1n, e2); // 23. xn = CMOV(x2n, x1n, e2) # If e2, x = x1, else x = x2
159
+ let y = Fp.cmov(y2, y1, e2); // 24. y = CMOV(y2, y1, e2) # If e2, y = y1, else y = y2
160
+ let e3 = Fp.isOdd(y); // 25. e3 = sgn0(y) == 1 # Fix sign of y
161
+ y = Fp.cmov(y, Fp.neg(y), e2 !== e3); // 26. y = CMOV(y, -y, e2 XOR e3)
162
+ return { xn, xd, yn: y, yd: Fp.ONE }; // 27. return (xn, xd, y, 1)
163
+ }
164
+ function map_to_curve_elligator2_edwards448(u) {
165
+ let { xn, xd, yn, yd } = map_to_curve_elligator2_curve448(u); // 1. (xn, xd, yn, yd) = map_to_curve_elligator2_curve448(u)
166
+ let xn2 = Fp.sqr(xn); // 2. xn2 = xn^2
167
+ let xd2 = Fp.sqr(xd); // 3. xd2 = xd^2
168
+ let xd4 = Fp.sqr(xd2); // 4. xd4 = xd2^2
169
+ let yn2 = Fp.sqr(yn); // 5. yn2 = yn^2
170
+ let yd2 = Fp.sqr(yd); // 6. yd2 = yd^2
171
+ let xEn = Fp.sub(xn2, xd2); // 7. xEn = xn2 - xd2
172
+ let tv2 = Fp.sub(xEn, xd2); // 8. tv2 = xEn - xd2
173
+ xEn = Fp.mul(xEn, xd2); // 9. xEn = xEn * xd2
174
+ xEn = Fp.mul(xEn, yd); // 10. xEn = xEn * yd
175
+ xEn = Fp.mul(xEn, yn); // 11. xEn = xEn * yn
176
+ xEn = Fp.mul(xEn, 4n); // 12. xEn = xEn * 4
177
+ tv2 = Fp.mul(tv2, xn2); // 13. tv2 = tv2 * xn2
178
+ tv2 = Fp.mul(tv2, yd2); // 14. tv2 = tv2 * yd2
179
+ let tv3 = Fp.mul(yn2, 4n); // 15. tv3 = 4 * yn2
180
+ let tv1 = Fp.add(tv3, yd2); // 16. tv1 = tv3 + yd2
181
+ tv1 = Fp.mul(tv1, xd4); // 17. tv1 = tv1 * xd4
182
+ let xEd = Fp.add(tv1, tv2); // 18. xEd = tv1 + tv2
183
+ tv2 = Fp.mul(tv2, xn); // 19. tv2 = tv2 * xn
184
+ let tv4 = Fp.mul(xn, xd4); // 20. tv4 = xn * xd4
185
+ let yEn = Fp.sub(tv3, yd2); // 21. yEn = tv3 - yd2
186
+ yEn = Fp.mul(yEn, tv4); // 22. yEn = yEn * tv4
187
+ yEn = Fp.sub(yEn, tv2); // 23. yEn = yEn - tv2
188
+ tv1 = Fp.add(xn2, xd2); // 24. tv1 = xn2 + xd2
189
+ tv1 = Fp.mul(tv1, xd2); // 25. tv1 = tv1 * xd2
190
+ tv1 = Fp.mul(tv1, xd); // 26. tv1 = tv1 * xd
191
+ tv1 = Fp.mul(tv1, yn2); // 27. tv1 = tv1 * yn2
192
+ tv1 = Fp.mul(tv1, BigInt(-2)); // 28. tv1 = -2 * tv1
193
+ let yEd = Fp.add(tv2, tv1); // 29. yEd = tv2 + tv1
194
+ tv4 = Fp.mul(tv4, yd2); // 30. tv4 = tv4 * yd2
195
+ yEd = Fp.add(yEd, tv4); // 31. yEd = yEd + tv4
196
+ tv1 = Fp.mul(xEd, yEd); // 32. tv1 = xEd * yEd
197
+ let e = Fp.eql(tv1, Fp.ZERO); // 33. e = tv1 == 0
198
+ xEn = Fp.cmov(xEn, Fp.ZERO, e); // 34. xEn = CMOV(xEn, 0, e)
199
+ xEd = Fp.cmov(xEd, Fp.ONE, e); // 35. xEd = CMOV(xEd, 1, e)
200
+ yEn = Fp.cmov(yEn, Fp.ONE, e); // 36. yEn = CMOV(yEn, 1, e)
201
+ yEd = Fp.cmov(yEd, Fp.ONE, e); // 37. yEd = CMOV(yEd, 1, e)
202
+ const inv = Fp.invertBatch([xEd, yEd]); // batch division
203
+ return { x: Fp.mul(xEn, inv[0]), y: Fp.mul(yEn, inv[1]) }; // 38. return (xEn, xEd, yEn, yEd)
204
+ }
205
+ const { hashToCurve, encodeToCurve } = htf.hashToCurve(exports.ed448.ExtendedPoint, (scalars) => map_to_curve_elligator2_edwards448(scalars[0]), {
206
+ DST: 'edwards448_XOF:SHAKE256_ELL2_RO_',
207
+ encodeDST: 'edwards448_XOF:SHAKE256_ELL2_NU_',
208
+ p: Fp.ORDER,
209
+ m: 1,
210
+ k: 224,
211
+ expand: 'xof',
212
+ hash: sha3_1.shake256,
213
+ });
214
+ exports.hashToCurve = hashToCurve;
215
+ exports.encodeToCurve = encodeToCurve;