Skip to content

Commit ca5b027

Browse files
authored
Merge pull request #648 from Kr0emer/fix/bug-004-modinverse-dos
fix(jsbn2): prevent modInverse hangs on zero and negative inputs
2 parents dc41d49 + 7a3ae70 commit ca5b027

File tree

2 files changed

+19
-4
lines changed

2 files changed

+19
-4
lines changed

ext/jsbn2.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -508,15 +508,17 @@ function bnpModInt(n) {
508508

509509
// (public) 1/this % m (HAC 14.61)
510510
function bnModInverse(m) {
511+
if(m.signum() == 0) return BigInteger.ZERO;
512+
var x = this.mod(m);
511513
var ac = m.isEven();
512-
if((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO;
513-
var u = m.clone(), v = this.clone();
514+
if((x.isEven() && ac) || x.signum() == 0) return BigInteger.ZERO;
515+
var u = m.clone(), v = x.clone();
514516
var a = nbv(1), b = nbv(0), c = nbv(0), d = nbv(1);
515517
while(u.signum() != 0) {
516518
while(u.isEven()) {
517519
u.rShiftTo(1,u);
518520
if(ac) {
519-
if(!a.isEven() || !b.isEven()) { a.addTo(this,a); b.subTo(m,b); }
521+
if(!a.isEven() || !b.isEven()) { a.addTo(x,a); b.subTo(m,b); }
520522
a.rShiftTo(1,a);
521523
}
522524
else if(!b.isEven()) b.subTo(m,b);
@@ -525,7 +527,7 @@ function bnModInverse(m) {
525527
while(v.isEven()) {
526528
v.rShiftTo(1,v);
527529
if(ac) {
528-
if(!c.isEven() || !d.isEven()) { c.addTo(this,c); d.subTo(m,d); }
530+
if(!c.isEven() || !d.isEven()) { c.addTo(x,c); d.subTo(m,d); }
529531
c.rShiftTo(1,c);
530532
}
531533
else if(!d.isEven()) d.subTo(m,d);

test/qunit-do-crypto.html

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,19 @@
257257
"reject mod(0)");
258258
});
259259

260+
test("BigInteger.modInverse returns quickly for zero input", function() {
261+
var biM = new BigInteger("97", 10);
262+
var biR = new BigInteger("0", 10).modInverse(biM);
263+
equal(biR.compareTo(BigInteger.ZERO), 0, "0 has no inverse");
264+
});
265+
266+
test("BigInteger.modInverse normalizes negative input", function() {
267+
var biM1 = new BigInteger("7", 10);
268+
var biM2 = new BigInteger("97", 10);
269+
equal(new BigInteger("-1", 10).modInverse(biM1).toString(10), "6", "-1 mod 7");
270+
equal(new BigInteger("-13", 10).modInverse(biM2).toString(10), "82", "-13 mod 97");
271+
});
272+
260273
test("MessageDigest test", function() {
261274
expect(10);
262275
var md1 = new KJUR.crypto.MessageDigest({"alg": "sha1", "prov": "cryptojs"});

0 commit comments

Comments
 (0)