mirror of
https://github.com/Instadapp/Swap-Aggregator-Subgraph.git
synced 2024-07-29 21:57:12 +00:00
244 lines
7.7 KiB
JavaScript
244 lines
7.7 KiB
JavaScript
'use strict'
|
|
var Buffer = require('safe-buffer').Buffer
|
|
var createHash = require('create-hash')
|
|
var HmacDRBG = require('drbg.js/hmac')
|
|
var messages = require('../messages.json')
|
|
var BN = require('./bn')
|
|
var ECPoint = require('./ecpoint')
|
|
var g = require('./ecpointg')
|
|
|
|
exports.privateKeyVerify = function (privateKey) {
|
|
var bn = BN.fromBuffer(privateKey)
|
|
return !(bn.isOverflow() || bn.isZero())
|
|
}
|
|
|
|
exports.privateKeyExport = function (privateKey, compressed) {
|
|
var d = BN.fromBuffer(privateKey)
|
|
if (d.isOverflow() || d.isZero()) throw new Error(messages.EC_PRIVATE_KEY_EXPORT_DER_FAIL)
|
|
|
|
return g.mul(d).toPublicKey(compressed)
|
|
}
|
|
|
|
exports.privateKeyNegate = function (privateKey) {
|
|
var bn = BN.fromBuffer(privateKey)
|
|
if (bn.isZero()) return Buffer.alloc(32)
|
|
|
|
if (bn.ucmp(BN.n) > 0) bn.isub(BN.n)
|
|
return BN.n.sub(bn).toBuffer()
|
|
}
|
|
|
|
exports.privateKeyModInverse = function (privateKey) {
|
|
var bn = BN.fromBuffer(privateKey)
|
|
if (bn.isOverflow() || bn.isZero()) throw new Error(messages.EC_PRIVATE_KEY_RANGE_INVALID)
|
|
|
|
return bn.uinvm().toBuffer()
|
|
}
|
|
|
|
exports.privateKeyTweakAdd = function (privateKey, tweak) {
|
|
var bn = BN.fromBuffer(tweak)
|
|
if (bn.isOverflow()) throw new Error(messages.EC_PRIVATE_KEY_TWEAK_ADD_FAIL)
|
|
|
|
bn.iadd(BN.fromBuffer(privateKey))
|
|
if (bn.isOverflow()) bn.isub(BN.n)
|
|
if (bn.isZero()) throw new Error(messages.EC_PRIVATE_KEY_TWEAK_ADD_FAIL)
|
|
|
|
return bn.toBuffer()
|
|
}
|
|
|
|
exports.privateKeyTweakMul = function (privateKey, tweak) {
|
|
var bn = BN.fromBuffer(tweak)
|
|
if (bn.isOverflow() || bn.isZero()) throw new Error(messages.EC_PRIVATE_KEY_TWEAK_MUL_FAIL)
|
|
|
|
var d = BN.fromBuffer(privateKey)
|
|
return bn.umul(d).ureduce().toBuffer()
|
|
}
|
|
|
|
exports.publicKeyCreate = function (privateKey, compressed) {
|
|
var d = BN.fromBuffer(privateKey)
|
|
if (d.isOverflow() || d.isZero()) throw new Error(messages.EC_PUBLIC_KEY_CREATE_FAIL)
|
|
|
|
return g.mul(d).toPublicKey(compressed)
|
|
}
|
|
|
|
exports.publicKeyConvert = function (publicKey, compressed) {
|
|
var point = ECPoint.fromPublicKey(publicKey)
|
|
if (point === null) throw new Error(messages.EC_PUBLIC_KEY_PARSE_FAIL)
|
|
|
|
return point.toPublicKey(compressed)
|
|
}
|
|
|
|
exports.publicKeyVerify = function (publicKey) {
|
|
return ECPoint.fromPublicKey(publicKey) !== null
|
|
}
|
|
|
|
exports.publicKeyTweakAdd = function (publicKey, tweak, compressed) {
|
|
var point = ECPoint.fromPublicKey(publicKey)
|
|
if (point === null) throw new Error(messages.EC_PUBLIC_KEY_PARSE_FAIL)
|
|
|
|
tweak = BN.fromBuffer(tweak)
|
|
if (tweak.isOverflow()) throw new Error(messages.EC_PUBLIC_KEY_TWEAK_ADD_FAIL)
|
|
|
|
var result = g.mul(tweak).add(point)
|
|
if (result.inf) throw new Error(messages.EC_PUBLIC_KEY_TWEAK_ADD_FAIL)
|
|
|
|
return result.toPublicKey(compressed)
|
|
}
|
|
|
|
exports.publicKeyTweakMul = function (publicKey, tweak, compressed) {
|
|
var point = ECPoint.fromPublicKey(publicKey)
|
|
if (point === null) throw new Error(messages.EC_PUBLIC_KEY_PARSE_FAIL)
|
|
|
|
tweak = BN.fromBuffer(tweak)
|
|
if (tweak.isOverflow() || tweak.isZero()) throw new Error(messages.EC_PUBLIC_KEY_TWEAK_MUL_FAIL)
|
|
|
|
return point.mul(tweak).toPublicKey(compressed)
|
|
}
|
|
|
|
exports.publicKeyCombine = function (publicKeys, compressed) {
|
|
var points = new Array(publicKeys.length)
|
|
for (var i = 0; i < publicKeys.length; ++i) {
|
|
points[i] = ECPoint.fromPublicKey(publicKeys[i])
|
|
if (points[i] === null) throw new Error(messages.EC_PUBLIC_KEY_PARSE_FAIL)
|
|
}
|
|
|
|
var point = points[0]
|
|
for (var j = 1; j < points.length; ++j) point = point.add(points[j])
|
|
if (point.inf) throw new Error(messages.EC_PUBLIC_KEY_COMBINE_FAIL)
|
|
|
|
return point.toPublicKey(compressed)
|
|
}
|
|
|
|
exports.signatureNormalize = function (signature) {
|
|
var r = BN.fromBuffer(signature.slice(0, 32))
|
|
var s = BN.fromBuffer(signature.slice(32, 64))
|
|
if (r.isOverflow() || s.isOverflow()) throw new Error(messages.ECDSA_SIGNATURE_PARSE_FAIL)
|
|
|
|
var result = Buffer.from(signature)
|
|
if (s.isHigh()) BN.n.sub(s).toBuffer().copy(result, 32)
|
|
|
|
return result
|
|
}
|
|
|
|
exports.signatureExport = function (signature) {
|
|
var r = signature.slice(0, 32)
|
|
var s = signature.slice(32, 64)
|
|
if (BN.fromBuffer(r).isOverflow() || BN.fromBuffer(s).isOverflow()) throw new Error(messages.ECDSA_SIGNATURE_PARSE_FAIL)
|
|
|
|
return { r: r, s: s }
|
|
}
|
|
|
|
exports.signatureImport = function (sigObj) {
|
|
var r = BN.fromBuffer(sigObj.r)
|
|
if (r.isOverflow()) r = BN.fromNumber(0)
|
|
|
|
var s = BN.fromBuffer(sigObj.s)
|
|
if (s.isOverflow()) s = BN.fromNumber(0)
|
|
|
|
return Buffer.concat([r.toBuffer(), s.toBuffer()])
|
|
}
|
|
|
|
exports.sign = function (message, privateKey, noncefn, data) {
|
|
var d = BN.fromBuffer(privateKey)
|
|
if (d.isOverflow() || d.isZero()) throw new Error(messages.ECDSA_SIGN_FAIL)
|
|
|
|
if (noncefn === null) {
|
|
var drbg = new HmacDRBG('sha256', privateKey, message, data)
|
|
noncefn = function () { return drbg.generate(32) }
|
|
}
|
|
|
|
var bnMessage = BN.fromBuffer(message)
|
|
for (var count = 0; ; ++count) {
|
|
var nonce = noncefn(message, privateKey, null, data, count)
|
|
if (!Buffer.isBuffer(nonce) || nonce.length !== 32) throw new Error(messages.ECDSA_SIGN_FAIL)
|
|
|
|
var k = BN.fromBuffer(nonce)
|
|
if (k.isOverflow() || k.isZero()) continue
|
|
|
|
var kp = g.mul(k)
|
|
var r = kp.x.fireduce()
|
|
if (r.isZero()) continue
|
|
|
|
var s = k.uinvm().umul(r.umul(d).ureduce().iadd(bnMessage).fireduce()).ureduce()
|
|
if (s.isZero()) continue
|
|
|
|
var recovery = (kp.x.ucmp(r) !== 0 ? 2 : 0) | (kp.y.isOdd() ? 1 : 0)
|
|
if (s.isHigh()) {
|
|
s = BN.n.sub(s)
|
|
recovery ^= 1
|
|
}
|
|
|
|
return {
|
|
signature: Buffer.concat([r.toBuffer(), s.toBuffer()]),
|
|
recovery: recovery
|
|
}
|
|
}
|
|
}
|
|
|
|
exports.verify = function (message, signature, publicKey) {
|
|
var sigr = BN.fromBuffer(signature.slice(0, 32))
|
|
var sigs = BN.fromBuffer(signature.slice(32, 64))
|
|
if (sigr.isOverflow() || sigs.isOverflow()) throw new Error(messages.ECDSA_SIGNATURE_PARSE_FAIL)
|
|
|
|
if (sigs.isHigh() || sigr.isZero() || sigs.isZero()) return false
|
|
|
|
var pub = ECPoint.fromPublicKey(publicKey)
|
|
if (pub === null) throw new Error(messages.EC_PUBLIC_KEY_PARSE_FAIL)
|
|
|
|
var sinv = sigs.uinvm()
|
|
var u1 = sinv.umul(BN.fromBuffer(message)).ureduce()
|
|
var u2 = sinv.umul(sigr).ureduce()
|
|
var point = g.mulAdd(u1, pub, u2)
|
|
if (point.inf) return false
|
|
|
|
// return ECPoint.fromECJPoint(point).x.fireduce().ucmp(sigr) === 0
|
|
// Inversion-free
|
|
var z2 = point.z.redSqr()
|
|
if (sigr.redMul(z2).ucmp(point.x) === 0) return true
|
|
if (sigr.ucmp(BN.psn) >= 0) return false
|
|
|
|
return sigr.iadd(BN.psn).redMul(z2).ucmp(point.x) === 0
|
|
}
|
|
|
|
exports.recover = function (message, signature, recovery, compressed) {
|
|
var sigr = BN.fromBuffer(signature.slice(0, 32))
|
|
var sigs = BN.fromBuffer(signature.slice(32, 64))
|
|
if (sigr.isOverflow() || sigs.isOverflow()) throw new Error(messages.ECDSA_SIGNATURE_PARSE_FAIL)
|
|
|
|
do {
|
|
if (sigr.isZero() || sigs.isZero()) break
|
|
|
|
var kpx = sigr
|
|
if (recovery >> 1) {
|
|
if (kpx.ucmp(BN.psn) >= 0) break
|
|
kpx = sigr.add(BN.n)
|
|
}
|
|
|
|
var kpPublicKey = Buffer.concat([Buffer.from([0x02 + (recovery & 0x01)]), kpx.toBuffer()])
|
|
var kp = ECPoint.fromPublicKey(kpPublicKey)
|
|
if (kp === null) break
|
|
|
|
var rInv = sigr.uinvm()
|
|
var s1 = BN.n.sub(BN.fromBuffer(message)).umul(rInv).ureduce()
|
|
var s2 = sigs.umul(rInv).ureduce()
|
|
var point = ECPoint.fromECJPoint(g.mulAdd(s1, kp, s2))
|
|
return point.toPublicKey(compressed)
|
|
} while (false)
|
|
|
|
throw new Error(messages.ECDSA_RECOVER_FAIL)
|
|
}
|
|
|
|
exports.ecdh = function (publicKey, privateKey) {
|
|
var shared = exports.ecdhUnsafe(publicKey, privateKey, true)
|
|
return createHash('sha256').update(shared).digest()
|
|
}
|
|
|
|
exports.ecdhUnsafe = function (publicKey, privateKey, compressed) {
|
|
var point = ECPoint.fromPublicKey(publicKey)
|
|
if (point === null) throw new Error(messages.EC_PUBLIC_KEY_PARSE_FAIL)
|
|
|
|
var scalar = BN.fromBuffer(privateKey)
|
|
if (scalar.isOverflow() || scalar.isZero()) throw new Error(messages.ECDH_FAIL)
|
|
|
|
return point.mul(scalar).toPublicKey(compressed)
|
|
}
|