@did-btcr2/keypair 0.7.0 → 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/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
- private _bytes?: KeyBytes;
82
+ readonly #bytes?: KeyBytes;
82
83
 
83
84
  /** @type {bigint} The entropy for the secret key as a bigint */
84
- private _seed?: bigint;
85
+ readonly #seed?: bigint;
85
86
 
86
87
  /** @type {string} The secret key as a secretKeyMultibase */
87
- private _multibase: string;
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._bytes = entropy;
108
- this._seed = Secp256k1SecretKey.toSecret(entropy);
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._bytes = Secp256k1SecretKey.toBytes(entropy);
114
- this._seed = entropy;
114
+ this.#bytes = Secp256k1SecretKey.toBytes(entropy);
115
+ this.#seed = entropy;
115
116
  }
116
117
 
117
- if(!this._bytes || this._bytes.length !== 32) {
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._seed || (this._seed < 1n || this._seed >= CURVE.n)) {
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._multibase = this.encode();
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._bytes!);
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._seed!) as bigint;
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._multibase;
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
@@ -1,12 +1,19 @@
1
- import { KeyBytes } from '@did-btcr2/common';
1
+ 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
8
10
  }
9
11
 
12
+ export type HexSchnorrKeyPair = {
13
+ public: Hex;
14
+ secret?: Hex
15
+ }
16
+
10
17
  /** Params for the {@link SchnorrKeyPair} constructor */
11
18
  export interface SchnorrKeyPairParams {
12
19
  secretKey?: Secp256k1SecretKey | KeyBytes;