204 lines
8.6 KiB
Lua
204 lines
8.6 KiB
Lua
--- Test vector specification for ChaCha20.
|
|
--
|
|
-- Derived from RFC 7539.
|
|
--
|
|
|
|
local util = require "spec.util"
|
|
local chacha20 = require "ccryptolib.chacha20"
|
|
|
|
describe("chacha20.crypt", function()
|
|
it("validates arguments", function()
|
|
local key = ("a"):rep(32)
|
|
local nonce = ("a"):rep(12)
|
|
local msg = ("a"):rep(179)
|
|
local rounds = 20
|
|
local offset = 1
|
|
|
|
-- Types
|
|
expect.error(chacha20.crypt, nil, nonce, msg, rounds, offset)
|
|
:eq("bad argument #1 (string expected, got nil)")
|
|
expect.error(chacha20.crypt, key, nil, msg, rounds, offset)
|
|
:eq("bad argument #2 (string expected, got nil)")
|
|
expect.error(chacha20.crypt, key, nonce, nil, rounds, offset)
|
|
:eq("bad argument #3 (string expected, got nil)")
|
|
expect.error(chacha20.crypt, key, nonce, msg, {}, offset)
|
|
:eq("bad argument #4 (number expected, got table)")
|
|
expect.error(chacha20.crypt, key, nonce, msg, nil, {})
|
|
:eq("bad argument #5 (number expected, got table)")
|
|
|
|
-- String lengths
|
|
expect.error(chacha20.crypt, key .. "a", nonce, msg, rounds, offset)
|
|
:eq("key length must be 32")
|
|
expect.error(chacha20.crypt, key, nonce .. "a", msg, rounds, offset)
|
|
:eq("nonce length must be 12")
|
|
|
|
-- Rounds
|
|
expect.error(chacha20.crypt, key, nonce, msg, 19.5, offset)
|
|
:eq("round number must be even")
|
|
expect.error(chacha20.crypt, key, nonce, msg, 19, offset)
|
|
:eq("round number must be even")
|
|
expect.error(chacha20.crypt, key, nonce, msg, 6, offset)
|
|
:eq("round number must be no smaller than 8")
|
|
expect.error(chacha20.crypt, key, nonce, msg, 22, offset)
|
|
:eq("round number must be no larger than 20")
|
|
expect.error(chacha20.crypt, key, nonce, msg, 1 / 0, offset)
|
|
:eq("round number must be even")
|
|
expect.error(chacha20.crypt, key, nonce, msg, -1 / 0, offset)
|
|
:eq("round number must be even")
|
|
expect.error(chacha20.crypt, key, nonce, msg, 0 / 0, offset)
|
|
:eq("round number must be even")
|
|
|
|
-- Offset
|
|
expect.error(chacha20.crypt, key, nonce, msg, rounds, 1.1)
|
|
:eq("offset must be an integer")
|
|
expect.error(chacha20.crypt, key, nonce, msg, rounds, -1)
|
|
:eq("offset must be nonnegative")
|
|
expect.error(chacha20.crypt, key, nonce, msg, rounds, 2 ^ 32)
|
|
:eq("offset too large")
|
|
expect.error(chacha20.crypt, key, nonce, msg, rounds, 1 / 0)
|
|
:eq("offset must be an integer")
|
|
expect.error(chacha20.crypt, key, nonce, msg, rounds, -1 / 0)
|
|
:eq("offset must be an integer")
|
|
expect.error(chacha20.crypt, key, nonce, msg, rounds, 0 / 0)
|
|
:eq("offset must be an integer")
|
|
end)
|
|
|
|
it("encrypts the section 2.4.2 test vector", function()
|
|
local key = util.hexcat {
|
|
"00:01:02:03:04:05:06:07:08:09:0a:0b:0c:0d:0e:0f",
|
|
"10:11:12:13:14:15:16:17:18:19:1a:1b:1c:1d:1e:1f",
|
|
}
|
|
|
|
local nonce = util.hexcat {
|
|
"00:00:00:00:00:00:00:4a:00:00:00:00"
|
|
}
|
|
|
|
local plaintextSunscreen = 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 ciphertextSunscreen = util.hexcat {
|
|
"6e 2e 35 9a 25 68 f9 80 41 ba 07 28 dd 0d 69 81",
|
|
"e9 7e 7a ec 1d 43 60 c2 0a 27 af cc fd 9f ae 0b",
|
|
"f9 1b 65 c5 52 47 33 ab 8f 59 3d ab cd 62 b3 57",
|
|
"16 39 d6 24 e6 51 52 ab 8f 53 0c 35 9f 08 61 d8",
|
|
"07 ca 0d bf 50 0d 6a 61 56 a3 8e 08 8a 22 b6 5e",
|
|
"52 bc 51 4d 16 cc f8 06 81 8c e9 1a b7 79 37 36",
|
|
"5a f9 0b bf 74 a3 5b e6 b4 0b 8e ed f2 78 5e 42",
|
|
"87 4d ",
|
|
}
|
|
|
|
expect(chacha20.crypt(key, nonce, plaintextSunscreen))
|
|
:eq(ciphertextSunscreen)
|
|
end)
|
|
|
|
it("encrypts the appendix A.2 test vector #1", function()
|
|
local key = util.hexcat {
|
|
"00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
|
|
"00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
|
|
}
|
|
|
|
local nonce = util.hexcat {
|
|
"00 00 00 00 00 00 00 00 00 00 00 00",
|
|
}
|
|
|
|
local plaintext = util.hexcat {
|
|
"00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
|
|
"00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
|
|
"00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
|
|
"00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
|
|
}
|
|
|
|
local ciphertext = util.hexcat {
|
|
"76 b8 e0 ad a0 f1 3d 90 40 5d 6a e5 53 86 bd 28",
|
|
"bd d2 19 b8 a0 8d ed 1a a8 36 ef cc 8b 77 0d c7",
|
|
"da 41 59 7c 51 57 48 8d 77 24 e0 3f b8 d8 4a 37",
|
|
"6a 43 b8 f4 15 18 a1 1c c3 87 b6 69 b2 ee 65 86",
|
|
}
|
|
|
|
expect(chacha20.crypt(key, nonce, plaintext, 20, 0))
|
|
:eq(ciphertext)
|
|
end)
|
|
|
|
it("encrypts the appendix A.2 test vector #2", function()
|
|
local key = util.hexcat {
|
|
"00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
|
|
"00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01",
|
|
}
|
|
|
|
local nonce = util.hexcat {
|
|
"00 00 00 00 00 00 00 00 00 00 00 02",
|
|
}
|
|
|
|
local plaintext = table.concat {
|
|
"Any submission to the IETF intended by the Contributor for publi",
|
|
"cation as all or part of an IETF Internet-Draft or RFC and any s",
|
|
"tatement made within the context of an IETF activity is consider",
|
|
'ed an "IETF Contribution". Such statements include oral statemen',
|
|
"ts in IETF sessions, as well as written and electronic communica",
|
|
"tions made at any time or place, which are addressed to",
|
|
}
|
|
|
|
local ciphertext = util.hexcat {
|
|
"a3 fb f0 7d f3 fa 2f de 4f 37 6c a2 3e 82 73 70",
|
|
"41 60 5d 9f 4f 4f 57 bd 8c ff 2c 1d 4b 79 55 ec",
|
|
"2a 97 94 8b d3 72 29 15 c8 f3 d3 37 f7 d3 70 05",
|
|
"0e 9e 96 d6 47 b7 c3 9f 56 e0 31 ca 5e b6 25 0d",
|
|
"40 42 e0 27 85 ec ec fa 4b 4b b5 e8 ea d0 44 0e",
|
|
"20 b6 e8 db 09 d8 81 a7 c6 13 2f 42 0e 52 79 50",
|
|
"42 bd fa 77 73 d8 a9 05 14 47 b3 29 1c e1 41 1c",
|
|
"68 04 65 55 2a a6 c4 05 b7 76 4d 5e 87 be a8 5a",
|
|
"d0 0f 84 49 ed 8f 72 d0 d6 62 ab 05 26 91 ca 66",
|
|
"42 4b c8 6d 2d f8 0e a4 1f 43 ab f9 37 d3 25 9d",
|
|
"c4 b2 d0 df b4 8a 6c 91 39 dd d7 f7 69 66 e9 28",
|
|
"e6 35 55 3b a7 6c 5c 87 9d 7b 35 d4 9e b2 e6 2b",
|
|
"08 71 cd ac 63 89 39 e2 5e 8a 1e 0e f9 d5 28 0f",
|
|
"a8 ca 32 8b 35 1c 3c 76 59 89 cb cf 3d aa 8b 6c",
|
|
"cc 3a af 9f 39 79 c9 2b 37 20 fc 88 dc 95 ed 84",
|
|
"a1 be 05 9c 64 99 b9 fd a2 36 e7 e8 18 b0 4b 0b",
|
|
"c3 9c 1e 87 6b 19 3b fe 55 69 75 3f 88 12 8c c0",
|
|
"8a aa 9b 63 d1 a1 6f 80 ef 25 54 d7 18 9c 41 1f",
|
|
"58 69 ca 52 c5 b8 3f a3 6f f2 16 b9 c1 d3 00 62",
|
|
"be bc fd 2d c5 bc e0 91 19 34 fd a7 9a 86 f6 e6",
|
|
"98 ce d7 59 c3 ff 9b 64 77 33 8f 3d a4 f9 cd 85",
|
|
"14 ea 99 82 cc af b3 41 b2 38 4d d9 02 f3 d1 ab",
|
|
"7a c6 1d d2 9c 6f 21 ba 5b 86 2f 37 30 e3 7c fd",
|
|
"c4 fd 80 6c 22 f2 21 ",
|
|
}
|
|
|
|
expect(chacha20.crypt(key, nonce, plaintext, 20, 1))
|
|
:eq(ciphertext)
|
|
end)
|
|
|
|
it("encrypts the appendix A.2 test vector #3", function()
|
|
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 00 00 00 00 00 00 00 02",
|
|
}
|
|
|
|
local plaintext = table.concat {
|
|
"'Twas brillig, and the slithy toves\nDid gyre and gimble in the w",
|
|
"abe:\nAll mimsy were the borogoves,\nAnd the mome raths outgrabe.",
|
|
}
|
|
|
|
local ciphertext = util.hexcat {
|
|
"62 e6 34 7f 95 ed 87 a4 5f fa e7 42 6f 27 a1 df",
|
|
"5f b6 91 10 04 4c 0d 73 11 8e ff a9 5b 01 e5 cf",
|
|
"16 6d 3d f2 d7 21 ca f9 b2 1e 5f b1 4c 61 68 71",
|
|
"fd 84 c5 4f 9d 65 b2 83 19 6c 7f e4 f6 05 53 eb",
|
|
"f3 9c 64 02 c4 22 34 e3 2a 35 6b 3e 76 43 12 a6",
|
|
"1a 55 32 05 57 16 ea d6 96 25 68 f8 7d 3f 3f 77",
|
|
"04 c6 a8 d1 bc d1 bf 4d 50 d6 15 4b 6d a7 31 b1",
|
|
"87 b5 8d fd 72 8a fa 36 75 7a 79 7a c1 88 d1 ",
|
|
}
|
|
|
|
expect(chacha20.crypt(key, nonce, plaintext, 20, 42))
|
|
:eq(ciphertext)
|
|
end)
|
|
end)
|