@noble/curves 1.9.0 → 1.9.2

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 (207) hide show
  1. package/README.md +78 -34
  2. package/_shortw_utils.d.ts +7 -5
  3. package/_shortw_utils.d.ts.map +1 -1
  4. package/_shortw_utils.js +2 -8
  5. package/_shortw_utils.js.map +1 -1
  6. package/abstract/bls.d.ts +60 -24
  7. package/abstract/bls.d.ts.map +1 -1
  8. package/abstract/bls.js +158 -109
  9. package/abstract/bls.js.map +1 -1
  10. package/abstract/curve.d.ts +44 -9
  11. package/abstract/curve.d.ts.map +1 -1
  12. package/abstract/curve.js +99 -11
  13. package/abstract/curve.js.map +1 -1
  14. package/abstract/edwards.d.ts +112 -25
  15. package/abstract/edwards.d.ts.map +1 -1
  16. package/abstract/edwards.js +141 -92
  17. package/abstract/edwards.js.map +1 -1
  18. package/abstract/fft.d.ts +122 -0
  19. package/abstract/fft.d.ts.map +1 -0
  20. package/abstract/fft.js +438 -0
  21. package/abstract/fft.js.map +1 -0
  22. package/abstract/hash-to-curve.d.ts +25 -11
  23. package/abstract/hash-to-curve.d.ts.map +1 -1
  24. package/abstract/hash-to-curve.js +17 -14
  25. package/abstract/hash-to-curve.js.map +1 -1
  26. package/abstract/modular.d.ts +28 -17
  27. package/abstract/modular.d.ts.map +1 -1
  28. package/abstract/modular.js +156 -139
  29. package/abstract/modular.js.map +1 -1
  30. package/abstract/montgomery.d.ts +3 -8
  31. package/abstract/montgomery.d.ts.map +1 -1
  32. package/abstract/montgomery.js +73 -93
  33. package/abstract/montgomery.js.map +1 -1
  34. package/abstract/poseidon.d.ts +5 -13
  35. package/abstract/poseidon.d.ts.map +1 -1
  36. package/abstract/poseidon.js +12 -7
  37. package/abstract/poseidon.js.map +1 -1
  38. package/abstract/tower.d.ts +20 -46
  39. package/abstract/tower.d.ts.map +1 -1
  40. package/abstract/tower.js +10 -4
  41. package/abstract/tower.js.map +1 -1
  42. package/abstract/utils.d.ts +1 -115
  43. package/abstract/utils.d.ts.map +1 -1
  44. package/abstract/utils.js +17 -371
  45. package/abstract/utils.js.map +1 -1
  46. package/abstract/weierstrass.d.ts +152 -73
  47. package/abstract/weierstrass.d.ts.map +1 -1
  48. package/abstract/weierstrass.js +487 -404
  49. package/abstract/weierstrass.js.map +1 -1
  50. package/bls12-381.d.ts +2 -0
  51. package/bls12-381.d.ts.map +1 -1
  52. package/bls12-381.js +504 -480
  53. package/bls12-381.js.map +1 -1
  54. package/bn254.d.ts +2 -0
  55. package/bn254.d.ts.map +1 -1
  56. package/bn254.js +44 -32
  57. package/bn254.js.map +1 -1
  58. package/ed25519.d.ts +25 -9
  59. package/ed25519.d.ts.map +1 -1
  60. package/ed25519.js +89 -65
  61. package/ed25519.js.map +1 -1
  62. package/ed448.d.ts +29 -10
  63. package/ed448.d.ts.map +1 -1
  64. package/ed448.js +116 -81
  65. package/ed448.js.map +1 -1
  66. package/esm/_shortw_utils.d.ts +7 -5
  67. package/esm/_shortw_utils.d.ts.map +1 -1
  68. package/esm/_shortw_utils.js +2 -8
  69. package/esm/_shortw_utils.js.map +1 -1
  70. package/esm/abstract/bls.d.ts +60 -24
  71. package/esm/abstract/bls.d.ts.map +1 -1
  72. package/esm/abstract/bls.js +158 -109
  73. package/esm/abstract/bls.js.map +1 -1
  74. package/esm/abstract/curve.d.ts +44 -9
  75. package/esm/abstract/curve.d.ts.map +1 -1
  76. package/esm/abstract/curve.js +96 -12
  77. package/esm/abstract/curve.js.map +1 -1
  78. package/esm/abstract/edwards.d.ts +112 -25
  79. package/esm/abstract/edwards.d.ts.map +1 -1
  80. package/esm/abstract/edwards.js +141 -94
  81. package/esm/abstract/edwards.js.map +1 -1
  82. package/esm/abstract/fft.d.ts +122 -0
  83. package/esm/abstract/fft.d.ts.map +1 -0
  84. package/esm/abstract/fft.js +425 -0
  85. package/esm/abstract/fft.js.map +1 -0
  86. package/esm/abstract/hash-to-curve.d.ts +25 -11
  87. package/esm/abstract/hash-to-curve.d.ts.map +1 -1
  88. package/esm/abstract/hash-to-curve.js +17 -14
  89. package/esm/abstract/hash-to-curve.js.map +1 -1
  90. package/esm/abstract/modular.d.ts +28 -17
  91. package/esm/abstract/modular.d.ts.map +1 -1
  92. package/esm/abstract/modular.js +155 -138
  93. package/esm/abstract/modular.js.map +1 -1
  94. package/esm/abstract/montgomery.d.ts +3 -8
  95. package/esm/abstract/montgomery.d.ts.map +1 -1
  96. package/esm/abstract/montgomery.js +74 -94
  97. package/esm/abstract/montgomery.js.map +1 -1
  98. package/esm/abstract/poseidon.d.ts +5 -13
  99. package/esm/abstract/poseidon.d.ts.map +1 -1
  100. package/esm/abstract/poseidon.js +12 -7
  101. package/esm/abstract/poseidon.js.map +1 -1
  102. package/esm/abstract/tower.d.ts +20 -46
  103. package/esm/abstract/tower.d.ts.map +1 -1
  104. package/esm/abstract/tower.js +10 -4
  105. package/esm/abstract/tower.js.map +1 -1
  106. package/esm/abstract/utils.d.ts +1 -115
  107. package/esm/abstract/utils.d.ts.map +1 -1
  108. package/esm/abstract/utils.js +3 -344
  109. package/esm/abstract/utils.js.map +1 -1
  110. package/esm/abstract/weierstrass.d.ts +152 -73
  111. package/esm/abstract/weierstrass.d.ts.map +1 -1
  112. package/esm/abstract/weierstrass.js +485 -406
  113. package/esm/abstract/weierstrass.js.map +1 -1
  114. package/esm/bls12-381.d.ts +2 -0
  115. package/esm/bls12-381.d.ts.map +1 -1
  116. package/esm/bls12-381.js +503 -479
  117. package/esm/bls12-381.js.map +1 -1
  118. package/esm/bn254.d.ts +2 -0
  119. package/esm/bn254.d.ts.map +1 -1
  120. package/esm/bn254.js +41 -29
  121. package/esm/bn254.js.map +1 -1
  122. package/esm/ed25519.d.ts +25 -9
  123. package/esm/ed25519.d.ts.map +1 -1
  124. package/esm/ed25519.js +84 -60
  125. package/esm/ed25519.js.map +1 -1
  126. package/esm/ed448.d.ts +29 -10
  127. package/esm/ed448.d.ts.map +1 -1
  128. package/esm/ed448.js +113 -78
  129. package/esm/ed448.js.map +1 -1
  130. package/esm/jubjub.d.ts +4 -0
  131. package/esm/jubjub.d.ts.map +1 -1
  132. package/esm/jubjub.js +4 -0
  133. package/esm/jubjub.js.map +1 -1
  134. package/esm/misc.d.ts.map +1 -1
  135. package/esm/misc.js +31 -26
  136. package/esm/misc.js.map +1 -1
  137. package/esm/nist.d.ts +8 -16
  138. package/esm/nist.d.ts.map +1 -1
  139. package/esm/nist.js +87 -97
  140. package/esm/nist.js.map +1 -1
  141. package/esm/p256.d.ts +3 -3
  142. package/esm/p384.d.ts +3 -3
  143. package/esm/p521.d.ts +3 -3
  144. package/esm/pasta.d.ts +4 -0
  145. package/esm/pasta.d.ts.map +1 -1
  146. package/esm/pasta.js +4 -0
  147. package/esm/pasta.js.map +1 -1
  148. package/esm/secp256k1.d.ts +6 -6
  149. package/esm/secp256k1.d.ts.map +1 -1
  150. package/esm/secp256k1.js +44 -41
  151. package/esm/secp256k1.js.map +1 -1
  152. package/esm/utils.d.ts +96 -0
  153. package/esm/utils.d.ts.map +1 -0
  154. package/esm/utils.js +279 -0
  155. package/esm/utils.js.map +1 -0
  156. package/jubjub.d.ts +4 -0
  157. package/jubjub.d.ts.map +1 -1
  158. package/jubjub.js +4 -0
  159. package/jubjub.js.map +1 -1
  160. package/misc.d.ts.map +1 -1
  161. package/misc.js +35 -30
  162. package/misc.js.map +1 -1
  163. package/nist.d.ts +8 -16
  164. package/nist.d.ts.map +1 -1
  165. package/nist.js +87 -97
  166. package/nist.js.map +1 -1
  167. package/p256.d.ts +3 -3
  168. package/p384.d.ts +3 -3
  169. package/p521.d.ts +3 -3
  170. package/package.json +26 -8
  171. package/pasta.d.ts +4 -0
  172. package/pasta.d.ts.map +1 -1
  173. package/pasta.js +4 -0
  174. package/pasta.js.map +1 -1
  175. package/secp256k1.d.ts +6 -6
  176. package/secp256k1.d.ts.map +1 -1
  177. package/secp256k1.js +47 -44
  178. package/secp256k1.js.map +1 -1
  179. package/src/_shortw_utils.ts +5 -15
  180. package/src/abstract/bls.ts +260 -145
  181. package/src/abstract/curve.ts +125 -18
  182. package/src/abstract/edwards.ts +282 -127
  183. package/src/abstract/fft.ts +519 -0
  184. package/src/abstract/hash-to-curve.ts +51 -27
  185. package/src/abstract/modular.ts +156 -143
  186. package/src/abstract/montgomery.ts +81 -111
  187. package/src/abstract/poseidon.ts +22 -18
  188. package/src/abstract/tower.ts +37 -68
  189. package/src/abstract/utils.ts +3 -378
  190. package/src/abstract/weierstrass.ts +752 -461
  191. package/src/bls12-381.ts +542 -507
  192. package/src/bn254.ts +47 -35
  193. package/src/ed25519.ts +104 -76
  194. package/src/ed448.ts +156 -105
  195. package/src/jubjub.ts +4 -0
  196. package/src/misc.ts +39 -34
  197. package/src/nist.ts +138 -126
  198. package/src/p256.ts +3 -3
  199. package/src/p384.ts +3 -3
  200. package/src/p521.ts +3 -3
  201. package/src/pasta.ts +5 -1
  202. package/src/secp256k1.ts +59 -47
  203. package/src/utils.ts +328 -0
  204. package/utils.d.ts +96 -0
  205. package/utils.d.ts.map +1 -0
  206. package/utils.js +313 -0
  207. package/utils.js.map +1 -0
