@noble/curves 2.0.1 → 2.2.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.
- package/README.md +214 -122
- package/abstract/bls.d.ts +299 -16
- package/abstract/bls.d.ts.map +1 -1
- package/abstract/bls.js +82 -22
- package/abstract/bls.js.map +1 -1
- package/abstract/curve.d.ts +274 -27
- package/abstract/curve.d.ts.map +1 -1
- package/abstract/curve.js +177 -23
- package/abstract/curve.js.map +1 -1
- package/abstract/edwards.d.ts +166 -30
- package/abstract/edwards.d.ts.map +1 -1
- package/abstract/edwards.js +221 -86
- package/abstract/edwards.js.map +1 -1
- package/abstract/fft.d.ts +322 -10
- package/abstract/fft.d.ts.map +1 -1
- package/abstract/fft.js +154 -12
- package/abstract/fft.js.map +1 -1
- package/abstract/frost.d.ts +293 -0
- package/abstract/frost.d.ts.map +1 -0
- package/abstract/frost.js +704 -0
- package/abstract/frost.js.map +1 -0
- package/abstract/hash-to-curve.d.ts +173 -24
- package/abstract/hash-to-curve.d.ts.map +1 -1
- package/abstract/hash-to-curve.js +170 -31
- package/abstract/hash-to-curve.js.map +1 -1
- package/abstract/modular.d.ts +429 -37
- package/abstract/modular.d.ts.map +1 -1
- package/abstract/modular.js +414 -119
- package/abstract/modular.js.map +1 -1
- package/abstract/montgomery.d.ts +83 -12
- package/abstract/montgomery.d.ts.map +1 -1
- package/abstract/montgomery.js +32 -7
- package/abstract/montgomery.js.map +1 -1
- package/abstract/oprf.d.ts +164 -91
- package/abstract/oprf.d.ts.map +1 -1
- package/abstract/oprf.js +88 -29
- package/abstract/oprf.js.map +1 -1
- package/abstract/poseidon.d.ts +138 -7
- package/abstract/poseidon.d.ts.map +1 -1
- package/abstract/poseidon.js +178 -15
- package/abstract/poseidon.js.map +1 -1
- package/abstract/tower.d.ts +122 -3
- package/abstract/tower.d.ts.map +1 -1
- package/abstract/tower.js +323 -139
- package/abstract/tower.js.map +1 -1
- package/abstract/weierstrass.d.ts +339 -76
- package/abstract/weierstrass.d.ts.map +1 -1
- package/abstract/weierstrass.js +395 -205
- package/abstract/weierstrass.js.map +1 -1
- package/bls12-381.d.ts +16 -2
- package/bls12-381.d.ts.map +1 -1
- package/bls12-381.js +199 -209
- package/bls12-381.js.map +1 -1
- package/bn254.d.ts +11 -2
- package/bn254.d.ts.map +1 -1
- package/bn254.js +93 -38
- package/bn254.js.map +1 -1
- package/ed25519.d.ts +125 -14
- package/ed25519.d.ts.map +1 -1
- package/ed25519.js +202 -40
- package/ed25519.js.map +1 -1
- package/ed448.d.ts +108 -14
- package/ed448.d.ts.map +1 -1
- package/ed448.js +194 -42
- package/ed448.js.map +1 -1
- package/index.js +7 -1
- package/index.js.map +1 -1
- package/misc.d.ts +106 -7
- package/misc.d.ts.map +1 -1
- package/misc.js +141 -32
- package/misc.js.map +1 -1
- package/nist.d.ts +112 -11
- package/nist.d.ts.map +1 -1
- package/nist.js +139 -17
- package/nist.js.map +1 -1
- package/package.json +11 -6
- package/secp256k1.d.ts +92 -15
- package/secp256k1.d.ts.map +1 -1
- package/secp256k1.js +211 -28
- package/secp256k1.js.map +1 -1
- package/src/abstract/bls.ts +350 -67
- package/src/abstract/curve.ts +327 -44
- package/src/abstract/edwards.ts +367 -143
- package/src/abstract/fft.ts +369 -36
- package/src/abstract/frost.ts +1092 -0
- package/src/abstract/hash-to-curve.ts +255 -56
- package/src/abstract/modular.ts +591 -144
- package/src/abstract/montgomery.ts +114 -30
- package/src/abstract/oprf.ts +383 -194
- package/src/abstract/poseidon.ts +235 -35
- package/src/abstract/tower.ts +428 -159
- package/src/abstract/weierstrass.ts +710 -312
- package/src/bls12-381.ts +239 -236
- package/src/bn254.ts +107 -46
- package/src/ed25519.ts +227 -55
- package/src/ed448.ts +227 -57
- package/src/index.ts +7 -1
- package/src/misc.ts +154 -35
- package/src/nist.ts +143 -20
- package/src/secp256k1.ts +284 -41
- package/src/utils.ts +583 -81
- package/src/webcrypto.ts +302 -73
- package/utils.d.ts +457 -24
- package/utils.d.ts.map +1 -1
- package/utils.js +410 -53
- package/utils.js.map +1 -1
- package/webcrypto.d.ts +167 -25
- package/webcrypto.d.ts.map +1 -1
- package/webcrypto.js +165 -58
- package/webcrypto.js.map +1 -1
package/ed448.d.ts
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import type { AffinePoint } from './abstract/curve.ts';
|
|
2
2
|
import { PrimeEdwardsPoint, type EdDSA, type EdwardsPoint, type EdwardsPointCons } from './abstract/edwards.ts';
|
|
3
|
+
import { type FROST } from './abstract/frost.ts';
|
|
3
4
|
import { type H2CHasher, type H2CHasherBase } from './abstract/hash-to-curve.ts';
|
|
4
5
|
import { type IField } from './abstract/modular.ts';
|
|
5
6
|
import { type MontgomeryECDH } from './abstract/montgomery.ts';
|
|
6
7
|
import { type OPRF } from './abstract/oprf.ts';
|
|
8
|
+
import { type TArg, type TRet } from './utils.ts';
|
|
7
9
|
/**
|
|
8
10
|
* ed448 EdDSA curve and methods.
|
|
9
11
|
* @example
|
|
12
|
+
* Generate one Ed448 keypair, sign a message, and verify it.
|
|
13
|
+
*
|
|
10
14
|
* ```js
|
|
11
15
|
* import { ed448 } from '@noble/curves/ed448.js';
|
|
12
16
|
* const { secretKey, publicKey } = ed448.keygen();
|
|
@@ -17,17 +21,46 @@ import { type OPRF } from './abstract/oprf.ts';
|
|
|
17
21
|
* ```
|
|
18
22
|
*/
|
|
19
23
|
export declare const ed448: EdDSA;
|
|
20
|
-
/**
|
|
24
|
+
/**
|
|
25
|
+
* Prehashed version of ed448. See {@link ed448}
|
|
26
|
+
* @example
|
|
27
|
+
* Use the prehashed Ed448 variant for one message.
|
|
28
|
+
*
|
|
29
|
+
* ```ts
|
|
30
|
+
* const { secretKey, publicKey } = ed448ph.keygen();
|
|
31
|
+
* const msg = new TextEncoder().encode('hello noble');
|
|
32
|
+
* const sig = ed448ph.sign(msg, secretKey);
|
|
33
|
+
* const isValid = ed448ph.verify(sig, msg, publicKey);
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
21
36
|
export declare const ed448ph: EdDSA;
|
|
22
37
|
/**
|
|
23
|
-
* E448
|
|
24
|
-
*
|
|
38
|
+
* E448 here is NIST SP 800-186 §3.2.3.3 E448, the Edwards representation of
|
|
39
|
+
* Curve448, not RFC 8032 edwards448 / Goldilocks.
|
|
40
|
+
* Goldilocks is the separate 4-isogenous curve exposed as `ed448`.
|
|
41
|
+
* We keep the corrected prime-order base here; RFC 7748's literal Edwards
|
|
42
|
+
* point / map are wrong for this curve model, and the literal point is the
|
|
43
|
+
* wrong-sign order-2*n variant.
|
|
44
|
+
* @param X - Projective X coordinate.
|
|
45
|
+
* @param Y - Projective Y coordinate.
|
|
46
|
+
* @param Z - Projective Z coordinate.
|
|
47
|
+
* @param T - Projective T coordinate.
|
|
48
|
+
* @example
|
|
49
|
+
* Multiply the E448 base point.
|
|
50
|
+
*
|
|
51
|
+
* ```ts
|
|
52
|
+
* const point = E448.BASE.multiply(2n);
|
|
53
|
+
* ```
|
|
25
54
|
*/
|
|
26
55
|
export declare const E448: EdwardsPointCons;
|
|
27
56
|
/**
|
|
28
57
|
* ECDH using curve448 aka x448.
|
|
58
|
+
* The wrapper aborts on all-zero shared secrets by default, and seeded
|
|
59
|
+
* `keygen(seed)` reuses the provided 56-byte seed buffer instead of copying it.
|
|
29
60
|
*
|
|
30
61
|
* @example
|
|
62
|
+
* Derive one shared secret between two X448 peers.
|
|
63
|
+
*
|
|
31
64
|
* ```js
|
|
32
65
|
* import { x448 } from '@noble/curves/ed448.js';
|
|
33
66
|
* const alice = x448.keygen();
|
|
@@ -35,9 +68,33 @@ export declare const E448: EdwardsPointCons;
|
|
|
35
68
|
* const shared = x448.getSharedSecret(alice.secretKey, bob.publicKey);
|
|
36
69
|
* ```
|
|
37
70
|
*/
|
|
38
|
-
export declare const x448: MontgomeryECDH
|
|
39
|
-
/**
|
|
71
|
+
export declare const x448: TRet<MontgomeryECDH>;
|
|
72
|
+
/**
|
|
73
|
+
* Hashing / encoding to ed448 points / field. RFC 9380 methods.
|
|
74
|
+
* Public `mapToCurve()` consumes one field element bigint for `m = 1`, and RFC
|
|
75
|
+
* Appendix J vectors use the special `QUUX-V01-*` test DST overrides rather
|
|
76
|
+
* than the default suite IDs below.
|
|
77
|
+
* @example
|
|
78
|
+
* Hash one message onto the ed448 curve.
|
|
79
|
+
*
|
|
80
|
+
* ```ts
|
|
81
|
+
* const point = ed448_hasher.hashToCurve(new TextEncoder().encode('hello noble'));
|
|
82
|
+
* ```
|
|
83
|
+
*/
|
|
40
84
|
export declare const ed448_hasher: H2CHasher<EdwardsPointCons>;
|
|
85
|
+
/**
|
|
86
|
+
* FROST threshold signatures over ed448. RFC 9591.
|
|
87
|
+
* @example
|
|
88
|
+
* Create one trusted-dealer package for 2-of-3 ed448 signing.
|
|
89
|
+
*
|
|
90
|
+
* ```ts
|
|
91
|
+
* const alice = ed448_FROST.Identifier.derive('alice@example.com');
|
|
92
|
+
* const bob = ed448_FROST.Identifier.derive('bob@example.com');
|
|
93
|
+
* const carol = ed448_FROST.Identifier.derive('carol@example.com');
|
|
94
|
+
* const deal = ed448_FROST.trustedDealer({ min: 2, max: 3 }, [alice, bob, carol]);
|
|
95
|
+
* ```
|
|
96
|
+
*/
|
|
97
|
+
export declare const ed448_FROST: TRet<FROST>;
|
|
41
98
|
/**
|
|
42
99
|
* Each ed448/EdwardsPoint has 4 different equivalent points. This can be
|
|
43
100
|
* a source of bugs for protocols like ring signatures. Decaf was created to solve this.
|
|
@@ -51,21 +108,27 @@ declare class _DecafPoint extends PrimeEdwardsPoint<_DecafPoint> {
|
|
|
51
108
|
static Fp: IField<bigint>;
|
|
52
109
|
static Fn: IField<bigint>;
|
|
53
110
|
constructor(ep: EdwardsPoint);
|
|
111
|
+
/**
|
|
112
|
+
* Create one Decaf448 point from affine Edwards coordinates.
|
|
113
|
+
* This wraps the internal Edwards representative directly and is not a
|
|
114
|
+
* canonical decaf448 decoding path.
|
|
115
|
+
* Use `toBytes()` / `fromBytes()` if canonical decaf448 bytes matter.
|
|
116
|
+
*/
|
|
54
117
|
static fromAffine(ap: AffinePoint<bigint>): _DecafPoint;
|
|
55
118
|
protected assertSame(other: _DecafPoint): void;
|
|
56
119
|
protected init(ep: EdwardsPoint): _DecafPoint;
|
|
57
|
-
static fromBytes(bytes: Uint8Array): _DecafPoint;
|
|
120
|
+
static fromBytes(bytes: TArg<Uint8Array>): _DecafPoint;
|
|
58
121
|
/**
|
|
59
122
|
* Converts decaf-encoded string to decaf point.
|
|
60
123
|
* Described in [RFC9496](https://www.rfc-editor.org/rfc/rfc9496#name-decode-2).
|
|
61
|
-
* @param hex Decaf-encoded 56 bytes. Not every 56-byte string is valid decaf encoding
|
|
124
|
+
* @param hex - Decaf-encoded 56 bytes. Not every 56-byte string is valid decaf encoding
|
|
62
125
|
*/
|
|
63
126
|
static fromHex(hex: string): _DecafPoint;
|
|
64
127
|
/**
|
|
65
128
|
* Encodes decaf point to Uint8Array.
|
|
66
129
|
* Described in [RFC9496](https://www.rfc-editor.org/rfc/rfc9496#name-encode-2).
|
|
67
130
|
*/
|
|
68
|
-
toBytes(): Uint8Array
|
|
131
|
+
toBytes(): TRet<Uint8Array>;
|
|
69
132
|
/**
|
|
70
133
|
* Compare one point to another.
|
|
71
134
|
* Described in [RFC9496](https://www.rfc-editor.org/rfc/rfc9496#name-equals-2).
|
|
@@ -73,19 +136,50 @@ declare class _DecafPoint extends PrimeEdwardsPoint<_DecafPoint> {
|
|
|
73
136
|
equals(other: _DecafPoint): boolean;
|
|
74
137
|
is0(): boolean;
|
|
75
138
|
}
|
|
139
|
+
/** Prime-order Decaf448 group bundle. */
|
|
76
140
|
export declare const decaf448: {
|
|
77
141
|
Point: typeof _DecafPoint;
|
|
78
142
|
};
|
|
79
|
-
/**
|
|
143
|
+
/**
|
|
144
|
+
* Hashing to decaf448 points / field. RFC 9380 methods.
|
|
145
|
+
* `hashToCurve()` is RFC 9380 `hash_to_decaf448`, `deriveToCurve()` is RFC
|
|
146
|
+
* 9496 element derivation, and `hashToScalar()` is a library helper layered on
|
|
147
|
+
* top of RFC 9496 scalar reduction.
|
|
148
|
+
* @example
|
|
149
|
+
* Hash one message onto decaf448.
|
|
150
|
+
*
|
|
151
|
+
* ```ts
|
|
152
|
+
* const point = decaf448_hasher.hashToCurve(new TextEncoder().encode('hello noble'));
|
|
153
|
+
* ```
|
|
154
|
+
*/
|
|
80
155
|
export declare const decaf448_hasher: H2CHasherBase<typeof _DecafPoint>;
|
|
81
|
-
/**
|
|
82
|
-
|
|
156
|
+
/**
|
|
157
|
+
* decaf448 OPRF, defined in RFC 9497.
|
|
158
|
+
* @example
|
|
159
|
+
* Run one blind/evaluate/finalize OPRF round over decaf448.
|
|
160
|
+
*
|
|
161
|
+
* ```ts
|
|
162
|
+
* const input = new TextEncoder().encode('hello noble');
|
|
163
|
+
* const keys = decaf448_oprf.oprf.generateKeyPair();
|
|
164
|
+
* const blind = decaf448_oprf.oprf.blind(input);
|
|
165
|
+
* const evaluated = decaf448_oprf.oprf.blindEvaluate(keys.secretKey, blind.blinded);
|
|
166
|
+
* const output = decaf448_oprf.oprf.finalize(input, blind.blind, evaluated);
|
|
167
|
+
* ```
|
|
168
|
+
*/
|
|
169
|
+
export declare const decaf448_oprf: TRet<OPRF>;
|
|
83
170
|
/**
|
|
84
171
|
* Weird / bogus points, useful for debugging.
|
|
85
172
|
* Unlike ed25519, there is no ed448 generator point which can produce full T subgroup.
|
|
86
|
-
* Instead,
|
|
87
|
-
* (
|
|
173
|
+
* Instead, the torsion subgroup here is cyclic of order 4, generated by
|
|
174
|
+
* `(1, 0)`, and the array below lists that subgroup set (Klein four-group).
|
|
175
|
+
* @example
|
|
176
|
+
* Decode one known torsion point for debugging.
|
|
177
|
+
*
|
|
178
|
+
* ```ts
|
|
179
|
+
* import { ED448_TORSION_SUBGROUP, ed448 } from '@noble/curves/ed448.js';
|
|
180
|
+
* const point = ed448.Point.fromHex(ED448_TORSION_SUBGROUP[1]);
|
|
181
|
+
* ```
|
|
88
182
|
*/
|
|
89
|
-
export declare const ED448_TORSION_SUBGROUP: string[];
|
|
183
|
+
export declare const ED448_TORSION_SUBGROUP: readonly string[];
|
|
90
184
|
export {};
|
|
91
185
|
//# sourceMappingURL=ed448.d.ts.map
|
package/ed448.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ed448.d.ts","sourceRoot":"","sources":["src/ed448.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAGL,iBAAiB,EACjB,KAAK,KAAK,EAGV,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACtB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAKL,KAAK,SAAS,EACd,KAAK,aAAa,EACnB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAiD,KAAK,MAAM,EAAE,MAAM,uBAAuB,CAAC;AACnG,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC3E,OAAO,EAAc,KAAK,IAAI,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"ed448.d.ts","sourceRoot":"","sources":["src/ed448.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAGL,iBAAiB,EACjB,KAAK,KAAK,EAGV,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACtB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAe,KAAK,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EAKL,KAAK,SAAS,EACd,KAAK,aAAa,EACnB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAiD,KAAK,MAAM,EAAE,MAAM,uBAAuB,CAAC;AACnG,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC3E,OAAO,EAAc,KAAK,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAKL,KAAK,IAAI,EACT,KAAK,IAAI,EACV,MAAM,YAAY,CAAC;AAyJpB;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,KAAK,EAAE,KAA+B,CAAC;AAGpD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,OAAO,EAAE,KAAqD,CAAC;AAC5E;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,IAAI,EAAE,gBAAsD,CAAC;AAE1E;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,IAAI,EAAE,IAAI,CAAC,cAAc,CAYlC,CAAC;AAqFL;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,YAAY,EAAE,SAAS,CAAC,gBAAgB,CAS9C,CAAC;AACR;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,WAAW,EAAE,IAAI,CAAC,KAAK,CAa7B,CAAC;AAwER;;;;;;GAMG;AACH,cAAM,WAAY,SAAQ,iBAAiB,CAAC,WAAW,CAAC;IAGtD,MAAM,CAAC,IAAI,EAAE,WAAW,CACoF;IAE5G,MAAM,CAAC,IAAI,EAAE,WAAW,CACsC;IAE9D,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,MAAM,CAAC,CACS;IAElC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,MAAM,CAAC,CACS;gBAEtB,EAAE,EAAE,YAAY;IAI5B;;;;;OAKG;IACH,MAAM,CAAC,UAAU,CAAC,EAAE,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,WAAW;IAIvD,SAAS,CAAC,UAAU,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI;IAI9C,SAAS,CAAC,IAAI,CAAC,EAAE,EAAE,YAAY,GAAG,WAAW;IAI7C,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,UAAU,CAAC,GAAG,WAAW;IA6BtD;;;;OAIG;IACH,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW;IAIxC;;;OAGG;IACH,OAAO,IAAI,IAAI,CAAC,UAAU,CAAC;IAe3B;;;OAGG;IACH,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO;IAQnC,GAAG,IAAI,OAAO;CAGf;AAMD,yCAAyC;AACzC,eAAO,MAAM,QAAQ,EAAE;IACrB,KAAK,EAAE,OAAO,WAAW,CAAC;CAC6B,CAAC;AAE1D;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,eAAe,EAAE,aAAa,CAAC,OAAO,WAAW,CAsC5D,CAAC;AAEH;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,aAAa,EAAE,IAAI,CAAC,IAAI,CAO9B,CAAC;AAER;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,sBAAsB,EAAE,SAAS,MAAM,EAKlD,CAAC"}
|
package/ed448.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Edwards448 (
|
|
2
|
+
* Edwards448 (also called Goldilocks) curve with following addons:
|
|
3
3
|
* - X448 ECDH
|
|
4
4
|
* - Decaf cofactor elimination
|
|
5
5
|
* - Elligator hash-to-group / point indistinguishability
|
|
@@ -10,18 +10,19 @@
|
|
|
10
10
|
import { shake256 } from '@noble/hashes/sha3.js';
|
|
11
11
|
import { concatBytes, hexToBytes, createHasher as wrapConstructor } from '@noble/hashes/utils.js';
|
|
12
12
|
import { eddsa, edwards, PrimeEdwardsPoint, } from "./abstract/edwards.js";
|
|
13
|
+
import { createFROST } from "./abstract/frost.js";
|
|
13
14
|
import { _DST_scalar, createHasher, expand_message_xof, } from "./abstract/hash-to-curve.js";
|
|
14
15
|
import { Field, FpInvertBatch, isNegativeLE, mod, pow2 } from "./abstract/modular.js";
|
|
15
16
|
import { montgomery } from "./abstract/montgomery.js";
|
|
16
|
-
import {
|
|
17
|
-
import { abytes, asciiToBytes, bytesToNumberLE, equalBytes } from "./utils.js";
|
|
17
|
+
import { createOPRF } from "./abstract/oprf.js";
|
|
18
|
+
import { abytes, asciiToBytes, bytesToNumberLE, equalBytes, } from "./utils.js";
|
|
18
19
|
// edwards448 curve
|
|
19
20
|
// a = 1n
|
|
20
21
|
// d = Fp.neg(39081n)
|
|
21
22
|
// Finite field 2n**448n - 2n**224n - 1n
|
|
22
23
|
// Subgroup order
|
|
23
24
|
// 2n**446n - 13818066809895115352007386748515426880336692474882178609894547503885n
|
|
24
|
-
const ed448_CURVE_p = BigInt('0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffff');
|
|
25
|
+
const ed448_CURVE_p = /* @__PURE__ */ BigInt('0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffff');
|
|
25
26
|
const ed448_CURVE = /* @__PURE__ */ (() => ({
|
|
26
27
|
p: ed448_CURVE_p,
|
|
27
28
|
n: BigInt('0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffff7cca23e9c44edb49aed63690216cc2728dc58f552378c292ab5844f3'),
|
|
@@ -31,9 +32,14 @@ const ed448_CURVE = /* @__PURE__ */ (() => ({
|
|
|
31
32
|
Gx: BigInt('0x4f1970c66bed0ded221d15a622bf36da9e146570470f1767ea6de324a3d3a46412ae1af72ab66511433b80e18b00938e2626a82bc70cc05e'),
|
|
32
33
|
Gy: BigInt('0x693f46716eb6bc248876203756c9c7624bea73736ca3984087789c1e05a0c2d73ad3ff1ce67c39c4fdbd132c4ed7c8ad9808795bf230fa14'),
|
|
33
34
|
}))();
|
|
34
|
-
//
|
|
35
|
-
//
|
|
36
|
-
//
|
|
35
|
+
// This is not RFC 8032 edwards448 / Goldilocks (`ed448` below, d = -39081).
|
|
36
|
+
// It is NIST SP 800-186 §3.2.3.3 E448, the Curve448-isomorphic Edwards model
|
|
37
|
+
// also described in draft-ietf-lwig-curve-representations-23 Appendix M, with
|
|
38
|
+
// d = 39082/39081 and Gy = 3/2.
|
|
39
|
+
// RFC 7748's literal Edwards point / birational map are wrong here: the literal
|
|
40
|
+
// point is the wrong-sign (Gx, -Gy) order-2*n variant. Keep the corrected
|
|
41
|
+
// prime-order (Gx, Gy) base so Point.BASE stays a subgroup generator, which is
|
|
42
|
+
// what noble's generic Edwards API expects.
|
|
37
43
|
const E448_CURVE = /* @__PURE__ */ (() => Object.assign({}, ed448_CURVE, {
|
|
38
44
|
d: BigInt('0xd78b4bdc7f0daf19f24f38c29373a2ccad46157242a50f37809b1da3412a12e79ccc9c81264cfe9ad080997058fb61c4243cc32dbaa156b9'),
|
|
39
45
|
Gx: BigInt('0x79a70b2b70400553ae7c9df416c792c61128751ac92969240c25a07d728bdc93e21f7787ed6972249de732f38496cd11698713093e9c04fc'),
|
|
@@ -42,9 +48,9 @@ const E448_CURVE = /* @__PURE__ */ (() => Object.assign({}, ed448_CURVE, {
|
|
|
42
48
|
const shake256_114 = /* @__PURE__ */ wrapConstructor(() => shake256.create({ dkLen: 114 }));
|
|
43
49
|
const shake256_64 = /* @__PURE__ */ wrapConstructor(() => shake256.create({ dkLen: 64 }));
|
|
44
50
|
// prettier-ignore
|
|
45
|
-
const _1n = BigInt(1), _2n = BigInt(2), _3n = BigInt(3), _4n = /* @__PURE__ */ BigInt(4), _11n = BigInt(11);
|
|
51
|
+
const _1n = /* @__PURE__ */ BigInt(1), _2n = /* @__PURE__ */ BigInt(2), _3n = /* @__PURE__ */ BigInt(3), _4n = /* @__PURE__ */ BigInt(4), _11n = /* @__PURE__ */ BigInt(11);
|
|
46
52
|
// prettier-ignore
|
|
47
|
-
const _22n = BigInt(22), _44n = BigInt(44), _88n = BigInt(88), _223n = BigInt(223);
|
|
53
|
+
const _22n = /* @__PURE__ */ BigInt(22), _44n = /* @__PURE__ */ BigInt(44), _88n = /* @__PURE__ */ BigInt(88), _223n = /* @__PURE__ */ BigInt(223);
|
|
48
54
|
// powPminus3div4 calculates z = x^k mod p, where k = (p-3)/4.
|
|
49
55
|
// Used for efficient square root calculation.
|
|
50
56
|
// ((P-3)/4).toString(2) would produce bits [223x 1, 0, 222x 1]
|
|
@@ -64,6 +70,8 @@ function ed448_pow_Pminus3div4(x) {
|
|
|
64
70
|
const b223 = (pow2(b222, _1n, P) * x) % P;
|
|
65
71
|
return (pow2(b223, _223n, P) * b222) % P;
|
|
66
72
|
}
|
|
73
|
+
// Mutates and returns the provided buffer in place. The final `bytes[56] = 0`
|
|
74
|
+
// write is the Ed448 path; for 56-byte X448 inputs it is an out-of-bounds no-op.
|
|
67
75
|
function adjustScalarBytes(bytes) {
|
|
68
76
|
// Section 5: Likewise, for X448, set the two least significant bits of the first byte to 0,
|
|
69
77
|
bytes[0] &= 252; // 0b11111100
|
|
@@ -73,8 +81,9 @@ function adjustScalarBytes(bytes) {
|
|
|
73
81
|
bytes[56] = 0; // Byte outside of group (456 buts vs 448 bits)
|
|
74
82
|
return bytes;
|
|
75
83
|
}
|
|
76
|
-
// Constant-time
|
|
77
|
-
//
|
|
84
|
+
// Constant-time Ed448 decode helper for RFC 8032 §5.2.3 steps 2-3. Unlike
|
|
85
|
+
// `SQRT_RATIO_M1`, the returned `value` only has the documented meaning when
|
|
86
|
+
// `isValid` is true.
|
|
78
87
|
function uvRatio(u, v) {
|
|
79
88
|
const P = ed448_CURVE_p;
|
|
80
89
|
// https://www.rfc-editor.org/rfc/rfc8032#section-5.2.3
|
|
@@ -95,27 +104,39 @@ function uvRatio(u, v) {
|
|
|
95
104
|
return { isValid: mod(x2 * v, P) === u, value: x };
|
|
96
105
|
}
|
|
97
106
|
// Finite field 2n**448n - 2n**224n - 1n
|
|
98
|
-
//
|
|
99
|
-
//
|
|
100
|
-
// -
|
|
107
|
+
// RFC 8032 encodes Ed448 field/scalar elements in 57 bytes even though field
|
|
108
|
+
// values fit in 448 bits and scalars in 446 bits. Noble models that with a
|
|
109
|
+
// 456-bit storage width so the final-octet x-sign bit (bit 455) still fits in
|
|
110
|
+
// the shared little-endian container.
|
|
101
111
|
const Fp = /* @__PURE__ */ (() => Field(ed448_CURVE_p, { BITS: 456, isLE: true }))();
|
|
112
|
+
// Same 57-byte container shape as `Fp`; canonical scalar encodings still have
|
|
113
|
+
// the top ten bits clear per RFC 8032.
|
|
102
114
|
const Fn = /* @__PURE__ */ (() => Field(ed448_CURVE.n, { BITS: 456, isLE: true }))();
|
|
103
|
-
// decaf448
|
|
115
|
+
// Generic 56-byte field shape used by decaf448 and raw X448 u-coordinates.
|
|
116
|
+
// Plain `Field` decoding stays canonical here, so callers that want RFC 7748's
|
|
117
|
+
// modulo-p acceptance must reduce externally.
|
|
104
118
|
const Fp448 = /* @__PURE__ */ (() => Field(ed448_CURVE_p, { BITS: 448, isLE: true }))();
|
|
119
|
+
// Strict 56-byte scalar parser matching RFC 9496's recommended canonical form.
|
|
105
120
|
const Fn448 = /* @__PURE__ */ (() => Field(ed448_CURVE.n, { BITS: 448, isLE: true }))();
|
|
106
121
|
// SHAKE256(dom4(phflag,context)||x, 114)
|
|
122
|
+
// RFC 8032 `dom4` prefix. Empty contexts are valid; the accepted length range
|
|
123
|
+
// is 0..255 octets inclusive.
|
|
107
124
|
function dom4(data, ctx, phflag) {
|
|
108
125
|
if (ctx.length > 255)
|
|
109
126
|
throw new Error('context must be smaller than 255, got: ' + ctx.length);
|
|
110
127
|
return concatBytes(asciiToBytes('SigEd448'), new Uint8Array([phflag ? 1 : 0, ctx.length]), ctx, data);
|
|
111
128
|
}
|
|
112
129
|
const ed448_Point = /* @__PURE__ */ edwards(ed448_CURVE, { Fp, Fn, uvRatio });
|
|
130
|
+
// Shared internal factory for both `ed448` and `ed448ph`; callers are only
|
|
131
|
+
// expected to override narrow family options such as prehashing.
|
|
113
132
|
function ed4(opts) {
|
|
114
133
|
return eddsa(ed448_Point, shake256_114, Object.assign({ adjustScalarBytes, domain: dom4 }, opts));
|
|
115
134
|
}
|
|
116
135
|
/**
|
|
117
136
|
* ed448 EdDSA curve and methods.
|
|
118
137
|
* @example
|
|
138
|
+
* Generate one Ed448 keypair, sign a message, and verify it.
|
|
139
|
+
*
|
|
119
140
|
* ```js
|
|
120
141
|
* import { ed448 } from '@noble/curves/ed448.js';
|
|
121
142
|
* const { secretKey, publicKey } = ed448.keygen();
|
|
@@ -127,17 +148,46 @@ function ed4(opts) {
|
|
|
127
148
|
*/
|
|
128
149
|
export const ed448 = /* @__PURE__ */ ed4({});
|
|
129
150
|
// There is no ed448ctx, since ed448 supports ctx by default
|
|
130
|
-
/**
|
|
151
|
+
/**
|
|
152
|
+
* Prehashed version of ed448. See {@link ed448}
|
|
153
|
+
* @example
|
|
154
|
+
* Use the prehashed Ed448 variant for one message.
|
|
155
|
+
*
|
|
156
|
+
* ```ts
|
|
157
|
+
* const { secretKey, publicKey } = ed448ph.keygen();
|
|
158
|
+
* const msg = new TextEncoder().encode('hello noble');
|
|
159
|
+
* const sig = ed448ph.sign(msg, secretKey);
|
|
160
|
+
* const isValid = ed448ph.verify(sig, msg, publicKey);
|
|
161
|
+
* ```
|
|
162
|
+
*/
|
|
131
163
|
export const ed448ph = /* @__PURE__ */ ed4({ prehash: shake256_64 });
|
|
132
164
|
/**
|
|
133
|
-
* E448
|
|
134
|
-
*
|
|
165
|
+
* E448 here is NIST SP 800-186 §3.2.3.3 E448, the Edwards representation of
|
|
166
|
+
* Curve448, not RFC 8032 edwards448 / Goldilocks.
|
|
167
|
+
* Goldilocks is the separate 4-isogenous curve exposed as `ed448`.
|
|
168
|
+
* We keep the corrected prime-order base here; RFC 7748's literal Edwards
|
|
169
|
+
* point / map are wrong for this curve model, and the literal point is the
|
|
170
|
+
* wrong-sign order-2*n variant.
|
|
171
|
+
* @param X - Projective X coordinate.
|
|
172
|
+
* @param Y - Projective Y coordinate.
|
|
173
|
+
* @param Z - Projective Z coordinate.
|
|
174
|
+
* @param T - Projective T coordinate.
|
|
175
|
+
* @example
|
|
176
|
+
* Multiply the E448 base point.
|
|
177
|
+
*
|
|
178
|
+
* ```ts
|
|
179
|
+
* const point = E448.BASE.multiply(2n);
|
|
180
|
+
* ```
|
|
135
181
|
*/
|
|
136
182
|
export const E448 = /* @__PURE__ */ edwards(E448_CURVE);
|
|
137
183
|
/**
|
|
138
184
|
* ECDH using curve448 aka x448.
|
|
185
|
+
* The wrapper aborts on all-zero shared secrets by default, and seeded
|
|
186
|
+
* `keygen(seed)` reuses the provided 56-byte seed buffer instead of copying it.
|
|
139
187
|
*
|
|
140
188
|
* @example
|
|
189
|
+
* Derive one shared secret between two X448 peers.
|
|
190
|
+
*
|
|
141
191
|
* ```js
|
|
142
192
|
* import { x448 } from '@noble/curves/ed448.js';
|
|
143
193
|
* const alice = x448.keygen();
|
|
@@ -159,8 +209,11 @@ export const x448 = /* @__PURE__ */ (() => {
|
|
|
159
209
|
});
|
|
160
210
|
})();
|
|
161
211
|
// Hash To Curve Elligator2 Map
|
|
162
|
-
|
|
212
|
+
// 1. c1 = (q - 3) / 4 # Integer arithmetic
|
|
213
|
+
const ELL2_C1 = /* @__PURE__ */ (() => (ed448_CURVE_p - BigInt(3)) / BigInt(4))();
|
|
163
214
|
const ELL2_J = /* @__PURE__ */ BigInt(156326);
|
|
215
|
+
// Returns RFC 9380 Appendix G.2.3 rational Montgomery numerators/denominators
|
|
216
|
+
// `{ xn, xd, yn, yd }`, not an affine point.
|
|
164
217
|
function map_to_curve_elligator2_curve448(u) {
|
|
165
218
|
let tv1 = Fp.sqr(u); // 1. tv1 = u^2
|
|
166
219
|
let e1 = Fp.eql(tv1, Fp.ONE); // 2. e1 = tv1 == 1
|
|
@@ -178,7 +231,8 @@ function map_to_curve_elligator2_curve448(u) {
|
|
|
178
231
|
tv3 = Fp.mul(tv3, tv2); // 14. tv3 = tv3 * tv2 # gx1 * gxd^3
|
|
179
232
|
let y1 = Fp.pow(tv3, ELL2_C1); // 15. y1 = tv3^c1 # (gx1 * gxd^3)^((p - 3) / 4)
|
|
180
233
|
y1 = Fp.mul(y1, tv2); // 16. y1 = y1 * tv2 # gx1 * gxd * (gx1 * gxd^3)^((p - 3) / 4)
|
|
181
|
-
|
|
234
|
+
// 17. x2n = -tv1 * x1n # x2 = x2n / xd = -1 * u^2 * x1n / xd
|
|
235
|
+
let x2n = Fp.mul(x1n, Fp.neg(tv1));
|
|
182
236
|
let y2 = Fp.mul(y1, u); // 18. y2 = y1 * u
|
|
183
237
|
y2 = Fp.cmov(y2, Fp.ZERO, e1); // 19. y2 = CMOV(y2, 0, e1)
|
|
184
238
|
tv2 = Fp.sqr(y1); // 20. tv2 = y1^2
|
|
@@ -190,8 +244,10 @@ function map_to_curve_elligator2_curve448(u) {
|
|
|
190
244
|
y = Fp.cmov(y, Fp.neg(y), e2 !== e3); // 26. y = CMOV(y, -y, e2 XOR e3)
|
|
191
245
|
return { xn, xd, yn: y, yd: Fp.ONE }; // 27. return (xn, xd, y, 1)
|
|
192
246
|
}
|
|
247
|
+
// Returns affine `{ x, y }` after inverting the Appendix G.2.4 denominators.
|
|
193
248
|
function map_to_curve_elligator2_edwards448(u) {
|
|
194
|
-
|
|
249
|
+
// 1. (xn, xd, yn, yd) = map_to_curve_elligator2_curve448(u)
|
|
250
|
+
let { xn, xd, yn, yd } = map_to_curve_elligator2_curve448(u);
|
|
195
251
|
let xn2 = Fp.sqr(xn); // 2. xn2 = xn^2
|
|
196
252
|
let xd2 = Fp.sqr(xd); // 3. xd2 = xd^2
|
|
197
253
|
let xd4 = Fp.sqr(xd2); // 4. xd4 = xd2^2
|
|
@@ -231,7 +287,18 @@ function map_to_curve_elligator2_edwards448(u) {
|
|
|
231
287
|
const inv = FpInvertBatch(Fp, [xEd, yEd], true); // batch division
|
|
232
288
|
return { x: Fp.mul(xEn, inv[0]), y: Fp.mul(yEn, inv[1]) }; // 38. return (xEn, xEd, yEn, yEd)
|
|
233
289
|
}
|
|
234
|
-
/**
|
|
290
|
+
/**
|
|
291
|
+
* Hashing / encoding to ed448 points / field. RFC 9380 methods.
|
|
292
|
+
* Public `mapToCurve()` consumes one field element bigint for `m = 1`, and RFC
|
|
293
|
+
* Appendix J vectors use the special `QUUX-V01-*` test DST overrides rather
|
|
294
|
+
* than the default suite IDs below.
|
|
295
|
+
* @example
|
|
296
|
+
* Hash one message onto the ed448 curve.
|
|
297
|
+
*
|
|
298
|
+
* ```ts
|
|
299
|
+
* const point = ed448_hasher.hashToCurve(new TextEncoder().encode('hello noble'));
|
|
300
|
+
* ```
|
|
301
|
+
*/
|
|
235
302
|
export const ed448_hasher = /* @__PURE__ */ (() => createHasher(ed448_Point, (scalars) => map_to_curve_elligator2_edwards448(scalars[0]), {
|
|
236
303
|
DST: 'edwards448_XOF:SHAKE256_ELL2_RO_',
|
|
237
304
|
encodeDST: 'edwards448_XOF:SHAKE256_ELL2_NU_',
|
|
@@ -241,6 +308,32 @@ export const ed448_hasher = /* @__PURE__ */ (() => createHasher(ed448_Point, (sc
|
|
|
241
308
|
expand: 'xof',
|
|
242
309
|
hash: shake256,
|
|
243
310
|
}))();
|
|
311
|
+
/**
|
|
312
|
+
* FROST threshold signatures over ed448. RFC 9591.
|
|
313
|
+
* @example
|
|
314
|
+
* Create one trusted-dealer package for 2-of-3 ed448 signing.
|
|
315
|
+
*
|
|
316
|
+
* ```ts
|
|
317
|
+
* const alice = ed448_FROST.Identifier.derive('alice@example.com');
|
|
318
|
+
* const bob = ed448_FROST.Identifier.derive('bob@example.com');
|
|
319
|
+
* const carol = ed448_FROST.Identifier.derive('carol@example.com');
|
|
320
|
+
* const deal = ed448_FROST.trustedDealer({ min: 2, max: 3 }, [alice, bob, carol]);
|
|
321
|
+
* ```
|
|
322
|
+
*/
|
|
323
|
+
export const ed448_FROST = /* @__PURE__ */ (() => createFROST({
|
|
324
|
+
name: 'FROST-ED448-SHAKE256-v1',
|
|
325
|
+
Point: ed448_Point,
|
|
326
|
+
validatePoint: (p) => {
|
|
327
|
+
p.assertValidity();
|
|
328
|
+
if (!p.isTorsionFree())
|
|
329
|
+
throw new Error('bad point: not torsion-free');
|
|
330
|
+
},
|
|
331
|
+
// Group: edwards448 [RFC8032], where Ne = 57 and Ns = 57.
|
|
332
|
+
// Fn is 57 bytes, Fp is 57 bytes too
|
|
333
|
+
Fn,
|
|
334
|
+
hash: shake256_114,
|
|
335
|
+
H2: 'SigEd448\0\0',
|
|
336
|
+
}))();
|
|
244
337
|
// 1-d
|
|
245
338
|
const ONE_MINUS_D = /* @__PURE__ */ BigInt('39082');
|
|
246
339
|
// 1-2d
|
|
@@ -249,12 +342,21 @@ const ONE_MINUS_TWO_D = /* @__PURE__ */ BigInt('78163');
|
|
|
249
342
|
const SQRT_MINUS_D = /* @__PURE__ */ BigInt('98944233647732219769177004876929019128417576295529901074099889598043702116001257856802131563896515373927712232092845883226922417596214');
|
|
250
343
|
// 1 / √(-d)
|
|
251
344
|
const INVSQRT_MINUS_D = /* @__PURE__ */ BigInt('315019913931389607337177038330951043522456072897266928557328499619017160722351061360252776265186336876723201881398623946864393857820716');
|
|
252
|
-
//
|
|
253
|
-
|
|
345
|
+
// RFC 9496 `SQRT_RATIO_M1` must return `CT_ABS(s)`, i.e. the nonnegative root.
|
|
346
|
+
// Keep this Decaf-local: RFC 9496 decode/encode/map formulas depend on that
|
|
347
|
+
// canonical representative, while ordinary Ed448 decoding still uses `uvRatio()`
|
|
348
|
+
// plus the public sign bit from RFC 8032.
|
|
349
|
+
const sqrtRatioM1 = (u, v) => {
|
|
350
|
+
const P = ed448_CURVE_p;
|
|
351
|
+
const { isValid, value } = uvRatio(u, v);
|
|
352
|
+
return { isValid, value: isNegativeLE(value, P) ? Fp448.create(-value) : value };
|
|
353
|
+
};
|
|
354
|
+
const invertSqrt = (number) => sqrtRatioM1(_1n, number);
|
|
254
355
|
/**
|
|
255
356
|
* Elligator map for hash-to-curve of decaf448.
|
|
256
|
-
*
|
|
257
|
-
* and
|
|
357
|
+
* Primary formula source is RFC 9496 §5.3.4. Step 1 intentionally reduces the
|
|
358
|
+
* input modulo `p`, and the return value is the internal Edwards
|
|
359
|
+
* representation, not a public decaf encoding.
|
|
258
360
|
*/
|
|
259
361
|
function calcElligatorDecafMap(r0) {
|
|
260
362
|
const { d, p: P } = ed448_CURVE;
|
|
@@ -262,7 +364,7 @@ function calcElligatorDecafMap(r0) {
|
|
|
262
364
|
const r = mod(-(r0 * r0)); // 1
|
|
263
365
|
const u0 = mod(d * (r - _1n)); // 2
|
|
264
366
|
const u1 = mod((u0 + _1n) * (u0 - r)); // 3
|
|
265
|
-
const { isValid: was_square, value: v } =
|
|
367
|
+
const { isValid: was_square, value: v } = sqrtRatioM1(ONE_MINUS_TWO_D, mod((r + _1n) * u1)); // 4
|
|
266
368
|
let v_prime = v; // 5
|
|
267
369
|
if (!was_square)
|
|
268
370
|
v_prime = mod(r0 * v);
|
|
@@ -280,6 +382,12 @@ function calcElligatorDecafMap(r0) {
|
|
|
280
382
|
const W3 = mod(v_prime * s * (r - _1n) * ONE_MINUS_TWO_D + sgn); // 11
|
|
281
383
|
return new ed448_Point(mod(W0 * W3), mod(W2 * W1), mod(W1 * W3), mod(W0 * W2));
|
|
282
384
|
}
|
|
385
|
+
// Keep the Decaf448 base representative literal here: deriving it with
|
|
386
|
+
// `new _DecafPoint(ed448_Point.BASE).multiplyUnsafe(2)` forces eager WNAF precomputes and
|
|
387
|
+
// adds about 100ms to `ed448.js` import time.
|
|
388
|
+
const DECAF_BASE_X = /* @__PURE__ */ BigInt('0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa955555555555555555555555555555555555555555555555555555555');
|
|
389
|
+
const DECAF_BASE_Y = /* @__PURE__ */ BigInt('0xae05e9634ad7048db359d6205086c2b0036ed7a035884dd7b7e36d728ad8c4b80d6565833a2a3098bbbcb2bed1cda06bdaeafbcdea9386ed');
|
|
390
|
+
const DECAF_BASE_T = /* @__PURE__ */ BigInt('0x696d84643374bace9d70983a12aa9d461da74d2d5c35e8d97ba72c3aba4450a5d29274229bd22c1d5e3a6474ee4ffb0e7a9e200a28eee402');
|
|
283
391
|
/**
|
|
284
392
|
* Each ed448/EdwardsPoint has 4 different equivalent points. This can be
|
|
285
393
|
* a source of bugs for protocols like ring signatures. Decaf was created to solve this.
|
|
@@ -291,7 +399,7 @@ class _DecafPoint extends PrimeEdwardsPoint {
|
|
|
291
399
|
// The following gymnastics is done because typescript strips comments otherwise
|
|
292
400
|
// prettier-ignore
|
|
293
401
|
static BASE =
|
|
294
|
-
/* @__PURE__ */ (() => new _DecafPoint(ed448_Point
|
|
402
|
+
/* @__PURE__ */ (() => new _DecafPoint(new ed448_Point(DECAF_BASE_X, DECAF_BASE_Y, _1n, DECAF_BASE_T)))();
|
|
295
403
|
// prettier-ignore
|
|
296
404
|
static ZERO =
|
|
297
405
|
/* @__PURE__ */ (() => new _DecafPoint(ed448_Point.ZERO))();
|
|
@@ -304,6 +412,12 @@ class _DecafPoint extends PrimeEdwardsPoint {
|
|
|
304
412
|
constructor(ep) {
|
|
305
413
|
super(ep);
|
|
306
414
|
}
|
|
415
|
+
/**
|
|
416
|
+
* Create one Decaf448 point from affine Edwards coordinates.
|
|
417
|
+
* This wraps the internal Edwards representative directly and is not a
|
|
418
|
+
* canonical decaf448 decoding path.
|
|
419
|
+
* Use `toBytes()` / `fromBytes()` if canonical decaf448 bytes matter.
|
|
420
|
+
*/
|
|
307
421
|
static fromAffine(ap) {
|
|
308
422
|
return new _DecafPoint(ed448_Point.fromAffine(ap));
|
|
309
423
|
}
|
|
@@ -341,7 +455,7 @@ class _DecafPoint extends PrimeEdwardsPoint {
|
|
|
341
455
|
/**
|
|
342
456
|
* Converts decaf-encoded string to decaf point.
|
|
343
457
|
* Described in [RFC9496](https://www.rfc-editor.org/rfc/rfc9496#name-decode-2).
|
|
344
|
-
* @param hex Decaf-encoded 56 bytes. Not every 56-byte string is valid decaf encoding
|
|
458
|
+
* @param hex - Decaf-encoded 56 bytes. Not every 56-byte string is valid decaf encoding
|
|
345
459
|
*/
|
|
346
460
|
static fromHex(hex) {
|
|
347
461
|
return _DecafPoint.fromBytes(hexToBytes(hex));
|
|
@@ -381,12 +495,29 @@ class _DecafPoint extends PrimeEdwardsPoint {
|
|
|
381
495
|
return this.equals(_DecafPoint.ZERO);
|
|
382
496
|
}
|
|
383
497
|
}
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
498
|
+
Object.freeze(_DecafPoint.BASE);
|
|
499
|
+
Object.freeze(_DecafPoint.ZERO);
|
|
500
|
+
Object.freeze(_DecafPoint.prototype);
|
|
501
|
+
Object.freeze(_DecafPoint);
|
|
502
|
+
/** Prime-order Decaf448 group bundle. */
|
|
503
|
+
export const decaf448 = /* @__PURE__ */ Object.freeze({ Point: _DecafPoint });
|
|
504
|
+
/**
|
|
505
|
+
* Hashing to decaf448 points / field. RFC 9380 methods.
|
|
506
|
+
* `hashToCurve()` is RFC 9380 `hash_to_decaf448`, `deriveToCurve()` is RFC
|
|
507
|
+
* 9496 element derivation, and `hashToScalar()` is a library helper layered on
|
|
508
|
+
* top of RFC 9496 scalar reduction.
|
|
509
|
+
* @example
|
|
510
|
+
* Hash one message onto decaf448.
|
|
511
|
+
*
|
|
512
|
+
* ```ts
|
|
513
|
+
* const point = decaf448_hasher.hashToCurve(new TextEncoder().encode('hello noble'));
|
|
514
|
+
* ```
|
|
515
|
+
*/
|
|
516
|
+
export const decaf448_hasher = Object.freeze({
|
|
387
517
|
Point: _DecafPoint,
|
|
388
518
|
hashToCurve(msg, options) {
|
|
389
|
-
|
|
519
|
+
// Preserve explicit empty/invalid DST overrides so expand_message_xof() can reject them.
|
|
520
|
+
const DST = options?.DST === undefined ? 'decaf448_XOF:SHAKE256_D448MAP_RO_' : options.DST;
|
|
390
521
|
return decaf448_hasher.deriveToCurve(expand_message_xof(msg, DST, 112, 224, shake256));
|
|
391
522
|
},
|
|
392
523
|
/**
|
|
@@ -403,8 +534,10 @@ export const decaf448_hasher = {
|
|
|
403
534
|
* HashToCurve-like construction based on RFC 9496 (Element Derivation).
|
|
404
535
|
* Converts 112 uniform random bytes into a curve point.
|
|
405
536
|
*
|
|
406
|
-
* WARNING: This represents an older hash-to-curve construction
|
|
407
|
-
*
|
|
537
|
+
* WARNING: This represents an older hash-to-curve construction from before
|
|
538
|
+
* RFC 9380 was finalized.
|
|
539
|
+
* It was later reused as a component in the newer
|
|
540
|
+
* `hash_to_decaf448` function defined in RFC 9380.
|
|
408
541
|
*/
|
|
409
542
|
deriveToCurve(bytes) {
|
|
410
543
|
abytes(bytes, 112);
|
|
@@ -418,9 +551,21 @@ export const decaf448_hasher = {
|
|
|
418
551
|
const R2 = calcElligatorDecafMap(r2);
|
|
419
552
|
return new _DecafPoint(R1.add(R2));
|
|
420
553
|
},
|
|
421
|
-
};
|
|
422
|
-
/**
|
|
423
|
-
|
|
554
|
+
});
|
|
555
|
+
/**
|
|
556
|
+
* decaf448 OPRF, defined in RFC 9497.
|
|
557
|
+
* @example
|
|
558
|
+
* Run one blind/evaluate/finalize OPRF round over decaf448.
|
|
559
|
+
*
|
|
560
|
+
* ```ts
|
|
561
|
+
* const input = new TextEncoder().encode('hello noble');
|
|
562
|
+
* const keys = decaf448_oprf.oprf.generateKeyPair();
|
|
563
|
+
* const blind = decaf448_oprf.oprf.blind(input);
|
|
564
|
+
* const evaluated = decaf448_oprf.oprf.blindEvaluate(keys.secretKey, blind.blinded);
|
|
565
|
+
* const output = decaf448_oprf.oprf.finalize(input, blind.blind, evaluated);
|
|
566
|
+
* ```
|
|
567
|
+
*/
|
|
568
|
+
export const decaf448_oprf = /* @__PURE__ */ (() => createOPRF({
|
|
424
569
|
name: 'decaf448-SHAKE256',
|
|
425
570
|
Point: _DecafPoint,
|
|
426
571
|
hash: (msg) => shake256(msg, { dkLen: 64 }),
|
|
@@ -430,13 +575,20 @@ export const decaf448_oprf = /* @__PURE__ */ (() => createORPF({
|
|
|
430
575
|
/**
|
|
431
576
|
* Weird / bogus points, useful for debugging.
|
|
432
577
|
* Unlike ed25519, there is no ed448 generator point which can produce full T subgroup.
|
|
433
|
-
* Instead,
|
|
434
|
-
* (
|
|
578
|
+
* Instead, the torsion subgroup here is cyclic of order 4, generated by
|
|
579
|
+
* `(1, 0)`, and the array below lists that subgroup set (Klein four-group).
|
|
580
|
+
* @example
|
|
581
|
+
* Decode one known torsion point for debugging.
|
|
582
|
+
*
|
|
583
|
+
* ```ts
|
|
584
|
+
* import { ED448_TORSION_SUBGROUP, ed448 } from '@noble/curves/ed448.js';
|
|
585
|
+
* const point = ed448.Point.fromHex(ED448_TORSION_SUBGROUP[1]);
|
|
586
|
+
* ```
|
|
435
587
|
*/
|
|
436
|
-
export const ED448_TORSION_SUBGROUP = [
|
|
588
|
+
export const ED448_TORSION_SUBGROUP = /* @__PURE__ */ Object.freeze([
|
|
437
589
|
'010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
|
|
438
590
|
'fefffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffff00',
|
|
439
591
|
'000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
|
|
440
592
|
'000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080',
|
|
441
|
-
];
|
|
593
|
+
]);
|
|
442
594
|
//# sourceMappingURL=ed448.js.map
|