Skip to content
This repository has been archived by the owner on Jun 26, 2024. It is now read-only.

Commit

Permalink
BigInteger: add support for division and negation
Browse files Browse the repository at this point in the history
Needed by noble-curves (secp256k1).
Also, mark `BigInteger.toUint8Array` params as optional in TS.
  • Loading branch information
larabr committed Jul 19, 2023
1 parent 6f5caf1 commit 46f2c70
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 2 deletions.
24 changes: 24 additions & 0 deletions src/biginteger/bn.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,24 @@ export default class BNBigInteger extends AbstractBigInteger {
return new BNBigInteger(this.value.invm(n.value));
}

/**
* BigInteger division, in place
* @param {BigInteger} n - Value to divide
*/
idiv(n: BNBigInteger) {
this.value = this.value.div(n.value);
return this;
}

/**
* BigInteger division
* @param {BigInteger} n - Value to divide
* @returns {BigInteger} this divded by n.
*/
div(n: BNBigInteger) {
return this.clone().idiv(n);
}

/**
* Compute greatest common divisor between this and n
* @param {BigInteger} n - Operand
Expand Down Expand Up @@ -302,6 +320,12 @@ export default class BNBigInteger extends AbstractBigInteger {
return res;
}

negate() {
const res = this.clone();
res.value.ineg();
return res;
}

/**
* Get this value as a string
* @returns {String} this value.
Expand Down
17 changes: 16 additions & 1 deletion src/biginteger/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,19 @@ abstract class BigInteger {
* @throws {Error} if the inverse does not exist
*/
abstract modInv(n: BigInteger): BigInteger;

/**
* BigInteger division, in place
* @param {BigInteger} n - Value to divide
*/
abstract idiv(n: BigInteger): BigInteger;

/**
* BigInteger division
* @param {BigInteger} n - Value to divide
* @returns {BigInteger} this divded by n.
*/
abstract div(n: BigInteger): BigInteger;

/**
* Compute greatest common divisor between this and n
Expand Down Expand Up @@ -192,6 +205,8 @@ abstract class BigInteger {

abstract abs(): BigInteger;

abstract negate(): BigInteger;

/**
* Get this value as a string
* @returns {String} this value.
Expand Down Expand Up @@ -235,7 +250,7 @@ abstract class BigInteger {
* @param {Number} length - Of output array
* @returns {Uint8Array}
*/
abstract toUint8Array(endian: string, length: number): Uint8Array;
abstract toUint8Array(endian?: string, length?: number): Uint8Array;
}

export { BigInteger, ConcreteBigInteger, BigInteger as default };
24 changes: 24 additions & 0 deletions src/biginteger/native.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,24 @@ export default class NativeBigInteger extends AbstractBigInteger {
return x.add(n).mod(n);
}

/**
* BigInteger division, in place
* @param {BigInteger} n - Value to divide
*/
idiv(n: NativeBigInteger) {
this.value /= n.value;
return this;
}

/**
* BigInteger division
* @param {BigInteger} n - Value to divide
* @returns {BigInteger} this divded by n.
*/
div(n: NativeBigInteger) {
return this.clone().idiv(n);
}

/**
* Extended Eucleadian algorithm (http://anh.cs.luc.edu/331/notes/xgcd.pdf)
* Given a = this and b, compute (x, y) such that ax + by = gdc(a, b)
Expand Down Expand Up @@ -371,6 +389,12 @@ export default class NativeBigInteger extends AbstractBigInteger {
return res;
}

negate() {
const res = this.clone();
res.value = -res.value;
return res;
}

/**
* Get this value as a string
* @returns {String} this value.
Expand Down
11 changes: 10 additions & 1 deletion test/biginteger.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ function bigIntegerTests (implementation) {
should('binary operators are consistent', function() {
const a = BigInteger.new(12);
const b = BigInteger.new(34);
const ops = ['add', 'sub', 'mul', 'mod', 'leftShift', 'rightShift'];
const ops = ['add', 'sub', 'mul', 'div', 'mod', 'leftShift', 'rightShift'];
ops.forEach(op => {
const iop = `i${op}`;
ok(a[op](b).equal(a[iop](b)));
Expand All @@ -124,9 +124,18 @@ function bigIntegerTests (implementation) {

should('unary operators are consistent', function() {
const a = BigInteger.new(12);
const zero = BigInteger.new(0);
const one = BigInteger.new(1);
ok(a.sub(one).equal(a.dec()));
ok(a.add(one).equal(a.inc()));

ok(a.negate().isNegative() === true);
ok(a.negate().abs().isNegative() === false);

ok(a.negate().equal( zero.sub(a) ));
ok(a.negate().negate().equal(a));
ok(a.negate().abs().equal(a));
ok(a.abs().equal(a));
});

should('modExp is correct (large values)', function() {
Expand Down

0 comments on commit 46f2c70

Please sign in to comment.