Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

noble-secp256k1

Package Overview
Dependencies
Maintainers
1
Versions
47
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.1.0 to 1.1.1

29

index.d.ts

@@ -15,3 +15,3 @@ declare const CURVE: {

declare type PubKey = Hex | Point;
declare type Signature = Hex | SignResult;
declare type Sig = Hex | Signature;
export declare class Point {

@@ -25,2 +25,3 @@ x: bigint;

_setWindowSize(windowSize: number): void;
private static fromX;
private static fromCompressedHex;

@@ -30,5 +31,7 @@ private static fromUncompressedHex;

static fromPrivateKey(privateKey: PrivKey): Point;
static fromSignature(msgHash: Hex, signature: Signature, recovery: number): Point | undefined;
static fromSignature(msgHash: Hex, signature: Sig, recovery: number): Point | undefined;
toRawBytes(isCompressed?: boolean): Uint8Array;
toHex(isCompressed?: boolean): string;
toHexX(): string;
toRawX(): Uint8Array;
assertValidity(): void;

@@ -42,10 +45,11 @@ equals(other: Point): boolean;

}
export declare class SignResult {
export declare class Signature {
r: bigint;
s: bigint;
constructor(r: bigint, s: bigint);
static fromHex(hex: Hex): SignResult;
static fromHex(hex: Hex): Signature;
toRawBytes(isCompressed?: boolean): Uint8Array;
toHex(isCompressed?: boolean): string;
}
export declare const SignResult: typeof Signature;
export declare function getPublicKey(privateKey: Uint8Array | bigint | number, isCompressed?: boolean): Uint8Array;

@@ -69,14 +73,21 @@ export declare function getPublicKey(privateKey: string, isCompressed?: boolean): string;

export declare function sign(msgHash: string, privateKey: PrivKey, opts?: OptsNoRecovered): Promise<string>;
export declare function verify(signature: Signature, msgHash: Hex, publicKey: PubKey): boolean;
declare class SchnorrSignResult {
export declare function verify(signature: Sig, msgHash: Hex, publicKey: PubKey): boolean;
declare class SchnorrSignature {
readonly r: bigint;
readonly s: bigint;
constructor(r: bigint, s: bigint);
static fromHex(hex: Hex): SchnorrSignature;
toHex(): string;
toRawBytes(): Uint8Array;
}
declare function schnorrGetPublicKey(privateKey: Uint8Array): Uint8Array;
declare function schnorrGetPublicKey(privateKey: string): string;
declare function schnorrSign(msgHash: string, privateKey: string, auxRand?: Hex): Promise<string>;
declare function schnorrSign(msgHash: Uint8Array, privateKey: Uint8Array, auxRand?: Hex): Promise<Uint8Array>;
declare function schnorrVerify(signature: Hex, msgHash: Hex, publicKey: Hex): Promise<boolean>;
export declare const schnorr: {
SignResult: typeof SchnorrSignResult;
sign(message: Hex, privateKey: PrivKey, auxRand?: Hex): Promise<SchnorrSignResult>;
verify(signature: SchnorrSignResult, message: Hex, publicKey: PubKey): Promise<boolean>;
Signature: typeof SchnorrSignature;
getPublicKey: typeof schnorrGetPublicKey;
sign: typeof schnorrSign;
verify: typeof schnorrVerify;
};

@@ -83,0 +94,0 @@ export declare const utils: {

@@ -246,5 +246,16 @@ 'use strict';

}
static fromX(bytes) {
const x = bytesToNumber(bytes);
const sqrY = weistrass(x);
let y = powMod(sqrY, P_DIV4_1, CURVE.P);
const isYOdd = (y & 1n) === 1n;
if (isYOdd)
y = mod(-y);
const point = new Point(x, y);
point.assertValidity();
return point;
}
static fromCompressedHex(bytes) {
if (bytes.length !== 33) {
throw new TypeError(`Point.fromHex: compressed expects 66 bytes, not ${bytes.length * 2}`);
throw new TypeError(`Point.fromHex: compressed expects 33 bytes, not ${bytes.length * 2}`);
}

@@ -256,5 +267,4 @@ const x = bytesToNumber(bytes.slice(1));

const isYOdd = (y & 1n) === 1n;
if (isFirstByteOdd !== isYOdd) {
if (isFirstByteOdd !== isYOdd)
y = mod(-y);
}
const point = new Point(x, y);

@@ -266,3 +276,3 @@ point.assertValidity();

if (bytes.length !== 65) {
throw new TypeError(`Point.fromHex: uncompressed expects 130 bytes, not ${bytes.length * 2}`);
throw new TypeError(`Point.fromHex: uncompressed expects 65 bytes, not ${bytes.length * 2}`);
}

@@ -277,2 +287,4 @@ const x = bytesToNumber(bytes.slice(1, 33));

const bytes = hex instanceof Uint8Array ? hex : hexToBytes(hex);
if (bytes.length === 32)
return this.fromX(bytes);
const header = bytes[0];

@@ -315,2 +327,8 @@ if (header === 0x02 || header === 0x03)

}
toHexX() {
return this.toHex(true).slice(2);
}
toRawX() {
return this.toRawBytes(true).slice(1);
}
assertValidity() {

@@ -352,3 +370,3 @@ const { x, y } = this;

}
class SignResult {
class Signature {
constructor(r, s) {

@@ -366,3 +384,3 @@ this.r = r;

if (check1 !== '30' || length !== str.length - 4 || check2 !== '02') {
throw new Error('SignResult.fromHex: Invalid signature');
throw new Error('Signature.fromHex: Invalid signature');
}

@@ -379,3 +397,3 @@ const rLen = parseByte(str.slice(6, 8));

const s = hexToNumber(str.slice(sStart, sStart + sLen));
return new SignResult(r, s);
return new Signature(r, s);
}

@@ -396,3 +414,4 @@ toRawBytes(isCompressed = false) {

}
exports.SignResult = SignResult;
exports.Signature = Signature;
exports.SignResult = Signature;
function concatBytes(...arrays) {

@@ -589,3 +608,3 @@ if (arrays.length === 1)

function normalizeSignature(signature) {
return signature instanceof SignResult ? signature : SignResult.fromHex(signature);
return signature instanceof Signature ? signature : Signature.fromHex(signature);
}

@@ -646,3 +665,3 @@ function getPublicKey(privateKey, isCompressed = false) {

}
const sig = new SignResult(r, adjustedS);
const sig = new Signature(r, adjustedS);
const hashed = typeof msgHash === 'string' ? sig.toHex() : sig.toRawBytes();

@@ -663,5 +682,2 @@ return recovered ? [hashed, recovery] : hashed;

exports.verify = verify;
function rawX(point) {
return point.toRawBytes(true).slice(1);
}
async function taggedHash(tag, ...messages) {

@@ -673,5 +689,5 @@ const tagB = new Uint8Array(tag.split('').map((c) => c.charCodeAt(0)));

}
async function createChallenge(x, p, message) {
async function createChallenge(x, P, message) {
const rx = pad32b(x);
const t = await taggedHash('BIP0340/challenge', rx, rawX(p), message);
const t = await taggedHash('BIP0340/challenge', rx, P.toRawX(), message);
return mod(t, CURVE.n);

@@ -682,7 +698,18 @@ }

}
class SchnorrSignResult {
class SchnorrSignature {
constructor(r, s) {
this.r = r;
this.s = s;
if (r === 0n || s === 0n || r >= CURVE.P || s >= CURVE.n)
throw new Error('Invalid signature');
}
static fromHex(hex) {
const bytes = hex instanceof Uint8Array ? hex : hexToBytes(hex);
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));
return new SchnorrSignature(r, s);
}
toHex() {

@@ -695,39 +722,53 @@ return pad64(this.r) + pad64(this.s);

}
function schnorrGetPublicKey(privateKey) {
const P = Point.fromPrivateKey(privateKey);
return typeof privateKey === 'string' ? P.toHexX() : P.toRawX();
}
async function schnorrSign(msgHash, privateKey, auxRand = exports.utils.randomPrivateKey()) {
if (msgHash == null)
throw new TypeError(`Expected valid message, not "${msgHash}"`);
if (!privateKey)
privateKey = 0n;
const { n } = CURVE;
const m = typeof msgHash === 'string' ? hexToBytes(msgHash) : msgHash;
const d0 = normalizePrivateKey(privateKey);
if (!(0 < d0 && d0 < n))
throw new Error('Invalid private key');
const rand = typeof auxRand === 'string' ? hexToBytes(auxRand) : auxRand;
if (rand.length !== 32)
throw new TypeError('Expected 32 bytes of aux randomness');
const P = Point.fromPrivateKey(d0);
const d = hasEvenY(P) ? d0 : n - d0;
const t0h = await taggedHash('BIP0340/aux', rand);
const t = d ^ t0h;
const k0h = await taggedHash('BIP0340/nonce', pad32b(t), P.toRawX(), m);
const k0 = mod(k0h, n);
if (k0 === 0n)
throw new Error('Creation of signature failed. k is zero');
const R = Point.fromPrivateKey(k0);
const k = hasEvenY(R) ? k0 : n - k0;
const e = await createChallenge(R.x, P, m);
const sig = new SchnorrSignature(R.x, mod(k + e * d, n));
const isValid = await schnorrVerify(sig.toRawBytes(), m, P.toRawX());
if (!isValid)
throw new Error('Invalid signature produced');
return typeof msgHash === 'string' ? sig.toHex() : sig.toRawBytes();
}
async function schnorrVerify(signature, msgHash, publicKey) {
const sig = signature instanceof SchnorrSignature ? signature : SchnorrSignature.fromHex(signature);
const m = typeof msgHash === 'string' ? hexToBytes(msgHash) : msgHash;
const P = normalizePublicKey(publicKey);
const e = await createChallenge(sig.r, P, m);
const sG = Point.fromPrivateKey(sig.s);
const eP = P.multiply(e);
const R = sG.subtract(eP);
if (R.equals(Point.BASE) || !hasEvenY(R) || R.x !== sig.r)
return false;
return true;
}
exports.schnorr = {
SignResult: SchnorrSignResult,
async sign(message, privateKey, auxRand = exports.utils.randomPrivateKey()) {
if (message == null)
throw new TypeError(`Expected valid message, not "${message}"`);
if (privateKey == null)
throw new TypeError('Expected valid private key');
const msg = typeof message === 'string' ? hexToBytes(message) : message;
const rand = typeof auxRand === 'string' ? hexToBytes(auxRand) : auxRand;
const order = CURVE.n;
const d0 = normalizePrivateKey(privateKey);
const p = Point.fromPrivateKey(d0);
const d = hasEvenY(p) ? d0 : order - d0;
const t0h = await taggedHash('BIP0340/aux', rand);
const t = d ^ t0h;
const k0h = await taggedHash('BIP0340/nonce', pad32b(t), rawX(p), msg);
const k0 = mod(k0h, order);
if (k0 === 0n)
throw new Error('Creation of signature failed. k is zero');
const r = Point.fromPrivateKey(k0);
const k = hasEvenY(r) ? k0 : order - k0;
const e = await createChallenge(r.x, p, msg);
const sig = new SchnorrSignResult(r.x, mod(k + e * d, order));
return sig;
},
async verify(signature, message, publicKey) {
const { r, s } = signature;
const msg = typeof message === 'string' ? hexToBytes(message) : message;
const pub = normalizePublicKey(publicKey);
if (r === 0n || s === 0n || r >= CURVE.P || s >= CURVE.n)
return false;
const e = await createChallenge(r, pub, msg);
const vr = Point.fromPrivateKey(s).add(pub.multiply(CURVE.n - e));
if (vr.equals(Point.BASE) || !hasEvenY(vr) || vr.x !== r)
return false;
return true;
},
Signature: SchnorrSignature,
getPublicKey: schnorrGetPublicKey,
sign: schnorrSign,
verify: schnorrVerify,
};

@@ -734,0 +775,0 @@ Point.BASE._setWindowSize(8);

{
"name": "noble-secp256k1",
"version": "1.1.0",
"version": "1.1.1",
"description": "Noble secp256k1. Very fast, high-security, auditable, 0-dep, 1-file ECDSA & Schnorr.",

@@ -5,0 +5,0 @@ "main": "index.js",

@@ -5,4 +5,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)

an elliptic curve that could be used for asymmetric encryption,
ECDH key agreement protocol and deterministic ECDSA signature scheme from RFC6979. Supports **Schnorr** signatures as per BIP0340.
ECDH key agreement protocol and signature schemes.
Supports deterministic **ECDSA** from RFC6979 and **Schnorr** signatures from BIP0340.
Algorithmically resistant to timing attacks. Tested against thousands of vectors from tiny-secp256k1.

@@ -133,5 +135,16 @@

##### `schnorr.getPublicKey(privateKey)`
```typescript
function schnorrGetPublicKey(privateKey: Uint8Array): Uint8Array;
function schnorrGetPublicKey(privateKey: string): string;
```
Returns 32-byte public key. *Warning:* it is incompatible with non-schnorr pubkey.
Specifically, its *y* coordinate may be flipped. See BIP0340 for clarification.
##### `schnorr.sign(hash, privateKey)`
```typescript
function schnorrSign(msgHash: Uint8Array, privateKey: Uint8Array, auxilaryRandom?: Uint8Array): Promise<schnorr.SignResult>;
function schnorrSign(msgHash: Uint8Array, privateKey: Uint8Array, auxilaryRandom?: Uint8Array): Promise<Uint8Array>;
function schnorrSign(msgHash: string, privateKey: string, auxilaryRandom?: string): Promise<string>;
```

@@ -144,7 +157,7 @@

- `auxilaryRandom?: Uint8Array` — optional 32 random bytes. By default, the method gathers cryptogarphically secure random.
- Returns Schnorr signature.
- Returns Schnorr signature in Hex format.
##### `schnorr.verify(signature, hash, publicKey)`
```typescript
function schnorrVerify(signature: Uint8Array, msgHash: Uint8Array, publicKey: Uint8Array): boolean
function schnorrVerify(signature: Uint8Array | string, msgHash: Uint8Array | string, publicKey: Uint8Array | string): boolean
```

@@ -236,4 +249,4 @@ - `signature: Uint8Array | string | { r: bigint, s: bigint }` - object returned by the `sign` function

getSharedSecret (precomputed) x 4,079 ops/sec @ 245μs/op
schnorr.sign x 1,643 ops/sec @ 608μs/op
schnorr.verify x 316 ops/sec @ 3ms/op
schnorr.sign x 252 ops/sec @ 3ms/op
schnorr.verify x 319 ops/sec @ 3ms/op

@@ -240,0 +253,0 @@ Compare to other libraries:

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