@noble/curves 1.9.0 → 1.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +78 -34
- package/_shortw_utils.d.ts +7 -5
- package/_shortw_utils.d.ts.map +1 -1
- package/_shortw_utils.js +2 -8
- package/_shortw_utils.js.map +1 -1
- package/abstract/bls.d.ts +60 -24
- package/abstract/bls.d.ts.map +1 -1
- package/abstract/bls.js +158 -109
- package/abstract/bls.js.map +1 -1
- package/abstract/curve.d.ts +44 -9
- package/abstract/curve.d.ts.map +1 -1
- package/abstract/curve.js +99 -11
- package/abstract/curve.js.map +1 -1
- package/abstract/edwards.d.ts +112 -25
- package/abstract/edwards.d.ts.map +1 -1
- package/abstract/edwards.js +141 -92
- package/abstract/edwards.js.map +1 -1
- package/abstract/fft.d.ts +122 -0
- package/abstract/fft.d.ts.map +1 -0
- package/abstract/fft.js +438 -0
- package/abstract/fft.js.map +1 -0
- package/abstract/hash-to-curve.d.ts +25 -11
- package/abstract/hash-to-curve.d.ts.map +1 -1
- package/abstract/hash-to-curve.js +17 -14
- package/abstract/hash-to-curve.js.map +1 -1
- package/abstract/modular.d.ts +28 -17
- package/abstract/modular.d.ts.map +1 -1
- package/abstract/modular.js +156 -139
- package/abstract/modular.js.map +1 -1
- package/abstract/montgomery.d.ts +3 -8
- package/abstract/montgomery.d.ts.map +1 -1
- package/abstract/montgomery.js +73 -93
- package/abstract/montgomery.js.map +1 -1
- package/abstract/poseidon.d.ts +5 -13
- package/abstract/poseidon.d.ts.map +1 -1
- package/abstract/poseidon.js +12 -7
- package/abstract/poseidon.js.map +1 -1
- package/abstract/tower.d.ts +20 -46
- package/abstract/tower.d.ts.map +1 -1
- package/abstract/tower.js +10 -4
- package/abstract/tower.js.map +1 -1
- package/abstract/utils.d.ts +1 -115
- package/abstract/utils.d.ts.map +1 -1
- package/abstract/utils.js +17 -371
- package/abstract/utils.js.map +1 -1
- package/abstract/weierstrass.d.ts +152 -73
- package/abstract/weierstrass.d.ts.map +1 -1
- package/abstract/weierstrass.js +487 -404
- package/abstract/weierstrass.js.map +1 -1
- package/bls12-381.d.ts +2 -0
- package/bls12-381.d.ts.map +1 -1
- package/bls12-381.js +504 -480
- package/bls12-381.js.map +1 -1
- package/bn254.d.ts +2 -0
- package/bn254.d.ts.map +1 -1
- package/bn254.js +44 -32
- package/bn254.js.map +1 -1
- package/ed25519.d.ts +25 -9
- package/ed25519.d.ts.map +1 -1
- package/ed25519.js +89 -65
- package/ed25519.js.map +1 -1
- package/ed448.d.ts +29 -10
- package/ed448.d.ts.map +1 -1
- package/ed448.js +116 -81
- package/ed448.js.map +1 -1
- package/esm/_shortw_utils.d.ts +7 -5
- package/esm/_shortw_utils.d.ts.map +1 -1
- package/esm/_shortw_utils.js +2 -8
- package/esm/_shortw_utils.js.map +1 -1
- package/esm/abstract/bls.d.ts +60 -24
- package/esm/abstract/bls.d.ts.map +1 -1
- package/esm/abstract/bls.js +158 -109
- package/esm/abstract/bls.js.map +1 -1
- package/esm/abstract/curve.d.ts +44 -9
- package/esm/abstract/curve.d.ts.map +1 -1
- package/esm/abstract/curve.js +96 -12
- package/esm/abstract/curve.js.map +1 -1
- package/esm/abstract/edwards.d.ts +112 -25
- package/esm/abstract/edwards.d.ts.map +1 -1
- package/esm/abstract/edwards.js +141 -94
- package/esm/abstract/edwards.js.map +1 -1
- package/esm/abstract/fft.d.ts +122 -0
- package/esm/abstract/fft.d.ts.map +1 -0
- package/esm/abstract/fft.js +425 -0
- package/esm/abstract/fft.js.map +1 -0
- package/esm/abstract/hash-to-curve.d.ts +25 -11
- package/esm/abstract/hash-to-curve.d.ts.map +1 -1
- package/esm/abstract/hash-to-curve.js +17 -14
- package/esm/abstract/hash-to-curve.js.map +1 -1
- package/esm/abstract/modular.d.ts +28 -17
- package/esm/abstract/modular.d.ts.map +1 -1
- package/esm/abstract/modular.js +155 -138
- package/esm/abstract/modular.js.map +1 -1
- package/esm/abstract/montgomery.d.ts +3 -8
- package/esm/abstract/montgomery.d.ts.map +1 -1
- package/esm/abstract/montgomery.js +74 -94
- package/esm/abstract/montgomery.js.map +1 -1
- package/esm/abstract/poseidon.d.ts +5 -13
- package/esm/abstract/poseidon.d.ts.map +1 -1
- package/esm/abstract/poseidon.js +12 -7
- package/esm/abstract/poseidon.js.map +1 -1
- package/esm/abstract/tower.d.ts +20 -46
- package/esm/abstract/tower.d.ts.map +1 -1
- package/esm/abstract/tower.js +10 -4
- package/esm/abstract/tower.js.map +1 -1
- package/esm/abstract/utils.d.ts +1 -115
- package/esm/abstract/utils.d.ts.map +1 -1
- package/esm/abstract/utils.js +3 -344
- package/esm/abstract/utils.js.map +1 -1
- package/esm/abstract/weierstrass.d.ts +152 -73
- package/esm/abstract/weierstrass.d.ts.map +1 -1
- package/esm/abstract/weierstrass.js +485 -406
- package/esm/abstract/weierstrass.js.map +1 -1
- package/esm/bls12-381.d.ts +2 -0
- package/esm/bls12-381.d.ts.map +1 -1
- package/esm/bls12-381.js +503 -479
- package/esm/bls12-381.js.map +1 -1
- package/esm/bn254.d.ts +2 -0
- package/esm/bn254.d.ts.map +1 -1
- package/esm/bn254.js +41 -29
- package/esm/bn254.js.map +1 -1
- package/esm/ed25519.d.ts +25 -9
- package/esm/ed25519.d.ts.map +1 -1
- package/esm/ed25519.js +84 -60
- package/esm/ed25519.js.map +1 -1
- package/esm/ed448.d.ts +29 -10
- package/esm/ed448.d.ts.map +1 -1
- package/esm/ed448.js +113 -78
- package/esm/ed448.js.map +1 -1
- package/esm/jubjub.d.ts +4 -0
- package/esm/jubjub.d.ts.map +1 -1
- package/esm/jubjub.js +4 -0
- package/esm/jubjub.js.map +1 -1
- package/esm/misc.d.ts.map +1 -1
- package/esm/misc.js +31 -26
- package/esm/misc.js.map +1 -1
- package/esm/nist.d.ts +8 -16
- package/esm/nist.d.ts.map +1 -1
- package/esm/nist.js +87 -97
- package/esm/nist.js.map +1 -1
- package/esm/p256.d.ts +3 -3
- package/esm/p384.d.ts +3 -3
- package/esm/p521.d.ts +3 -3
- package/esm/pasta.d.ts +4 -0
- package/esm/pasta.d.ts.map +1 -1
- package/esm/pasta.js +4 -0
- package/esm/pasta.js.map +1 -1
- package/esm/secp256k1.d.ts +6 -6
- package/esm/secp256k1.d.ts.map +1 -1
- package/esm/secp256k1.js +44 -41
- package/esm/secp256k1.js.map +1 -1
- package/esm/utils.d.ts +96 -0
- package/esm/utils.d.ts.map +1 -0
- package/esm/utils.js +279 -0
- package/esm/utils.js.map +1 -0
- package/jubjub.d.ts +4 -0
- package/jubjub.d.ts.map +1 -1
- package/jubjub.js +4 -0
- package/jubjub.js.map +1 -1
- package/misc.d.ts.map +1 -1
- package/misc.js +35 -30
- package/misc.js.map +1 -1
- package/nist.d.ts +8 -16
- package/nist.d.ts.map +1 -1
- package/nist.js +87 -97
- package/nist.js.map +1 -1
- package/p256.d.ts +3 -3
- package/p384.d.ts +3 -3
- package/p521.d.ts +3 -3
- package/package.json +26 -8
- package/pasta.d.ts +4 -0
- package/pasta.d.ts.map +1 -1
- package/pasta.js +4 -0
- package/pasta.js.map +1 -1
- package/secp256k1.d.ts +6 -6
- package/secp256k1.d.ts.map +1 -1
- package/secp256k1.js +47 -44
- package/secp256k1.js.map +1 -1
- package/src/_shortw_utils.ts +5 -15
- package/src/abstract/bls.ts +260 -145
- package/src/abstract/curve.ts +125 -18
- package/src/abstract/edwards.ts +282 -127
- package/src/abstract/fft.ts +519 -0
- package/src/abstract/hash-to-curve.ts +51 -27
- package/src/abstract/modular.ts +156 -143
- package/src/abstract/montgomery.ts +81 -111
- package/src/abstract/poseidon.ts +22 -18
- package/src/abstract/tower.ts +37 -68
- package/src/abstract/utils.ts +3 -378
- package/src/abstract/weierstrass.ts +752 -461
- package/src/bls12-381.ts +542 -507
- package/src/bn254.ts +47 -35
- package/src/ed25519.ts +104 -76
- package/src/ed448.ts +156 -105
- package/src/jubjub.ts +4 -0
- package/src/misc.ts +39 -34
- package/src/nist.ts +138 -126
- package/src/p256.ts +3 -3
- package/src/p384.ts +3 -3
- package/src/p521.ts +3 -3
- package/src/pasta.ts +5 -1
- package/src/secp256k1.ts +59 -47
- package/src/utils.ts +328 -0
- package/utils.d.ts +96 -0
- package/utils.d.ts.map +1 -0
- package/utils.js +313 -0
- package/utils.js.map +1 -0
package/src/ed448.ts
CHANGED
|
@@ -7,17 +7,29 @@
|
|
|
7
7
|
* @module
|
|
8
8
|
*/
|
|
9
9
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
10
|
-
import { shake256 } from '@noble/hashes/sha3';
|
|
11
|
-
import {
|
|
10
|
+
import { shake256 } from '@noble/hashes/sha3.js';
|
|
11
|
+
import {
|
|
12
|
+
abytes,
|
|
13
|
+
concatBytes,
|
|
14
|
+
utf8ToBytes,
|
|
15
|
+
createHasher as wrapConstructor,
|
|
16
|
+
} from '@noble/hashes/utils.js';
|
|
12
17
|
import type { AffinePoint, Group } from './abstract/curve.ts';
|
|
13
18
|
import { pippenger } from './abstract/curve.ts';
|
|
14
|
-
import {
|
|
19
|
+
import {
|
|
20
|
+
type CurveFn,
|
|
21
|
+
edwards,
|
|
22
|
+
type EdwardsOpts,
|
|
23
|
+
type ExtPointConstructor,
|
|
24
|
+
type ExtPointType,
|
|
25
|
+
twistedEdwards,
|
|
26
|
+
} from './abstract/edwards.ts';
|
|
15
27
|
import {
|
|
16
28
|
createHasher,
|
|
17
29
|
expand_message_xof,
|
|
18
|
-
type
|
|
30
|
+
type H2CHasher,
|
|
31
|
+
type H2CMethod,
|
|
19
32
|
type htfBasicOpts,
|
|
20
|
-
type HTFMethod,
|
|
21
33
|
} from './abstract/hash-to-curve.ts';
|
|
22
34
|
import { Field, FpInvertBatch, isNegativeLE, mod, pow2 } from './abstract/modular.ts';
|
|
23
35
|
import { montgomery, type CurveFn as XCurveFn } from './abstract/montgomery.ts';
|
|
@@ -28,13 +40,53 @@ import {
|
|
|
28
40
|
equalBytes,
|
|
29
41
|
type Hex,
|
|
30
42
|
numberToBytesLE,
|
|
31
|
-
} from './
|
|
43
|
+
} from './utils.ts';
|
|
44
|
+
|
|
45
|
+
// a = 1n
|
|
46
|
+
// d = Fp.neg(39081n)
|
|
47
|
+
// Finite field 2n**448n - 2n**224n - 1n
|
|
48
|
+
// Subgroup order
|
|
49
|
+
// 2n**446n - 13818066809895115352007386748515426880336692474882178609894547503885n
|
|
50
|
+
const ed448_CURVE: EdwardsOpts = {
|
|
51
|
+
p: BigInt(
|
|
52
|
+
'0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
|
|
53
|
+
),
|
|
54
|
+
n: BigInt(
|
|
55
|
+
'0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffff7cca23e9c44edb49aed63690216cc2728dc58f552378c292ab5844f3'
|
|
56
|
+
),
|
|
57
|
+
h: BigInt(4),
|
|
58
|
+
a: BigInt(1),
|
|
59
|
+
d: BigInt(
|
|
60
|
+
'0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffff6756'
|
|
61
|
+
),
|
|
62
|
+
Gx: BigInt(
|
|
63
|
+
'0x4f1970c66bed0ded221d15a622bf36da9e146570470f1767ea6de324a3d3a46412ae1af72ab66511433b80e18b00938e2626a82bc70cc05e'
|
|
64
|
+
),
|
|
65
|
+
Gy: BigInt(
|
|
66
|
+
'0x693f46716eb6bc248876203756c9c7624bea73736ca3984087789c1e05a0c2d73ad3ff1ce67c39c4fdbd132c4ed7c8ad9808795bf230fa14'
|
|
67
|
+
),
|
|
68
|
+
};
|
|
32
69
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
70
|
+
// E448 != Edwards448 used in ed448
|
|
71
|
+
// E448 is defined by NIST
|
|
72
|
+
// It's birationally equivalent to edwards448
|
|
73
|
+
// d = 39082/39081
|
|
74
|
+
// Gx = 3/2
|
|
75
|
+
const E448_CURVE: EdwardsOpts = Object.assign({}, ed448_CURVE, {
|
|
76
|
+
d: BigInt(
|
|
77
|
+
'0xd78b4bdc7f0daf19f24f38c29373a2ccad46157242a50f37809b1da3412a12e79ccc9c81264cfe9ad080997058fb61c4243cc32dbaa156b9'
|
|
78
|
+
),
|
|
79
|
+
Gx: BigInt(
|
|
80
|
+
'0x79a70b2b70400553ae7c9df416c792c61128751ac92969240c25a07d728bdc93e21f7787ed6972249de732f38496cd11698713093e9c04fc'
|
|
81
|
+
),
|
|
82
|
+
Gy: BigInt(
|
|
83
|
+
'0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffff80000000000000000000000000000000000000000000000000000001'
|
|
84
|
+
),
|
|
85
|
+
});
|
|
86
|
+
export const E448: ExtPointConstructor = edwards(E448_CURVE);
|
|
87
|
+
|
|
88
|
+
const shake256_114 = /* @__PURE__ */ wrapConstructor(() => shake256.create({ dkLen: 114 }));
|
|
89
|
+
const shake256_64 = /* @__PURE__ */ wrapConstructor(() => shake256.create({ dkLen: 64 }));
|
|
38
90
|
|
|
39
91
|
// prettier-ignore
|
|
40
92
|
const _1n = BigInt(1), _2n = BigInt(2), _3n = BigInt(3), _4n = BigInt(4), _11n = BigInt(11);
|
|
@@ -45,7 +97,7 @@ const _22n = BigInt(22), _44n = BigInt(44), _88n = BigInt(88), _223n = BigInt(22
|
|
|
45
97
|
// Used for efficient square root calculation.
|
|
46
98
|
// ((P-3)/4).toString(2) would produce bits [223x 1, 0, 222x 1]
|
|
47
99
|
function ed448_pow_Pminus3div4(x: bigint): bigint {
|
|
48
|
-
const P =
|
|
100
|
+
const P = ed448_CURVE.p;
|
|
49
101
|
const b2 = (x * x * x) % P;
|
|
50
102
|
const b3 = (b2 * b2 * x) % P;
|
|
51
103
|
const b6 = (pow2(b3, _3n, P) * b3) % P;
|
|
@@ -75,7 +127,7 @@ function adjustScalarBytes(bytes: Uint8Array): Uint8Array {
|
|
|
75
127
|
// Constant-time ratio of u to v. Allows to combine inversion and square root u/√v.
|
|
76
128
|
// Uses algo from RFC8032 5.1.3.
|
|
77
129
|
function uvRatio(u: bigint, v: bigint): { isValid: boolean; value: bigint } {
|
|
78
|
-
const P =
|
|
130
|
+
const P = ed448_CURVE.p;
|
|
79
131
|
// https://www.rfc-editor.org/rfc/rfc8032#section-5.2.3
|
|
80
132
|
// To compute the square root of (u/v), the first step is to compute the
|
|
81
133
|
// candidate root x = (u/v)^((p+1)/4). This can be done using the
|
|
@@ -94,34 +146,15 @@ function uvRatio(u: bigint, v: bigint): { isValid: boolean; value: bigint } {
|
|
|
94
146
|
return { isValid: mod(x2 * v, P) === u, value: x };
|
|
95
147
|
}
|
|
96
148
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
d: BigInt(
|
|
104
|
-
'726838724295606890549323807888004534353641360687318060281490199180612328166730772686396383698676545930088884461843637361053498018326358'
|
|
105
|
-
),
|
|
106
|
-
// Finite field 2n**448n - 2n**224n - 1n
|
|
149
|
+
// Finite field 2n**448n - 2n**224n - 1n
|
|
150
|
+
const Fp = /* @__PURE__ */ (() => Field(ed448_CURVE.p, 456, true))();
|
|
151
|
+
// RFC 7748 has 56-byte keys, RFC 8032 has 57-byte keys
|
|
152
|
+
// SHAKE256(dom4(phflag,context)||x, 114)
|
|
153
|
+
const ED448_DEF = /* @__PURE__ */ (() => ({
|
|
154
|
+
...ed448_CURVE,
|
|
107
155
|
Fp,
|
|
108
|
-
// Subgroup order
|
|
109
|
-
// 2n**446n - 13818066809895115352007386748515426880336692474882178609894547503885n
|
|
110
|
-
n: BigInt(
|
|
111
|
-
'181709681073901722637330951972001133588410340171829515070372549795146003961539585716195755291692375963310293709091662304773755859649779'
|
|
112
|
-
),
|
|
113
|
-
// RFC 7748 has 56-byte keys, RFC 8032 has 57-byte keys
|
|
114
156
|
nBitLength: 456,
|
|
115
|
-
h: BigInt(4),
|
|
116
|
-
Gx: BigInt(
|
|
117
|
-
'224580040295924300187604334099896036246789641632564134246125461686950415467406032909029192869357953282578032075146446173674602635247710'
|
|
118
|
-
),
|
|
119
|
-
Gy: BigInt(
|
|
120
|
-
'298819210078481492676017930443930673437544040154080242095928241372331506189835876003536878655418784733982303233503462500531545062832660'
|
|
121
|
-
),
|
|
122
|
-
// SHAKE256(dom4(phflag,context)||x, 114)
|
|
123
157
|
hash: shake256_114,
|
|
124
|
-
randomBytes,
|
|
125
158
|
adjustScalarBytes,
|
|
126
159
|
// dom4
|
|
127
160
|
domain: (data: Uint8Array, ctx: Uint8Array, phflag: boolean) => {
|
|
@@ -134,7 +167,7 @@ const ED448_DEF = {
|
|
|
134
167
|
);
|
|
135
168
|
},
|
|
136
169
|
uvRatio,
|
|
137
|
-
}
|
|
170
|
+
}))();
|
|
138
171
|
|
|
139
172
|
/**
|
|
140
173
|
* ed448 EdDSA curve and methods.
|
|
@@ -146,33 +179,32 @@ const ED448_DEF = {
|
|
|
146
179
|
* const sig = ed448.sign(msg, priv);
|
|
147
180
|
* ed448.verify(sig, msg, pub);
|
|
148
181
|
*/
|
|
149
|
-
export const ed448: CurveFn =
|
|
182
|
+
export const ed448: CurveFn = twistedEdwards(ED448_DEF);
|
|
150
183
|
// NOTE: there is no ed448ctx, since ed448 supports ctx by default
|
|
151
|
-
export const ed448ph: CurveFn = /* @__PURE__ */
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
184
|
+
export const ed448ph: CurveFn = /* @__PURE__ */ (() =>
|
|
185
|
+
twistedEdwards({
|
|
186
|
+
...ED448_DEF,
|
|
187
|
+
prehash: shake256_64,
|
|
188
|
+
}))();
|
|
155
189
|
|
|
156
190
|
/**
|
|
157
191
|
* ECDH using curve448 aka x448.
|
|
192
|
+
* x448 has 56-byte keys as per RFC 7748, while
|
|
193
|
+
* ed448 has 57-byte keys as per RFC 8032.
|
|
158
194
|
*/
|
|
159
|
-
export const x448: XCurveFn = /* @__PURE__ */ (() =>
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
nByteLength: 56,
|
|
165
|
-
P: ed448P,
|
|
166
|
-
Gu: BigInt(5),
|
|
195
|
+
export const x448: XCurveFn = /* @__PURE__ */ (() => {
|
|
196
|
+
const P = ed448_CURVE.p;
|
|
197
|
+
return montgomery({
|
|
198
|
+
P,
|
|
199
|
+
type: 'x448',
|
|
167
200
|
powPminus2: (x: bigint): bigint => {
|
|
168
|
-
const P = ed448P;
|
|
169
201
|
const Pminus3div4 = ed448_pow_Pminus3div4(x);
|
|
170
|
-
const Pminus3 = pow2(Pminus3div4,
|
|
202
|
+
const Pminus3 = pow2(Pminus3div4, _2n, P);
|
|
171
203
|
return mod(Pminus3 * x, P); // Pminus3 * x = Pminus2
|
|
172
204
|
},
|
|
173
205
|
adjustScalarBytes,
|
|
174
|
-
|
|
175
|
-
|
|
206
|
+
});
|
|
207
|
+
})();
|
|
176
208
|
|
|
177
209
|
/**
|
|
178
210
|
* Converts edwards448 public key to x448 public key. Uses formula:
|
|
@@ -183,7 +215,8 @@ export const x448: XCurveFn = /* @__PURE__ */ (() =>
|
|
|
183
215
|
* x448.getSharedSecret(edwardsToMontgomery(aPub), edwardsToMontgomery(someonesPub))
|
|
184
216
|
*/
|
|
185
217
|
export function edwardsToMontgomeryPub(edwardsPub: string | Uint8Array): Uint8Array {
|
|
186
|
-
const
|
|
218
|
+
const bpub = ensureBytes('pub', edwardsPub);
|
|
219
|
+
const { y } = ed448.Point.fromHex(bpub);
|
|
187
220
|
const _1n = BigInt(1);
|
|
188
221
|
return Fp.toBytes(Fp.create((y - _1n) * Fp.inv(y + _1n)));
|
|
189
222
|
}
|
|
@@ -192,8 +225,8 @@ export const edwardsToMontgomery: typeof edwardsToMontgomeryPub = edwardsToMontg
|
|
|
192
225
|
// TODO: add edwardsToMontgomeryPriv, similar to ed25519 version
|
|
193
226
|
|
|
194
227
|
// Hash To Curve Elligator2 Map
|
|
195
|
-
const ELL2_C1 = (Fp.ORDER - BigInt(3)) / BigInt(4); // 1. c1 = (q - 3) / 4 # Integer arithmetic
|
|
196
|
-
const ELL2_J = BigInt(156326);
|
|
228
|
+
const ELL2_C1 = /* @__PURE__ */ (() => (Fp.ORDER - BigInt(3)) / BigInt(4))(); // 1. c1 = (q - 3) / 4 # Integer arithmetic
|
|
229
|
+
const ELL2_J = /* @__PURE__ */ BigInt(156326);
|
|
197
230
|
|
|
198
231
|
function map_to_curve_elligator2_curve448(u: bigint) {
|
|
199
232
|
let tv1 = Fp.sqr(u); // 1. tv1 = u^2
|
|
@@ -268,22 +301,18 @@ function map_to_curve_elligator2_edwards448(u: bigint) {
|
|
|
268
301
|
return { x: Fp.mul(xEn, inv[0]), y: Fp.mul(yEn, inv[1]) }; // 38. return (xEn, xEd, yEn, yEd)
|
|
269
302
|
}
|
|
270
303
|
|
|
271
|
-
export const ed448_hasher:
|
|
272
|
-
createHasher(
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
}
|
|
284
|
-
))();
|
|
285
|
-
export const hashToCurve: HTFMethod<bigint> = /* @__PURE__ */ (() => ed448_hasher.hashToCurve)();
|
|
286
|
-
export const encodeToCurve: HTFMethod<bigint> = /* @__PURE__ */ (() =>
|
|
304
|
+
export const ed448_hasher: H2CHasher<bigint> = /* @__PURE__ */ (() =>
|
|
305
|
+
createHasher(ed448.Point, (scalars: bigint[]) => map_to_curve_elligator2_edwards448(scalars[0]), {
|
|
306
|
+
DST: 'edwards448_XOF:SHAKE256_ELL2_RO_',
|
|
307
|
+
encodeDST: 'edwards448_XOF:SHAKE256_ELL2_NU_',
|
|
308
|
+
p: Fp.ORDER,
|
|
309
|
+
m: 1,
|
|
310
|
+
k: 224,
|
|
311
|
+
expand: 'xof',
|
|
312
|
+
hash: shake256,
|
|
313
|
+
}))();
|
|
314
|
+
export const hashToCurve: H2CMethod<bigint> = /* @__PURE__ */ (() => ed448_hasher.hashToCurve)();
|
|
315
|
+
export const encodeToCurve: H2CMethod<bigint> = /* @__PURE__ */ (() =>
|
|
287
316
|
ed448_hasher.encodeToCurve)();
|
|
288
317
|
|
|
289
318
|
function adecafp(other: unknown) {
|
|
@@ -291,34 +320,36 @@ function adecafp(other: unknown) {
|
|
|
291
320
|
}
|
|
292
321
|
|
|
293
322
|
// 1-d
|
|
294
|
-
const ONE_MINUS_D = BigInt('39082');
|
|
323
|
+
const ONE_MINUS_D = /* @__PURE__ */ BigInt('39082');
|
|
295
324
|
// 1-2d
|
|
296
|
-
const ONE_MINUS_TWO_D = BigInt('78163');
|
|
325
|
+
const ONE_MINUS_TWO_D = /* @__PURE__ */ BigInt('78163');
|
|
297
326
|
// √(-d)
|
|
298
|
-
const SQRT_MINUS_D = BigInt(
|
|
327
|
+
const SQRT_MINUS_D = /* @__PURE__ */ BigInt(
|
|
299
328
|
'98944233647732219769177004876929019128417576295529901074099889598043702116001257856802131563896515373927712232092845883226922417596214'
|
|
300
329
|
);
|
|
301
330
|
// 1 / √(-d)
|
|
302
|
-
const INVSQRT_MINUS_D = BigInt(
|
|
331
|
+
const INVSQRT_MINUS_D = /* @__PURE__ */ BigInt(
|
|
303
332
|
'315019913931389607337177038330951043522456072897266928557328499619017160722351061360252776265186336876723201881398623946864393857820716'
|
|
304
333
|
);
|
|
305
334
|
// Calculates 1/√(number)
|
|
306
335
|
const invertSqrt = (number: bigint) => uvRatio(_1n, number);
|
|
307
336
|
|
|
308
|
-
const MAX_448B = BigInt(
|
|
337
|
+
const MAX_448B = /* @__PURE__ */ BigInt(
|
|
309
338
|
'0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
|
|
310
339
|
);
|
|
311
|
-
const bytes448ToNumberLE = (bytes: Uint8Array) =>
|
|
312
|
-
ed448.CURVE.Fp.create(bytesToNumberLE(bytes) & MAX_448B);
|
|
340
|
+
const bytes448ToNumberLE = (bytes: Uint8Array) => Fp.create(bytesToNumberLE(bytes) & MAX_448B);
|
|
313
341
|
|
|
314
342
|
type ExtendedPoint = ExtPointType;
|
|
315
343
|
|
|
316
|
-
|
|
317
|
-
|
|
344
|
+
/**
|
|
345
|
+
* Elligator map for hash-to-curve of decaf448.
|
|
346
|
+
* Described in [RFC9380](https://www.rfc-editor.org/rfc/rfc9380#appendix-C)
|
|
347
|
+
* and [RFC9496](https://www.rfc-editor.org/rfc/rfc9496#name-element-derivation-2).
|
|
348
|
+
*/
|
|
318
349
|
function calcElligatorDecafMap(r0: bigint): ExtendedPoint {
|
|
319
350
|
const { d } = ed448.CURVE;
|
|
320
|
-
const P =
|
|
321
|
-
const mod =
|
|
351
|
+
const P = Fp.ORDER;
|
|
352
|
+
const mod = Fp.create;
|
|
322
353
|
|
|
323
354
|
const r = mod(-(r0 * r0)); // 1
|
|
324
355
|
const u0 = mod(d * (r - _1n)); // 2
|
|
@@ -341,7 +372,7 @@ function calcElligatorDecafMap(r0: bigint): ExtendedPoint {
|
|
|
341
372
|
const W1 = mod(s2 + _1n); // 9
|
|
342
373
|
const W2 = mod(s2 - _1n); // 10
|
|
343
374
|
const W3 = mod(v_prime * s * (r - _1n) * ONE_MINUS_TWO_D + sgn); // 11
|
|
344
|
-
return new ed448.
|
|
375
|
+
return new ed448.Point(mod(W0 * W3), mod(W2 * W1), mod(W1 * W3), mod(W0 * W2));
|
|
345
376
|
}
|
|
346
377
|
|
|
347
378
|
/**
|
|
@@ -349,7 +380,7 @@ function calcElligatorDecafMap(r0: bigint): ExtendedPoint {
|
|
|
349
380
|
* a source of bugs for protocols like ring signatures. Decaf was created to solve this.
|
|
350
381
|
* Decaf point operates in X:Y:Z:T extended coordinates like ExtendedPoint,
|
|
351
382
|
* but it should work in its own namespace: do not combine those two.
|
|
352
|
-
* https://
|
|
383
|
+
* See [RFC9496](https://www.rfc-editor.org/rfc/rfc9496).
|
|
353
384
|
*/
|
|
354
385
|
class DcfPoint implements Group<DcfPoint> {
|
|
355
386
|
static BASE: DcfPoint;
|
|
@@ -362,14 +393,15 @@ class DcfPoint implements Group<DcfPoint> {
|
|
|
362
393
|
}
|
|
363
394
|
|
|
364
395
|
static fromAffine(ap: AffinePoint<bigint>): DcfPoint {
|
|
365
|
-
return new DcfPoint(ed448.
|
|
396
|
+
return new DcfPoint(ed448.Point.fromAffine(ap));
|
|
366
397
|
}
|
|
367
398
|
|
|
368
399
|
/**
|
|
369
400
|
* Takes uniform output of 112-byte hash function like shake256 and converts it to `DecafPoint`.
|
|
370
401
|
* The hash-to-group operation applies Elligator twice and adds the results.
|
|
371
402
|
* **Note:** this is one-way map, there is no conversion from point to hash.
|
|
372
|
-
* https://
|
|
403
|
+
* Described in [RFC9380](https://www.rfc-editor.org/rfc/rfc9380#appendix-C)
|
|
404
|
+
* and [RFC9496](https://www.rfc-editor.org/rfc/rfc9496#name-element-derivation-2).
|
|
373
405
|
* @param hex 112-byte output of a hash function
|
|
374
406
|
*/
|
|
375
407
|
static hashToCurve(hex: Hex): DcfPoint {
|
|
@@ -381,16 +413,21 @@ class DcfPoint implements Group<DcfPoint> {
|
|
|
381
413
|
return new DcfPoint(R1.add(R2));
|
|
382
414
|
}
|
|
383
415
|
|
|
416
|
+
static fromBytes(bytes: Uint8Array): DcfPoint {
|
|
417
|
+
abytes(bytes);
|
|
418
|
+
return this.fromHex(bytes);
|
|
419
|
+
}
|
|
420
|
+
|
|
384
421
|
/**
|
|
385
422
|
* Converts decaf-encoded string to decaf point.
|
|
386
|
-
* https://
|
|
423
|
+
* Described in [RFC9496](https://www.rfc-editor.org/rfc/rfc9496#name-decode-2).
|
|
387
424
|
* @param hex Decaf-encoded 56 bytes. Not every 56-byte string is valid decaf encoding
|
|
388
425
|
*/
|
|
389
426
|
static fromHex(hex: Hex): DcfPoint {
|
|
390
427
|
hex = ensureBytes('decafHex', hex, 56);
|
|
391
428
|
const { d } = ed448.CURVE;
|
|
392
|
-
const P =
|
|
393
|
-
const mod =
|
|
429
|
+
const P = Fp.ORDER;
|
|
430
|
+
const mod = Fp.create;
|
|
394
431
|
const emsg = 'DecafPoint.fromHex: the hex is not valid encoding of DecafPoint';
|
|
395
432
|
const s = bytes448ToNumberLE(hex);
|
|
396
433
|
|
|
@@ -413,7 +450,7 @@ class DcfPoint implements Group<DcfPoint> {
|
|
|
413
450
|
const t = mod(x * y); // 8
|
|
414
451
|
|
|
415
452
|
if (!isValid) throw new Error(emsg);
|
|
416
|
-
return new DcfPoint(new ed448.
|
|
453
|
+
return new DcfPoint(new ed448.Point(x, y, _1n, t));
|
|
417
454
|
}
|
|
418
455
|
|
|
419
456
|
static msm(points: DcfPoint[], scalars: bigint[]): DcfPoint {
|
|
@@ -423,12 +460,12 @@ class DcfPoint implements Group<DcfPoint> {
|
|
|
423
460
|
|
|
424
461
|
/**
|
|
425
462
|
* Encodes decaf point to Uint8Array.
|
|
426
|
-
* https://
|
|
463
|
+
* Described in [RFC9496](https://www.rfc-editor.org/rfc/rfc9496#name-encode-2).
|
|
427
464
|
*/
|
|
428
|
-
|
|
465
|
+
toBytes(): Uint8Array {
|
|
429
466
|
let { ex: x, ey: _y, ez: z, et: t } = this.ep;
|
|
430
|
-
const P =
|
|
431
|
-
const mod =
|
|
467
|
+
const P = Fp.ORDER;
|
|
468
|
+
const mod = Fp.create;
|
|
432
469
|
|
|
433
470
|
const u1 = mod(mod(x + t) * mod(x - t)); // 1
|
|
434
471
|
const x2 = mod(x * x);
|
|
@@ -445,21 +482,28 @@ class DcfPoint implements Group<DcfPoint> {
|
|
|
445
482
|
return numberToBytesLE(s, 56);
|
|
446
483
|
}
|
|
447
484
|
|
|
485
|
+
/** @deprecated use `toBytes` */
|
|
486
|
+
toRawBytes(): Uint8Array {
|
|
487
|
+
return this.toBytes();
|
|
488
|
+
}
|
|
489
|
+
|
|
448
490
|
toHex(): string {
|
|
449
|
-
return bytesToHex(this.
|
|
491
|
+
return bytesToHex(this.toBytes());
|
|
450
492
|
}
|
|
451
493
|
|
|
452
494
|
toString(): string {
|
|
453
495
|
return this.toHex();
|
|
454
496
|
}
|
|
455
497
|
|
|
456
|
-
|
|
457
|
-
|
|
498
|
+
/**
|
|
499
|
+
* Compare one point to another.
|
|
500
|
+
* Described in [RFC9496](https://www.rfc-editor.org/rfc/rfc9496#name-equals-2).
|
|
501
|
+
*/
|
|
458
502
|
equals(other: DcfPoint): boolean {
|
|
459
503
|
adecafp(other);
|
|
460
504
|
const { ex: X1, ey: Y1 } = this.ep;
|
|
461
505
|
const { ex: X2, ey: Y2 } = other.ep;
|
|
462
|
-
const mod =
|
|
506
|
+
const mod = Fp.create;
|
|
463
507
|
// (x1 * y2 == y1 * x2)
|
|
464
508
|
return mod(X1 * Y2) === mod(Y1 * X2);
|
|
465
509
|
}
|
|
@@ -491,15 +535,22 @@ class DcfPoint implements Group<DcfPoint> {
|
|
|
491
535
|
}
|
|
492
536
|
}
|
|
493
537
|
|
|
538
|
+
/**
|
|
539
|
+
* Wrapper over Edwards Point for decaf448 from
|
|
540
|
+
* [RFC9496](https://www.rfc-editor.org/rfc/rfc9496).
|
|
541
|
+
*/
|
|
494
542
|
export const DecafPoint: typeof DcfPoint = /* @__PURE__ */ (() => {
|
|
495
543
|
// decaf448 base point is ed448 base x 2
|
|
496
544
|
// https://github.com/dalek-cryptography/curve25519-dalek/blob/59837c6ecff02b77b9d5ff84dbc239d0cf33ef90/vendor/ristretto.sage#L699
|
|
497
|
-
if (!DcfPoint.BASE) DcfPoint.BASE = new DcfPoint(ed448.
|
|
498
|
-
if (!DcfPoint.ZERO) DcfPoint.ZERO = new DcfPoint(ed448.
|
|
545
|
+
if (!DcfPoint.BASE) DcfPoint.BASE = new DcfPoint(ed448.Point.BASE).multiply(_2n);
|
|
546
|
+
if (!DcfPoint.ZERO) DcfPoint.ZERO = new DcfPoint(ed448.Point.ZERO);
|
|
499
547
|
return DcfPoint;
|
|
500
548
|
})();
|
|
501
549
|
|
|
502
|
-
|
|
550
|
+
/**
|
|
551
|
+
* hash-to-curve for decaf448.
|
|
552
|
+
* Described in [RFC9380](https://www.rfc-editor.org/rfc/rfc9380#appendix-C).
|
|
553
|
+
*/
|
|
503
554
|
export const hashToDecaf448 = (msg: Uint8Array, options: htfBasicOpts): DcfPoint => {
|
|
504
555
|
const d = options.DST;
|
|
505
556
|
const DST = typeof d === 'string' ? utf8ToBytes(d) : d;
|
package/src/jubjub.ts
CHANGED
package/src/misc.ts
CHANGED
|
@@ -4,52 +4,57 @@
|
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
6
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
7
|
-
import { blake256 } from '@noble/hashes/blake1';
|
|
8
|
-
import { blake2s } from '@noble/hashes/blake2';
|
|
9
|
-
import { sha256, sha512 } from '@noble/hashes/sha2';
|
|
10
|
-
import { concatBytes,
|
|
11
|
-
import {
|
|
12
|
-
|
|
7
|
+
import { blake256 } from '@noble/hashes/blake1.js';
|
|
8
|
+
import { blake2s } from '@noble/hashes/blake2.js';
|
|
9
|
+
import { sha256, sha512 } from '@noble/hashes/sha2.js';
|
|
10
|
+
import { concatBytes, utf8ToBytes } from '@noble/hashes/utils.js';
|
|
11
|
+
import {
|
|
12
|
+
twistedEdwards,
|
|
13
|
+
type CurveFn,
|
|
14
|
+
type EdwardsOpts,
|
|
15
|
+
type ExtPointType,
|
|
16
|
+
} from './abstract/edwards.ts';
|
|
13
17
|
import { Field, mod } from './abstract/modular.ts';
|
|
14
|
-
import { type CurveFn as WCurveFn
|
|
18
|
+
import { weierstrass, type CurveFn as WCurveFn } from './abstract/weierstrass.ts';
|
|
19
|
+
import { bls12_381_Fr } from './bls12-381.ts';
|
|
20
|
+
import { bn254_Fr } from './bn254.ts';
|
|
15
21
|
|
|
16
22
|
// Jubjub curves have 𝔽p over scalar fields of other curves. They are friendly to ZK proofs.
|
|
17
23
|
// jubjub Fp = bls n. babyjubjub Fp = bn254 n.
|
|
18
24
|
// verify manually, check bls12-381.ts and bn254.ts.
|
|
19
25
|
// https://neuromancer.sk/std/other/JubJub
|
|
20
26
|
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
);
|
|
24
|
-
const bn254_Fr = Field(
|
|
25
|
-
BigInt('21888242871839275222246405745257275088548364400416034343698204186575808495617')
|
|
26
|
-
);
|
|
27
|
-
|
|
28
|
-
/** Curve over scalar field of bls12-381. jubjub Fp = bls n */
|
|
29
|
-
export const jubjub: CurveFn = /* @__PURE__ */ twistedEdwards({
|
|
30
|
-
a: BigInt('0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000000'),
|
|
31
|
-
d: BigInt('0x2a9318e74bfa2b48f5fd9207e6bd7fd4292d7f6d37579d2601065fd6d6343eb1'),
|
|
32
|
-
Fp: bls12_381_Fr,
|
|
27
|
+
const jubjub_CURVE: EdwardsOpts = {
|
|
28
|
+
p: bls12_381_Fr.ORDER,
|
|
33
29
|
n: BigInt('0xe7db4ea6533afa906673b0101343b00a6682093ccc81082d0970e5ed6f72cb7'),
|
|
34
30
|
h: BigInt(8),
|
|
31
|
+
a: BigInt('0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000000'),
|
|
32
|
+
d: BigInt('0x2a9318e74bfa2b48f5fd9207e6bd7fd4292d7f6d37579d2601065fd6d6343eb1'),
|
|
35
33
|
Gx: BigInt('0x11dafe5d23e1218086a365b99fbf3d3be72f6afd7d1f72623e6b071492d1122b'),
|
|
36
34
|
Gy: BigInt('0x1d523cf1ddab1a1793132e78c866c0c33e26ba5cc220fed7cc3f870e59d292aa'),
|
|
35
|
+
};
|
|
36
|
+
/** Curve over scalar field of bls12-381. jubjub Fp = bls n */
|
|
37
|
+
export const jubjub: CurveFn = /* @__PURE__ */ twistedEdwards({
|
|
38
|
+
...jubjub_CURVE,
|
|
39
|
+
Fp: bls12_381_Fr,
|
|
37
40
|
hash: sha512,
|
|
38
|
-
|
|
39
|
-
} as const);
|
|
41
|
+
});
|
|
40
42
|
|
|
43
|
+
const babyjubjub_CURVE: EdwardsOpts = {
|
|
44
|
+
p: bn254_Fr.ORDER,
|
|
45
|
+
n: BigInt('0x30644e72e131a029b85045b68181585d59f76dc1c90770533b94bee1c9093788'),
|
|
46
|
+
h: BigInt(8),
|
|
47
|
+
a: BigInt('168700'),
|
|
48
|
+
d: BigInt('168696'),
|
|
49
|
+
Gx: BigInt('0x23343e3445b673d38bcba38f25645adb494b1255b1162bb40f41a59f4d4b45e'),
|
|
50
|
+
Gy: BigInt('0xc19139cb84c680a6e14116da06056174a0cfa121e6e5c2450f87d64fc000001'),
|
|
51
|
+
};
|
|
41
52
|
/** Curve over scalar field of bn254. babyjubjub Fp = bn254 n */
|
|
42
53
|
export const babyjubjub: CurveFn = /* @__PURE__ */ twistedEdwards({
|
|
43
|
-
|
|
44
|
-
d: BigInt(168696),
|
|
54
|
+
...babyjubjub_CURVE,
|
|
45
55
|
Fp: bn254_Fr,
|
|
46
|
-
n: BigInt('21888242871839275222246405745257275088614511777268538073601725287587578984328'),
|
|
47
|
-
h: BigInt(8),
|
|
48
|
-
Gx: BigInt('995203441582195749578291179787384436505546430278305826713579947235728471134'),
|
|
49
|
-
Gy: BigInt('5472060717959818805561601436314318772137091100104008585924551046643952123905'),
|
|
50
56
|
hash: blake256,
|
|
51
|
-
|
|
52
|
-
} as const);
|
|
57
|
+
});
|
|
53
58
|
|
|
54
59
|
const jubjub_gh_first_block = utf8ToBytes(
|
|
55
60
|
'096b36a5804bfacef1691e173c366a47ff5ba84a44f26ddd7e8d9f79d5b42df0'
|
|
@@ -61,10 +66,10 @@ export function jubjub_groupHash(tag: Uint8Array, personalization: Uint8Array):
|
|
|
61
66
|
h.update(jubjub_gh_first_block);
|
|
62
67
|
h.update(tag);
|
|
63
68
|
// NOTE: returns ExtendedPoint, in case it will be multiplied later
|
|
64
|
-
let p = jubjub.
|
|
69
|
+
let p = jubjub.Point.fromHex(h.digest());
|
|
65
70
|
// NOTE: cannot replace with isSmallOrder, returns Point*8
|
|
66
71
|
p = p.multiply(jubjub.CURVE.h);
|
|
67
|
-
if (p.equals(jubjub.
|
|
72
|
+
if (p.equals(jubjub.Point.ZERO)) throw new Error('Point has small order');
|
|
68
73
|
return p;
|
|
69
74
|
}
|
|
70
75
|
|
|
@@ -72,7 +77,7 @@ export function jubjub_groupHash(tag: Uint8Array, personalization: Uint8Array):
|
|
|
72
77
|
// It operates over public data:
|
|
73
78
|
// const G_SPEND = jubjub.findGroupHash(Uint8Array.of(), utf8ToBytes('Item_G_'));
|
|
74
79
|
export function jubjub_findGroupHash(m: Uint8Array, personalization: Uint8Array): ExtPointType {
|
|
75
|
-
const tag = concatBytes(m,
|
|
80
|
+
const tag = concatBytes(m, Uint8Array.of(0));
|
|
76
81
|
const hashes = [];
|
|
77
82
|
for (let i = 0; i < 256; i++) {
|
|
78
83
|
tag[tag.length - 1] = i;
|
|
@@ -105,7 +110,7 @@ export const pallas: WCurveFn = weierstrass({
|
|
|
105
110
|
Gx: mod(BigInt(-1), pasta_p),
|
|
106
111
|
Gy: BigInt(2),
|
|
107
112
|
h: BigInt(1),
|
|
108
|
-
|
|
113
|
+
hash: sha256,
|
|
109
114
|
});
|
|
110
115
|
/**
|
|
111
116
|
* https://neuromancer.sk/std/other/Vesta
|
|
@@ -119,5 +124,5 @@ export const vesta: WCurveFn = weierstrass({
|
|
|
119
124
|
Gx: mod(BigInt(-1), pasta_q),
|
|
120
125
|
Gy: BigInt(2),
|
|
121
126
|
h: BigInt(1),
|
|
122
|
-
|
|
127
|
+
hash: sha256,
|
|
123
128
|
});
|