@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.
Files changed (110) hide show
  1. package/README.md +214 -122
  2. package/abstract/bls.d.ts +299 -16
  3. package/abstract/bls.d.ts.map +1 -1
  4. package/abstract/bls.js +82 -22
  5. package/abstract/bls.js.map +1 -1
  6. package/abstract/curve.d.ts +274 -27
  7. package/abstract/curve.d.ts.map +1 -1
  8. package/abstract/curve.js +177 -23
  9. package/abstract/curve.js.map +1 -1
  10. package/abstract/edwards.d.ts +166 -30
  11. package/abstract/edwards.d.ts.map +1 -1
  12. package/abstract/edwards.js +221 -86
  13. package/abstract/edwards.js.map +1 -1
  14. package/abstract/fft.d.ts +322 -10
  15. package/abstract/fft.d.ts.map +1 -1
  16. package/abstract/fft.js +154 -12
  17. package/abstract/fft.js.map +1 -1
  18. package/abstract/frost.d.ts +293 -0
  19. package/abstract/frost.d.ts.map +1 -0
  20. package/abstract/frost.js +704 -0
  21. package/abstract/frost.js.map +1 -0
  22. package/abstract/hash-to-curve.d.ts +173 -24
  23. package/abstract/hash-to-curve.d.ts.map +1 -1
  24. package/abstract/hash-to-curve.js +170 -31
  25. package/abstract/hash-to-curve.js.map +1 -1
  26. package/abstract/modular.d.ts +429 -37
  27. package/abstract/modular.d.ts.map +1 -1
  28. package/abstract/modular.js +414 -119
  29. package/abstract/modular.js.map +1 -1
  30. package/abstract/montgomery.d.ts +83 -12
  31. package/abstract/montgomery.d.ts.map +1 -1
  32. package/abstract/montgomery.js +32 -7
  33. package/abstract/montgomery.js.map +1 -1
  34. package/abstract/oprf.d.ts +164 -91
  35. package/abstract/oprf.d.ts.map +1 -1
  36. package/abstract/oprf.js +88 -29
  37. package/abstract/oprf.js.map +1 -1
  38. package/abstract/poseidon.d.ts +138 -7
  39. package/abstract/poseidon.d.ts.map +1 -1
  40. package/abstract/poseidon.js +178 -15
  41. package/abstract/poseidon.js.map +1 -1
  42. package/abstract/tower.d.ts +122 -3
  43. package/abstract/tower.d.ts.map +1 -1
  44. package/abstract/tower.js +323 -139
  45. package/abstract/tower.js.map +1 -1
  46. package/abstract/weierstrass.d.ts +339 -76
  47. package/abstract/weierstrass.d.ts.map +1 -1
  48. package/abstract/weierstrass.js +395 -205
  49. package/abstract/weierstrass.js.map +1 -1
  50. package/bls12-381.d.ts +16 -2
  51. package/bls12-381.d.ts.map +1 -1
  52. package/bls12-381.js +199 -209
  53. package/bls12-381.js.map +1 -1
  54. package/bn254.d.ts +11 -2
  55. package/bn254.d.ts.map +1 -1
  56. package/bn254.js +93 -38
  57. package/bn254.js.map +1 -1
  58. package/ed25519.d.ts +125 -14
  59. package/ed25519.d.ts.map +1 -1
  60. package/ed25519.js +202 -40
  61. package/ed25519.js.map +1 -1
  62. package/ed448.d.ts +108 -14
  63. package/ed448.d.ts.map +1 -1
  64. package/ed448.js +194 -42
  65. package/ed448.js.map +1 -1
  66. package/index.js +7 -1
  67. package/index.js.map +1 -1
  68. package/misc.d.ts +106 -7
  69. package/misc.d.ts.map +1 -1
  70. package/misc.js +141 -32
  71. package/misc.js.map +1 -1
  72. package/nist.d.ts +112 -11
  73. package/nist.d.ts.map +1 -1
  74. package/nist.js +139 -17
  75. package/nist.js.map +1 -1
  76. package/package.json +11 -6
  77. package/secp256k1.d.ts +92 -15
  78. package/secp256k1.d.ts.map +1 -1
  79. package/secp256k1.js +211 -28
  80. package/secp256k1.js.map +1 -1
  81. package/src/abstract/bls.ts +350 -67
  82. package/src/abstract/curve.ts +327 -44
  83. package/src/abstract/edwards.ts +367 -143
  84. package/src/abstract/fft.ts +369 -36
  85. package/src/abstract/frost.ts +1092 -0
  86. package/src/abstract/hash-to-curve.ts +255 -56
  87. package/src/abstract/modular.ts +591 -144
  88. package/src/abstract/montgomery.ts +114 -30
  89. package/src/abstract/oprf.ts +383 -194
  90. package/src/abstract/poseidon.ts +235 -35
  91. package/src/abstract/tower.ts +428 -159
  92. package/src/abstract/weierstrass.ts +710 -312
  93. package/src/bls12-381.ts +239 -236
  94. package/src/bn254.ts +107 -46
  95. package/src/ed25519.ts +227 -55
  96. package/src/ed448.ts +227 -57
  97. package/src/index.ts +7 -1
  98. package/src/misc.ts +154 -35
  99. package/src/nist.ts +143 -20
  100. package/src/secp256k1.ts +284 -41
  101. package/src/utils.ts +583 -81
  102. package/src/webcrypto.ts +302 -73
  103. package/utils.d.ts +457 -24
  104. package/utils.d.ts.map +1 -1
  105. package/utils.js +410 -53
  106. package/utils.js.map +1 -1
  107. package/webcrypto.d.ts +167 -25
  108. package/webcrypto.d.ts.map +1 -1
  109. package/webcrypto.js +165 -58
  110. 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
