382 lines
15 KiB
Lua
382 lines
15 KiB
Lua
--- Test vector specification for ChaCha20Poly1305AEAD.
|
|
--
|
|
-- Derived from RFC 7539.
|
|
--
|
|
|
|
local util = require "spec.util"
|
|
local aead = require "ccryptolib.aead"
|
|
|
|
describe("aead.encrypt", function()
|
|
it("validates arguments", function()
|
|
local key = ("a"):rep(32)
|
|
local nonce = ("a"):rep(12)
|
|
local msg = ("a"):rep(179)
|
|
local aad = ("a"):rep(79)
|
|
local rounds = 20
|
|
|
|
-- Types
|
|
expect.error(aead.encrypt, nil, nonce, msg, aad, rounds)
|
|
:eq("bad argument #1 (string expected, got nil)")
|
|
expect.error(aead.encrypt, key, nil, msg, aad, rounds)
|
|
:eq("bad argument #2 (string expected, got nil)")
|
|
expect.error(aead.encrypt, key, nonce, nil, aad, rounds)
|
|
:eq("bad argument #3 (string expected, got nil)")
|
|
expect.error(aead.encrypt, key, nonce, msg, nil, rounds)
|
|
:eq("bad argument #4 (string expected, got nil)")
|
|
expect.error(aead.encrypt, key, nonce, msg, aad, {})
|
|
:eq("bad argument #5 (number expected, got table)")
|
|
|
|
-- String lengths
|
|
expect.error(aead.encrypt, key .. "a", nonce, msg, aad, rounds)
|
|
:eq("key length must be 32")
|
|
expect.error(aead.encrypt, key, nonce .. "a", msg, aad, rounds)
|
|
:eq("nonce length must be 12")
|
|
|
|
-- Rounds
|
|
expect.error(aead.encrypt, key, nonce, msg, aad, 19.5)
|
|
:eq("round number must be even")
|
|
expect.error(aead.encrypt, key, nonce, msg, aad, 19)
|
|
:eq("round number must be even")
|
|
expect.error(aead.encrypt, key, nonce, msg, aad, 6)
|
|
:eq("round number must be no smaller than 8")
|
|
expect.error(aead.encrypt, key, nonce, msg, aad, 22)
|
|
:eq("round number must be no larger than 20")
|
|
expect.error(aead.encrypt, key, nonce, msg, aad, 1 / 0)
|
|
:eq("round number must be even")
|
|
expect.error(aead.encrypt, key, nonce, msg, aad, -1 / 0)
|
|
:eq("round number must be even")
|
|
expect.error(aead.encrypt, key, nonce, msg, aad, 0 / 0)
|
|
:eq("round number must be even")
|
|
end)
|
|
|
|
it("encrypts the section 2.8.2 test vector", function()
|
|
local plaintext = table.concat {
|
|
"Ladies and Gentlemen of the class of '99: If I could offer you o",
|
|
"nly one tip for the future, sunscreen would be it.",
|
|
}
|
|
|
|
local aad = util.hexcat {
|
|
"50 51 52 53 c0 c1 c2 c3 c4 c5 c6 c7",
|
|
}
|
|
|
|
local key = util.hexcat {
|
|
"80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f",
|
|
"90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f",
|
|
}
|
|
|
|
local nonce = util.hexcat {
|
|
"07 00 00 00 40 41 42 43 44 45 46 47",
|
|
}
|
|
|
|
local ciphertext = util.hexcat {
|
|
"d3 1a 8d 34 64 8e 60 db 7b 86 af bc 53 ef 7e c2",
|
|
"a4 ad ed 51 29 6e 08 fe a9 e2 b5 a7 36 ee 62 d6",
|
|
"3d be a4 5e 8c a9 67 12 82 fa fb 69 da 92 72 8b",
|
|
"1a 71 de 0a 9e 06 0b 29 05 d6 a5 b6 7e cd 3b 36",
|
|
"92 dd bd 7f 2d 77 8b 8c 98 03 ae e3 28 09 1b 58",
|
|
"fa b3 24 e4 fa d6 75 94 55 85 80 8b 48 31 d7 bc",
|
|
"3f f4 de f0 8e 4b 7a 9d e5 76 d2 65 86 ce c6 4b",
|
|
"61 16 ",
|
|
}
|
|
|
|
local tag = util.hexcat {
|
|
"1a:e1:0b:59:4f:09:e2:6a:7e:90:2e:cb:d0:60:06:91",
|
|
}
|
|
|
|
local cCiphertext, cTag = aead.encrypt(key, nonce, plaintext, aad)
|
|
|
|
expect(cCiphertext):equals(ciphertext)
|
|
expect(cTag):equals(tag)
|
|
end)
|
|
|
|
it("encrypts the appendix A.5 test vector", function()
|
|
local plaintext = table.concat {
|
|
"Internet-Drafts are draft documents valid for a maximum of six m",
|
|
"onths and may be updated, replaced, or obsoleted by other docume",
|
|
"nts at any time. It is inappropriate to use Internet-Drafts as r",
|
|
"eference material or to cite them other than as /\xe2\x80\x9cwor",
|
|
"k in progress./\xe2\x80\x9d",
|
|
}
|
|
|
|
local aad = util.hexcat {
|
|
"f3 33 88 86 00 00 00 00 00 00 4e 91",
|
|
}
|
|
|
|
local key = util.hexcat {
|
|
"1c 92 40 a5 eb 55 d3 8a f3 33 88 86 04 f6 b5 f0",
|
|
"47 39 17 c1 40 2b 80 09 9d ca 5c bc 20 70 75 c0",
|
|
}
|
|
|
|
local nonce = util.hexcat {
|
|
"00 00 00 00 01 02 03 04 05 06 07 08",
|
|
}
|
|
|
|
local ciphertext = util.hexcat {
|
|
"64 a0 86 15 75 86 1a f4 60 f0 62 c7 9b e6 43 bd",
|
|
"5e 80 5c fd 34 5c f3 89 f1 08 67 0a c7 6c 8c b2",
|
|
"4c 6c fc 18 75 5d 43 ee a0 9e e9 4e 38 2d 26 b0",
|
|
"bd b7 b7 3c 32 1b 01 00 d4 f0 3b 7f 35 58 94 cf",
|
|
"33 2f 83 0e 71 0b 97 ce 98 c8 a8 4a bd 0b 94 81",
|
|
"14 ad 17 6e 00 8d 33 bd 60 f9 82 b1 ff 37 c8 55",
|
|
"97 97 a0 6e f4 f0 ef 61 c1 86 32 4e 2b 35 06 38",
|
|
"36 06 90 7b 6a 7c 02 b0 f9 f6 15 7b 53 c8 67 e4",
|
|
"b9 16 6c 76 7b 80 4d 46 a5 9b 52 16 cd e7 a4 e9",
|
|
"90 40 c5 a4 04 33 22 5e e2 82 a1 b0 a0 6c 52 3e",
|
|
"af 45 34 d7 f8 3f a1 15 5b 00 47 71 8c bc 54 6a",
|
|
"0d 07 2b 04 b3 56 4e ea 1b 42 22 73 f5 48 27 1a",
|
|
"0b b2 31 60 53 fa 76 99 19 55 eb d6 31 59 43 4e",
|
|
"ce bb 4e 46 6d ae 5a 10 73 a6 72 76 27 09 7a 10",
|
|
"49 e6 17 d9 1d 36 10 94 fa 68 f0 ff 77 98 71 30",
|
|
"30 5b ea ba 2e da 04 df 99 7b 71 4d 6c 6f 2c 29",
|
|
"a6 ad 5c b4 02 2b 02 70 9b ",
|
|
}
|
|
|
|
local tag = util.hexcat {
|
|
"ee ad 9d 67 89 0c bb 22 39 23 36 fe a1 85 1f 38",
|
|
}
|
|
|
|
local cCiphertext, cTag = aead.encrypt(key, nonce, plaintext, aad)
|
|
|
|
expect(cCiphertext):equals(ciphertext)
|
|
expect(cTag):equals(tag)
|
|
end)
|
|
|
|
|
|
end)
|
|
|
|
describe("aead.decrypt", function()
|
|
it("validates arguments", function()
|
|
local key = ("a"):rep(32)
|
|
local nonce = ("a"):rep(12)
|
|
local tag = ("a"):rep(16)
|
|
local ctx = ("a"):rep(179)
|
|
local aad = ("a"):rep(79)
|
|
local rounds = 20
|
|
|
|
-- Types
|
|
expect.error(aead.decrypt, nil, nonce, tag, ctx, aad, rounds)
|
|
:eq("bad argument #1 (string expected, got nil)")
|
|
expect.error(aead.decrypt, key, nil, tag, ctx, aad, rounds)
|
|
:eq("bad argument #2 (string expected, got nil)")
|
|
expect.error(aead.decrypt, key, nonce, nil, ctx, aad, rounds)
|
|
:eq("bad argument #3 (string expected, got nil)")
|
|
expect.error(aead.decrypt, key, nonce, tag, nil, aad, rounds)
|
|
:eq("bad argument #4 (string expected, got nil)")
|
|
expect.error(aead.decrypt, key, nonce, tag, ctx, nil, rounds)
|
|
:eq("bad argument #5 (string expected, got nil)")
|
|
expect.error(aead.decrypt, key, nonce, tag, ctx, aad, {})
|
|
:eq("bad argument #6 (number expected, got table)")
|
|
|
|
-- String lengths
|
|
expect.error(aead.decrypt, key .. "a", nonce, tag, ctx, aad, rounds)
|
|
:eq("key length must be 32")
|
|
expect.error(aead.decrypt, key, nonce .. "a", tag, ctx, aad, rounds)
|
|
:eq("nonce length must be 12")
|
|
expect.error(aead.decrypt, key, nonce, tag .. "a", ctx, aad, rounds)
|
|
:eq("tag length must be 16")
|
|
|
|
-- Rounds
|
|
expect.error(aead.decrypt, key, nonce, tag, ctx, aad, 19.5)
|
|
:eq("round number must be even")
|
|
expect.error(aead.decrypt, key, nonce, tag, ctx, aad, 19)
|
|
:eq("round number must be even")
|
|
expect.error(aead.decrypt, key, nonce, tag, ctx, aad, 6)
|
|
:eq("round number must be no smaller than 8")
|
|
expect.error(aead.decrypt, key, nonce, tag, ctx, aad, 22)
|
|
:eq("round number must be no larger than 20")
|
|
expect.error(aead.decrypt, key, nonce, tag, ctx, aad, 1 / 0)
|
|
:eq("round number must be even")
|
|
expect.error(aead.decrypt, key, nonce, tag, ctx, aad, -1 / 0)
|
|
:eq("round number must be even")
|
|
expect.error(aead.decrypt, key, nonce, tag, ctx, aad, 0 / 0)
|
|
:eq("round number must be even")
|
|
end)
|
|
|
|
it("decrypts the section 2.8.2 test vector", function()
|
|
local plaintext = table.concat {
|
|
"Ladies and Gentlemen of the class of '99: If I could offer you o",
|
|
"nly one tip for the future, sunscreen would be it.",
|
|
}
|
|
|
|
local aad = util.hexcat {
|
|
"50 51 52 53 c0 c1 c2 c3 c4 c5 c6 c7",
|
|
}
|
|
|
|
local key = util.hexcat {
|
|
"80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f",
|
|
"90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f",
|
|
}
|
|
|
|
local nonce = util.hexcat {
|
|
"07 00 00 00 40 41 42 43 44 45 46 47",
|
|
}
|
|
|
|
local ciphertext = util.hexcat {
|
|
"d3 1a 8d 34 64 8e 60 db 7b 86 af bc 53 ef 7e c2",
|
|
"a4 ad ed 51 29 6e 08 fe a9 e2 b5 a7 36 ee 62 d6",
|
|
"3d be a4 5e 8c a9 67 12 82 fa fb 69 da 92 72 8b",
|
|
"1a 71 de 0a 9e 06 0b 29 05 d6 a5 b6 7e cd 3b 36",
|
|
"92 dd bd 7f 2d 77 8b 8c 98 03 ae e3 28 09 1b 58",
|
|
"fa b3 24 e4 fa d6 75 94 55 85 80 8b 48 31 d7 bc",
|
|
"3f f4 de f0 8e 4b 7a 9d e5 76 d2 65 86 ce c6 4b",
|
|
"61 16 ",
|
|
}
|
|
|
|
local tag = util.hexcat {
|
|
"1a:e1:0b:59:4f:09:e2:6a:7e:90:2e:cb:d0:60:06:91",
|
|
}
|
|
|
|
expect(aead.decrypt(key, nonce, tag, ciphertext, aad))
|
|
:eq(plaintext)
|
|
end)
|
|
|
|
it("returns nil on invalid ciphertext", function()
|
|
local aad = util.hexcat {
|
|
"50 51 52 53 c0 c1 c2 c3 c4 c5 c6 c7",
|
|
}
|
|
|
|
local key = util.hexcat {
|
|
"80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f",
|
|
"90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f",
|
|
}
|
|
|
|
local nonce = util.hexcat {
|
|
"07 00 00 00 40 41 42 43 44 45 46 47",
|
|
}
|
|
|
|
local ciphertext = util.hexcat {
|
|
"d3 1a 8d 34 64 8e 60 db 7b 86 af bc 53 ef 7e c3", -- Bit flip
|
|
"a4 ad ed 51 29 6e 08 fe a9 e2 b5 a7 36 ee 62 d6",
|
|
"3d be a4 5e 8c a9 67 12 82 fa fb 69 da 92 72 8b",
|
|
"1a 71 de 0a 9e 06 0b 29 05 d6 a5 b6 7e cd 3b 36",
|
|
"92 dd bd 7f 2d 77 8b 8c 98 03 ae e3 28 09 1b 58",
|
|
"fa b3 24 e4 fa d6 75 94 55 85 80 8b 48 31 d7 bc",
|
|
"3f f4 de f0 8e 4b 7a 9d e5 76 d2 65 86 ce c6 4b",
|
|
"61 16 ",
|
|
}
|
|
|
|
local tag = util.hexcat {
|
|
"1a:e1:0b:59:4f:09:e2:6a:7e:90:2e:cb:d0:60:06:91",
|
|
}
|
|
|
|
expect(aead.decrypt(key, nonce, tag, ciphertext, aad))
|
|
:eq(nil)
|
|
end)
|
|
|
|
it("returns nil on invalid AAD", function()
|
|
local aad = util.hexcat {
|
|
"50 51 52 53 c0 c1 c2 c3 c4 c5 c6 c6", -- Bit flip
|
|
}
|
|
|
|
local key = util.hexcat {
|
|
"80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f",
|
|
"90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f",
|
|
}
|
|
|
|
local nonce = util.hexcat {
|
|
"07 00 00 00 40 41 42 43 44 45 46 47",
|
|
}
|
|
|
|
local ciphertext = util.hexcat {
|
|
"d3 1a 8d 34 64 8e 60 db 7b 86 af bc 53 ef 7e c2",
|
|
"a4 ad ed 51 29 6e 08 fe a9 e2 b5 a7 36 ee 62 d6",
|
|
"3d be a4 5e 8c a9 67 12 82 fa fb 69 da 92 72 8b",
|
|
"1a 71 de 0a 9e 06 0b 29 05 d6 a5 b6 7e cd 3b 36",
|
|
"92 dd bd 7f 2d 77 8b 8c 98 03 ae e3 28 09 1b 58",
|
|
"fa b3 24 e4 fa d6 75 94 55 85 80 8b 48 31 d7 bc",
|
|
"3f f4 de f0 8e 4b 7a 9d e5 76 d2 65 86 ce c6 4b",
|
|
"61 16 ",
|
|
}
|
|
|
|
local tag = util.hexcat {
|
|
"1a:e1:0b:59:4f:09:e2:6a:7e:90:2e:cb:d0:60:06:91",
|
|
}
|
|
|
|
expect(aead.decrypt(key, nonce, tag, ciphertext, aad))
|
|
:eq(nil)
|
|
end)
|
|
|
|
it("returns nil on invalid tag", function()
|
|
local aad = util.hexcat {
|
|
"50 51 52 53 c0 c1 c2 c3 c4 c5 c6 c7",
|
|
}
|
|
|
|
local key = util.hexcat {
|
|
"80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f",
|
|
"90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f",
|
|
}
|
|
|
|
local nonce = util.hexcat {
|
|
"07 00 00 00 40 41 42 43 44 45 46 47",
|
|
}
|
|
|
|
local ciphertext = util.hexcat {
|
|
"d3 1a 8d 34 64 8e 60 db 7b 86 af bc 53 ef 7e c2",
|
|
"a4 ad ed 51 29 6e 08 fe a9 e2 b5 a7 36 ee 62 d6",
|
|
"3d be a4 5e 8c a9 67 12 82 fa fb 69 da 92 72 8b",
|
|
"1a 71 de 0a 9e 06 0b 29 05 d6 a5 b6 7e cd 3b 36",
|
|
"92 dd bd 7f 2d 77 8b 8c 98 03 ae e3 28 09 1b 58",
|
|
"fa b3 24 e4 fa d6 75 94 55 85 80 8b 48 31 d7 bc",
|
|
"3f f4 de f0 8e 4b 7a 9d e5 76 d2 65 86 ce c6 4b",
|
|
"61 16 ",
|
|
}
|
|
|
|
local tag = util.hexcat {
|
|
"1a:e1:0b:59:4f:09:e2:6a:7e:90:2e:cb:d0:60:06:90", -- Bit flip
|
|
}
|
|
|
|
expect(aead.decrypt(key, nonce, tag, ciphertext, aad))
|
|
:eq(nil)
|
|
end)
|
|
|
|
it("decrypts the appendix A.5 test vector", function()
|
|
local plaintext = table.concat {
|
|
"Internet-Drafts are draft documents valid for a maximum of six m",
|
|
"onths and may be updated, replaced, or obsoleted by other docume",
|
|
"nts at any time. It is inappropriate to use Internet-Drafts as r",
|
|
"eference material or to cite them other than as /\xe2\x80\x9cwor",
|
|
"k in progress./\xe2\x80\x9d",
|
|
}
|
|
|
|
local aad = util.hexcat {
|
|
"f3 33 88 86 00 00 00 00 00 00 4e 91",
|
|
}
|
|
|
|
local key = util.hexcat {
|
|
"1c 92 40 a5 eb 55 d3 8a f3 33 88 86 04 f6 b5 f0",
|
|
"47 39 17 c1 40 2b 80 09 9d ca 5c bc 20 70 75 c0",
|
|
}
|
|
|
|
local nonce = util.hexcat {
|
|
"00 00 00 00 01 02 03 04 05 06 07 08",
|
|
}
|
|
|
|
local ciphertext = util.hexcat {
|
|
"64 a0 86 15 75 86 1a f4 60 f0 62 c7 9b e6 43 bd",
|
|
"5e 80 5c fd 34 5c f3 89 f1 08 67 0a c7 6c 8c b2",
|
|
"4c 6c fc 18 75 5d 43 ee a0 9e e9 4e 38 2d 26 b0",
|
|
"bd b7 b7 3c 32 1b 01 00 d4 f0 3b 7f 35 58 94 cf",
|
|
"33 2f 83 0e 71 0b 97 ce 98 c8 a8 4a bd 0b 94 81",
|
|
"14 ad 17 6e 00 8d 33 bd 60 f9 82 b1 ff 37 c8 55",
|
|
"97 97 a0 6e f4 f0 ef 61 c1 86 32 4e 2b 35 06 38",
|
|
"36 06 90 7b 6a 7c 02 b0 f9 f6 15 7b 53 c8 67 e4",
|
|
"b9 16 6c 76 7b 80 4d 46 a5 9b 52 16 cd e7 a4 e9",
|
|
"90 40 c5 a4 04 33 22 5e e2 82 a1 b0 a0 6c 52 3e",
|
|
"af 45 34 d7 f8 3f a1 15 5b 00 47 71 8c bc 54 6a",
|
|
"0d 07 2b 04 b3 56 4e ea 1b 42 22 73 f5 48 27 1a",
|
|
"0b b2 31 60 53 fa 76 99 19 55 eb d6 31 59 43 4e",
|
|
"ce bb 4e 46 6d ae 5a 10 73 a6 72 76 27 09 7a 10",
|
|
"49 e6 17 d9 1d 36 10 94 fa 68 f0 ff 77 98 71 30",
|
|
"30 5b ea ba 2e da 04 df 99 7b 71 4d 6c 6f 2c 29",
|
|
"a6 ad 5c b4 02 2b 02 70 9b ",
|
|
}
|
|
|
|
local tag = util.hexcat {
|
|
"ee ad 9d 67 89 0c bb 22 39 23 36 fe a1 85 1f 38",
|
|
}
|
|
|
|
expect(aead.decrypt(key, nonce, tag, ciphertext, aad))
|
|
:eq(plaintext)
|
|
end)
|
|
end)
|