mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-11-20 12:15:51 +00:00
Added Jacobi functionality, more bn features - plus tests.
This commit is contained in:
@@ -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);
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user