@noble/curves 0.7.2 → 0.7.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 +24 -9
- package/abstract/hash-to-curve.d.ts +13 -4
- package/abstract/hash-to-curve.d.ts.map +1 -1
- package/abstract/hash-to-curve.js +28 -25
- package/abstract/hash-to-curve.js.map +1 -1
- package/esm/abstract/hash-to-curve.js +29 -26
- package/esm/abstract/hash-to-curve.js.map +1 -1
- package/package.json +1 -1
- package/src/abstract/hash-to-curve.ts +39 -38
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@ Audited & minimal JS implementation of elliptic curve cryptography.
|
|
|
5
5
|
- **noble** family, zero dependencies
|
|
6
6
|
- Short Weierstrass, Edwards, Montgomery curves
|
|
7
7
|
- ECDSA, EdDSA, Schnorr, BLS signature schemes, ECDH key agreement
|
|
8
|
-
- #️⃣ [hash to curve](
|
|
8
|
+
- #️⃣ [hash to curve](#abstracthash-to-curve-hashing-strings-to-curve-points)
|
|
9
9
|
for encoding or hashing an arbitrary string to an elliptic curve point
|
|
10
10
|
- 🧜♂️ [Poseidon](https://www.poseidon-hash.info) ZK-friendly hash
|
|
11
11
|
- 🏎 [Ultra-fast](#speed), hand-optimized for caveats of JS engines
|
|
@@ -470,7 +470,7 @@ const x25519 = montgomery({
|
|
|
470
470
|
|
|
471
471
|
### abstract/hash-to-curve: Hashing strings to curve points
|
|
472
472
|
|
|
473
|
-
The module allows to hash arbitrary strings to elliptic curve points. Implements [hash-to-curve
|
|
473
|
+
The module allows to hash arbitrary strings to elliptic curve points. Implements [hash-to-curve v16](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-16).
|
|
474
474
|
|
|
475
475
|
Every curve has exported `hashToCurve` and `encodeToCurve` methods:
|
|
476
476
|
|
|
@@ -481,7 +481,6 @@ hashToCurve('0102abcd');
|
|
|
481
481
|
console.log(hashToCurve(randomBytes()));
|
|
482
482
|
console.log(encodeToCurve(randomBytes()));
|
|
483
483
|
|
|
484
|
-
|
|
485
484
|
import { bls12_381 } from '@noble/curves/bls12-381';
|
|
486
485
|
bls12_381.G1.hashToCurve(randomBytes(), { DST: 'another' });
|
|
487
486
|
bls12_381.G2.hashToCurve(randomBytes(), { DST: 'custom' });
|
|
@@ -491,6 +490,8 @@ If you need low-level methods from spec:
|
|
|
491
490
|
|
|
492
491
|
`expand_message_xmd` [(spec)](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-11#section-5.4.1) produces a uniformly random byte string using a cryptographic hash function H that outputs b bits.
|
|
493
492
|
|
|
493
|
+
Hash must conform to `CHash` interface (see [weierstrass section](#abstractweierstrass-short-weierstrass-curve)).
|
|
494
|
+
|
|
494
495
|
```ts
|
|
495
496
|
function expand_message_xmd(
|
|
496
497
|
msg: Uint8Array,
|
|
@@ -509,13 +510,18 @@ function expand_message_xof(
|
|
|
509
510
|
|
|
510
511
|
`hash_to_field(msg, count, options)` [(spec)](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-11#section-5.3)
|
|
511
512
|
hashes arbitrary-length byte strings to a list of one or more elements of a finite field F.
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
513
|
+
|
|
514
|
+
- `msg` a byte string containing the message to hash
|
|
515
|
+
- `count` the number of elements of F to output
|
|
516
|
+
- `options` `{DST: string, p: bigint, m: number, k: number, expand: 'xmd' | 'xof', hash: H}`.
|
|
517
|
+
- `p` is field prime, m=field extension (1 for prime fields)
|
|
518
|
+
- `k` is security target in bits (e.g. 128).
|
|
519
|
+
- `expand` should be `xmd` for SHA2, SHA3, BLAKE; `xof` for SHAKE, BLAKE-XOF
|
|
520
|
+
- `hash` conforming to `utils.CHash` interface, with `outputLen` / `blockLen` props
|
|
521
|
+
- Returns `[u_0, ..., u_(count - 1)]`, a list of field elements.
|
|
516
522
|
|
|
517
523
|
```ts
|
|
518
|
-
function hash_to_field(msg: Uint8Array, count: number, options:
|
|
524
|
+
function hash_to_field(msg: Uint8Array, count: number, options: Opts): bigint[][];
|
|
519
525
|
```
|
|
520
526
|
|
|
521
527
|
### abstract/poseidon: Poseidon hash
|
|
@@ -586,7 +592,6 @@ const derived = hkdf(sha256, someKey, undefined, 'application', 40); // 40 bytes
|
|
|
586
592
|
const validPrivateKey = mod.hashToPrivateScalar(derived, p256.CURVE.n);
|
|
587
593
|
```
|
|
588
594
|
|
|
589
|
-
|
|
590
595
|
### abstract/utils: General utilities
|
|
591
596
|
|
|
592
597
|
```ts
|
|
@@ -692,6 +697,16 @@ aggregatePublicKeys/128 x 7 ops/sec @ 125ms/op
|
|
|
692
697
|
aggregateSignatures/8 x 45 ops/sec @ 22ms/op
|
|
693
698
|
aggregateSignatures/32 x 11 ops/sec @ 84ms/op
|
|
694
699
|
aggregateSignatures/128 x 3 ops/sec @ 332ms/opp
|
|
700
|
+
|
|
701
|
+
hash-to-curve
|
|
702
|
+
hash_to_field x 850,340 ops/sec @ 1μs/op
|
|
703
|
+
hashToCurve
|
|
704
|
+
├─secp256k1 x 1,850 ops/sec @ 540μs/op
|
|
705
|
+
├─P256 x 3,352 ops/sec @ 298μs/op
|
|
706
|
+
├─P384 x 1,367 ops/sec @ 731μs/op
|
|
707
|
+
├─P521 x 691 ops/sec @ 1ms/op
|
|
708
|
+
├─ed25519 x 2,492 ops/sec @ 401μs/op
|
|
709
|
+
└─ed448 x 1,045 ops/sec @ 956μs/op
|
|
695
710
|
```
|
|
696
711
|
|
|
697
712
|
## Resources
|
|
@@ -2,9 +2,16 @@
|
|
|
2
2
|
import type { Group, GroupConstructor, AffinePoint } from './curve.js';
|
|
3
3
|
import { Field } from './modular.js';
|
|
4
4
|
import { CHash } from './utils.js';
|
|
5
|
+
/**
|
|
6
|
+
* * `DST` is a domain separation tag, defined in section 2.2.5
|
|
7
|
+
* * `p` characteristic of F, where F is a finite field of characteristic p and order q = p^m
|
|
8
|
+
* * `m` is extension degree (1 for prime fields)
|
|
9
|
+
* * `k` is the target security target in bits (e.g. 128), from section 5.1
|
|
10
|
+
* * `expand` is `xmd` (SHA2, SHA3, BLAKE) or `xof` (SHAKE, BLAKE-XOF)
|
|
11
|
+
* * `hash` conforming to `utils.CHash` interface, with `outputLen` / `blockLen` props
|
|
12
|
+
*/
|
|
5
13
|
export declare type Opts = {
|
|
6
|
-
DST: string;
|
|
7
|
-
encodeDST: string;
|
|
14
|
+
DST: string | Uint8Array;
|
|
8
15
|
p: bigint;
|
|
9
16
|
m: number;
|
|
10
17
|
k: number;
|
|
@@ -18,7 +25,7 @@ export declare function expand_message_xof(msg: Uint8Array, DST: Uint8Array, len
|
|
|
18
25
|
* https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-11#section-5.3
|
|
19
26
|
* @param msg a byte string containing the message to hash
|
|
20
27
|
* @param count the number of elements of F to output
|
|
21
|
-
* @param options `{DST: string, p: bigint, m: number, k: number, expand: 'xmd' | 'xof', hash: H}
|
|
28
|
+
* @param options `{DST: string, p: bigint, m: number, k: number, expand: 'xmd' | 'xof', hash: H}`, see above
|
|
22
29
|
* @returns [u_0, ..., u_(count - 1)], a list of field elements.
|
|
23
30
|
*/
|
|
24
31
|
export declare function hash_to_field(msg: Uint8Array, count: number, options: Opts): bigint[][];
|
|
@@ -39,7 +46,9 @@ export declare type MapToCurve<T> = (scalar: bigint[]) => AffinePoint<T>;
|
|
|
39
46
|
export declare type htfBasicOpts = {
|
|
40
47
|
DST: string;
|
|
41
48
|
};
|
|
42
|
-
export declare function createHasher<T>(Point: H2CPointConstructor<T>, mapToCurve: MapToCurve<T>, def: Opts
|
|
49
|
+
export declare function createHasher<T>(Point: H2CPointConstructor<T>, mapToCurve: MapToCurve<T>, def: Opts & {
|
|
50
|
+
encodeDST?: string;
|
|
51
|
+
}): {
|
|
43
52
|
hashToCurve(msg: Uint8Array, options?: htfBasicOpts): H2CPoint<T>;
|
|
44
53
|
encodeToCurve(msg: Uint8Array, options?: htfBasicOpts): H2CPoint<T>;
|
|
45
54
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hash-to-curve.d.ts","sourceRoot":"","sources":["../src/abstract/hash-to-curve.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,OAAO,KAAK,EAAE,KAAK,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACvE,OAAO,EAAO,KAAK,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,
|
|
1
|
+
{"version":3,"file":"hash-to-curve.d.ts","sourceRoot":"","sources":["../src/abstract/hash-to-curve.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,OAAO,KAAK,EAAE,KAAK,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACvE,OAAO,EAAO,KAAK,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAmB,KAAK,EAA4C,MAAM,YAAY,CAAC;AAE9F;;;;;;;GAOG;AACH,oBAAY,IAAI,GAAG;IACjB,GAAG,EAAE,MAAM,GAAG,UAAU,CAAC;IACzB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,MAAM,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;IACvB,IAAI,EAAE,KAAK,CAAC;CACb,CAAC;AAyCF,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,UAAU,EACf,GAAG,EAAE,UAAU,EACf,UAAU,EAAE,MAAM,EAClB,CAAC,EAAE,KAAK,GACP,UAAU,CAqBZ;AAED,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,UAAU,EACf,GAAG,EAAE,UAAU,EACf,UAAU,EAAE,MAAM,EAClB,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,KAAK,GACP,UAAU,CAqBZ;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,GAAG,MAAM,EAAE,EAAE,CA6BvF;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,OAGxE,CAAC,KAAK,CAAC;;;EAQnB;AAED,MAAM,WAAW,QAAQ,CAAC,CAAC,CAAE,SAAQ,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IACrD,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IACnC,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;IACtC,aAAa,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAC;IAC7B,cAAc,IAAI,IAAI,CAAC;CACxB;AAED,MAAM,WAAW,mBAAmB,CAAC,CAAC,CAAE,SAAQ,gBAAgB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAC3E,UAAU,CAAC,EAAE,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;CAC7C;AAED,oBAAY,UAAU,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,WAAW,CAAC,CAAC,CAAC,CAAC;AAIjE,oBAAY,YAAY,GAAG;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC;AAE3C,wBAAgB,YAAY,CAAC,CAAC,EAC5B,KAAK,EAAE,mBAAmB,CAAC,CAAC,CAAC,EAC7B,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,EACzB,GAAG,EAAE,IAAI,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE;qBAaf,UAAU,YAAY,YAAY;uBAUhC,UAAU,YAAY,YAAY;EAOxD"}
|
|
@@ -3,16 +3,16 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.createHasher = exports.isogenyMap = exports.hash_to_field = exports.expand_message_xof = exports.expand_message_xmd = void 0;
|
|
4
4
|
const modular_js_1 = require("./modular.js");
|
|
5
5
|
const utils_js_1 = require("./utils.js");
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
13
|
-
return result;
|
|
6
|
+
function validateDST(dst) {
|
|
7
|
+
if (dst instanceof Uint8Array)
|
|
8
|
+
return dst;
|
|
9
|
+
if (typeof dst === 'string')
|
|
10
|
+
return (0, utils_js_1.utf8ToBytes)(dst);
|
|
11
|
+
throw new Error('DST must be Uint8Array or string');
|
|
14
12
|
}
|
|
15
|
-
//
|
|
13
|
+
// Octet Stream to Integer. "spec" implementation of os2ip is 2.5x slower vs bytesToNumberBE.
|
|
14
|
+
const os2ip = utils_js_1.bytesToNumberBE;
|
|
15
|
+
// Integer to Octet Stream (numberToBytesBE)
|
|
16
16
|
function i2osp(value, length) {
|
|
17
17
|
if (value < 0 || value >= 1 << (8 * length)) {
|
|
18
18
|
throw new Error(`bad I2OSP call: value=${value} length=${length}`);
|
|
@@ -48,14 +48,13 @@ function expand_message_xmd(msg, DST, lenInBytes, H) {
|
|
|
48
48
|
// https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-16#section-5.3.3
|
|
49
49
|
if (DST.length > 255)
|
|
50
50
|
DST = H((0, utils_js_1.concatBytes)((0, utils_js_1.utf8ToBytes)('H2C-OVERSIZE-DST-'), DST));
|
|
51
|
-
const b_in_bytes = H
|
|
52
|
-
const r_in_bytes = H.blockLen;
|
|
51
|
+
const { outputLen: b_in_bytes, blockLen: r_in_bytes } = H;
|
|
53
52
|
const ell = Math.ceil(lenInBytes / b_in_bytes);
|
|
54
53
|
if (ell > 255)
|
|
55
54
|
throw new Error('Invalid xmd length');
|
|
56
55
|
const DST_prime = (0, utils_js_1.concatBytes)(DST, i2osp(DST.length, 1));
|
|
57
56
|
const Z_pad = i2osp(0, r_in_bytes);
|
|
58
|
-
const l_i_b_str = i2osp(lenInBytes, 2);
|
|
57
|
+
const l_i_b_str = i2osp(lenInBytes, 2); // len_in_bytes_str
|
|
59
58
|
const b = new Array(ell);
|
|
60
59
|
const b_0 = H((0, utils_js_1.concatBytes)(Z_pad, msg, l_i_b_str, i2osp(0, 1), DST_prime));
|
|
61
60
|
b[0] = H((0, utils_js_1.concatBytes)(b_0, i2osp(1, 1), DST_prime));
|
|
@@ -93,30 +92,36 @@ exports.expand_message_xof = expand_message_xof;
|
|
|
93
92
|
* https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-11#section-5.3
|
|
94
93
|
* @param msg a byte string containing the message to hash
|
|
95
94
|
* @param count the number of elements of F to output
|
|
96
|
-
* @param options `{DST: string, p: bigint, m: number, k: number, expand: 'xmd' | 'xof', hash: H}
|
|
95
|
+
* @param options `{DST: string, p: bigint, m: number, k: number, expand: 'xmd' | 'xof', hash: H}`, see above
|
|
97
96
|
* @returns [u_0, ..., u_(count - 1)], a list of field elements.
|
|
98
97
|
*/
|
|
99
98
|
function hash_to_field(msg, count, options) {
|
|
100
99
|
const { p, k, m, hash, expand, DST: _DST } = options;
|
|
101
100
|
isBytes(msg);
|
|
102
101
|
isNum(count);
|
|
103
|
-
|
|
104
|
-
throw new Error('DST must be valid');
|
|
102
|
+
const DST = validateDST(_DST);
|
|
105
103
|
const log2p = p.toString(2).length;
|
|
106
104
|
const L = Math.ceil((log2p + k) / 8); // section 5.1 of ietf draft link above
|
|
107
105
|
const len_in_bytes = count * m * L;
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
106
|
+
let prb; // pseudo_random_bytes
|
|
107
|
+
if (expand === 'xmd') {
|
|
108
|
+
prb = expand_message_xmd(msg, DST, len_in_bytes, hash);
|
|
109
|
+
}
|
|
110
|
+
else if (expand === 'xof') {
|
|
111
|
+
prb = expand_message_xof(msg, DST, len_in_bytes, k, hash);
|
|
112
|
+
}
|
|
113
|
+
else if (expand === undefined) {
|
|
114
|
+
prb = msg;
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
throw new Error('expand must be "xmd", "xof" or undefined');
|
|
118
|
+
}
|
|
114
119
|
const u = new Array(count);
|
|
115
120
|
for (let i = 0; i < count; i++) {
|
|
116
121
|
const e = new Array(m);
|
|
117
122
|
for (let j = 0; j < m; j++) {
|
|
118
123
|
const elm_offset = L * (j + i * m);
|
|
119
|
-
const tv =
|
|
124
|
+
const tv = prb.subarray(elm_offset, elm_offset + L);
|
|
120
125
|
e[j] = (0, modular_js_1.mod)(os2ip(tv), p);
|
|
121
126
|
}
|
|
122
127
|
u[i] = e;
|
|
@@ -143,10 +148,8 @@ function createHasher(Point, mapToCurve, def) {
|
|
|
143
148
|
k: 'isSafeInteger',
|
|
144
149
|
hash: 'hash',
|
|
145
150
|
});
|
|
146
|
-
if (def.expand !== 'xmd' && def.expand !== 'xof' && def.expand !== undefined)
|
|
147
|
-
throw new Error('Invalid htf/expand');
|
|
148
151
|
if (typeof mapToCurve !== 'function')
|
|
149
|
-
throw new Error('
|
|
152
|
+
throw new Error('mapToCurve() must be defined');
|
|
150
153
|
return {
|
|
151
154
|
// Encodes byte string to elliptic curve
|
|
152
155
|
// https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-11#section-3
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hash-to-curve.js","sourceRoot":"","sources":["../src/abstract/hash-to-curve.ts"],"names":[],"mappings":";;;AAEA,6CAA0C;AAC1C,
|
|
1
|
+
{"version":3,"file":"hash-to-curve.js","sourceRoot":"","sources":["../src/abstract/hash-to-curve.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { mod } from './modular.js';
|
|
2
|
-
import { concatBytes, utf8ToBytes, validateObject } from './utils.js';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}
|
|
10
|
-
return result;
|
|
2
|
+
import { bytesToNumberBE, concatBytes, utf8ToBytes, validateObject } from './utils.js';
|
|
3
|
+
function validateDST(dst) {
|
|
4
|
+
if (dst instanceof Uint8Array)
|
|
5
|
+
return dst;
|
|
6
|
+
if (typeof dst === 'string')
|
|
7
|
+
return utf8ToBytes(dst);
|
|
8
|
+
throw new Error('DST must be Uint8Array or string');
|
|
11
9
|
}
|
|
12
|
-
//
|
|
10
|
+
// Octet Stream to Integer. "spec" implementation of os2ip is 2.5x slower vs bytesToNumberBE.
|
|
11
|
+
const os2ip = bytesToNumberBE;
|
|
12
|
+
// Integer to Octet Stream (numberToBytesBE)
|
|
13
13
|
function i2osp(value, length) {
|
|
14
14
|
if (value < 0 || value >= 1 << (8 * length)) {
|
|
15
15
|
throw new Error(`bad I2OSP call: value=${value} length=${length}`);
|
|
@@ -45,14 +45,13 @@ export function expand_message_xmd(msg, DST, lenInBytes, H) {
|
|
|
45
45
|
// https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-16#section-5.3.3
|
|
46
46
|
if (DST.length > 255)
|
|
47
47
|
DST = H(concatBytes(utf8ToBytes('H2C-OVERSIZE-DST-'), DST));
|
|
48
|
-
const b_in_bytes = H
|
|
49
|
-
const r_in_bytes = H.blockLen;
|
|
48
|
+
const { outputLen: b_in_bytes, blockLen: r_in_bytes } = H;
|
|
50
49
|
const ell = Math.ceil(lenInBytes / b_in_bytes);
|
|
51
50
|
if (ell > 255)
|
|
52
51
|
throw new Error('Invalid xmd length');
|
|
53
52
|
const DST_prime = concatBytes(DST, i2osp(DST.length, 1));
|
|
54
53
|
const Z_pad = i2osp(0, r_in_bytes);
|
|
55
|
-
const l_i_b_str = i2osp(lenInBytes, 2);
|
|
54
|
+
const l_i_b_str = i2osp(lenInBytes, 2); // len_in_bytes_str
|
|
56
55
|
const b = new Array(ell);
|
|
57
56
|
const b_0 = H(concatBytes(Z_pad, msg, l_i_b_str, i2osp(0, 1), DST_prime));
|
|
58
57
|
b[0] = H(concatBytes(b_0, i2osp(1, 1), DST_prime));
|
|
@@ -88,30 +87,36 @@ export function expand_message_xof(msg, DST, lenInBytes, k, H) {
|
|
|
88
87
|
* https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-11#section-5.3
|
|
89
88
|
* @param msg a byte string containing the message to hash
|
|
90
89
|
* @param count the number of elements of F to output
|
|
91
|
-
* @param options `{DST: string, p: bigint, m: number, k: number, expand: 'xmd' | 'xof', hash: H}
|
|
90
|
+
* @param options `{DST: string, p: bigint, m: number, k: number, expand: 'xmd' | 'xof', hash: H}`, see above
|
|
92
91
|
* @returns [u_0, ..., u_(count - 1)], a list of field elements.
|
|
93
92
|
*/
|
|
94
93
|
export function hash_to_field(msg, count, options) {
|
|
95
94
|
const { p, k, m, hash, expand, DST: _DST } = options;
|
|
96
95
|
isBytes(msg);
|
|
97
96
|
isNum(count);
|
|
98
|
-
|
|
99
|
-
throw new Error('DST must be valid');
|
|
97
|
+
const DST = validateDST(_DST);
|
|
100
98
|
const log2p = p.toString(2).length;
|
|
101
99
|
const L = Math.ceil((log2p + k) / 8); // section 5.1 of ietf draft link above
|
|
102
100
|
const len_in_bytes = count * m * L;
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
101
|
+
let prb; // pseudo_random_bytes
|
|
102
|
+
if (expand === 'xmd') {
|
|
103
|
+
prb = expand_message_xmd(msg, DST, len_in_bytes, hash);
|
|
104
|
+
}
|
|
105
|
+
else if (expand === 'xof') {
|
|
106
|
+
prb = expand_message_xof(msg, DST, len_in_bytes, k, hash);
|
|
107
|
+
}
|
|
108
|
+
else if (expand === undefined) {
|
|
109
|
+
prb = msg;
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
throw new Error('expand must be "xmd", "xof" or undefined');
|
|
113
|
+
}
|
|
109
114
|
const u = new Array(count);
|
|
110
115
|
for (let i = 0; i < count; i++) {
|
|
111
116
|
const e = new Array(m);
|
|
112
117
|
for (let j = 0; j < m; j++) {
|
|
113
118
|
const elm_offset = L * (j + i * m);
|
|
114
|
-
const tv =
|
|
119
|
+
const tv = prb.subarray(elm_offset, elm_offset + L);
|
|
115
120
|
e[j] = mod(os2ip(tv), p);
|
|
116
121
|
}
|
|
117
122
|
u[i] = e;
|
|
@@ -136,10 +141,8 @@ export function createHasher(Point, mapToCurve, def) {
|
|
|
136
141
|
k: 'isSafeInteger',
|
|
137
142
|
hash: 'hash',
|
|
138
143
|
});
|
|
139
|
-
if (def.expand !== 'xmd' && def.expand !== 'xof' && def.expand !== undefined)
|
|
140
|
-
throw new Error('Invalid htf/expand');
|
|
141
144
|
if (typeof mapToCurve !== 'function')
|
|
142
|
-
throw new Error('
|
|
145
|
+
throw new Error('mapToCurve() must be defined');
|
|
143
146
|
return {
|
|
144
147
|
// Encodes byte string to elliptic curve
|
|
145
148
|
// https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-11#section-3
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hash-to-curve.js","sourceRoot":"","sources":["../../src/abstract/hash-to-curve.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,GAAG,EAAS,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAS,WAAW,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"hash-to-curve.js","sourceRoot":"","sources":["../../src/abstract/hash-to-curve.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,GAAG,EAAS,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAS,WAAW,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAmB9F,SAAS,WAAW,CAAC,GAAwB;IAC3C,IAAI,GAAG,YAAY,UAAU;QAAE,OAAO,GAAG,CAAC;IAC1C,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC;IACrD,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;AACtD,CAAC;AAED,6FAA6F;AAC7F,MAAM,KAAK,GAAG,eAAe,CAAC;AAE9B,4CAA4C;AAC5C,SAAS,KAAK,CAAC,KAAa,EAAE,MAAc;IAC1C,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC,EAAE;QAC3C,MAAM,IAAI,KAAK,CAAC,yBAAyB,KAAK,WAAW,MAAM,EAAE,CAAC,CAAC;KACpE;IACD,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAa,CAAC;IACvD,KAAK,IAAI,CAAC,GAAG,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE;QACpC,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,IAAI,CAAC;QACtB,KAAK,MAAM,CAAC,CAAC;KACd;IACD,OAAO,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC;AAC7B,CAAC;AAED,SAAS,MAAM,CAAC,CAAa,EAAE,CAAa;IAC1C,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IACrC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;QACjC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;KACtB;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,OAAO,CAAC,IAAa;IAC5B,IAAI,CAAC,CAAC,IAAI,YAAY,UAAU,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;AAC5E,CAAC;AACD,SAAS,KAAK,CAAC,IAAa;IAC1B,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;AACtE,CAAC;AAED,oGAAoG;AACpG,uFAAuF;AACvF,MAAM,UAAU,kBAAkB,CAChC,GAAe,EACf,GAAe,EACf,UAAkB,EAClB,CAAQ;IAER,OAAO,CAAC,GAAG,CAAC,CAAC;IACb,OAAO,CAAC,GAAG,CAAC,CAAC;IACb,KAAK,CAAC,UAAU,CAAC,CAAC;IAClB,uFAAuF;IACvF,IAAI,GAAG,CAAC,MAAM,GAAG,GAAG;QAAE,GAAG,GAAG,CAAC,CAAC,WAAW,CAAC,WAAW,CAAC,mBAAmB,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;IAClF,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC;IAC1D,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC,CAAC;IAC/C,IAAI,GAAG,GAAG,GAAG;QAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;IACrD,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;IACzD,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;IACnC,MAAM,SAAS,GAAG,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC,mBAAmB;IAC3D,MAAM,CAAC,GAAG,IAAI,KAAK,CAAa,GAAG,CAAC,CAAC;IACrC,MAAM,GAAG,GAAG,CAAC,CAAC,WAAW,CAAC,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC;IAC1E,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,WAAW,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC;IACnD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,GAAG,EAAE,CAAC,EAAE,EAAE;QAC7B,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;QACjE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;KAChC;IACD,MAAM,mBAAmB,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9C,OAAO,mBAAmB,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,kBAAkB,CAChC,GAAe,EACf,GAAe,EACf,UAAkB,EAClB,CAAS,EACT,CAAQ;IAER,OAAO,CAAC,GAAG,CAAC,CAAC;IACb,OAAO,CAAC,GAAG,CAAC,CAAC;IACb,KAAK,CAAC,UAAU,CAAC,CAAC;IAClB,uFAAuF;IACvF,oFAAoF;IACpF,IAAI,GAAG,CAAC,MAAM,GAAG,GAAG,EAAE;QACpB,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACrC,GAAG,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,mBAAmB,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC;KACzF;IACD,IAAI,UAAU,GAAG,KAAK,IAAI,GAAG,CAAC,MAAM,GAAG,GAAG;QACxC,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;IAC5D,OAAO,CACL,CAAC,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC;SAC5B,MAAM,CAAC,GAAG,CAAC;SACX,MAAM,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;QAC7B,2CAA2C;SAC1C,MAAM,CAAC,GAAG,CAAC;SACX,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;SAC5B,MAAM,EAAE,CACZ,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAAC,GAAe,EAAE,KAAa,EAAE,OAAa;IACzE,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;IACrD,OAAO,CAAC,GAAG,CAAC,CAAC;IACb,KAAK,CAAC,KAAK,CAAC,CAAC;IACb,MAAM,GAAG,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;IAC9B,MAAM,KAAK,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IACnC,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,uCAAuC;IAC7E,MAAM,YAAY,GAAG,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC;IACnC,IAAI,GAAG,CAAC,CAAC,sBAAsB;IAC/B,IAAI,MAAM,KAAK,KAAK,EAAE;QACpB,GAAG,GAAG,kBAAkB,CAAC,GAAG,EAAE,GAAG,EAAE,YAAY,EAAE,IAAI,CAAC,CAAC;KACxD;SAAM,IAAI,MAAM,KAAK,KAAK,EAAE;QAC3B,GAAG,GAAG,kBAAkB,CAAC,GAAG,EAAE,GAAG,EAAE,YAAY,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;KAC3D;SAAM,IAAI,MAAM,KAAK,SAAS,EAAE;QAC/B,GAAG,GAAG,GAAG,CAAC;KACX;SAAM;QACL,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;KAC7D;IACD,MAAM,CAAC,GAAG,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;IAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE;QAC9B,MAAM,CAAC,GAAG,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC;QACvB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE;YAC1B,MAAM,UAAU,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;YACnC,MAAM,EAAE,GAAG,GAAG,CAAC,QAAQ,CAAC,UAAU,EAAE,UAAU,GAAG,CAAC,CAAC,CAAC;YACpD,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;SAC1B;QACD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;KACV;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,MAAM,UAAU,UAAU,CAAwB,KAAQ,EAAE,GAAyB;IACnF,6BAA6B;IAC7B,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;IACtD,OAAO,CAAC,CAAI,EAAE,CAAI,EAAE,EAAE;QACpB,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CACjD,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CACxD,CAAC;QACF,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,cAAc;QACzC,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,oBAAoB;QAC7D,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;IAClB,CAAC,CAAC;AACJ,CAAC;AAmBD,MAAM,UAAU,YAAY,CAC1B,KAA6B,EAC7B,UAAyB,EACzB,GAAkC;IAElC,cAAc,CAAC,GAAG,EAAE;QAClB,GAAG,EAAE,QAAQ;QACb,CAAC,EAAE,QAAQ;QACX,CAAC,EAAE,eAAe;QAClB,CAAC,EAAE,eAAe;QAClB,IAAI,EAAE,MAAM;KACb,CAAC,CAAC;IACH,IAAI,OAAO,UAAU,KAAK,UAAU;QAAE,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;IACtF,OAAO;QACL,wCAAwC;QACxC,mFAAmF;QACnF,WAAW,CAAC,GAAe,EAAE,OAAsB;YACjD,MAAM,CAAC,GAAG,aAAa,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,GAAG,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,OAAO,EAAU,CAAC,CAAC;YAC9E,MAAM,EAAE,GAAG,KAAK,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC9C,MAAM,EAAE,GAAG,KAAK,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC9C,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,aAAa,EAAE,CAAC;YACrC,CAAC,CAAC,cAAc,EAAE,CAAC;YACnB,OAAO,CAAC,CAAC;QACX,CAAC;QAED,mFAAmF;QACnF,aAAa,CAAC,GAAe,EAAE,OAAsB;YACnD,MAAM,CAAC,GAAG,aAAa,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,GAAG,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,SAAS,EAAE,GAAG,OAAO,EAAU,CAAC,CAAC;YACpF,MAAM,CAAC,GAAG,KAAK,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;YAC7D,CAAC,CAAC,cAAc,EAAE,CAAC;YACnB,OAAO,CAAC,CAAC;QACX,CAAC;KACF,CAAC;AACJ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,33 +1,35 @@
|
|
|
1
1
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
2
2
|
import type { Group, GroupConstructor, AffinePoint } from './curve.js';
|
|
3
3
|
import { mod, Field } from './modular.js';
|
|
4
|
-
import { CHash, concatBytes, utf8ToBytes, validateObject } from './utils.js';
|
|
4
|
+
import { bytesToNumberBE, CHash, concatBytes, utf8ToBytes, validateObject } from './utils.js';
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* * `DST` is a domain separation tag, defined in section 2.2.5
|
|
8
|
+
* * `p` characteristic of F, where F is a finite field of characteristic p and order q = p^m
|
|
9
|
+
* * `m` is extension degree (1 for prime fields)
|
|
10
|
+
* * `k` is the target security target in bits (e.g. 128), from section 5.1
|
|
11
|
+
* * `expand` is `xmd` (SHA2, SHA3, BLAKE) or `xof` (SHAKE, BLAKE-XOF)
|
|
12
|
+
* * `hash` conforming to `utils.CHash` interface, with `outputLen` / `blockLen` props
|
|
13
|
+
*/
|
|
6
14
|
export type Opts = {
|
|
7
|
-
DST: string
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
expand?: 'xmd' | 'xof'; // use a message that has already been processed by expand_message_xmd
|
|
13
|
-
// Hash functions for: expand_message_xmd is appropriate for use with a
|
|
14
|
-
// wide range of hash functions, including SHA-2, SHA-3, BLAKE2, and others.
|
|
15
|
-
// BBS+ uses blake2: https://github.com/hyperledger/aries-framework-go/issues/2247
|
|
16
|
-
// TODO: verify that hash is shake if expand==='xof' via types
|
|
15
|
+
DST: string | Uint8Array;
|
|
16
|
+
p: bigint;
|
|
17
|
+
m: number;
|
|
18
|
+
k: number;
|
|
19
|
+
expand?: 'xmd' | 'xof';
|
|
17
20
|
hash: CHash;
|
|
18
21
|
};
|
|
19
22
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
result <<= 8n;
|
|
25
|
-
result += BigInt(bytes[i]);
|
|
26
|
-
}
|
|
27
|
-
return result;
|
|
23
|
+
function validateDST(dst: string | Uint8Array): Uint8Array {
|
|
24
|
+
if (dst instanceof Uint8Array) return dst;
|
|
25
|
+
if (typeof dst === 'string') return utf8ToBytes(dst);
|
|
26
|
+
throw new Error('DST must be Uint8Array or string');
|
|
28
27
|
}
|
|
29
28
|
|
|
30
|
-
//
|
|
29
|
+
// Octet Stream to Integer. "spec" implementation of os2ip is 2.5x slower vs bytesToNumberBE.
|
|
30
|
+
const os2ip = bytesToNumberBE;
|
|
31
|
+
|
|
32
|
+
// Integer to Octet Stream (numberToBytesBE)
|
|
31
33
|
function i2osp(value: number, length: number): Uint8Array {
|
|
32
34
|
if (value < 0 || value >= 1 << (8 * length)) {
|
|
33
35
|
throw new Error(`bad I2OSP call: value=${value} length=${length}`);
|
|
@@ -68,13 +70,12 @@ export function expand_message_xmd(
|
|
|
68
70
|
isNum(lenInBytes);
|
|
69
71
|
// https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-16#section-5.3.3
|
|
70
72
|
if (DST.length > 255) DST = H(concatBytes(utf8ToBytes('H2C-OVERSIZE-DST-'), DST));
|
|
71
|
-
const b_in_bytes = H
|
|
72
|
-
const r_in_bytes = H.blockLen;
|
|
73
|
+
const { outputLen: b_in_bytes, blockLen: r_in_bytes } = H;
|
|
73
74
|
const ell = Math.ceil(lenInBytes / b_in_bytes);
|
|
74
75
|
if (ell > 255) throw new Error('Invalid xmd length');
|
|
75
76
|
const DST_prime = concatBytes(DST, i2osp(DST.length, 1));
|
|
76
77
|
const Z_pad = i2osp(0, r_in_bytes);
|
|
77
|
-
const l_i_b_str = i2osp(lenInBytes, 2);
|
|
78
|
+
const l_i_b_str = i2osp(lenInBytes, 2); // len_in_bytes_str
|
|
78
79
|
const b = new Array<Uint8Array>(ell);
|
|
79
80
|
const b_0 = H(concatBytes(Z_pad, msg, l_i_b_str, i2osp(0, 1), DST_prime));
|
|
80
81
|
b[0] = H(concatBytes(b_0, i2osp(1, 1), DST_prime));
|
|
@@ -120,30 +121,33 @@ export function expand_message_xof(
|
|
|
120
121
|
* https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-11#section-5.3
|
|
121
122
|
* @param msg a byte string containing the message to hash
|
|
122
123
|
* @param count the number of elements of F to output
|
|
123
|
-
* @param options `{DST: string, p: bigint, m: number, k: number, expand: 'xmd' | 'xof', hash: H}
|
|
124
|
+
* @param options `{DST: string, p: bigint, m: number, k: number, expand: 'xmd' | 'xof', hash: H}`, see above
|
|
124
125
|
* @returns [u_0, ..., u_(count - 1)], a list of field elements.
|
|
125
126
|
*/
|
|
126
127
|
export function hash_to_field(msg: Uint8Array, count: number, options: Opts): bigint[][] {
|
|
127
128
|
const { p, k, m, hash, expand, DST: _DST } = options;
|
|
128
129
|
isBytes(msg);
|
|
129
130
|
isNum(count);
|
|
130
|
-
|
|
131
|
+
const DST = validateDST(_DST);
|
|
131
132
|
const log2p = p.toString(2).length;
|
|
132
133
|
const L = Math.ceil((log2p + k) / 8); // section 5.1 of ietf draft link above
|
|
133
134
|
const len_in_bytes = count * m * L;
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
135
|
+
let prb; // pseudo_random_bytes
|
|
136
|
+
if (expand === 'xmd') {
|
|
137
|
+
prb = expand_message_xmd(msg, DST, len_in_bytes, hash);
|
|
138
|
+
} else if (expand === 'xof') {
|
|
139
|
+
prb = expand_message_xof(msg, DST, len_in_bytes, k, hash);
|
|
140
|
+
} else if (expand === undefined) {
|
|
141
|
+
prb = msg;
|
|
142
|
+
} else {
|
|
143
|
+
throw new Error('expand must be "xmd", "xof" or undefined');
|
|
144
|
+
}
|
|
141
145
|
const u = new Array(count);
|
|
142
146
|
for (let i = 0; i < count; i++) {
|
|
143
147
|
const e = new Array(m);
|
|
144
148
|
for (let j = 0; j < m; j++) {
|
|
145
149
|
const elm_offset = L * (j + i * m);
|
|
146
|
-
const tv =
|
|
150
|
+
const tv = prb.subarray(elm_offset, elm_offset + L);
|
|
147
151
|
e[j] = mod(os2ip(tv), p);
|
|
148
152
|
}
|
|
149
153
|
u[i] = e;
|
|
@@ -184,7 +188,7 @@ export type htfBasicOpts = { DST: string };
|
|
|
184
188
|
export function createHasher<T>(
|
|
185
189
|
Point: H2CPointConstructor<T>,
|
|
186
190
|
mapToCurve: MapToCurve<T>,
|
|
187
|
-
def: Opts
|
|
191
|
+
def: Opts & { encodeDST?: string }
|
|
188
192
|
) {
|
|
189
193
|
validateObject(def, {
|
|
190
194
|
DST: 'string',
|
|
@@ -193,10 +197,7 @@ export function createHasher<T>(
|
|
|
193
197
|
k: 'isSafeInteger',
|
|
194
198
|
hash: 'hash',
|
|
195
199
|
});
|
|
196
|
-
if (
|
|
197
|
-
throw new Error('Invalid htf/expand');
|
|
198
|
-
if (typeof mapToCurve !== 'function')
|
|
199
|
-
throw new Error('hashToCurve: mapToCurve() has not been defined');
|
|
200
|
+
if (typeof mapToCurve !== 'function') throw new Error('mapToCurve() must be defined');
|
|
200
201
|
return {
|
|
201
202
|
// Encodes byte string to elliptic curve
|
|
202
203
|
// https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-11#section-3
|