@noble/curves 2.0.0-beta.1 → 2.0.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +443 -276
- package/abstract/bls.d.ts +17 -17
- package/abstract/bls.d.ts.map +1 -1
- package/abstract/bls.js.map +1 -1
- package/abstract/curve.d.ts +14 -9
- package/abstract/curve.d.ts.map +1 -1
- package/abstract/curve.js +9 -3
- package/abstract/curve.js.map +1 -1
- package/abstract/edwards.d.ts +7 -9
- package/abstract/edwards.d.ts.map +1 -1
- package/abstract/edwards.js +12 -16
- package/abstract/edwards.js.map +1 -1
- package/abstract/hash-to-curve.d.ts +32 -31
- package/abstract/hash-to-curve.d.ts.map +1 -1
- package/abstract/hash-to-curve.js +15 -14
- package/abstract/hash-to-curve.js.map +1 -1
- package/abstract/modular.d.ts.map +1 -1
- package/abstract/modular.js +7 -5
- package/abstract/modular.js.map +1 -1
- package/abstract/montgomery.d.ts +3 -3
- package/abstract/montgomery.d.ts.map +1 -1
- package/abstract/montgomery.js +9 -13
- package/abstract/montgomery.js.map +1 -1
- package/abstract/oprf.d.ts +4 -4
- package/abstract/oprf.d.ts.map +1 -1
- package/abstract/oprf.js +3 -3
- package/abstract/oprf.js.map +1 -1
- package/abstract/poseidon.d.ts.map +1 -1
- package/abstract/poseidon.js +8 -9
- package/abstract/poseidon.js.map +1 -1
- package/abstract/utils.d.ts +74 -1
- package/abstract/utils.d.ts.map +1 -1
- package/abstract/utils.js +67 -17
- package/abstract/utils.js.map +1 -1
- package/abstract/weierstrass.d.ts +66 -20
- package/abstract/weierstrass.d.ts.map +1 -1
- package/abstract/weierstrass.js +72 -68
- package/abstract/weierstrass.js.map +1 -1
- package/bls12-381.d.ts +3 -9
- package/bls12-381.d.ts.map +1 -1
- package/bls12-381.js +3 -14
- package/bls12-381.js.map +1 -1
- package/bn254.d.ts +4 -4
- package/bn254.d.ts.map +1 -1
- package/bn254.js +1 -1
- package/bn254.js.map +1 -1
- package/ed25519.d.ts +22 -18
- package/ed25519.d.ts.map +1 -1
- package/ed25519.js +59 -31
- package/ed25519.js.map +1 -1
- package/ed448.d.ts +17 -8
- package/ed448.d.ts.map +1 -1
- package/ed448.js +69 -52
- package/ed448.js.map +1 -1
- package/index.d.ts +1 -0
- package/index.js +20 -4
- package/index.js.map +1 -1
- package/misc.d.ts.map +1 -1
- package/misc.js +6 -8
- package/misc.js.map +1 -1
- package/nist.d.ts +20 -2
- package/nist.d.ts.map +1 -1
- package/nist.js +30 -10
- package/nist.js.map +1 -1
- package/package.json +34 -37
- package/secp256k1.d.ts +10 -7
- package/secp256k1.d.ts.map +1 -1
- package/secp256k1.js +15 -16
- package/secp256k1.js.map +1 -1
- package/src/abstract/bls.ts +22 -22
- package/src/abstract/curve.ts +19 -5
- package/src/abstract/edwards.ts +20 -23
- package/src/abstract/hash-to-curve.ts +50 -51
- package/src/abstract/modular.ts +7 -5
- package/src/abstract/montgomery.ts +12 -18
- package/src/abstract/oprf.ts +6 -6
- package/src/abstract/poseidon.ts +6 -8
- package/src/abstract/weierstrass.ts +139 -89
- package/src/bls12-381.ts +4 -15
- package/src/bn254.ts +7 -7
- package/src/ed25519.ts +65 -40
- package/src/ed448.ts +87 -69
- package/src/index.ts +19 -3
- package/src/misc.ts +7 -8
- package/src/nist.ts +31 -15
- package/src/secp256k1.ts +16 -18
- package/src/utils.ts +33 -83
- package/src/webcrypto.ts +148 -107
- package/utils.d.ts +5 -21
- package/utils.d.ts.map +1 -1
- package/utils.js +31 -74
- package/utils.js.map +1 -1
- package/webcrypto.d.ts +73 -21
- package/webcrypto.d.ts.map +1 -1
- package/webcrypto.js +101 -76
- package/webcrypto.js.map +1 -1
|
@@ -7,18 +7,18 @@
|
|
|
7
7
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
8
8
|
import type { CHash } from '../utils.ts';
|
|
9
9
|
import {
|
|
10
|
-
_validateObject,
|
|
11
10
|
abytes,
|
|
11
|
+
asafenumber,
|
|
12
12
|
asciiToBytes,
|
|
13
13
|
bytesToNumberBE,
|
|
14
14
|
concatBytes,
|
|
15
15
|
isBytes,
|
|
16
|
-
|
|
16
|
+
validateObject,
|
|
17
17
|
} from '../utils.ts';
|
|
18
18
|
import type { AffinePoint, PC_ANY, PC_F, PC_P } from './curve.ts';
|
|
19
19
|
import { FpInvertBatch, mod, type IField } from './modular.ts';
|
|
20
20
|
|
|
21
|
-
export type
|
|
21
|
+
export type AsciiOrBytes = string | Uint8Array;
|
|
22
22
|
|
|
23
23
|
/**
|
|
24
24
|
* * `DST` is a domain separation tag, defined in section 2.2.5
|
|
@@ -29,7 +29,7 @@ export type UnicodeOrBytes = string | Uint8Array;
|
|
|
29
29
|
* * `hash` conforming to `utils.CHash` interface, with `outputLen` / `blockLen` props
|
|
30
30
|
*/
|
|
31
31
|
export type H2COpts = {
|
|
32
|
-
DST:
|
|
32
|
+
DST: AsciiOrBytes;
|
|
33
33
|
expand: 'xmd' | 'xof';
|
|
34
34
|
hash: CHash;
|
|
35
35
|
p: bigint;
|
|
@@ -40,14 +40,37 @@ export type H2CHashOpts = {
|
|
|
40
40
|
expand: 'xmd' | 'xof';
|
|
41
41
|
hash: CHash;
|
|
42
42
|
};
|
|
43
|
+
export type MapToCurve<T> = (scalar: bigint[]) => AffinePoint<T>;
|
|
44
|
+
|
|
45
|
+
// Separated from initialization opts, so users won't accidentally change per-curve parameters
|
|
46
|
+
// (changing DST is ok!)
|
|
47
|
+
export type H2CDSTOpts = { DST: AsciiOrBytes };
|
|
48
|
+
export type H2CHasherBase<PC extends PC_ANY> = {
|
|
49
|
+
hashToCurve(msg: Uint8Array, options?: H2CDSTOpts): PC_P<PC>;
|
|
50
|
+
hashToScalar(msg: Uint8Array, options?: H2CDSTOpts): bigint;
|
|
51
|
+
deriveToCurve?(msg: Uint8Array, options?: H2CDSTOpts): PC_P<PC>;
|
|
52
|
+
Point: PC;
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* RFC 9380 methods, with cofactor clearing. See https://www.rfc-editor.org/rfc/rfc9380#section-3.
|
|
56
|
+
*
|
|
57
|
+
* * hashToCurve: `map(hash(input))`, encodes RANDOM bytes to curve (WITH hashing)
|
|
58
|
+
* * encodeToCurve: `map(hash(input))`, encodes NON-UNIFORM bytes to curve (WITH hashing)
|
|
59
|
+
* * mapToCurve: `map(scalars)`, encodes NON-UNIFORM scalars to curve (NO hashing)
|
|
60
|
+
*/
|
|
61
|
+
export type H2CHasher<PC extends PC_ANY> = H2CHasherBase<PC> & {
|
|
62
|
+
encodeToCurve(msg: Uint8Array, options?: H2CDSTOpts): PC_P<PC>;
|
|
63
|
+
mapToCurve: MapToCurve<PC_F<PC>>;
|
|
64
|
+
defaults: H2COpts & { encodeDST?: AsciiOrBytes };
|
|
65
|
+
};
|
|
43
66
|
|
|
44
67
|
// Octet Stream to Integer. "spec" implementation of os2ip is 2.5x slower vs bytesToNumberBE.
|
|
45
68
|
const os2ip = bytesToNumberBE;
|
|
46
69
|
|
|
47
70
|
// Integer to Octet Stream (numberToBytesBE)
|
|
48
71
|
function i2osp(value: number, length: number): Uint8Array {
|
|
49
|
-
|
|
50
|
-
|
|
72
|
+
asafenumber(value);
|
|
73
|
+
asafenumber(length);
|
|
51
74
|
if (value < 0 || value >= 1 << (8 * length)) throw new Error('invalid I2OSP input: ' + value);
|
|
52
75
|
const res = Array.from({ length }).fill(0) as number[];
|
|
53
76
|
for (let i = length - 1; i >= 0; i--) {
|
|
@@ -65,13 +88,9 @@ function strxor(a: Uint8Array, b: Uint8Array): Uint8Array {
|
|
|
65
88
|
return arr;
|
|
66
89
|
}
|
|
67
90
|
|
|
68
|
-
function anum(item: unknown): void {
|
|
69
|
-
if (!Number.isSafeInteger(item)) throw new Error('number expected');
|
|
70
|
-
}
|
|
71
|
-
|
|
72
91
|
// User can always use utf8 if they want, by passing Uint8Array.
|
|
73
92
|
// If string is passed, we treat it as ASCII: other formats are likely a mistake.
|
|
74
|
-
function normDST(DST:
|
|
93
|
+
function normDST(DST: AsciiOrBytes): Uint8Array {
|
|
75
94
|
if (!isBytes(DST) && typeof DST !== 'string')
|
|
76
95
|
throw new Error('DST must be Uint8Array or ascii string');
|
|
77
96
|
return typeof DST === 'string' ? asciiToBytes(DST) : DST;
|
|
@@ -83,12 +102,12 @@ function normDST(DST: UnicodeOrBytes): Uint8Array {
|
|
|
83
102
|
*/
|
|
84
103
|
export function expand_message_xmd(
|
|
85
104
|
msg: Uint8Array,
|
|
86
|
-
DST:
|
|
105
|
+
DST: AsciiOrBytes,
|
|
87
106
|
lenInBytes: number,
|
|
88
107
|
H: CHash
|
|
89
108
|
): Uint8Array {
|
|
90
109
|
abytes(msg);
|
|
91
|
-
|
|
110
|
+
asafenumber(lenInBytes);
|
|
92
111
|
DST = normDST(DST);
|
|
93
112
|
// https://www.rfc-editor.org/rfc/rfc9380#section-5.3.3
|
|
94
113
|
if (DST.length > 255) DST = H(concatBytes(asciiToBytes('H2C-OVERSIZE-DST-'), DST));
|
|
@@ -118,13 +137,13 @@ export function expand_message_xmd(
|
|
|
118
137
|
*/
|
|
119
138
|
export function expand_message_xof(
|
|
120
139
|
msg: Uint8Array,
|
|
121
|
-
DST:
|
|
140
|
+
DST: AsciiOrBytes,
|
|
122
141
|
lenInBytes: number,
|
|
123
142
|
k: number,
|
|
124
143
|
H: CHash
|
|
125
144
|
): Uint8Array {
|
|
126
145
|
abytes(msg);
|
|
127
|
-
|
|
146
|
+
asafenumber(lenInBytes);
|
|
128
147
|
DST = normDST(DST);
|
|
129
148
|
// https://www.rfc-editor.org/rfc/rfc9380#section-5.3.3
|
|
130
149
|
// DST = H('H2C-OVERSIZE-DST-' || a_very_long_DST, Math.ceil((lenInBytes * k) / 8));
|
|
@@ -154,16 +173,16 @@ export function expand_message_xof(
|
|
|
154
173
|
* @returns [u_0, ..., u_(count - 1)], a list of field elements.
|
|
155
174
|
*/
|
|
156
175
|
export function hash_to_field(msg: Uint8Array, count: number, options: H2COpts): bigint[][] {
|
|
157
|
-
|
|
176
|
+
validateObject(options, {
|
|
158
177
|
p: 'bigint',
|
|
159
178
|
m: 'number',
|
|
160
179
|
k: 'number',
|
|
161
180
|
hash: 'function',
|
|
162
181
|
});
|
|
163
182
|
const { p, k, m, hash, expand, DST } = options;
|
|
164
|
-
|
|
183
|
+
asafenumber(hash.outputLen, 'valid hash');
|
|
165
184
|
abytes(msg);
|
|
166
|
-
|
|
185
|
+
asafenumber(count);
|
|
167
186
|
const log2p = p.toString(2).length;
|
|
168
187
|
const L = Math.ceil((log2p + k) / 8); // section 5.1 of ietf draft link above
|
|
169
188
|
const len_in_bytes = count * m * L;
|
|
@@ -191,8 +210,8 @@ export function hash_to_field(msg: Uint8Array, count: number, options: H2COpts):
|
|
|
191
210
|
return u;
|
|
192
211
|
}
|
|
193
212
|
|
|
194
|
-
|
|
195
|
-
|
|
213
|
+
type XY<T> = (x: T, y: T) => { x: T; y: T };
|
|
214
|
+
type XYRatio<T> = [T[], T[], T[], T[]]; // xn/xd, yn/yd
|
|
196
215
|
export function isogenyMap<T, F extends IField<T>>(field: F, map: XYRatio<T>): XY<T> {
|
|
197
216
|
// Make same order as in spec
|
|
198
217
|
const coeff = map.map((i) => Array.from(i).reverse());
|
|
@@ -211,38 +230,13 @@ export function isogenyMap<T, F extends IField<T>>(field: F, map: XYRatio<T>): X
|
|
|
211
230
|
};
|
|
212
231
|
}
|
|
213
232
|
|
|
214
|
-
export type MapToCurve<T> = (scalar: bigint[]) => AffinePoint<T>;
|
|
215
|
-
|
|
216
|
-
// Separated from initialization opts, so users won't accidentally change per-curve parameters
|
|
217
|
-
// (changing DST is ok!)
|
|
218
|
-
export type htfBasicOpts = { DST: UnicodeOrBytes };
|
|
219
|
-
export type H2CMethod<P> = (msg: Uint8Array, options?: htfBasicOpts) => P;
|
|
220
|
-
// TODO: remove
|
|
221
|
-
export type H2CHasherBase<P> = {
|
|
222
|
-
hashToCurve: H2CMethod<P>;
|
|
223
|
-
hashToScalar: (msg: Uint8Array, options?: htfBasicOpts) => bigint;
|
|
224
|
-
};
|
|
225
|
-
/**
|
|
226
|
-
* RFC 9380 methods, with cofactor clearing. See https://www.rfc-editor.org/rfc/rfc9380#section-3.
|
|
227
|
-
*
|
|
228
|
-
* * hashToCurve: `map(hash(input))`, encodes RANDOM bytes to curve (WITH hashing)
|
|
229
|
-
* * encodeToCurve: `map(hash(input))`, encodes NON-UNIFORM bytes to curve (WITH hashing)
|
|
230
|
-
* * mapToCurve: `map(scalars)`, encodes NON-UNIFORM scalars to curve (NO hashing)
|
|
231
|
-
*/
|
|
232
|
-
export type H2CHasher<PC extends PC_ANY> = H2CHasherBase<PC_P<PC>> & {
|
|
233
|
-
Point: PC;
|
|
234
|
-
encodeToCurve: H2CMethod<PC_P<PC>>;
|
|
235
|
-
mapToCurve: MapToCurve<PC_F<PC>>;
|
|
236
|
-
defaults: H2COpts & { encodeDST?: UnicodeOrBytes };
|
|
237
|
-
};
|
|
238
|
-
|
|
239
233
|
export const _DST_scalar: Uint8Array = asciiToBytes('HashToScalar-');
|
|
240
234
|
|
|
241
235
|
/** Creates hash-to-curve methods from EC Point and mapToCurve function. See {@link H2CHasher}. */
|
|
242
236
|
export function createHasher<PC extends PC_ANY>(
|
|
243
237
|
Point: PC,
|
|
244
238
|
mapToCurve: MapToCurve<PC_F<PC>>,
|
|
245
|
-
defaults: H2COpts & { encodeDST?:
|
|
239
|
+
defaults: H2COpts & { encodeDST?: AsciiOrBytes }
|
|
246
240
|
): H2CHasher<PC> {
|
|
247
241
|
if (typeof mapToCurve !== 'function') throw new Error('mapToCurve() must be defined');
|
|
248
242
|
function map(num: bigint[]): PC_P<PC> {
|
|
@@ -256,17 +250,17 @@ export function createHasher<PC extends PC_ANY>(
|
|
|
256
250
|
}
|
|
257
251
|
|
|
258
252
|
return {
|
|
259
|
-
defaults,
|
|
253
|
+
defaults: Object.freeze(defaults),
|
|
260
254
|
Point,
|
|
261
255
|
|
|
262
|
-
hashToCurve(msg: Uint8Array, options?:
|
|
256
|
+
hashToCurve(msg: Uint8Array, options?: H2CDSTOpts): PC_P<PC> {
|
|
263
257
|
const opts = Object.assign({}, defaults, options);
|
|
264
258
|
const u = hash_to_field(msg, 2, opts);
|
|
265
259
|
const u0 = map(u[0]);
|
|
266
260
|
const u1 = map(u[1]);
|
|
267
261
|
return clear(u0.add(u1) as PC_P<PC>);
|
|
268
262
|
},
|
|
269
|
-
encodeToCurve(msg: Uint8Array, options?:
|
|
263
|
+
encodeToCurve(msg: Uint8Array, options?: H2CDSTOpts): PC_P<PC> {
|
|
270
264
|
const optsDst = defaults.encodeDST ? { DST: defaults.encodeDST } : {};
|
|
271
265
|
const opts = Object.assign({}, defaults, optsDst, options);
|
|
272
266
|
const u = hash_to_field(msg, 1, opts);
|
|
@@ -274,7 +268,12 @@ export function createHasher<PC extends PC_ANY>(
|
|
|
274
268
|
return clear(u0);
|
|
275
269
|
},
|
|
276
270
|
/** See {@link H2CHasher} */
|
|
277
|
-
mapToCurve(scalars: bigint[]): PC_P<PC> {
|
|
271
|
+
mapToCurve(scalars: bigint | bigint[]): PC_P<PC> {
|
|
272
|
+
// Curves with m=1 accept only single scalar
|
|
273
|
+
if (defaults.m === 1) {
|
|
274
|
+
if (typeof scalars !== 'bigint') throw new Error('expected bigint (m=1)');
|
|
275
|
+
return clear(map([scalars]));
|
|
276
|
+
}
|
|
278
277
|
if (!Array.isArray(scalars)) throw new Error('expected array of bigints');
|
|
279
278
|
for (const i of scalars)
|
|
280
279
|
if (typeof i !== 'bigint') throw new Error('expected array of bigints');
|
|
@@ -283,7 +282,7 @@ export function createHasher<PC extends PC_ANY>(
|
|
|
283
282
|
|
|
284
283
|
// hash_to_scalar can produce 0: https://www.rfc-editor.org/errata/eid8393
|
|
285
284
|
// RFC 9380, draft-irtf-cfrg-bbs-signatures-08
|
|
286
|
-
hashToScalar(msg: Uint8Array, options?:
|
|
285
|
+
hashToScalar(msg: Uint8Array, options?: H2CDSTOpts): bigint {
|
|
287
286
|
// @ts-ignore
|
|
288
287
|
const N = Point.Fn.ORDER;
|
|
289
288
|
const opts = Object.assign({}, defaults, { p: N, m: 1, DST: _DST_scalar }, options);
|
package/src/abstract/modular.ts
CHANGED
|
@@ -6,21 +6,23 @@
|
|
|
6
6
|
*/
|
|
7
7
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
8
8
|
import {
|
|
9
|
-
_validateObject,
|
|
10
9
|
abytes,
|
|
11
10
|
anumber,
|
|
12
11
|
bytesToNumberBE,
|
|
13
12
|
bytesToNumberLE,
|
|
14
13
|
numberToBytesBE,
|
|
15
14
|
numberToBytesLE,
|
|
15
|
+
validateObject,
|
|
16
16
|
} from '../utils.ts';
|
|
17
17
|
|
|
18
|
+
// Numbers aren't used in x25519 / x448 builds
|
|
18
19
|
// prettier-ignore
|
|
19
|
-
const _0n =
|
|
20
|
+
const _0n = /* @__PURE__ */ BigInt(0), _1n = /* @__PURE__ */ BigInt(1), _2n = /* @__PURE__ */ BigInt(2);
|
|
20
21
|
// prettier-ignore
|
|
21
|
-
const
|
|
22
|
+
const _3n = /* @__PURE__ */ BigInt(3), _4n = /* @__PURE__ */ BigInt(4), _5n = /* @__PURE__ */ BigInt(5);
|
|
22
23
|
// prettier-ignore
|
|
23
|
-
const
|
|
24
|
+
const _7n = /* @__PURE__ */ BigInt(7), _8n = /* @__PURE__ */ BigInt(8), _9n = /* @__PURE__ */ BigInt(9);
|
|
25
|
+
const _16n = /* @__PURE__ */ BigInt(16);
|
|
24
26
|
|
|
25
27
|
// Calculates a modulo b
|
|
26
28
|
export function mod(a: bigint, b: bigint): bigint {
|
|
@@ -281,7 +283,7 @@ export function validateField<T>(field: IField<T>): IField<T> {
|
|
|
281
283
|
map[val] = 'function';
|
|
282
284
|
return map;
|
|
283
285
|
}, initial);
|
|
284
|
-
|
|
286
|
+
validateObject(field, opts);
|
|
285
287
|
// const max = 16384;
|
|
286
288
|
// if (field.BYTES < 1 || field.BYTES > max) throw new Error('invalid field');
|
|
287
289
|
// if (field.BITS < 1 || field.BITS > 8 * max) throw new Error('invalid field');
|
|
@@ -6,23 +6,23 @@
|
|
|
6
6
|
*/
|
|
7
7
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
8
8
|
import {
|
|
9
|
-
_validateObject,
|
|
10
9
|
abytes,
|
|
11
10
|
aInRange,
|
|
12
11
|
bytesToNumberLE,
|
|
13
12
|
copyBytes,
|
|
14
13
|
numberToBytesLE,
|
|
15
14
|
randomBytes,
|
|
15
|
+
validateObject,
|
|
16
16
|
type CryptoKeys,
|
|
17
17
|
} from '../utils.ts';
|
|
18
|
-
import type
|
|
18
|
+
import { createKeygen, type CurveLengths } from './curve.ts';
|
|
19
19
|
import { mod } from './modular.ts';
|
|
20
20
|
|
|
21
21
|
const _0n = BigInt(0);
|
|
22
22
|
const _1n = BigInt(1);
|
|
23
23
|
const _2n = BigInt(2);
|
|
24
24
|
|
|
25
|
-
export type
|
|
25
|
+
export type MontgomeryOpts = {
|
|
26
26
|
P: bigint; // finite field prime
|
|
27
27
|
type: 'x25519' | 'x448';
|
|
28
28
|
adjustScalarBytes: (bytes: Uint8Array) => Uint8Array;
|
|
@@ -43,15 +43,15 @@ export type MontgomeryECDH = {
|
|
|
43
43
|
keygen: (seed?: Uint8Array) => { secretKey: Uint8Array; publicKey: Uint8Array };
|
|
44
44
|
};
|
|
45
45
|
|
|
46
|
-
function validateOpts(curve:
|
|
47
|
-
|
|
46
|
+
function validateOpts(curve: MontgomeryOpts) {
|
|
47
|
+
validateObject(curve, {
|
|
48
48
|
adjustScalarBytes: 'function',
|
|
49
49
|
powPminus2: 'function',
|
|
50
50
|
});
|
|
51
51
|
return Object.freeze({ ...curve } as const);
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
export function montgomery(curveDef:
|
|
54
|
+
export function montgomery(curveDef: MontgomeryOpts): MontgomeryECDH {
|
|
55
55
|
const CURVE = validateOpts(curveDef);
|
|
56
56
|
const { P, type, adjustScalarBytes, powPminus2, randomBytes: rand } = CURVE;
|
|
57
57
|
const is25519 = type === 'x25519';
|
|
@@ -105,6 +105,8 @@ export function montgomery(curveDef: CurveType): MontgomeryECDH {
|
|
|
105
105
|
function scalarMultBase(scalar: Uint8Array): Uint8Array {
|
|
106
106
|
return scalarMult(scalar, GuBytes);
|
|
107
107
|
}
|
|
108
|
+
const getPublicKey = scalarMultBase;
|
|
109
|
+
const getSharedSecret = scalarMult;
|
|
108
110
|
|
|
109
111
|
// cswap from RFC7748 "example code"
|
|
110
112
|
function cswap(swap: bigint, x_2: bigint, x_3: bigint): { x_2: bigint; x_3: bigint } {
|
|
@@ -170,20 +172,12 @@ export function montgomery(curveDef: CurveType): MontgomeryECDH {
|
|
|
170
172
|
abytes(seed, lengths.seed, 'seed');
|
|
171
173
|
return seed;
|
|
172
174
|
};
|
|
173
|
-
|
|
174
|
-
const secretKey = randomSecretKey(seed);
|
|
175
|
-
return { secretKey, publicKey: scalarMultBase(secretKey) };
|
|
176
|
-
}
|
|
177
|
-
const utils = {
|
|
178
|
-
randomSecretKey,
|
|
179
|
-
randomPrivateKey: randomSecretKey,
|
|
180
|
-
};
|
|
175
|
+
const utils = { randomSecretKey };
|
|
181
176
|
|
|
182
177
|
return Object.freeze({
|
|
183
|
-
keygen,
|
|
184
|
-
getSharedSecret
|
|
185
|
-
|
|
186
|
-
getPublicKey: (secretKey: Uint8Array): Uint8Array => scalarMultBase(secretKey),
|
|
178
|
+
keygen: createKeygen(randomSecretKey, getPublicKey),
|
|
179
|
+
getSharedSecret,
|
|
180
|
+
getPublicKey,
|
|
187
181
|
scalarMult,
|
|
188
182
|
scalarMultBase,
|
|
189
183
|
utils,
|
package/src/abstract/oprf.ts
CHANGED
|
@@ -60,8 +60,8 @@ import {
|
|
|
60
60
|
validateObject,
|
|
61
61
|
} from '../utils.ts';
|
|
62
62
|
import { pippenger, type CurvePoint, type CurvePointCons } from './curve.ts';
|
|
63
|
-
import { _DST_scalar, type
|
|
64
|
-
import { getMinHashLength, mapHashToField } from './modular.
|
|
63
|
+
import { _DST_scalar, type H2CDSTOpts } from './hash-to-curve.ts';
|
|
64
|
+
import { getMinHashLength, mapHashToField } from './modular.ts';
|
|
65
65
|
|
|
66
66
|
// OPRF is designed to be used across network, so we default to serialized values.
|
|
67
67
|
export type PointBytes = Uint8Array;
|
|
@@ -73,9 +73,9 @@ export type OPRFOpts<P extends CurvePoint<any, P>> = {
|
|
|
73
73
|
name: string;
|
|
74
74
|
Point: CurvePointCons<P>; // we don't return Point, so we need generic interface only
|
|
75
75
|
// Fn: IField<bigint>;
|
|
76
|
-
hash
|
|
77
|
-
hashToScalar
|
|
78
|
-
hashToGroup
|
|
76
|
+
hash(msg: Bytes): Bytes;
|
|
77
|
+
hashToScalar(msg: Uint8Array, options: H2CDSTOpts): bigint;
|
|
78
|
+
hashToGroup(msg: Uint8Array, options: H2CDSTOpts): P;
|
|
79
79
|
};
|
|
80
80
|
|
|
81
81
|
export type OPRFKeys = { secretKey: ScalarBytes; publicKey: PointBytes };
|
|
@@ -433,7 +433,7 @@ export function createORPF<P extends CurvePoint<any, P>>(opts: OPRFOpts<P>): OPR
|
|
|
433
433
|
|
|
434
434
|
function deriveKeyPair(ctx: Bytes, seed: Bytes, info: Bytes) {
|
|
435
435
|
const dst = concatBytes(asciiToBytes('DeriveKeyPair'), ctx);
|
|
436
|
-
const msg = concatBytes(seed, encode(info),
|
|
436
|
+
const msg = concatBytes(seed, encode(info), Uint8Array.of(0));
|
|
437
437
|
for (let counter = 0; counter <= 255; counter++) {
|
|
438
438
|
msg[msg.length - 1] = counter;
|
|
439
439
|
const skS = opts.hashToScalar(msg, { DST: dst });
|
package/src/abstract/poseidon.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* @module
|
|
8
8
|
*/
|
|
9
9
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
10
|
-
import {
|
|
10
|
+
import { asafenumber, bitGet, validateObject } from '../utils.ts';
|
|
11
11
|
import { FpInvertBatch, FpPow, type IField, validateField } from './modular.ts';
|
|
12
12
|
|
|
13
13
|
// Grain LFSR (Linear-Feedback Shift Register): https://eprint.iacr.org/2009/109.pdf
|
|
@@ -44,7 +44,7 @@ export type PoseidonBasicOpts = {
|
|
|
44
44
|
function assertValidPosOpts(opts: PoseidonBasicOpts) {
|
|
45
45
|
const { Fp, roundsFull } = opts;
|
|
46
46
|
validateField(Fp);
|
|
47
|
-
|
|
47
|
+
validateObject(
|
|
48
48
|
opts,
|
|
49
49
|
{
|
|
50
50
|
t: 'number',
|
|
@@ -55,8 +55,9 @@ function assertValidPosOpts(opts: PoseidonBasicOpts) {
|
|
|
55
55
|
isSboxInverse: 'boolean',
|
|
56
56
|
}
|
|
57
57
|
);
|
|
58
|
-
for (const
|
|
59
|
-
|
|
58
|
+
for (const k of ['t', 'roundsFull', 'roundsPartial'] as const) {
|
|
59
|
+
asafenumber(opts[k], k);
|
|
60
|
+
if (opts[k] < 1) throw new Error('invalid number ' + k);
|
|
60
61
|
}
|
|
61
62
|
if (roundsFull & 1) throw new Error('roundsFull is not even' + roundsFull);
|
|
62
63
|
}
|
|
@@ -322,10 +323,7 @@ export type PoseidonSpongeOpts = Omit<PoseidonOpts, 't'> & {
|
|
|
322
323
|
* - https://github.com/arkworks-rs/crypto-primitives/tree/main
|
|
323
324
|
*/
|
|
324
325
|
export function poseidonSponge(opts: PoseidonSpongeOpts): () => PoseidonSponge {
|
|
325
|
-
for (const
|
|
326
|
-
if (typeof opts[i] !== 'number' || !Number.isSafeInteger(opts[i]))
|
|
327
|
-
throw new Error('invalid number ' + i);
|
|
328
|
-
}
|
|
326
|
+
for (const k of ['rate', 'capacity'] as const) asafenumber(opts[k], k);
|
|
329
327
|
const { rate, capacity } = opts;
|
|
330
328
|
const t = opts.rate + opts.capacity;
|
|
331
329
|
// Re-use hash instance between multiple instances
|