@noble/curves 0.2.1 → 0.3.1
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 +14 -19
- package/lib/crypto.d.ts +4 -0
- package/lib/crypto.js +8 -0
- package/lib/cryptoBrowser.d.ts +4 -0
- package/lib/cryptoBrowser.js +7 -0
- package/lib/definitions/_shortw_utils.d.ts +63 -0
- package/lib/definitions/_shortw_utils.js +18 -0
- package/lib/definitions/bn.d.ts +7 -0
- package/lib/definitions/bn.js +23 -0
- package/lib/definitions/ed25519.d.ts +49 -0
- package/lib/definitions/ed25519.js +308 -0
- package/lib/definitions/ed448.d.ts +3 -0
- package/lib/definitions/ed448.js +127 -0
- package/lib/definitions/index.d.ts +0 -0
- package/lib/definitions/index.js +2 -0
- package/lib/definitions/jubjub.d.ts +7 -0
- package/lib/definitions/jubjub.js +55 -0
- package/lib/definitions/p192.d.ts +112 -0
- package/lib/definitions/p192.js +23 -0
- package/lib/definitions/p224.d.ts +112 -0
- package/lib/definitions/p224.js +24 -0
- package/lib/definitions/p256.d.ts +112 -0
- package/lib/definitions/p256.js +23 -0
- package/lib/definitions/p384.d.ts +112 -0
- package/lib/definitions/p384.js +24 -0
- package/lib/definitions/p521.d.ts +113 -0
- package/lib/definitions/p521.js +36 -0
- package/lib/definitions/pasta.d.ts +2 -0
- package/lib/definitions/pasta.js +32 -0
- package/lib/definitions/secp256k1.d.ts +87 -0
- package/lib/definitions/secp256k1.js +245 -0
- package/lib/definitions/stark.d.ts +62 -0
- package/lib/definitions/stark.js +248 -0
- package/lib/edwards.d.ts +2 -2
- package/lib/edwards.js +2 -6
- package/lib/esm/crypto.js +5 -0
- package/lib/esm/cryptoBrowser.js +4 -0
- package/lib/esm/definitions/_shortw_utils.js +13 -0
- package/lib/esm/definitions/bn.js +20 -0
- package/lib/esm/definitions/ed25519.js +304 -0
- package/lib/esm/definitions/ed448.js +124 -0
- package/lib/esm/definitions/index.js +2 -0
- package/lib/esm/definitions/jubjub.js +50 -0
- package/lib/esm/definitions/p192.js +20 -0
- package/lib/esm/definitions/p224.js +21 -0
- package/lib/esm/definitions/p256.js +20 -0
- package/lib/esm/definitions/p384.js +21 -0
- package/lib/esm/definitions/p521.js +33 -0
- package/lib/esm/definitions/pasta.js +29 -0
- package/lib/esm/definitions/secp256k1.js +241 -0
- package/lib/esm/definitions/stark.js +227 -0
- package/lib/esm/edwards.js +3 -7
- package/lib/esm/modular.js +14 -9
- package/lib/esm/utils.js +17 -0
- package/lib/esm/weierstrass.js +17 -9
- package/lib/modular.d.ts +8 -1
- package/lib/modular.js +14 -9
- package/lib/utils.d.ts +4 -0
- package/lib/utils.js +19 -1
- package/lib/weierstrass.d.ts +5 -3
- package/lib/weierstrass.js +16 -8
- package/package.json +38 -8
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
export declare const P384: Readonly<{
|
|
2
|
+
create: (hash: import("../weierstrass.js").CHash) => import("../weierstrass.js").CurveFn;
|
|
3
|
+
CURVE: Readonly<{
|
|
4
|
+
readonly nBitLength: number;
|
|
5
|
+
readonly nByteLength: number;
|
|
6
|
+
readonly P: bigint;
|
|
7
|
+
readonly n: bigint;
|
|
8
|
+
readonly h: bigint;
|
|
9
|
+
readonly Gx: bigint;
|
|
10
|
+
readonly Gy: bigint;
|
|
11
|
+
readonly a: bigint;
|
|
12
|
+
readonly b: bigint;
|
|
13
|
+
lowS: boolean;
|
|
14
|
+
readonly hash: import("../weierstrass.js").CHash;
|
|
15
|
+
readonly hmac: (key: Uint8Array, ...messages: Uint8Array[]) => Uint8Array;
|
|
16
|
+
randomBytes: typeof import("../utils.js").randomBytes;
|
|
17
|
+
readonly truncateHash?: ((hash: Uint8Array, truncateOnly?: boolean | undefined) => bigint) | undefined;
|
|
18
|
+
readonly sqrtMod?: ((n: bigint) => bigint) | undefined;
|
|
19
|
+
readonly normalizePrivateKey?: ((key: import("../utils.js").PrivKey) => import("../utils.js").PrivKey) | undefined;
|
|
20
|
+
readonly endo?: {
|
|
21
|
+
beta: bigint;
|
|
22
|
+
splitScalar: (k: bigint) => {
|
|
23
|
+
k1neg: boolean;
|
|
24
|
+
k1: bigint;
|
|
25
|
+
k2neg: boolean;
|
|
26
|
+
k2: bigint;
|
|
27
|
+
};
|
|
28
|
+
} | undefined;
|
|
29
|
+
}>;
|
|
30
|
+
getPublicKey: (privateKey: import("../utils.js").PrivKey, isCompressed?: boolean | undefined) => Uint8Array;
|
|
31
|
+
getSharedSecret: (privateA: import("../utils.js").PrivKey, publicB: import("../weierstrass.js").PubKey, isCompressed?: boolean | undefined) => Uint8Array;
|
|
32
|
+
sign: (msgHash: import("../utils.js").Hex, privKey: import("../utils.js").PrivKey, opts?: {
|
|
33
|
+
lowS?: boolean | undefined;
|
|
34
|
+
extraEntropy?: (true | import("../utils.js").Hex) | undefined;
|
|
35
|
+
} | undefined) => import("../weierstrass.js").SignatureType;
|
|
36
|
+
verify: (signature: import("../utils.js").Hex | import("../weierstrass.js").SignatureType, msgHash: import("../utils.js").Hex, publicKey: import("../weierstrass.js").PubKey, opts?: {
|
|
37
|
+
lowS?: boolean | undefined;
|
|
38
|
+
} | undefined) => boolean;
|
|
39
|
+
Point: import("../weierstrass.js").PointConstructor;
|
|
40
|
+
JacobianPoint: import("../weierstrass.js").JacobianPointConstructor;
|
|
41
|
+
Signature: import("../weierstrass.js").SignatureConstructor;
|
|
42
|
+
utils: {
|
|
43
|
+
mod: (a: bigint, b?: bigint | undefined) => bigint;
|
|
44
|
+
invert: (number: bigint, modulo?: bigint | undefined) => bigint;
|
|
45
|
+
_bigintToBytes: (num: bigint) => Uint8Array;
|
|
46
|
+
_bigintToString: (num: bigint) => string;
|
|
47
|
+
_normalizePrivateKey: (key: import("../utils.js").PrivKey) => bigint;
|
|
48
|
+
_normalizePublicKey: (publicKey: import("../weierstrass.js").PubKey) => import("../weierstrass.js").PointType;
|
|
49
|
+
_isWithinCurveOrder: (num: bigint) => boolean;
|
|
50
|
+
_isValidFieldElement: (num: bigint) => boolean;
|
|
51
|
+
_weierstrassEquation: (x: bigint) => bigint;
|
|
52
|
+
isValidPrivateKey(privateKey: import("../utils.js").PrivKey): boolean;
|
|
53
|
+
hashToPrivateKey: (hash: import("../utils.js").Hex) => Uint8Array;
|
|
54
|
+
randomPrivateKey: () => Uint8Array;
|
|
55
|
+
};
|
|
56
|
+
}>;
|
|
57
|
+
export declare const secp384r1: Readonly<{
|
|
58
|
+
create: (hash: import("../weierstrass.js").CHash) => import("../weierstrass.js").CurveFn;
|
|
59
|
+
CURVE: Readonly<{
|
|
60
|
+
readonly nBitLength: number;
|
|
61
|
+
readonly nByteLength: number;
|
|
62
|
+
readonly P: bigint;
|
|
63
|
+
readonly n: bigint;
|
|
64
|
+
readonly h: bigint;
|
|
65
|
+
readonly Gx: bigint;
|
|
66
|
+
readonly Gy: bigint;
|
|
67
|
+
readonly a: bigint;
|
|
68
|
+
readonly b: bigint;
|
|
69
|
+
lowS: boolean;
|
|
70
|
+
readonly hash: import("../weierstrass.js").CHash;
|
|
71
|
+
readonly hmac: (key: Uint8Array, ...messages: Uint8Array[]) => Uint8Array;
|
|
72
|
+
randomBytes: typeof import("../utils.js").randomBytes;
|
|
73
|
+
readonly truncateHash?: ((hash: Uint8Array, truncateOnly?: boolean | undefined) => bigint) | undefined;
|
|
74
|
+
readonly sqrtMod?: ((n: bigint) => bigint) | undefined;
|
|
75
|
+
readonly normalizePrivateKey?: ((key: import("../utils.js").PrivKey) => import("../utils.js").PrivKey) | undefined;
|
|
76
|
+
readonly endo?: {
|
|
77
|
+
beta: bigint;
|
|
78
|
+
splitScalar: (k: bigint) => {
|
|
79
|
+
k1neg: boolean;
|
|
80
|
+
k1: bigint;
|
|
81
|
+
k2neg: boolean;
|
|
82
|
+
k2: bigint;
|
|
83
|
+
};
|
|
84
|
+
} | undefined;
|
|
85
|
+
}>;
|
|
86
|
+
getPublicKey: (privateKey: import("../utils.js").PrivKey, isCompressed?: boolean | undefined) => Uint8Array;
|
|
87
|
+
getSharedSecret: (privateA: import("../utils.js").PrivKey, publicB: import("../weierstrass.js").PubKey, isCompressed?: boolean | undefined) => Uint8Array;
|
|
88
|
+
sign: (msgHash: import("../utils.js").Hex, privKey: import("../utils.js").PrivKey, opts?: {
|
|
89
|
+
lowS?: boolean | undefined;
|
|
90
|
+
extraEntropy?: (true | import("../utils.js").Hex) | undefined;
|
|
91
|
+
} | undefined) => import("../weierstrass.js").SignatureType;
|
|
92
|
+
verify: (signature: import("../utils.js").Hex | import("../weierstrass.js").SignatureType, msgHash: import("../utils.js").Hex, publicKey: import("../weierstrass.js").PubKey, opts?: {
|
|
93
|
+
lowS?: boolean | undefined;
|
|
94
|
+
} | undefined) => boolean;
|
|
95
|
+
Point: import("../weierstrass.js").PointConstructor;
|
|
96
|
+
JacobianPoint: import("../weierstrass.js").JacobianPointConstructor;
|
|
97
|
+
Signature: import("../weierstrass.js").SignatureConstructor;
|
|
98
|
+
utils: {
|
|
99
|
+
mod: (a: bigint, b?: bigint | undefined) => bigint;
|
|
100
|
+
invert: (number: bigint, modulo?: bigint | undefined) => bigint;
|
|
101
|
+
_bigintToBytes: (num: bigint) => Uint8Array;
|
|
102
|
+
_bigintToString: (num: bigint) => string;
|
|
103
|
+
_normalizePrivateKey: (key: import("../utils.js").PrivKey) => bigint;
|
|
104
|
+
_normalizePublicKey: (publicKey: import("../weierstrass.js").PubKey) => import("../weierstrass.js").PointType;
|
|
105
|
+
_isWithinCurveOrder: (num: bigint) => boolean;
|
|
106
|
+
_isValidFieldElement: (num: bigint) => boolean;
|
|
107
|
+
_weierstrassEquation: (x: bigint) => bigint;
|
|
108
|
+
isValidPrivateKey(privateKey: import("../utils.js").PrivKey): boolean;
|
|
109
|
+
hashToPrivateKey: (hash: import("../utils.js").Hex) => Uint8Array;
|
|
110
|
+
randomPrivateKey: () => Uint8Array;
|
|
111
|
+
};
|
|
112
|
+
}>;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.secp384r1 = exports.P384 = void 0;
|
|
4
|
+
/*! @noble/curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
5
|
+
const _shortw_utils_js_1 = require("./_shortw_utils.js");
|
|
6
|
+
const sha512_1 = require("@noble/hashes/sha512");
|
|
7
|
+
// NIST secp384r1 aka P384
|
|
8
|
+
// https://www.secg.org/sec2-v2.pdf, https://neuromancer.sk/std/nist/P-384
|
|
9
|
+
// prettier-ignore
|
|
10
|
+
exports.P384 = (0, _shortw_utils_js_1.createCurve)({
|
|
11
|
+
// Params: a, b
|
|
12
|
+
a: BigInt('0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000fffffffc'),
|
|
13
|
+
b: BigInt('0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8edd3ec2aef'),
|
|
14
|
+
// Field over which we'll do calculations. 2n**384n - 2n**128n - 2n**96n + 2n**32n - 1n
|
|
15
|
+
P: BigInt('0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff'),
|
|
16
|
+
// Curve order, total count of valid points in the field.
|
|
17
|
+
n: BigInt('0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973'),
|
|
18
|
+
// Base point (x, y) aka generator point
|
|
19
|
+
Gx: BigInt('0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7'),
|
|
20
|
+
Gy: BigInt('0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f'),
|
|
21
|
+
h: BigInt(1),
|
|
22
|
+
lowS: false,
|
|
23
|
+
}, sha512_1.sha384);
|
|
24
|
+
exports.secp384r1 = exports.P384;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { PrivKey } from '../utils';
|
|
2
|
+
export declare const P521: Readonly<{
|
|
3
|
+
create: (hash: import("../weierstrass.js").CHash) => import("../weierstrass.js").CurveFn;
|
|
4
|
+
CURVE: Readonly<{
|
|
5
|
+
readonly nBitLength: number;
|
|
6
|
+
readonly nByteLength: number;
|
|
7
|
+
readonly P: bigint;
|
|
8
|
+
readonly n: bigint;
|
|
9
|
+
readonly h: bigint;
|
|
10
|
+
readonly Gx: bigint;
|
|
11
|
+
readonly Gy: bigint;
|
|
12
|
+
readonly a: bigint;
|
|
13
|
+
readonly b: bigint;
|
|
14
|
+
lowS: boolean;
|
|
15
|
+
readonly hash: import("../weierstrass.js").CHash;
|
|
16
|
+
readonly hmac: (key: Uint8Array, ...messages: Uint8Array[]) => Uint8Array;
|
|
17
|
+
randomBytes: typeof import("../utils").randomBytes;
|
|
18
|
+
readonly truncateHash?: ((hash: Uint8Array, truncateOnly?: boolean | undefined) => bigint) | undefined;
|
|
19
|
+
readonly sqrtMod?: ((n: bigint) => bigint) | undefined;
|
|
20
|
+
readonly normalizePrivateKey?: ((key: PrivKey) => PrivKey) | undefined;
|
|
21
|
+
readonly endo?: {
|
|
22
|
+
beta: bigint;
|
|
23
|
+
splitScalar: (k: bigint) => {
|
|
24
|
+
k1neg: boolean;
|
|
25
|
+
k1: bigint;
|
|
26
|
+
k2neg: boolean;
|
|
27
|
+
k2: bigint;
|
|
28
|
+
};
|
|
29
|
+
} | undefined;
|
|
30
|
+
}>;
|
|
31
|
+
getPublicKey: (privateKey: PrivKey, isCompressed?: boolean | undefined) => Uint8Array;
|
|
32
|
+
getSharedSecret: (privateA: PrivKey, publicB: import("../weierstrass.js").PubKey, isCompressed?: boolean | undefined) => Uint8Array;
|
|
33
|
+
sign: (msgHash: import("../utils").Hex, privKey: PrivKey, opts?: {
|
|
34
|
+
lowS?: boolean | undefined;
|
|
35
|
+
extraEntropy?: (true | import("../utils").Hex) | undefined;
|
|
36
|
+
} | undefined) => import("../weierstrass.js").SignatureType;
|
|
37
|
+
verify: (signature: import("../utils").Hex | import("../weierstrass.js").SignatureType, msgHash: import("../utils").Hex, publicKey: import("../weierstrass.js").PubKey, opts?: {
|
|
38
|
+
lowS?: boolean | undefined;
|
|
39
|
+
} | undefined) => boolean;
|
|
40
|
+
Point: import("../weierstrass.js").PointConstructor;
|
|
41
|
+
JacobianPoint: import("../weierstrass.js").JacobianPointConstructor;
|
|
42
|
+
Signature: import("../weierstrass.js").SignatureConstructor;
|
|
43
|
+
utils: {
|
|
44
|
+
mod: (a: bigint, b?: bigint | undefined) => bigint;
|
|
45
|
+
invert: (number: bigint, modulo?: bigint | undefined) => bigint;
|
|
46
|
+
_bigintToBytes: (num: bigint) => Uint8Array;
|
|
47
|
+
_bigintToString: (num: bigint) => string;
|
|
48
|
+
_normalizePrivateKey: (key: PrivKey) => bigint;
|
|
49
|
+
_normalizePublicKey: (publicKey: import("../weierstrass.js").PubKey) => import("../weierstrass.js").PointType;
|
|
50
|
+
_isWithinCurveOrder: (num: bigint) => boolean;
|
|
51
|
+
_isValidFieldElement: (num: bigint) => boolean;
|
|
52
|
+
_weierstrassEquation: (x: bigint) => bigint;
|
|
53
|
+
isValidPrivateKey(privateKey: PrivKey): boolean;
|
|
54
|
+
hashToPrivateKey: (hash: import("../utils").Hex) => Uint8Array;
|
|
55
|
+
randomPrivateKey: () => Uint8Array;
|
|
56
|
+
};
|
|
57
|
+
}>;
|
|
58
|
+
export declare const secp521r1: Readonly<{
|
|
59
|
+
create: (hash: import("../weierstrass.js").CHash) => import("../weierstrass.js").CurveFn;
|
|
60
|
+
CURVE: Readonly<{
|
|
61
|
+
readonly nBitLength: number;
|
|
62
|
+
readonly nByteLength: number;
|
|
63
|
+
readonly P: bigint;
|
|
64
|
+
readonly n: bigint;
|
|
65
|
+
readonly h: bigint;
|
|
66
|
+
readonly Gx: bigint;
|
|
67
|
+
readonly Gy: bigint;
|
|
68
|
+
readonly a: bigint;
|
|
69
|
+
readonly b: bigint;
|
|
70
|
+
lowS: boolean;
|
|
71
|
+
readonly hash: import("../weierstrass.js").CHash;
|
|
72
|
+
readonly hmac: (key: Uint8Array, ...messages: Uint8Array[]) => Uint8Array;
|
|
73
|
+
randomBytes: typeof import("../utils").randomBytes;
|
|
74
|
+
readonly truncateHash?: ((hash: Uint8Array, truncateOnly?: boolean | undefined) => bigint) | undefined;
|
|
75
|
+
readonly sqrtMod?: ((n: bigint) => bigint) | undefined;
|
|
76
|
+
readonly normalizePrivateKey?: ((key: PrivKey) => PrivKey) | undefined;
|
|
77
|
+
readonly endo?: {
|
|
78
|
+
beta: bigint;
|
|
79
|
+
splitScalar: (k: bigint) => {
|
|
80
|
+
k1neg: boolean;
|
|
81
|
+
k1: bigint;
|
|
82
|
+
k2neg: boolean;
|
|
83
|
+
k2: bigint;
|
|
84
|
+
};
|
|
85
|
+
} | undefined;
|
|
86
|
+
}>;
|
|
87
|
+
getPublicKey: (privateKey: PrivKey, isCompressed?: boolean | undefined) => Uint8Array;
|
|
88
|
+
getSharedSecret: (privateA: PrivKey, publicB: import("../weierstrass.js").PubKey, isCompressed?: boolean | undefined) => Uint8Array;
|
|
89
|
+
sign: (msgHash: import("../utils").Hex, privKey: PrivKey, opts?: {
|
|
90
|
+
lowS?: boolean | undefined;
|
|
91
|
+
extraEntropy?: (true | import("../utils").Hex) | undefined;
|
|
92
|
+
} | undefined) => import("../weierstrass.js").SignatureType;
|
|
93
|
+
verify: (signature: import("../utils").Hex | import("../weierstrass.js").SignatureType, msgHash: import("../utils").Hex, publicKey: import("../weierstrass.js").PubKey, opts?: {
|
|
94
|
+
lowS?: boolean | undefined;
|
|
95
|
+
} | undefined) => boolean;
|
|
96
|
+
Point: import("../weierstrass.js").PointConstructor;
|
|
97
|
+
JacobianPoint: import("../weierstrass.js").JacobianPointConstructor;
|
|
98
|
+
Signature: import("../weierstrass.js").SignatureConstructor;
|
|
99
|
+
utils: {
|
|
100
|
+
mod: (a: bigint, b?: bigint | undefined) => bigint;
|
|
101
|
+
invert: (number: bigint, modulo?: bigint | undefined) => bigint;
|
|
102
|
+
_bigintToBytes: (num: bigint) => Uint8Array;
|
|
103
|
+
_bigintToString: (num: bigint) => string;
|
|
104
|
+
_normalizePrivateKey: (key: PrivKey) => bigint;
|
|
105
|
+
_normalizePublicKey: (publicKey: import("../weierstrass.js").PubKey) => import("../weierstrass.js").PointType;
|
|
106
|
+
_isWithinCurveOrder: (num: bigint) => boolean;
|
|
107
|
+
_isValidFieldElement: (num: bigint) => boolean;
|
|
108
|
+
_weierstrassEquation: (x: bigint) => bigint;
|
|
109
|
+
isValidPrivateKey(privateKey: PrivKey): boolean;
|
|
110
|
+
hashToPrivateKey: (hash: import("../utils").Hex) => Uint8Array;
|
|
111
|
+
randomPrivateKey: () => Uint8Array;
|
|
112
|
+
};
|
|
113
|
+
}>;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.secp521r1 = exports.P521 = void 0;
|
|
4
|
+
/*! @noble/curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
5
|
+
const _shortw_utils_js_1 = require("./_shortw_utils.js");
|
|
6
|
+
const sha512_1 = require("@noble/hashes/sha512");
|
|
7
|
+
const utils_1 = require("../utils");
|
|
8
|
+
// NIST secp521r1 aka P521
|
|
9
|
+
// Note that it's 521, which differs from 512 of its hash function.
|
|
10
|
+
// https://www.secg.org/sec2-v2.pdf, https://neuromancer.sk/std/nist/P-521
|
|
11
|
+
// prettier-ignore
|
|
12
|
+
exports.P521 = (0, _shortw_utils_js_1.createCurve)({
|
|
13
|
+
// Params: a, b
|
|
14
|
+
a: BigInt('0x01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc'),
|
|
15
|
+
b: BigInt('0x0051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00'),
|
|
16
|
+
// Field over which we'll do calculations; 2n**521n - 1n
|
|
17
|
+
P: BigInt('0x1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'),
|
|
18
|
+
// Curve order, total count of valid points in the field
|
|
19
|
+
n: BigInt('0x01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409'),
|
|
20
|
+
// Base point (x, y) aka generator point
|
|
21
|
+
Gx: BigInt('0x00c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66'),
|
|
22
|
+
Gy: BigInt('0x011839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650'),
|
|
23
|
+
h: BigInt(1),
|
|
24
|
+
lowS: false,
|
|
25
|
+
normalizePrivateKey(key) {
|
|
26
|
+
if (typeof key === 'bigint')
|
|
27
|
+
return key;
|
|
28
|
+
if (key instanceof Uint8Array)
|
|
29
|
+
key = (0, utils_1.bytesToHex)(key);
|
|
30
|
+
if (typeof key !== 'string' || !([130, 131, 132].includes(key.length))) {
|
|
31
|
+
throw new Error('Invalid key');
|
|
32
|
+
}
|
|
33
|
+
return key.padStart(66 * 2, '0');
|
|
34
|
+
}
|
|
35
|
+
}, sha512_1.sha512);
|
|
36
|
+
exports.secp521r1 = exports.P521;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.vesta = exports.pallas = void 0;
|
|
4
|
+
/*! @noble/curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
5
|
+
const sha256_1 = require("@noble/hashes/sha256");
|
|
6
|
+
const weierstrass_1 = require("../weierstrass");
|
|
7
|
+
const _shortw_utils_js_1 = require("./_shortw_utils.js");
|
|
8
|
+
const mod = require("../modular");
|
|
9
|
+
const p = BigInt('0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001');
|
|
10
|
+
const q = BigInt('0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001');
|
|
11
|
+
// https://neuromancer.sk/std/other/Pallas
|
|
12
|
+
exports.pallas = (0, weierstrass_1.weierstrass)({
|
|
13
|
+
a: BigInt(0),
|
|
14
|
+
b: BigInt(5),
|
|
15
|
+
P: p,
|
|
16
|
+
n: q,
|
|
17
|
+
Gx: mod.mod(BigInt(-1), p),
|
|
18
|
+
Gy: BigInt(2),
|
|
19
|
+
h: BigInt(1),
|
|
20
|
+
...(0, _shortw_utils_js_1.getHash)(sha256_1.sha256),
|
|
21
|
+
});
|
|
22
|
+
// https://neuromancer.sk/std/other/Vesta
|
|
23
|
+
exports.vesta = (0, weierstrass_1.weierstrass)({
|
|
24
|
+
a: BigInt(0),
|
|
25
|
+
b: BigInt(5),
|
|
26
|
+
P: q,
|
|
27
|
+
n: p,
|
|
28
|
+
Gx: mod.mod(BigInt(-1), q),
|
|
29
|
+
Gy: BigInt(2),
|
|
30
|
+
h: BigInt(1),
|
|
31
|
+
...(0, _shortw_utils_js_1.getHash)(sha256_1.sha256),
|
|
32
|
+
});
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { PointType } from '../weierstrass';
|
|
2
|
+
import { Hex, PrivKey, randomBytes } from '../utils';
|
|
3
|
+
export declare const secp256k1: Readonly<{
|
|
4
|
+
create: (hash: import("../weierstrass").CHash) => import("../weierstrass").CurveFn;
|
|
5
|
+
CURVE: Readonly<{
|
|
6
|
+
readonly nBitLength: number;
|
|
7
|
+
readonly nByteLength: number;
|
|
8
|
+
readonly P: bigint;
|
|
9
|
+
readonly n: bigint;
|
|
10
|
+
readonly h: bigint;
|
|
11
|
+
readonly Gx: bigint;
|
|
12
|
+
readonly Gy: bigint;
|
|
13
|
+
readonly a: bigint;
|
|
14
|
+
readonly b: bigint;
|
|
15
|
+
lowS: boolean;
|
|
16
|
+
readonly hash: import("../weierstrass").CHash;
|
|
17
|
+
readonly hmac: (key: Uint8Array, ...messages: Uint8Array[]) => Uint8Array;
|
|
18
|
+
randomBytes: typeof randomBytes;
|
|
19
|
+
readonly truncateHash?: ((hash: Uint8Array, truncateOnly?: boolean | undefined) => bigint) | undefined;
|
|
20
|
+
readonly sqrtMod?: ((n: bigint) => bigint) | undefined;
|
|
21
|
+
readonly normalizePrivateKey?: ((key: PrivKey) => PrivKey) | undefined;
|
|
22
|
+
readonly endo?: {
|
|
23
|
+
beta: bigint;
|
|
24
|
+
splitScalar: (k: bigint) => {
|
|
25
|
+
k1neg: boolean;
|
|
26
|
+
k1: bigint;
|
|
27
|
+
k2neg: boolean;
|
|
28
|
+
k2: bigint;
|
|
29
|
+
};
|
|
30
|
+
} | undefined;
|
|
31
|
+
}>;
|
|
32
|
+
getPublicKey: (privateKey: PrivKey, isCompressed?: boolean | undefined) => Uint8Array;
|
|
33
|
+
getSharedSecret: (privateA: PrivKey, publicB: import("../weierstrass").PubKey, isCompressed?: boolean | undefined) => Uint8Array;
|
|
34
|
+
sign: (msgHash: Hex, privKey: PrivKey, opts?: {
|
|
35
|
+
lowS?: boolean | undefined;
|
|
36
|
+
extraEntropy?: (true | Hex) | undefined;
|
|
37
|
+
} | undefined) => import("../weierstrass").SignatureType;
|
|
38
|
+
verify: (signature: Hex | import("../weierstrass").SignatureType, msgHash: Hex, publicKey: import("../weierstrass").PubKey, opts?: {
|
|
39
|
+
lowS?: boolean | undefined;
|
|
40
|
+
} | undefined) => boolean;
|
|
41
|
+
Point: import("../weierstrass").PointConstructor;
|
|
42
|
+
JacobianPoint: import("../weierstrass").JacobianPointConstructor;
|
|
43
|
+
Signature: import("../weierstrass").SignatureConstructor;
|
|
44
|
+
utils: {
|
|
45
|
+
mod: (a: bigint, b?: bigint | undefined) => bigint;
|
|
46
|
+
invert: (number: bigint, modulo?: bigint | undefined) => bigint;
|
|
47
|
+
_bigintToBytes: (num: bigint) => Uint8Array;
|
|
48
|
+
_bigintToString: (num: bigint) => string;
|
|
49
|
+
_normalizePrivateKey: (key: PrivKey) => bigint;
|
|
50
|
+
_normalizePublicKey: (publicKey: import("../weierstrass").PubKey) => PointType;
|
|
51
|
+
_isWithinCurveOrder: (num: bigint) => boolean;
|
|
52
|
+
_isValidFieldElement: (num: bigint) => boolean;
|
|
53
|
+
_weierstrassEquation: (x: bigint) => bigint;
|
|
54
|
+
isValidPrivateKey(privateKey: PrivKey): boolean;
|
|
55
|
+
hashToPrivateKey: (hash: Hex) => Uint8Array;
|
|
56
|
+
randomPrivateKey: () => Uint8Array;
|
|
57
|
+
};
|
|
58
|
+
}>;
|
|
59
|
+
export declare function taggedHash(tag: string, ...messages: Uint8Array[]): Uint8Array;
|
|
60
|
+
declare class SchnorrSignature {
|
|
61
|
+
readonly r: bigint;
|
|
62
|
+
readonly s: bigint;
|
|
63
|
+
constructor(r: bigint, s: bigint);
|
|
64
|
+
static fromHex(hex: Hex): SchnorrSignature;
|
|
65
|
+
assertValidity(): void;
|
|
66
|
+
toHex(): string;
|
|
67
|
+
toRawBytes(): Uint8Array;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Synchronously creates Schnorr signature. Improved security: verifies itself before
|
|
71
|
+
* producing an output.
|
|
72
|
+
* @param msg message (not message hash)
|
|
73
|
+
* @param privateKey private key
|
|
74
|
+
* @param auxRand random bytes that would be added to k. Bad RNG won't break it.
|
|
75
|
+
*/
|
|
76
|
+
declare function schnorrSign(message: Hex, privateKey: PrivKey, auxRand?: Hex): Uint8Array;
|
|
77
|
+
/**
|
|
78
|
+
* Verifies Schnorr signature synchronously.
|
|
79
|
+
*/
|
|
80
|
+
declare function schnorrVerify(signature: Hex, message: Hex, publicKey: Hex): boolean;
|
|
81
|
+
export declare const schnorr: {
|
|
82
|
+
Signature: typeof SchnorrSignature;
|
|
83
|
+
getPublicKey: (privateKey: PrivKey) => Uint8Array;
|
|
84
|
+
sign: typeof schnorrSign;
|
|
85
|
+
verify: typeof schnorrVerify;
|
|
86
|
+
};
|
|
87
|
+
export {};
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.schnorr = exports.taggedHash = exports.secp256k1 = void 0;
|
|
4
|
+
/*! @noble/curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
5
|
+
const sha256_1 = require("@noble/hashes/sha256");
|
|
6
|
+
const modular_1 = require("../modular");
|
|
7
|
+
const _shortw_utils_js_1 = require("./_shortw_utils.js");
|
|
8
|
+
const utils_1 = require("../utils");
|
|
9
|
+
/**
|
|
10
|
+
* secp256k1 belongs to Koblitz curves: it has
|
|
11
|
+
* efficiently computable Frobenius endomorphism.
|
|
12
|
+
* Endomorphism improves efficiency:
|
|
13
|
+
* Uses 2x less RAM, speeds up precomputation by 2x and ECDH / sign key recovery by 20%.
|
|
14
|
+
* Should always be used for Jacobian's double-and-add multiplication.
|
|
15
|
+
* For affines cached multiplication, it trades off 1/2 init time & 1/3 ram for 20% perf hit.
|
|
16
|
+
* https://gist.github.com/paulmillr/eb670806793e84df628a7c434a873066
|
|
17
|
+
*/
|
|
18
|
+
const secp256k1P = BigInt('0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f');
|
|
19
|
+
const secp256k1N = BigInt('0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141');
|
|
20
|
+
const _1n = BigInt(1);
|
|
21
|
+
const _2n = BigInt(2);
|
|
22
|
+
const divNearest = (a, b) => (a + b / _2n) / b;
|
|
23
|
+
/**
|
|
24
|
+
* Allows to compute square root √y 2x faster.
|
|
25
|
+
* To calculate √y, we need to exponentiate it to a very big number:
|
|
26
|
+
* `y² = x³ + ax + b; y = y² ^ (p+1)/4`
|
|
27
|
+
* We are unwrapping the loop and multiplying it bit-by-bit.
|
|
28
|
+
* (P+1n/4n).toString(2) would produce bits [223x 1, 0, 22x 1, 4x 0, 11, 00]
|
|
29
|
+
*/
|
|
30
|
+
// prettier-ignore
|
|
31
|
+
function sqrtMod(y) {
|
|
32
|
+
const P = secp256k1P;
|
|
33
|
+
const _3n = BigInt(3), _6n = BigInt(6), _11n = BigInt(11);
|
|
34
|
+
const _22n = BigInt(22);
|
|
35
|
+
const _23n = BigInt(23), _44n = BigInt(44), _88n = BigInt(88);
|
|
36
|
+
const b2 = (y * y * y) % P; // x^3, 11
|
|
37
|
+
const b3 = (b2 * b2 * y) % P; // x^7
|
|
38
|
+
const b6 = ((0, modular_1.pow2)(b3, _3n, P) * b3) % P;
|
|
39
|
+
const b9 = ((0, modular_1.pow2)(b6, _3n, P) * b3) % P;
|
|
40
|
+
const b11 = ((0, modular_1.pow2)(b9, _2n, P) * b2) % P;
|
|
41
|
+
const b22 = ((0, modular_1.pow2)(b11, _11n, P) * b11) % P;
|
|
42
|
+
const b44 = ((0, modular_1.pow2)(b22, _22n, P) * b22) % P;
|
|
43
|
+
const b88 = ((0, modular_1.pow2)(b44, _44n, P) * b44) % P;
|
|
44
|
+
const b176 = ((0, modular_1.pow2)(b88, _88n, P) * b88) % P;
|
|
45
|
+
const b220 = ((0, modular_1.pow2)(b176, _44n, P) * b44) % P;
|
|
46
|
+
const b223 = ((0, modular_1.pow2)(b220, _3n, P) * b3) % P;
|
|
47
|
+
const t1 = ((0, modular_1.pow2)(b223, _23n, P) * b22) % P;
|
|
48
|
+
const t2 = ((0, modular_1.pow2)(t1, _6n, P) * b2) % P;
|
|
49
|
+
return (0, modular_1.pow2)(t2, _2n, P);
|
|
50
|
+
}
|
|
51
|
+
exports.secp256k1 = (0, _shortw_utils_js_1.createCurve)({
|
|
52
|
+
// Params: a, b
|
|
53
|
+
// Seem to be rigid https://bitcointalk.org/index.php?topic=289795.msg3183975#msg3183975
|
|
54
|
+
a: BigInt(0),
|
|
55
|
+
b: BigInt(7),
|
|
56
|
+
// Field over which we'll do calculations;
|
|
57
|
+
// 2n**256n - 2n**32n - 2n**9n - 2n**8n - 2n**7n - 2n**6n - 2n**4n - 1n
|
|
58
|
+
P: secp256k1P,
|
|
59
|
+
// Curve order, total count of valid points in the field
|
|
60
|
+
n: secp256k1N,
|
|
61
|
+
// Base point (x, y) aka generator point
|
|
62
|
+
Gx: BigInt('55066263022277343669578718895168534326250603453777594175500187360389116729240'),
|
|
63
|
+
Gy: BigInt('32670510020758816978083085130507043184471273380659243275938904335757337482424'),
|
|
64
|
+
h: BigInt(1),
|
|
65
|
+
// Alllow only low-S signatures by default in sign() and verify()
|
|
66
|
+
lowS: true,
|
|
67
|
+
sqrtMod,
|
|
68
|
+
endo: {
|
|
69
|
+
// Params taken from https://gist.github.com/paulmillr/eb670806793e84df628a7c434a873066
|
|
70
|
+
beta: BigInt('0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee'),
|
|
71
|
+
splitScalar: (k) => {
|
|
72
|
+
const n = secp256k1N;
|
|
73
|
+
const a1 = BigInt('0x3086d221a7d46bcde86c90e49284eb15');
|
|
74
|
+
const b1 = -_1n * BigInt('0xe4437ed6010e88286f547fa90abfe4c3');
|
|
75
|
+
const a2 = BigInt('0x114ca50f7a8e2f3f657c1108d9d44cfd8');
|
|
76
|
+
const b2 = a1;
|
|
77
|
+
const POW_2_128 = BigInt('0x100000000000000000000000000000000');
|
|
78
|
+
const c1 = divNearest(b2 * k, n);
|
|
79
|
+
const c2 = divNearest(-b1 * k, n);
|
|
80
|
+
let k1 = (0, modular_1.mod)(k - c1 * a1 - c2 * a2, n);
|
|
81
|
+
let k2 = (0, modular_1.mod)(-c1 * b1 - c2 * b2, n);
|
|
82
|
+
const k1neg = k1 > POW_2_128;
|
|
83
|
+
const k2neg = k2 > POW_2_128;
|
|
84
|
+
if (k1neg)
|
|
85
|
+
k1 = n - k1;
|
|
86
|
+
if (k2neg)
|
|
87
|
+
k2 = n - k2;
|
|
88
|
+
if (k1 > POW_2_128 || k2 > POW_2_128) {
|
|
89
|
+
throw new Error('splitScalar: Endomorphism failed, k=' + k);
|
|
90
|
+
}
|
|
91
|
+
return { k1neg, k1, k2neg, k2 };
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
}, sha256_1.sha256);
|
|
95
|
+
// Schnorr
|
|
96
|
+
const _0n = BigInt(0);
|
|
97
|
+
const numTo32b = exports.secp256k1.utils._bigintToBytes;
|
|
98
|
+
const numTo32bStr = exports.secp256k1.utils._bigintToString;
|
|
99
|
+
const normalizePrivateKey = exports.secp256k1.utils._normalizePrivateKey;
|
|
100
|
+
// TODO: export?
|
|
101
|
+
function normalizePublicKey(publicKey) {
|
|
102
|
+
if (publicKey instanceof exports.secp256k1.Point) {
|
|
103
|
+
publicKey.assertValidity();
|
|
104
|
+
return publicKey;
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
const bytes = (0, utils_1.ensureBytes)(publicKey);
|
|
108
|
+
// Schnorr is 32 bytes
|
|
109
|
+
if (bytes.length === 32) {
|
|
110
|
+
const x = (0, utils_1.bytesToNumberBE)(bytes);
|
|
111
|
+
if (!isValidFieldElement(x))
|
|
112
|
+
throw new Error('Point is not on curve');
|
|
113
|
+
const y2 = exports.secp256k1.utils._weierstrassEquation(x); // y² = x³ + ax + b
|
|
114
|
+
let y = sqrtMod(y2); // y = y² ^ (p+1)/4
|
|
115
|
+
const isYOdd = (y & _1n) === _1n;
|
|
116
|
+
// Schnorr
|
|
117
|
+
if (isYOdd)
|
|
118
|
+
y = (0, modular_1.mod)(-y, exports.secp256k1.CURVE.P);
|
|
119
|
+
const point = new exports.secp256k1.Point(x, y);
|
|
120
|
+
point.assertValidity();
|
|
121
|
+
return point;
|
|
122
|
+
}
|
|
123
|
+
// Do we need that in schnorr at all?
|
|
124
|
+
return exports.secp256k1.Point.fromHex(publicKey);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
const isWithinCurveOrder = exports.secp256k1.utils._isWithinCurveOrder;
|
|
128
|
+
const isValidFieldElement = exports.secp256k1.utils._isValidFieldElement;
|
|
129
|
+
const TAGS = {
|
|
130
|
+
challenge: 'BIP0340/challenge',
|
|
131
|
+
aux: 'BIP0340/aux',
|
|
132
|
+
nonce: 'BIP0340/nonce',
|
|
133
|
+
};
|
|
134
|
+
/** An object mapping tags to their tagged hash prefix of [SHA256(tag) | SHA256(tag)] */
|
|
135
|
+
const TAGGED_HASH_PREFIXES = {};
|
|
136
|
+
function taggedHash(tag, ...messages) {
|
|
137
|
+
let tagP = TAGGED_HASH_PREFIXES[tag];
|
|
138
|
+
if (tagP === undefined) {
|
|
139
|
+
const tagH = (0, sha256_1.sha256)(Uint8Array.from(tag, (c) => c.charCodeAt(0)));
|
|
140
|
+
tagP = (0, utils_1.concatBytes)(tagH, tagH);
|
|
141
|
+
TAGGED_HASH_PREFIXES[tag] = tagP;
|
|
142
|
+
}
|
|
143
|
+
return (0, sha256_1.sha256)((0, utils_1.concatBytes)(tagP, ...messages));
|
|
144
|
+
}
|
|
145
|
+
exports.taggedHash = taggedHash;
|
|
146
|
+
const toRawX = (point) => point.toRawBytes(true).slice(1);
|
|
147
|
+
// Schnorr signatures are superior to ECDSA from above.
|
|
148
|
+
// Below is Schnorr-specific code as per BIP0340.
|
|
149
|
+
function schnorrChallengeFinalize(ch) {
|
|
150
|
+
return (0, modular_1.mod)((0, utils_1.bytesToNumberBE)(ch), exports.secp256k1.CURVE.n);
|
|
151
|
+
}
|
|
152
|
+
// Do we need this at all for Schnorr?
|
|
153
|
+
class SchnorrSignature {
|
|
154
|
+
constructor(r, s) {
|
|
155
|
+
this.r = r;
|
|
156
|
+
this.s = s;
|
|
157
|
+
this.assertValidity();
|
|
158
|
+
}
|
|
159
|
+
static fromHex(hex) {
|
|
160
|
+
const bytes = (0, utils_1.ensureBytes)(hex);
|
|
161
|
+
if (bytes.length !== 64)
|
|
162
|
+
throw new TypeError(`SchnorrSignature.fromHex: expected 64 bytes, not ${bytes.length}`);
|
|
163
|
+
const r = (0, utils_1.bytesToNumberBE)(bytes.subarray(0, 32));
|
|
164
|
+
const s = (0, utils_1.bytesToNumberBE)(bytes.subarray(32, 64));
|
|
165
|
+
return new SchnorrSignature(r, s);
|
|
166
|
+
}
|
|
167
|
+
assertValidity() {
|
|
168
|
+
const { r, s } = this;
|
|
169
|
+
if (!isValidFieldElement(r) || !isWithinCurveOrder(s))
|
|
170
|
+
throw new Error('Invalid signature');
|
|
171
|
+
}
|
|
172
|
+
toHex() {
|
|
173
|
+
return numTo32bStr(this.r) + numTo32bStr(this.s);
|
|
174
|
+
}
|
|
175
|
+
toRawBytes() {
|
|
176
|
+
return (0, utils_1.hexToBytes)(this.toHex());
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
function schnorrGetScalar(priv) {
|
|
180
|
+
const point = exports.secp256k1.Point.fromPrivateKey(priv);
|
|
181
|
+
const scalar = point.hasEvenY() ? priv : exports.secp256k1.CURVE.n - priv;
|
|
182
|
+
return { point, scalar, x: toRawX(point) };
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Synchronously creates Schnorr signature. Improved security: verifies itself before
|
|
186
|
+
* producing an output.
|
|
187
|
+
* @param msg message (not message hash)
|
|
188
|
+
* @param privateKey private key
|
|
189
|
+
* @param auxRand random bytes that would be added to k. Bad RNG won't break it.
|
|
190
|
+
*/
|
|
191
|
+
function schnorrSign(message, privateKey, auxRand = (0, utils_1.randomBytes)(32)) {
|
|
192
|
+
if (message == null)
|
|
193
|
+
throw new TypeError(`sign: Expected valid message, not "${message}"`);
|
|
194
|
+
const m = (0, utils_1.ensureBytes)(message);
|
|
195
|
+
// checks for isWithinCurveOrder
|
|
196
|
+
const { x: px, scalar: d } = schnorrGetScalar(normalizePrivateKey(privateKey));
|
|
197
|
+
const rand = (0, utils_1.ensureBytes)(auxRand);
|
|
198
|
+
if (rand.length !== 32)
|
|
199
|
+
throw new TypeError('sign: Expected 32 bytes of aux randomness');
|
|
200
|
+
const tag = taggedHash;
|
|
201
|
+
const t0h = tag(TAGS.aux, rand);
|
|
202
|
+
const t = numTo32b(d ^ (0, utils_1.bytesToNumberBE)(t0h));
|
|
203
|
+
const k0h = tag(TAGS.nonce, t, px, m);
|
|
204
|
+
const k0 = (0, modular_1.mod)((0, utils_1.bytesToNumberBE)(k0h), exports.secp256k1.CURVE.n);
|
|
205
|
+
if (k0 === _0n)
|
|
206
|
+
throw new Error('sign: Creation of signature failed. k is zero');
|
|
207
|
+
const { point: R, x: rx, scalar: k } = schnorrGetScalar(k0);
|
|
208
|
+
const e = schnorrChallengeFinalize(tag(TAGS.challenge, rx, px, m));
|
|
209
|
+
const sig = new SchnorrSignature(R.x, (0, modular_1.mod)(k + e * d, exports.secp256k1.CURVE.n)).toRawBytes();
|
|
210
|
+
if (!schnorrVerify(sig, m, px))
|
|
211
|
+
throw new Error('sign: Invalid signature produced');
|
|
212
|
+
return sig;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Verifies Schnorr signature synchronously.
|
|
216
|
+
*/
|
|
217
|
+
function schnorrVerify(signature, message, publicKey) {
|
|
218
|
+
try {
|
|
219
|
+
const raw = signature instanceof SchnorrSignature;
|
|
220
|
+
const sig = raw ? signature : SchnorrSignature.fromHex(signature);
|
|
221
|
+
if (raw)
|
|
222
|
+
sig.assertValidity(); // just in case
|
|
223
|
+
const { r, s } = sig;
|
|
224
|
+
const m = (0, utils_1.ensureBytes)(message);
|
|
225
|
+
const P = normalizePublicKey(publicKey);
|
|
226
|
+
const e = schnorrChallengeFinalize(taggedHash(TAGS.challenge, numTo32b(r), toRawX(P), m));
|
|
227
|
+
// Finalize
|
|
228
|
+
// R = s⋅G - e⋅P
|
|
229
|
+
// -eP == (n-e)P
|
|
230
|
+
const R = exports.secp256k1.Point.BASE.multiplyAndAddUnsafe(P, normalizePrivateKey(s), (0, modular_1.mod)(-e, exports.secp256k1.CURVE.n));
|
|
231
|
+
if (!R || !R.hasEvenY() || R.x !== r)
|
|
232
|
+
return false;
|
|
233
|
+
return true;
|
|
234
|
+
}
|
|
235
|
+
catch (error) {
|
|
236
|
+
return false;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
exports.schnorr = {
|
|
240
|
+
Signature: SchnorrSignature,
|
|
241
|
+
// Schnorr's pubkey is just `x` of Point (BIP340)
|
|
242
|
+
getPublicKey: (privateKey) => toRawX(exports.secp256k1.Point.fromPrivateKey(privateKey)),
|
|
243
|
+
sign: schnorrSign,
|
|
244
|
+
verify: schnorrVerify,
|
|
245
|
+
};
|