Home Manual Reference Source

Function

Static Public Summary
public

add(r: Number, a: Array, ai: Number, aj: Number, b: Array, bi: Number, bj: Number, c: Array, ci: Number, cj: Number): *

Adds two big endian arrays and puts result in a destination array.

public

cmp(a: number[], ai: number, aj: number, b: number[], bi: number, bj: number): number

Compares two big endian arrays with little constraints on the operands.

public

convert(f: number, t: number, a: number[], ai: number, aj: number): number[]

Converts the input number A represented in base f to a number B represented in base t.

public

Converts the input number A represented in base f to a number B represented in base t.

public

decrement(r: Number, a: Array, ai: Number, aj: Number)

Subtracts 1 from a big endian array.

public

eq(a: number[], ai: number, aj: number, b: number[], bi: number, bj: number): boolean

Tests whether two big endian arrays are equal.

public

euclidean_algorithm(r: Number, a: Array, ai: Number, aj: Number, b: Array, bi: Number, bj: Number): Array

No constraints on the input.

public

No constraints on the input.

public

ge(a: number[], ai: number, aj: number, b: number[], bi: number, bj: number): boolean

Compares two big endian arrays: returns true if the first is greater or equal to the second.

public

gt(a: number[], ai: number, aj: number, b: number[], bi: number, bj: number): boolean

Compares two big endian arrays: returns true if the first is greater than the second.

public

iadd(r: Number, a: Array, ai: Number, aj: Number, b: Array, bi: Number, bj: Number): *

Adds a big endian array to another in-place.

public

increment(r: Number, a: Array, ai: Number, aj: Number)

Adds 1 to a big endian array.

public

jz(a: number[], ai: number, aj: number): boolean

Returns true if and only if input number A is 0.

public

le(a: number[], ai: number, aj: number, b: number[], bi: number, bj: number): boolean

Compares two big endian arrays: returns true if the first is less or equal to the second.

public

lt(a: number[], ai: number, aj: number, b: number[], bi: number, bj: number): boolean

Compares two big endian arrays: returns true if the first is less than the second.

public

mul(r: Number, a: Array, ai: Number, aj: Number, b: Array, bi: Number, bj: Number, c: Array, ci: Number, cj: Number): *

Multiplies two big endian arrays and puts result in a destination array.

public

ne(a: number[], ai: number, aj: number, b: number[], bi: number, bj: number): boolean

Tests whether two big endian arrays are not equal.

public

parse(f: number, t: number, string: string): number[]

Converts a string representation in base f to a limb array in base t.

public

Converts a string representation in base f to a limb array in base t keeping all leading zeros resulting from the conversion process.

public

stringify(f: number, t: number, a: number[], ai: number, aj: number): string

Converts a limb array in base f to a string representation in base t.

public

translate(f: number, t: number, string: string): string

Converts a string representation in base f to a string representation in base t.

public

trim_natural(a: number[], ai: number, aj: number): number[]

Trim a limb array so that it is either [0] or does not start with any leading zeros.

Static Private Summary
private

_add(r: Number, a: Array, ai: Number, aj: Number, b: Array, bi: Number, bj: Number, c: Array, ci: Number, cj: Number)

Adds two big endian arrays and puts result in a destination array.

private

Allocate a new limb array.

private

_build(base: *, number: *, data: *, n: *): *

private

Converts a limb to a character representation.

private

_cmp(a: number[], ai: number, aj: number, b: number[], bi: number, bj: number): number

Compares two big endian arrays.

private

_cmp_half(r: Number, a: array, ai: Number, aj: Number): Number

Compares a number A with size n = |A| to R = (r^n)/2.

private

_cmp_half_even_radix(_r: *, a: *, ai: *, aj: *): *

private

_cmp_half_odd_radix(_r: *, a: *, ai: *, aj: *): *

private

_cmp_n(a: number[], ai: number, aj: number, b: number[], bi: number): number

Compares two big endian arrays.

private

_convert(f: number, t: number, a: number[], ai: number, aj: number, b: number[], bi: number, bj: number): *

Dispatcher for the various base conversion implementations.

private

_convert_dc(size_small_block: Number, f: Number, t: Number, a: Array, ai: Number, aj: Number, b: Array, bi: Number, bj: Number)

O(M(N) log N) where M(N) is multiplication time complexity.

private

_convert_slow(f: Number, t: Number, a: Array, ai: Number, aj: Number, b: Array, bi: Number, bj: Number): *

F != t

private

_convert_to_larger(f: Number, t: Number, a: Array, ai: Number, aj: Number, b: Array, bi: Number, bj: Number): *

private

_convert_to_larger_fast(ar: Number, z: Number, a: Array, ai: Number, aj: Number, b: Array, bi: Number, bj: Number)

private

_convert_to_larger_slow(f: Number, t: Number, a: Array, ai: Number, aj: Number, b: Array, bi: Number, bj: Number)

O(N^2).

private

_convert_to_smaller(f: Number, t: Number, a: Array, ai: Number, aj: Number, b: Array, bi: Number, bj: Number): *

private

_convert_to_smaller_fast(br: Number, z: Number, a: Array, ai: Number, aj: Number, b: Array, bi: Number, bj: Number)

private

O(N^2).

private

_copy(a: number[], ai: number, aj: number, b: number[], bi: number)

Copy a limb array into another limb array.

private

_div_limb_with_prefix(r: Number, tmp: Number, d: Number, D: Array, Di: Number, Dj: Number, Q: Array, Qi: Number)

Divides a big endian number by a single limb number.

private

_divmod(r: Number, D: Array, Di: Number, Dj: Number, d: Array, di: Number, dj: Number, Q: Array, Qi: Number, Qj: Number, R: Array, Ri: Number, Rj: Number)

Computes the quotient and remainder of two numbers.

private

Euclidean algorithm.

private

Precondition:

  • A >= B
  • No leading zeroes.
private

M >= n >= 0 m >= 1

private

_extended_euclidean_algorithm_loop(r: *, R0: *, R1: *, S0: *, T0: *, S1: *, T1: *, Q: *, X: *): undefined[]

Extended Euclidean algorithm.

private

_fill(a: number[], ai: number, aj: number, v: number)

Fill the input limb array with a fixed value.

private

_from_string(string: string): number[]

Converts a string representation to a limb array representation without radix conversion.

private

_iadd(r: Number, a: Array, ai: Number, aj: Number, b: Array, bi: Number, bj: Number)

Adds a big endian array to another.

private

_iadd_limb(r: Number, x: Number, a: Array, ai: Number, aj: Number)

Adds single limb to a big endian array.

private

