Socket
Socket
Sign inDemoInstall

@noble/secp256k1

Package Overview
Dependencies
Maintainers
1
Versions
20
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@noble/secp256k1 - npm Package Compare versions

Comparing version 1.4.0 to 1.5.0

243

lib/esm/index.js

@@ -1,2 +0,2 @@

/*! noble-secp256k1 - MIT License (c) Paul Miller (paulmillr.com) */
/*! noble-secp256k1 - MIT License (c) 2019 Paul Miller (paulmillr.com) */
import nodeCrypto from 'crypto';

@@ -22,3 +22,5 @@ const _0n = BigInt(0);

const { a, b } = CURVE;
return mod(x ** _3n + a * x + b);
const x2 = mod(x * x);
const x3 = mod(x2 * x);
return mod(x3 + a * x + b);
}

@@ -148,3 +150,3 @@ const USE_ENDOMORPHISM = CURVE.a === _0n;

const windows = USE_ENDOMORPHISM ? 128 / W + 1 : 256 / W + 1;
let points = [];
const points = [];
let p = this;

@@ -326,9 +328,8 @@ let base = p;

const msg = 'Point is not on elliptic curve';
const { P } = CURVE;
const { x, y } = this;
if (x === _0n || y === _0n || x >= P || y >= P)
if (!isWithinCurvePrime(x) || !isWithinCurvePrime(y))
throw new Error(msg);
const left = mod(y * y);
const right = weistrass(x);
if ((left - right) % P !== _0n)
if (mod(left - right) !== _0n)
throw new Error(msg);

@@ -455,2 +456,4 @@ }