@@ -1,5 +1,4 @@
1
1
  /**
2
- * BLS (Barreto-Lynn-Scott) family of pairing-friendly curves.
3
2
  * BLS != BLS.
4
3
  * The file implements BLS (Boneh-Lynn-Shacham) signatures.
5
4
  * Used in both BLS (Barreto-Lynn-Scott) and BN (Barreto-Naehrig)
@@ -10,28 +9,39 @@
10
9
  * - Gt, created by bilinear (ate) pairing e(G1, G2), consists of p-th roots of unity in
11
10
  * Fq^k where k is embedding degree. Only degree 12 is currently supported, 24 is not.
12
11
  * Pairing is used to aggregate and verify signatures.
13
- * There are two main ways to use it:
14
- * 1. Fp for short private keys, Fp₂ for signatures
15
- * 2. Fp for short signatures, Fp₂ for private keys
12
+ * There are two modes of operation:
13
+ * - Long signatures: X-byte keys + 2X-byte sigs (G1 keys + G2 sigs).
14
+ * - Short signatures: 2X-byte keys + X-byte sigs (G2 keys + G1 sigs).
16
15
  * @module
17
16
  **/
18
17
  /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
19
- // TODO: import { AffinePoint } from './curve.ts';
20
18
  import {
19
+ abytes,
20
+ ensureBytes,
21
+ memoized,
22
+ randomBytes,
23
+ type CHash,
24
+ type Hex,
25
+ type PrivKey,
26
+ } from '../utils.ts';
27
+ import { normalizeZ } from './curve.ts';
28
+ import {
29
+ createHasher,
30
+ type H2CHasher,
31
+ type H2CHashOpts,
32
+ type H2COpts,
21
33
  type H2CPointConstructor,
22
34
  type htfBasicOpts,
23
- type Opts as HTFOpts,
24
35
  type MapToCurve,
25
- createHasher,
26
36
  } from './hash-to-curve.ts';
27
- import { type IField, getMinHashLength, mapHashToField } from './modular.ts';
28
- import type { Fp12, Fp12Bls, Fp2, Fp2Bls, Fp6 } from './tower.ts';
29
- import { type CHash, type Hex, type PrivKey, ensureBytes, memoized } from './utils.ts';
37
+ import { getMinHashLength, mapHashToField, type IField } from './modular.ts';
38
+ import type { Fp12, Fp12Bls, Fp2, Fp2Bls, Fp6Bls } from './tower.ts';
30
39
  import {
40
+ weierstrassPoints,
31
41
  type CurvePointsRes,
32
42
  type CurvePointsType,
43
+ type ProjConstructor,
33
44
  type ProjPointType,
34
- weierstrassPoints,
35
45
  } from './weierstrass.ts';
36
46
 
37
47
  type Fp = bigint; // Can be different field?
@@ -42,13 +52,19 @@ const _0n = BigInt(0), _1n = BigInt(1), _2n = BigInt(2), _3n = BigInt(3);
42
52
  export type TwistType = 'multiplicative' | 'divisive';
43
53
 
44
54
  export type ShortSignatureCoder<Fp> = {
55
+ fromBytes(bytes: Uint8Array): ProjPointType<Fp>;
45
56
  fromHex(hex: Hex): ProjPointType<Fp>;
57
+ toBytes(point: ProjPointType<Fp>): Uint8Array;
58
+ /** @deprecated use `toBytes` */
46
59
  toRawBytes(point: ProjPointType<Fp>): Uint8Array;
47
60
  toHex(point: ProjPointType<Fp>): string;
48
61
  };
49
62
 
50
63
  export type SignatureCoder<Fp> = {
64
+ fromBytes(bytes: Uint8Array): ProjPointType<Fp>;
51
65
  fromHex(hex: Hex): ProjPointType<Fp>;
66
+ toBytes(point: ProjPointType<Fp>): Uint8Array;
67
+ /** @deprecated use `toBytes` */
52
68
  toRawBytes(point: ProjPointType<Fp>): Uint8Array;
53
69
  toHex(point: ProjPointType<Fp>): string;
54
70
  };
@@ -69,21 +85,21 @@ export type PostPrecomputeFn = (
69
85
  pointAdd: PostPrecomputePointAddFn
70
86
  ) => void;
