mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-11-21 04:35:49 +00:00
Added Jacobi functionality, more bn features - plus tests.
This commit is contained in:
@@ -40,7 +40,8 @@ module.exports = function(grunt) {
|
||||
"src/js/sjcl-custom/sjcl-ripemd160.js",
|
||||
"src/js/sjcl-custom/sjcl-extramath.js",
|
||||
"src/js/sjcl-custom/sjcl-validecc.js",
|
||||
"src/js/sjcl-custom/sjcl-ecdsa-der.js"
|
||||
"src/js/sjcl-custom/sjcl-ecdsa-der.js",
|
||||
"src/js/sjcl-custom/sjcl-jacobi.js"
|
||||
],
|
||||
dest: 'build/sjcl.js'
|
||||
}
|
||||
|
||||
@@ -45,8 +45,8 @@ sjcl.bn.prototype.div = function (that) {
|
||||
};
|
||||
|
||||
sjcl.bn.prototype.sign = function () {
|
||||
return this.greaterEquals(sjcl.bn.ZERO) ? 1 : -1;
|
||||
};
|
||||
return this.greaterEquals(sjcl.bn.ZERO) ? 1 : -1;
|
||||
};
|
||||
|
||||
/** -this */
|
||||
sjcl.bn.prototype.neg = function () {
|
||||
@@ -59,3 +59,79 @@ sjcl.bn.prototype.abs = function () {
|
||||
return this.neg();
|
||||
} else return this;
|
||||
};
|
||||
|
||||
/** this >> that */
|
||||
sjcl.bn.prototype.shiftRight = function (that) {
|
||||
if ("number" !== typeof that) {
|
||||
throw new Error("shiftRight expects a number");
|
||||
}
|
||||
|
||||
that = +that;
|
||||
|
||||
if (that < 0) {
|
||||
return this.shiftLeft(that);
|
||||
}
|
||||
|
||||
var a = new sjcl.bn(this);
|
||||
|
||||
while (that--) {
|
||||
a.halveM();
|
||||
}
|
||||
|
||||
return a;
|
||||
};
|
||||
|
||||
/** this >> that */
|
||||
sjcl.bn.prototype.shiftLeft = function (that) {
|
||||
if ("number" !== typeof that) {
|
||||
throw new Error("shiftLeft expects a number");
|
||||
}
|
||||
|
||||
that = +that;
|
||||
|
||||
if (that < 0) {
|
||||
return this.shiftRight(that);
|
||||
}
|
||||
|
||||
var a = new sjcl.bn(this);
|
||||
|
||||
while (that--) {
|
||||
a.doubleM();
|
||||
}
|
||||
|
||||
return a;
|
||||
};
|
||||
|
||||
/** (int)this */
|
||||
// NOTE Truncates to 32-bit integer
|
||||
sjcl.bn.prototype.toNumber = function () {
|
||||
return this.limbs[0] | 0;
|
||||
};
|
||||
|
||||
/** find n-th bit, 0 = LSB */
|
||||
sjcl.bn.prototype.testBit = function (bitIndex) {
|
||||
var limbIndex = Math.floor(bitIndex / this.radix);
|
||||
var bitIndexInLimb = bitIndex % this.radix;
|
||||
|
||||
if (limbIndex >= this.limbs.length) return 0;
|
||||
|
||||
return (this.limbs[limbIndex] >>> bitIndexInLimb) & 1;
|
||||
};
|
||||
|
||||
/** set n-th bit, 0 = LSB */
|
||||
sjcl.bn.prototype.setBitM = function (bitIndex) {
|
||||
var limbIndex = Math.floor(bitIndex / this.radix);
|
||||
var bitIndexInLimb = bitIndex % this.radix;
|
||||
|
||||
while (limbIndex >= this.limbs.length) this.limbs.push(0);
|
||||
|
||||
this.limbs[limbIndex] |= 1 << bitIndexInLimb;
|
||||
|
||||
this.cnormalize();
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
sjcl.bn.prototype.modInt = function (n) {
|
||||
return this.toNumber() % n;
|
||||
};
|
||||
|
||||
45
src/js/sjcl-custom/sjcl-jacobi.js
Normal file
45
src/js/sjcl-custom/sjcl-jacobi.js
Normal file
@@ -0,0 +1,45 @@
|
||||
sjcl.bn.prototype.jacobi = function (that) {
|
||||
var a = this;
|
||||
that = new sjcl.bn(that);
|
||||
|
||||
if (that.sign() === -1) return;
|
||||
|
||||
// 1. If a = 0 then return(0).
|
||||
if (a.equals(0)) { return 0; }
|
||||
|
||||
// 2. If a = 1 then return(1).
|
||||
if (a.equals(1)) { return 1; }
|
||||
|
||||
var s = 0;
|
||||
|
||||
// 3. Write a = 2^e * a1, where a1 is odd.
|
||||
var e = 0;
|
||||
while (!a.testBit(e)) e++;
|
||||
var a1 = a.shiftRight(e);
|
||||
|
||||
// 4. If e is even then set s ← 1.
|
||||
if ((e & 1) === 0) {
|
||||
s = 1;
|
||||
} else {
|
||||
var residue = that.modInt(8);
|
||||
|
||||
if (residue === 1 || residue === 7) {
|
||||
// Otherwise set s ← 1 if n ≡ 1 or 7 (mod 8)
|
||||
s = 1;
|
||||
} else if (residue === 3 || residue === 5) {
|
||||
// Or set s ← −1 if n ≡ 3 or 5 (mod 8).
|
||||
s = -1;
|
||||
}
|
||||
}
|
||||
|
||||
// 5. If n ≡ 3 (mod 4) and a1 ≡ 3 (mod 4) then set s ← −s.
|
||||
if (that.modInt(4) === 3 && a1.modInt(4) === 3) {
|
||||
s = -s;
|
||||
}
|
||||
|
||||
if (a1.equals(1)) {
|
||||
return s;
|
||||
} else {
|
||||
return s * that.mod(a1).jacobi(a1);
|
||||
}
|
||||
};
|
||||
39
test/sjcl-extramath-test.js
Normal file
39
test/sjcl-extramath-test.js
Normal file
@@ -0,0 +1,39 @@
|
||||
var assert = require('assert');
|
||||
var utils = require('./testutils');
|
||||
var sjcl = require('../build/sjcl');
|
||||
|
||||
describe('SJCL Extramath', function() {
|
||||
describe('setBitM', function() {
|
||||
it('0x0f set bit 4 => 0x1f', function () {
|
||||
var val = new sjcl.bn("0f");
|
||||
val.setBitM(4);
|
||||
assert.strictEqual(val.toString(), '0x1f');
|
||||
});
|
||||
it('0x0f set bit 23 => 0x80000f', function () {
|
||||
var val = new sjcl.bn("0f");
|
||||
val.setBitM(23);
|
||||
assert.strictEqual(val.toString(), '0x80000f');
|
||||
});
|
||||
it('0x0f set bit 24 => 0x100000f', function () {
|
||||
var val = new sjcl.bn("0f");
|
||||
val.setBitM(24);
|
||||
assert.strictEqual(val.toString(), '0x100000f');
|
||||
});
|
||||
});
|
||||
describe('testBit', function() {
|
||||
it('0x03 test bit 0 => 1', function () {
|
||||
var val = new sjcl.bn("03");
|
||||
assert.strictEqual(val.testBit(0), 1);
|
||||
});
|
||||
it('0x03 test bit 1 => 1', function () {
|
||||
var val = new sjcl.bn("03");
|
||||
assert.strictEqual(val.testBit(1), 1);
|
||||
});
|
||||
it('0x03 test bit 2 => 0', function () {
|
||||
var val = new sjcl.bn("03");
|
||||
assert.strictEqual(val.testBit(2), 0);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// vim:sw=2:sts=2:ts=8:et
|
||||
48
test/sjcl-jacobi-test.js
Normal file
48
test/sjcl-jacobi-test.js
Normal file
@@ -0,0 +1,48 @@
|
||||
var assert = require('assert');
|
||||
var utils = require('./testutils');
|
||||
var sjcl = require('../build/sjcl');
|
||||
|
||||
describe('SJCL Jacobi', function() {
|
||||
it('(15/13) = -1', function () {
|
||||
var jac = new sjcl.bn(15).jacobi(13);
|
||||
assert.strictEqual(jac, -1);
|
||||
});
|
||||
it('(4/97) = 1', function () {
|
||||
var jac = new sjcl.bn(4).jacobi(97);
|
||||
assert.strictEqual(jac, 1);
|
||||
});
|
||||
it('(17/17) = 0', function () {
|
||||
var jac = new sjcl.bn(17).jacobi(17);
|
||||
assert.strictEqual(jac, 0);
|
||||
});
|
||||
it('(34/17) = 0', function () {
|
||||
var jac = new sjcl.bn(34).jacobi(17);
|
||||
assert.strictEqual(jac, 0);
|
||||
});
|
||||
it('(19/45) = 1', function () {
|
||||
var jac = new sjcl.bn(19).jacobi(45);
|
||||
assert.strictEqual(jac, 1);
|
||||
});
|
||||
it('(8/21) = -1', function () {
|
||||
var jac = new sjcl.bn(8).jacobi(21);
|
||||
assert.strictEqual(jac, -1);
|
||||
});
|
||||
it('(5/21) = 1', function () {
|
||||
var jac = new sjcl.bn(5).jacobi(21);
|
||||
assert.strictEqual(jac, 1);
|
||||
});
|
||||
it('(1001/9907) = -1', function () {
|
||||
var jac = new sjcl.bn(1001).jacobi(9907);
|
||||
assert.strictEqual(jac, -1);
|
||||
});
|
||||
it('(1236/20003) = 1', function () {
|
||||
var jac = new sjcl.bn(1236).jacobi(20003);
|
||||
assert.strictEqual(jac, 1);
|
||||
});
|
||||
it('With huge numbers', function () {
|
||||
var jac = new sjcl.bn("217033ffbc5a462201407027104916c5e7bf09f2b0c926f7c5cb20858be29d92e7fe67080eeb268fcbc2bc44d9cecfe1d3acbb302111eba355a8b769ed4bdbf773d37dca47e2293c173ff4f84b38f4e84bfad7cc1a913d70e11cf664a95575b80ec9d10123289b402ad2c71c70f2dc28360262d3d703faa964c741a711e4eebd324d659601dd14564fcd8c5908bbf8c97cf3ff82f083da3005848b48cb545b31be2039cca1d67714f32d32b3228c1a659415ee6c138ca274f789006a90a9a41bbc3934b84c78948eae8351f45696fa716b1328561f4c3bbb44ac73112c291b6b4587365e44fa09d583fb8074eb35bf947231e500c0d2c79c5fb957e50e84f6c9").jacobi("c7f1bc1dfb1be82d244aef01228c1409c198894eca9e21430f1669b4aa3864c9f37f3d51b2b4ba1ab9e80f59d267fda1521e88b05117993175e004543c6e3611242f24432ce8efa3b81f0ff660b4f91c5d52f2511a6f38181a7bf9abeef72db056508bbb4eeb5f65f161dd2d5b439655d2ae7081fcc62fdcb281520911d96700c85cdaf12e7d1f15b55ade867240722425198d4ce39019550c4c8a921fc231d3e94297688c2d77cd68ee8fdeda38b7f9a274701fef23b4eaa6c1a9c15b2d77f37634930386fc20ec291be95aed9956801e1c76601b09c413ad915ff03bfdc0b6b233686ae59e8caf11750b509ab4e57ee09202239baee3d6e392d1640185e1cd");
|
||||
assert.strictEqual(jac, -1);
|
||||
});
|
||||
});
|
||||
|
||||
// vim:sw=2:sts=2:ts=8:et
|
||||
Reference in New Issue
Block a user