negate: () => Point
double: () => Point
add: (other: Point) => Point
- multiply: (n: bigint) => Point
toAffine: () => AffinePoint
assertValidity: () => Point
toBytes: (isCompressed?: boolean) => Bytes
Z3 = M(Z3 + t0) // step 40
return secp256k1.Point(X3, Y3, Z3)
},
- /**
- * Point-by-scalar multiplication. Scalar must be in range 1 <= n < CURVE.n.
- * Uses {@link wNAF} for base point.
- * Uses fake point to mitigate side-channel leakage.
- * @param n scalar by which point is multiplied
- * @param safe safe mode guards against timing attacks; unsafe mode is faster
- */
- multiply (n: bigint): Point {
- if (secp256k1.bigintInRange(n, 1n, secp256k1.N) === 1n) return this
- if (this.equals(secp256k1.G)) return secp256k1.wNAF(n).p
- // init result point & fake point
- let p = secp256k1.I
- let f = secp256k1.G
- for (let d: Point = this; n > 0n; d = d.double(), n >>= 1n) {
- // if bit is present, add to point
- // if not present, add to fake, for timing safety
- if (n & 1n) p = p.add(d)
- else f = f.add(d)
- }
- return p
- },
/** Convert point to 2d xy affine point. (X, Y, Z) ∋ (x=X/Z, y=Y/Z) */
toAffine (): AffinePoint {
const { X: x, Y: y, Z: z } = this
/** Creates 33/65-byte public key from 32-byte private key. */
static getPublicKey (sk: Bytes, isCompressed = true): Bytes {
- return this.G.multiply(this.secretKeyToScalar(sk)).toBytes(isCompressed)
+ return this.wNAF(this.secretKeyToScalar(sk)).p.toBytes(isCompressed)
}
static isValidPublicKey (pk: Bytes, isCompressed?: boolean): boolean {
return cnd ? n : p
}
static wNAF (n: bigint): { p: Point; f: Point } {
+ console.log('mult', n)
const comp = this.Gpows || (this.Gpows = this.precompute())
let p = this.I
let f = this.G // f must be G, or could become I in the end