71
87
  export type CurveType = {
72
- G1: Omit<CurvePointsType<Fp>, 'n'> & {
88
+ G1: CurvePointsType<Fp> & {
73
89
  ShortSignature: SignatureCoder<Fp>;
74
90
  mapToCurve: MapToCurve<Fp>;
75
- htfDefaults: HTFOpts;
91
+ htfDefaults: H2COpts;
76
92
  };
77
- G2: Omit<CurvePointsType<Fp2>, 'n'> & {
93
+ G2: CurvePointsType<Fp2> & {
78
94
  Signature: SignatureCoder<Fp2>;
79
95
  mapToCurve: MapToCurve<Fp2>;
80
- htfDefaults: HTFOpts;
96
+ htfDefaults: H2COpts;
81
97
  };
82
98
  fields: {
83
99
  Fp: IField<Fp>;
84
100
  Fr: IField<bigint>;
85
101
  Fp2: Fp2Bls;
86
- Fp6: IField<Fp6>;
102
+ Fp6: Fp6Bls;
87
103
  Fp12: Fp12Bls;
88
104
  };
89
105
  params: {
@@ -92,12 +108,12 @@ export type CurveType = {
92
108
  // Can be different from 'X' (seed) param!
93
109
  ateLoopSize: bigint;
94
110
  xNegative: boolean;
95
- r: bigint;
111
+ r: bigint; // TODO: remove
96
112
  twistType: TwistType; // BLS12-381: Multiplicative, BN254: Divisive
97
113
  };
98
- htfDefaults: HTFOpts;
114
+ htfDefaults: H2COpts;
99
115
  hash: CHash; // Because we need outputLen for DRBG
100
- randomBytes: (bytesLength?: number) => Uint8Array;
116
+ randomBytes?: (bytesLength?: number) => Uint8Array;
101
117
  // This is super ugly hack for untwist point in BN254 after miller loop
102
118
  postPrecompute?: PostPrecomputeFn;
103
119
  };
@@ -106,22 +122,38 @@ type PrecomputeSingle = [Fp2, Fp2, Fp2][];
106
122
  type Precompute = PrecomputeSingle[];
107
123
 
108
124
  export type CurveFn = {
125
+ longSignatures: BLSSigs<bigint, Fp2>;
126
+ shortSignatures: BLSSigs<Fp2, bigint>;
127
+
128
+ millerLoopBatch: (pairs: [Precompute, Fp, Fp][]) => Fp12;
129
+ pairing: (P: ProjPointType<Fp>, Q: ProjPointType<Fp2>, withFinalExponent?: boolean) => Fp12;
130
+ pairingBatch: (
131
+ pairs: { g1: ProjPointType<Fp>; g2: ProjPointType<Fp2> }[],
132
+ withFinalExponent?: boolean
133
+ ) => Fp12;
134
+
135
+ /** @deprecated use `longSignatures.getPublicKey` */
109
136
  getPublicKey: (privateKey: PrivKey) => Uint8Array;
137
+ /** @deprecated use `shortSignatures.getPublicKey` */
110
138
  getPublicKeyForShortSignatures: (privateKey: PrivKey) => Uint8Array;
139
+ /** @deprecated use `longSignatures.sign` */
111
140
  sign: {
112
141
  (message: Hex, privateKey: PrivKey, htfOpts?: htfBasicOpts): Uint8Array;
113
142
  (message: ProjPointType<Fp2>, privateKey: PrivKey, htfOpts?: htfBasicOpts): ProjPointType<Fp2>;
114
143
  };
144
+ /** @deprecated use `shortSignatures.sign` */
115
145
  signShortSignature: {
116
146
  (message: Hex, privateKey: PrivKey, htfOpts?: htfBasicOpts): Uint8Array;
117
147
  (message: ProjPointType<Fp>, privateKey: PrivKey, htfOpts?: htfBasicOpts): ProjPointType<Fp>;
118
148
  };
149
+ /** @deprecated use `longSignatures.verify` */
119
150
  verify: (
120
151
  signature: Hex | ProjPointType<Fp2>,
121
152
  message: Hex | ProjPointType<Fp2>,
122
153
  publicKey: Hex | ProjPointType<Fp>,
123
154
  htfOpts?: htfBasicOpts
124
155
  ) => boolean;
156
+ /** @deprecated use `shortSignatures.verify` */
125
157
  verifyShortSignature: (
126
158
  signature: Hex | ProjPointType<Fp>,
127
159
  message: Hex | ProjPointType<Fp>,
@@ -134,38 +166,45 @@ export type CurveFn = {
134
166
  publicKeys: (Hex | ProjPointType<Fp>)[],
135
167
  htfOpts?: htfBasicOpts
136
168
  ) => boolean;
169
+ /** @deprecated use `longSignatures.aggregatePublicKeys` */
137
170
  aggregatePublicKeys: {
138
171
  (publicKeys: Hex[]): Uint8Array;
139
172
  (publicKeys: ProjPointType<Fp>[]): ProjPointType<Fp>;
140
173
  };
174
+ /** @deprecated use `longSignatures.aggregateSignatures` */
141
175
  aggregateSignatures: {
142
176
  (signatures: Hex[]): Uint8Array;
143
177
  (signatures: ProjPointType<Fp2>[]): ProjPointType<Fp2>;
144
178
  };
179
+ /** @deprecated use `shortSignatures.aggregateSignatures` */
145
180
  aggregateShortSignatures: {
146
181
  (signatures: Hex[]): Uint8Array;
147
182
  (signatures: ProjPointType<Fp>[]): ProjPointType<Fp>;
148
183
  };
149
- millerLoopBatch: (pairs: [Precompute, Fp, Fp][]) => Fp12;
150
- pairing: (P: ProjPointType<Fp>, Q: ProjPointType<Fp2>, withFinalExponent?: boolean) => Fp12;
151
- pairingBatch: (
152
- pairs: { g1: ProjPointType<Fp>; g2: ProjPointType<Fp2> }[],
153
- withFinalExponent?: boolean
154
- ) => Fp12;
155
- G1: CurvePointsRes<Fp> & ReturnType<typeof createHasher<Fp>>;
156
- G2: CurvePointsRes<Fp2> & ReturnType<typeof createHasher<Fp2>>;
184
+ /** @deprecated use `curves.G1` and `curves.G2` */
185
+ G1: CurvePointsRes<Fp> & H2CHasher<Fp>;
186
+ G2: CurvePointsRes<Fp2> & H2CHasher<Fp2>;
187
+ /** @deprecated use `longSignatures.Signature` */
157
188
  Signature: SignatureCoder<Fp2>;
189
+ /** @deprecated use `shortSignatures.Signature` */
158
190
  ShortSignature: ShortSignatureCoder<Fp>;
159
191
  params: {
160
192
  ateLoopSize: bigint;
161
193
  r: bigint;
194
+ twistType: TwistType;
195
+ /** @deprecated */
162
196
  G1b: bigint;
197
+ /** @deprecated */
163
198
  G2b: Fp2;
164
199
  };
200
+ curves: {
201
+ G1: ProjConstructor<bigint>;
202
+ G2: ProjConstructor<Fp2>;
203
+ };
165
204
  fields: {
166
205
  Fp: IField<Fp>;
167
206
  Fp2: Fp2Bls;
168
- Fp6: IField<Fp6>;
207
+ Fp6: Fp6Bls;
169
208
  Fp12: Fp12Bls;
170
209
  Fr: IField<bigint>;
171
210
  };
@@ -175,6 +214,21 @@ export type CurveFn = {
175
214
  };
176
215
  };
177
216
 
217
+ type BLSInput = Hex | Uint8Array;
218
+ export interface BLSSigs<P, S> {
219
+ getPublicKey(privateKey: PrivKey): ProjPointType<P>;
220
+ sign(hashedMessage: ProjPointType<S>, privateKey: PrivKey): ProjPointType<S>;
221
+ verify(
222
+ signature: ProjPointType<S> | BLSInput,
223
+ message: ProjPointType<S>,
224
+ publicKey: ProjPointType<P> | BLSInput
225
+ ): boolean;
226
+ aggregatePublicKeys(publicKeys: (ProjPointType<P> | BLSInput)[]): ProjPointType<P>;
227
+ aggregateSignatures(signatures: (ProjPointType<S> | BLSInput)[]): ProjPointType<S>;
228
+ hash(message: Uint8Array, DST?: string | Uint8Array, hashOpts?: H2CHashOpts): ProjPointType<S>;
229
+ Signature: SignatureCoder<S>;
230
+ }
231
+
178
232
  // Not used with BLS12-381 (no sequential `11` in X). Useful for other curves.
179
233
  function NAfDecomposition(a: bigint) {
180
234
  const res = [];
@@ -189,31 +243,32 @@ function NAfDecomposition(a: bigint) {
189
243
  return res;
190
244
  }
191
245
 
246
+ // G1_Point: ProjConstructor<bigint>, G2_Point: ProjConstructor<Fp2>,
192
247
  export function bls(CURVE: CurveType): CurveFn {
193
248
  // Fields are specific for curve, so for now we'll need to pass them with opts
194
249
  const { Fp, Fr, Fp2, Fp6, Fp12 } = CURVE.fields;
195
250
  const BLS_X_IS_NEGATIVE = CURVE.params.xNegative;
196
251
  const TWIST: TwistType = CURVE.params.twistType;
197
252
  // Point on G1 curve: (x, y)
198
- const G1_ = weierstrassPoints({ n: Fr.ORDER, ...CURVE.G1 });
253
+ const G1_ = weierstrassPoints(CURVE.G1);
199
254
  const G1 = Object.assign(
200
255
  G1_,
201
- createHasher(G1_.ProjectivePoint, CURVE.G1.mapToCurve, {
256
+ createHasher(G1_.Point, CURVE.G1.mapToCurve, {
202
257
  ...CURVE.htfDefaults,
203
258
  ...CURVE.G1.htfDefaults,
204
259
  })
205
260
  );
206
261
  // Point on G2 curve (complex numbers): (x₁, x₂+i), (y₁, y₂+i)
207
- const G2_ = weierstrassPoints({ n: Fr.ORDER, ...CURVE.G2 });
262
+ const G2_ = weierstrassPoints(CURVE.G2);
208
263
  const G2 = Object.assign(
209
264
  G2_,
210
- createHasher(G2_.ProjectivePoint as H2CPointConstructor<Fp2>, CURVE.G2.mapToCurve, {
265
+ createHasher(G2_.Point as H2CPointConstructor<Fp2>, CURVE.G2.mapToCurve, {
211
266
  ...CURVE.htfDefaults,
212
267
  ...CURVE.G2.htfDefaults,
213
268
  })
214
269
  );
215
- type G1 = typeof G1.ProjectivePoint.BASE;
216
- type G2 = typeof G2.ProjectivePoint.BASE;
270
+ type G1 = typeof G1.Point.BASE;
271
+ type G2 = typeof G2.Point.BASE;
217
272
 
218
273
  // Applies sparse multiplication as line function
219
274
  let lineFunction: (c0: Fp2, c1: Fp2, c2: Fp2, f: Fp12, Px: Fp, Py: Fp) => Fp12;
@@ -316,11 +371,18 @@ export function bls(CURVE: CurveType): CurveFn {
316
371
  function pairingBatch(pairs: PairingInput[], withFinalExponent: boolean = true) {
317
372
  const res: MillerInput = [];
318
373
  // Cache precomputed toAffine for all points
319
- G1.ProjectivePoint.normalizeZ(pairs.map(({ g1 }) => g1));
320
- G2.ProjectivePoint.normalizeZ(pairs.map(({ g2 }) => g2));
374
+ normalizeZ(
375
+ G1.Point,
376
+ 'pz',
377
+ pairs.map(({ g1 }) => g1)
378
+ );
379
+ normalizeZ(
380
+ G2.Point,
381
+ 'pz',
382
+ pairs.map(({ g2 }) => g2)
383
+ );
321
384
  for (const { g1, g2 } of pairs) {
322
- if (g1.equals(G1.ProjectivePoint.ZERO) || g2.equals(G2.ProjectivePoint.ZERO))
323
- throw new Error('pairing is not available for ZERO point');
385
+ if (g1.is0() || g2.is0()) throw new Error('pairing is not available for ZERO point');
324
386
  // This uses toAffine inside
325
387
  g1.assertValidity();
326
388
  g2.assertValidity();
@@ -334,60 +396,154 @@ export function bls(CURVE: CurveType): CurveFn {
334
396
  return pairingBatch([{ g1: Q, g2: P }], withFinalExponent);
335
397
  }
336
398
 
399
+ const rand = CURVE.randomBytes || randomBytes;
400
+
337
401
  const utils = {
338
402
  randomPrivateKey: (): Uint8Array => {
339
403
  const length = getMinHashLength(Fr.ORDER);
340
- return mapHashToField(CURVE.randomBytes(length), Fr.ORDER);
404
+ return mapHashToField(rand(length), Fr.ORDER);
341
405
  },
342
406
  calcPairingPrecomputes,
343
407
  };
344
408
 
345
- const { ShortSignature } = CURVE.G1;
346
- const { Signature } = CURVE.G2;
409
+ function aNonEmpty(arr: any[]) {
410
+ if (!Array.isArray(arr) || arr.length === 0) throw new Error('expected non-empty array');
411
+ }
347
412
 
348
413
  type G1Hex = Hex | G1;
349
414
  type G2Hex = Hex | G2;
350
415
  function normP1(point: G1Hex): G1 {
351
- return point instanceof G1.ProjectivePoint ? (point as G1) : G1.ProjectivePoint.fromHex(point);
416
+ return point instanceof G1.Point ? (point as G1) : G1.Point.fromHex(point);
352
417
  }
418
+ function normP2(point: G2Hex): G2 {
419
+ return point instanceof G2.Point ? point : Signature.fromHex(point);
420
+ }
421
+
422
+ // TODO: add verifyBatch, fix types, Export Signature property,
423
+ // actually expose the generated APIs
424
+ function createBls<P, S>(PubCurve: any, SigCurve: any): BLSSigs<P, S> {
425
+ type PubPoint = ProjPointType<P>;
426
+ type SigPoint = ProjPointType<S>;
427
+ function normPub(point: PubPoint | BLSInput): PubPoint {
428
+ return point instanceof PubCurve.Point ? (point as PubPoint) : PubCurve.Point.fromHex(point);
429
+ }
430
+ function normSig(point: SigPoint | BLSInput): SigPoint {
431
+ return point instanceof SigCurve.Point ? (point as SigPoint) : SigCurve.Point.fromHex(point);
432
+ }
433
+ function amsg(m: unknown): SigPoint {
434
+ if (!(m instanceof SigCurve.Point))
435
+ throw new Error(`expected valid message hashed to ${isLongSigs ? 'G2' : 'G1'} curve`);
436
+ return m as any;
437
+ }
438
+
439
+ // TODO: is this always ok?
440
+ const isLongSigs = SigCurve.Point.Fp.BYTES > PubCurve.Point.Fp.BYTES;
441
+ return {
442
+ // P = pk x G
443
+ getPublicKey(privateKey: PrivKey): PubPoint {
444
+ return PubCurve.Point.fromPrivateKey(privateKey);
445
+ },
446
+ // S = pk x H(m)
447
+ sign(message: SigPoint, privateKey: PrivKey, unusedArg?: any): SigPoint {
448
+ if (unusedArg != null) throw new Error('sign() expects 2 arguments');
449
+ amsg(message).assertValidity();
450
+ return message.multiply(PubCurve.normPrivateKeyToScalar(privateKey));
451
+ },
452
+ // Checks if pairing of public key & hash is equal to pairing of generator & signature.
453
+ // e(P, H(m)) == e(G, S)
454
+ // e(S, G) == e(H(m), P)
455
+ verify(
456
+ signature: SigPoint | BLSInput,
457
+ message: SigPoint,
458
+ publicKey: PubPoint | BLSInput,
459
+ unusedArg?: any
460
+ ): boolean {
461
+ if (unusedArg != null) throw new Error('verify() expects 3 arguments');
462
+ signature = normSig(signature);
463
+ publicKey = normPub(publicKey);
464
+ const P = publicKey.negate();
465
+ const G = PubCurve.Point.BASE;
466
+ const Hm = amsg(message);
467
+ const S = signature;
468
+ // This code was changed in 1.9.x:
469
+ // Before it was G.negate() in G2, now it's always pubKey.negate
470
+ // TODO: understand if this is OK?
471
+ // prettier-ignore
472
+ const exp_ = isLongSigs ? [
473
+ { g1: P, g2: Hm },
474
+ { g1: G, g2: S }
475
+ ] : [
476
+ { g1: Hm, g2: P },
477
+ { g1: S, g2: G }
478
+ ];
479
+ // TODO
480
+ // @ts-ignore
481
+ const exp = pairingBatch(exp_);
482
+ return Fp12.eql(exp, Fp12.ONE);
483
+ },
484
+
485
+ // Adds a bunch of public key points together.
486
+ // pk1 + pk2 + pk3 = pkA
487
+ aggregatePublicKeys(publicKeys: (PubPoint | BLSInput)[]): PubPoint {
488
+ aNonEmpty(publicKeys);
489
+ publicKeys = publicKeys.map((pub) => normPub(pub));
490
+ const agg = publicKeys.reduce((sum, p) => sum.add(p), PubCurve.Point.ZERO);
491
+ agg.assertValidity();
492
+ return agg;
493
+ },
494
+
495
+ // Adds a bunch of signature points together.
496
+ // pk1 + pk2 + pk3 = pkA
497
+ aggregateSignatures(signatures: (SigPoint | BLSInput)[]): SigPoint {
498
+ aNonEmpty(signatures);
499
+ signatures = signatures.map((sig) => normSig(sig));
500
+ const agg = signatures.reduce((sum, s) => sum.add(s), SigCurve.Point.ZERO);
501
+ agg.assertValidity();
502
+ return agg;
503
+ },
504
+
505
+ hash(messageBytes: Uint8Array, DST?: string | Uint8Array): SigPoint {
506
+ abytes(messageBytes);
507
+ const opts = DST ? { DST } : undefined;
508
+ return SigCurve.hashToCurve(messageBytes, opts);
509
+ },
510
+
511
+ // @ts-ignore
512
+ Signature: isLongSigs ? CURVE.G2.Signature : CURVE.G1.ShortSignature,
513
+ };
514
+ }
515
+
516
+ const longSignatures = createBls<bigint, Fp2>(G1, G2);
517
+ const shortSignatures = createBls<Fp2, bigint>(G2, G1);
518
+
519
+ // LEGACY code
520
+ const { ShortSignature } = CURVE.G1;
521
+ const { Signature } = CURVE.G2;
522
+
353
523
  function normP1Hash(point: G1Hex, htfOpts?: htfBasicOpts): G1 {
354
- return point instanceof G1.ProjectivePoint
524
+ return point instanceof G1.Point
355
525
  ? point
356
- : (G1.hashToCurve(ensureBytes('point', point), htfOpts) as G1);
357
- }
358
- function normP2(point: G2Hex): G2 {
359
- return point instanceof G2.ProjectivePoint ? point : Signature.fromHex(point);
526
+ : shortSignatures.hash(ensureBytes('point', point), htfOpts?.DST);
360
527
  }
361
528
  function normP2Hash(point: G2Hex, htfOpts?: htfBasicOpts): G2 {
362
- return point instanceof G2.ProjectivePoint
529
+ return point instanceof G2.Point
363
530
  ? point
364
- : (G2.hashToCurve(ensureBytes('point', point), htfOpts) as G2);
531
+ : longSignatures.hash(ensureBytes('point', point), htfOpts?.DST);
365
532
  }
366
533
 
367
- // Multiplies generator (G1) by private key.
368
- // P = pk x G
369
534
  function getPublicKey(privateKey: PrivKey): Uint8Array {
370
- return G1.ProjectivePoint.fromPrivateKey(privateKey).toRawBytes(true);
535
+ return longSignatures.getPublicKey(privateKey).toBytes(true);
371
536
  }
372
-
373
- // Multiplies generator (G2) by private key.
374
- // P = pk x G
375
537
  function getPublicKeyForShortSignatures(privateKey: PrivKey): Uint8Array {
376
- return G2.ProjectivePoint.fromPrivateKey(privateKey).toRawBytes(true);
538
+ return shortSignatures.getPublicKey(privateKey).toBytes(true);
377
539
  }
378
-
379
- // Executes `hashToCurve` on the message and then multiplies the result by private key.
380
- // S = pk x H(m)
381
540
  function sign(message: Hex, privateKey: PrivKey, htfOpts?: htfBasicOpts): Uint8Array;
382
541
  function sign(message: G2, privateKey: PrivKey, htfOpts?: htfBasicOpts): G2;
383
542
  function sign(message: G2Hex, privateKey: PrivKey, htfOpts?: htfBasicOpts): Uint8Array | G2 {
384
- const msgPoint = normP2Hash(message, htfOpts);
385
- msgPoint.assertValidity();
386
- const sigPoint = msgPoint.multiply(G1.normPrivateKeyToScalar(privateKey));
387
- if (message instanceof G2.ProjectivePoint) return sigPoint;
388
- return Signature.toRawBytes(sigPoint);
543
+ const Hm = normP2Hash(message, htfOpts);
544
+ const S = longSignatures.sign(Hm, privateKey);
545
+ return message instanceof G2.Point ? S : Signature.toBytes(S);
389
546
  }
390
-
391
547
  function signShortSignature(
392
548
  message: Hex,
393
549
  privateKey: PrivKey,
@@ -399,104 +555,52 @@ export function bls(CURVE: CurveType): CurveFn {
399
555
  privateKey: PrivKey,
400
556
  htfOpts?: htfBasicOpts
401
557
  ): Uint8Array | G1 {
402
- const msgPoint = normP1Hash(message, htfOpts);
403
- msgPoint.assertValidity();
404
- const sigPoint = msgPoint.multiply(G1.normPrivateKeyToScalar(privateKey));
405
- if (message instanceof G1.ProjectivePoint) return sigPoint;
406
- return ShortSignature.toRawBytes(sigPoint);
558
+ const Hm = normP1Hash(message, htfOpts);
559
+ const S = shortSignatures.sign(Hm, privateKey);
560
+ return message instanceof G1.Point ? S : ShortSignature.toBytes(S);
407
561
  }
408
-
409
- // Checks if pairing of public key & hash is equal to pairing of generator & signature.
410
- // e(P, H(m)) == e(G, S)
411
562
  function verify(
412
563
  signature: G2Hex,
413
564
  message: G2Hex,
414
565
  publicKey: G1Hex,
415
566
  htfOpts?: htfBasicOpts
416
567
  ): boolean {
417
- const P = normP1(publicKey);
418
568
  const Hm = normP2Hash(message, htfOpts);
419
- const G = G1.ProjectivePoint.BASE;
420
- const S = normP2(signature);
421
- const exp = pairingBatch([
422
- { g1: P.negate(), g2: Hm }, // ePHM = pairing(P.negate(), Hm, false);
423
- { g1: G, g2: S }, // eGS = pairing(G, S, false);
424
- ]);
425
- return Fp12.eql(exp, Fp12.ONE);
569
+ return longSignatures.verify(signature, Hm, publicKey);
426
570
  }
427
-
428
- // Checks if pairing of public key & hash is equal to pairing of generator & signature.
429
- // e(S, G) == e(H(m), P)
430
571
  function verifyShortSignature(
431
572
  signature: G1Hex,
432
573
  message: G1Hex,
433
574
  publicKey: G2Hex,
434
575
  htfOpts?: htfBasicOpts
435
576
  ): boolean {
436
- const P = normP2(publicKey);
437
577
  const Hm = normP1Hash(message, htfOpts);
438
- const G = G2.ProjectivePoint.BASE;
439
- const S = normP1(signature);
440
- const exp = pairingBatch([
441
- { g1: Hm, g2: P }, // eHmP = pairing(Hm, P, false);
442
- { g1: S, g2: G.negate() }, // eSG = pairing(S, G.negate(), false);
443
- ]);
444
- return Fp12.eql(exp, Fp12.ONE);
445
- }
446
-
447
- function aNonEmpty(arr: any[]) {
448
- if (!Array.isArray(arr) || arr.length === 0) throw new Error('expected non-empty array');
578
+ return shortSignatures.verify(signature, Hm, publicKey);
449
579
  }
450
-
451
- // Adds a bunch of public key points together.
452
- // pk1 + pk2 + pk3 = pkA
453
580
  function aggregatePublicKeys(publicKeys: Hex[]): Uint8Array;
454
581
  function aggregatePublicKeys(publicKeys: G1[]): G1;
455
582
  function aggregatePublicKeys(publicKeys: G1Hex[]): Uint8Array | G1 {
456
- aNonEmpty(publicKeys);
457
- const agg = publicKeys.map(normP1).reduce((sum, p) => sum.add(p), G1.ProjectivePoint.ZERO);
458
- const aggAffine = agg; //.toAffine();
459
- if (publicKeys[0] instanceof G1.ProjectivePoint) {
460
- aggAffine.assertValidity();
461
- return aggAffine;
462
- }
463
- // toRawBytes ensures point validity
464
- return aggAffine.toRawBytes(true);
583
+ const agg = longSignatures.aggregatePublicKeys(publicKeys);
584
+ return publicKeys[0] instanceof G1.Point ? agg : agg.toBytes(true);
465
585
  }
466
-
467
- // Adds a bunch of signature points together.
468
586
  function aggregateSignatures(signatures: Hex[]): Uint8Array;
469
587
  function aggregateSignatures(signatures: G2[]): G2;
470
588
  function aggregateSignatures(signatures: G2Hex[]): Uint8Array | G2 {
471
- aNonEmpty(signatures);
472
- const agg = signatures.map(normP2).reduce((sum, s) => sum.add(s), G2.ProjectivePoint.ZERO);
473
- const aggAffine = agg; //.toAffine();
474
- if (signatures[0] instanceof G2.ProjectivePoint) {
475
- aggAffine.assertValidity();
476
- return aggAffine;
477
- }
478
- return Signature.toRawBytes(aggAffine);
589
+ const agg = longSignatures.aggregateSignatures(signatures);
590
+ return signatures[0] instanceof G2.Point ? agg : Signature.toBytes(agg);
479
591
  }
480
-
481
- // Adds a bunch of signature points together.
482
592
  function aggregateShortSignatures(signatures: Hex[]): Uint8Array;
483
593
  function aggregateShortSignatures(signatures: G1[]): G1;
484
594
  function aggregateShortSignatures(signatures: G1Hex[]): Uint8Array | G1 {
485
- aNonEmpty(signatures);
486
- const agg = signatures.map(normP1).reduce((sum, s) => sum.add(s), G1.ProjectivePoint.ZERO);
487
- const aggAffine = agg; //.toAffine();
488
- if (signatures[0] instanceof G1.ProjectivePoint) {
489
- aggAffine.assertValidity();
490
- return aggAffine;
491
- }
492
- return ShortSignature.toRawBytes(aggAffine);
595
+ const agg = shortSignatures.aggregateSignatures(signatures);
596
+ return signatures[0] instanceof G1.Point ? agg : ShortSignature.toBytes(agg);
493
597
  }
494
598
 
495
599
  // https://ethresear.ch/t/fast-verification-of-multiple-bls-signatures/5407
496
600
  // e(G, S) = e(G, SUM(n)(Si)) = MUL(n)(e(G, Si))
601
+ // TODO: maybe `{message: G2Hex, publicKey: G1Hex}[]` instead?
497
602
  function verifyBatch(
498
603
  signature: G2Hex,
499
- // TODO: maybe `{message: G2Hex, publicKey: G1Hex}[]` instead?
500
604
  messages: G2Hex[],
501
605
  publicKeys: G1Hex[],
502
606
  htfOpts?: htfBasicOpts
@@ -525,33 +629,27 @@ export function bls(CURVE: CurveType): CurveFn {
525
629
  const groupPublicKey = keys.reduce((acc, msg) => acc.add(msg));
526
630
  paired.push({ g1: groupPublicKey, g2: msg });
527
631
  }
528
- paired.push({ g1: G1.ProjectivePoint.BASE.negate(), g2: sig });
632
+ paired.push({ g1: G1.Point.BASE.negate(), g2: sig });
529
633
  return Fp12.eql(pairingBatch(paired), Fp12.ONE);
530
634
  } catch {
531
635
  return false;
532
636
  }
533
637
  }
534
638
 
535
- G1.ProjectivePoint.BASE._setWindowSize(4);
639
+ G1.Point.BASE.precompute(4);
536
640
 
537
641
  return {
538
- getPublicKey,
539
- getPublicKeyForShortSignatures,
540
- sign,
541
- signShortSignature,
542
- verify,
543
- verifyBatch,
544
- verifyShortSignature,
545
- aggregatePublicKeys,
546
- aggregateSignatures,
547
- aggregateShortSignatures,
642
+ longSignatures,
643
+ shortSignatures,
548
644
  millerLoopBatch,
549
645
  pairing,
550
646
  pairingBatch,
551
- G1,
552
- G2,
553
- Signature,
554
- ShortSignature,
647
+ // TODO!!!
648
+ verifyBatch,
649
+ curves: {
650
+ G1: G1_.Point,
651
+ G2: G2_.Point,
652
+ },
555
653
  fields: {
556
654
  Fr,
557
655
  Fp,
@@ -561,10 +659,27 @@ export function bls(CURVE: CurveType): CurveFn {
561
659
  },
562
660
  params: {
563
661
  ateLoopSize: CURVE.params.ateLoopSize,
662
+ twistType: CURVE.params.twistType,
663
+ // deprecated
564
664
  r: CURVE.params.r,
565
665
  G1b: CURVE.G1.b,
566
666
  G2b: CURVE.G2.b,
567
667
  },
568
668
  utils,
669
+
670
+ // deprecated
671
+ getPublicKey,
672
+ getPublicKeyForShortSignatures,
673
+ sign,
674
+ signShortSignature,
675
+ verify,
676
+ verifyShortSignature,
677
+ aggregatePublicKeys,
678
+ aggregateSignatures,
679
+ aggregateShortSignatures,
680
+ G1,
681
+ G2,
682
+ Signature,
683
+ ShortSignature,
569
684
  };
570
685
  }