From 77dfbae8438d48117a7bf9b1bd16fe3766966e80 Mon Sep 17 00:00:00 2001 From: Miguel Oliveira Date: Mon, 2 Jan 2023 20:56:35 -0300 Subject: [PATCH] Switch argument validation back to assertions --- ccryptolib/aead.lua | 24 ++++++++++++------------ ccryptolib/blake3.lua | 27 ++++++++++++++------------- ccryptolib/chacha20.lua | 17 +++++++++-------- ccryptolib/ed25519.lua | 9 +++++---- ccryptolib/internal/util.lua | 6 ++++++ ccryptolib/poly1305.lua | 18 ++---------------- ccryptolib/sha256.lua | 5 +++-- ccryptolib/x25519.lua | 9 +++++---- ccryptolib/x25519c.lua | 25 +++++++++++++------------ spec/blake3_spec.lua | 30 +++++++++++++++--------------- 10 files changed, 84 insertions(+), 86 deletions(-) diff --git a/ccryptolib/aead.lua b/ccryptolib/aead.lua index 9821cfa..0ec8b04 100644 --- a/ccryptolib/aead.lua +++ b/ccryptolib/aead.lua @@ -4,6 +4,7 @@ -- local expect = require "cc.expect".expect +local lassert = require "ccryptolib.internal.util".lassert local packing = require "ccryptolib.internal.packing" local chacha20 = require "ccryptolib.chacha20" local poly1305 = require "ccryptolib.poly1305" @@ -11,7 +12,6 @@ local poly1305 = require "ccryptolib.poly1305" local p8x1, fmt8x1 = packing.compilePack(" 20 then error("round number must be no larger than 20", 2) end + lassert(rounds % 2 == 0, "round number must be even", 2) + lassert(rounds >= 8, "round number must be no smaller than 8", 2) + lassert(rounds <= 20, "round number must be no larger than 20", 2) -- Generate auth key and encrypt. local msgLong = ("\0"):rep(64) .. message @@ -65,17 +65,17 @@ end -- local function decrypt(key, nonce, tag, ciphertext, aad, rounds) expect(1, key, "string") - if #key ~= 32 then error("key length must be 32", 2) end + lassert(#key == 32, "key length must be 32", 2) expect(2, nonce, "string") - if #nonce ~= 12 then error("nonce length must be 12", 2) end + lassert(#nonce == 12, "nonce length must be 12", 2) expect(3, tag, "string") - if #tag ~= 16 then error("tag length must be 16", 2) end + lassert(#tag == 16, "tag length must be 16", 2) expect(4, ciphertext, "string") expect(5, aad, "string") rounds = expect(6, rounds, "number", "nil") or 20 - if rounds % 2 ~= 0 then error("round number must be even", 2) end - if rounds < 8 then error("round number must be no smaller than 8", 2) end - if rounds > 20 then error("round number must be no larger than 20", 2) end + lassert(rounds % 2 == 0, "round number must be even", 2) + lassert(rounds >= 8, "round number must be no smaller than 8", 2) + lassert(rounds <= 20, "round number must be no larger than 20", 2) -- Generate auth key. local authKey = chacha20.crypt(key, nonce, ("\0"):rep(32), rounds, 0) diff --git a/ccryptolib/blake3.lua b/ccryptolib/blake3.lua index 9fd2f73..015ae4c 100644 --- a/ccryptolib/blake3.lua +++ b/ccryptolib/blake3.lua @@ -4,6 +4,7 @@ -- local expect = require "cc.expect".expect +local lassert = require "ccryptolib.internal.util".lassert local packing = require "ccryptolib.internal.packing" local unpack = unpack or table.unpack @@ -125,12 +126,12 @@ end local function expand(state, len, offset) expect(1, state, "table") expect(1, len, "number") - if len % 1 ~= 0 then error("length must be an integer", 2) end - if len < 1 then error("length must be positive", 2) end + lassert(len % 1 == 0, "desired output length must be an integer", 2) + lassert(len >= 1, "desired output length must be positive", 2) offset = expect(2, offset, "nil", "number") or 0 - if offset % 1 ~= 0 then error("offset must be an integer", 2) end - if offset < 0 then error("offset must be nonnegative", 2) end - if offset + len > 2 ^ 32 then error("offset is too large", 2) end + lassert(offset % 1 == 0, "offset must be an integer", 2) + lassert(offset >= 0, "offset must be nonnegative", 2) + lassert(offset + len <= 2 ^ 32, "offset is too large", 2) -- Expand output. local out = {} @@ -276,7 +277,7 @@ end function mod.newKeyed(key) expect(1, key, "string") - if #key ~= 32 then error("key length must be 32", 2) end + lassert(#key == 32, "key length must be 32", 2) return new({u8x4(fmt8x4, key, 1)}, KEYED_HASH) end @@ -295,8 +296,8 @@ end function mod.digest(message, len) expect(1, message, "string") len = expect(2, len, "number", "nil") or 32 - if len % 1 ~= 0 then error("length must be an integer", 2) end - if len < 1 then error("length must be positive", 2) end + lassert(len % 1 == 0, "desired output length must be an integer", 2) + lassert(len >= 1, "desired output length must be positive", 2) return new(IV, 0):update(message):finalize():expand(len) end @@ -309,11 +310,11 @@ end -- function mod.digestKeyed(key, message, len) expect(1, key, "string") - if #key ~= 32 then error("key length must be 32", 2) end + lassert(#key == 32, "key length must be 32", 2) expect(2, message, "string") len = expect(3, len, "number", "nil") or 32 - if len % 1 ~= 0 then error("length must be an integer", 2) end - if len < 1 then error("length must be positive", 2) end + lassert(len % 1 == 0, "desired output length must be an integer", 2) + lassert(len >= 1, "desired output length must be positive", 2) local h = new({u8x4(fmt8x4, key, 1)}, KEYED_HASH) return h:update(message):finalize():expand(len) end @@ -330,8 +331,8 @@ function mod.deriveKey(context) return function(material, len) expect(1, material, "string") len = expect(2, len, "number", "nil") or 32 - if len % 1 ~= 0 then error("length must be an integer", 2) end - if len < 1 then error("length must be positive", 2) end + lassert(len % 1 == 0, "desired output length must be an integer", 2) + lassert(len >= 1, "desired output length must be positive", 2) local h = new({u8x4(fmt8x4, iv, 1)}, DERIVE_KEY_MATERIAL) return h:update(material):finalize():expand(len) end diff --git a/ccryptolib/chacha20.lua b/ccryptolib/chacha20.lua index 34c21df..d4642aa 100644 --- a/ccryptolib/chacha20.lua +++ b/ccryptolib/chacha20.lua @@ -4,6 +4,7 @@ -- local expect = require "cc.expect".expect +local lassert = require "ccryptolib.internal.util".lassert local packing = require "ccryptolib.internal.packing" local bxor = bit32.bxor @@ -26,18 +27,18 @@ local mod = {} -- function mod.crypt(key, nonce, message, rounds, offset) expect(1, key, "string") - if #key ~= 32 then error("key length must be 32", 2) end + lassert(#key == 32, "key length must be 32", 2) expect(2, nonce, "string") - if #nonce ~= 12 then error("nonce length must be 12", 2) end + lassert(#nonce == 12, "nonce length must be 12", 2) expect(3, message, "string") rounds = expect(4, rounds, "number", "nil") or 20 - if rounds % 2 ~= 0 then error("round number must be even", 2) end - if rounds < 8 then error("round number must be no smaller than 8", 2) end - if rounds > 20 then error("round number must be no larger than 20", 2) end + lassert(rounds % 2 == 0, "round number must be even", 2) + lassert(rounds >= 8, "round number must be no smaller than 8", 2) + lassert(rounds <= 20, "round number must be no larger than 20", 2) offset = expect(5, offset, "number", "nil") or 1 - if offset % 1 ~= 0 then error("offset must be an integer", 2) end - if offset < 0 then error("offset must be nonnegative", 2) end - if #message + 64 * offset >= 2 ^ 37 then error("offset too large", 2) end + lassert(offset % 1 == 0, "offset must be an integer", 2) + lassert(offset >= 0, "offset must be nonnegative", 2) + lassert(#message + 64 * offset <= 2 ^ 38, "offset too large", 2) -- Build the state block. local i0, i1, i2, i3 = 0x61707865, 0x3320646e, 0x79622d32, 0x6b206574 diff --git a/ccryptolib/ed25519.lua b/ccryptolib/ed25519.lua index 01b2036..ae921a4 100644 --- a/ccryptolib/ed25519.lua +++ b/ccryptolib/ed25519.lua @@ -4,6 +4,7 @@ -- local expect = require "cc.expect".expect +local lassert = require "ccryptolib.internal.util".lassert local fq = require "ccryptolib.internal.fq" local sha512 = require "ccryptolib.internal.sha512" local ed = require "ccryptolib.internal.edwards25519" @@ -35,9 +36,9 @@ end -- function mod.sign(sk, pk, msg) expect(1, sk, "string") - assert(#sk == 32, "secret key length must be 32") + lassert(#sk == 32, "secret key length must be 32", 2) expect(2, pk, "string") - assert(#pk == 32, "public key length must be 32") + lassert(#pk == 32, "public key length must be 32", 2) expect(3, msg, "string") -- Secret key. @@ -69,10 +70,10 @@ end -- function mod.verify(pk, msg, sig) expect(1, pk, "string") - assert(#pk == 32, "public key length must be 32") + lassert(#pk == 32, "public key length must be 32", 2) expect(2, msg, "string") expect(3, sig, "string") - assert(#sig == 64, "signature length must be 64") + lassert(#sig == 64, "signature length must be 64", 2) local y = ed.decode(pk) if not y then return nil end diff --git a/ccryptolib/internal/util.lua b/ccryptolib/internal/util.lua index 558857c..e5695ab 100644 --- a/ccryptolib/internal/util.lua +++ b/ccryptolib/internal/util.lua @@ -1,3 +1,8 @@ +local function lassert(val, err, level) + if not val then error(err, level + 1) end + return val +end + --- Converts a little-endian array from one power-of-two base to another. -- -- @tparam {number...} a The array to convert, in little-endian. @@ -65,6 +70,7 @@ local function bits8(str) end return { + lassert = lassert, rebaseLE = rebaseLE, bits = bits, bits8 = bits8, diff --git a/ccryptolib/poly1305.lua b/ccryptolib/poly1305.lua index 6410b7e..b3839a5 100644 --- a/ccryptolib/poly1305.lua +++ b/ccryptolib/poly1305.lua @@ -4,7 +4,7 @@ -- local expect = require "cc.expect".expect -local random = require "ccryptolib.random" +local lassert = require "ccryptolib.internal.util".lassert local packing = require "ccryptolib.internal.packing" local u4x4, fmt4x4 = packing.compileUnpack(" 0, "iteration number must be positive") + lassert(iter % 1 == 0, "iteration number must be an integer", 2) + lassert(iter > 0, "iteration number must be positive", 2) -- Pad password. if #password > 64 then password = digest(password) end diff --git a/ccryptolib/x25519.lua b/ccryptolib/x25519.lua index 6c71ac7..ad6ab87 100644 --- a/ccryptolib/x25519.lua +++ b/ccryptolib/x25519.lua @@ -4,6 +4,7 @@ -- local expect = require "cc.expect".expect +local lassert = require "ccryptolib.internal.util".lassert local util = require "ccryptolib.internal.util" local c25 = require "ccryptolib.internal.curve25519" @@ -28,18 +29,18 @@ end -- function mod.exchange(sk, pk) expect(1, sk, "string") - assert(#sk == 32, "secret key length must be 32") + lassert(#sk == 32, "secret key length must be 32", 2) expect(2, pk, "string") - assert(#pk == 32, "public key length must be 32") + lassert(#pk == 32, "public key length must be 32", 2) return c25.encode(c25.scale(c25.ladder8(c25.decode(pk), util.bits8(sk)))) end --- Same as @{exchange}, but decodes the public key as an Edwards25519 point. function mod.exchangeEd(sk, pk) expect(1, sk, "string") - assert(#sk == 32, "secret key length must be 32") + lassert(#sk == 32, "secret key length must be 32", 2) expect(2, pk, "string") - assert(#pk == 32, "public key length must be 32") + lassert(#pk == 32, "public key length must be 32", 2) return c25.encode(c25.scale(c25.ladder8(c25.decodeEd(pk), util.bits8(sk)))) end diff --git a/ccryptolib/x25519c.lua b/ccryptolib/x25519c.lua index 406a1f4..f3f6385 100644 --- a/ccryptolib/x25519c.lua +++ b/ccryptolib/x25519c.lua @@ -1,4 +1,5 @@ local expect = require "cc.expect".expect +local lassert = require "ccryptolib.internal.util".lassert local fq = require "ccryptolib.internal.fq" local fp = require "ccryptolib.internal.fp" local c25 = require "ccryptolib.internal.curve25519" @@ -9,7 +10,7 @@ local random = require "ccryptolib.random" --- Masks an exchange secret key. local function maskX(sk) expect(1, sk, "string") - assert(#sk == 32, "secret key length must be 32") + lassert(#sk == 32, "secret key length must be 32", 2) local mask = random.random(32) local x = fq.decodeClamped(sk) local r = fq.decodeClamped(mask) @@ -20,14 +21,14 @@ end --- Masks a signature secret key. function maskS(sk) expect(1, sk, "string") - assert(#sk == 32, "secret key length must be 32") + lassert(#sk == 32, "secret key length must be 32", 2) return maskX(sha512.digest(sk):sub(1, 32)) end --- Rerandomizes the masking on a masked key. local function remask(sk) expect(1, sk, "string") - assert(#sk == 64, "masked secret key length must be 64") + lassert(#sk == 64, "masked secret key length must be 64", 2) local newMask = random.random(32) local xr = fq.decode(sk:sub(1, 32)) local r = fq.decodeClamped(sk:sub(33)) @@ -44,7 +45,7 @@ end -- local function ephemeralSk(sk) expect(1, sk, "string") - assert(#sk == 64, "masked secret key length must be 64") + lassert(#sk == 64, "masked secret key length must be 64", 2) return sk:sub(33) end @@ -109,14 +110,14 @@ end --- Returns the X25519 public key of this masked key. local function publicKeyX(sk) expect(1, sk, "string") - assert(#sk == 64, "masked secret key length must be 64") + lassert(#sk == 64, "masked secret key length must be 64", 2) return (exchangeOnPoint(sk, c25.G)) end --- Returns the Ed25519 public key of this masked key. local function publicKeyS(sk) expect(1, sk, "string") - assert(#sk == 64, "masked secret key length must be 64") + lassert(#sk == 64, "masked secret key length must be 64", 2) local xr = fq.decode(sk:sub(1, 32)) local r = fq.decodeClamped(sk:sub(33)) local y = ed.add(ed.mulG(fq.bits(xr)), ed.niels(ed.mulG(fq.bits(r)))) @@ -134,9 +135,9 @@ end -- local function exchangeX(sk, pk) expect(1, sk, "string") - assert(#sk == 64, "masked secret key length must be 64") + lassert(#sk == 64, "masked secret key length must be 64", 2) expect(2, pk, "string") - assert(#pk == 32, "public key length must be 32") + lassert(#pk == 32, "public key length must be 32", 2) return exchangeOnPoint(sk, c25.decode(pk)) end @@ -148,18 +149,18 @@ end -- local function exchangeS(sk, pk) expect(1, sk, "string") - assert(#sk == 64, "masked secret key length must be 64") + lassert(#sk == 64, "masked secret key length must be 64", 2) expect(2, pk, "string") - assert(#pk == 32, "public key length must be 32") + lassert(#pk == 32, "public key length must be 32", 2) return exchangeOnPoint(sk, c25.decodeEd(pk)) end --- Signs a message using Ed25519. local function sign(sk, pk, msg) expect(1, sk, "string") - assert(#sk == 64, "masked secret key length must be 64") + lassert(#sk == 64, "masked secret key length must be 64", 2) expect(2, pk, "string") - assert(#pk == 32, "public key length must be 32") + lassert(#pk == 32, "public key length must be 32", 2) expect(3, msg, "string") -- Secret key. diff --git a/spec/blake3_spec.lua b/spec/blake3_spec.lua index 09b998f..d2a3511 100644 --- a/spec/blake3_spec.lua +++ b/spec/blake3_spec.lua @@ -24,15 +24,15 @@ describe("blake3.digest", function() -- Length expect.error(blake3.digest, "", 0.5) - :eq("length must be an integer") + :eq("desired output length must be an integer") expect.error(blake3.digest, "", 0) - :eq("length must be positive") + :eq("desired output length must be positive") expect.error(blake3.digest, "", 1 / 0) - :eq("length must be an integer") + :eq("desired output length must be an integer") expect.error(blake3.digest, "", -1 / 0) - :eq("length must be an integer") + :eq("desired output length must be an integer") expect.error(blake3.digest, "", 0 / 0) - :eq("length must be an integer") + :eq("desired output length must be an integer") end) if not hasVecs then @@ -68,15 +68,15 @@ describe("blake3.digestKeyed", function() -- Length expect.error(blake3.digestKeyed, key, "", 0.5) - :eq("length must be an integer") + :eq("desired output length must be an integer") expect.error(blake3.digestKeyed, key, "", 0) - :eq("length must be positive") + :eq("desired output length must be positive") expect.error(blake3.digestKeyed, key, "", 1 / 0) - :eq("length must be an integer") + :eq("desired output length must be an integer") expect.error(blake3.digestKeyed, key, "", -1 / 0) - :eq("length must be an integer") + :eq("desired output length must be an integer") expect.error(blake3.digestKeyed, key, "", 0 / 0) - :eq("length must be an integer") + :eq("desired output length must be an integer") end) if not hasVecs then @@ -107,15 +107,15 @@ describe("blake3.deriveKey", function() -- Length expect.error(blake3.deriveKey(""), "", 0.5) - :eq("length must be an integer") + :eq("desired output length must be an integer") expect.error(blake3.deriveKey(""), "", 0) - :eq("length must be positive") + :eq("desired output length must be positive") expect.error(blake3.deriveKey(""), "", 1 / 0) - :eq("length must be an integer") + :eq("desired output length must be an integer") expect.error(blake3.deriveKey(""), "", -1 / 0) - :eq("length must be an integer") + :eq("desired output length must be an integer") expect.error(blake3.deriveKey(""), "", 0 / 0) - :eq("length must be an integer") + :eq("desired output length must be an integer") end) if not hasVecs then