function concatBytes(...arrays) {
if (!arrays.every((a) => a instanceof Uint8Array))
throw new Error('Uint8Array list expected');
if (arrays.length === 1)

@@ -493,10 +496,2 @@ return arrays[0];

}
function parseHexByte(hexByte) {
if (hexByte.length !== 2)
throw new Error('Invalid byte sequence');
const byte = Number.parseInt(hexByte, 16);
if (Number.isNaN(byte))
throw new Error('Invalid byte sequence');
return byte;
}
function hexToBytes(hex) {

@@ -507,7 +502,11 @@ if (typeof hex !== 'string') {

if (hex.length % 2)
throw new Error('hexToBytes: received invalid unpadded hex');
throw new Error('hexToBytes: received invalid unpadded hex' + hex.length);
const array = new Uint8Array(hex.length / 2);
for (let i = 0; i < array.length; i++) {
const j = i * 2;
array[i] = parseHexByte(hex.slice(j, j + 2));
const hexByte = hex.slice(j, j + 2);
const byte = Number.parseInt(hexByte, 16);
if (Number.isNaN(byte))
throw new Error('Invalid byte sequence');
array[i] = byte;
}

@@ -520,2 +519,4 @@ return array;

function bytesToNumber(bytes) {
if (!(bytes instanceof Uint8Array))
throw new Error('Expected Uint8Array');
return hexToNumber(bytesToHex(bytes));

@@ -641,76 +642,73 @@ }

}
function _abc6979(msgHash, privateKey, extraEntropy) {
if (msgHash == null)
throw new Error(`sign: expected valid msgHash, not "${msgHash}"`);
const num = typeof msgHash === 'string' ? hexToNumber(msgHash) : bytesToNumber(msgHash);
const h1 = pad32b(num);
const h1n = bytesToNumber(h1);
const x = pad32b(privateKey);
let v = new Uint8Array(32).fill(1);
let k = new Uint8Array(32).fill(0);
const b0 = Uint8Array.from([0x00]);
const b1 = Uint8Array.from([0x01]);
let xh1 = concatBytes(x, h1);
if (extraEntropy != null) {
const e = pad32b(typeof extraEntropy === 'string' ? hexToNumber(extraEntropy) : bytesToNumber(extraEntropy));
if (e.length !== 32)
throw new Error('secp256k1: Expected 32 bytes of extra data');
xh1 = concatBytes(xh1, e);
class HmacDrbg {
constructor() {
this.v = new Uint8Array(32).fill(1);
this.k = new Uint8Array(32).fill(0);
this.counter = 0;
}
return { xh1, h1n, v, k, b0, b1 };
}
async function getQRSrfc6979(msgHash, privateKey, extraEntropy) {
const privKey = normalizePrivateKey(privateKey);
let { xh1, h1n, v, k, b0, b1 } = _abc6979(msgHash, privKey, extraEntropy);
const hmac = utils.hmacSha256;
k = await hmac(k, v, b0, xh1);
v = await hmac(k, v);
k = await hmac(k, v, b1, xh1);
v = await hmac(k, v);
for (let i = 0; i < 1000; i++) {
v = await hmac(k, v);
const qrs = calcQRSFromK(v, h1n, privKey);
if (qrs)
return qrs;
k = await hmac(k, v, b0);
v = await hmac(k, v);
hmac(...values) {
return utils.hmacSha256(this.k, ...values);
}
throw new TypeError('secp256k1: Tried 1,000 k values for sign(), all were invalid');
}
function getQRSrfc6979Sync(msgHash, privateKey, extraEntropy) {
const privKey = normalizePrivateKey(privateKey);
let { xh1, h1n, v, k, b0, b1 } = _abc6979(msgHash, privKey, extraEntropy);
const hmac = utils.hmacSha256Sync;
if (!hmac)
throw new Error('utils.hmacSha256Sync is undefined, you need to set it');
k = hmac(k, v, b0, xh1);
if (k instanceof Promise)
throw new Error('To use sync sign(), ensure utils.hmacSha256 is sync');
v = hmac(k, v);
k = hmac(k, v, b1, xh1);
v = hmac(k, v);
for (let i = 0; i < 1000; i++) {
v = hmac(k, v);
const qrs = calcQRSFromK(v, h1n, privKey);
if (qrs)
return qrs;
k = hmac(k, v, b0);
v = hmac(k, v);
hmacSync(...values) {
if (typeof utils.hmacSha256Sync !== 'function')
throw new Error('utils.hmacSha256Sync is undefined, you need to set it');
const res = utils.hmacSha256Sync(this.k, ...values);
if (res instanceof Promise)
throw new Error('To use sync sign(), ensure utils.hmacSha256 is sync');
return res;
}
throw new TypeError('secp256k1: Tried 1,000 k values for sign(), all were invalid');
incr() {
if (this.counter >= 1000) {
throw new Error('Tried 1,000 k values for sign(), all were invalid');
}
this.counter += 1;
}
async reseed(seed = new Uint8Array()) {
this.k = await this.hmac(this.v, Uint8Array.from([0x00]), seed);
this.v = await this.hmac(this.v);
if (seed.length === 0)
return;
this.k = await this.hmac(this.v, Uint8Array.from([0x01]), seed);
this.v = await this.hmac(this.v);
}
reseedSync(seed = new Uint8Array()) {
this.k = this.hmacSync(this.v, Uint8Array.from([0x00]), seed);
this.v = this.hmacSync(this.v);
if (seed.length === 0)
return;
this.k = this.hmacSync(this.v, Uint8Array.from([0x01]), seed);
this.v = this.hmacSync(this.v);
}
async generate() {
this.incr();
this.v = await this.hmac(this.v);
return this.v;
}
generateSync() {
this.incr();
this.v = this.hmacSync(this.v);
return this.v;
}
}
function isWithinCurveOrder(num) {
return 0 < num && num < CURVE.n;
return _0n < num && num < CURVE.n;
}
function calcQRSFromK(v, msg, priv) {
const k = bytesToNumber(v);
function isWithinCurvePrime(num) {
return 0n < num && num < CURVE.P;
}
function kmdToSig(kBytes, m, d) {
const k = bytesToNumber(kBytes);
if (!isWithinCurveOrder(k))
return;
const max = CURVE.n;
const { n } = CURVE;
const q = Point.BASE.multiply(k);
const r = mod(q.x, max);
const s = mod(invert(k, max) * (msg + r * priv), max);
if (r === _0n || s === _0n)
const r = mod(q.x, n);
if (r === _0n)
return;
return { q, r, s };
const s = mod(invert(k, n) * mod(m + d * r, n), n);
if (s === _0n)
return;
const sig = new Signature(r, s);
const recovery = (q.x === sig.r ? 0 : 2) | Number(q.y & _1n);
return { sig, recovery };
}

@@ -790,8 +788,38 @@ function normalizePrivateKey(key) {

}
function QRSToSig(qrs, opts) {
const { q, r, s } = qrs;
const defaultOpts = { canonical: true, der: true };
let { canonical, der, recovered } = Object.assign(defaultOpts, opts);
let recovery = (q.x === r ? 0 : 2) | Number(q.y & _1n);
let sig = new Signature(r, s);
function bits2int(bytes) {
const slice = bytes.length > 32 ? bytes.slice(0, 32) : bytes;
return bytesToNumber(slice);
}
function bits2octets(bytes) {
const z1 = bits2int(bytes);
const z2 = mod(z1, CURVE.n);
return int2octets(z2 < _0n ? z1 : z2);
}
function int2octets(num) {
if (typeof num !== 'bigint')
throw new Error('Expected bigint');
const hex = pad64(num);
return hexToBytes(hex);
}
function initSigArgs(msgHash, privateKey, extraEntropy) {
if (msgHash == null)
throw new Error(`sign: expected valid msgHash, not "${msgHash}"`);
const h1 = ensureBytes(msgHash);
const d = normalizePrivateKey(privateKey);
const seedArgs = [int2octets(d), bits2octets(h1)];
if (extraEntropy != null) {
if (extraEntropy === true)
extraEntropy = utils.randomBytes(32);
const e = pad32b(bytesToNumber(ensureBytes(extraEntropy)));
if (e.length !== 32)
throw new Error('secp256k1: Expected 32 bytes of extra data');
seedArgs.push(e);
}
const seed = concatBytes(...seedArgs);
const m = bits2int(h1);
return { seed, m, d };
}
function finalizeSig(recSig, opts) {
let { sig, recovery } = recSig;
const { canonical, der, recovered } = Object.assign({ canonical: true, der: true }, opts);
if (canonical && sig.hasHighS()) {

@@ -805,6 +833,18 @@ sig = sig.normalizeS();

async function sign(msgHash, privKey, opts = {}) {
return QRSToSig(await getQRSrfc6979(msgHash, privKey, opts.extraEntropy), opts);
const { seed, m, d } = initSigArgs(msgHash, privKey, opts.extraEntropy);
let sig;
const drbg = new HmacDrbg();
await drbg.reseed(seed);
while (!(sig = kmdToSig(await drbg.generate(), m, d)))
await drbg.reseed();
return finalizeSig(sig, opts);
}
function signSync(msgHash, privKey, opts = {}) {
return QRSToSig(getQRSrfc6979Sync(msgHash, privKey, opts.extraEntropy), opts);
const { seed, m, d } = initSigArgs(msgHash, privKey, opts.extraEntropy);
let sig;
const drbg = new HmacDrbg();
drbg.reseedSync(seed);
while (!(sig = kmdToSig(drbg.generateSync(), m, d)))
drbg.reseedSync();
return finalizeSig(sig, opts);
}

@@ -862,3 +902,3 @@ export { sign, signSync };

this.s = s;
if (r <= _0n || s <= _0n || r >= CURVE.P || s >= CURVE.n)
if (!isWithinCurvePrime(r) || !isWithinCurveOrder(s))
throw new Error('Invalid signature');

@@ -868,7 +908,6 @@ }

const bytes = ensureBytes(hex);
if (bytes.length !== 64) {
if (bytes.length !== 64)
throw new TypeError(`SchnorrSignature.fromHex: expected 64 bytes, not ${bytes.length}`);
}
const r = bytesToNumber(bytes.slice(0, 32));
const s = bytesToNumber(bytes.slice(32));
const s = bytesToNumber(bytes.slice(32, 64));
return new SchnorrSignature(r, s);

@@ -886,9 +925,7 @@ }

}
async function schnorrSign(msgHash, privateKey, auxRand = utils.randomBytes()) {
if (msgHash == null)
throw new TypeError(`sign: Expected valid message, not "${msgHash}"`);
if (!privateKey)
privateKey = _0n;
async function schnorrSign(message, privateKey, auxRand = utils.randomBytes()) {
if (message == null)
throw new TypeError(`sign: Expected valid message, not "${message}"`);
const { n } = CURVE;
const m = ensureBytes(msgHash);
const m = ensureBytes(message);
const d0 = normalizePrivateKey(privateKey);

@@ -915,5 +952,5 @@ const rand = ensureBytes(auxRand);

}
async function schnorrVerify(signature, msgHash, publicKey) {
async function schnorrVerify(signature, message, publicKey) {
const sig = signature instanceof SchnorrSignature ? signature : SchnorrSignature.fromHex(signature);
const m = typeof msgHash === 'string' ? hexToBytes(msgHash) : msgHash;
const m = ensureBytes(message);
const P = normalizePublicKey(publicKey);

@@ -955,3 +992,3 @@ const e = await createChallenge(sig.r, P, m);

const { randomBytes } = crypto.node;
return new Uint8Array(randomBytes(bytesLength).buffer);
return Uint8Array.from(randomBytes(bytesLength));
}

@@ -996,5 +1033,3 @@ else {

const hash = createHmac('sha256', key);
for (const message of messages) {
hash.update(message);
}
messages.forEach((m) => hash.update(m));
return Uint8Array.from(hash.digest());

@@ -1001,0 +1036,0 @@ }

@@ -1,2 +0,2 @@

/*! noble-secp256k1 - MIT License (c) Paul Miller (paulmillr.com) */
/*! noble-secp256k1 - MIT License (c) 2019 Paul Miller (paulmillr.com) */
declare const CURVE: {

@@ -64,2 +64,3 @@ a: bigint;

export declare function getSharedSecret(privateA: PrivKey, publicB: PubKey, isCompressed?: boolean): Uint8Array;
declare type Ent = Hex | true;
declare type OptsRecov = {

@@ -69,3 +70,3 @@ recovered: true;

der?: boolean;
extraEntropy?: Hex;
extraEntropy?: Ent;
};

@@ -76,3 +77,3 @@ declare type OptsNoRecov = {

der?: boolean;
extraEntropy?: Hex;
extraEntropy?: Ent;
};

@@ -97,4 +98,4 @@ declare function sign(msgHash: Hex, privKey: PrivKey, opts: OptsRecov): Promise<[U8A, number]>;

declare function schnorrGetPublicKey(privateKey: PrivKey): Uint8Array;
declare function schnorrSign(msgHash: Hex, privateKey: PrivKey, auxRand?: Hex): Promise<Uint8Array>;
declare function schnorrVerify(signature: Hex, msgHash: Hex, publicKey: Hex): Promise<boolean>;
declare function schnorrSign(message: Hex, privateKey: PrivKey, auxRand?: Hex): Promise<Uint8Array>;
declare function schnorrVerify(signature: Hex, message: Hex, publicKey: Hex): Promise<boolean>;
export declare const schnorr: {

@@ -101,0 +102,0 @@ Signature: typeof SchnorrSignature;

"use strict";
/*! noble-secp256k1 - MIT License (c) Paul Miller (paulmillr.com) */
/*! noble-secp256k1 - MIT License (c) 2019 Paul Miller (paulmillr.com) */
var __importDefault = (this && this.__importDefault) || function (mod) {

@@ -28,3 +28,5 @@ return (mod && mod.__esModule) ? mod : { "default": mod };

const { a, b } = CURVE;
return mod(x ** _3n + a * x + b);
const x2 = mod(x * x);
const x3 = mod(x2 * x);
return mod(x3 + a * x + b);
}

@@ -154,3 +156,3 @@ const USE_ENDOMORPHISM = CURVE.a === _0n;

const windows = USE_ENDOMORPHISM ? 128 / W + 1 : 256 / W + 1;
let points = [];
const points = [];
let p = this;

@@ -332,9 +334,8 @@ let base = p;

const msg = 'Point is not on elliptic curve';
const { P } = CURVE;
const { x, y } = this;
if (x === _0n || y === _0n || x >= P || y >= P)
if (!isWithinCurvePrime(x) || !isWithinCurvePrime(y))
throw new Error(msg);
const left = mod(y * y);
const right = weistrass(x);
if ((left - right) % P !== _0n)
if (mod(left - right) !== _0n)
throw new Error(msg);

@@ -463,2 +464,4 @@ }

function concatBytes(...arrays) {
if (!arrays.every((a) => a instanceof Uint8Array))
throw new Error('Uint8Array list expected');
if (arrays.length === 1)

@@ -501,10 +504,2 @@ return arrays[0];

}
function parseHexByte(hexByte) {
if (hexByte.length !== 2)
throw new Error('Invalid byte sequence');
const byte = Number.parseInt(hexByte, 16);
if (Number.isNaN(byte))
throw new Error('Invalid byte sequence');
return byte;
}
function hexToBytes(hex) {

@@ -515,7 +510,11 @@ if (typeof hex !== 'string') {

if (hex.length % 2)
throw new Error('hexToBytes: received invalid unpadded hex');
throw new Error('hexToBytes: received invalid unpadded hex' + hex.length);
const array = new Uint8Array(hex.length / 2);
for (let i = 0; i < array.length; i++) {
const j = i * 2;
array[i] = parseHexByte(hex.slice(j, j + 2));
const hexByte = hex.slice(j, j + 2);
const byte = Number.parseInt(hexByte, 16);
if (Number.isNaN(byte))
throw new Error('Invalid byte sequence');
array[i] = byte;
}

@@ -528,2 +527,4 @@ return array;

function bytesToNumber(bytes) {
if (!(bytes instanceof Uint8Array))
throw new Error('Expected Uint8Array');
return hexToNumber(bytesToHex(bytes));

@@ -649,76 +650,73 @@ }

}
function _abc6979(msgHash, privateKey, extraEntropy) {
if (msgHash == null)
throw new Error(`sign: expected valid msgHash, not "${msgHash}"`);
const num = typeof msgHash === 'string' ? hexToNumber(msgHash) : bytesToNumber(msgHash);
const h1 = pad32b(num);
const h1n = bytesToNumber(h1);
const x = pad32b(privateKey);
let v = new Uint8Array(32).fill(1);
let k = new Uint8Array(32).fill(0);
const b0 = Uint8Array.from([0x00]);
const b1 = Uint8Array.from([0x01]);
let xh1 = concatBytes(x, h1);
if (extraEntropy != null) {
const e = pad32b(typeof extraEntropy === 'string' ? hexToNumber(extraEntropy) : bytesToNumber(extraEntropy));
if (e.length !== 32)
throw new Error('secp256k1: Expected 32 bytes of extra data');
xh1 = concatBytes(xh1, e);
class HmacDrbg {
constructor() {
this.v = new Uint8Array(32).fill(1);
this.k = new Uint8Array(32).fill(0);
this.counter = 0;
}
return { xh1, h1n, v, k, b0, b1 };
}
async function getQRSrfc6979(msgHash, privateKey, extraEntropy) {
const privKey = normalizePrivateKey(privateKey);
let { xh1, h1n, v, k, b0, b1 } = _abc6979(msgHash, privKey, extraEntropy);
const hmac = exports.utils.hmacSha256;
k = await hmac(k, v, b0, xh1);
v = await hmac(k, v);
k = await hmac(k, v, b1, xh1);
v = await hmac(k, v);
for (let i = 0; i < 1000; i++) {
v = await hmac(k, v);
const qrs = calcQRSFromK(v, h1n, privKey);
if (qrs)
return qrs;
k = await hmac(k, v, b0);
v = await hmac(k, v);
hmac(...values) {
return exports.utils.hmacSha256(this.k, ...values);
}
throw new TypeError('secp256k1: Tried 1,000 k values for sign(), all were invalid');
}
function getQRSrfc6979Sync(msgHash, privateKey, extraEntropy) {
const privKey = normalizePrivateKey(privateKey);
let { xh1, h1n, v, k, b0, b1 } = _abc6979(msgHash, privKey, extraEntropy);
const hmac = exports.utils.hmacSha256Sync;
if (!hmac)
throw new Error('utils.hmacSha256Sync is undefined, you need to set it');
k = hmac(k, v, b0, xh1);
if (k instanceof Promise)
throw new Error('To use sync sign(), ensure utils.hmacSha256 is sync');
v = hmac(k, v);
k = hmac(k, v, b1, xh1);
v = hmac(k, v);
for (let i = 0; i < 1000; i++) {
v = hmac(k, v);
const qrs = calcQRSFromK(v, h1n, privKey);
if (qrs)
return qrs;
k = hmac(k, v, b0);
v = hmac(k, v);
hmacSync(...values) {
if (typeof exports.utils.hmacSha256Sync !== 'function')
throw new Error('utils.hmacSha256Sync is undefined, you need to set it');
const res = exports.utils.hmacSha256Sync(this.k, ...values);
if (res instanceof Promise)
throw new Error('To use sync sign(), ensure utils.hmacSha256 is sync');
return res;
}
throw new TypeError('secp256k1: Tried 1,000 k values for sign(), all were invalid');
incr() {
if (this.counter >= 1000) {
throw new Error('Tried 1,000 k values for sign(), all were invalid');
}
this.counter += 1;
}
async reseed(seed = new Uint8Array()) {
this.k = await this.hmac(this.v, Uint8Array.from([0x00]), seed);
this.v = await this.hmac(this.v);
if (seed.length === 0)
return;
this.k = await this.hmac(this.v, Uint8Array.from([0x01]), seed);
this.v = await this.hmac(this.v);
}
reseedSync(seed = new Uint8Array()) {
this.k = this.hmacSync(this.v, Uint8Array.from([0x00]), seed);
this.v = this.hmacSync(this.v);
if (seed.length === 0)
return;
this.k = this.hmacSync(this.v, Uint8Array.from([0x01]), seed);
this.v = this.hmacSync(this.v);
}
async generate() {
this.incr();
this.v = await this.hmac(this.v);
return this.v;
}
generateSync() {
this.incr();
this.v = this.hmacSync(this.v);
return this.v;
}
}
function isWithinCurveOrder(num) {
return 0 < num && num < CURVE.n;
return _0n < num && num < CURVE.n;
}
function calcQRSFromK(v, msg, priv) {
const k = bytesToNumber(v);
function isWithinCurvePrime(num) {
return 0n < num && num < CURVE.P;
}
function kmdToSig(kBytes, m, d) {
const k = bytesToNumber(kBytes);
if (!isWithinCurveOrder(k))
return;
const max = CURVE.n;
const { n } = CURVE;
const q = Point.BASE.multiply(k);
const r = mod(q.x, max);
const s = mod(invert(k, max) * (msg + r * priv), max);
if (r === _0n || s === _0n)
const r = mod(q.x, n);
if (r === _0n)
return;
return { q, r, s };
const s = mod(invert(k, n) * mod(m + d * r, n), n);
if (s === _0n)
return;
const sig = new Signature(r, s);
const recovery = (q.x === sig.r ? 0 : 2) | Number(q.y & _1n);
return { sig, recovery };
}

@@ -801,8 +799,38 @@ function normalizePrivateKey(key) {

exports.getSharedSecret = getSharedSecret;
function QRSToSig(qrs, opts) {
const { q, r, s } = qrs;
const defaultOpts = { canonical: true, der: true };
let { canonical, der, recovered } = Object.assign(defaultOpts, opts);
let recovery = (q.x === r ? 0 : 2) | Number(q.y & _1n);
let sig = new Signature(r, s);
function bits2int(bytes) {
const slice = bytes.length > 32 ? bytes.slice(0, 32) : bytes;
return bytesToNumber(slice);
}
function bits2octets(bytes) {
const z1 = bits2int(bytes);
const z2 = mod(z1, CURVE.n);
return int2octets(z2 < _0n ? z1 : z2);
}
function int2octets(num) {
if (typeof num !== 'bigint')
throw new Error('Expected bigint');
const hex = pad64(num);
return hexToBytes(hex);
}
function initSigArgs(msgHash, privateKey, extraEntropy) {
if (msgHash == null)
throw new Error(`sign: expected valid msgHash, not "${msgHash}"`);
const h1 = ensureBytes(msgHash);
const d = normalizePrivateKey(privateKey);
const seedArgs = [int2octets(d), bits2octets(h1)];
if (extraEntropy != null) {
if (extraEntropy === true)
extraEntropy = exports.utils.randomBytes(32);
const e = pad32b(bytesToNumber(ensureBytes(extraEntropy)));
if (e.length !== 32)
throw new Error('secp256k1: Expected 32 bytes of extra data');
seedArgs.push(e);
}
const seed = concatBytes(...seedArgs);
const m = bits2int(h1);
return { seed, m, d };
}
function finalizeSig(recSig, opts) {
let { sig, recovery } = recSig;
const { canonical, der, recovered } = Object.assign({ canonical: true, der: true }, opts);
if (canonical && sig.hasHighS()) {

@@ -816,7 +844,19 @@ sig = sig.normalizeS();

async function sign(msgHash, privKey, opts = {}) {
return QRSToSig(await getQRSrfc6979(msgHash, privKey, opts.extraEntropy), opts);
const { seed, m, d } = initSigArgs(msgHash, privKey, opts.extraEntropy);
let sig;
const drbg = new HmacDrbg();
await drbg.reseed(seed);
while (!(sig = kmdToSig(await drbg.generate(), m, d)))
await drbg.reseed();
return finalizeSig(sig, opts);
}
exports.sign = sign;
function signSync(msgHash, privKey, opts = {}) {
return QRSToSig(getQRSrfc6979Sync(msgHash, privKey, opts.extraEntropy), opts);
const { seed, m, d } = initSigArgs(msgHash, privKey, opts.extraEntropy);
let sig;
const drbg = new HmacDrbg();
drbg.reseedSync(seed);
while (!(sig = kmdToSig(drbg.generateSync(), m, d)))
drbg.reseedSync();
return finalizeSig(sig, opts);
}

@@ -875,3 +915,3 @@ exports.signSync = signSync;

this.s = s;
if (r <= _0n || s <= _0n || r >= CURVE.P || s >= CURVE.n)
if (!isWithinCurvePrime(r) || !isWithinCurveOrder(s))
throw new Error('Invalid signature');

@@ -881,7 +921,6 @@ }

const bytes = ensureBytes(hex);
if (bytes.length !== 64) {
if (bytes.length !== 64)
throw new TypeError(`SchnorrSignature.fromHex: expected 64 bytes, not ${bytes.length}`);
}
const r = bytesToNumber(bytes.slice(0, 32));
const s = bytesToNumber(bytes.slice(32));
const s = bytesToNumber(bytes.slice(32, 64));
return new SchnorrSignature(r, s);

@@ -899,9 +938,7 @@ }

}
async function schnorrSign(msgHash, privateKey, auxRand = exports.utils.randomBytes()) {
if (msgHash == null)
throw new TypeError(`sign: Expected valid message, not "${msgHash}"`);
if (!privateKey)
privateKey = _0n;
async function schnorrSign(message, privateKey, auxRand = exports.utils.randomBytes()) {
if (message == null)
throw new TypeError(`sign: Expected valid message, not "${message}"`);
const { n } = CURVE;
const m = ensureBytes(msgHash);
const m = ensureBytes(message);
const d0 = normalizePrivateKey(privateKey);

@@ -928,5 +965,5 @@ const rand = ensureBytes(auxRand);

}
async function schnorrVerify(signature, msgHash, publicKey) {
async function schnorrVerify(signature, message, publicKey) {
const sig = signature instanceof SchnorrSignature ? signature : SchnorrSignature.fromHex(signature);
const m = typeof msgHash === 'string' ? hexToBytes(msgHash) : msgHash;
const m = ensureBytes(message);
const P = normalizePublicKey(publicKey);

@@ -968,3 +1005,3 @@ const e = await createChallenge(sig.r, P, m);

const { randomBytes } = crypto.node;
return new Uint8Array(randomBytes(bytesLength).buffer);
return Uint8Array.from(randomBytes(bytesLength));
}

@@ -1009,5 +1046,3 @@ else {

const hash = createHmac('sha256', key);
for (const message of messages) {
hash.update(message);
}
messages.forEach((m) => hash.update(m));
return Uint8Array.from(hash.digest());

@@ -1014,0 +1049,0 @@ }

{
"name": "@noble/secp256k1",
"version": "1.4.0",
"version": "1.5.0",
"description": "Fastest JS implementation of secp256k1. Independently audited, high-security, 0-dependency ECDSA & Schnorr signatures",

@@ -13,3 +13,3 @@ "files": [

"build": "tsc -d && tsc -p tsconfig.esm.json",
"build-release": "rollup -c rollup.config.js",
"build:release": "rollup -c rollup.config.js",
"lint": "prettier --print-width 100 --single-quote --check index.ts",

@@ -31,3 +31,3 @@ "test": "jest",

"devDependencies": {
"@noble/hashes": "^0.5.6",
"@noble/hashes": "~1.0.0",
"@rollup/plugin-commonjs": "^21.0.0",

@@ -34,0 +34,0 @@ "@rollup/plugin-node-resolve": "^13.0.0",

@@ -37,5 +37,6 @@ # noble-secp256k1 ![Node CI](https://github.com/paulmillr/noble-secp256k1/workflows/Node%20CI/badge.svg) [![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier)

(async () => {
// You pass either a hex string, or Uint8Array
// You pass a hex string, or Uint8Array
const privateKey = "6b911fd37cdf5c81d4c0adb1ab7fa822ed253ab0ad9aa18d77257c88b29b718e";
const messageHash = "a33321f98e4ff1c283c76998f14f57447545d339b3db534c6d886decb4209f28";
const message = "hello world";
const messageHash = await secp.utils.sha256(message);
const publicKey = secp.getPublicKey(privateKey);

@@ -45,9 +46,13 @@ const signature = await secp.sign(messageHash, privateKey);

// Signatures compatible with openssl
const signatureS = await secp.sign(messageHash, privateKey, { canonical: false });
// Sigs with improved security (see README)
const signatureE = await secp.sign(messageHash, privateKey, { extraEntropy: true });
// Malleable signatures, compatible with openssl
const signatureM = await secp.sign(messageHash, privateKey, { canonical: false });
// Supports Schnorr signatures
const rpub = secp.schnorr.getPublicKey(privateKey);
const rsignature = await secp.schnorr.sign(messageHash, privateKey);
const risSigned = await secp.schnorr.verify(rsignature, messageHash, rpub);
const rsignature = await secp.schnorr.sign(message, privateKey);
const risSigned = await secp.schnorr.verify(rsignature, message, rpub);
})();

@@ -122,2 +127,12 @@ ```

It's strongly recommended to pass `{extraEntropy: true}` to improve security of signatures:
- In case the entropy generator is broken, signatures would be just like they are without the option
- It would help a lot in case there is an error somewhere in `k` generation. Exposing `k` could leak private keys
- Schnorr signatures are adding extra entropy every time
- The only disadvantage to this is the fact signatures won't be exactly equal to fully-deterministic sigs;
think backwards-compatibility with test vectors. They would still be valid, though
`sign` arguments:
- `msgHash: Uint8Array | string` - message hash which would be signed

@@ -130,3 +145,3 @@ - `privateKey: Uint8Array | string | bigint` - private key which will sign the hash

`false` makes signatures compatible with openssl
- `options?.extraEntropy: Uint8Array | string` - additional entropy `k'` for deterministic signature, follows section 3.6 of RFC6979. [Could be reused](https://crypto.stackexchange.com/questions/97911/reusing-additional-data-k-nonce-from-rfc6979-ecdsa).
- `options?.extraEntropy: Uint8Array | string | true` - additional entropy `k'` for deterministic signature, follows section 3.6 of RFC6979. When `true`, it would automatically be filled with 32 bytes of cryptographically secure entropy
- `options?.der: boolean = true` - whether the returned signature should be in DER format. If `false`, it would be in Compact format (32-byte r + 32-byte s)

@@ -196,3 +211,3 @@

- `privateKey: Uint8Array | string | bigint` - private key which will sign the hash
- `auxilaryRandom?: Uint8Array` — optional 32 random bytes. By default, the method gathers cryptogarphically secure random.
- `auxilaryRandom?: Uint8Array` — optional 32 random bytes. By default, the method gathers cryptogarphically secure entropy
- Returns Schnorr signature in Hex format.

@@ -213,2 +228,8 @@

###### `utils.randomBytes(): Uint8Array`
Returns `Uint8Array` of 32 cryptographically secure random bytes.
Uses `crypto.web.getRandomValues` in browser, `require('crypto').randomBytes` in node.js.
###### `utils.randomPrivateKey(): Uint8Array`

@@ -300,3 +321,3 @@

We however consider infrastructure attacks like rogue NPM modules very important; that's why it's crucial to minimize the amount of 3rd-party dependencies & native bindings. If your app uses 500 dependencies, any dep could get hacked and you'll be downloading rootkits with every `npm install`. Our goal is to minimize this attack vector.
We however consider infrastructure attacks like rogue NPM modules very important; that's why it's crucial to minimize the amount of 3rd-party dependencies & native bindings. If your app uses 500 dependencies, any dep could get hacked and you'll be downloading malware with every `npm install`. Our goal is to minimize this attack vector.

@@ -307,3 +328,3 @@ ## Speed

getPublicKey(utils.randomPrivateKey()) x 6,121 ops/sec @ 163μs/op
getPublicKey(utils.randomPrivateKey()) x 6,216 ops/sec @ 160μs/op
sign x 4,789 ops/sec @ 208μs/op

@@ -310,0 +331,0 @@ verify x 923 ops/sec @ 1ms/op

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc