11import { randomBytes , createHash } from 'crypto' ;
22import { Buffer } from 'buffer' ;
33
4- // helpers
5-
6- /**
7- * Computes SHA-256 hash of the input buffer.
8- *
9- * @param {Buffer } buf - The buffer to hash.
10- * @returns {Buffer } The SHA-256 hash of the input.
11- */
12- function sha256 ( buf ) {
13- return createHash ( 'sha256' ) . update ( buf ) . digest ( ) ;
14- }
15-
16- /**
17- * Computes double SHA-256 hash of the input buffer.
18- *
19- * @param {Buffer } buf - The buffer to hash.
20- * @returns {Buffer } The double SHA-256 hash of the input.
21- */
22- function doubleSha256 ( buf ) {
23- return sha256 ( sha256 ( buf ) ) ;
24- }
25-
264/**
275 * A minimal wrapper around the `secp256k1` elliptic curve cryptography using the `elliptic` library.
286 * Provides functionality for creating and managing an elliptic key pair, signing messages,
@@ -47,7 +25,7 @@ function doubleSha256(buf) {
4725 * privateKeyEncoding: 'hex'
4826 * });
4927 * await signer.init();
50- * const sig = signer.signMessageWithRecovery ('hello');
28+ * const sig = signer.signMessage ('hello');
5129 * const pubKey = signer.recoverMessage('hello', sig);
5230 * ```
5331 *
@@ -64,7 +42,27 @@ class TinySecp256k1 {
6442 /** @typedef {import('elliptic') } Elliptic */
6543 /** @typedef {import('elliptic').ec } ec */
6644 /** @typedef {import('elliptic').ec.KeyPair } KeyPair */
67- #msgPrefix = '\x18Tinychain Signed Message:\n' ;
45+ msgPrefix = '\x18Tinychain Signed Message:\n' ;
46+
47+ /**
48+ * Computes SHA-256 hash of the input buffer.
49+ *
50+ * @param {Buffer } buf - The buffer to hash.
51+ * @returns {Buffer } The SHA-256 hash of the input.
52+ */
53+ static sha256 ( buf ) {
54+ return createHash ( 'sha256' ) . update ( buf ) . digest ( ) ;
55+ }
56+
57+ /**
58+ * Computes double SHA-256 hash of the input buffer.
59+ *
60+ * @param {Buffer } buf - The buffer to hash.
61+ * @returns {Buffer } The double SHA-256 hash of the input.
62+ */
63+ static doubleSha256 ( buf ) {
64+ return TinySecp256k1 . sha256 ( TinySecp256k1 . sha256 ( buf ) ) ;
65+ }
6866
6967 /**
7068 * Creates an instance of TinySecp256k1.
@@ -75,7 +73,7 @@ class TinySecp256k1 {
7573 * @param {BufferEncoding } [options.privateKeyEncoding='hex'] - Encoding used for the privateKey string.
7674 */
7775 constructor ( { msgPrefix = null , privateKey = null , privateKeyEncoding = 'hex' } = { } ) {
78- if ( typeof msgPrefix === 'string' ) this . # msgPrefix = msgPrefix ;
76+ if ( typeof msgPrefix === 'string' ) this . msgPrefix = msgPrefix ;
7977 this . privateKey = privateKey ? Buffer . from ( privateKey , privateKeyEncoding ) : randomBytes ( 32 ) ;
8078 }
8179
@@ -190,7 +188,7 @@ class TinySecp256k1 {
190188 */
191189 signECDSA ( message , encoding = 'utf8' ) {
192190 const msgBuffer = Buffer . isBuffer ( message ) ? message : Buffer . from ( message , encoding ) ;
193- const hash = doubleSha256 ( msgBuffer ) ;
191+ const hash = TinySecp256k1 . doubleSha256 ( msgBuffer ) ;
194192 const signature = this . getKeyPair ( ) . sign ( hash , { canonical : true } ) ;
195193 return Buffer . from ( signature . toDER ( ) ) ;
196194 }
@@ -207,7 +205,7 @@ class TinySecp256k1 {
207205 verifyECDSA ( message , signatureBuffer , pubKeyHex , encoding ) {
208206 const ec = this . getEc ( ) ;
209207 const msgBuffer = Buffer . isBuffer ( message ) ? message : Buffer . from ( message , encoding ) ;
210- const hash = doubleSha256 ( msgBuffer ) ;
208+ const hash = TinySecp256k1 . doubleSha256 ( msgBuffer ) ;
211209 const key = ec . keyFromPublic ( pubKeyHex , 'hex' ) ;
212210 return key . verify ( hash , signatureBuffer ) ;
213211 }
@@ -239,7 +237,7 @@ class TinySecp256k1 {
239237 const msgBuffer = Buffer . isBuffer ( message ) ? message : Buffer . from ( message , encoding ) ;
240238 const msgPrefix = Buffer . from ( prefix + msgBuffer . length ) ;
241239 const fullMessage = Buffer . concat ( [ msgPrefix , msgBuffer ] ) ;
242- const hash = doubleSha256 ( fullMessage ) ;
240+ const hash = TinySecp256k1 . doubleSha256 ( fullMessage ) ;
243241 return hash ;
244242 }
245243
@@ -250,13 +248,13 @@ class TinySecp256k1 {
250248 * @param {Buffer } signature - A 65-byte compact signature buffer (r + s + v).
251249 * @param {Object } [options] - Options for decoding the message hash.
252250 * @param {BufferEncoding } [options.encoding='hex'] - The encoding of the input message.
253- * @param {string } [options.prefix=this.# msgPrefix] - Optional prefix used before hashing the message.
251+ * @param {string } [options.prefix=this.msgPrefix] - Optional prefix used before hashing the message.
254252 * @returns {string } The recovered compressed public key in hex format, or null if recovery fails.
255253 * @throws {Error } If the encoding type is unsupported or signature is invalid.
256254 */
257255 recoverMessage ( message , signature , options = { } ) {
258256 const ec = this . getEc ( ) ;
259- const { encoding = 'hex' , prefix = this . # msgPrefix } = options ;
257+ const { encoding = 'hex' , prefix = this . msgPrefix } = options ;
260258 const hash = this . #getMessageHash( message , encoding , prefix ) ;
261259
262260 const { r, s, v } = this . #normalizeSignature( signature ) ;
@@ -270,18 +268,18 @@ class TinySecp256k1 {
270268 * @param {string|Buffer } message - The message to sign.
271269 * @param {Object } [options] - Options for the message hashing process.
272270 * @param {BufferEncoding } [options.encoding='hex'] - The encoding used for string messages.
273- * @param {string } [options.prefix=this.# msgPrefix] - Optional message prefix for the hash.
271+ * @param {string } [options.prefix=this.msgPrefix] - Optional message prefix for the hash.
274272 * @returns {Buffer } A 65-byte recoverable signature (r + s + v).
275273 * @throws {Error } If recovery param is missing or encoding type is unsupported.
276274 */
277275 signMessage ( message , options = { } ) {
278276 const keyPair = this . getKeyPair ( ) ;
279- const { encoding = 'hex' , prefix = this . # msgPrefix } = options ;
277+ const { encoding = 'hex' , prefix = this . msgPrefix } = options ;
280278 const hash = this . #getMessageHash( message , encoding , prefix ) ;
281279
282280 const { r, s, recoveryParam } = keyPair . sign ( hash , { canonical : true } ) ;
283281 if ( typeof recoveryParam !== 'number' )
284- throw new Error ( '[signMessageWithRecovery ] Missing recovery param from signature' ) ;
282+ throw new Error ( '[signMessage ] Missing recovery param from signature' ) ;
285283
286284 const rBuf = r . toArrayLike ( Buffer , 'be' , 32 ) ;
287285 const sBuf = s . toArrayLike ( Buffer , 'be' , 32 ) ;
0 commit comments