Viewing File: /home/ubuntu/efiexchange-node-base/node_modules/bitcoinjs-lib/node_modules/tiny-secp256k1/js.js
const BN = require('bn.js')
const EC = require('elliptic').ec
const secp256k1 = new EC('secp256k1')
const deterministicGenerateK = require('./rfc6979')
const ZERO32 = Buffer.alloc(32, 0)
const EC_GROUP_ORDER = Buffer.from('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141', 'hex')
const EC_P = Buffer.from('fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f', 'hex')
const n = secp256k1.curve.n
const nDiv2 = n.shrn(1)
const G = secp256k1.curve.g
const THROW_BAD_PRIVATE = 'Expected Private'
const THROW_BAD_POINT = 'Expected Point'
const THROW_BAD_TWEAK = 'Expected Tweak'
const THROW_BAD_HASH = 'Expected Hash'
const THROW_BAD_SIGNATURE = 'Expected Signature'
const THROW_BAD_EXTRA_DATA = 'Expected Extra Data (32 bytes)'
function isScalar (x) {
return (x instanceof Uint8Array) && x.length === 32
}
function isOrderScalar (x) {
if (!isScalar(x)) return false
return EC_GROUP_ORDER.compare(x) > 0 // < G
}
function isPoint (p) {
if (!(p instanceof Uint8Array)) return false
if (p.length < 33) return false
const t = p[0]
const x = p.subarray(1, 33)
if (ZERO32.compare(x) === 0) return false
if (EC_P.compare(x) <= 0) return false
if ((t === 0x02 || t === 0x03) && p.length === 33) {
try { decodeFrom(p) } catch (e) { return false } // TODO: temporary
return true
}
const y = p.subarray(33)
if (ZERO32.compare(y) === 0) return false
if (EC_P.compare(y) <= 0) return false
if (t === 0x04 && p.length === 65) return true
return false
}
function __isPointCompressed (p) {
return p[0] !== 0x04
}
function isPointCompressed (p) {
if (!isPoint(p)) return false
return __isPointCompressed(p)
}
function isPrivate (x) {
if (!isScalar(x)) return false
return ZERO32.compare(x) < 0 && // > 0
EC_GROUP_ORDER.compare(x) > 0 // < G
}
function isSignature (value) {
const r = value.subarray(0, 32)
const s = value.subarray(32, 64)
return (value instanceof Uint8Array) && value.length === 64 &&
EC_GROUP_ORDER.compare(r) > 0 &&
EC_GROUP_ORDER.compare(s) > 0
}
function assumeCompression (value, pubkey) {
if (value === undefined && pubkey !== undefined) return __isPointCompressed(pubkey)
if (value === undefined) return true
return value
}
function fromBuffer (d) { return new BN(d) }
function toBuffer (d) { return d.toArrayLike(Buffer, 'be', 32) }
function decodeFrom (P) { return secp256k1.curve.decodePoint(P) }
function getEncoded (P, compressed) { return Buffer.from(P._encode(compressed)) }
function pointAdd (pA, pB, __compressed) {
if (!isPoint(pA)) throw new TypeError(THROW_BAD_POINT)
if (!isPoint(pB)) throw new TypeError(THROW_BAD_POINT)
const a = decodeFrom(pA)
const b = decodeFrom(pB)
const pp = a.add(b)
if (pp.isInfinity()) return null
const compressed = assumeCompression(__compressed, pA)
return getEncoded(pp, compressed)
}
function pointAddScalar (p, tweak, __compressed) {
if (!isPoint(p)) throw new TypeError(THROW_BAD_POINT)
if (!isOrderScalar(tweak)) throw new TypeError(THROW_BAD_TWEAK)
const compressed = assumeCompression(__compressed, p)
const pp = decodeFrom(p)
if (ZERO32.compare(tweak) === 0) return getEncoded(pp, compressed)
const tt = fromBuffer(tweak)
const qq = G.mul(tt)
const uu = pp.add(qq)
if (uu.isInfinity()) return null
return getEncoded(uu, compressed)
}
function pointCompress (p, __compressed) {
if (!isPoint(p)) throw new TypeError(THROW_BAD_POINT)
const pp = decodeFrom(p)
if (pp.isInfinity()) throw new TypeError(THROW_BAD_POINT)
const compressed = assumeCompression(__compressed, p)
return getEncoded(pp, compressed)
}
function pointFromScalar (d, __compressed) {
if (!isPrivate(d)) throw new TypeError(THROW_BAD_PRIVATE)
const dd = fromBuffer(d)
const pp = G.mul(dd)
if (pp.isInfinity()) return null
const compressed = assumeCompression(__compressed)
return getEncoded(pp, compressed)
}
function pointMultiply (p, tweak, __compressed) {
if (!isPoint(p)) throw new TypeError(THROW_BAD_POINT)
if (!isOrderScalar(tweak)) throw new TypeError(THROW_BAD_TWEAK)
const compressed = assumeCompression(__compressed, p)
const pp = decodeFrom(p)
const tt = fromBuffer(tweak)
const qq = pp.mul(tt)
if (qq.isInfinity()) return null
return getEncoded(qq, compressed)
}
function privateAdd (d, tweak) {
if (!isPrivate(d)) throw new TypeError(THROW_BAD_PRIVATE)
if (!isOrderScalar(tweak)) throw new TypeError(THROW_BAD_TWEAK)
const dd = fromBuffer(d)
const tt = fromBuffer(tweak)
const dt = toBuffer(dd.add(tt).umod(n))
if (!isPrivate(dt)) return null
return dt
}
function privateSub (d, tweak) {
if (!isPrivate(d)) throw new TypeError(THROW_BAD_PRIVATE)
if (!isOrderScalar(tweak)) throw new TypeError(THROW_BAD_TWEAK)
const dd = fromBuffer(d)
const tt = fromBuffer(tweak)
const dt = toBuffer(dd.sub(tt).umod(n))
if (!isPrivate(dt)) return null
return dt
}
function sign (hash, x) {
return __sign(hash, x)
}
function signWithEntropy (hash, x, addData) {
return __sign(hash, x, addData)
}
function __sign (hash, x, addData) {
if (!isScalar(hash)) throw new TypeError(THROW_BAD_HASH)
if (!isPrivate(x)) throw new TypeError(THROW_BAD_PRIVATE)
if (addData !== undefined && !isScalar(addData)) throw new TypeError(THROW_BAD_EXTRA_DATA)
const d = fromBuffer(x)
const e = fromBuffer(hash)
let r, s
const checkSig = function (k) {
const kI = fromBuffer(k)
const Q = G.mul(kI)
if (Q.isInfinity()) return false
r = Q.x.umod(n)
if (r.isZero() === 0) return false
s = kI
.invm(n)
.mul(e.add(d.mul(r)))
.umod(n)
if (s.isZero() === 0) return false
return true
}
deterministicGenerateK(hash, x, checkSig, isPrivate, addData)
// enforce low S values, see bip62: 'low s values in signatures'
if (s.cmp(nDiv2) > 0) {
s = n.sub(s)
}
const buffer = Buffer.allocUnsafe(64)
toBuffer(r).copy(buffer, 0)
toBuffer(s).copy(buffer, 32)
return buffer
}
function verify (hash, q, signature, strict) {
if (!isScalar(hash)) throw new TypeError(THROW_BAD_HASH)
if (!isPoint(q)) throw new TypeError(THROW_BAD_POINT)
// 1.4.1 Enforce r and s are both integers in the interval [1, n − 1] (1, isSignature enforces '< n - 1')
if (!isSignature(signature)) throw new TypeError(THROW_BAD_SIGNATURE)
const Q = decodeFrom(q)
const r = fromBuffer(signature.subarray(0, 32))
const s = fromBuffer(signature.subarray(32, 64))
if (strict && s.cmp(nDiv2) > 0) {
return false
}
// 1.4.1 Enforce r and s are both integers in the interval [1, n − 1] (2, enforces '> 0')
if (r.gtn(0) <= 0 /* || r.compareTo(n) >= 0 */) return false
if (s.gtn(0) <= 0 /* || s.compareTo(n) >= 0 */) return false
// 1.4.2 H = Hash(M), already done by the user
// 1.4.3 e = H
const e = fromBuffer(hash)
// Compute s^-1
const sInv = s.invm(n)
// 1.4.4 Compute u1 = es^−1 mod n
// u2 = rs^−1 mod n
const u1 = e.mul(sInv).umod(n)
const u2 = r.mul(sInv).umod(n)
// 1.4.5 Compute R = (xR, yR)
// R = u1G + u2Q
const R = G.mulAdd(u1, Q, u2)
// 1.4.5 (cont.) Enforce R is not at infinity
if (R.isInfinity()) return false
// 1.4.6 Convert the field element R.x to an integer
const xR = R.x
// 1.4.7 Set v = xR mod n
const v = xR.umod(n)
// 1.4.8 If v = r, output "valid", and if v != r, output "invalid"
return v.eq(r)
}
module.exports = {
isPoint,
isPointCompressed,
isPrivate,
pointAdd,
pointAddScalar,
pointCompress,
pointFromScalar,
pointMultiply,
privateAdd,
privateSub,
sign,
signWithEntropy,
verify
}
Back to Directory
File Manager