Add masking docs
This commit is contained in:
parent
206f8474ff
commit
ed8f66070f
|
@ -280,6 +280,11 @@ local function bits(a)
|
||||||
return util.rebaseLE(demontgomery(a), 2 ^ 24, 2)
|
return util.rebaseLE(demontgomery(a), 2 ^ 24, 2)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Clones a scalar.
|
||||||
|
--
|
||||||
|
-- @tparam {number...} a The scalar to clone.
|
||||||
|
-- @treturn {number...} The exact same value but as a different object.
|
||||||
|
--
|
||||||
local function clone(a)
|
local function clone(a)
|
||||||
return {unpack(a)}
|
return {unpack(a)}
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,26 @@
|
||||||
|
--- Additive arithmetic masking modulo q (unstable, for internal use only).
|
||||||
|
--
|
||||||
|
-- Representing secret scalars in Cobalt is potentially dangerous since the VM
|
||||||
|
-- leaks information through timing. To remedy this, we use _masking_, which is
|
||||||
|
-- a randomized representation of a scalar s as several values {s₁, s₂, s₃, ...}
|
||||||
|
-- such that s₁ + s₂ + s₃ + ... ≡ s (mod q).
|
||||||
|
--
|
||||||
|
-- Using masking, we can perform arithmetic on the masked value without needing
|
||||||
|
-- to render the raw secrets in memory. After these operations, we can unwrap
|
||||||
|
-- the result which, depending on the operations, is harder to measure.
|
||||||
|
--
|
||||||
|
-- @module internal.maddq
|
||||||
|
--
|
||||||
|
|
||||||
local fq = require "ccryptolib.internal.fq"
|
local fq = require "ccryptolib.internal.fq"
|
||||||
local random = require "ccryptolib.random"
|
local random = require "ccryptolib.random"
|
||||||
|
|
||||||
|
--- Builds a masked scalar from a regular one.
|
||||||
|
--
|
||||||
|
-- @tparam {number...} val The input scalar.
|
||||||
|
-- @tparam number order How many values to use, must be at least 2.
|
||||||
|
-- @treturn {{number...}...} The masked scalar.
|
||||||
|
--
|
||||||
local function new(val, order)
|
local function new(val, order)
|
||||||
local out = {}
|
local out = {}
|
||||||
local sum = fq.num(0)
|
local sum = fq.num(0)
|
||||||
|
@ -14,36 +34,68 @@ local function new(val, order)
|
||||||
return out
|
return out
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Unwraps a masked scalar, getting the raw unmasked value.
|
||||||
|
--
|
||||||
|
-- @tparam {{number...}...} arr The input masked scalar.
|
||||||
|
-- @treturn {number...} The unmasked scalar.
|
||||||
|
--
|
||||||
local function unwrap(arr)
|
local function unwrap(arr)
|
||||||
local sum = fq.num(0)
|
local sum = fq.num(0)
|
||||||
for i = 1, #arr do sum = fq.add(sum, arr[i]) end
|
for i = 1, #arr do sum = fq.add(sum, arr[i]) end
|
||||||
return sum
|
return sum
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Encodes a masked scalar into a string.
|
||||||
|
--
|
||||||
|
-- @tparam {{number...}...} arr The input masked scalar.
|
||||||
|
-- @treturn string The encoded value.
|
||||||
|
--
|
||||||
local function encode(arr)
|
local function encode(arr)
|
||||||
local out = {}
|
local out = {}
|
||||||
for i = 1, #arr do out[i] = fq.encode(arr[i]) end
|
for i = 1, #arr do out[i] = fq.encode(arr[i]) end
|
||||||
return table.concat(out)
|
return table.concat(out)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Decodes a masked scalar from a string.
|
||||||
|
--
|
||||||
|
-- @tparam string str The encoded scalar. Length must be a multiple of 32.
|
||||||
|
-- @treturn {{number...}...} The decoded value.
|
||||||
|
--
|
||||||
local function decode(str)
|
local function decode(str)
|
||||||
local out = {}
|
local out = {}
|
||||||
for i = 1, #str / 32 do out[i] = fq.decode(str:sub(i * 32 - 31, i * 32)) end
|
for i = 1, #str / 32 do out[i] = fq.decode(str:sub(i * 32 - 31, i * 32)) end
|
||||||
return out
|
return out
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Rerandomizes a masked scalar's representation.
|
||||||
|
--
|
||||||
|
-- @tparam {{number...}...} arr The input masked scalar.
|
||||||
|
-- @treturn {{number...}...} The rerandomized representation of the input.
|
||||||
|
--
|
||||||
local function remask(arr)
|
local function remask(arr)
|
||||||
local out = new(fq.num(0), #arr)
|
local out = new(fq.num(0), #arr)
|
||||||
for i = 1, #arr do out[i] = fq.add(out[i], arr[i]) end
|
for i = 1, #arr do out[i] = fq.add(out[i], arr[i]) end
|
||||||
return out
|
return out
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Multiplies a masked scalar by a regular scalar.
|
||||||
|
--
|
||||||
|
-- @tparam {{number...}...} arr The input masked scalar.
|
||||||
|
-- @tparam {number...} k The scalar to multiply by.
|
||||||
|
-- @treturn {{number...}...} The masked product of both values.
|
||||||
|
--
|
||||||
local function mul(arr, k)
|
local function mul(arr, k)
|
||||||
local out = {}
|
local out = {}
|
||||||
for i = 1, #arr do out[i] = fq.mul(arr[i], k) end
|
for i = 1, #arr do out[i] = fq.mul(arr[i], k) end
|
||||||
return out
|
return out
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Adds a regular scalar to a masked scalar.
|
||||||
|
--
|
||||||
|
-- @tparam {{number...}...} The input masked scalar.
|
||||||
|
-- @tparam {number...} v The scalar to add to.
|
||||||
|
-- @treturn {{number...}...} The masked sum of both values.
|
||||||
|
--
|
||||||
local function add(arr, v)
|
local function add(arr, v)
|
||||||
local out = {}
|
local out = {}
|
||||||
for i = 1, #arr do out[i] = fq.clone(arr[i]) end
|
for i = 1, #arr do out[i] = fq.clone(arr[i]) end
|
||||||
|
|
Loading…
Reference in a new issue