_idivmod(r: Number, D: Array, Di: Number, Dj: Number, d: Array, di: Number, dj: Number, Q: Array, Qi: Number, Qj: Number): *

Computes the quotient and remainder of two numbers.

private

_idivmod_dc(X: Number, a: Array, ai: Number, aj: Number, b: Array, bi: Number, bj: Number, c: Array, ci: Number, cj: Number)

Input

  • No leading zeros
  • |A| = |C|
  • C must be zero-initialized.
private

_idivmod_dc_21(r: *, a: *, ai: *, aj: *, b: *, bi: *, bj: *, c: *, ci: *, cj: *): *

Algorithm 3.3 Divide-and-conquer division (2 by 1)

private

_idivmod_dc_32(r: *, a: *, ai: *, aj: *, b: *, bi: *, bj: *, c: *, ci: *, cj: *)

Algorithm 3.4 Divide-and-conquer division (3 by 2)

private

_idivmod_limb(r: Number, d: Number, D: Array, Di: Number, Dj: Number, Q: Array, Qi: Number): *

Divides a big endian number by a single limb number.

private

Divides a big endian number by a single limb number.

private

_idivmod_schoolbook(r: Number, a: Array, ai: Number, aj: Number, b: Array, bi: Number, bj: Number, q: Array, qi: Number)

Computes q <- a / b and a <- a % b.

private

Input

  • Two integers A and B such that r^(m-1) <= A < r^m and (r^n)/2 <= B < r^(n).
private

Input

  • Two integers A and B such that 0 <= A < β^(n+1) and (β^n)/2 <= B < β^n.
private

Input

  • Two integers A and B such that 0 <= A < B * β and (β^n)/2 <= B < β^n.
private

_idivmod_slow(x: Number, r: array, ri: Number, rj: Number, b: array, bi: Number, bj: Number, q: array, qi: Number)

Computes quotient and remainder of two big endian arrays.

private

_imod(r: Number, D: Array, Di: Number, Dj: Number, d: Array, di: Number, dj: Number, _: Array, _i: Number, _j: Number): *

Computes the remainder of two numbers.

private

_imod_limb(r: Number, d: Number, D: Array, Di: Number, Dj: Number)

Divides a big endian number by a single limb number and writes the remainder to the dividend array.

private

_imod_schoolbook(r: Number, a: Array, ai: Number, aj: Number, b: Array, bi: Number, bj: Number)

Divides a big endian number by another big endian number and writes the remainder to the dividend array.

private

Input

  • Two integers A and B such that r^(m-1) <= A < r^m and (r^n)/2 <= B < r^(n).
private

Input

  • Two integers A and B such that 0 <= A < β^(n+1) and (β^n)/2 <= B < β^n.
private

Input

  • Two integers A and B such that 0 <= A < B * β and (β^n)/2 <= B < β^n.
private

Converts an input character representation to a limb.

private

_isub(r: Number, a: array, ai: Number, aj: Number, b: array, bi: Number, bj: Number)

Subtracts B from A, |A| >= |B|.

private

_karatsuba(r: Number, a: Array, ai: Number, aj: Number, b: Array, bi: Number, bj: Number, c: Array, ci: Number, cj: Number): *

Multiply two big endian arrays using karatsuba algorithm, |A| >= |B| >= 1, |C| >= |A| + |B|, |A| >= 2.

private

_karatsuba_right_op_is_small(r: Number, a: Array, ai: Number, aj: Number, b: Array, bi: Number, bj: Number, c: Array, ci: Number, cj: Number)

Multiply two big endian arrays using karatsuba algorithm, WHEN THE SECOND OPERAND IS SMALL.

private

_log(x: *, y: *): undefined[]

private

_mod_limb(r: Number, d: Number, D: Array, Di: Number, Dj: Number): Number

Divides a big endian number by a single limb number and returns only the remainder.

private

_mul(r: Number, a: Array, ai: Number, aj: Number, b: Array, bi: Number, bj: Number, c: Array, ci: Number, cj: Number): *

Computes C = A+B.

private

_mul_limb(r: *, x: *, b: *, bi: *, bj: *, c: *, ci: *, cj: *)

Compute x * b where x is a single limb.

private

_pow_double(r: Number, x: Number, a: Array, ai: Number, aj: Number, c: Array, ci: Number, cj: Number)

Computes pow(a,x) = a^x using exponentiation by squaring.

private

_pow_double_recursive(r: Number, x: Number, a: Array, ai: Number, aj: Number, c: Array, ci: Number, cj: Number)

Computes pow(a,x) = a^x using exponentiation by squaring.

private

_reset(a: number[], ai: number, aj: number)

Fill the input limb array with zeros.

private

_schoolbook_mul(r: *, a: *, ai: *, aj: *, b: *, bi: *, bj: *, c: *, ci: *, cj: *)

Computes the product of two big endian arrays using schoolbook multiplication.

private

_sub(r: Number, a: array, ai: Number, aj: Number, b: array, bi: Number, bj: Number, c: array, ci: Number, cj: Number)

Subtracts two big endian arrays, |C| >= |A| >= |B|.

private

Convert an entire limb array to a string representation (without changing the radix).

private

Compute the new inclusive left bound of a limb array by skipping all leading zeros.

private

_validate(base: *, a: *, ai: *, aj: *): boolean

private

Allocate a new limb array filled with zeros.

Static Public

public add(r: Number, a: Array, ai: Number, aj: Number, b: Array, bi: Number, bj: Number, c: Array, ci: Number, cj: Number): * source

Adds two big endian arrays and puts result in a destination array. Wraps on overflow. Works with any combination of array sizes.

Params:

NameTypeAttributeDescription
r Number

base (radix)

a Array

first operand

ai Number

a left

aj Number

a right

b Array

second operand

bi Number

b left

bj Number

b right

c Array

result, must be 0 initialized

ci Number

c left

cj Number

c right

Return:

*

public cmp(a: number[], ai: number, aj: number, b: number[], bi: number, bj: number): number source

Compares two big endian arrays with little constraints on the operands.

Input:

  • |A| >= 0
  • |B| >= 0

Params:

NameTypeAttributeDescription
a number[]

first operand

ai number

a left

aj number

a right

b number[]

second operand

bi number

b left

bj number

b right

Return:

number

result 1 if a > b; 0 if a = b; -1 otherwise.

public convert(f: number, t: number, a: number[], ai: number, aj: number): number[] source

Converts the input number A represented in base f to a number B represented in base t. If A is 0 the output is B = [0], otherwise all leading zeros are trimmed.

Params:

NameTypeAttributeDescription
f number

