noble-secp256k1
Advanced tools
Comparing version 1.2.1 to 1.2.2
@@ -47,2 +47,3 @@ /*! noble-secp256k1 - MIT License (c) Paul Miller (paulmillr.com) */ | ||
static fromHex(hex: Hex): Signature; | ||
assertValidity(): void; | ||
toRawBytes(isCompressed?: boolean): Uint8Array; | ||
@@ -49,0 +50,0 @@ toHex(isCompressed?: boolean): string; |
162
index.js
@@ -16,3 +16,2 @@ "use strict"; | ||
exports.CURVE = CURVE; | ||
const PRIME_SIZE = 256; | ||
function weistrass(x) { | ||
@@ -111,9 +110,5 @@ const { a, b } = CURVE; | ||
multiplyUnsafe(scalar) { | ||
if (typeof scalar !== 'number' && typeof scalar !== 'bigint') { | ||
throw new TypeError('Point#multiply: expected number or bigint'); | ||
} | ||
if (!isValidScalar(scalar)) | ||
throw new TypeError('Point#multiply: expected valid scalar'); | ||
let n = mod(BigInt(scalar), CURVE.n); | ||
if (n <= 0) { | ||
throw new Error('Point#multiply: invalid scalar, expected positive integer'); | ||
} | ||
if (!USE_ENDOMORPHISM) { | ||
@@ -207,9 +202,5 @@ let p = JacobianPoint.ZERO; | ||
multiply(scalar, affinePoint) { | ||
if (typeof scalar !== 'number' && typeof scalar !== 'bigint') { | ||
throw new TypeError('Point#multiply: expected number or bigint'); | ||
} | ||
if (!isValidScalar(scalar)) | ||
throw new TypeError('Point#multiply: expected valid scalar'); | ||
let n = mod(BigInt(scalar), CURVE.n); | ||
if (n <= 0) { | ||
throw new Error('Point#multiply: invalid scalar, expected positive integer'); | ||
} | ||
let point; | ||
@@ -304,5 +295,5 @@ let fake; | ||
} | ||
const { r, s } = normalizeSignature(signature); | ||
if (r === 0n || s === 0n) | ||
throw new Error('Invalid signature'); | ||
const sig = normalizeSignature(signature); | ||
sig.assertValidity(); | ||
const { r, s } = sig; | ||
if (recovery !== 0 && recovery !== 1) | ||
@@ -393,3 +384,3 @@ throw new Error('Invalid yParity bit'); | ||
if (check3 !== '02') { | ||
throw new Error('SignResult.fromHex: Invalid signature'); | ||
throw new Error('Signature.fromHex: Invalid signature'); | ||
} | ||
@@ -401,2 +392,10 @@ const sLen = parseByte(str.slice(rEnd + 2, rEnd + 4)); | ||
} | ||
assertValidity() { | ||
const { n } = CURVE; | ||
const { r, s } = this; | ||
if (!isWithinCurveOrder(r)) | ||
throw new Error('Invalid Signature: r must be 0 < r < n'); | ||
if (!isWithinCurveOrder(s)) | ||
throw new Error('Invalid Signature: s must be 0 < s < n'); | ||
} | ||
toRawBytes(isCompressed = false) { | ||
@@ -454,3 +453,3 @@ return hexToBytes(this.toHex(isCompressed)); | ||
function hexToBytes(hex) { | ||
if (hex.length & 1) | ||
if (typeof hex !== 'string' || hex.length % 2) | ||
throw new Error('Expected valid hex'); | ||
@@ -470,2 +469,9 @@ const array = new Uint8Array(hex.length / 2); | ||
} | ||
function isValidScalar(num) { | ||
if (typeof num === 'bigint' && num > 0n) | ||
return true; | ||
if (typeof num === 'number' && num > 0 && Number.isSafeInteger(num)) | ||
return true; | ||
return false; | ||
} | ||
function mod(a, b = CURVE.P) { | ||
@@ -475,5 +481,5 @@ const result = a % b; | ||
} | ||
function powMod2(t, power) { | ||
function pow2(x, power) { | ||
const { P } = CURVE; | ||
let res = t; | ||
let res = x; | ||
while (power-- > 0n) { | ||
@@ -485,20 +491,25 @@ res *= res; | ||
} | ||
function sqrtMod(a) { | ||
function sqrtMod(x) { | ||
const { P } = CURVE; | ||
const x2 = (a * a * a) % P; | ||
const x3 = (x2 * x2 * a) % P; | ||
const x6 = (powMod2(x3, 3n) * x3) % P; | ||
const x9 = (powMod2(x6, 3n) * x3) % P; | ||
const x11 = (powMod2(x9, 2n) * x2) % P; | ||
const x22 = (powMod2(x11, 11n) * x11) % P; | ||
const x44 = (powMod2(x22, 22n) * x22) % P; | ||
const x88 = (powMod2(x44, 44n) * x44) % P; | ||
const x176 = (powMod2(x88, 88n) * x88) % P; | ||
const x220 = (powMod2(x176, 44n) * x44) % P; | ||
const x223 = (powMod2(x220, 3n) * x3) % P; | ||
const t1 = (powMod2(x223, 23n) * x22) % P; | ||
const t2 = (powMod2(t1, 6n) * x2) % P; | ||
return powMod2(t2, 2n); | ||
const b2 = (x * x * x) % P; | ||
const b3 = (b2 * b2 * x) % P; | ||
const b6 = (pow2(b3, 3n) * b3) % P; | ||
const b9 = (pow2(b6, 3n) * b3) % P; | ||
const b11 = (pow2(b9, 2n) * b2) % P; | ||
const b22 = (pow2(b11, 11n) * b11) % P; | ||
const b44 = (pow2(b22, 22n) * b22) % P; | ||
const b88 = (pow2(b44, 44n) * b44) % P; | ||
const b176 = (pow2(b88, 88n) * b88) % P; | ||
const b220 = (pow2(b176, 44n) * b44) % P; | ||
const b223 = (pow2(b220, 3n) * b3) % P; | ||
const t1 = (pow2(b223, 23n) * b22) % P; | ||
const t2 = (pow2(t1, 6n) * b2) % P; | ||
return pow2(t2, 2n); | ||
} | ||
function egcd(a, b) { | ||
function invert(number, modulo = CURVE.P) { | ||
if (number === 0n || modulo <= 0n) { | ||
throw new Error('invert: expected positive integers'); | ||
} | ||
let a = mod(number, modulo); | ||
let b = modulo; | ||
let [x, y, u, v] = [0n, 1n, 1n, 0n]; | ||
@@ -515,9 +526,2 @@ while (a !== 0n) { | ||
const gcd = b; | ||
return [gcd, x, y]; | ||
} | ||
function invert(number, modulo = CURVE.P) { | ||
if (number === 0n || modulo <= 0n) { | ||
throw new Error('invert: expected positive integers'); | ||
} | ||
const [gcd, x] = egcd(mod(number, modulo), modulo); | ||
if (gcd !== 1n) | ||
@@ -570,5 +574,7 @@ throw new Error('invert: does not exist'); | ||
function truncateHash(hash) { | ||
hash = typeof hash === 'string' ? hash : bytesToHex(hash); | ||
if (typeof hash !== 'string') | ||
hash = bytesToHex(hash); | ||
let msg = hexToNumber(hash || '0'); | ||
const delta = (hash.length / 2) * 8 - PRIME_SIZE; | ||
const byteLength = hash.length / 2; | ||
const delta = byteLength * 8 - 256; | ||
if (delta > 0) { | ||
@@ -599,3 +605,3 @@ msg = msg >> BigInt(delta); | ||
let qrs; | ||
if (isValidPrivateKey(T) && (qrs = calcQRSFromK(T, h1n, privateKey))) { | ||
if (isWithinCurveOrder(T) && (qrs = calcQRSFromK(T, h1n, privateKey))) { | ||
return qrs; | ||
@@ -608,4 +614,4 @@ } | ||
} | ||
function isValidPrivateKey(privateKey) { | ||
return 0 < privateKey && privateKey < CURVE.n; | ||
function isWithinCurveOrder(num) { | ||
return 0 < num && num < CURVE.n; | ||
} | ||
@@ -621,24 +627,26 @@ function calcQRSFromK(k, msg, priv) { | ||
} | ||
function normalizePrivateKey(privateKey) { | ||
let key; | ||
if (privateKey instanceof Uint8Array) { | ||
if (privateKey.length !== 32) | ||
function normalizePrivateKey(key) { | ||
let num; | ||
if (typeof key === 'bigint') { | ||
num = key; | ||
} | ||
else if (Number.isSafeInteger(key) && key > 0) { | ||
num = BigInt(key); | ||
} | ||
else if (typeof key === 'string') { | ||
if (key.length !== 64) | ||
throw new Error('Expected 32 bytes of private key'); | ||
key = bytesToNumber(privateKey); | ||
num = hexToNumber(key); | ||
} | ||
else if (typeof privateKey === 'string') { | ||
if (privateKey.length !== 64) | ||
else if (key instanceof Uint8Array) { | ||
if (key.length !== 32) | ||
throw new Error('Expected 32 bytes of private key'); | ||
key = hexToNumber(privateKey); | ||
num = bytesToNumber(key); | ||
} | ||
else if (Number.isSafeInteger(privateKey) && privateKey > 0) { | ||
key = BigInt(privateKey); | ||
} | ||
else if (typeof privateKey === 'bigint' && privateKey > 0n && privateKey < CURVE.P) { | ||
key = privateKey; | ||
} | ||
else { | ||
throw new TypeError('Expected valid private key'); | ||
} | ||
return key; | ||
if (!isWithinCurveOrder(num)) | ||
throw new Error('Expected private key 0 < key < n'); | ||
return num; | ||
} | ||
@@ -707,10 +715,18 @@ function normalizePublicKey(publicKey) { | ||
function verify(signature, msgHash, publicKey) { | ||
const { n } = CURVE; | ||
const sig = normalizeSignature(signature); | ||
try { | ||
sig.assertValidity(); | ||
} | ||
catch (error) { | ||
return false; | ||
} | ||
const { r, s } = sig; | ||
const h = truncateHash(msgHash); | ||
const { r, s } = normalizeSignature(signature); | ||
if (r === 0n || s === 0n) | ||
if (h === 0n) | ||
return false; | ||
const pubKey = JacobianPoint.fromAffine(normalizePublicKey(publicKey)); | ||
const s1 = invert(s, CURVE.n); | ||
const Ghs1 = JacobianPoint.BASE.multiply(mod(h * s1, CURVE.n)); | ||
const Prs1 = pubKey.multiplyUnsafe(mod(r * s1, CURVE.n)); | ||
const s1 = invert(s, n); | ||
const Ghs1 = JacobianPoint.BASE.multiply(mod(h * s1, n)); | ||
const Prs1 = pubKey.multiplyUnsafe(mod(r * s1, n)); | ||
const res = Ghs1.add(Prs1).toAffine(); | ||
@@ -769,3 +785,3 @@ return res.x === r; | ||
const d0 = normalizePrivateKey(privateKey); | ||
if (!(0 < d0 && d0 < n)) | ||
if (!isWithinCurveOrder(d0)) | ||
throw new Error('Invalid private key'); | ||
@@ -813,3 +829,9 @@ const rand = typeof auxRand === 'string' ? hexToBytes(auxRand) : auxRand; | ||
isValidPrivateKey(privateKey) { | ||
return isValidPrivateKey(normalizePrivateKey(privateKey)); | ||
try { | ||
normalizePrivateKey(privateKey); | ||
return true; | ||
} | ||
catch (error) { | ||
return false; | ||
} | ||
}, | ||
@@ -816,0 +838,0 @@ randomPrivateKey: (bytesLength = 32) => { |
{ | ||
"name": "noble-secp256k1", | ||
"version": "1.2.1", | ||
"version": "1.2.2", | ||
"description": "Fastest JS implementation of secp256k1. Zero-dependency, high-security, audited ECDSA & Schnorr", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
50239
966