Skip to content

Commit 1e388a5

Browse files
TinySecp256k1 --> sha256 and doubleSha256 are static now.
1 parent 8af1adc commit 1e388a5

1 file changed

Lines changed: 31 additions & 33 deletions

File tree

src/TinyChain/Secp256k1.mjs

Lines changed: 31 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,6 @@
11
import { randomBytes, createHash } from 'crypto';
22
import { 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

Comments
 (0)