the base to convert from

t number

the base to convert to

a number[]

the origin array

ai number

start offset in the origin array

aj number

end offset in the origin array

Return:

number[]

The result of the conversion.

public convert_keep_zeros(f: number, t: number, a: number[], ai: number, aj: number): number[] source

Converts the input number A represented in base f to a number B represented in base t. All leading zeros resulting from the conversion are kept.

Params:

NameTypeAttributeDescription
f number

the base to convert from

t number

the base to convert to

a number[]

the origin array

ai number

start offset in the origin array

aj number

end offset in the origin array

Return:

number[]

The resulting limb array.

public decrement(r: Number, a: Array, ai: Number, aj: Number) source

Subtracts 1 from a big endian array.

Wraps on underflow. Hence, does nothing if aj <= ai.

O(|A|) time in the worst case. O(1) amortized time over any number of successive operations starting with A = O(1). O(1) amortized time over O(|A|) successive operations starting with any A.

Params:

NameTypeAttributeDescription
r Number

radix

a Array

first operand

ai Number

a left

aj Number

a right

public eq(a: number[], ai: number, aj: number, b: number[], bi: number, bj: number): boolean source

Tests whether two big endian arrays are equal.

Input:

  • |A| >= 0
  • |B| >= 0

Params:

NameTypeAttributeDescription
a number[]

first operand

ai number

a left

aj number

a right

b number[]

second operand

bi number

b left

bj number

b right

Return:

boolean

true iff A = B.

public euclidean_algorithm(r: Number, a: Array, ai: Number, aj: Number, b: Array, bi: Number, bj: Number): Array source

No constraints on the input.

Params:

NameTypeAttributeDescription
r Number

The radix.

a Array

First input number a>b.

ai Number

a left bound.

aj Number

a right bound.

b Array

Second input number b<a.

bi Number

b left bound.

bj Number

b right bound.

Return:

Array

The array containing the gcd of A and B (one of A and B). Return as [ d , di , dj ], where d is the array and di and dj are its left and right bounds.

public extended_euclidean_algorithm(r: Number, a: Array, ai: Number, aj: Number, b: Array, bi: Number, bj: Number): undefined[] source

No constraints on the input.

Params:

NameTypeAttributeDescription
r Number

The radix.

a Array

First input number a>b.

ai Number

a left bound.

aj Number

a right bound.

b Array

Second input number b<a.

bi Number

b left bound.

bj Number

b right bound.

Return:

undefined[]

public ge(a: number[], ai: number, aj: number, b: number[], bi: number, bj: number): boolean source

Compares two big endian arrays: returns true if the first is greater or equal to the second.

Input:

  • |A| >= 0
  • |B| >= 0

Params:

NameTypeAttributeDescription
a number[]

first operand

ai number

a left

aj number

a right

b number[]

second operand

bi number

b left

bj number

b right

Return:

boolean

true iff A >= B.

public gt(a: number[], ai: number, aj: number, b: number[], bi: number, bj: number): boolean source

Compares two big endian arrays: returns true if the first is greater than the second.

Input:

  • |A| >= 0
  • |B| >= 0

Params:

NameTypeAttributeDescription
a number[]

first operand

ai number

a left

aj number

a right

b number[]

second operand

bi number

b left

bj number

b right

Return:

boolean

true iff A > B.

public iadd(r: Number, a: Array, ai: Number, aj: Number, b: Array, bi: Number, bj: Number): * source

Adds a big endian array to another in-place. Wraps on overflow. Works with any combination of array sizes.

Params:

NameTypeAttributeDescription
r Number

base (radix)

a Array

first operand (modified in-place)

ai Number

a left

aj Number

a right

b Array

second operand

bi Number

b left

bj Number

b right

Return:

*

public increment(r: Number, a: Array, ai: Number, aj: Number) source

Adds 1 to a big endian array.

Wraps on overflow. Hence, does nothing if aj <= ai.

O(|A|) time in the worst case. O(1) amortized time over any number of successive operations starting with A = O(1). O(1) amortized time over O(|A|) successive operations starting with any A.

Params:

NameTypeAttributeDescription
r Number

radix

a Array

first operand

ai Number

a left

aj Number

a right

public jz(a: number[], ai: number, aj: number): boolean source

Returns true if and only if input number A is 0.

Returns true if aj <= ai. O(|A|) time in the worst case. O(1) time if A has no leading zero.

Params:

NameTypeAttributeDescription
a number[]

first operand

ai number

a left

aj number

a right

Return:

boolean

true if and only if input number is 0.

public le(a: number[], ai: number, aj: number, b: number[], bi: number, bj: number): boolean source

Compares two big endian arrays: returns true if the first is less or equal to the second.

Input:

  • |A| >= 0
  • |B| >= 0

Params:

NameTypeAttributeDescription
a number[]

first operand

ai number

a left

aj number

a right

b number[]

second operand

bi number

b left

bj number

b right

Return:

boolean

true iff A <= B.

public lt(a: number[], ai: number, aj: number, b: number[], bi: number, bj: number): boolean source

Compares two big endian arrays: returns true if the first is less than the second.

Input:

  • |A| >= 0
  • |B| >= 0

Params:

NameTypeAttributeDescription
a number[]

first operand

ai number

a left

aj number

a right

b number[]

second operand

bi number

b left

bj number

b right

Return:

boolean

true iff A < B.

public mul(r: Number, a: Array, ai: Number, aj: Number, b: Array, bi: Number, bj: Number, c: Array, ci: Number, cj: Number): * source

Multiplies two big endian arrays and puts result in a destination array.

Constraints:

  • C is zero initialized,
  • |A| >= 0,
  • |B| >= 0,
  • |C| >= |A| + |B|.

Params:

NameTypeAttributeDescription
r Number

base (radix)

a Array

first operand

ai Number

a left

aj Number

a right

b Array

second operand

bi Number

b left

bj Number

b right

c Array

result, must be 0 initialized and be able to contain result

ci Number

c left

cj Number

c right

Return:

*

public ne(a: number[], ai: number, aj: number, b: number[], bi: number, bj: number): boolean source

Tests whether two big endian arrays are not equal.

Input:

  • |A| >= 0
  • |B| >= 0

Params:

NameTypeAttributeDescription
a number[]

first operand

ai number

a left

aj number

a right

b number[]

second operand

bi number

b left

bj number

b right

Return:

boolean

true iff A != B.

public parse(f: number, t: number, string: string): number[] source

Converts a string representation in base f to a limb array in base t.

Params:

NameTypeAttributeDescription
f number

radix of the representation

t number

radix of the limb array

string string

the input representation

