Remove dependency on string.pack
This commit is contained in:
parent
0cd726952a
commit
d4c173c713
15
aead.lua
15
aead.lua
|
@ -4,9 +4,12 @@
|
|||
--
|
||||
|
||||
local expect = require "cc.expect".expect
|
||||
local packing = require "ccryptolib.internal.packing"
|
||||
local chacha20 = require "ccryptolib.chacha20"
|
||||
local poly1305 = require "ccryptolib.poly1305"
|
||||
|
||||
local p8x1, fmt8x1 = packing.compilePack("<I8")
|
||||
local u4x4, fmt4x4 = packing.compileUnpack("<I4I4I4I4")
|
||||
local bxor = bit32.bxor
|
||||
local bor = bit32.bor
|
||||
|
||||
|
@ -39,8 +42,8 @@ local function encrypt(key, nonce, message, aad, rounds)
|
|||
-- Authenticate.
|
||||
local pad1 = ("\0"):rep(-#aad % 16)
|
||||
local pad2 = ("\0"):rep(-#ciphertext % 16)
|
||||
local aadLen = ("<I8"):pack(#aad)
|
||||
local ctxLen = ("<I8"):pack(#ciphertext)
|
||||
local aadLen = p8x1("<I8", #aad)
|
||||
local ctxLen = p8x1("<I8", #ciphertext)
|
||||
local combined = aad .. pad1 .. ciphertext .. pad2 .. aadLen .. ctxLen
|
||||
local tag = poly1305.mac(authKey, combined)
|
||||
|
||||
|
@ -77,11 +80,11 @@ local function decrypt(key, nonce, tag, ciphertext, aad, rounds)
|
|||
-- Check tag.
|
||||
local pad1 = ("\0"):rep(-#aad % 16)
|
||||
local pad2 = ("\0"):rep(-#ciphertext % 16)
|
||||
local aadLen = ("<I8"):pack(#aad)
|
||||
local ctxLen = ("<I8"):pack(#ciphertext)
|
||||
local aadLen = p8x1(fmt8x1, #aad)
|
||||
local ctxLen = p8x1(fmt8x1, #ciphertext)
|
||||
local combined = aad .. pad1 .. ciphertext .. pad2 .. aadLen .. ctxLen
|
||||
local t1, t2, t3, t4 = ("<I4I4I4I4"):unpack(tag)
|
||||
local u1, u2, u3, u4 = ("<I4I4I4I4"):unpack(poly1305.mac(authKey, combined))
|
||||
local t1, t2, t3, t4 = u4x4(fmt4x4, tag, 1)
|
||||
local u1, u2, u3, u4 = u4x4(fmt4x4, poly1305.mac(authKey, combined), 1)
|
||||
local eq = bor(bxor(t1, u1), bxor(t2, u2), bxor(t3, u3), bxor(t4, u4))
|
||||
if eq == 0 then return message end
|
||||
end
|
||||
|
|
20
blake3.lua
20
blake3.lua
|
@ -3,11 +3,15 @@
|
|||
-- @module blake3
|
||||
--
|
||||
|
||||
local expect = require "cc.expect".expect
|
||||
local expect = require "cc.expect".expect
|
||||
local packing = require "ccryptolib.internal.packing"
|
||||
|
||||
local unpack = unpack or table.unpack
|
||||
local bxor = bit32.bxor
|
||||
local rol = bit32.lrotate
|
||||
local p16x4, fmt16x4 = packing.compilePack("<I4I4I4I4I4I4I4I4I4I4I4I4I4I4I4I4")
|
||||
local u16x4 = packing.compileUnpack(fmt16x4)
|
||||
local u8x4, fmt8x4 = packing.compileUnpack("<I4I4I4I4I4I4I4I4")
|
||||
|
||||
local CHUNK_START = 0x01
|
||||
local CHUNK_END = 0x02
|
||||
|
@ -129,7 +133,7 @@ local function expand(state, len, offset)
|
|||
for i = 0, len / 64 do
|
||||
local n = offset + i
|
||||
local md = compress(state.cv, state.m, n, state.n, state.f, true)
|
||||
out[i + 1] = ("<I4I4I4I4I4I4I4I4I4I4I4I4I4I4I4I4"):pack(unpack(md))
|
||||
out[i + 1] = p16x4(fmt16x4, unpack(md))
|
||||
end
|
||||
|
||||
return table.concat(out):sub(1, len)
|
||||
|
@ -150,7 +154,7 @@ local function update(state, message)
|
|||
-- Digest complete blocks.
|
||||
for i = 1, #blocks, 64 do
|
||||
-- Compress the block.
|
||||
local block = {("<I4I4I4I4I4I4I4I4I4I4I4I4I4I4I4I4"):unpack(blocks, i)}
|
||||
local block = {u16x4(fmt16x4, blocks, i)}
|
||||
local stateFlags = state.f + state.s + state.e
|
||||
state.cv = compress(state.cv, block, state.t, 64, stateFlags)
|
||||
state.s = 0
|
||||
|
@ -188,7 +192,7 @@ local function finalize(state)
|
|||
-- Pad the last message block.
|
||||
local lastLen = #state.m
|
||||
local padded = state.m .. ("\0"):rep(64)
|
||||
local last = {("<I4I4I4I4I4I4I4I4I4I4I4I4I4I4I4I4"):unpack(padded)}
|
||||
local last = {u16x4(fmt16x4, padded, 1)}
|
||||
|
||||
-- Prepare output expansion state.
|
||||
if state.t > 0 then
|
||||
|
@ -267,13 +271,13 @@ end
|
|||
function mod.newKeyed(key)
|
||||
expect(1, key, "string")
|
||||
assert(#key == 32, "key length must be 32")
|
||||
return new({("<I4I4I4I4I4I4I4I4"):unpack(key)}, KEYED_HASH)
|
||||
return new({u8x4(fmt8x4, key, 1)}, KEYED_HASH)
|
||||
end
|
||||
|
||||
function mod.newDk(context)
|
||||
expect(1, context, "string")
|
||||
local iv = new(IV, DERIVE_KEY_CONTEXT):update(context):finalize():expand(32)
|
||||
return new({("<I4I4I4I4I4I4I4I4"):unpack(iv)}, DERIVE_KEY_MATERIAL)
|
||||
return new({u8x4(fmt8x4, iv, 1)}, DERIVE_KEY_MATERIAL)
|
||||
end
|
||||
|
||||
--- Hashes data using BLAKE3.
|
||||
|
@ -304,7 +308,7 @@ function mod.digestKeyed(key, message, len)
|
|||
expect(3, len, "number", "nil")
|
||||
len = len or 32
|
||||
assert(len % 1 == 0 and len >= 1, "length must be a positive integer")
|
||||
local h = new({("<I4I4I4I4I4I4I4I4"):unpack(key)}, KEYED_HASH)
|
||||
local h = new({u8x4(fmt8x4, key, 1)}, KEYED_HASH)
|
||||
return h:update(message):finalize():expand(len)
|
||||
end
|
||||
|
||||
|
@ -322,7 +326,7 @@ function mod.deriveKey(context)
|
|||
expect(2, len, "number", "nil")
|
||||
len = len or 32
|
||||
assert(len % 1 == 0 and len >= 1, "length must be a positive integer")
|
||||
local h = new({("<I4I4I4I4I4I4I4I4"):unpack(iv)}, DERIVE_KEY_MATERIAL)
|
||||
local h = new({u8x4(fmt8x4, iv, 1)}, DERIVE_KEY_MATERIAL)
|
||||
return h:update(material):finalize():expand(len)
|
||||
end
|
||||
end
|
||||
|
|
15
chacha20.lua
15
chacha20.lua
|
@ -3,10 +3,15 @@
|
|||
-- @module chacha20
|
||||
--
|
||||
|
||||
local expect = require "cc.expect".expect
|
||||
local expect = require "cc.expect".expect
|
||||
local packing = require "ccryptolib.internal.packing"
|
||||
|
||||
local bxor = bit32.bxor
|
||||
local rol = bit32.lrotate
|
||||
local u8x4, fmt8x4 = packing.compileUnpack("<I4I4I4I4I4I4I4I4")
|
||||
local u3x4, fmt3x4 = packing.compileUnpack("<I4I4I4")
|
||||
local p16x4, fmt16x4 = packing.compilePack("<I4I4I4I4I4I4I4I4I4I4I4I4I4I4I4I4")
|
||||
local u16x4 = packing.compileUnpack(fmt16x4)
|
||||
|
||||
local mod = {}
|
||||
|
||||
|
@ -36,8 +41,8 @@ function mod.crypt(key, nonce, message, rounds, offset)
|
|||
|
||||
-- Build the state block.
|
||||
local i0, i1, i2, i3 = 0x61707865, 0x3320646e, 0x79622d32, 0x6b206574
|
||||
local k0, k1, k2, k3, k4, k5, k6, k7 = ("<I4I4I4I4I4I4I4I4"):unpack(key)
|
||||
local cr, n0, n1, n2 = offset, ("<I4I4I4"):unpack(nonce)
|
||||
local k0, k1, k2, k3, k4, k5, k6, k7 = u8x4(fmt8x4, key, 1)
|
||||
local cr, n0, n1, n2 = offset, u3x4(fmt3x4, nonce, 1)
|
||||
|
||||
-- Pad the message.
|
||||
local padded = message .. ("\0"):rep(-#message % 64)
|
||||
|
@ -101,10 +106,10 @@ function mod.crypt(key, nonce, message, rounds, offset)
|
|||
|
||||
m00, m01, m02, m03, m04, m05, m06, m07,
|
||||
m08, m09, m10, m11, m12, m13, m14, m15, idx =
|
||||
("<I4I4I4I4I4I4I4I4I4I4I4I4I4I4I4I4"):unpack(padded, idx)
|
||||
u16x4(fmt16x4, padded, idx)
|
||||
|
||||
-- Feed-forward and combine.
|
||||
out[i] = ("<I4I4I4I4I4I4I4I4I4I4I4I4I4I4I4I4"):pack(
|
||||
out[i] = p16x4(fmt16x4,
|
||||
bxor(m00, s00 + i0), bxor(m01, s01 + i1),
|
||||
bxor(m02, s02 + i2), bxor(m03, s03 + i3),
|
||||
bxor(m04, s04 + k0), bxor(m05, s05 + k1),
|
||||
|
|
|
@ -10,7 +10,10 @@
|
|||
-- @module[kind=internal] internal.fp
|
||||
--
|
||||
|
||||
local packing = require "ccryptolib.inernal.packing"
|
||||
|
||||
local unpack = unpack or table.unpack
|
||||
local ufp, fmtfp = packing.compileUnpack("<I3I3I2I3I3I2I3I3I2I3I3I2")
|
||||
|
||||
--- The modular square root of -1.
|
||||
local I = {
|
||||
|
@ -751,7 +754,7 @@ end
|
|||
--
|
||||
local function decode(b)
|
||||
local w00, w01, w02, w03, w04, w05, w06, w07, w08, w09, w10, w11 =
|
||||
("<I3I3I2I3I3I2I3I3I2I3I3I2"):unpack(b)
|
||||
ufp(fmtfp, b, 1)
|
||||
|
||||
w11 = w11 % 2 ^ 15
|
||||
|
||||
|
|
|
@ -10,10 +10,15 @@
|
|||
-- @module[kind=internal] internal.fq
|
||||
--
|
||||
|
||||
local mp = require "ccryptolib.internal.mp"
|
||||
local util = require "ccryptolib.internal.util"
|
||||
local mp = require "ccryptolib.internal.mp"
|
||||
local util = require "ccryptolib.internal.util"
|
||||
local packing = require "ccryptolib.internal.packing"
|
||||
|
||||
local unpack = unpack or table.unpack
|
||||
local pfq, fmtfq = packing.compilePack("<I3I3I3I3I3I3I3I3I3I3I2")
|
||||
local ufq = packing.compileUnpack(fmtfq)
|
||||
local ufql, fmtfql = packing.compileUnpack("<I3I3I3I3I3I3I3I3I3I3I3")
|
||||
local ufqh, fmtfqh = packing.compileUnpack("<I3I3I3I3I3I3I3I3I3I3I1")
|
||||
|
||||
--- The scalar field's order, q.
|
||||
local Q = {
|
||||
|
@ -180,7 +185,7 @@ end
|
|||
-- @treturn string The 32-byte string encoding of a.
|
||||
--
|
||||
local function encode(a)
|
||||
return ("<I3I3I3I3I3I3I3I3I3I3I2"):pack(unpack(demontgomery(a)))
|
||||
return pfq(fmtfq, unpack(demontgomery(a)))
|
||||
end
|
||||
|
||||
--- Decodes a scalar.
|
||||
|
@ -189,7 +194,7 @@ end
|
|||
-- @treturn {number...} 2²⁶⁴ × a mod q as 11 limbs in [0..2²⁴).
|
||||
--
|
||||
local function decode(str)
|
||||
local dec = {("<I3I3I3I3I3I3I3I3I3I3I2"):unpack(str)} dec[12] = nil
|
||||
local dec = {ufq(fmtfq, str, 1)} dec[12] = nil
|
||||
return montgomery(dec)
|
||||
end
|
||||
|
||||
|
@ -199,8 +204,8 @@ end
|
|||
-- @treturn {number...} 2²⁶⁴ × a mod q as 11 limbs in [0..2²⁴).
|
||||
--
|
||||
local function decodeWide(str)
|
||||
local low = {("<I3I3I3I3I3I3I3I3I3I3I3"):unpack(str)} low[12] = nil
|
||||
local high = {("<I3I3I3I3I3I3I3I3I3I3I1"):unpack(str, 34)} high[12] = nil
|
||||
local low = {ufql(fmtfql, str, 1)} low[12] = nil
|
||||
local high = {ufqh(fmtfqh, str, 34)} high[12] = nil
|
||||
return add(montgomery(low), montgomery(montgomery(high)))
|
||||
end
|
||||
|
||||
|
@ -211,7 +216,7 @@ end
|
|||
--
|
||||
local function decodeClamped(str)
|
||||
-- Decode.
|
||||
local words = {("<I3I3I3I3I3I3I3I3I3I3I2"):unpack(str)} words[12] = nil
|
||||
local words = {ufq(fmtfq, str, 1)} words[12] = nil
|
||||
|
||||
-- Clamp.
|
||||
words[1] = bit32.band(words[1], 0xfffff8)
|
||||
|
@ -229,7 +234,7 @@ end
|
|||
--
|
||||
local function decodeClamped8(str)
|
||||
-- Decode.
|
||||
local words = {("<I3I3I3I3I3I3I3I3I3I3I2"):unpack(str)} words[12] = nil
|
||||
local words = {ufq(fmtfq, str, 1)} words[12] = nil
|
||||
|
||||
-- Clamp.
|
||||
words[1] = bit32.band(words[1], 0xfffff8)
|
||||
|
|
166
internal/packing.lua
Normal file
166
internal/packing.lua
Normal file
|
@ -0,0 +1,166 @@
|
|||
--- High-performance binary packing of integers.
|
||||
--
|
||||
-- :::note Internal Module
|
||||
-- This module is meant for internal use within the library. Its API is unstable
|
||||
-- and subject to change without major version bumps.
|
||||
-- :::
|
||||
--
|
||||
-- <br />
|
||||
--
|
||||
-- :::warning
|
||||
-- For performance reasons, **the generated functions do not check types,
|
||||
-- lengths, nor ranges**. You must ensure that the passed arguments are
|
||||
-- well-formed and respect the format string yourself.
|
||||
-- :::
|
||||
--
|
||||
-- <br />
|
||||
--
|
||||
-- @module[kind=internal] internal.packing
|
||||
--
|
||||
|
||||
local fmt = string.format
|
||||
|
||||
local function mkPack(words, BE)
|
||||
local out = "local C=string.char return function(_,"
|
||||
local nb = 0
|
||||
for i = 1, #words do
|
||||
out = out .. fmt("n%d,", i)
|
||||
nb = nb + words[i]
|
||||
end
|
||||
out = out:sub(1, -2) .. ")local "
|
||||
for i = 1, nb do
|
||||
out = out .. fmt("b%d,", i)
|
||||
end
|
||||
out = out:sub(1, -2) .. " "
|
||||
local bi = 1
|
||||
for i = 1, #words do
|
||||
for _ = 1, words[i] - 1 do
|
||||
out = out .. fmt("b%d=n%d%%2^8 n%d=(n%d-b%d)*2^-8 ", bi, i, i, i, bi)
|
||||
bi = bi + 1
|
||||
end
|
||||
bi = bi + 1
|
||||
end
|
||||
out = out .. "return C("
|
||||
bi = 1
|
||||
if not BE then
|
||||
for i = 1, #words do
|
||||
for _ = 1, words[i] - 1 do
|
||||
out = out .. fmt("b%d,", bi)
|
||||
bi = bi + 1
|
||||
end
|
||||
out = out .. fmt("n%d%%2^8,", i)
|
||||
bi = bi + 1
|
||||
end
|
||||
else
|
||||
for i = 1, #words do
|
||||
out = out .. fmt("n%d%%2^8,", i)
|
||||
bi = bi + words[i] - 2
|
||||
for _ = 1, words[i] - 1 do
|
||||
out = out .. fmt("b%d,", bi)
|
||||
bi = bi - 1
|
||||
end
|
||||
bi = bi + words[i] + 1
|
||||
end
|
||||
end
|
||||
out = out:sub(1, -2) .. ")end"
|
||||
return load(out)()
|
||||
end
|
||||
|
||||
local function mkUnpack(words, BE)
|
||||
local out = "local B=string.byte return function(_,s,i)local "
|
||||
local bi = 1
|
||||
if not BE then
|
||||
for i = 1, #words do
|
||||
for _ = 1, words[i] do
|
||||
out = out .. fmt("b%d,", bi)
|
||||
bi = bi + 1
|
||||
end
|
||||
end
|
||||
else
|
||||
for i = 1, #words do
|
||||
bi = bi + words[i] - 1
|
||||
for _ = 1, words[i] do
|
||||
out = out .. fmt("b%d,", bi)
|
||||
bi = bi - 1
|
||||
end
|
||||
bi = bi + words[i] + 1
|
||||
end
|
||||
end
|
||||
out = out:sub(1, -2) .. fmt("=B(s,i,i+%d)return ", bi - 2)
|
||||
bi = 1
|
||||
for i = 1, #words do
|
||||
out = out .. fmt("b%d", bi)
|
||||
bi = bi + 1
|
||||
for j = 2, words[i] do
|
||||
out = out .. fmt("+b%d*2^%d", bi, 8 * j - 8)
|
||||
bi = bi + 1
|
||||
end
|
||||
out = out .. ","
|
||||
end
|
||||
out = out .. fmt("i+%d end", bi - 1)
|
||||
return load(out)()
|
||||
end
|
||||
|
||||
local mod = {}
|
||||
|
||||
-- Check whether string.pack is implemented in a high-speed language.
|
||||
if not string.pack or pcall(string.dump, string.pack) then
|
||||
local function compile(fmt, fn)
|
||||
local e = assert(fmt:match("^([><])I[I%d]+$"), "invalid format string")
|
||||
local w = {}
|
||||
for i in fmt:gmatch("I([%d]+)") do
|
||||
local n = tonumber(i) or 4
|
||||
assert(n > 0 and n <= 4, "integral size out of limits")
|
||||
w[#w + 1] = n
|
||||
end
|
||||
return fn(w, e == ">")
|
||||
end
|
||||
|
||||
local packCache = {}
|
||||
local unpackCache = {}
|
||||
|
||||
--- (`string.pack == nil`) Compiles a binary packing function.
|
||||
-- @tparam string fmt A string matched by `^([><])I[I%d]+$`.
|
||||
-- @treturn function A high-performance function that behaves like an unsafe
|
||||
-- version of `string.pack` for the given format string. Note that the third
|
||||
-- argument isn't optional.
|
||||
-- @treturn string fmt
|
||||
-- @throws If the string is invalid or has an invalid integral size.
|
||||
-- @throws If the compiled function is too large.
|
||||
function mod.compilePack(fmt)
|
||||
if not packCache[fmt] then
|
||||
packCache[fmt] = compile(fmt, mkPack)
|
||||
end
|
||||
return packCache[fmt], fmt
|
||||
end
|
||||
|
||||
--- (`string.pack == nil`) Compiles a binary unpacking function.
|
||||
-- @tparam string fmt A string matched by `^([><])I[I%d]+$`.
|
||||
-- @treturn function A high-performance function that behaves like an unsafe
|
||||
-- version of `string.unpack` for the given format string.
|
||||
-- @treturn string fmt
|
||||
-- @throws If the string is invalid or has an invalid integral size.
|
||||
-- @throws If the compiled function is too large.
|
||||
function mod.compileUnpack(fmt)
|
||||
if not unpackCache[fmt] then
|
||||
unpackCache[fmt] = compile(fmt, mkUnpack)
|
||||
end
|
||||
return unpackCache[fmt], fmt
|
||||
end
|
||||
|
||||
return mod
|
||||
else
|
||||
--- (`string.pack ~= nil`) Compiles a binary packing function.
|
||||
-- @tparam string fmt
|
||||
-- @treturn function `string.pack`
|
||||
-- @treturn string fmt
|
||||
mod.compilePack = function(fmt) return string.pack, fmt end
|
||||
|
||||
--- (`string.pack ~= nil`) Compiles a binary unpacking function.
|
||||
-- @tparam string fmt
|
||||
-- @treturn function `string.unpack`
|
||||
-- @treturn string fmt
|
||||
mod.compileUnpack = function(fmt) return string.unpack, fmt end
|
||||
end
|
||||
|
||||
return mod
|
|
@ -10,13 +10,17 @@
|
|||
-- @module[kind=internal] internal.sha512
|
||||
--
|
||||
|
||||
local expect = require "cc.expect".expect
|
||||
local expect = require "cc.expect".expect
|
||||
local packing = require "ccryptolib.internal.packing"
|
||||
|
||||
local shl = bit32.lshift
|
||||
local shr = bit32.rshift
|
||||
local bxor = bit32.bxor
|
||||
local bnot = bit32.bnot
|
||||
local band = bit32.band
|
||||
local p1x16, fmt1x16 = packing.compilePack(">I16")
|
||||
local p16x4, fmt16x4 = packing.compilePack(">I4I4I4I4I4I4I4I4I4I4I4I4I4I4I4I4")
|
||||
local u32x4, fmt32x4 = packing.compileUnpack(">I4I4I4I4I4I4I4I4I4I4I4I4I4I4I4I4I4I4I4I4I4I4I4I4I4I4I4I4I4I4I4I4")
|
||||
|
||||
local function carry64(a1, a0)
|
||||
local r0 = a0 % 2 ^ 32
|
||||
|
@ -65,9 +69,7 @@ local function digest(data)
|
|||
-- Pad input.
|
||||
local bitlen = #data * 8
|
||||
local padlen = -(#data + 17) % 128
|
||||
data = data .. "\x80" .. ("\0"):rep(padlen) .. (">I16"):pack(bitlen)
|
||||
local dataWords = {(">" .. ("I4"):rep(#data / 4)):unpack(data)}
|
||||
dataWords[#dataWords] = nil
|
||||
data = data .. "\x80" .. ("\0"):rep(padlen) .. p1x16(fmt1x16, bitlen)
|
||||
|
||||
-- Initialize state.
|
||||
local h01, h00 = 0x6a09e667, 0xf3bcc908
|
||||
|
@ -80,12 +82,8 @@ local function digest(data)
|
|||
local h71, h70 = 0x5be0cd19, 0x137e2179
|
||||
|
||||
-- Digest.
|
||||
local w = {}
|
||||
for i = 1, #dataWords, 32 do
|
||||
local index = i - 1
|
||||
for j = 1, 32 do
|
||||
w[j] = dataWords[index + j]
|
||||
end
|
||||
for i = 1, #data, 128 do
|
||||
local w = {u32x4(fmt32x4, data, i)}
|
||||
|
||||
-- Message schedule.
|
||||
for j = 33, 160, 2 do
|
||||
|
@ -172,7 +170,7 @@ local function digest(data)
|
|||
h71, h70 = carry64(h71 + h1, h70 + h0)
|
||||
end
|
||||
|
||||
return (">I4I4I4I4I4I4I4I4I4I4I4I4I4I4I4I4"):pack(
|
||||
return p16x4(fmt16x4,
|
||||
h01, h00, h11, h10, h21, h20, h31, h30,
|
||||
h41, h40, h51, h50, h61, h60, h71, h70
|
||||
)
|
||||
|
|
16
poly1305.lua
16
poly1305.lua
|
@ -3,8 +3,12 @@
|
|||
-- @module poly1305
|
||||
--
|
||||
|
||||
local expect = require "cc.expect".expect
|
||||
local random = require "ccryptolib.random"
|
||||
local expect = require "cc.expect".expect
|
||||
local random = require "ccryptolib.random"
|
||||
local packing = require "ccryptolib.internal.packing"
|
||||
|
||||
local u4x4, fmt4x4 = packing.compileUnpack("<I4I4I4I4")
|
||||
local p4x4 = packing.compilePack(fmt4x4)
|
||||
|
||||
local mod = {}
|
||||
|
||||
|
@ -27,7 +31,7 @@ function mod.mac(key, message)
|
|||
end
|
||||
|
||||
-- Decode r.
|
||||
local R0, R1, R2, R3 = ("<I4I4I4I4"):unpack(key)
|
||||
local R0, R1, R2, R3 = u4x4(fmt4x4, key, 1)
|
||||
|
||||
-- Clamp and shift.
|
||||
R0 = R0 % 2 ^ 28
|
||||
|
@ -55,7 +59,7 @@ function mod.mac(key, message)
|
|||
|
||||
for i = 1, #message, 16 do
|
||||
-- Decode message block.
|
||||
local m0, m1, m2, m3 = ("<I4I4I4I4"):unpack(message, i)
|
||||
local m0, m1, m2, m3 = u4x4(fmt4x4, message, i)
|
||||
|
||||
-- Shift message and add.
|
||||
local x0 = h0 + h1 + m0
|
||||
|
@ -119,7 +123,7 @@ function mod.mac(key, message)
|
|||
end
|
||||
|
||||
-- Decode s.
|
||||
local s0, s1, s2, s3 = ("<I4I4I4I4"):unpack(key, 17)
|
||||
local s0, s1, s2, s3 = u4x4(fmt4x4, key, 17)
|
||||
|
||||
-- Add.
|
||||
local t0 = s0 + c0 + c1 local u0 = t0 % 2 ^ 32
|
||||
|
@ -128,7 +132,7 @@ function mod.mac(key, message)
|
|||
local t3 = t2 - u2 + s3 * 2 ^ 96 + c6 + c7 local u3 = t3 % 2 ^ 128
|
||||
|
||||
-- Encode.
|
||||
return ("<I4I4I4I4"):pack(u0, u1 / 2 ^ 32, u2 / 2 ^ 64, u3 / 2 ^ 96)
|
||||
return p4x4(fmt4x4, u0, u1 / 2 ^ 32, u2 / 2 ^ 64, u3 / 2 ^ 96)
|
||||
end
|
||||
|
||||
local mac = mod.mac
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
local blake3 = require "ccryptolib.blake3"
|
||||
local chacha20 = require "ccryptolib.chacha20"
|
||||
local packing = require "ccryptolib.internal.packing"
|
||||
|
||||
local u1x4, fmt1x4 = packing.compileUnpack("<I4")
|
||||
|
||||
-- Initialize from local context.
|
||||
local ctx = {
|
||||
|
@ -55,7 +58,7 @@ end
|
|||
stir(512)
|
||||
|
||||
-- Save.
|
||||
math.randomseed(("I4"):unpack(random(4)))
|
||||
math.randomseed(u1x4(fmt1x4, random(4), 1))
|
||||
save()
|
||||
|
||||
return {
|
||||
|
|
22
sha256.lua
22
sha256.lua
|
@ -3,7 +3,8 @@
|
|||
-- @module sha256
|
||||
--
|
||||
|
||||
local expect = require "cc.expect".expect
|
||||
local expect = require "cc.expect".expect
|
||||
local packing = require "ccryptolib.internal.packing"
|
||||
|
||||
local rol = bit32.lrotate
|
||||
local shr = bit32.rshift
|
||||
|
@ -11,6 +12,11 @@ local bxor = bit32.bxor
|
|||
local bnot = bit32.bnot
|
||||
local band = bit32.band
|
||||
local unpack = unpack or table.unpack
|
||||
local p1x8, fmt1x8 = packing.compilePack(">I8")
|
||||
local p16x4, fmt16x4 = packing.compilePack(">I4I4I4I4I4I4I4I4I4I4I4I4I4I4I4I4")
|
||||
local u16x4 = packing.compileUnpack(fmt16x4)
|
||||
local p8x4, fmt8x4 = packing.compilePack(">I4I4I4I4I4I4I4I4")
|
||||
local u8x4 = packing.compileUnpack(fmt8x4)
|
||||
|
||||
local function primes(n, exp)
|
||||
local out = {}
|
||||
|
@ -82,15 +88,15 @@ local function digest(data)
|
|||
-- Pad input.
|
||||
local bitlen = #data * 8
|
||||
local padlen = -(#data + 9) % 64
|
||||
data = data .. "\x80" .. ("\0"):rep(padlen) .. (">I8"):pack(bitlen)
|
||||
data = data .. "\x80" .. ("\0"):rep(padlen) .. p1x8(fmt1x8, bitlen)
|
||||
|
||||
-- Digest.
|
||||
local h = h0
|
||||
for i = 1, #data, 64 do
|
||||
h = compress(h, {(">I4I4I4I4I4I4I4I4I4I4I4I4I4I4I4I4"):unpack(data, i)})
|
||||
h = compress(h, {u16x4(fmt16x4, data, i)})
|
||||
end
|
||||
|
||||
return (">I4I4I4I4I4I4I4I4"):pack(unpack(h))
|
||||
return p8x4(fmt8x4, unpack(h))
|
||||
end
|
||||
|
||||
--- Hashes a password using PBKDF2-HMAC-SHA256.
|
||||
|
@ -110,7 +116,7 @@ local function pbkdf2(password, salt, iter)
|
|||
-- Pad password.
|
||||
if #password > 64 then password = digest(password) end
|
||||
password = password .. ("\0"):rep(-#password % 64)
|
||||
password = {(">I4I4I4I4I4I4I4I4I4I4I4I4I4I4I4I4"):unpack(password)}
|
||||
password = {u16x4(fmt16x4, password, 1)}
|
||||
|
||||
-- Compute password blocks.
|
||||
local ikp = {}
|
||||
|
@ -127,8 +133,8 @@ local function pbkdf2(password, salt, iter)
|
|||
local pad96 = {2 ^ 31, 0, 0, 0, 0, 0, 0, 0x300}
|
||||
|
||||
-- First iteration.
|
||||
local pre = (">I4I4I4I4I4I4I4I4I4I4I4I4I4I4I4I4"):pack(unpack(ikp))
|
||||
local hs = {(">I4I4I4I4I4I4I4I4"):unpack(digest(pre .. salt .. "\0\0\0\1"))}
|
||||
local pre = p16x4(fmt16x4, unpack(ikp))
|
||||
local hs = {u8x4(fmt8x4, digest(pre .. salt .. "\0\0\0\1"), 1)}
|
||||
for i = 1, 8 do hs[i + 8] = pad96[i] end
|
||||
hs = compress(hokp, hs)
|
||||
|
||||
|
@ -142,7 +148,7 @@ local function pbkdf2(password, salt, iter)
|
|||
for i = 1, 8 do out[i] = bxor(out[i], hs[i]) end
|
||||
end
|
||||
|
||||
return (">I4I4I4I4I4I4I4I4"):pack(unpack(out))
|
||||
return p8x4(fmt8x4, unpack(out))
|
||||
end
|
||||
|
||||
return {
|
||||
|
|
Loading…
Reference in a new issue