Skip to content

Commit 879bab2

Browse files
Merge pull request #913 from cryspen/jonas/xchacha-wycheproof
Wycherproof test for XChacha20Poly1305
2 parents de48705 + b877e5c commit 879bab2

File tree

2 files changed

+4666
-1
lines changed

2 files changed

+4666
-1
lines changed

chacha20poly1305/tests/chachapoly.rs

Lines changed: 88 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ pub(crate) trait ReadFromFile {
3030
#[allow(non_snake_case)]
3131
struct AeadTestVector {
3232
algorithm: String,
33-
generatorVersion: String,
3433
numberOfTests: usize,
3534
notes: Option<Value>, // text notes (might not be present), keys correspond to flags
3635
header: Vec<Value>, // not used
@@ -145,6 +144,94 @@ fn wycheproof() {
145144
assert_eq!(num_tests - skipped_tests, tests_run);
146145
}
147146

147+
#[allow(non_snake_case)]
148+
#[test]
149+
fn wycheproof_xchacha() {
150+
let chacha_poly_tests: AeadTestVector =
151+
AeadTestVector::from_file("../tests/wycheproof/xchacha20_poly1305_test.json");
152+
153+
let num_tests = chacha_poly_tests.numberOfTests;
154+
let mut skipped_tests = 0;
155+
let mut tests_run = 0;
156+
assert_eq!(chacha_poly_tests.algorithm, "XCHACHA20-POLY1305");
157+
158+
test_group(chacha_poly_tests, &mut skipped_tests, &mut tests_run);
159+
160+
fn test_group(test_vec: AeadTestVector, skipped_tests: &mut usize, tests_run: &mut usize) {
161+
for testGroup in test_vec.testGroups.iter() {
162+
assert_eq!(testGroup.r#type, "AeadTest");
163+
assert_eq!(testGroup.keySize, 256);
164+
165+
let invalid_iv = testGroup.ivSize != 96;
166+
167+
for test in testGroup.tests.iter() {
168+
let valid = test.result.eq("valid");
169+
if invalid_iv {
170+
// AEAD requires input of a 12-byte nonce.
171+
let nonce = &test.iv;
172+
assert!(nonce.len() != 12);
173+
*skipped_tests += 1;
174+
continue;
175+
}
176+
println!("Test {:?}: {:?}", test.tcId, test.comment);
177+
// Don't attempt to read nonces less than 24 bytes long.
178+
if test.iv.len() != 24 {
179+
*tests_run += 1;
180+
continue;
181+
}
182+
let nonce = <&[u8; 24]>::try_from(&test.iv[..]).unwrap();
183+
let msg = &test.msg;
184+
let aad = &test.aad;
185+
let exp_cipher = &test.ct;
186+
let exp_tag = &test.tag;
187+
let key = <&[u8; 32]>::try_from(&test.key[..]).unwrap();
188+
189+
let mut ctxt = msg.clone();
190+
let tag = match libcrux_chacha20poly1305::xchacha20_poly1305::encrypt(
191+
key, msg, &mut ctxt, aad, nonce,
192+
) {
193+
Ok((_v, t)) => t,
194+
Err(_) => {
195+
*tests_run += 1;
196+
continue;
197+
}
198+
};
199+
if valid {
200+
assert_eq!(tag, exp_tag.as_slice());
201+
} else {
202+
assert_ne!(tag, exp_tag.as_slice());
203+
}
204+
assert_eq!(ctxt, exp_cipher.as_slice());
205+
206+
let mut decrypted = vec![0; msg.len()];
207+
match libcrux_chacha20poly1305::xchacha20_poly1305::decrypt(
208+
key,
209+
&mut decrypted,
210+
&ctxt,
211+
aad,
212+
nonce,
213+
) {
214+
Ok(m) => {
215+
assert_eq!(m, msg);
216+
assert_eq!(&decrypted, msg);
217+
}
218+
Err(_) => {
219+
assert!(!valid);
220+
}
221+
};
222+
223+
*tests_run += 1;
224+
}
225+
}
226+
}
227+
// Check that we ran all tests.
228+
println!(
229+
"Ran {} out of {} tests and skipped {}.",
230+
tests_run, num_tests, skipped_tests
231+
);
232+
assert_eq!(num_tests - skipped_tests, tests_run);
233+
}
234+
148235
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
149236
#[test]
150237
fn chachapoly_self_test() {

0 commit comments

Comments
 (0)