Return:

number[]

the resulting limb array

public parse_keep_zeros(f: number, t: number, string: string): number[] source

Converts a string representation in base f to a limb array in base t keeping all leading zeros resulting from the conversion process.

Params:

NameTypeAttributeDescription
f number

radix of the representation

t number

radix of the limb array

string string

the input representation

Return:

number[]

the resulting limb array

public stringify(f: number, t: number, a: number[], ai: number, aj: number): string source

Converts a limb array in base f to a string representation in base t.

Params:

NameTypeAttributeDescription
f number

radix of the limb array

t number

radix of the representation

a number[]

the input limb array

ai number

left bound of the input

aj number

non-inclusive right bound of the input

Return:

string

the resulting representation

public translate(f: number, t: number, string: string): string source

Converts a string representation in base f to a string representation in base t.

Params:

NameTypeAttributeDescription
f number

radix of the input

t number

radix of the output

string string

the input representation

Return:

string

the output representation

public trim_natural(a: number[], ai: number, aj: number): number[] source

Trim a limb array so that it is either [0] or does not start with any leading zeros. Return a newly allocated array and does not modify the input.

Params:

NameTypeAttributeDescription
a number[]

The input limb array.

ai number
aj number

Return:

number[]

The input but trimmed.

Static Private

private _add(r: Number, a: Array, ai: Number, aj: Number, b: Array, bi: Number, bj: Number, c: Array, ci: Number, cj: Number) source

Adds two big endian arrays and puts result in a destination array. Wraps on overflow. |C| >= |A| >= |B|.

Params:

NameTypeAttributeDescription
r Number

base (radix)

a Array

first operand

ai Number

a left

aj Number

a right

b Array

second operand

bi Number

b left

bj Number

b right

c Array

result, must be 0 initialized

ci Number

c left

cj Number

c right

private _alloc(n: number): number[] source

Allocate a new limb array.

Params:

NameTypeAttributeDescription
n number

The size of the array to allocate.

Return:

number[]

The new limb array.

private _build(base: *, number: *, data: *, n: *): * source

Params:

NameTypeAttributeDescription
base *
number *
data *
n *

Return:

*

private _chr(x: number): string source

Converts a limb to a character representation. This only works if the limb is at most 35.

Params:

NameTypeAttributeDescription
x number

The input limb.

Return:

string

The corresponding character representation.

private _cmp(a: number[], ai: number, aj: number, b: number[], bi: number, bj: number): number source

Compares two big endian arrays. The second operand cannot have more limbs than the first.

Input:

  • |A| >= |B| >= 0

Params:

NameTypeAttributeDescription
a number[]

first operand

ai number

a left

aj number

a right

b number[]

second operand

bi number

b left

bj number

b right

Return:

number

result 1 if a > b; 0 if a = b; -1 otherwise.

private _cmp_half(r: Number, a: array, ai: Number, aj: Number): Number source

Compares a number A with size n = |A| to R = (r^n)/2. When n=0, R=1/2, hence result is -1.

Params:

NameTypeAttributeDescription
r Number

the base

a array

first operand

ai Number

a left

aj Number

a right

Return:

Number

result 1 if A > R; 0 if a = R; -1 otherwise.

private _cmp_half_even_radix(_r: *, a: *, ai: *, aj: *): * source

Params:

NameTypeAttributeDescription
_r *
a *
ai *
aj *

Return:

*

private _cmp_half_odd_radix(_r: *, a: *, ai: *, aj: *): * source

Params:

NameTypeAttributeDescription
_r *
a *
ai *
aj *

Return:

*

private _cmp_n(a: number[], ai: number, aj: number, b: number[], bi: number): number source

Compares two big endian arrays.

Input:

  • |A| = |B|

Params:

NameTypeAttributeDescription
a number[]

first operand

ai number

a left

aj number

a right

b number[]

second operand

bi number

b left

Return:

number

1 if a > b; 0 if a = b; -1 otherwise.

private _convert(f: number, t: number, a: number[], ai: number, aj: number, b: number[], bi: number, bj: number): * source

Dispatcher for the various base conversion implementations. The decision is based on the relation f <= t.

Params:

NameTypeAttributeDescription
f number

the base to convert from

t number

the base to convert to

a number[]

the origin array

ai number

start offset in the origin array

aj number

end offset in the origin array

b number[]

the destination array

bi number

start offset in the destination array

bj number

end offset in the destination array

Return:

*

private _convert_dc(size_small_block: Number, f: Number, t: Number, a: Array, ai: Number, aj: Number, b: Array, bi: Number, bj: Number) source

O(M(N) log N) where M(N) is multiplication time complexity.

  • bj - bi >= log_t(f) * ( aj - ai ) ;

Roughly, split number A into two halves A0 * f^l + A1. Convert A0 to B0 and A1 to B1 recursively. Then multiply B0 by f^l in base t and finally add B1.

This implementation is not recursive. It is iterative, and will call a simpler subroutine for the base case.

Params:

NameTypeAttributeDescription
size_small_block Number

the size of a small block

f Number

the base to convert from

t Number

the base to convert to

a Array

the origin array

ai Number

start offset in the origin array

aj Number

end offset in the origin array

b Array

the destination array

bi Number

start offset in the destination array

bj Number

end offset in the destination array

private _convert_slow(f: Number, t: Number, a: Array, ai: Number, aj: Number, b: Array, bi: Number, bj: Number): * source

F != t

Params:

NameTypeAttributeDescription
f Number

the base to convert from

t Number

the base to convert to

a Array

the origin array

ai Number

start offset in the origin array

aj Number

end offset in the origin array

b Array

the destination array

bi Number

start offset in the destination array

bj Number

end offset in the destination array

Return:

*

private _convert_to_larger(f: Number, t: Number, a: Array, ai: Number, aj: Number, b: Array, bi: Number, bj: Number): * source

Params:

NameTypeAttributeDescription
f Number

the base to convert from

t Number

the base to convert to

a Array

the origin array

ai Number

start offset in the origin array

aj Number

end offset in the origin array

b Array

the destination array

bi Number

start offset in the destination array

bj Number

end offset in the destination array

Return:

*

private _convert_to_larger_fast(ar: Number, z: Number, a: Array, ai: Number, aj: Number, b: Array, bi: Number, bj: Number) source

Params:

NameTypeAttributeDescription
ar Number

the base to convert from

z Number

if br is the base to convert to then log(br) = z log(ar)

a Array

the origin array

ai Number

start offset in the origin array

aj Number

end offset in the origin array

b Array

the destination array

bi Number

start offset in the destination array

bj Number

end offset in the destination array

