BigInteger: throw if modular inverse doesn't exist (#1228)
This commit is contained in:
parent
ca092c7cd0
commit
051f5ec8cf
|
@ -28,7 +28,7 @@ export default class BigInteger {
|
||||||
* BigInteger increment in place
|
* BigInteger increment in place
|
||||||
*/
|
*/
|
||||||
iinc() {
|
iinc() {
|
||||||
this.value.iadd(one.value);
|
this.value.iadd(new BN(1));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ export default class BigInteger {
|
||||||
* BigInteger decrement in place
|
* BigInteger decrement in place
|
||||||
*/
|
*/
|
||||||
idec() {
|
idec() {
|
||||||
this.value.isub(one.value);
|
this.value.isub(new BN(1));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,8 +151,13 @@ export default class BigInteger {
|
||||||
* Note: this and and n must be relatively prime
|
* Note: this and and n must be relatively prime
|
||||||
* @param {BigInteger} n modulo
|
* @param {BigInteger} n modulo
|
||||||
* @return {BigInteger} x such that this*x = 1 mod n
|
* @return {BigInteger} x such that this*x = 1 mod n
|
||||||
|
* @throws {Error} if the inverse does not exist
|
||||||
*/
|
*/
|
||||||
modInv(n) {
|
modInv(n) {
|
||||||
|
// invm returns a wrong result if the inverse does not exist
|
||||||
|
if (!this.gcd(n).isOne()) {
|
||||||
|
throw new Error('Inverse does not exist');
|
||||||
|
}
|
||||||
return new BigInteger(this.value.invm(n.value));
|
return new BigInteger(this.value.invm(n.value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,7 +256,7 @@ export default class BigInteger {
|
||||||
}
|
}
|
||||||
|
|
||||||
isOne() {
|
isOne() {
|
||||||
return this.equal(one);
|
return this.value.eq(new BN(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
isNegative() {
|
isNegative() {
|
||||||
|
@ -320,5 +325,3 @@ export default class BigInteger {
|
||||||
return this.value.toArrayLike(Uint8Array, endian, length);
|
return this.value.toArrayLike(Uint8Array, endian, length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const one = new BigInteger(1);
|
|
||||||
|
|
|
@ -175,9 +175,14 @@ export default class BigInteger {
|
||||||
* Note: this and and n must be relatively prime
|
* Note: this and and n must be relatively prime
|
||||||
* @param {BigInteger} n modulo
|
* @param {BigInteger} n modulo
|
||||||
* @return {BigInteger} x such that this*x = 1 mod n
|
* @return {BigInteger} x such that this*x = 1 mod n
|
||||||
|
* @throws {Error} if the inverse does not exist
|
||||||
*/
|
*/
|
||||||
modInv(n) {
|
modInv(n) {
|
||||||
return this._egcd(n).x.add(n).mod(n);
|
const { gcd, x } = this._egcd(n);
|
||||||
|
if (!gcd.isOne()) {
|
||||||
|
throw new Error('Inverse does not exist');
|
||||||
|
}
|
||||||
|
return x.add(n).mod(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -149,6 +149,7 @@ module.exports = () => describe('BigInteger interface', function() {
|
||||||
const n = new BigInteger(moduloBN.toString());
|
const n = new BigInteger(moduloBN.toString());
|
||||||
const expected = baseBN.invm(moduloBN);
|
const expected = baseBN.invm(moduloBN);
|
||||||
expect(a.modInv(n).toString()).to.equal(expected.toString());
|
expect(a.modInv(n).toString()).to.equal(expected.toString());
|
||||||
|
expect(() => a.mul(n).modInv(n)).to.throw('Inverse does not exist');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('getBit is correct', async function() {
|
it('getBit is correct', async function() {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user