@did-btcr2/keypair 0.7.1 → 0.7.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/dist/cjs/public.js +40 -17
- package/dist/cjs/public.js.map +1 -1
- package/dist/cjs/secret.js +35 -14
- package/dist/cjs/secret.js.map +1 -1
- package/dist/esm/public.js +40 -17
- package/dist/esm/public.js.map +1 -1
- package/dist/esm/secret.js +35 -14
- package/dist/esm/secret.js.map +1 -1
- package/dist/types/public.d.ts +21 -9
- package/dist/types/public.d.ts.map +1 -1
- package/dist/types/secret.d.ts +12 -7
- package/dist/types/secret.d.ts.map +1 -1
- package/dist/types/types.d.ts +3 -0
- package/dist/types/types.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/public.ts +52 -20
- package/src/secret.ts +42 -17
- package/src/types.ts +2 -0
package/dist/cjs/public.js
CHANGED
|
@@ -12,39 +12,42 @@ import { Secp256k1SecretKey } from './secret.js';
|
|
|
12
12
|
*/
|
|
13
13
|
export class CompressedSecp256k1PublicKey {
|
|
14
14
|
/** @type {KeyBytes} The public key bytes */
|
|
15
|
-
|
|
15
|
+
#bytes;
|
|
16
16
|
/** @type {MultibaseObject} The public key as a MultibaseObject */
|
|
17
|
-
|
|
17
|
+
#multibase = {
|
|
18
18
|
prefix: BIP340_PUBLIC_KEY_MULTIBASE_PREFIX,
|
|
19
19
|
key: [],
|
|
20
20
|
encoded: ''
|
|
21
21
|
};
|
|
22
22
|
/**
|
|
23
23
|
* Creates a CompressedSecp256k1PublicKey instance.
|
|
24
|
-
* @param {
|
|
24
|
+
* @param {Hex} pk The public key byte array.
|
|
25
25
|
* @throws {PublicKeyError} if the byte length is not 32 (x-only) or 33 (compressed)
|
|
26
26
|
*/
|
|
27
|
-
constructor(
|
|
27
|
+
constructor(pk) {
|
|
28
|
+
pk = pk instanceof Uint8Array
|
|
29
|
+
? pk
|
|
30
|
+
: Buffer.fromHex(pk);
|
|
28
31
|
// If the byte length is not 33, throw an error
|
|
29
|
-
if (
|
|
30
|
-
throw new PublicKeyError('Invalid argument: byte length must be 33 (compressed)', 'CONSTRUCTOR_ERROR', {
|
|
32
|
+
if (!pk || pk.length !== 33) {
|
|
33
|
+
throw new PublicKeyError('Invalid argument: byte length must be 33 (compressed)', 'CONSTRUCTOR_ERROR', { pk });
|
|
31
34
|
}
|
|
32
35
|
// Validate the point is on curve and in compressed form
|
|
33
|
-
if (!tinysecp.isPoint(
|
|
34
|
-
throw new PublicKeyError('Invalid argument:
|
|
36
|
+
if (!tinysecp.isPoint(pk)) {
|
|
37
|
+
throw new PublicKeyError('Invalid argument: not a valid secp256k1 compressed point', 'CONSTRUCTOR_ERROR', { pk });
|
|
35
38
|
}
|
|
36
39
|
// Set the bytes
|
|
37
|
-
this
|
|
40
|
+
this.#bytes = pk;
|
|
38
41
|
// Set multibase
|
|
39
|
-
this.
|
|
40
|
-
this.
|
|
42
|
+
this.#multibase.encoded = this.encode();
|
|
43
|
+
this.#multibase.key = [...this.#multibase.prefix, ...this.compressed];
|
|
41
44
|
}
|
|
42
45
|
/**
|
|
43
46
|
* Get the compressed public key.
|
|
44
47
|
* @returns {KeyBytes} The 33-byte compressed public key (0x02 or 0x03, x).
|
|
45
48
|
*/
|
|
46
49
|
get compressed() {
|
|
47
|
-
const bytes = new Uint8Array(this
|
|
50
|
+
const bytes = new Uint8Array(this.#bytes);
|
|
48
51
|
return bytes;
|
|
49
52
|
}
|
|
50
53
|
;
|
|
@@ -60,7 +63,8 @@ export class CompressedSecp256k1PublicKey {
|
|
|
60
63
|
* X-only (32-byte) view of the public key per BIP-340.
|
|
61
64
|
*/
|
|
62
65
|
get xOnly() {
|
|
63
|
-
|
|
66
|
+
const xOnly = this.compressed.slice(1);
|
|
67
|
+
return xOnly;
|
|
64
68
|
}
|
|
65
69
|
/**
|
|
66
70
|
* Parity of the SEC compressed public key.
|
|
@@ -68,7 +72,7 @@ export class CompressedSecp256k1PublicKey {
|
|
|
68
72
|
* @throws {PublicKeyError} If the parity byte is not 0x02 or 0x03.
|
|
69
73
|
*/
|
|
70
74
|
get parity() {
|
|
71
|
-
const parity = this.
|
|
75
|
+
const parity = this.compressed[0];
|
|
72
76
|
if (![0x02, 0x03].includes(parity)) {
|
|
73
77
|
throw new PublicKeyError('Invalid state: parity byte must be 2 or 3', 'PARITY_ERROR', { parity });
|
|
74
78
|
}
|
|
@@ -79,7 +83,7 @@ export class CompressedSecp256k1PublicKey {
|
|
|
79
83
|
* @returns {boolean} True if the public key has even Y.
|
|
80
84
|
*/
|
|
81
85
|
get isEven() {
|
|
82
|
-
return this.
|
|
86
|
+
return this.parity === 0x02;
|
|
83
87
|
}
|
|
84
88
|
/**
|
|
85
89
|
* Get the x-coordinate of the public key.
|
|
@@ -102,12 +106,12 @@ export class CompressedSecp256k1PublicKey {
|
|
|
102
106
|
* @returns {MultibaseObject} An object containing the multibase bytes, address and prefix.
|
|
103
107
|
*/
|
|
104
108
|
get multibase() {
|
|
105
|
-
const multibase = this
|
|
109
|
+
const multibase = this.#multibase;
|
|
106
110
|
return multibase;
|
|
107
111
|
}
|
|
108
112
|
/**
|
|
109
113
|
* Returns the raw public key as a hex string.
|
|
110
|
-
* @returns {
|
|
114
|
+
* @returns {string} The public key as a hex string.
|
|
111
115
|
*/
|
|
112
116
|
get hex() {
|
|
113
117
|
const hex = Buffer.from(this.compressed).toString('hex');
|
|
@@ -190,6 +194,25 @@ export class CompressedSecp256k1PublicKey {
|
|
|
190
194
|
// Encode the bytes in base58btc format and return
|
|
191
195
|
return base58btc.encode(publicKeyMultibase.toUint8Array());
|
|
192
196
|
}
|
|
197
|
+
/**
|
|
198
|
+
* Verify a signature using schnorr or ecdsa.
|
|
199
|
+
* @param {SignatureBytes} signature Signature for verification.
|
|
200
|
+
* @param {string} data Data for verification.
|
|
201
|
+
* @param {CryptoOptions} opts Options for signing.
|
|
202
|
+
* @param {('ecdsa' | 'schnorr')} opts.scheme The signature scheme to use. Default is 'schnorr'.
|
|
203
|
+
* @returns {boolean} If the signature is valid against the public key.
|
|
204
|
+
*/
|
|
205
|
+
verify(signature, data, opts) {
|
|
206
|
+
opts ??= { scheme: 'schnorr' };
|
|
207
|
+
// Verify the signature depending on the scheme and return the result
|
|
208
|
+
if (opts.scheme === 'ecdsa') {
|
|
209
|
+
return tinysecp.verify(data, this.compressed, signature);
|
|
210
|
+
}
|
|
211
|
+
else if (opts.scheme === 'schnorr') {
|
|
212
|
+
return tinysecp.verifySchnorr(data, this.x, signature);
|
|
213
|
+
}
|
|
214
|
+
throw new PublicKeyError(`Invalid scheme: ${opts.scheme}.`, 'VERIFY_SIGNATURE_ERROR', opts);
|
|
215
|
+
}
|
|
193
216
|
/**
|
|
194
217
|
* Compares this public key to another public key.
|
|
195
218
|
* @param {CompressedSecp256k1PublicKey} other The other public key to compare
|
package/dist/cjs/public.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"public.js","sourceRoot":"","sources":["../../src/public.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kCAAkC,EAClC,uCAAuC,
|
|
1
|
+
{"version":3,"file":"public.js","sourceRoot":"","sources":["../../src/public.ts"],"names":[],"mappings":"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"}
|
package/dist/cjs/secret.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BIP340_SECRET_KEY_MULTIBASE_PREFIX, BIP340_SECRET_KEY_MULTIBASE_PREFIX_HASH, CURVE, SecretKeyError } from '@did-btcr2/common';
|
|
2
2
|
import { sha256 } from '@noble/hashes/sha2';
|
|
3
|
-
import { getRandomValues } from 'crypto';
|
|
3
|
+
import { getRandomValues, randomBytes } from 'crypto';
|
|
4
4
|
import { base58btc } from 'multiformats/bases/base58';
|
|
5
5
|
import * as tinysecp from 'tiny-secp256k1';
|
|
6
6
|
import { SchnorrKeyPair } from './pair.js';
|
|
@@ -15,11 +15,11 @@ import { CompressedSecp256k1PublicKey } from './public.js';
|
|
|
15
15
|
*/
|
|
16
16
|
export class Secp256k1SecretKey {
|
|
17
17
|
/** @type {KeyBytes} The entropy for the secret key as a byte array */
|
|
18
|
-
|
|
18
|
+
#bytes;
|
|
19
19
|
/** @type {bigint} The entropy for the secret key as a bigint */
|
|
20
|
-
|
|
20
|
+
#seed;
|
|
21
21
|
/** @type {string} The secret key as a secretKeyMultibase */
|
|
22
|
-
|
|
22
|
+
#multibase;
|
|
23
23
|
/**
|
|
24
24
|
* Instantiates an instance of Secp256k1SecretKey.
|
|
25
25
|
* @param {Entropy} entropy bytes (Uint8Array) or secret (bigint)
|
|
@@ -34,22 +34,22 @@ export class Secp256k1SecretKey {
|
|
|
34
34
|
}
|
|
35
35
|
// If bytes and bytes are not length 32
|
|
36
36
|
if (isBytes && entropy.length === 32) {
|
|
37
|
-
this
|
|
38
|
-
this
|
|
37
|
+
this.#bytes = entropy;
|
|
38
|
+
this.#seed = Secp256k1SecretKey.toSecret(entropy);
|
|
39
39
|
}
|
|
40
40
|
// If secret and secret is not a valid bigint, throw error
|
|
41
41
|
if (isSecret && !(entropy < 1n || entropy >= CURVE.n)) {
|
|
42
|
-
this
|
|
43
|
-
this
|
|
42
|
+
this.#bytes = Secp256k1SecretKey.toBytes(entropy);
|
|
43
|
+
this.#seed = entropy;
|
|
44
44
|
}
|
|
45
|
-
if (!this
|
|
45
|
+
if (!this.#bytes || this.#bytes.length !== 32) {
|
|
46
46
|
throw new SecretKeyError('Invalid bytes: must be a valid 32-byte secret key', 'CONSTRUCTOR_ERROR');
|
|
47
47
|
}
|
|
48
|
-
if (!this
|
|
48
|
+
if (!this.#seed || (this.#seed < 1n || this.#seed >= CURVE.n)) {
|
|
49
49
|
throw new SecretKeyError('Invalid seed: must must be valid bigint', 'CONSTRUCTOR_ERROR');
|
|
50
50
|
}
|
|
51
51
|
// Set the secret key multibase
|
|
52
|
-
this
|
|
52
|
+
this.#multibase = this.encode();
|
|
53
53
|
}
|
|
54
54
|
/**
|
|
55
55
|
* Get the secret key entropy as a byte array.
|
|
@@ -57,7 +57,7 @@ export class Secp256k1SecretKey {
|
|
|
57
57
|
*/
|
|
58
58
|
get bytes() {
|
|
59
59
|
// Return a copy of the secret key bytes
|
|
60
|
-
const bytes = new Uint8Array(this
|
|
60
|
+
const bytes = new Uint8Array(this.#bytes);
|
|
61
61
|
return bytes;
|
|
62
62
|
}
|
|
63
63
|
/**
|
|
@@ -66,7 +66,7 @@ export class Secp256k1SecretKey {
|
|
|
66
66
|
*/
|
|
67
67
|
get seed() {
|
|
68
68
|
// Memoize the secret and return
|
|
69
|
-
const seed = BigInt(this
|
|
69
|
+
const seed = BigInt(this.#seed);
|
|
70
70
|
return seed;
|
|
71
71
|
}
|
|
72
72
|
/**
|
|
@@ -82,7 +82,7 @@ export class Secp256k1SecretKey {
|
|
|
82
82
|
* @returns {string} The secret key in base58btc multibase format
|
|
83
83
|
*/
|
|
84
84
|
get multibase() {
|
|
85
|
-
const multibase = this
|
|
85
|
+
const multibase = this.#multibase;
|
|
86
86
|
return multibase;
|
|
87
87
|
}
|
|
88
88
|
/**
|
|
@@ -160,6 +160,27 @@ export class Secp256k1SecretKey {
|
|
|
160
160
|
// Return true if the computed public key equals the provided public key
|
|
161
161
|
return true;
|
|
162
162
|
}
|
|
163
|
+
/**
|
|
164
|
+
* Produce a signature over arbitrary data using schnorr or ecdsa.
|
|
165
|
+
* @param {MessageBytes} data Data to be signed.
|
|
166
|
+
* @param {CryptoOptions} opts Options for signing.
|
|
167
|
+
* @param {('ecdsa' | 'schnorr')} opts.scheme The signature scheme to use. Default is 'schnorr'.
|
|
168
|
+
* @returns {SignatureBytes} Signature byte array.
|
|
169
|
+
* @throws {SecretKeyError} if no private key is provided.
|
|
170
|
+
*/
|
|
171
|
+
sign(data, opts) {
|
|
172
|
+
// Set default options if not provided
|
|
173
|
+
opts ??= { scheme: 'schnorr' };
|
|
174
|
+
// Sign ecdsa and return
|
|
175
|
+
if (opts.scheme === 'ecdsa') {
|
|
176
|
+
return tinysecp.sign(data, this.bytes);
|
|
177
|
+
}
|
|
178
|
+
// Sign schnorr and return
|
|
179
|
+
if (opts.scheme === 'schnorr') {
|
|
180
|
+
return tinysecp.signSchnorr(data, this.bytes, randomBytes(32));
|
|
181
|
+
}
|
|
182
|
+
throw new SecretKeyError(`Invalid scheme: ${opts.scheme}.`, 'SIGN_ERROR', opts);
|
|
183
|
+
}
|
|
163
184
|
/**
|
|
164
185
|
* Decodes the multibase string to the 34-byte secret key (2 byte prefix + 32 byte key).
|
|
165
186
|
* @param {string} multibase The multibase string to decode
|
package/dist/cjs/secret.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"secret.js","sourceRoot":"","sources":["../../src/secret.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kCAAkC,EAClC,uCAAuC,EAEvC,KAAK,EAIL,cAAc,
|
|
1
|
+
{"version":3,"file":"secret.js","sourceRoot":"","sources":["../../src/secret.ts"],"names":[],"mappings":"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"}
|
package/dist/esm/public.js
CHANGED
|
@@ -12,39 +12,42 @@ import { Secp256k1SecretKey } from './secret.js';
|
|
|
12
12
|
*/
|
|
13
13
|
export class CompressedSecp256k1PublicKey {
|
|
14
14
|
/** @type {KeyBytes} The public key bytes */
|
|
15
|
-
|
|
15
|
+
#bytes;
|
|
16
16
|
/** @type {MultibaseObject} The public key as a MultibaseObject */
|
|
17
|
-
|
|
17
|
+
#multibase = {
|
|
18
18
|
prefix: BIP340_PUBLIC_KEY_MULTIBASE_PREFIX,
|
|
19
19
|
key: [],
|
|
20
20
|
encoded: ''
|
|
21
21
|
};
|
|
22
22
|
/**
|
|
23
23
|
* Creates a CompressedSecp256k1PublicKey instance.
|
|
24
|
-
* @param {
|
|
24
|
+
* @param {Hex} pk The public key byte array.
|
|
25
25
|
* @throws {PublicKeyError} if the byte length is not 32 (x-only) or 33 (compressed)
|
|
26
26
|
*/
|
|
27
|
-
constructor(
|
|
27
|
+
constructor(pk) {
|
|
28
|
+
pk = pk instanceof Uint8Array
|
|
29
|
+
? pk
|
|
30
|
+
: Buffer.fromHex(pk);
|
|
28
31
|
// If the byte length is not 33, throw an error
|
|
29
|
-
if (
|
|
30
|
-
throw new PublicKeyError('Invalid argument: byte length must be 33 (compressed)', 'CONSTRUCTOR_ERROR', {
|
|
32
|
+
if (!pk || pk.length !== 33) {
|
|
33
|
+
throw new PublicKeyError('Invalid argument: byte length must be 33 (compressed)', 'CONSTRUCTOR_ERROR', { pk });
|
|
31
34
|
}
|
|
32
35
|
// Validate the point is on curve and in compressed form
|
|
33
|
-
if (!tinysecp.isPoint(
|
|
34
|
-
throw new PublicKeyError('Invalid argument:
|
|
36
|
+
if (!tinysecp.isPoint(pk)) {
|
|
37
|
+
throw new PublicKeyError('Invalid argument: not a valid secp256k1 compressed point', 'CONSTRUCTOR_ERROR', { pk });
|
|
35
38
|
}
|
|
36
39
|
// Set the bytes
|
|
37
|
-
this
|
|
40
|
+
this.#bytes = pk;
|
|
38
41
|
// Set multibase
|
|
39
|
-
this.
|
|
40
|
-
this.
|
|
42
|
+
this.#multibase.encoded = this.encode();
|
|
43
|
+
this.#multibase.key = [...this.#multibase.prefix, ...this.compressed];
|
|
41
44
|
}
|
|
42
45
|
/**
|
|
43
46
|
* Get the compressed public key.
|
|
44
47
|
* @returns {KeyBytes} The 33-byte compressed public key (0x02 or 0x03, x).
|
|
45
48
|
*/
|
|
46
49
|
get compressed() {
|
|
47
|
-
const bytes = new Uint8Array(this
|
|
50
|
+
const bytes = new Uint8Array(this.#bytes);
|
|
48
51
|
return bytes;
|
|
49
52
|
}
|
|
50
53
|
;
|
|
@@ -60,7 +63,8 @@ export class CompressedSecp256k1PublicKey {
|
|
|
60
63
|
* X-only (32-byte) view of the public key per BIP-340.
|
|
61
64
|
*/
|
|
62
65
|
get xOnly() {
|
|
63
|
-
|
|
66
|
+
const xOnly = this.compressed.slice(1);
|
|
67
|
+
return xOnly;
|
|
64
68
|
}
|
|
65
69
|
/**
|
|
66
70
|
* Parity of the SEC compressed public key.
|
|
@@ -68,7 +72,7 @@ export class CompressedSecp256k1PublicKey {
|
|
|
68
72
|
* @throws {PublicKeyError} If the parity byte is not 0x02 or 0x03.
|
|
69
73
|
*/
|
|
70
74
|
get parity() {
|
|
71
|
-
const parity = this.
|
|
75
|
+
const parity = this.compressed[0];
|
|
72
76
|
if (![0x02, 0x03].includes(parity)) {
|
|
73
77
|
throw new PublicKeyError('Invalid state: parity byte must be 2 or 3', 'PARITY_ERROR', { parity });
|
|
74
78
|
}
|
|
@@ -79,7 +83,7 @@ export class CompressedSecp256k1PublicKey {
|
|
|
79
83
|
* @returns {boolean} True if the public key has even Y.
|
|
80
84
|
*/
|
|
81
85
|
get isEven() {
|
|
82
|
-
return this.
|
|
86
|
+
return this.parity === 0x02;
|
|
83
87
|
}
|
|
84
88
|
/**
|
|
85
89
|
* Get the x-coordinate of the public key.
|
|
@@ -102,12 +106,12 @@ export class CompressedSecp256k1PublicKey {
|
|
|
102
106
|
* @returns {MultibaseObject} An object containing the multibase bytes, address and prefix.
|
|
103
107
|
*/
|
|
104
108
|
get multibase() {
|
|
105
|
-
const multibase = this
|
|
109
|
+
const multibase = this.#multibase;
|
|
106
110
|
return multibase;
|
|
107
111
|
}
|
|
108
112
|
/**
|
|
109
113
|
* Returns the raw public key as a hex string.
|
|
110
|
-
* @returns {
|
|
114
|
+
* @returns {string} The public key as a hex string.
|
|
111
115
|
*/
|
|
112
116
|
get hex() {
|
|
113
117
|
const hex = Buffer.from(this.compressed).toString('hex');
|
|
@@ -190,6 +194,25 @@ export class CompressedSecp256k1PublicKey {
|
|
|
190
194
|
// Encode the bytes in base58btc format and return
|
|
191
195
|
return base58btc.encode(publicKeyMultibase.toUint8Array());
|
|
192
196
|
}
|
|
197
|
+
/**
|
|
198
|
+
* Verify a signature using schnorr or ecdsa.
|
|
199
|
+
* @param {SignatureBytes} signature Signature for verification.
|
|
200
|
+
* @param {string} data Data for verification.
|
|
201
|
+
* @param {CryptoOptions} opts Options for signing.
|
|
202
|
+
* @param {('ecdsa' | 'schnorr')} opts.scheme The signature scheme to use. Default is 'schnorr'.
|
|
203
|
+
* @returns {boolean} If the signature is valid against the public key.
|
|
204
|
+
*/
|
|
205
|
+
verify(signature, data, opts) {
|
|
206
|
+
opts ??= { scheme: 'schnorr' };
|
|
207
|
+
// Verify the signature depending on the scheme and return the result
|
|
208
|
+
if (opts.scheme === 'ecdsa') {
|
|
209
|
+
return tinysecp.verify(data, this.compressed, signature);
|
|
210
|
+
}
|
|
211
|
+
else if (opts.scheme === 'schnorr') {
|
|
212
|
+
return tinysecp.verifySchnorr(data, this.x, signature);
|
|
213
|
+
}
|
|
214
|
+
throw new PublicKeyError(`Invalid scheme: ${opts.scheme}.`, 'VERIFY_SIGNATURE_ERROR', opts);
|
|
215
|
+
}
|
|
193
216
|
/**
|
|
194
217
|
* Compares this public key to another public key.
|
|
195
218
|
* @param {CompressedSecp256k1PublicKey} other The other public key to compare
|
package/dist/esm/public.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"public.js","sourceRoot":"","sources":["../../src/public.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kCAAkC,EAClC,uCAAuC,
|
|
1
|
+
{"version":3,"file":"public.js","sourceRoot":"","sources":["../../src/public.ts"],"names":[],"mappings":"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"}
|
package/dist/esm/secret.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BIP340_SECRET_KEY_MULTIBASE_PREFIX, BIP340_SECRET_KEY_MULTIBASE_PREFIX_HASH, CURVE, SecretKeyError } from '@did-btcr2/common';
|
|
2
2
|
import { sha256 } from '@noble/hashes/sha2';
|
|
3
|
-
import { getRandomValues } from 'crypto';
|
|
3
|
+
import { getRandomValues, randomBytes } from 'crypto';
|
|
4
4
|
import { base58btc } from 'multiformats/bases/base58';
|
|
5
5
|
import * as tinysecp from 'tiny-secp256k1';
|
|
6
6
|
import { SchnorrKeyPair } from './pair.js';
|
|
@@ -15,11 +15,11 @@ import { CompressedSecp256k1PublicKey } from './public.js';
|
|
|
15
15
|
*/
|
|
16
16
|
export class Secp256k1SecretKey {
|
|
17
17
|
/** @type {KeyBytes} The entropy for the secret key as a byte array */
|
|
18
|
-
|
|
18
|
+
#bytes;
|
|
19
19
|
/** @type {bigint} The entropy for the secret key as a bigint */
|
|
20
|
-
|
|
20
|
+
#seed;
|
|
21
21
|
/** @type {string} The secret key as a secretKeyMultibase */
|
|
22
|
-
|
|
22
|
+
#multibase;
|
|
23
23
|
/**
|
|
24
24
|
* Instantiates an instance of Secp256k1SecretKey.
|
|
25
25
|
* @param {Entropy} entropy bytes (Uint8Array) or secret (bigint)
|
|
@@ -34,22 +34,22 @@ export class Secp256k1SecretKey {
|
|
|
34
34
|
}
|
|
35
35
|
// If bytes and bytes are not length 32
|
|
36
36
|
if (isBytes && entropy.length === 32) {
|
|
37
|
-
this
|
|
38
|
-
this
|
|
37
|
+
this.#bytes = entropy;
|
|
38
|
+
this.#seed = Secp256k1SecretKey.toSecret(entropy);
|
|
39
39
|
}
|
|
40
40
|
// If secret and secret is not a valid bigint, throw error
|
|
41
41
|
if (isSecret && !(entropy < 1n || entropy >= CURVE.n)) {
|
|
42
|
-
this
|
|
43
|
-
this
|
|
42
|
+
this.#bytes = Secp256k1SecretKey.toBytes(entropy);
|
|
43
|
+
this.#seed = entropy;
|
|
44
44
|
}
|
|
45
|
-
if (!this
|
|
45
|
+
if (!this.#bytes || this.#bytes.length !== 32) {
|
|
46
46
|
throw new SecretKeyError('Invalid bytes: must be a valid 32-byte secret key', 'CONSTRUCTOR_ERROR');
|
|
47
47
|
}
|
|
48
|
-
if (!this
|
|
48
|
+
if (!this.#seed || (this.#seed < 1n || this.#seed >= CURVE.n)) {
|
|
49
49
|
throw new SecretKeyError('Invalid seed: must must be valid bigint', 'CONSTRUCTOR_ERROR');
|
|
50
50
|
}
|
|
51
51
|
// Set the secret key multibase
|
|
52
|
-
this
|
|
52
|
+
this.#multibase = this.encode();
|
|
53
53
|
}
|
|
54
54
|
/**
|
|
55
55
|
* Get the secret key entropy as a byte array.
|
|
@@ -57,7 +57,7 @@ export class Secp256k1SecretKey {
|
|
|
57
57
|
*/
|
|
58
58
|
get bytes() {
|
|
59
59
|
// Return a copy of the secret key bytes
|
|
60
|
-
const bytes = new Uint8Array(this
|
|
60
|
+
const bytes = new Uint8Array(this.#bytes);
|
|
61
61
|
return bytes;
|
|
62
62
|
}
|
|
63
63
|
/**
|
|
@@ -66,7 +66,7 @@ export class Secp256k1SecretKey {
|
|
|
66
66
|
*/
|
|
67
67
|
get seed() {
|
|
68
68
|
// Memoize the secret and return
|
|
69
|
-
const seed = BigInt(this
|
|
69
|
+
const seed = BigInt(this.#seed);
|
|
70
70
|
return seed;
|
|
71
71
|
}
|
|
72
72
|
/**
|
|
@@ -82,7 +82,7 @@ export class Secp256k1SecretKey {
|
|
|
82
82
|
* @returns {string} The secret key in base58btc multibase format
|
|
83
83
|
*/
|
|
84
84
|
get multibase() {
|
|
85
|
-
const multibase = this
|
|
85
|
+
const multibase = this.#multibase;
|
|
86
86
|
return multibase;
|
|
87
87
|
}
|
|
88
88
|
/**
|
|
@@ -160,6 +160,27 @@ export class Secp256k1SecretKey {
|
|
|
160
160
|
// Return true if the computed public key equals the provided public key
|
|
161
161
|
return true;
|
|
162
162
|
}
|
|
163
|
+
/**
|
|
164
|
+
* Produce a signature over arbitrary data using schnorr or ecdsa.
|
|
165
|
+
* @param {MessageBytes} data Data to be signed.
|
|
166
|
+
* @param {CryptoOptions} opts Options for signing.
|
|
167
|
+
* @param {('ecdsa' | 'schnorr')} opts.scheme The signature scheme to use. Default is 'schnorr'.
|
|
168
|
+
* @returns {SignatureBytes} Signature byte array.
|
|
169
|
+
* @throws {SecretKeyError} if no private key is provided.
|
|
170
|
+
*/
|
|
171
|
+
sign(data, opts) {
|
|
172
|
+
// Set default options if not provided
|
|
173
|
+
opts ??= { scheme: 'schnorr' };
|
|
174
|
+
// Sign ecdsa and return
|
|
175
|
+
if (opts.scheme === 'ecdsa') {
|
|
176
|
+
return tinysecp.sign(data, this.bytes);
|
|
177
|
+
}
|
|
178
|
+
// Sign schnorr and return
|
|
179
|
+
if (opts.scheme === 'schnorr') {
|
|
180
|
+
return tinysecp.signSchnorr(data, this.bytes, randomBytes(32));
|
|
181
|
+
}
|
|
182
|
+
throw new SecretKeyError(`Invalid scheme: ${opts.scheme}.`, 'SIGN_ERROR', opts);
|
|
183
|
+
}
|
|
163
184
|
/**
|
|
164
185
|
* Decodes the multibase string to the 34-byte secret key (2 byte prefix + 32 byte key).
|
|
165
186
|
* @param {string} multibase The multibase string to decode
|
package/dist/esm/secret.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"secret.js","sourceRoot":"","sources":["../../src/secret.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kCAAkC,EAClC,uCAAuC,EAEvC,KAAK,EAIL,cAAc,
|
|
1
|
+
{"version":3,"file":"secret.js","sourceRoot":"","sources":["../../src/secret.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kCAAkC,EAClC,uCAAuC,EAEvC,KAAK,EAIL,cAAc,EAGf,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,4BAA4B,EAAE,MAAM,aAAa,CAAC;AAsD3D;;;;;;;GAOG;AACH,MAAM,OAAO,kBAAkB;IAC7B,sEAAsE;IAC7D,MAAM,CAAY;IAE3B,gEAAgE;IACvD,KAAK,CAAU;IAExB,4DAA4D;IACnD,UAAU,CAAS;IAE5B;;;;OAIG;IACH,YAAY,OAAgB;QAC1B,4DAA4D;QAC5D,MAAM,OAAO,GAAG,OAAO,YAAY,UAAU,CAAC;QAC9C,MAAM,QAAQ,GAAG,OAAO,OAAO,KAAK,QAAQ,CAAC;QAC7C,IAAG,CAAC,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;YACzB,MAAM,IAAI,cAAc,CACtB,4DAA4D,EAC5D,mBAAmB,CACpB,CAAC;QACJ,CAAC;QAED,uCAAuC;QACvC,IAAI,OAAO,IAAI,OAAO,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;YACrC,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC;YACtB,IAAI,CAAC,KAAK,GAAG,kBAAkB,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACpD,CAAC;QAED,0DAA0D;QAC1D,IAAI,QAAQ,IAAI,CAAC,CAAC,OAAO,GAAG,EAAE,IAAI,OAAO,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;YACtD,IAAI,CAAC,MAAM,GAAG,kBAAkB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YAClD,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC;QACvB,CAAC;QAED,IAAG,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;YAC7C,MAAM,IAAI,cAAc,CACtB,mDAAmD,EACnD,mBAAmB,CACpB,CAAC;QACJ,CAAC;QAED,IAAG,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,EAAE,IAAI,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7D,MAAM,IAAI,cAAc,CACtB,yCAAyC,EACzC,mBAAmB,CACpB,CAAC;QACJ,CAAC;QAED,+BAA+B;QAC/B,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;IAClC,CAAC;IAED;;;OAGG;IACH,IAAI,KAAK;QACP,wCAAwC;QACxC,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,MAAO,CAAC,CAAC;QAC3C,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;OAGG;IACH,IAAI,IAAI;QACN,gCAAgC;QAChC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,KAAM,CAAW,CAAC;QAC3C,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;OAGG;IACH,IAAI,GAAG;QACL,mDAAmD;QACnD,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACjD,CAAC;IAGD;;;OAGG;IACH,IAAI,SAAS;QACX,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC;QAClC,OAAO,SAAS,CAAC;IACnB,CAAC;IAED;;;OAGG;IACI,MAAM;QACX,uCAAuC;QACvC,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;QAE5C,IAAG,cAAc,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;YAChC,MAAM,IAAI,cAAc,CACtB,wDAAwD,EACxD,wBAAwB,CACzB,CAAC;QACJ,CAAC;QACD,6BAA6B;QAC7B,MAAM,UAAU,GAAG,kCAAkC,CAAC,OAAO,EAAE,CAAC;QAEhE,qDAAqD;QACrD,UAAU,CAAC,IAAI,CAAC,GAAG,cAAc,CAAC,CAAC;QAEnC,kDAAkD;QAClD,OAAO,SAAS,CAAC,MAAM,CAAC,UAAU,CAAC,YAAY,EAAE,CAAC,CAAC;IACrD,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,KAAyB;QACrC,8CAA8C;QAC9C,OAAO,IAAI,CAAC,GAAG,KAAK,KAAK,CAAC,GAAG,CAAC;IAChC,CAAC;IAED;;;OAGG;IACI,gBAAgB;QACrB,4CAA4C;QAC5C,MAAM,cAAc,GAAG,QAAQ,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAElE,gCAAgC;QAChC,IAAI,CAAC,cAAc,EAAE,CAAC;YACpB,MAAM,IAAI,cAAc,CACtB,8CAA8C,EAC9C,0BAA0B,CAC3B,CAAC;QACJ,CAAC;QAED,+CAA+C;QAC/C,IAAG,cAAc,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;YAChC,MAAM,IAAI,cAAc,CACtB,mDAAmD,EACnD,0BAA0B,CAC3B,CAAC;QACJ,CAAC;QAED,OAAO,IAAI,4BAA4B,CAAC,cAAc,CAAC,CAAC;IAC1D,CAAC;IAED;;;OAGG;IACI,IAAI;QACT,OAAO;YACL,KAAK,EAAG,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE;YAC5B,IAAI,EAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;YAC5B,GAAG,EAAK,IAAI,CAAC,GAAG;SACjB,CAAC;IACJ,CAAC;IAED;;;OAGG;IACI,OAAO;QACZ,OAAO,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACxC,CAAC;IAED;;;OAGG;IACI,iBAAiB;QACtB,6DAA6D;QAC7D,MAAM,EAAE,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAEnC,+CAA+C;QAC/C,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC;YACrC,OAAO,KAAK,CAAC;QACf,CAAC;QAED,wEAAwE;QACxE,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;OAOG;IACI,IAAI,CAAC,IAAW,EAAE,IAAoB;QAC3C,sCAAsC;QACtC,IAAI,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;QAE/B,wBAAwB;QACxB,IAAG,IAAI,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;YAC3B,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;QACzC,CAAC;QAED,0BAA0B;QAC1B,IAAG,IAAI,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAC7B,OAAO,QAAQ,CAAC,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC;QACjE,CAAC;QAED,MAAM,IAAI,cAAc,CAAC,mBAAmB,IAAI,CAAC,MAAM,GAAG,EAAE,YAAY,EAAE,IAAI,CAAC,CAAC;IAClF,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,MAAM,CAAC,SAAiB;QACpC,yCAAyC;QACzC,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAE5C,2DAA2D;QAC3D,IAAG,OAAO,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;YACzB,MAAM,IAAI,cAAc,CACtB,sDAAsD,EACtD,wBAAwB,CACzB,CAAC;QACJ,CAAC;QAED,wBAAwB;QACxB,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAEnC,0BAA0B;QAC1B,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAE/D,2EAA2E;QAC3E,IAAI,UAAU,KAAK,uCAAuC,EAAE,CAAC;YAC3D,MAAM,IAAI,cAAc,CACtB,8CAA8C,MAAM,EAAE,EACtD,wBAAwB,CACzB,CAAC;QACJ,CAAC;QAED,+BAA+B;QAC/B,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,QAAQ,CAAC,IAAqB;QAC1C,OAAO,IAAI,kBAAkB,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IAC5D,CAAC;IAED;;;;;OAKG;IACI,MAAM,CAAC,SAAS,CAAC,KAAe;QACrC,iDAAiD;QACjD,MAAM,SAAS,GAAG,IAAI,kBAAkB,CAAC,KAAK,CAAC,CAAC;QAEhD,6CAA6C;QAC7C,MAAM,SAAS,GAAG,SAAS,CAAC,gBAAgB,EAAE,CAAC;QAE/C,uDAAuD;QACvD,OAAO,IAAI,cAAc,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC,CAAC;IACtD,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,QAAQ,CAAC,KAAe;QACpC,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;IACrE,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,OAAO,CAAC,MAAc;QAClC,iFAAiF;QACjF,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,CAC3B,EAAE,MAAM,EAAE,EAAE,EAAE,EACd,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAChE,CAAC;QAEF,6DAA6D;QAC7D,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;YAC/B,MAAM,IAAI,cAAc,CACtB,+CAA+C,EAC/C,uBAAuB,CACxB,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,WAAW,CAAC,OAAe;QACvC,4CAA4C;QAC5C,MAAM,SAAS,GAAG,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;QACzD,yCAAyC;QACzC,MAAM,eAAe,GAAG,IAAI,UAAU,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,CAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;QAClG,yCAAyC;QACzC,OAAO,IAAI,kBAAkB,CAAC,eAAe,CAAC,CAAC;IACjD,CAAC;IAED;;;OAGG;IACI,MAAM,CAAC,MAAM;QAClB,+BAA+B;QAC/B,MAAM,SAAS,GAAG,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC;QAErC,4EAA4E;QAC5E,OAAO,eAAe,CAAC,SAAS,CAAC,CAAC;IACpC,CAAC;IAED;;;OAGG;IACI,MAAM,CAAC,QAAQ;QACpB,+BAA+B;QAC/B,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAElC,4EAA4E;QAC5E,OAAO,IAAI,kBAAkB,CAAC,WAAW,CAAC,CAAC;IAC7C,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,YAAY,CAAC,KAAe;QACxC,4EAA4E;QAC5E,OAAO,IAAI,kBAAkB,CAAC,KAAK,CAAC,CAAC,gBAAgB,EAAE,CAAC;IAC1D,CAAC;CACF"}
|
package/dist/types/public.d.ts
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
|
-
import { Hex, KeyBytes, MultibaseObject, PublicKeyObject } from '@did-btcr2/common';
|
|
1
|
+
import { Bytes, Hex, KeyBytes, MultibaseObject, PublicKeyObject } from '@did-btcr2/common';
|
|
2
2
|
import { Secp256k1SecretKey } from './secret.js';
|
|
3
|
+
import { CryptoOptions } from './types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Point Interface representing an (x, y) coordinate on the secp256k1 curve.
|
|
6
|
+
* @interface Point
|
|
7
|
+
* @type {Point}
|
|
8
|
+
*/
|
|
3
9
|
export interface Point {
|
|
4
10
|
x: KeyBytes;
|
|
5
11
|
y: KeyBytes;
|
|
@@ -90,16 +96,13 @@ export interface PublicKey {
|
|
|
90
96
|
* @type {CompressedSecp256k1PublicKey}
|
|
91
97
|
*/
|
|
92
98
|
export declare class CompressedSecp256k1PublicKey implements PublicKey {
|
|
93
|
-
|
|
94
|
-
private readonly _bytes;
|
|
95
|
-
/** @type {MultibaseObject} The public key as a MultibaseObject */
|
|
96
|
-
private _multibase;
|
|
99
|
+
#private;
|
|
97
100
|
/**
|
|
98
101
|
* Creates a CompressedSecp256k1PublicKey instance.
|
|
99
|
-
* @param {
|
|
102
|
+
* @param {Hex} pk The public key byte array.
|
|
100
103
|
* @throws {PublicKeyError} if the byte length is not 32 (x-only) or 33 (compressed)
|
|
101
104
|
*/
|
|
102
|
-
constructor(
|
|
105
|
+
constructor(pk: Hex);
|
|
103
106
|
/**
|
|
104
107
|
* Get the compressed public key.
|
|
105
108
|
* @returns {KeyBytes} The 33-byte compressed public key (0x02 or 0x03, x).
|
|
@@ -142,9 +145,9 @@ export declare class CompressedSecp256k1PublicKey implements PublicKey {
|
|
|
142
145
|
get multibase(): MultibaseObject;
|
|
143
146
|
/**
|
|
144
147
|
* Returns the raw public key as a hex string.
|
|
145
|
-
* @returns {
|
|
148
|
+
* @returns {string} The public key as a hex string.
|
|
146
149
|
*/
|
|
147
|
-
get hex():
|
|
150
|
+
get hex(): string;
|
|
148
151
|
/**
|
|
149
152
|
* Return the public key point.
|
|
150
153
|
* @returns {Point} The public key point.
|
|
@@ -172,6 +175,15 @@ export declare class CompressedSecp256k1PublicKey implements PublicKey {
|
|
|
172
175
|
* @returns {string} The public key encoded in base-58-btc multibase format.
|
|
173
176
|
*/
|
|
174
177
|
encode(): string;
|
|
178
|
+
/**
|
|
179
|
+
* Verify a signature using schnorr or ecdsa.
|
|
180
|
+
* @param {SignatureBytes} signature Signature for verification.
|
|
181
|
+
* @param {string} data Data for verification.
|
|
182
|
+
* @param {CryptoOptions} opts Options for signing.
|
|
183
|
+
* @param {('ecdsa' | 'schnorr')} opts.scheme The signature scheme to use. Default is 'schnorr'.
|
|
184
|
+
* @returns {boolean} If the signature is valid against the public key.
|
|
185
|
+
*/
|
|
186
|
+
verify(signature: Bytes, data: Bytes, opts?: CryptoOptions): boolean;
|
|
175
187
|
/**
|
|
176
188
|
* Compares this public key to another public key.
|
|
177
189
|
* @param {CompressedSecp256k1PublicKey} other The other public key to compare
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../src/public.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../src/public.ts"],"names":[],"mappings":"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"}
|
package/dist/types/secret.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { Bytes, Entropy, Hex, KeyBytes, SecretKeyObject } from '@did-btcr2/common';
|
|
1
|
+
import { Bytes, Entropy, Hex, KeyBytes, SecretKeyObject, SignatureBytes } from '@did-btcr2/common';
|
|
2
2
|
import { SchnorrKeyPair } from './pair.js';
|
|
3
3
|
import { CompressedSecp256k1PublicKey } from './public.js';
|
|
4
|
+
import { CryptoOptions } from './types.js';
|
|
4
5
|
/**
|
|
5
6
|
* General SecretKey interface for the Secp256k1SecretKey class.
|
|
6
7
|
* @interface SecretKey
|
|
@@ -54,12 +55,7 @@ export interface SecretKey {
|
|
|
54
55
|
* @implements {SecretKey}
|
|
55
56
|
*/
|
|
56
57
|
export declare class Secp256k1SecretKey implements SecretKey {
|
|
57
|
-
|
|
58
|
-
private _bytes?;
|
|
59
|
-
/** @type {bigint} The entropy for the secret key as a bigint */
|
|
60
|
-
private _seed?;
|
|
61
|
-
/** @type {string} The secret key as a secretKeyMultibase */
|
|
62
|
-
private _multibase;
|
|
58
|
+
#private;
|
|
63
59
|
/**
|
|
64
60
|
* Instantiates an instance of Secp256k1SecretKey.
|
|
65
61
|
* @param {Entropy} entropy bytes (Uint8Array) or secret (bigint)
|
|
@@ -117,6 +113,15 @@ export declare class Secp256k1SecretKey implements SecretKey {
|
|
|
117
113
|
* @returns {boolean} True if the public key is valid, false otherwise
|
|
118
114
|
*/
|
|
119
115
|
hasValidPublicKey(): boolean;
|
|
116
|
+
/**
|
|
117
|
+
* Produce a signature over arbitrary data using schnorr or ecdsa.
|
|
118
|
+
* @param {MessageBytes} data Data to be signed.
|
|
119
|
+
* @param {CryptoOptions} opts Options for signing.
|
|
120
|
+
* @param {('ecdsa' | 'schnorr')} opts.scheme The signature scheme to use. Default is 'schnorr'.
|
|
121
|
+
* @returns {SignatureBytes} Signature byte array.
|
|
122
|
+
* @throws {SecretKeyError} if no private key is provided.
|
|
123
|
+
*/
|
|
124
|
+
sign(data: Bytes, opts?: CryptoOptions): SignatureBytes;
|
|
120
125
|
/**
|
|
121
126
|
* Decodes the multibase string to the 34-byte secret key (2 byte prefix + 32 byte key).
|
|
122
127
|
* @param {string} multibase The multibase string to decode
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"secret.d.ts","sourceRoot":"","sources":["../../src/secret.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,EAEL,OAAO,EACP,GAAG,EACH,QAAQ,EAER,eAAe,
|
|
1
|
+
{"version":3,"file":"secret.d.ts","sourceRoot":"","sources":["../../src/secret.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,EAEL,OAAO,EACP,GAAG,EACH,QAAQ,EAER,eAAe,EACf,cAAc,EACf,MAAM,mBAAmB,CAAC;AAK3B,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,4BAA4B,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C;;;;GAIG;AACH,MAAM,WAAW,SAAS;IACxB;;;OAGG;IACH,KAAK,EAAE,QAAQ,CAAC;IAEhB;;;;OAIG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;;OAGG;IACH,GAAG,EAAE,GAAG,CAAC;IAET;;;;OAIG;IACH,MAAM,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC;IAE3C;;;OAGG;IACH,gBAAgB,IAAI,4BAA4B,CAAC;IAEjD;;;OAGG;IACH,OAAO,IAAI,OAAO,CAAC;IAEnB;;;OAGG;IACH,IAAI,IAAI,eAAe,CAAC;CACzB;AAED;;;;;;;GAOG;AACH,qBAAa,kBAAmB,YAAW,SAAS;;IAUlD;;;;OAIG;gBACS,OAAO,EAAE,OAAO;IAyC5B;;;OAGG;IACH,IAAI,KAAK,IAAI,UAAU,CAItB;IAED;;;OAGG;IACH,IAAI,IAAI,IAAI,MAAM,CAIjB;IAED;;;OAGG;IACH,IAAI,GAAG,IAAI,GAAG,CAGb;IAGD;;;OAGG;IACH,IAAI,SAAS,IAAI,MAAM,CAGtB;IAED;;;OAGG;IACI,MAAM,IAAI,MAAM;IAoBvB;;;;OAIG;IACI,MAAM,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO;IAKjD;;;OAGG;IACI,gBAAgB,IAAI,4BAA4B;IAuBvD;;;OAGG;IACI,IAAI,IAAI,eAAe;IAQ9B;;;OAGG;IACI,OAAO,IAAI,OAAO;IAIzB;;;OAGG;IACI,iBAAiB,IAAI,OAAO;IAanC;;;;;;;OAOG;IACI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,aAAa,GAAG,cAAc;IAiB9D;;;;OAIG;WACW,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,KAAK;IA8B9C;;;;OAIG;WACW,QAAQ,CAAC,IAAI,EAAE,eAAe,GAAG,kBAAkB;IAIjE;;;;;OAKG;WACW,SAAS,CAAC,KAAK,EAAE,QAAQ,GAAG,cAAc;IAWxD;;;;OAIG;WACW,QAAQ,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM;IAI/C;;;;OAIG;WACW,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ;IAiB/C;;;;OAIG;WACW,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,kBAAkB;IAS9D;;;OAGG;WACW,MAAM,IAAI,QAAQ;IAQhC;;;OAGG;WACW,QAAQ,IAAI,kBAAkB;IAQ5C;;;;OAIG;WACW,YAAY,CAAC,KAAK,EAAE,QAAQ,GAAG,4BAA4B;CAI1E"}
|
package/dist/types/types.d.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { Hex, KeyBytes } from '@did-btcr2/common';
|
|
2
2
|
import { CompressedSecp256k1PublicKey } from './public.js';
|
|
3
3
|
import { Secp256k1SecretKey } from './secret.js';
|
|
4
|
+
export type CryptoOptions = {
|
|
5
|
+
scheme: 'ecdsa' | 'schnorr';
|
|
6
|
+
};
|
|
4
7
|
export type RawSchnorrKeyPair = {
|
|
5
8
|
public: KeyBytes;
|
|
6
9
|
secret?: KeyBytes;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,4BAA4B,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEjD,MAAM,MAAM,iBAAiB,GAAG;IAC9B,MAAM,EAAE,QAAQ,CAAC;IACjB,MAAM,CAAC,EAAE,QAAQ,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,MAAM,EAAE,GAAG,CAAC;IACZ,MAAM,CAAC,EAAE,GAAG,CAAA;CACb,CAAA;AAED,wDAAwD;AACxD,MAAM,WAAW,oBAAoB;IACnC,SAAS,CAAC,EAAE,kBAAkB,GAAG,QAAQ,CAAC;IAC1C,SAAS,CAAC,EAAE,4BAA4B,GAAG,QAAQ,CAAC;CACrD;AAED,MAAM,WAAW,aAAa;IAC5B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,kBAAkB,EAAE,MAAM,CAAA;CAC3B"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,4BAA4B,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEjD,MAAM,MAAM,aAAa,GAAG;IAAE,MAAM,EAAE,OAAO,GAAG,SAAS,CAAA;CAAE,CAAA;AAE3D,MAAM,MAAM,iBAAiB,GAAG;IAC9B,MAAM,EAAE,QAAQ,CAAC;IACjB,MAAM,CAAC,EAAE,QAAQ,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,MAAM,EAAE,GAAG,CAAC;IACZ,MAAM,CAAC,EAAE,GAAG,CAAA;CACb,CAAA;AAED,wDAAwD;AACxD,MAAM,WAAW,oBAAoB;IACnC,SAAS,CAAC,EAAE,kBAAkB,GAAG,QAAQ,CAAC;IAC1C,SAAS,CAAC,EAAE,4BAA4B,GAAG,QAAQ,CAAC;CACrD;AAED,MAAM,WAAW,aAAa;IAC5B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,kBAAkB,EAAE,MAAM,CAAA;CAC3B"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@did-btcr2/keypair",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "JavaScript/TypeScript implementation of secp256k1 public/private key pairs with BIP340 schnorr signatures. Used by various parts of the did-btcr2-js monorepo.",
|
|
6
6
|
"main": "./dist/cjs/index.js",
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
"@noble/hashes": "^1.7.1",
|
|
63
63
|
"multiformats": "^13.3.2",
|
|
64
64
|
"tiny-secp256k1": "^2.2.3",
|
|
65
|
-
"@did-btcr2/common": "2.2.
|
|
65
|
+
"@did-btcr2/common": "2.2.2"
|
|
66
66
|
},
|
|
67
67
|
"devDependencies": {
|
|
68
68
|
"@eslint/js": "^9.20.0",
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
"@types/chai-as-promised": "^8.0.1",
|
|
71
71
|
"@types/eslint": "^9.6.1",
|
|
72
72
|
"@types/mocha": "^10.0.10",
|
|
73
|
-
"@types/node": "^22.
|
|
73
|
+
"@types/node": "^22.18.4",
|
|
74
74
|
"@typescript-eslint/eslint-plugin": "^8.24.1",
|
|
75
75
|
"@typescript-eslint/parser": "^8.24.1",
|
|
76
76
|
"c8": "^10.1.3",
|
package/src/public.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
BIP340_PUBLIC_KEY_MULTIBASE_PREFIX,
|
|
3
3
|
BIP340_PUBLIC_KEY_MULTIBASE_PREFIX_HASH,
|
|
4
|
+
Bytes,
|
|
4
5
|
CURVE,
|
|
5
6
|
Hex,
|
|
6
7
|
KeyBytes,
|
|
@@ -12,7 +13,13 @@ import { sha256 } from '@noble/hashes/sha2';
|
|
|
12
13
|
import { base58btc } from 'multiformats/bases/base58';
|
|
13
14
|
import * as tinysecp from 'tiny-secp256k1';
|
|
14
15
|
import { Secp256k1SecretKey } from './secret.js';
|
|
16
|
+
import { CryptoOptions } from './types.js';
|
|
15
17
|
|
|
18
|
+
/**
|
|
19
|
+
* Point Interface representing an (x, y) coordinate on the secp256k1 curve.
|
|
20
|
+
* @interface Point
|
|
21
|
+
* @type {Point}
|
|
22
|
+
*/
|
|
16
23
|
export interface Point {
|
|
17
24
|
x: KeyBytes;
|
|
18
25
|
y: KeyBytes;
|
|
@@ -119,10 +126,10 @@ export interface PublicKey {
|
|
|
119
126
|
*/
|
|
120
127
|
export class CompressedSecp256k1PublicKey implements PublicKey {
|
|
121
128
|
/** @type {KeyBytes} The public key bytes */
|
|
122
|
-
|
|
129
|
+
readonly #bytes: KeyBytes;
|
|
123
130
|
|
|
124
131
|
/** @type {MultibaseObject} The public key as a MultibaseObject */
|
|
125
|
-
|
|
132
|
+
readonly #multibase: MultibaseObject = {
|
|
126
133
|
prefix : BIP340_PUBLIC_KEY_MULTIBASE_PREFIX,
|
|
127
134
|
key : [],
|
|
128
135
|
encoded : ''
|
|
@@ -130,31 +137,35 @@ export class CompressedSecp256k1PublicKey implements PublicKey {
|
|
|
130
137
|
|
|
131
138
|
/**
|
|
132
139
|
* Creates a CompressedSecp256k1PublicKey instance.
|
|
133
|
-
* @param {
|
|
140
|
+
* @param {Hex} pk The public key byte array.
|
|
134
141
|
* @throws {PublicKeyError} if the byte length is not 32 (x-only) or 33 (compressed)
|
|
135
142
|
*/
|
|
136
|
-
constructor(
|
|
143
|
+
constructor(pk: Hex) {
|
|
144
|
+
pk = pk instanceof Uint8Array
|
|
145
|
+
? pk
|
|
146
|
+
: Buffer.fromHex(pk);
|
|
147
|
+
|
|
137
148
|
// If the byte length is not 33, throw an error
|
|
138
|
-
if(
|
|
149
|
+
if(!pk || pk.length !== 33) {
|
|
139
150
|
throw new PublicKeyError(
|
|
140
151
|
'Invalid argument: byte length must be 33 (compressed)',
|
|
141
|
-
'CONSTRUCTOR_ERROR', {
|
|
152
|
+
'CONSTRUCTOR_ERROR', { pk }
|
|
142
153
|
);
|
|
143
154
|
}
|
|
144
155
|
|
|
145
156
|
// Validate the point is on curve and in compressed form
|
|
146
|
-
if (!tinysecp.isPoint(
|
|
157
|
+
if (!tinysecp.isPoint(pk)) {
|
|
147
158
|
throw new PublicKeyError(
|
|
148
|
-
'Invalid argument:
|
|
149
|
-
'CONSTRUCTOR_ERROR', {
|
|
159
|
+
'Invalid argument: not a valid secp256k1 compressed point',
|
|
160
|
+
'CONSTRUCTOR_ERROR', { pk }
|
|
150
161
|
);
|
|
151
162
|
}
|
|
152
163
|
// Set the bytes
|
|
153
|
-
this
|
|
164
|
+
this.#bytes = pk;
|
|
154
165
|
|
|
155
166
|
// Set multibase
|
|
156
|
-
this.
|
|
157
|
-
this.
|
|
167
|
+
this.#multibase.encoded = this.encode();
|
|
168
|
+
this.#multibase.key = [...this.#multibase.prefix, ...this.compressed];
|
|
158
169
|
}
|
|
159
170
|
|
|
160
171
|
/**
|
|
@@ -162,7 +173,7 @@ export class CompressedSecp256k1PublicKey implements PublicKey {
|
|
|
162
173
|
* @returns {KeyBytes} The 33-byte compressed public key (0x02 or 0x03, x).
|
|
163
174
|
*/
|
|
164
175
|
get compressed(): KeyBytes {
|
|
165
|
-
const bytes = new Uint8Array(this
|
|
176
|
+
const bytes = new Uint8Array(this.#bytes);
|
|
166
177
|
return bytes;
|
|
167
178
|
};
|
|
168
179
|
|
|
@@ -179,7 +190,8 @@ export class CompressedSecp256k1PublicKey implements PublicKey {
|
|
|
179
190
|
* X-only (32-byte) view of the public key per BIP-340.
|
|
180
191
|
*/
|
|
181
192
|
get xOnly(): KeyBytes {
|
|
182
|
-
|
|
193
|
+
const xOnly = this.compressed.slice(1);
|
|
194
|
+
return xOnly;
|
|
183
195
|
}
|
|
184
196
|
|
|
185
197
|
/**
|
|
@@ -188,7 +200,7 @@ export class CompressedSecp256k1PublicKey implements PublicKey {
|
|
|
188
200
|
* @throws {PublicKeyError} If the parity byte is not 0x02 or 0x03.
|
|
189
201
|
*/
|
|
190
202
|
get parity(): 0x02 | 0x03 {
|
|
191
|
-
const parity = this.
|
|
203
|
+
const parity = this.compressed[0];
|
|
192
204
|
if(![0x02, 0x03].includes(parity)) {
|
|
193
205
|
throw new PublicKeyError(
|
|
194
206
|
'Invalid state: parity byte must be 2 or 3',
|
|
@@ -203,7 +215,7 @@ export class CompressedSecp256k1PublicKey implements PublicKey {
|
|
|
203
215
|
* @returns {boolean} True if the public key has even Y.
|
|
204
216
|
*/
|
|
205
217
|
get isEven(): boolean {
|
|
206
|
-
return this.
|
|
218
|
+
return this.parity === 0x02;
|
|
207
219
|
}
|
|
208
220
|
|
|
209
221
|
/**
|
|
@@ -229,15 +241,15 @@ export class CompressedSecp256k1PublicKey implements PublicKey {
|
|
|
229
241
|
* @returns {MultibaseObject} An object containing the multibase bytes, address and prefix.
|
|
230
242
|
*/
|
|
231
243
|
get multibase(): MultibaseObject {
|
|
232
|
-
const multibase = this
|
|
244
|
+
const multibase = this.#multibase;
|
|
233
245
|
return multibase;
|
|
234
246
|
}
|
|
235
247
|
|
|
236
248
|
/**
|
|
237
249
|
* Returns the raw public key as a hex string.
|
|
238
|
-
* @returns {
|
|
250
|
+
* @returns {string} The public key as a hex string.
|
|
239
251
|
*/
|
|
240
|
-
get hex():
|
|
252
|
+
get hex(): string {
|
|
241
253
|
const hex = Buffer.from(this.compressed).toString('hex');
|
|
242
254
|
return hex;
|
|
243
255
|
}
|
|
@@ -267,7 +279,7 @@ export class CompressedSecp256k1PublicKey implements PublicKey {
|
|
|
267
279
|
* @returns {Point} The point of the public key.
|
|
268
280
|
* @throws {PublicKeyError} If the public key is not a valid hex string or byte array.
|
|
269
281
|
*/
|
|
270
|
-
static point(pk: Hex): Point {
|
|
282
|
+
public static point(pk: Hex): Point {
|
|
271
283
|
// If the public key is a hex string, convert it to a CompressedSecp256k1PublicKey object and return the point
|
|
272
284
|
if(typeof pk === 'string' && /^[0-9a-fA-F]+$/.test(pk)) {
|
|
273
285
|
const publicKey = new CompressedSecp256k1PublicKey(Buffer.fromHex(pk));
|
|
@@ -347,6 +359,26 @@ export class CompressedSecp256k1PublicKey implements PublicKey {
|
|
|
347
359
|
return base58btc.encode(publicKeyMultibase.toUint8Array());
|
|
348
360
|
}
|
|
349
361
|
|
|
362
|
+
/**
|
|
363
|
+
* Verify a signature using schnorr or ecdsa.
|
|
364
|
+
* @param {SignatureBytes} signature Signature for verification.
|
|
365
|
+
* @param {string} data Data for verification.
|
|
366
|
+
* @param {CryptoOptions} opts Options for signing.
|
|
367
|
+
* @param {('ecdsa' | 'schnorr')} opts.scheme The signature scheme to use. Default is 'schnorr'.
|
|
368
|
+
* @returns {boolean} If the signature is valid against the public key.
|
|
369
|
+
*/
|
|
370
|
+
public verify(signature: Bytes, data: Bytes, opts?: CryptoOptions): boolean {
|
|
371
|
+
opts ??= { scheme: 'schnorr' };
|
|
372
|
+
// Verify the signature depending on the scheme and return the result
|
|
373
|
+
if(opts.scheme === 'ecdsa') {
|
|
374
|
+
return tinysecp.verify(data, this.compressed, signature); }
|
|
375
|
+
else if(opts.scheme === 'schnorr') {
|
|
376
|
+
return tinysecp.verifySchnorr(data, this.x, signature);
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
throw new PublicKeyError(`Invalid scheme: ${opts.scheme}.`, 'VERIFY_SIGNATURE_ERROR', opts);
|
|
380
|
+
}
|
|
381
|
+
|
|
350
382
|
/**
|
|
351
383
|
* Compares this public key to another public key.
|
|
352
384
|
* @param {CompressedSecp256k1PublicKey} other The other public key to compare
|
package/src/secret.ts
CHANGED
|
@@ -7,14 +7,16 @@ import {
|
|
|
7
7
|
Hex,
|
|
8
8
|
KeyBytes,
|
|
9
9
|
SecretKeyError,
|
|
10
|
-
SecretKeyObject
|
|
10
|
+
SecretKeyObject,
|
|
11
|
+
SignatureBytes
|
|
11
12
|
} from '@did-btcr2/common';
|
|
12
13
|
import { sha256 } from '@noble/hashes/sha2';
|
|
13
|
-
import { getRandomValues } from 'crypto';
|
|
14
|
+
import { getRandomValues, randomBytes } from 'crypto';
|
|
14
15
|
import { base58btc } from 'multiformats/bases/base58';
|
|
15
16
|
import * as tinysecp from 'tiny-secp256k1';
|
|
16
17
|
import { SchnorrKeyPair } from './pair.js';
|
|
17
18
|
import { CompressedSecp256k1PublicKey } from './public.js';
|
|
19
|
+
import { CryptoOptions } from './types.js';
|
|
18
20
|
|
|
19
21
|
/**
|
|
20
22
|
* General SecretKey interface for the Secp256k1SecretKey class.
|
|
@@ -60,7 +62,6 @@ export interface SecretKey {
|
|
|
60
62
|
*/
|
|
61
63
|
isValid(): boolean;
|
|
62
64
|
|
|
63
|
-
|
|
64
65
|
/**
|
|
65
66
|
* JSON representation of a Secp256k1SecretKey object.
|
|
66
67
|
* @returns {SecretKeyObject} The Secp256k1SecretKey as a JSON object.
|
|
@@ -78,13 +79,13 @@ export interface SecretKey {
|
|
|
78
79
|
*/
|
|
79
80
|
export class Secp256k1SecretKey implements SecretKey {
|
|
80
81
|
/** @type {KeyBytes} The entropy for the secret key as a byte array */
|
|
81
|
-
|
|
82
|
+
readonly #bytes?: KeyBytes;
|
|
82
83
|
|
|
83
84
|
/** @type {bigint} The entropy for the secret key as a bigint */
|
|
84
|
-
|
|
85
|
+
readonly #seed?: bigint;
|
|
85
86
|
|
|
86
87
|
/** @type {string} The secret key as a secretKeyMultibase */
|
|
87
|
-
|
|
88
|
+
readonly #multibase: string;
|
|
88
89
|
|
|
89
90
|
/**
|
|
90
91
|
* Instantiates an instance of Secp256k1SecretKey.
|
|
@@ -104,24 +105,24 @@ export class Secp256k1SecretKey implements SecretKey {
|
|
|
104
105
|
|
|
105
106
|
// If bytes and bytes are not length 32
|
|
106
107
|
if (isBytes && entropy.length === 32) {
|
|
107
|
-
this
|
|
108
|
-
this
|
|
108
|
+
this.#bytes = entropy;
|
|
109
|
+
this.#seed = Secp256k1SecretKey.toSecret(entropy);
|
|
109
110
|
}
|
|
110
111
|
|
|
111
112
|
// If secret and secret is not a valid bigint, throw error
|
|
112
113
|
if (isSecret && !(entropy < 1n || entropy >= CURVE.n)) {
|
|
113
|
-
this
|
|
114
|
-
this
|
|
114
|
+
this.#bytes = Secp256k1SecretKey.toBytes(entropy);
|
|
115
|
+
this.#seed = entropy;
|
|
115
116
|
}
|
|
116
117
|
|
|
117
|
-
if(!this
|
|
118
|
+
if(!this.#bytes || this.#bytes.length !== 32) {
|
|
118
119
|
throw new SecretKeyError(
|
|
119
120
|
'Invalid bytes: must be a valid 32-byte secret key',
|
|
120
121
|
'CONSTRUCTOR_ERROR'
|
|
121
122
|
);
|
|
122
123
|
}
|
|
123
124
|
|
|
124
|
-
if(!this
|
|
125
|
+
if(!this.#seed || (this.#seed < 1n || this.#seed >= CURVE.n)) {
|
|
125
126
|
throw new SecretKeyError(
|
|
126
127
|
'Invalid seed: must must be valid bigint',
|
|
127
128
|
'CONSTRUCTOR_ERROR'
|
|
@@ -129,7 +130,7 @@ export class Secp256k1SecretKey implements SecretKey {
|
|
|
129
130
|
}
|
|
130
131
|
|
|
131
132
|
// Set the secret key multibase
|
|
132
|
-
this
|
|
133
|
+
this.#multibase = this.encode();
|
|
133
134
|
}
|
|
134
135
|
|
|
135
136
|
/**
|
|
@@ -138,7 +139,7 @@ export class Secp256k1SecretKey implements SecretKey {
|
|
|
138
139
|
*/
|
|
139
140
|
get bytes(): Uint8Array {
|
|
140
141
|
// Return a copy of the secret key bytes
|
|
141
|
-
const bytes = new Uint8Array(this
|
|
142
|
+
const bytes = new Uint8Array(this.#bytes!);
|
|
142
143
|
return bytes;
|
|
143
144
|
}
|
|
144
145
|
|
|
@@ -148,7 +149,7 @@ export class Secp256k1SecretKey implements SecretKey {
|
|
|
148
149
|
*/
|
|
149
150
|
get seed(): bigint {
|
|
150
151
|
// Memoize the secret and return
|
|
151
|
-
const seed = BigInt(this
|
|
152
|
+
const seed = BigInt(this.#seed!) as bigint;
|
|
152
153
|
return seed;
|
|
153
154
|
}
|
|
154
155
|
|
|
@@ -167,7 +168,7 @@ export class Secp256k1SecretKey implements SecretKey {
|
|
|
167
168
|
* @returns {string} The secret key in base58btc multibase format
|
|
168
169
|
*/
|
|
169
170
|
get multibase(): string {
|
|
170
|
-
const multibase = this
|
|
171
|
+
const multibase = this.#multibase;
|
|
171
172
|
return multibase;
|
|
172
173
|
}
|
|
173
174
|
|
|
@@ -269,6 +270,31 @@ export class Secp256k1SecretKey implements SecretKey {
|
|
|
269
270
|
return true;
|
|
270
271
|
}
|
|
271
272
|
|
|
273
|
+
/**
|
|
274
|
+
* Produce a signature over arbitrary data using schnorr or ecdsa.
|
|
275
|
+
* @param {MessageBytes} data Data to be signed.
|
|
276
|
+
* @param {CryptoOptions} opts Options for signing.
|
|
277
|
+
* @param {('ecdsa' | 'schnorr')} opts.scheme The signature scheme to use. Default is 'schnorr'.
|
|
278
|
+
* @returns {SignatureBytes} Signature byte array.
|
|
279
|
+
* @throws {SecretKeyError} if no private key is provided.
|
|
280
|
+
*/
|
|
281
|
+
public sign(data: Bytes, opts?: CryptoOptions): SignatureBytes {
|
|
282
|
+
// Set default options if not provided
|
|
283
|
+
opts ??= { scheme: 'schnorr' };
|
|
284
|
+
|
|
285
|
+
// Sign ecdsa and return
|
|
286
|
+
if(opts.scheme === 'ecdsa') {
|
|
287
|
+
return tinysecp.sign(data, this.bytes);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// Sign schnorr and return
|
|
291
|
+
if(opts.scheme === 'schnorr') {
|
|
292
|
+
return tinysecp.signSchnorr(data, this.bytes, randomBytes(32));
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
throw new SecretKeyError(`Invalid scheme: ${opts.scheme}.`, 'SIGN_ERROR', opts);
|
|
296
|
+
}
|
|
297
|
+
|
|
272
298
|
/**
|
|
273
299
|
* Decodes the multibase string to the 34-byte secret key (2 byte prefix + 32 byte key).
|
|
274
300
|
* @param {string} multibase The multibase string to decode
|
|
@@ -387,7 +413,6 @@ export class Secp256k1SecretKey implements SecretKey {
|
|
|
387
413
|
return getRandomValues(byteArray);
|
|
388
414
|
}
|
|
389
415
|
|
|
390
|
-
|
|
391
416
|
/**
|
|
392
417
|
* Creates a new Secp256k1SecretKey from random secret key bytes.
|
|
393
418
|
* @returns {Secp256k1SecretKey} A new Secp256k1SecretKey object
|
package/src/types.ts
CHANGED
|
@@ -2,6 +2,8 @@ import { Hex, KeyBytes } from '@did-btcr2/common';
|
|
|
2
2
|
import { CompressedSecp256k1PublicKey } from './public.js';
|
|
3
3
|
import { Secp256k1SecretKey } from './secret.js';
|
|
4
4
|
|
|
5
|
+
export type CryptoOptions = { scheme: 'ecdsa' | 'schnorr' }
|
|
6
|
+
|
|
5
7
|
export type RawSchnorrKeyPair = {
|
|
6
8
|
public: KeyBytes;
|
|
7
9
|
secret?: KeyBytes
|