private _convert_to_larger_slow(f: Number, t: Number, a: Array, ai: Number, aj: Number, b: Array, bi: Number, bj: Number) source

O(N^2). f < t.

Params:

NameTypeAttributeDescription
f Number

the base to convert from

t Number

the base to convert to

a Array

the origin array

ai Number

start offset in the origin array

aj Number

end offset in the origin array

b Array

the destination array

bi Number

start offset in the destination array

bj Number

end offset in the destination array

private _convert_to_smaller(f: Number, t: Number, a: Array, ai: Number, aj: Number, b: Array, bi: Number, bj: Number): * source

Params:

NameTypeAttributeDescription
f Number

the base to convert from

t Number

the base to convert to

a Array

the origin array

ai Number

start offset in the origin array

aj Number

end offset in the origin array

b Array

the destination array

bi Number

start offset in the destination array

bj Number

end offset in the destination array

Return:

*

private _convert_to_smaller_fast(br: Number, z: Number, a: Array, ai: Number, aj: Number, b: Array, bi: Number, bj: Number) source

Params:

NameTypeAttributeDescription
br Number

the base to convert to

z Number

if ar is the base to convert to then log(ar) = z log(br)

a Array

the origin array

ai Number

start offset in the origin array

aj Number

end offset in the origin array

b Array

the destination array

bi Number

start offset in the destination array

bj Number

end offset in the destination array

private _convert_to_smaller_slow(f: Number, t: Number, a: Array, ai: Number, aj: Number, b: Array, bi: Number, bj: Number) source

O(N^2). f > t.

|A| >= 1 |B| is large enough to hold the result

Params:

NameTypeAttributeDescription
f Number

the base to convert from

t Number

the base to convert to

a Array

the origin array

ai Number

start offset in the origin array

aj Number

end offset in the origin array

b Array

the destination array

bi Number

start offset in the destination array

bj Number

end offset in the destination array

private _copy(a: number[], ai: number, aj: number, b: number[], bi: number) source

Copy a limb array into another limb array.

Params:

NameTypeAttributeDescription
a number[]

The copied limb array.

ai number
aj number
b number[]

The destination limb array.

bi number

private _div_limb_with_prefix(r: Number, tmp: Number, d: Number, D: Array, Di: Number, Dj: Number, Q: Array, Qi: Number) source

Divides a big endian number by a single limb number. Can only work with limbs of size at most sqrt( 2^53 ). Allows to prefix the dividend with an intermediate remainder.

Does not update the remainder.

Input

  • 0 <= tmp <= d - 1
  • 1 <= d <= r - 1
  • |Q| = |D|

Params:

NameTypeAttributeDescription
r Number

The radix.

tmp Number

Intermediate remainder (MUST be < d).

d Number

The divisor >= 1.

D Array

The dividend (NOT modified).

Di Number

Left of dividend.

Dj Number

Right of dividend.

Q Array

The quotient.

Qi Number

Left of quotient.

private _divmod(r: Number, D: Array, Di: Number, Dj: Number, d: Array, di: Number, dj: Number, Q: Array, Qi: Number, Qj: Number, R: Array, Ri: Number, Rj: Number) source

Computes the quotient and remainder of two numbers. Uses the most appropriate algorithms depending on the size of the operands. The remainder is written to the dividend array. There are a few assumptions made on the input.

Input

  • No leading zeros in D or Q.
  • |D| = |Q| = |R|

Params:

NameTypeAttributeDescription
r Number

The base to work with.

D Array

Dividend array.

Di Number

Left of dividend.

Dj Number

Right of dividend.

d Array

Divisor array.

di Number

Left of divisor.

dj Number

Right of divisor.

Q Array

Quotient array.

Qi Number

Left of quotient.

Qj Number

Right of quotient.

R Array

Remainder array.

Ri Number

Left of remainder.

Rj Number

Right of remainder.

private _euclidean_algorithm_loop(r: Number, a: Array, ai: Number, aj: Number, b: Array, bi: Number, bj: Number): Array source

Euclidean algorithm. Computes the gcd of the two input numbers A and B, A >= B. Input arrays are modified in-place.

Input

  • A >= B
  • No leading zeros

Params:

NameTypeAttributeDescription
r Number

The radix.

a Array

The first input number A.

ai Number

Left of A.

aj Number

Right of A.

b Array

The second input number B.

bi Number

Left of B.

bj Number

Right of B.

Return:

Array

The array containing the gcd of A and B (one of A and B). Return as [ d , di , dj ], where d is the array and di and dj are its left and right bounds.

private _extended_euclidean_algorithm(r: Number, a: Array, ai: Number, aj: Number, b: Array, bi: Number, bj: Number): * source

Precondition:

  • A >= B
  • No leading zeroes.

Params:

NameTypeAttributeDescription
r Number

The radix.

a Array

First input number a>b.

ai Number

a left bound.

aj Number

a right bound.

b Array

Second input number b<a.

bi Number

b left bound.

bj Number

b right bound.

Return:

*

private _extended_euclidean_algorithm_allocate(m: *, n: *): undefined[] source

M >= n >= 0 m >= 1

Params:

NameTypeAttributeDescription
m *
n *

Return:

undefined[]

private _extended_euclidean_algorithm_loop(r: *, R0: *, R1: *, S0: *, T0: *, S1: *, T1: *, Q: *, X: *): undefined[] source

Extended Euclidean algorithm.

Params:

NameTypeAttributeDescription
r *
R0 *
R1 *
S0 *
T0 *
S1 *
T1 *
Q *
X *

Return:

undefined[]

See:

private _fill(a: number[], ai: number, aj: number, v: number) source

Fill the input limb array with a fixed value.

Params:

NameTypeAttributeDescription
a number[]

input limb array

ai number
aj number
v number

the value used to fill the input array

private _from_string(string: string): number[] source

Converts a string representation to a limb array representation without radix conversion.

Params:

NameTypeAttributeDescription
string string

input string

Return:

number[]

output limb array

private _iadd(r: Number, a: Array, ai: Number, aj: Number, b: Array, bi: Number, bj: Number) source

Adds a big endian array to another. Wraps on overflow. |A| >= |B|.

Params:

NameTypeAttributeDescription
r Number

base (radix)

a Array

first operand

ai Number

a left

aj Number

a right

b Array

second operand

bi Number

b left

bj Number

b right

private _iadd_limb(r: Number, x: Number, a: Array, ai: Number, aj: Number) source

Adds single limb to a big endian array. Wraps on overflow.

Input:

  • |A| >= 1.

Params:

NameTypeAttributeDescription
r Number

base (radix)

x Number

limb to add

a Array

first operand

ai Number

a left

aj Number

a right

private _idivmod(r: Number, D: Array, Di: Number, Dj: Number, d: Array, di: Number, dj: Number, Q: Array, Qi: Number, Qj: Number): * source

Computes the quotient and remainder of two numbers. Uses the most appropriate algorithm depending on the size of the operands. The remainder is written to the dividend array. There are a few assumptions made on the input.

Input

  • |d| >= 1
  • |D| = |Q| >= 1
  • No leading zeros in D or d.
  • Q is zero initialized.

Params:

NameTypeAttributeDescription
r Number

The base to work with.

D Array

Dividend / Remainder array (remainder computed in-place).

Di Number

Left of dividend.

Dj Number

Right of dividend.

d Array

Divisor array.

di Number

Left of divisor.

dj Number

Right of divisor.

Q Array

Quotient array (zero initialized).

Qi Number

Left of quotient.

Qj Number

Right of quotient.

Return:

*

private _idivmod_dc(X: Number, a: Array, ai: Number, aj: Number, b: Array, bi: Number, bj: Number, c: Array, ci: Number, cj: Number) source

Input

  • No leading zeros
  • |A| = |C|
  • C must be zero-initialized.

References

Params:

NameTypeAttributeDescription
X Number

The radix.

a Array

Dividend / Remainder.

ai Number
aj Number
b Array

Divisor.

bi Number
bj Number
c Array

Quotient.

ci Number
cj Number

private _idivmod_dc_21(r: *, a: *, ai: *, aj: *, b: *, bi: *, bj: *, c: *, ci: *, cj: *): * source

Algorithm 3.3 Divide-and-conquer division (2 by 1)

Input

Two nonnegative integers A and B, such that A < β^n B and β^n / 2 ≤ B < β^n. n must be even if n >= THRESHOLD_DIV_DC.

               -----------                 -----
              |  :  |  :  |               |  :  |
               -----------                 -----

Output

The quotient floor( A/B ) and the remainder A mod B.

Complexity

T(n) = 2T'(n/2) + K

Params:

NameTypeAttributeDescription
r *
a *
ai *
aj *
b *
bi *
bj *
c *
ci *
cj *

Return:

*

private _idivmod_dc_32(r: *, a: *, ai: *, aj: *, b: *, bi: *, bj: *, c: *, ci: *, cj: *) source

Algorithm 3.4 Divide-and-conquer division (3 by 2)

Input

Two nonnegative integers A and B, such that A < β^n B and β^{2n} / 2 ≤ B < β^{2n}. n must be even.

               --------                 -----
              |  |  |  |               |  |  |
               --------                 -----

Output

The quotient floor( A/B ) and the remainder A mod B.

Complexity

T'(n) ≤ T(n) + M(n) + Ln

Params:

NameTypeAttributeDescription
r *
a *
ai *
aj *
b *
bi *
bj *
c *
ci *
cj *

private _idivmod_limb(r: Number, d: Number, D: Array, Di: Number, Dj: Number, Q: Array, Qi: Number): * source

Divides a big endian number by a single limb number. Can only work with limbs of size at most sqrt( 2^53 ).

Params:

NameTypeAttributeDescription
r Number

The radix.

d Number

The divisor.

D Array

The dividend.

Di Number

Left of dividend.

Dj Number

Right of dividend.

Q Array

The quotient.

Qi Number

Left of quotient.

Return:

*

private _idivmod_limb_with_prefix(r: Number, tmp: Number, d: Number, D: Array, Di: Number, Dj: Number, Q: Array, Qi: Number) source

Divides a big endian number by a single limb number. Can only work with limbs of size at most sqrt( 2^53 ). Allows to prefix the dividend with an intermediate remainder.

Input

  • |Q| = |D| >= 1.
  • NO NEED to reset Q. The loop will set every member of Q.

Params:

NameTypeAttributeDescription
r Number

The radix.

tmp Number

Intermediate remainder (MUST be < d).

d Number

The divisor >= 1.

D Array

The dividend.

Di Number

Left of dividend.

Dj Number

Right of dividend.

Q Array

The quotient.

Qi Number

Left of quotient.

private _idivmod_schoolbook(r: Number, a: Array, ai: Number, aj: Number, b: Array, bi: Number, bj: Number, q: Array, qi: Number) source

Computes q <- a / b and a <- a % b. No leading zeros allowed. q has length at least aj - ai

Params:

NameTypeAttributeDescription
r Number

The radix.

a Array

Dividend / Remainder.

ai Number
aj Number
b Array

Divisor.

bi Number
bj Number
q Array

Quotient.

qi Number

private _idivmod_schoolbook_large_divisor(r: Number, a: Array, ai: Number, aj: Number, b: Array, bi: Number, bj: Number, q: Array, qi: Number): * source

Input

  • Two integers A and B such that r^(m-1) <= A < r^m and (r^n)/2 <= B < r^(n).
  • No leading zeros (ONLY IN B?)
  • Q is initialized with some limbs.

Output

The quotient floor( A/B ) and the remainder A mod B.

Params:

NameTypeAttributeDescription
r Number

The radix.

a Array

Dividend.

ai Number

Left of dividend.

aj Number

Right of dividend.

b Array

Divisor.

bi Number

Left of divisor.

bj Number

Right of divisor.

q Array

Quotient.

qi Number

Left of quotient.

Return:

*

private _idivmod_schoolbook_subroutine(r: Number, a: Array, ai: Number, aj: Number, b: Array, bi: Number, bj: Number, q: Array, qi: Number) source

Input

  • Two integers A and B such that 0 <= A < β^(n+1) and (β^n)/2 <= B < β^n.
  • |A| = |B| + 1
  • |Q| = |A|

Output

The quotient floor( A/B ) and the remainder A mod B.

Params:

NameTypeAttributeDescription
r Number

The radix.

a Array

Dividend.

ai Number

Left of dividend.

aj Number

Right of dividend.

b Array

Divisor.

bi Number

Left of divisor.

bj Number

Right of divisor.

q Array

Quotient.

qi Number

Left of quotient.

private _idivmod_schoolbook_subroutine_do(r: Number, a: Array, ai: Number, aj: Number, b: Array, bi: Number, bj: Number, q: Array, qi: Number) source

Input

  • Two integers A and B such that 0 <= A < B * β and (β^n)/2 <= B < β^n. (Hence B >= 1).
  • |A| = |B| + 1
  • |Q| = |A|

Output

The quotient floor( A/B ) and the remainder A mod B.

Params:

NameTypeAttributeDescription
r Number

The radix.

a Array

Dividend.

ai Number

Left of dividend.

aj Number

Right of dividend.

b Array

Divisor.

bi Number

Left of divisor.

bj Number

Right of divisor.

q Array

Quotient.

qi Number

Left of quotient.

private _idivmod_slow(x: Number, r: array, ri: Number, rj: Number, b: array, bi: Number, bj: Number, q: array, qi: Number) source

Computes quotient and remainder of two big endian arrays.

Computes quotient and remainder of two big endian arrays using long division algorithm (the one teached in european primary schools).

/!\ This algorithm modifies its first operand.

HYP : q is at least as large as r b is not zero

Params:

NameTypeAttributeDescription
x Number

the radix

r array

dividend and remainder

ri Number

r left

rj Number

r right

b array

divisor

bi Number

b left

bj Number

b right

q array

quotient, must be 0 initialized

qi Number

q left

private _imod(r: Number, D: Array, Di: Number, Dj: Number, d: Array, di: Number, dj: Number, _: Array, _i: Number, _j: Number): * source

Computes the remainder of two numbers. Uses the most appropriate algorithm depending on the size of the operands. The remainder is written to the dividend array. There are a few assumptions made on the input.

Input

  • |d| >= 1
  • |D| = |_| >= 1
  • No leading zeros in D or d.

Params:

NameTypeAttributeDescription
r Number

The base to work with.

D Array

Dividend / Remainder array (remainder computed in-place).

Di Number

Left of dividend.

Dj Number

Right of dividend.

d Array

Divisor array.

di Number

Left of divisor.

dj Number

Right of divisor.

_ Array

Additional memory array.

_i Number

Left of memory.

_j Number

Right of memory.

Return:

*

private _imod_limb(r: Number, d: Number, D: Array, Di: Number, Dj: Number) source

Divides a big endian number by a single limb number and writes the remainder to the dividend array.

Computes a <- a % b. Only works with limbs of size at most sqrt( 2^53 ).

Params:

NameTypeAttributeDescription
r Number

The radix of D.

d Number

The divisor >= 1.

D Array

The dividend.

Di Number

Left of D.

Dj Number

Right of D.

private _imod_schoolbook(r: Number, a: Array, ai: Number, aj: Number, b: Array, bi: Number, bj: Number) source

Divides a big endian number by another big endian number and writes the remainder to the dividend array.

Computes a <- a % b. No leading zeros allowed.

Params:

NameTypeAttributeDescription
r Number

The radix.

a Array

Dividend / Remainder.

ai Number
aj Number
b Array

Divisor.

bi Number
bj Number

private _imod_schoolbook_large_divisor(r: Number, a: Array, ai: Number, aj: Number, b: Array, bi: Number, bj: Number): * source

Input

  • Two integers A and B such that r^(m-1) <= A < r^m and (r^n)/2 <= B < r^(n).
  • No leading zeros (ONLY IN B?)

Output

The remainder A mod B.

Params:

NameTypeAttributeDescription
r Number

The radix.

a Array

Dividend.

ai Number

Left of dividend.

aj Number

Right of dividend.

b Array

Divisor.

bi Number

Left of divisor.

bj Number

Right of divisor.

Return:

*

private _imod_schoolbook_subroutine(r: Number, a: Array, ai: Number, aj: Number, b: Array, bi: Number, bj: Number) source

Input

  • Two integers A and B such that 0 <= A < β^(n+1) and (β^n)/2 <= B < β^n.
  • |A| = |B| + 1

Output

The remainder A mod B.

Params:

NameTypeAttributeDescription
r Number

The radix.

a Array

Dividend.

ai Number

Left of dividend.

aj Number

Right of dividend.

b Array

Divisor.

bi Number

Left of divisor.

bj Number

Right of divisor.

private _imod_schoolbook_subroutine_do(r: Number, a: Array, ai: Number, aj: Number, b: Array, bi: Number, bj: Number) source

Input

  • Two integers A and B such that 0 <= A < B * β and (β^n)/2 <= B < β^n. (Hence B >= 1).
  • |A| = |B| + 1

Output

The remainder A mod B.

Params:

NameTypeAttributeDescription
r Number

The radix.

a Array

Dividend.

ai Number

Left of dividend.

aj Number

Right of dividend.

b Array

Divisor.

bi Number

Left of divisor.

bj Number

Right of divisor.

private _int(x: string): number source

Converts an input character representation to a limb.

Params:

NameTypeAttributeDescription
x string

input character

Return:

number

output limb

private _isub(r: Number, a: array, ai: Number, aj: Number, b: array, bi: Number, bj: Number) source

Subtracts B from A, |A| >= |B|. Wraps.

Params:

NameTypeAttributeDescription
r Number

base (radix)

a array

first operand

ai Number

a left

aj Number

a right

b array

second operand

bi Number

b left

bj Number

b right

private _karatsuba(r: Number, a: Array, ai: Number, aj: Number, b: Array, bi: Number, bj: Number, c: Array, ci: Number, cj: Number): * source

Multiply two big endian arrays using karatsuba algorithm, |A| >= |B| >= 1, |C| >= |A| + |B|, |A| >= 2.

/!\ BLOCK MULTIPLICATION RESULT MUST HOLD IN THE JAVASCRIPT NUMBER TYPE (DOUBLE i.e. 53 bits)

EXPLANATION

###########

We consider the numbers a and b, both of size N = 2n.

We divide a and b into their lower and upper parts.

a = a1 r^{n} + a0 (1) b = b1 r^{n} + b0 (2)

We express the product of a and b using their lower and upper parts.

a b = (a1 r^{n} + a0) (b1 r^{n} + b0) (3) = a1 b1 r^{2n} + (a1 b0 + a0 b1) r^{n} + a0 b0 (4)

This gives us 4 multiplications with operands of size n. Using a simple trick, we can reduce this computation to 3 multiplications.

We give the 3 terms of (4) the names z0, z1 and z2.

z2 = a1 b1 z1 = a1 b0 + a0 b1 z0 = a0 b0

a b = z2 r^{2n} + z1 r^{n} + z0

We then express z1 using z0, z2 and one additional multiplication.

(a1 + a0)(b1 + b0) = a1 b1 + a0 b0 + (a1 b0 + a0 b1) = z2 + z0 + z1

z1 = (a1 + a0)(b1 + b0) - z2 - z0

AN ANOTHER WAY AROUND (not used here)

(a1 - a0)(b1 - b0) = (a1 b1 + a0 b0) - (a1 b0 + a0 b1) (a0 - a1)(b1 - b0) = (a1 b0 + a0 b1) - (a1 b1 + a0 b0) a b = (r^{2n} + r^{n})a1 b1 + r^{n}(a0 - a1)(b1 - b0) + (r^{n} + 1)a0 b0

