Skip to content

Commit

Permalink
curve: throw on missing quadratic residue
Browse files Browse the repository at this point in the history
  • Loading branch information
indutny committed Jan 24, 2016
1 parent 6d25d37 commit 8d02ee5
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 3 deletions.
6 changes: 5 additions & 1 deletion lib/elliptic/curve/edwards.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,11 @@ EdwardsCurve.prototype.pointFromX = function pointFromX(x, odd) {
var rhs = this.c2.redSub(this.a.redMul(x2));
var lhs = this.one.redSub(this.c2.redMul(this.d).redMul(x2));

var y = rhs.redMul(lhs.redInvm()).redSqrt();
var y2 = rhs.redMul(lhs.redInvm());
var y = y2.redSqrt();
if (y.redSqr().redSub(y2).cmp(this.zero) !== 0)
throw new Error('invalid point');

var isOdd = y.fromRed().isOdd();
if (odd && !isOdd || !odd && isOdd)
y = y.redNeg();
Expand Down
2 changes: 2 additions & 0 deletions lib/elliptic/curve/short.js
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,8 @@ ShortCurve.prototype.pointFromX = function pointFromX(x, odd) {

var y2 = x.redSqr().redMul(x).redIAdd(x.redMul(this.a)).redIAdd(this.b);
var y = y2.redSqrt();
if (y.redSqr().redSub(y2).cmp(this.zero) !== 0)
throw new Error('invalid point');

// XXX Is there any way to tell if the number is odd without converting it
// to non-red form?
Expand Down
7 changes: 6 additions & 1 deletion lib/elliptic/ec/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,12 @@ EC.prototype.getKeyRecoveryParam = function(e, signature, Q, enc) {
return signature.recoveryParam;

for (var i = 0; i < 4; i++) {
var Qprime = this.recoverPubKey(e, signature, i);
var Qprime;
try {
Qprime = this.recoverPubKey(e, signature, i);
} catch (e) {
continue;
}

if (Qprime.eq(Q))
return i;
Expand Down
2 changes: 1 addition & 1 deletion lib/elliptic/ec/signature.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ function Signature(options, enc) {
assert(options.r && options.s, 'Signature without r or s');
this.r = new BN(options.r, 16);
this.s = new BN(options.s, 16);
if (options.recoveryParam !== null)
if (options.recoveryParam)
this.recoveryParam = options.recoveryParam;
else
this.recoveryParam = null;
Expand Down
15 changes: 15 additions & 0 deletions test/ecdsa-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -367,4 +367,19 @@ describe('ECDSA', function() {
var r = ec.recoverPubKey(msg, signature, recid);
assert(key.getPublic().eq(r), 'the keys should match');
});

it('should fail to recover key when no quadratic residue available',
function() {
var ec = new elliptic.ec('secp256k1');

var message =
'f75c6b18a72fabc0f0b888c3da58e004f0af1fe14f7ca5d8c897fe164925d5e9';

assert.throws(function() {
ecdsa.recoverPubKey(message, {
r: 'fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140',
s: '8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3',
}, 0);
});
});
});

0 comments on commit 8d02ee5

Please sign in to comment.