Split Fq masking internals
This commit is contained in:
parent
8335ddc81c
commit
d3f04036c7
47
internal/maddq.lua
Normal file
47
internal/maddq.lua
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
local fq = require "ccryptolib.internal.fq"
|
||||||
|
local random = require "ccryptolib.random"
|
||||||
|
|
||||||
|
local function new(val, order)
|
||||||
|
local out = {}
|
||||||
|
local sum = fq.num(0)
|
||||||
|
for i = 1, order - 1 do
|
||||||
|
out[i] = fq.decodeWide(random.random(64))
|
||||||
|
sum = fq.add(sum, out[i])
|
||||||
|
end
|
||||||
|
|
||||||
|
out[order] = fq.add(val, fq.neg(sum))
|
||||||
|
|
||||||
|
return out
|
||||||
|
end
|
||||||
|
|
||||||
|
local function encode(arr)
|
||||||
|
local out = {}
|
||||||
|
for i = 1, #arr do out[i] = fq.encode(arr[i]) end
|
||||||
|
return table.concat(out)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function decode(str)
|
||||||
|
local out = {}
|
||||||
|
for i = 1, #str / 32 do out[i] = fq.decode(str:sub(i * 32 - 31, i * 32)) end
|
||||||
|
return out
|
||||||
|
end
|
||||||
|
|
||||||
|
local function remask(arr)
|
||||||
|
local out = new(fq.num(0), #arr)
|
||||||
|
for i = 1, #arr do out[i] = fq.add(out[i], arr[i]) end
|
||||||
|
return out
|
||||||
|
end
|
||||||
|
|
||||||
|
local function reduce(arr, k)
|
||||||
|
local out = fq.num(0)
|
||||||
|
for i = 1, #arr do out = fq.add(out, fq.mul(arr[i], k)) end
|
||||||
|
return out
|
||||||
|
end
|
||||||
|
|
||||||
|
return {
|
||||||
|
new = new,
|
||||||
|
encode = encode,
|
||||||
|
decode = decode,
|
||||||
|
remask = remask,
|
||||||
|
reduce = reduce,
|
||||||
|
}
|
61
x25519c.lua
61
x25519c.lua
|
@ -2,6 +2,7 @@ local expect = require "cc.expect".expect
|
||||||
local fp = require "ccryptolib.internal.fp"
|
local fp = require "ccryptolib.internal.fp"
|
||||||
local fq = require "ccryptolib.internal.fq"
|
local fq = require "ccryptolib.internal.fq"
|
||||||
local x25519 = require "ccryptolib.internal.x25519"
|
local x25519 = require "ccryptolib.internal.x25519"
|
||||||
|
local maddq = require "ccryptolib.internal.maddq"
|
||||||
local random = require "ccryptolib.random"
|
local random = require "ccryptolib.random"
|
||||||
|
|
||||||
local ORDER = 4
|
local ORDER = 4
|
||||||
|
@ -21,10 +22,6 @@ local INV8Q = {
|
||||||
4095,
|
4095,
|
||||||
}
|
}
|
||||||
|
|
||||||
local function fqRandom()
|
|
||||||
return fq.decodeWide(random.random(64))
|
|
||||||
end
|
|
||||||
|
|
||||||
local function ladder8(dx, bits)
|
local function ladder8(dx, bits)
|
||||||
local x1 = fp.num(1)
|
local x1 = fp.num(1)
|
||||||
local z1 = fp.num(0)
|
local z1 = fp.num(0)
|
||||||
|
@ -55,49 +52,26 @@ end
|
||||||
|
|
||||||
local mod = {}
|
local mod = {}
|
||||||
|
|
||||||
function mod.secretKeyInit(sk)
|
function mod.new(sk)
|
||||||
sk = fq.decodeClamped(sk)
|
expect(1, sk, "string")
|
||||||
|
assert(#sk == 32, "secret key length must be 32")
|
||||||
|
|
||||||
-- Set up the mask.
|
return maddq.new(fq.decodeClamped(sk), ORDER)
|
||||||
local sks = {}
|
|
||||||
local sum = fq.num(0)
|
|
||||||
for i = 1, ORDER - 1 do
|
|
||||||
sks[i] = fqRandom()
|
|
||||||
sum = fq.add(sum, sks[i])
|
|
||||||
end
|
|
||||||
sks[ORDER] = fq.add(sk, fq.neg(sum))
|
|
||||||
|
|
||||||
return sks
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function mod.secretKeyEncode(sks)
|
function mod.encode(sks)
|
||||||
local out = {}
|
return maddq.encode(sks)
|
||||||
for i = 1, ORDER do out[i] = fq.encode(sks[i]) end
|
|
||||||
return table.concat(out)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function mod.secretKeyDecode(str)
|
function mod.decode(str)
|
||||||
expect(1, str, "string")
|
expect(1, str, "string")
|
||||||
assert(#str == ORDER * 32, ("secret key length must be %d"):format(ORDER * 32))
|
assert(#str == 128, "encoded sks length must be 128")
|
||||||
|
|
||||||
local out = {}
|
return maddq.decode(str)
|
||||||
for i = 1, ORDER do out[i] = fq.decode(str:sub(i * 32 - 31, i * 32)) end
|
|
||||||
return out
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function mod.secretKeyRemask(sks)
|
function mod.remask(sks)
|
||||||
local sum = fq.num(0)
|
return maddq.remask(sks)
|
||||||
local out = {}
|
|
||||||
|
|
||||||
for i = 1, ORDER - 1 do
|
|
||||||
local element = fqRandom()
|
|
||||||
out[i] = fq.add(sks[i], element)
|
|
||||||
sum = fq.add(sum, element)
|
|
||||||
end
|
|
||||||
|
|
||||||
out[ORDER] = fq.add(sks[ORDER], fq.neg(sum))
|
|
||||||
|
|
||||||
return out
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function mod.exchange(sks, pk, mc)
|
function mod.exchange(sks, pk, mc)
|
||||||
|
@ -106,18 +80,13 @@ function mod.exchange(sks, pk, mc)
|
||||||
expect(3, mc, "string")
|
expect(3, mc, "string")
|
||||||
assert(#mc == 32, "multiplier length must be 32")
|
assert(#mc == 32, "multiplier length must be 32")
|
||||||
|
|
||||||
-- Get the multiplier in Fq.
|
-- Reduce secret key using the multiplier.
|
||||||
mc = fq.decodeClamped(mc)
|
local skmc = maddq.reduce(sks, fq.decodeClamped(mc))
|
||||||
|
|
||||||
-- Multiply secret key members and add them together.
|
|
||||||
-- This unwraps into the "true" secret key times the multiplier (mod q).
|
|
||||||
local skmt = fq.num(0)
|
|
||||||
for i = 1, #sks do skmt = fq.add(skmt, fq.mul(sks[i], mc)) end
|
|
||||||
|
|
||||||
-- Get bits.
|
-- Get bits.
|
||||||
-- We have our exponent modulo q. We also know that its value is 0 modulo 8.
|
-- We have our exponent modulo q. We also know that its value is 0 modulo 8.
|
||||||
-- Use the Chinese Remainder Theorem to find its value modulo 8q.
|
-- Use the Chinese Remainder Theorem to find its value modulo 8q.
|
||||||
local bits = fq.bits(fq.mul(skmt, INV8Q))
|
local bits = fq.bits(fq.mul(skmc, INV8Q))
|
||||||
|
|
||||||
return fp.encode(ladder8(fp.decode(pk), bits))
|
return fp.encode(ladder8(fp.decode(pk), bits))
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue