diff --git a/fq.lua b/fq.lua index 20e6865..cfff414 100644 --- a/fq.lua +++ b/fq.lua @@ -3,36 +3,9 @@ -- @module ccryptolib.fq -- -local unpack = unpack or table.unpack +local util = require "ccryptolib.util" ---- Converts a little-endian array from one power-of-two base to another. --- --- @tparam {number...} a The array to convert, in little-endian. --- @tparam number base1 The base to convert from. Must be a power of 2. --- @tparam number base2 The base to convert to. Must be a power of 2. --- @treturn {number...} --- -local function rebaseLE(a, base1, base2) - local out = {} - local outlen = 1 - local acc = 0 - local mul = 1 - for i = 1, #a do - acc = acc + a[i] * mul - mul = mul * base1 - while mul >= base2 do - local rem = acc % base2 - acc = (acc - rem) / base2 - mul = mul / base2 - out[outlen] = rem - outlen = outlen + 1 - end - end - if mul > 0 then - out[outlen] = acc - end - return out -end +local unpack = unpack or table.unpack --- The scalar field's order, q. local Q = { @@ -53,7 +26,7 @@ local INVEXP_BITS = nil do local Q2 = {unpack(Q)} Q2[1] = Q2[1] - 2 - INVEXP_BITS = rebaseLE(Q2, 2 ^ 24, 2) + INVEXP_BITS = util.rebaseLE(Q2, 2 ^ 24, 2) end --- The first Montgomery precomputed constant, -q⁻¹ mod 2²⁶⁴. @@ -313,7 +286,7 @@ end -- @treturn {number...} 2⁻²⁶⁴ * a mod q as limbs in [0..2). -- local function bits(a) - return rebaseLE(demontgomery(a), 2 ^ 24, 2) + return util.rebaseLE(demontgomery(a), 2 ^ 24, 2) end return { diff --git a/util.lua b/util.lua new file mode 100644 index 0000000..73c6940 --- /dev/null +++ b/util.lua @@ -0,0 +1,32 @@ +local mod = {} + +--- Converts a little-endian array from one power-of-two base to another. +-- +-- @tparam {number...} a The array to convert, in little-endian. +-- @tparam number base1 The base to convert from. Must be a power of 2. +-- @tparam number base2 The base to convert to. Must be a power of 2. +-- @treturn {number...} +-- +function mod.rebaseLE(a, base1, base2) + local out = {} + local outlen = 1 + local acc = 0 + local mul = 1 + for i = 1, #a do + acc = acc + a[i] * mul + mul = mul * base1 + while mul >= base2 do + local rem = acc % base2 + acc = (acc - rem) / base2 + mul = mul / base2 + out[outlen] = rem + outlen = outlen + 1 + end + end + if mul > 0 then + out[outlen] = acc + end + return out +end + +return mod