Comparing version 3.0.4 to 3.1.0
@@ -127,3 +127,4 @@ 'use strict'; | ||
var r = kp.getX().mod(this.n); | ||
var kpX = kp.getX(); | ||
var r = kpX.mod(this.n); | ||
if (r.cmpn(0) === 0) | ||
@@ -140,3 +141,6 @@ continue; | ||
return new Signature({ r: r, s: s }); | ||
var recoveryParam = (kp.getY().isOdd() ? 1 : 0) | | ||
(kpX.cmp(r) !== 0 ? 2 : 0); | ||
return new Signature({ r: r, s: s, recoveryParam: recoveryParam }); | ||
} while (true); | ||
@@ -169,1 +173,40 @@ }; | ||
}; | ||
EC.prototype.recoverPubKey = function(msg, signature, j, enc) { | ||
assert((3 & j) === j, 'The recovery param is more than two bits'); | ||
signature = new Signature(signature, enc); | ||
var n = this.n; | ||
var e = new bn(msg); | ||
var r = signature.r; | ||
var s = signature.s; | ||
// A set LSB signifies that the y-coordinate is odd | ||
var isYOdd = j & 1; | ||
var isSecondKey = j >> 1; | ||
if (r.cmp(this.curve.p.mod(this.curve.n)) >= 0 && isSecondKey) | ||
throw new Error('Unable to find sencond key candinate'); | ||
// 1.1. Let x = r + jn. | ||
r = this.curve.pointFromX(isYOdd, r); | ||
var eNeg = e.neg().mod(n); | ||
// 1.6.1 Compute Q = r^-1 (sR - eG) | ||
// Q = r^-1 (sR + -eG) | ||
var rInv = signature.r.invm(n); | ||
return r.mul(s).add(this.g.mul(eNeg)).mul(rInv); | ||
}; | ||
EC.prototype.getKeyRecoveryParam = function(e, signature, Q, enc) { | ||
signature = new Signature(signature, enc); | ||
if (signature.recoveryParam !== null) | ||
return signature.recoveryParam; | ||
for (var i = 0; i < 4; i++) { | ||
var Qprime = this.recoverPubKey(e, signature, i); | ||
if (Qprime.eq(Q)) | ||
return i; | ||
} | ||
throw new Error('Unable to find valid recovery factor'); | ||
}; |
@@ -19,2 +19,6 @@ 'use strict'; | ||
this.s = new bn(options.s, 16); | ||
if (options.recoveryParam !== null) | ||
this.recoveryParam = options.recoveryParam; | ||
else | ||
this.recoveryParam = null; | ||
} | ||
@@ -47,2 +51,3 @@ module.exports = Signature; | ||
this.s = new bn(data.slice(4 + rlen + 2, 4 + rlen + 2 + slen)); | ||
this.recoveryParam = null; | ||
@@ -49,0 +54,0 @@ return true; |
{ | ||
"name": "elliptic", | ||
"version": "3.0.4", | ||
"version": "3.1.0", | ||
"description": "EC cryptography", | ||
@@ -33,3 +33,3 @@ "main": "lib/elliptic.js", | ||
"dependencies": { | ||
"bn.js": "^2.0.0", | ||
"bn.js": "^2.0.3", | ||
"brorand": "^1.0.1", | ||
@@ -36,0 +36,0 @@ "hash.js": "^1.0.0", |
@@ -210,2 +210,12 @@ var assert = require('assert'); | ||
}); | ||
it('should recover the public key from a signature', function(){ | ||
var ec = new elliptic.ec('secp256k1'); | ||
var key = ec.genKeyPair(); | ||
var msg = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]; | ||
var signature = key.sign(msg); | ||
var recid = ec.getKeyRecoveryParam(msg, signature, key.getPublic()); | ||
var r = ec.recoverPubKey(msg, signature, recid); | ||
assert(key.getPublic().eq(r), 'the keys should match'); | ||
}); | ||
}); |
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
145233
3737
Updatedbn.js@^2.0.3