Document Curve25519
This commit is contained in:
parent
d983042092
commit
bd832f1a23
|
@ -43,27 +43,14 @@ local function step(dxmul, dx, x1, z1, x2, z2)
|
||||||
return x3, z3, x4, z4
|
return x3, z3, x4, z4
|
||||||
end
|
end
|
||||||
|
|
||||||
local function bits(str)
|
--- Performs a Montgomery ladder operation with multiplication by 8.
|
||||||
-- Decode.
|
--
|
||||||
local bytes = {str:byte(1, 32)}
|
-- @tparam function(a:internal.fp.fp1, dx:any):internal.fp.fpq dxmul A function
|
||||||
local out = {}
|
-- to multiply an element in Fp by dx.
|
||||||
for i = 1, 32 do
|
-- @tparam any dx The base point's x coordinate. Z is assumed to be equal to 1.
|
||||||
local byte = bytes[i]
|
-- @tparam {number...} bits The multiplier scalar divided by 8, in little-endian
|
||||||
for j = -7, 0 do
|
-- bits.
|
||||||
local bit = byte % 2
|
--
|
||||||
out[8 * i + j] = bit
|
|
||||||
byte = (byte - bit) / 2
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Clamp.
|
|
||||||
out[256] = 0
|
|
||||||
out[255] = 1
|
|
||||||
|
|
||||||
-- We remove the 3 lowest bits since the ladder already multiplies by 8.
|
|
||||||
return {unpack(out, 4)}
|
|
||||||
end
|
|
||||||
|
|
||||||
local function ladder8(dxmul, dx, bits)
|
local function ladder8(dxmul, dx, bits)
|
||||||
local x1 = fp.num(1)
|
local x1 = fp.num(1)
|
||||||
local z1 = fp.num(0)
|
local z1 = fp.num(0)
|
||||||
|
@ -89,7 +76,5 @@ local function ladder8(dxmul, dx, bits)
|
||||||
end
|
end
|
||||||
|
|
||||||
return {
|
return {
|
||||||
double = double,
|
|
||||||
bits = bits,
|
|
||||||
ladder8 = ladder8,
|
ladder8 = ladder8,
|
||||||
}
|
}
|
||||||
|
|
26
x25519.lua
26
x25519.lua
|
@ -7,6 +7,28 @@ local expect = require "cc.expect".expect
|
||||||
local fp = require "ccryptolib.internal.fp"
|
local fp = require "ccryptolib.internal.fp"
|
||||||
local mont = require "ccryptolib.internal.curve25519"
|
local mont = require "ccryptolib.internal.curve25519"
|
||||||
|
|
||||||
|
-- TODO This function feels out of place anywhere I try putting it on.
|
||||||
|
local function bits(str)
|
||||||
|
-- Decode.
|
||||||
|
local bytes = {str:byte(1, 32)}
|
||||||
|
local out = {}
|
||||||
|
for i = 1, 32 do
|
||||||
|
local byte = bytes[i]
|
||||||
|
for j = -7, 0 do
|
||||||
|
local bit = byte % 2
|
||||||
|
out[8 * i + j] = bit
|
||||||
|
byte = (byte - bit) / 2
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Clamp.
|
||||||
|
out[256] = 0
|
||||||
|
out[255] = 1
|
||||||
|
|
||||||
|
-- We remove the 3 lowest bits since the ladder already multiplies by 8.
|
||||||
|
return {unpack(out, 4)}
|
||||||
|
end
|
||||||
|
|
||||||
local mod = {}
|
local mod = {}
|
||||||
|
|
||||||
--- Computes the public key from a secret key.
|
--- Computes the public key from a secret key.
|
||||||
|
@ -17,7 +39,7 @@ local mod = {}
|
||||||
function mod.publicKey(sk)
|
function mod.publicKey(sk)
|
||||||
expect(1, sk, "string")
|
expect(1, sk, "string")
|
||||||
assert(#sk == 32, "secret key length must be 32")
|
assert(#sk == 32, "secret key length must be 32")
|
||||||
return fp.encode(mont.ladder8(fp.kmul, 9, mont.bits(sk)))
|
return fp.encode(mont.ladder8(fp.kmul, 9, bits(sk)))
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Performs the key exchange.
|
--- Performs the key exchange.
|
||||||
|
@ -31,7 +53,7 @@ function mod.exchange(sk, pk)
|
||||||
assert(#sk == 32, "secret key length must be 32")
|
assert(#sk == 32, "secret key length must be 32")
|
||||||
expect(2, pk, "string")
|
expect(2, pk, "string")
|
||||||
assert(#pk == 32, "public key length must be 32")
|
assert(#pk == 32, "public key length must be 32")
|
||||||
return fp.encode(mont.ladder8(fp.mul, fp.decode(pk), mont.bits(sk)))
|
return fp.encode(mont.ladder8(fp.mul, fp.decode(pk), bits(sk)))
|
||||||
end
|
end
|
||||||
|
|
||||||
return mod
|
return mod
|
||||||
|
|
Loading…
Reference in a new issue