This algorithm is a specific case of the Toom-Cook algorithm, when m = n = 2.

For further reference, see

Params:

NameTypeAttributeDescription
r Number

base (radix)

a Array

first operand

ai Number

a left

aj Number

a right

b Array

second operand

bi Number

b left

bj Number

b right

c Array

result, must be 0 initialized

ci Number

c left

cj Number

c right

Return:

*

private _karatsuba_right_op_is_small(r: Number, a: Array, ai: Number, aj: Number, b: Array, bi: Number, bj: Number, c: Array, ci: Number, cj: Number) source

Multiply two big endian arrays using karatsuba algorithm, WHEN THE SECOND OPERAND IS SMALL. |A| >= |B| >= 1, |C| >= |A| + |B|, |A| >= 2, Math.ceil(|A|/2) >= |B|.

/!\ BLOCK MULTIPLICATION RESULT MUST HOLD IN THE JAVASCRIPT NUMBER TYPE (DOUBLE i.e. 53 bits)

EXPLANATION

###########

We consider the numbers a and b0. a has size N = 2n, and b0 has size n.

We divide a into its lower and upper parts.

a = a1 r^{n} + a0 (1)

We express the product of a and b0 using these.

a b0 = (a1 r^{n} + a0) b0 (3) = a1 b0 r^{n} + a0 b0 (4)

This gives us 2 multiplications with operands of size n.

Params:

NameTypeAttributeDescription
r Number

base (radix)

a Array

first operand

ai Number

a left

aj Number

a right

b Array

second operand

bi Number

b left

bj Number

b right

c Array

result, must be 0 initialized

ci Number

c left

cj Number

c right

private _log(x: *, y: *): undefined[] source

Params:

NameTypeAttributeDescription
x *
y *

Return:

undefined[]

private _mod_limb(r: Number, d: Number, D: Array, Di: Number, Dj: Number): Number source

Divides a big endian number by a single limb number and returns only the remainder.

Only works with limbs of size at most sqrt( 2^53 ).

Params:

NameTypeAttributeDescription
r Number

The radix of D.

d Number

The divisor >= 1.

D Array

The dividend (NOT modified).

Di Number

Left of D.

Dj Number

Right of D.

Return:

Number

The remainder D % d.

private _mul(r: Number, a: Array, ai: Number, aj: Number, b: Array, bi: Number, bj: Number, c: Array, ci: Number, cj: Number): * source

Computes C = A+B.

Constraints:

  • C is zero initialized,
  • |A| >= |B| >= 0,
  • |C| >= |A| + |B|.

TODO:

  • Use schoolbook mul if n = O(log m).

Params:

NameTypeAttributeDescription
r Number

base (radix)

a Array

first operand

ai Number

a left

aj Number

a right

b Array

second operand, cannot have more limbs than A

bi Number

b left

bj Number

b right

c Array

result, must be 0 initialized and be able to contain A+B

ci Number

c left

cj Number

c right

Return:

*

private _mul_limb(r: *, x: *, b: *, bi: *, bj: *, c: *, ci: *, cj: *) source

Compute x * b where x is a single limb. 0 <= x <= r-1 No restriction on operand sizes.

Params:

NameTypeAttributeDescription
r *
x *
b *
bi *
bj *
c *
ci *
cj *

private _pow_double(r: Number, x: Number, a: Array, ai: Number, aj: Number, c: Array, ci: Number, cj: Number) source

Computes pow(a,x) = a^x using exponentiation by squaring. Writes result to output array.

/!\ |A| >= 1, |C| >= 1, |C| >= |A| * x, |C| = 000...0

Params:

NameTypeAttributeDescription
r Number

The base to work with.

x Number

The power to raise a to.

a Array

The base array.

ai Number

a left.

aj Number

b right.

c Array

The output array.

ci Number

a left.

cj Number

b right.

private _pow_double_recursive(r: Number, x: Number, a: Array, ai: Number, aj: Number, c: Array, ci: Number, cj: Number) source

Computes pow(a,x) = a^x using exponentiation by squaring. Writes result to output array.

/!\ |A| >= 1, |C| >= 1, |C| >= |A| * x, |C| = 000...0

Params:

NameTypeAttributeDescription
r Number

The base to work with.

x Number

The power to raise a to.

a Array

The base array.

ai Number

a left.

aj Number

b right.

c Array

The output array.

ci Number

a left.

cj Number

b right.

private _reset(a: number[], ai: number, aj: number) source

Fill the input limb array with zeros.

Params:

NameTypeAttributeDescription
a number[]

input limb array

ai number
aj number

private _schoolbook_mul(r: *, a: *, ai: *, aj: *, b: *, bi: *, bj: *, c: *, ci: *, cj: *) source

Computes the product of two big endian arrays using schoolbook multiplication. |C| >= |A|+|B|.

TODO Can this be optimized if we know that |A| >= |B|? Probably better to do many small passes rather than few large passes ?! This is what this implementation achieves, although it returns correct results even when |A| < |B|.

Params:

NameTypeAttributeDescription
r *
a *
ai *
aj *
b *
bi *
bj *
c *
ci *
cj *

private _sub(r: Number, a: array, ai: Number, aj: Number, b: array, bi: Number, bj: Number, c: array, ci: Number, cj: Number) source

Subtracts two big endian arrays, |C| >= |A| >= |B|. Wraps.

Params:

NameTypeAttributeDescription
r Number

base (radix)

a array

first operand

ai Number

a left

aj Number

a right

b array

second operand

bi Number

b left

bj Number

b right

c array

result, must be 0 initialized

ci Number

c left

cj Number

c right

private _to_string(b: number[]): string source

Convert an entire limb array to a string representation (without changing the radix).

Params:

NameTypeAttributeDescription
b number[]

The inpurt limb array.

Return:

string

The string representation.

private _trim_positive(a: number[], ai: number, aj: number): number source

Compute the new inclusive left bound of a limb array by skipping all leading zeros.

Params:

NameTypeAttributeDescription
a number[]

The input limb array.

ai number
aj number

Return:

number

The new inclusive left bound of the input.

private _validate(base: *, a: *, ai: *, aj: *): boolean source

Params:

NameTypeAttributeDescription
base *
a *
ai *
aj *

Return:

boolean

private _zeros(n: number): number[] source

Allocate a new limb array filled with zeros.

Params:

NameTypeAttributeDescription
n number

The size of the allocated array.

Return:

number[]

The newly allocated array.