- /** Prehashed version of ed448. See {@link ed448} */
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 (NIST) != edwards448 used in ed448.
24
- * E448 is birationally equivalent to edwards448.
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
- /** Hashing / encoding to ed448 points / field. RFC 9380 methods. */
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
- /** Hashing to decaf448 points / field. RFC 9380 methods. */
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
- /** decaf448 OPRF, defined in RFC 9497. */
82
- export declare const decaf448_oprf: OPRF;
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, there is a Klein four-group, which spans over 2 independent 2-torsion points:
87
- * (0, 1), (0, -1), (-1, 0), (1, 0).
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;AAoI3D;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,KAAK,EAAE,KAA+B,CAAC;AAGpD,oDAAoD;AACpD,eAAO,MAAM,OAAO,EAAE,KAAqD,CAAC;AAC5E;;;GAGG;AACH,eAAO,MAAM,IAAI,EAAE,gBAAsD,CAAC;AAE1E;;;;;;;;;;GAUG;AACH,eAAO,MAAM,IAAI,EAAE,cAYf,CAAC;AA+EL,oEAAoE;AACpE,eAAO,MAAM,YAAY,EAAE,SAAS,CAAC,gBAAgB,CAS9C,CAAC;AAkDR;;;;;;GAMG;AACH,cAAM,WAAY,SAAQ,iBAAiB,CAAC,WAAW,CAAC;IAGtD,MAAM,CAAC,IAAI,EAAE,WAAW,CAC0D;IAElF,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,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,UAAU,GAAG,WAAW;IA6BhD;;;;OAIG;IACH,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW;IAIxC;;;OAGG;IACH,OAAO,IAAI,UAAU;IAerB;;;OAGG;IACH,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO;IAQnC,GAAG,IAAI,OAAO;CAGf;AAED,eAAO,MAAM,QAAQ,EAAE;IACrB,KAAK,EAAE,OAAO,WAAW,CAAC;CACF,CAAC;AAE3B,4DAA4D;AAC5D,eAAO,MAAM,eAAe,EAAE,aAAa,CAAC,OAAO,WAAW,CAmC7D,CAAC;AAEF,0CAA0C;AAC1C,eAAO,MAAM,aAAa,EAAE,IAOrB,CAAC;AAER;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,EAAE,MAAM,EAK1C,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 (not Ed448-Goldilocks) curve with following addons:
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 { createORPF } from "./abstract/oprf.js";
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
- // E448 NIST curve is identical to edwards448, except for:
35
- // d = 39082/39081
36
- // Gx = 3/2
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 ratio of u to v. Allows to combine inversion and square root u/√v.
77
- // Uses algo from RFC8032 5.1.3.
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
- // The value fits in 448 bits, but we use 456-bit (57-byte) elements because of bitflags.
99
- // - ed25519 fits in 255 bits, allowing using last 1 byte for specifying bit flag of point negation.
100
- // - ed448 fits in 448 bits. We can't use last 1 byte: we can only use a bit 224 in the middle.
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 uses 448-bit (56-byte) keys
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
- /** Prehashed version of ed448. See {@link ed448} */
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 (NIST) != edwards448 used in ed448.
134
- * E448 is birationally equivalent to edwards448.
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
- const ELL2_C1 = /* @__PURE__ */ (() => (ed448_CURVE_p - BigInt(3)) / BigInt(4))(); // 1. c1 = (q - 3) / 4 # Integer arithmetic
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
- let x2n = Fp.mul(x1n, Fp.neg(tv1)); // 17. x2n = -tv1 * x1n # x2 = x2n / xd = -1 * u^2 * x1n / xd
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
- let { xn, xd, yn, yd } = map_to_curve_elligator2_curve448(u); // 1. (xn, xd, yn, yd) = map_to_curve_elligator2_curve448(u)
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
- /** Hashing / encoding to ed448 points / field. RFC 9380 methods. */
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
- // Calculates 1/√(number)
253
- const invertSqrt = (number) => uvRatio(_1n, number);
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
- * Described in [RFC9380](https://www.rfc-editor.org/rfc/rfc9380#appendix-C)
257
- * and [RFC9496](https://www.rfc-editor.org/rfc/rfc9496#name-element-derivation-2).
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 } = uvRatio(ONE_MINUS_TWO_D, mod((r + _1n) * u1)); // 4
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.BASE).multiplyUnsafe(_2n))();
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
- export const decaf448 = { Point: _DecafPoint };
385
- /** Hashing to decaf448 points / field. RFC 9380 methods. */
386
- export const decaf448_hasher = {
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
- const DST = options?.DST || 'decaf448_XOF:SHAKE256_D448MAP_RO_';
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, preceding the finalization of RFC 9380.
407
- * It was later reused as a component in the newer `hash_to_ristretto255` function defined in RFC 9380.
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
- /** decaf448 OPRF, defined in RFC 9497. */
423
- export const decaf448_oprf = /* @__PURE__ */ (() => createORPF({
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, there is a Klein four-group, which spans over 2 independent 2-torsion points:
434
- * (0, 1), (0, -1), (-1, 0), (1, 0).
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