v2 / vlib / crypto / argon2 / argon2_test.v
164 lines · 154 sloc · 3.36 KB · c2958b2a9c2981675812046b40de5a687c3080a9
Raw
1// Test vectors adapted from the Go x/crypto argon2 package.
2module argon2
3
4import encoding.hex
5
6const gen_kat_password = [
7 u8(0x01),
8 0x01,
9 0x01,
10 0x01,
11 0x01,
12 0x01,
13 0x01,
14 0x01,
15 0x01,
16 0x01,
17 0x01,
18 0x01,
19 0x01,
20 0x01,
21 0x01,
22 0x01,
23 0x01,
24 0x01,
25 0x01,
26 0x01,
27 0x01,
28 0x01,
29 0x01,
30 0x01,
31 0x01,
32 0x01,
33 0x01,
34 0x01,
35 0x01,
36 0x01,
37 0x01,
38 0x01,
39]!
40const gen_kat_salt = [
41 u8(0x02),
42 0x02,
43 0x02,
44 0x02,
45 0x02,
46 0x02,
47 0x02,
48 0x02,
49 0x02,
50 0x02,
51 0x02,
52 0x02,
53 0x02,
54 0x02,
55 0x02,
56 0x02,
57]!
58const gen_kat_secret = [u8(0x03), 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03]!
59const gen_kat_aad = [u8(0x04), 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04]!
60
61struct TestVector {
62 mode int
63 time u32
64 memory u32
65 threads u8
66 hash string
67}
68
69const test_vectors = [
70 TestVector{
71 mode: argon2_i
72 time: 1
73 memory: 64
74 threads: 1
75 hash: 'b9c401d1844a67d50eae3967dc28870b22e508092e861a37'
76 },
77 TestVector{
78 mode: argon2_d
79 time: 1
80 memory: 64
81 threads: 1
82 hash: '8727405fd07c32c78d64f547f24150d3f2e703a89f981a19'
83 },
84 TestVector{
85 mode: argon2_id
86 time: 1
87 memory: 64
88 threads: 1
89 hash: '655ad15eac652dc59f7170a7332bf49b8469be1fdb9c28bb'
90 },
91 TestVector{
92 mode: argon2_id
93 time: 2
94 memory: 64
95 threads: 2
96 hash: '350ac37222f436ccb5c0972f1ebd3bf6b958bf2071841362'
97 },
98 TestVector{
99 mode: argon2_i
100 time: 3
101 memory: 256
102 threads: 2
103 hash: 'f5bbf5d4c3836af13193053155b73ec7476a6a2eb93fd5e6'
104 },
105 TestVector{
106 mode: argon2_id
107 time: 4
108 memory: 1024
109 threads: 8
110 hash: '8dafa8e004f8ea96bf7c0f93eecf67a6047476143d15577f'
111 },
112]!
113
114fn test_argon2_known_answer_vectors() {
115 want_d := hex.decode('512b391b6f1162975371d30919734294f868e3be3984f3c1a13a4db9fabe4acb')!
116 got_d := derive_key(argon2_d, gen_kat_password[..], gen_kat_salt[..], gen_kat_secret[..],
117 gen_kat_aad[..], 3, 32, 4, u32(want_d.len))!
118 assert got_d == want_d
119
120 want_i := hex.decode('c814d9d1dc7f37aa13f0d77f2494bda1c8de6b016dd388d29952a4c4672b6ce8')!
121 got_i := derive_key(argon2_i, gen_kat_password[..], gen_kat_salt[..], gen_kat_secret[..],
122 gen_kat_aad[..], 3, 32, 4, u32(want_i.len))!
123 assert got_i == want_i
124
125 want_id := hex.decode('0d640df58d78766c08c037a34a8b53c9d01ef0452d75b65eb52520e96b01e659')!
126 got_id := derive_key(argon2_id, gen_kat_password[..], gen_kat_salt[..], gen_kat_secret[..],
127 gen_kat_aad[..], 3, 32, 4, u32(want_id.len))!
128 assert got_id == want_id
129}
130
131fn test_argon2_reference_vectors() {
132 password := 'password'.bytes()
133 salt := 'somesalt'.bytes()
134 for vector in test_vectors {
135 want := hex.decode(vector.hash)!
136 got := derive_key(vector.mode, password, salt, []u8{}, []u8{}, vector.time, vector.memory,
137 vector.threads, u32(want.len))!
138 assert got == want
139 }
140}
141
142fn test_generate_from_password_and_compare() {
143 params := Params{
144 time: 2
145 memory: 64
146 threads: 1
147 key_len: 24
148 salt_len: 16
149 }
150 password := 'correct horse battery staple'.bytes()
151 hash := generate_from_password_with_params(password, params)!
152 assert hash.starts_with('\$argon2id\$v=19\$m=64,t=2,p=1\$')
153 compare_hash_and_password(password, hash.bytes())!
154 compare_hash_and_password('incorrect'.bytes(), hash.bytes()) or {
155 assert err.msg() == 'mismatched hash and password'
156 return
157 }
158 assert false
159}
160
161fn test_generate_from_password_uses_defaults() {
162 hash := generate_from_password('hunter2'.bytes())!
163 assert hash.starts_with('\$argon2id\$v=19\$m=65536,t=3,p=4\$')
164}
165