UNPKG

@arithmetic-operations-for/integers-modulo-n-big-endian

Version:
1 lines 23.3 kB
{"version":3,"file":"index.modern.mjs","sources":["../src/_redc.js","../src/_mul.js","../src/_iadd.js","../src/_isub.js","../src/_montgomery.js","../src/modR.js","../src/modN.js","../src/Montgomery.js"],"sourcesContent":["import assert from 'assert';\nimport {\n\t_zeros as n_zeros,\n\t_copy as n_copy,\n\t_reset as n_reset,\n\t_cmp_n as n_cmp_n,\n\t_mul as n_mul,\n\t_iadd as n_iadd,\n\t_isub as n_isub,\n} from '@arithmetic-operations-for/naturals-big-endian';\n\n/**\n * Function REDC is\n *\n * input: Integers R = b^k > N with gcd(R, N) = 1,\n * Integer M in [0, R − 1] such that NM ≡ −1 mod R,\n * Integer T in the range [0, RN − 1]\n *\n * All numbers are given in base b (big endian order).\n * output: Integer S in the range [0, N − 1] such that S ≡ TR−1 mod N\n *\n * m ← ((T mod R)M) mod R // Can be implemented by discarding limbs\n * t ← (T + mN) / R // Can be implemented with a shift\n * // /!\\ T + mN is potentially RN - 1 + (R-1) N = 2RN - N - 1 so need one\n * // extra limb for carry ?\n * if t ≥ N then\n * return t − N\n * else\n * return t // Can add dummy - zero vector here in case we want to avoid side\n * // channel attacks\n * end if\n * end function\n *\n */\nexport default function _redc(b, k, N, Ni, Nj, M, Mi, Mj, T, Ti, Tj) {\n\tassert(Nj - Ni === k, '|N| !== k');\n\tassert(Mj - Mi === k, '|M| !== k'); // Can allow |M| <= k here.\n\tassert(Tj - Ti === 2 * k + 1, '|T| !== 2*k+1');\n\tassert(T[Ti] === 0, 'T[Ti] !== 0');\n\n\t// Reduce T mod R\n\tconst _Ti = Tj - k;\n\tconst _2k = k << 1; // eslint-disable-line no-bitwise\n\n\tconst m = n_zeros(_2k);\n\tconst mj = _2k;\n\n\t// M = ((T mod R) M) mod R\n\tn_mul(b, T, _Ti, Tj, M, Mi, Mj, m, 0, mj);\n\t// Could be even more efficient here\n\t// if we had a multiplication method that discards higher order\n\t// bits\n\n\tconst mi = k; // M = m mod R\n\n\t// X = m * N\n\tconst X = n_zeros(_2k); // TODO mutualize allocation with m\n\tconst Xj = _2k;\n\tn_mul(b, m, mi, mj, N, Ni, Nj, X, 0, Xj);\n\n\t// T = T + X = T + mN\n\tn_iadd(b, T, Ti, Tj, X, 0, Xj);\n\n\t// T = T / R\n\tassert(T[Ti] === 0, 'T[Ti] !== 0');\n\tn_copy(T, Ti + 1, _Ti, T, _Ti);\n\t// Assert T[Ti] === 0\n\tconst _Ti_1 = _Ti;\n\t// T[_Ti_1] = T[Ti];\n\tn_reset(T, Ti, _Ti_1);\n\n\t// If t ≥ N then\n\tif (n_cmp_n(T, _Ti_1, Tj, N, Ni) >= 0) {\n\t\tn_isub(b, T, _Ti_1, Tj, N, Ni, Nj); // Return t − N\n\t\treturn true;\n\t}\n\n\treturn false;\n\t// Else return t\n}\n","import assert from 'assert';\nimport {_mul as n_mul} from '@arithmetic-operations-for/naturals-big-endian';\n\nimport _redc from './_redc.js';\n\n// TODO\n// mul by non montgomery ?\n// abR mod N = (aR mod N)(b mod N) MODULO????\n\n/**\n *\n * abR mod N = REDC((aR mod N)(bR mod N))\n *\n *\n * |N| >= |a| >= |b|\n * |c| = 2*|N| + 1\n * c = 0000.0000 is zero initialized\n *\n */\n\nexport default function _mul(r, N, M, a, b, c) {\n\tconst k = N.length;\n\tconst _2kp1 = 2 * k + 1;\n\n\tassert(a.length <= k, '|a| > |N|');\n\tassert(b.length <= a.length, '|b| > |a|');\n\tassert(c.length === _2kp1, '|c| !== 2*k+1');\n\n\t// C = (aR mod N)(bR mod N)\n\tn_mul(\n\t\tr,\n\t\ta,\n\t\t0,\n\t\ta.length,\n\t\tb,\n\t\t0,\n\t\tb.length,\n\t\tc,\n\t\t_2kp1 - a.length - b.length,\n\t\t_2kp1,\n\t);\n\n\t// C = REDC((aR mod N)(bR mod N))\n\treturn _redc(r, k, N, 0, k, M, 0, k, c, 0, _2kp1);\n}\n","import assert from 'assert';\nimport {\n\t_iadd as n_iadd,\n\t_isub as n_isub,\n\t_cmp as n_cmp,\n\t_cmp_n as n_cmp_n,\n} from '@arithmetic-operations-for/naturals-big-endian';\n\n/**\n *\n * @param {Number} r the radix\n * @param {Array} N number array of length k.\n * @param {Array} a\n * @param {Array} b\n *\n * (a+b)R mod N = aR mod N + bR mod N - ( 0/1 * N )\n *\n * R = r^k\n * N has no leading zeroes\n * N has length k\n * |N| = |a| >= |b|\n * |a| = |b| if you want to avoid side channel attacks\n * a < N\n * b < N\n *\n * t = a + b mod r^k\n * if t < b or t >= N then return t - N mod r^k\n * else return t // Can subtract dummy zero vector here in case we want\n * // to avoid side channel attacks\n *\n */\nexport default function _iadd(r, N, a, b) {\n\tconst k = N.length;\n\n\tassert(k >= 1);\n\tassert(N[0] !== 0);\n\tassert(a.length === k, '|a| !== k');\n\tassert(b.length <= k, '|b| > k');\n\n\tn_iadd(r, a, 0, k, b, 0, b.length);\n\t// TODO Use overflow bit.\n\t// const overflow = _iadd(r, a, 0, k, b, 0, b.length) ;\n\n\tif (\n\t\t// Overflow\n\t\tn_cmp(a, 0, k, b, 0, b.length) < 0 ||\n\t\tn_cmp_n(a, 0, k, N, 0) >= 0\n\t) {\n\t\tn_isub(r, a, 0, k, N, 0, k); // Exploits wrapping\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n","import assert from 'assert';\nimport {\n\t_iadd as n_iadd,\n\t_isub as n_isub,\n\t_cmp as n_cmp,\n} from '@arithmetic-operations-for/naturals-big-endian';\n\n/**\n *\n * @param {Number} r the radix\n * @param {Array} N number array of length k.\n * @param {Array} a\n * @param {Array} b\n *\n * (a+b)R mod N = aR mod N - bR mod N + ( 0/1 * N )\n *\n * R = r^k\n * N has no leading zeroes\n * N has length k\n * |N| = |a| >= |b|\n * |a| = |b| if you want to avoid side channel attacks\n * a < N\n * b < N\n *\n * t = a - b mod r^k\n * if a < b then return t + N mod r^k\n * else return t // Can add dummy zero vector here in case we want\n * // to avoid side channel attacks\n *\n */\nexport default function _isub(r, N, a, b) {\n\tconst k = N.length;\n\n\tassert(k >= 1);\n\tassert(N[0] !== 0);\n\tassert(a.length === k, '|a| !== k');\n\tassert(b.length <= k, '|b| > k');\n\n\tconst underflow = n_cmp(a, 0, k, b, 0, b.length) < 0;\n\tn_isub(r, a, 0, k, b, 0, b.length);\n\t// TODO Use underflow bit.\n\t// const underflow = n_isub(r, a, 0, k, b, 0, b.length) ;\n\tif (underflow) {\n\t\tn_iadd(r, a, 0, k, N, 0, k); // Exploits wrapping\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n","import assert from 'assert';\nimport {\n\t_alloc as n_alloc,\n\t_zeros as n_zeros,\n\t_copy as n_copy,\n\t_mul as n_mul,\n\t_idivmod as n_idivmod,\n\t_sub as n_sub,\n\t_extended_euclidean_algorithm as n_extended_euclidean_algorithm,\n} from '@arithmetic-operations-for/naturals-big-endian';\n\nimport _redc from './_redc.js';\n\n/**\n *\n * N has no leading zeroes\n *\n * @param {Number} b the radix\n * @param {Array} N number array of length k.\n *\n *\n *\n *\n */\nexport default function _montgomery(b, N) {\n\tassert(N.length > 0);\n\tassert(N[0] !== 0);\n\n\tconst k = N.length;\n\n\tconst _2kp1 = 2 * k + 1;\n\tconst _R = n_zeros(_2kp1);\n\t_R[k] = 1; // B^k\n\n\tconst [\n\t\tGCD,\n\t\tGCDi,\n\t\t// eslint-disable-next-line no-unused-vars\n\t\t_S,\n\t\t// eslint-disable-next-line no-unused-vars\n\t\t_Si,\n\t\t_M,\n\t\t// eslint-disable-next-line no-unused-vars\n\t\t_1,\n\t\t// eslint-disable-next-line no-unused-vars\n\t\t_2,\n\t\t// eslint-disable-next-line no-unused-vars\n\t\t_3,\n\t\t// eslint-disable-next-line no-unused-vars\n\t\t_4,\n\t\t// eslint-disable-next-line no-unused-vars\n\t\t_5,\n\t\tsteps,\n\t] = n_extended_euclidean_algorithm(b, _R, k, _2kp1, N, 0, k);\n\n\t// Assert that GCD(R,N) is 1.\n\tif (GCD.length - GCDi !== 1 || GCD[GCDi] !== 1)\n\t\tthrow new Error('Montgomery: GCD(R,N) is not 1.');\n\n\tconst M = n_alloc(k); // M mod R on k words\n\tif (steps % 2 === 0) {\n\t\t// We use _R[0:k] because it is filled with zeros.\n\t\tn_sub(b, _R, 0, k, _M, _M.length - k, _M.length, M, 0, k); // _M.length-k is always 1 ?\n\t} else {\n\t\tn_copy(_M, _M.length - k, _M.length, M, 0); // _M.length-k is always 1 ?\n\t}\n\n\t// R^2 mod N\n\tconst _R2 = n_zeros(_2kp1);\n\t_R2[0] = 1;\n\tn_idivmod(b, _R2, 0, _2kp1, N, 0, k, _R, 0, _2kp1); // Use mod only function once implemented\n\tconst R2 = n_alloc(k); // R^2 mod N on k words\n\tn_copy(_R2, k + 1, _2kp1, R2, 0);\n\n\t// Avoid using division for the computation of the other constants.\n\t// From Wikipedia:\n\t// Performing these operations requires knowing at least N′ and R2 mod N.\n\t// When R is a power of a small positive integer b, N′ can be computed by\n\t// Hensel's lemma: The inverse of N modulo b is computed by a naive\n\t// algorithm (for instance, if b = 2 then the inverse is 1), and Hensel's\n\t// lemma is used repeatedly to find the inverse modulo higher and higher\n\t// powers of b, stopping when the inverse modulo R is known; N′ is the\n\t// negation of this inverse. The constants R mod N and R3 mod N can be\n\t// generated as REDC(R2 mod N) and as REDC((R2 mod N)(R2 mod N)). The\n\t// fundamental operation is to compute REDC of a product. When standalone\n\t// REDC is needed, it can be computed as REDC of a product with 1 mod N. The\n\t// only place where a direct reduction modulo N is necessary is in the\n\t// precomputation of R2 mod N.\n\n\t// R mod N = REDC(R^2 mod N)\n\t_redc(b, k, N, 0, k, M, 0, k, _R2, 0, _2kp1);\n\tconst R = n_alloc(k); // R mod N on k words\n\tn_copy(_R2, k + 1, _2kp1, R, 0);\n\n\t// R^3 mod N = REDC((R^2 mod N)(R^2 mod N))\n\tconst _R3 = n_zeros(_2kp1);\n\tn_mul(b, R2, 0, k, R2, 0, k, _R3, 1, _2kp1);\n\t_redc(b, k, N, 0, k, M, 0, k, _R3, 0, _2kp1);\n\tconst R3 = n_alloc(k); // R^3 mod N on k words\n\tn_copy(_R3, k + 1, _2kp1, R3, 0);\n\n\t// Console.debug({b, N, k, M, R, R2, R3});\n\treturn {k, M, R, R2, R3};\n}\n","import assert from 'assert';\nimport {\n\t_alloc as n_alloc,\n\t_copy as n_copy,\n} from '@arithmetic-operations-for/naturals-big-endian';\n\n/**\n *\n * |x| >= k\n *\n */\nexport default function modR(k, x) {\n\tassert(x.length >= k, '|x| >= k');\n\n\tconst xmodR = n_alloc(k); // TODO Use UintXArray ?\n\tn_copy(x, x.length - k, x.length, xmodR, 0);\n\treturn xmodR;\n}\n","import {\n\t_alloc as n_alloc,\n\t_zeros as n_zeros,\n\t_copy as n_copy,\n\t_idivmod as n_idivmod,\n\t_trim_positive as n_trim_positive,\n\t_cmp_n as n_cmp_n,\n} from '@arithmetic-operations-for/naturals-big-endian';\n\nimport modR from './modR.js';\n\nexport default function modN(r, N, x) {\n\tconst k = N.length;\n\tconst xj = x.length;\n\tconst xi = n_trim_positive(x, 0, xj);\n\tconst xn = xj - xi;\n\tif (xn > k || (xn === k && n_cmp_n(x, xi, xj, N, 0) >= 0)) {\n\t\tconst xmodN = n_alloc(xn); // TODO Use UintXArray ?\n\t\tn_copy(x, xi, xj, xmodN, 0);\n\t\tconst _ = n_zeros(xn); // TODO use _imod once implemented\n\t\tn_idivmod(r, xmodN, 0, xn, N, 0, k, _, 0, xn);\n\t\treturn modR(k, xmodN);\n\t}\n\n\tconst xmodN = n_zeros(k); // TODO Use UintXArray ?\n\tn_copy(x, xi, xj, xmodN, k - xn);\n\treturn xmodN;\n}\n","import {\n\t_alloc as n_alloc,\n\t_zeros as n_zeros,\n\t_reset as n_reset,\n\t_copy as n_copy,\n\tjz as njz,\n\t_extended_euclidean_algorithm as n_extended_euclidean_algorithm,\n\t_trim_positive as n_trim_positive,\n\t_sub as n_sub,\n\tconvert as nconvert,\n} from '@arithmetic-operations-for/naturals-big-endian';\n\nimport _mul from './_mul.js';\nimport _iadd from './_iadd.js';\nimport _isub from './_isub.js';\nimport _redc from './_redc.js';\nimport _montgomery from './_montgomery.js';\nimport modR from './modR.js';\nimport modN from './modN.js';\n\nexport default class Montgomery {\n\tconstructor(b, N) {\n\t\tconst {k, M, R, R2, R3} = _montgomery(b, N);\n\t\tthis.b = b;\n\t\tthis.N = N;\n\t\tthis.k = k;\n\t\tthis.M = M;\n\t\tthis.R = R;\n\t\tthis.R2 = R2;\n\t\tthis.R3 = R3;\n\t\t// Use shared/pooled memory ?\n\t}\n\n\tone() {\n\t\treturn this.R;\n\t}\n\n\tzero() {\n\t\treturn n_zeros(this.k);\n\t}\n\n\tfrom(x) {\n\t\t// Conversion into Montgomery form is done by computing .\n\t\t// aR mod N = REDC((a mod N)(R^2 mod N))\n\t\tconst _2kp1 = 2 * this.k + 1;\n\t\tconst red = n_zeros(_2kp1); // TODO Use UintXArray ?\n\t\tconst amodN = modN(this.b, this.N, x);\n\t\t_mul(this.b, this.N, this.M, this.R2, amodN, red);\n\t\t// TODO many unnecessary copies/alloc can be avoided by\n\t\t// allowing array offsets in methods.\n\t\treturn modR(this.k, red);\n\t}\n\n\tout(aRmodN) {\n\t\t// Conversion out of Montgomery form is done by computing.\n\t\t// a mod N = REDC(aR mod N)\n\t\tconst _2kp1 = 2 * this.k + 1;\n\t\tconst _red = n_zeros(_2kp1); // TODO Use UintXArray ?\n\t\tn_copy(aRmodN, 0, this.k, _red, _2kp1 - this.k);\n\t\t_redc(this.b, this.k, this.N, 0, this.k, this.M, 0, this.k, _red, 0, _2kp1);\n\t\tconst i = n_trim_positive(_red, this.k + 1, _2kp1);\n\t\tconst red = n_alloc(_2kp1 - i); // TODO Use UintXArray ?\n\t\tn_copy(_red, i, _2kp1, red, 0);\n\t\treturn red;\n\t}\n\n\tmul(aRmodN, bRmodN) {\n\t\tconst _2kp1 = 2 * this.k + 1;\n\t\tconst abRmodN = n_zeros(_2kp1);\n\n\t\t_mul(this.b, this.N, this.M, aRmodN, bRmodN, abRmodN);\n\n\t\treturn modR(this.k, abRmodN);\n\t}\n\n\tadd(aRmodN, bRmodN) {\n\t\tconst aRpbRmodN = n_alloc(this.k);\n\t\tn_copy(aRmodN, 0, this.k, aRpbRmodN, 0);\n\t\t_iadd(this.b, this.N, aRpbRmodN, bRmodN);\n\t\treturn aRpbRmodN;\n\t}\n\n\tsub(aRmodN, bRmodN) {\n\t\tconst aRpbRmodN = n_alloc(this.k);\n\t\tn_copy(aRmodN, 0, this.k, aRpbRmodN, 0);\n\t\t_isub(this.b, this.N, aRpbRmodN, bRmodN);\n\t\treturn aRpbRmodN;\n\t}\n\n\tinv(aRmodN) {\n\t\t// The modular inverse\n\t\t// Compute (aR mod N)^-1 using Euclidean algo\n\t\tconst ai = n_trim_positive(aRmodN, 0, this.k);\n\n\t\tlet [\n\t\t\tGCD,\n\t\t\tGCDi,\n\t\t\t// eslint-disable-next-line no-unused-vars\n\t\t\t_S,\n\t\t\t// eslint-disable-next-line no-unused-vars\n\t\t\t_Si,\n\t\t\taRmodNi,\n\t\t\t// eslint-disable-next-line no-unused-vars\n\t\t\t_1,\n\t\t\t// eslint-disable-next-line no-unused-vars\n\t\t\t_2,\n\t\t\t// eslint-disable-next-line no-unused-vars\n\t\t\t_3,\n\t\t\t// eslint-disable-next-line no-unused-vars\n\t\t\t_4,\n\t\t\t// eslint-disable-next-line no-unused-vars\n\t\t\t_5,\n\t\t\tsteps,\n\t\t] = n_extended_euclidean_algorithm(\n\t\t\tthis.b,\n\t\t\tthis.N,\n\t\t\t0,\n\t\t\tthis.k,\n\t\t\taRmodN,\n\t\t\tai,\n\t\t\tthis.k,\n\t\t);\n\n\t\t// Assert that GCD(N,aRmodN) is 1.\n\t\tif (GCD.length - GCDi !== 1 || GCD[GCDi] !== 1)\n\t\t\tthrow new Error('aRmodN has no inverse modulo N');\n\n\t\tconst _2kp1 = 2 * this.k + 1;\n\t\tconst red = n_zeros(_2kp1); // TODO Use UintXArray ?\n\n\t\tif (steps % 2 === 1) {\n\t\t\t// We compute N - aRmodNi\n\t\t\tconst temporary = n_zeros(this.k);\n\t\t\tn_sub(\n\t\t\t\tthis.b,\n\t\t\t\tthis.N,\n\t\t\t\t0,\n\t\t\t\tthis.k,\n\t\t\t\taRmodNi,\n\t\t\t\t0,\n\t\t\t\tthis.k,\n\t\t\t\ttemporary,\n\t\t\t\t0,\n\t\t\t\tthis.k,\n\t\t\t);\n\t\t\taRmodNi = temporary;\n\t\t}\n\n\t\t// A^-1 R mod N = REDC((aR mod N)^-1(R^3 mod N)).\n\t\t_mul(this.b, this.N, this.M, this.R3, aRmodNi, red);\n\n\t\treturn modR(this.k, red);\n\t}\n\n\tpown(aRmodN, x) {\n\t\t// Modular\n\t\t// exponentiation can be done using exponentiation by squaring by initializing the\n\t\t// initial product to the Montgomery representation of 1, that is, to R mod N, and\n\t\t// by replacing the multiply and square steps by Montgomery multiplies.\n\n\t\tconst nonneg = x >= 0;\n\n\t\tif (!nonneg) x = -x;\n\n\t\tif (x === 0) return this.R;\n\t\tif (x === 1) return nonneg ? aRmodN : this.inv(aRmodN);\n\n\t\tconst xbits = [];\n\n\t\tdo {\n\t\t\txbits.push(x & 1); // eslint-disable-line no-bitwise\n\t\t\tx >>= 1; // eslint-disable-line no-bitwise\n\t\t} while (x !== 1);\n\n\t\treturn this._powb(aRmodN, xbits, nonneg);\n\t}\n\n\t_powb(aRmodN, xbits, nonneg) {\n\t\t// The binary expansion of the exponent is 1 concatenanted with xbits\n\t\t// reversed. Must have xbits.length >= 1.\n\t\tconst aRmodNpown = n_alloc(this.k);\n\t\tn_copy(aRmodN, 0, this.k, aRmodNpown, 0);\n\n\t\tconst _2kp1 = 2 * this.k + 1;\n\t\tconst temporary = n_alloc(_2kp1);\n\n\t\tdo {\n\t\t\tn_reset(temporary, 0, _2kp1);\n\t\t\t_mul(this.b, this.N, this.M, aRmodNpown, aRmodNpown, temporary);\n\t\t\tn_copy(temporary, _2kp1 - this.k, _2kp1, aRmodNpown, 0);\n\t\t\tif (xbits.pop() === 1) {\n\t\t\t\tn_reset(temporary, 0, _2kp1);\n\t\t\t\t_mul(this.b, this.N, this.M, aRmodNpown, aRmodN, temporary);\n\t\t\t\tn_copy(temporary, _2kp1 - this.k, _2kp1, aRmodNpown, 0);\n\t\t\t}\n\t\t} while (xbits.length > 0);\n\n\t\treturn nonneg ? aRmodNpown : this.inv(aRmodNpown);\n\t}\n\n\tpow(aRmodN, b, nonneg = true) {\n\t\tif (njz(b, 0, b.length - 1)) {\n\t\t\t// B consists of a single limb\n\t\t\treturn this.pown(aRmodN, nonneg ? b[b.length - 1] : -b[b.length - 1]);\n\t\t}\n\n\t\tconst xbits = nconvert(this.b, 2, b, 0, b.length);\n\t\txbits.reverse();\n\t\txbits.pop();\n\n\t\treturn this._powb(aRmodN, xbits, nonneg);\n\t}\n}\n"],"names":["_redc","b","k","N","Ni","Nj","M","Mi","Mj","T","Ti","Tj","_Ti","_2k","m","n_zeros","mj","n_mul","mi","X","Xj","n_iadd","n_copy","_Ti_1","n_reset","n_cmp_n","n_isub","_mul","r","a","c","length","_2kp1","_iadd","n_cmp","_isub","underflow","_montgomery","_R","GCD","GCDi","_S","_Si","_M","_1","_2","_3","_4","_5","steps","n_extended_euclidean_algorithm","Error","n_alloc","n_sub","_R2","n_idivmod","R2","R","_R3","R3","modR","x","xmodR","xi","n_trim_positive","xj","xn","_xmodN","xmodN","_","Montgomery","constructor","this","one","zero","from","red","amodN","modN","out","aRmodN","_red","i","mul","bRmodN","abRmodN","add","aRpbRmodN","sub","inv","ai","aRmodNi","temporary","pown","nonneg","xbits","push","_powb","aRmodNpown","pop","pow","njz","nconvert","reverse"],"mappings":"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"}