noble-secp256k1
Advanced tools
Comparing version 0.5.1 to 0.5.2
@@ -14,2 +14,17 @@ export declare const CURVE_PARAMS: { | ||
declare type Signature = Uint8Array | string | SignResult; | ||
declare class JacobianPoint { | ||
x: bigint; | ||
y: bigint; | ||
z: bigint; | ||
static ZERO_POINT: JacobianPoint; | ||
static fromPoint(p: Point): JacobianPoint; | ||
constructor(x: bigint, y: bigint, z: bigint); | ||
static batchAffine(points: JacobianPoint[]): Point[]; | ||
equals(other: JacobianPoint): boolean; | ||
negate(): JacobianPoint; | ||
double(): JacobianPoint; | ||
add(other: JacobianPoint): JacobianPoint; | ||
multiplyUnsafe(n: bigint): JacobianPoint; | ||
toAffine(invZ?: bigint): Point; | ||
} | ||
export declare class Point { | ||
@@ -38,3 +53,4 @@ x: bigint; | ||
private precomputeWindow; | ||
multiply(scalar: bigint): Point; | ||
multiply(scalar: bigint, isAffine: false): JacobianPoint; | ||
multiply(scalar: bigint, isAffine?: true): Point; | ||
} | ||
@@ -41,0 +57,0 @@ export declare class SignResult { |
58
index.js
@@ -40,2 +40,14 @@ 'use strict'; | ||
} | ||
equals(other) { | ||
const a = this; | ||
const b = other; | ||
const az2 = mod(a.z * a.z); | ||
const az3 = mod(a.z * az2); | ||
const bz2 = mod(b.z * b.z); | ||
const bz3 = mod(b.z * bz2); | ||
return mod(a.x * bz2) === mod(az2 * b.x) && mod(a.y * bz3) === mod(az3 * b.y); | ||
} | ||
negate() { | ||
return new JacobianPoint(this.x, mod(-this.y), this.z); | ||
} | ||
double() { | ||
@@ -56,5 +68,5 @@ const a = this.x ** 2n; | ||
const b = other; | ||
if (!b.x || !b.y) | ||
if (b.x === 0n || b.y === 0n) | ||
return a; | ||
if (!a.x || !a.y) | ||
if (a.x === 0n || a.y === 0n) | ||
return b; | ||
@@ -85,6 +97,17 @@ const z1z1 = a.z ** 2n; | ||
} | ||
toAffine(negZ) { | ||
const negZ2 = negZ ** 2n; | ||
const x = mod(this.x * negZ2, P); | ||
const y = mod(this.y * negZ2 * negZ, P); | ||
multiplyUnsafe(n) { | ||
let p = JacobianPoint.ZERO_POINT; | ||
let d = this; | ||
while (n > 0n) { | ||
if (n & 1n) | ||
p = p.add(d); | ||
d = d.double(); | ||
n >>= 1n; | ||
} | ||
return p; | ||
} | ||
toAffine(invZ = modInverse(this.z)) { | ||
const invZ2 = invZ ** 2n; | ||
const x = mod(this.x * invZ2, P); | ||
const y = mod(this.y * invZ2 * invZ, P); | ||
return new Point(x, y); | ||
@@ -162,6 +185,6 @@ } | ||
const P_ = Point.fromHex(`0${2 + (recovery & 1)}${pad64(r)}`); | ||
const sP = P_.multiply(s); | ||
const hG = Point.BASE_POINT.multiply(h).negate(); | ||
const Q = sP.add(hG).multiply(rinv); | ||
return Q; | ||
const sP = P_.multiply(s, false); | ||
const hG = Point.BASE_POINT.multiply(h, false).negate(); | ||
const Q = sP.add(hG).multiplyUnsafe(rinv); | ||
return Q.toAffine(); | ||
} | ||
@@ -234,4 +257,5 @@ toRawBytes(isCompressed = false) { | ||
} | ||
const res = JacobianPoint.batchAffine(points).map(p => JacobianPoint.fromPoint(p)); | ||
let res = points; | ||
if (W !== 1) { | ||
res = JacobianPoint.batchAffine(points).map(p => JacobianPoint.fromPoint(p)); | ||
this.PRECOMPUTES = res; | ||
@@ -241,3 +265,3 @@ } | ||
} | ||
multiply(scalar) { | ||
multiply(scalar, isAffine = true) { | ||
if (typeof scalar !== 'number' && typeof scalar !== 'bigint') { | ||
@@ -272,3 +296,3 @@ throw new TypeError('Point#multiply: expected number or bigint'); | ||
} | ||
return JacobianPoint.batchAffine([p, f])[0]; | ||
return isAffine ? JacobianPoint.batchAffine([p, f])[0] : p; | ||
} | ||
@@ -556,7 +580,7 @@ } | ||
const { r, s } = normalizeSignature(signature); | ||
const pubKey = normalizePublicKey(publicKey); | ||
const pubKey = JacobianPoint.fromPoint(normalizePublicKey(publicKey)); | ||
const s1 = modInverse(s, PRIME_ORDER); | ||
const Ghs1 = Point.BASE_POINT.multiply(mod(h * s1, PRIME_ORDER)); | ||
const Prs1 = pubKey.multiply(mod(r * s1, PRIME_ORDER)); | ||
const res = Ghs1.add(Prs1); | ||
const Ghs1 = Point.BASE_POINT.multiply(mod(h * s1, PRIME_ORDER), false); | ||
const Prs1 = pubKey.multiplyUnsafe(mod(r * s1, PRIME_ORDER)); | ||
const res = Ghs1.add(Prs1).toAffine(); | ||
return res.x === r; | ||
@@ -563,0 +587,0 @@ } |
{ | ||
"name": "noble-secp256k1", | ||
"version": "0.5.1", | ||
"version": "0.5.2", | ||
"description": "Noble secp256k1. High-security, easily auditable, 0-dep, 1-file pubkey & ECDSA.", | ||
@@ -33,2 +33,3 @@ "main": "index.js", | ||
"jest": "^25.1.0", | ||
"micro-bmark": "^0.1.1", | ||
"ts-jest": "^25.2.0", | ||
@@ -35,0 +36,0 @@ "typescript": "3.8.3" |
@@ -182,19 +182,14 @@ # noble-secp256k1 | ||
getPublicKey x 2309 ops/sec @ 432μs/op | ||
getPublicKey x 2394 ops/sec @ 416μs/op | ||
sign x 1815 ops/sec @ 550μs/op | ||
verify x 235 ops/sec @ 4ms/op | ||
recoverPublicKey x 123 ops/sec @ 8ms/op | ||
getSharedSecret aka ecdh x 278 ops/sec @ 3ms/op | ||
verify x 396 ops/sec @ 2ms/op | ||
recoverPublicKey x 163 ops/sec @ 6ms/op | ||
getSharedSecret aka ecdh x 287 ops/sec @ 3ms/op | ||
getSharedSecret (precomputed) x 2593 ops/sec @ 385μs/op | ||
generateRandomPrivateKey x 339328 ops/sec @ 2μs/op | ||
Custom window=16 (takes 11sec to initialize): | ||
Custom window=16 (takes 10s to initialize): | ||
getPublicKey x 6010 ops/sec @ 166μs/op | ||
sign x 3451 ops/sec @ 289μs/op | ||
verify x 246 ops/sec @ 4ms/op | ||
recoverPublicKey x 125 ops/sec @ 7ms/op | ||
getSharedSecret aka ecdh x 273 ops/sec @ 3ms/op | ||
getSharedSecret (precomputed) x 5066 ops/sec @ 197μs/op | ||
generateRandomPrivateKey x 339328 ops/sec @ 2μs/op | ||
@@ -201,0 +196,0 @@ ## Security |
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
36111
679
7
217