Quinn Slack 15 лет назад
Родитель
Сommit
2bbda850b1
3 измененных файлов с 93 добавлено и 0 удалено
  1. 15 0
      core/bn.js
  2. 22 0
      test/bn_test.js
  3. 56 0
      test/bn_vectors.js

+ 15 - 0
core/bn.js

@@ -275,6 +275,21 @@ sjcl.bn.prototype = {
     return out;
   },
 
+  mulmod: function(x, N) {
+    return this.mod(N).mul(x.mod(N)).mod(N);
+  },
+
+  powermod: function(x, N) {
+    var result = new sjcl.bn(1), a = new sjcl.bn(this), k = new sjcl.bn(x);
+    while (true) {
+      if (k.limbs[0] & 1) { result = result.mulmod(a, N); }
+      k.halveM();
+      if (k.equals(0)) { break; }
+      a = a.mulmod(a, N);
+    }
+    return result.normalize().reduce();
+  },
+
   trim: function() {
     var l = this.limbs, p;
     do {

+ 22 - 0
test/bn_test.js

@@ -0,0 +1,22 @@
+new sjcl.test.TestCase("Bignum modular exponentiation test", function (cb) {
+  if (!sjcl.bn) {
+    this.unimplemented();
+    cb && cb();
+    return;
+  }
+  
+  var i, tv, g, x, N, v;
+  for (i=0; i < sjcl.test.vector.bn_powermod.length; i++) {
+    tv = sjcl.test.vector.bn_powermod[i];
+    try {
+      g = new sjcl.bn(tv.g);
+      x = new sjcl.bn(tv.x);
+      N = new sjcl.bn(tv.N);
+      v = g.powermod(x, N);
+      this.require(v.equals(new sjcl.bn(tv.v)));
+    } catch(e) {
+      this.fail(e);
+    }
+  }
+  cb && cb();
+});

+ 56 - 0
test/bn_vectors.js

@@ -0,0 +1,56 @@
+sjcl.test.vector.bn_powermod = [
+  {
+    g: 2,
+    x: 3,
+    N: 3,
+    v: 2
+  },
+  {
+    g: 2,
+    x: "10000000000000000000000000",
+    N: 1337,
+    v: 1206
+  },
+  {
+    g: 17,
+    x: 90,
+    N: 34717861147,
+    v: 28445204336
+  },
+  {
+    g: 2,
+    x: "0x844A000000000000000000000",
+    N: 13,
+    v: 9
+  },
+  {
+    g: 2,
+    x: 0x1010,
+    N: 131,
+    v: 59
+  },  
+  {
+    g: 2,
+    x: "43207437777777877617151",
+    N: 13,
+    v: 2
+  },
+  {
+    g: 2,
+    x: "389274238947216444871600001871964319565192765874149",
+    N: 117,
+    v: 44
+  },
+  {
+    g: 2,
+    x: "89457115510016156219817846189181057618965150496979174671534084187",
+    N: "1897166415676096761",
+    v: "16840615e646a4c5c8d"
+  },
+  {
+    g: 2,
+    x: "94B7555AABE9127CC58CCF4993DB6CF84D16C124",
+    N: "EEAF0AB9ADB38DD69C33F80AFA8FC5E86072618775FF3C0B9EA2314C9C256576D674DF7496EA81D3383B4813D692C6E0E0D5D8E250B98BE48E495C1D6089DAD15DC7D7B46154D6B6CE8EF4AD69B15D4982559B297BCF1885C529F566660E57EC68EDBC3C05726CC02FD4CBF4976EAA9AFD5138FE8376435B9FC61D2FC0EB06E3",
+    v: "7E273DE8696FFC4F4E337D05B4B375BEB0DDE1569E8FA00A9886D8129BADA1F1822223CA1A605B530E379BA4729FDC59F105B4787E5186F5C671085A1447B52A48CF1970B4FB6F8400BBF4CEBFBB168152E08AB5EA53D15C1AFF87B2B9DA6E04E058AD51CC72BFC9033B564E26480D78E955A5E29E7AB245DB2BE315E2099AFB"
+  }
+]