@noble/curves 1.3.0 → 1.4.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 +23 -8
- package/abstract/bls.d.ts +4 -4
- package/abstract/bls.d.ts.map +1 -1
- package/abstract/hash-to-curve.d.ts.map +1 -1
- package/abstract/hash-to-curve.js +10 -21
- package/abstract/hash-to-curve.js.map +1 -1
- package/abstract/utils.d.ts +2 -1
- package/abstract/utils.d.ts.map +1 -1
- package/abstract/utils.js +13 -12
- package/abstract/utils.js.map +1 -1
- package/abstract/weierstrass.d.ts +1 -1
- package/abstract/weierstrass.d.ts.map +1 -1
- package/abstract/weierstrass.js +10 -4
- package/abstract/weierstrass.js.map +1 -1
- package/bls12-381.js +1 -1
- package/bls12-381.js.map +1 -1
- package/esm/abstract/hash-to-curve.js +6 -17
- package/esm/abstract/hash-to-curve.js.map +1 -1
- package/esm/abstract/utils.js +11 -11
- package/esm/abstract/utils.js.map +1 -1
- package/esm/abstract/weierstrass.js +10 -4
- package/esm/abstract/weierstrass.js.map +1 -1
- package/esm/bls12-381.js +1 -1
- package/esm/bls12-381.js.map +1 -1
- package/esm/index.js +1 -1
- package/esm/index.js.map +1 -1
- package/package.json +5 -5
- package/src/abstract/bls.ts +4 -4
- package/src/abstract/hash-to-curve.ts +6 -15
- package/src/abstract/utils.ts +11 -8
- package/src/abstract/weierstrass.ts +10 -4
- package/src/bls12-381.ts +1 -1
- package/src/package.json +3 -0
package/src/abstract/bls.ts
CHANGED
|
@@ -83,12 +83,12 @@ export type CurveFn<Fp, Fp2, Fp6, Fp12> = {
|
|
|
83
83
|
getPublicKey: (privateKey: PrivKey) => Uint8Array;
|
|
84
84
|
getPublicKeyForShortSignatures: (privateKey: PrivKey) => Uint8Array;
|
|
85
85
|
sign: {
|
|
86
|
-
(message: Hex, privateKey: PrivKey): Uint8Array;
|
|
87
|
-
(message: ProjPointType<Fp2>, privateKey: PrivKey): ProjPointType<Fp2>;
|
|
86
|
+
(message: Hex, privateKey: PrivKey, htfOpts?: htfBasicOpts): Uint8Array;
|
|
87
|
+
(message: ProjPointType<Fp2>, privateKey: PrivKey, htfOpts?: htfBasicOpts): ProjPointType<Fp2>;
|
|
88
88
|
};
|
|
89
89
|
signShortSignature: {
|
|
90
|
-
(message: Hex, privateKey: PrivKey): Uint8Array;
|
|
91
|
-
(message: ProjPointType<Fp>, privateKey: PrivKey): ProjPointType<Fp>;
|
|
90
|
+
(message: Hex, privateKey: PrivKey, htfOpts?: htfBasicOpts): Uint8Array;
|
|
91
|
+
(message: ProjPointType<Fp>, privateKey: PrivKey, htfOpts?: htfBasicOpts): ProjPointType<Fp>;
|
|
92
92
|
};
|
|
93
93
|
verify: (
|
|
94
94
|
signature: Hex | ProjPointType<Fp2>,
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import type { Group, GroupConstructor, AffinePoint } from './curve.js';
|
|
3
3
|
import { mod, IField } from './modular.js';
|
|
4
4
|
import type { CHash } from './utils.js';
|
|
5
|
-
import { bytesToNumberBE,
|
|
5
|
+
import { bytesToNumberBE, abytes, concatBytes, utf8ToBytes, validateObject } from './utils.js';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* * `DST` is a domain separation tag, defined in section 2.2.5
|
|
@@ -22,12 +22,6 @@ export type Opts = {
|
|
|
22
22
|
hash: CHash;
|
|
23
23
|
};
|
|
24
24
|
|
|
25
|
-
function validateDST(dst: UnicodeOrBytes): Uint8Array {
|
|
26
|
-
if (isBytes(dst)) return dst;
|
|
27
|
-
if (typeof dst === 'string') return utf8ToBytes(dst);
|
|
28
|
-
throw new Error('DST must be Uint8Array or string');
|
|
29
|
-
}
|
|
30
|
-
|
|
31
25
|
// Octet Stream to Integer. "spec" implementation of os2ip is 2.5x slower vs bytesToNumberBE.
|
|
32
26
|
const os2ip = bytesToNumberBE;
|
|
33
27
|
|
|
@@ -52,10 +46,7 @@ function strxor(a: Uint8Array, b: Uint8Array): Uint8Array {
|
|
|
52
46
|
return arr;
|
|
53
47
|
}
|
|
54
48
|
|
|
55
|
-
function
|
|
56
|
-
if (!isBytes(item)) throw new Error('Uint8Array expected');
|
|
57
|
-
}
|
|
58
|
-
function isNum(item: unknown): void {
|
|
49
|
+
function anum(item: unknown): void {
|
|
59
50
|
if (!Number.isSafeInteger(item)) throw new Error('number expected');
|
|
60
51
|
}
|
|
61
52
|
|
|
@@ -69,7 +60,7 @@ export function expand_message_xmd(
|
|
|
69
60
|
): Uint8Array {
|
|
70
61
|
abytes(msg);
|
|
71
62
|
abytes(DST);
|
|
72
|
-
|
|
63
|
+
anum(lenInBytes);
|
|
73
64
|
// https://www.rfc-editor.org/rfc/rfc9380#section-5.3.3
|
|
74
65
|
if (DST.length > 255) DST = H(concatBytes(utf8ToBytes('H2C-OVERSIZE-DST-'), DST));
|
|
75
66
|
const { outputLen: b_in_bytes, blockLen: r_in_bytes } = H;
|
|
@@ -103,7 +94,7 @@ export function expand_message_xof(
|
|
|
103
94
|
): Uint8Array {
|
|
104
95
|
abytes(msg);
|
|
105
96
|
abytes(DST);
|
|
106
|
-
|
|
97
|
+
anum(lenInBytes);
|
|
107
98
|
// https://www.rfc-editor.org/rfc/rfc9380#section-5.3.3
|
|
108
99
|
// DST = H('H2C-OVERSIZE-DST-' || a_very_long_DST, Math.ceil((lenInBytes * k) / 8));
|
|
109
100
|
if (DST.length > 255) {
|
|
@@ -141,8 +132,8 @@ export function hash_to_field(msg: Uint8Array, count: number, options: Opts): bi
|
|
|
141
132
|
});
|
|
142
133
|
const { p, k, m, hash, expand, DST: _DST } = options;
|
|
143
134
|
abytes(msg);
|
|
144
|
-
|
|
145
|
-
const DST =
|
|
135
|
+
anum(count);
|
|
136
|
+
const DST = typeof _DST === 'string' ? utf8ToBytes(_DST) : _DST;
|
|
146
137
|
const log2p = p.toString(2).length;
|
|
147
138
|
const L = Math.ceil((log2p + k) / 8); // section 5.1 of ietf draft link above
|
|
148
139
|
const len_in_bytes = count * m * L;
|
package/src/abstract/utils.ts
CHANGED
|
@@ -23,6 +23,10 @@ export function isBytes(a: unknown): a is Uint8Array {
|
|
|
23
23
|
);
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
+
export function abytes(item: unknown): void {
|
|
27
|
+
if (!isBytes(item)) throw new Error('Uint8Array expected');
|
|
28
|
+
}
|
|
29
|
+
|
|
26
30
|
// Array where index 0xf0 (240) is mapped to string 'f0'
|
|
27
31
|
const hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) =>
|
|
28
32
|
i.toString(16).padStart(2, '0')
|
|
@@ -31,7 +35,7 @@ const hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) =>
|
|
|
31
35
|
* @example bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])) // 'cafe0123'
|
|
32
36
|
*/
|
|
33
37
|
export function bytesToHex(bytes: Uint8Array): string {
|
|
34
|
-
|
|
38
|
+
abytes(bytes);
|
|
35
39
|
// pre-caching improves the speed 6x
|
|
36
40
|
let hex = '';
|
|
37
41
|
for (let i = 0; i < bytes.length; i++) {
|
|
@@ -86,7 +90,7 @@ export function bytesToNumberBE(bytes: Uint8Array): bigint {
|
|
|
86
90
|
return hexToNumber(bytesToHex(bytes));
|
|
87
91
|
}
|
|
88
92
|
export function bytesToNumberLE(bytes: Uint8Array): bigint {
|
|
89
|
-
|
|
93
|
+
abytes(bytes);
|
|
90
94
|
return hexToNumber(bytesToHex(Uint8Array.from(bytes).reverse()));
|
|
91
95
|
}
|
|
92
96
|
|
|
@@ -138,12 +142,11 @@ export function concatBytes(...arrays: Uint8Array[]): Uint8Array {
|
|
|
138
142
|
let sum = 0;
|
|
139
143
|
for (let i = 0; i < arrays.length; i++) {
|
|
140
144
|
const a = arrays[i];
|
|
141
|
-
|
|
145
|
+
abytes(a);
|
|
142
146
|
sum += a.length;
|
|
143
147
|
}
|
|
144
|
-
|
|
145
|
-
let pad = 0;
|
|
146
|
-
for (let i = 0; i < arrays.length; i++) {
|
|
148
|
+
const res = new Uint8Array(sum);
|
|
149
|
+
for (let i = 0, pad = 0; i < arrays.length; i++) {
|
|
147
150
|
const a = arrays[i];
|
|
148
151
|
res.set(a, pad);
|
|
149
152
|
pad += a.length;
|
|
@@ -195,9 +198,9 @@ export function bitGet(n: bigint, pos: number) {
|
|
|
195
198
|
/**
|
|
196
199
|
* Sets single bit at position.
|
|
197
200
|
*/
|
|
198
|
-
export
|
|
201
|
+
export function bitSet(n: bigint, pos: number, value: boolean) {
|
|
199
202
|
return n | ((value ? _1n : _0n) << BigInt(pos));
|
|
200
|
-
}
|
|
203
|
+
}
|
|
201
204
|
|
|
202
205
|
/**
|
|
203
206
|
* Calculate mask for N bits. Not using ** operator with bigints because of old engines.
|
|
@@ -27,7 +27,7 @@ export type BasicWCurve<T> = BasicCurve<T> & {
|
|
|
27
27
|
clearCofactor?: (c: ProjConstructor<T>, point: ProjPointType<T>) => ProjPointType<T>;
|
|
28
28
|
};
|
|
29
29
|
|
|
30
|
-
type Entropy = Hex |
|
|
30
|
+
type Entropy = Hex | boolean;
|
|
31
31
|
export type SignOpts = { lowS?: boolean; extraEntropy?: Entropy; prehash?: boolean };
|
|
32
32
|
export type VerOpts = { lowS?: boolean; prehash?: boolean };
|
|
33
33
|
|
|
@@ -158,7 +158,7 @@ export const DER = {
|
|
|
158
158
|
// parse DER signature
|
|
159
159
|
const { Err: E } = DER;
|
|
160
160
|
const data = typeof hex === 'string' ? h2b(hex) : hex;
|
|
161
|
-
|
|
161
|
+
ut.abytes(data);
|
|
162
162
|
let l = data.length;
|
|
163
163
|
if (l < 2 || data[0] != 0x30) throw new E('Invalid signature tag');
|
|
164
164
|
if (data[1] !== l - 2) throw new E('Invalid signature: incorrect length');
|
|
@@ -733,7 +733,13 @@ export function weierstrass(curveDef: CurveType): CurveFn {
|
|
|
733
733
|
const x = ut.bytesToNumberBE(tail);
|
|
734
734
|
if (!isValidFieldElement(x)) throw new Error('Point is not on curve');
|
|
735
735
|
const y2 = weierstrassEquation(x); // y² = x³ + ax + b
|
|
736
|
-
let y
|
|
736
|
+
let y: bigint;
|
|
737
|
+
try {
|
|
738
|
+
y = Fp.sqrt(y2); // y = y² ^ (p+1)/4
|
|
739
|
+
} catch (sqrtError) {
|
|
740
|
+
const suffix = sqrtError instanceof Error ? ': ' + sqrtError.message : '';
|
|
741
|
+
throw new Error('Point is not on curve' + suffix);
|
|
742
|
+
}
|
|
737
743
|
const isYOdd = (y & _1n) === _1n;
|
|
738
744
|
// ECDSA
|
|
739
745
|
const isHeadOdd = (head & 1) === 1;
|
|
@@ -971,7 +977,7 @@ export function weierstrass(curveDef: CurveType): CurveFn {
|
|
|
971
977
|
const d = normPrivateKeyToScalar(privateKey); // validate private key, convert to bigint
|
|
972
978
|
const seedArgs = [int2octets(d), int2octets(h1int)];
|
|
973
979
|
// extraEntropy. RFC6979 3.6: additional k' (optional).
|
|
974
|
-
if (ent != null) {
|
|
980
|
+
if (ent != null && ent !== false) {
|
|
975
981
|
// K = HMAC_K(V || 0x00 || int2octets(x) || bits2octets(h1) || k')
|
|
976
982
|
const e = ent === true ? randomBytes(Fp.BYTES) : ent; // generate random bytes OR pass as-is
|
|
977
983
|
seedArgs.push(ensureBytes('extraEntropy', e)); // check for being bytes
|
package/src/bls12-381.ts
CHANGED
|
@@ -1364,7 +1364,7 @@ export const bls12_381: CurveFn<Fp, Fp2, Fp6, Fp12> = bls({
|
|
|
1364
1364
|
fromHex(hex: Hex): ProjPointType<Fp2> {
|
|
1365
1365
|
const { infinity, sort, value } = parseMask(ensureBytes('signatureHex', hex));
|
|
1366
1366
|
const P = Fp.ORDER;
|
|
1367
|
-
const half =
|
|
1367
|
+
const half = value.length / 2;
|
|
1368
1368
|
if (half !== 48 && half !== 96)
|
|
1369
1369
|
throw new Error('Invalid compressed signature length, must be 96 or 192');
|
|
1370
1370
|
const z1 = bytesToNumberBE(value.slice(0, half));
|
package/src/package.json
ADDED