From 88729c08b6444338e3846824efada73ca62d6070 Mon Sep 17 00:00:00 2001 From: Johannes Date: Fri, 26 Nov 2021 09:04:41 +0100 Subject: [PATCH] Test with new test vectors (#25) * Test: Test with new test vectors * Update test vectors * Update to test vector v0.2.0 * Tests: Update parsing of test vectors * Update test vectors to 0.3.0 * Test key are hex in test vectors 0.3.0 --- .gitignore | 2 + Cargo.toml | 1 + src/lib.rs | 176 ++++++++++++++--------- test_data/test_vectors.json | 268 ++++++++++++++++++++++++++++++++++++ 4 files changed, 382 insertions(+), 65 deletions(-) create mode 100644 test_data/test_vectors.json diff --git a/.gitignore b/.gitignore index 979d87e..63fd23e 100755 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,5 @@ Cargo.lock /target **/*.rs.bk Cargo.lock + +.DS_Store \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index 6edd3bb..9da9973 100755 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,4 +23,5 @@ orion = "0.16.0" serde = "^1.0" serde_derive = "1.0.115" serde_json = "1.0" +hex = "0.4.2" getrandom = "0.2.3" \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 77ed89f..3bda6fb 100755 --- a/src/lib.rs +++ b/src/lib.rs @@ -501,77 +501,123 @@ mod unit_tests { use super::*; - #[derive(Serialize, Deserialize, Debug)] - struct JSONTest { - a: String, - b: bool, - } - - // Test vectors from: https://github.com/tuupola/branca-js/blob/master/test.js - #[test] - pub fn test_decode_1() { - let ciphertext = - "870S4BYjk7NvyViEjUNsTEmGXbARAX9PamXZg0b3JyeIdGyZkFJhNsOQW6m0K9KnXt3ZUBqDB6hF4"; - let key = b"supersecretkeyyoushouldnotcommit"; - let ttl = 0; - - assert_eq!(decode(ciphertext, key, ttl).unwrap(), b"Hello world!"); - } - - #[test] - pub fn test_decode_2() { - let ciphertext = - "89i7YCwtsSiYfXvOKlgkCyElnGCOEYG7zLCjUp4MuDIZGbkKJgt79Sts9RdW2Yo4imonXsILmqtNb"; - let key = b"supersecretkeyyoushouldnotcommit"; - let ttl = 0; - - assert_eq!(decode(ciphertext, key, ttl).unwrap(), b"Hello world!"); - } - - #[test] - pub fn test_decode_3() { - let ciphertext = - "875GH234UdXU6PkYq8g7tIM80XapDQOH72bU48YJ7SK1iHiLkrqT8Mly7P59TebOxCyQeqpMJ0a7a"; - let key = b"supersecretkeyyoushouldnotcommit"; - let ttl = 0; - - assert_eq!(decode(ciphertext, key, ttl).unwrap(), b"Hello world!"); - } + mod json_test_vectors { + use super::*; + use std::fs::File; + use std::io::BufReader; + + #[allow(non_snake_case)] + #[derive(Serialize, Deserialize, Debug)] + struct TestFile { + version: String, + numberOfTests: u32, + testGroups: Vec, + } - #[test] - pub fn test_decode_4() { - let ciphertext = "1jIBheHWEwYIP59Wpm4QkjkIKuhc12NcYdp9Y60B6av7sZc3vJ5wBwmKJyQzGfJCrvuBgGnf"; - let key = b"supersecretkeyyoushouldnotcommit"; - let ttl = 0; + #[allow(non_snake_case)] + #[derive(Serialize, Deserialize, Debug)] + struct TestGroup { + testType: String, + tests: Vec, + } - assert_eq!( - decode(ciphertext, key, ttl).unwrap(), - b"\x00\x00\x00\x00\x00\x00\x00\x00" - ); - } + #[allow(non_snake_case)] + #[derive(Serialize, Deserialize, Debug)] + struct TestVector { + id: u32, + comment: String, + key: String, + nonce: Option, + timestamp: u32, + token: String, + msg: String, + isValid: bool, + } - #[test] - pub fn test_decode_5() { - let ciphertext = "1jrx6DUq9HmXvYdmhWMhXzx3klRzhlAjsc3tUFxDPCvZZLm16GYOzsBG4KwF1djjW1yTeZ2B"; - let key = b"supersecretkeyyoushouldnotcommit"; - let ttl = 0; + fn parse_hex(data: &str) -> Vec { + match data { + "" => vec![0u8; 0], + "80" => b"\x80".to_vec(), + _ => hex::decode(data).unwrap(), + } + } - assert_eq!( - decode(ciphertext, key, ttl).unwrap(), - b"\x00\x00\x00\x00\x00\x00\x00\x00" - ); + #[test] + pub fn run_test_vectors() { + let file = File::open("test_data/test_vectors.json").unwrap(); + let reader = BufReader::new(file); + let tests: TestFile = serde_json::from_reader(reader).unwrap(); + + let mut tests_run = 0; + for test_group in tests.testGroups.iter() { + for test in test_group.tests.iter() { + if test_group.testType == "encoding" { + debug_assert!(test.nonce.is_some()); + + if test.isValid { + let nonce = Nonce::from_slice(&parse_hex(test.nonce.as_ref().unwrap())) + .unwrap(); + + let res = encode_with_nonce( + &parse_hex(&test.msg), + &parse_hex(&test.key), + &nonce, + test.timestamp, + ) + .unwrap(); + + assert_eq!(res, test.token); + assert_eq!( + decode(&test.token, &parse_hex(&test.key), 0).unwrap(), + parse_hex(&test.msg) + ); + + tests_run += 1; + } + + if !test.isValid { + let nonce = Nonce::from_slice(&parse_hex(test.nonce.as_ref().unwrap())); + + if nonce.is_err() { + tests_run += 1; + continue; + } + + let res = encode_with_nonce( + &parse_hex(&test.msg), + &parse_hex(&test.key), + &nonce.unwrap(), + test.timestamp, + ); + + assert!(res.is_err()); + tests_run += 1; + } + } + + if test_group.testType == "decoding" { + debug_assert!(test.nonce.is_none()); + + let res = decode( + &test.token, + &parse_hex(&test.key), + 0, // Not a part of test vectors + ); + + assert_eq!(test.isValid, res.is_ok()); + tests_run += 1; + } + } + } + + assert_eq!(tests_run, tests.numberOfTests); + } } - #[test] - pub fn test_decode_6() { - let ciphertext = "1jJDJOEfuc4uBJh5ivaadjo6UaBZJDZ1NsWixVCz2mXw3824JRDQZIgflRqCNKz6yC7a0JKC"; - let key = b"supersecretkeyyoushouldnotcommit"; - let ttl = 0; - - assert_eq!( - decode(ciphertext, key, ttl).unwrap(), - b"\x00\x00\x00\x00\x00\x00\x00\x00" - ); + #[derive(Serialize, Deserialize, Debug)] + struct JSONTest { + a: String, + b: bool, } #[test] diff --git a/test_data/test_vectors.json b/test_data/test_vectors.json new file mode 100644 index 0000000..e7e1bb4 --- /dev/null +++ b/test_data/test_vectors.json @@ -0,0 +1,268 @@ +{ + "version": "0.3.0", + "numberOfTests": 25, + "testGroups": [ + { + "testType": "encoding", + "tests": [ + { + "id": 0, + "comment": "Hello world with zero timestamp", + "key": "73757065727365637265746b6579796f7573686f756c646e6f74636f6d6d6974", + "nonce": "beefbeefbeefbeefbeefbeefbeefbeefbeefbeefbeefbeef", + "timestamp": 0, + "token": "870S4BYxgHw0KnP3W9fgVUHEhT5g86vJ17etaC5Kh5uIraWHCI1psNQGv298ZmjPwoYbjDQ9chy2z", + "msg": "48656c6c6f20776f726c6421", + "isValid": true + }, + { + "id": 1, + "comment": "Hello world with max timestamp", + "key": "73757065727365637265746b6579796f7573686f756c646e6f74636f6d6d6974", + "nonce": "beefbeefbeefbeefbeefbeefbeefbeefbeefbeefbeefbeef", + "timestamp": 4294967295, + "token": "89i7YCwu5tWAJNHUDdmIqhzOi5hVHOd4afjZcGMcVmM4enl4yeLiDyYv41eMkNmTX6IwYEFErCSqr", + "msg": "48656c6c6f20776f726c6421", + "isValid": true + }, + { + "id": 2, + "comment": "Hello world with November 27 timestamp", + "key": "73757065727365637265746b6579796f7573686f756c646e6f74636f6d6d6974", + "nonce": "beefbeefbeefbeefbeefbeefbeefbeefbeefbeefbeefbeef", + "timestamp": 123206400, + "token": "875GH23U0Dr6nHFA63DhOyd9LkYudBkX8RsCTOMz5xoYAMw9sMd5QwcEqLDRnTDHPenOX7nP2trlT", + "msg": "48656c6c6f20776f726c6421", + "isValid": true + }, + { + "id": 3, + "comment": "Eight null bytes with zero timestamp", + "key": "73757065727365637265746b6579796f7573686f756c646e6f74636f6d6d6974", + "nonce": "beefbeefbeefbeefbeefbeefbeefbeefbeefbeefbeefbeef", + "timestamp": 0, + "token": "1jIBheHbDdkCDFQmtgw4RUZeQoOJgGwTFJSpwOAk3XYpJJr52DEpILLmmwYl4tjdSbbNqcF1", + "msg": "0000000000000000", + "isValid": true + }, + { + "id": 4, + "comment": "Eight null bytes with max timestamp", + "key": "73757065727365637265746b6579796f7573686f756c646e6f74636f6d6d6974", + "nonce": "beefbeefbeefbeefbeefbeefbeefbeefbeefbeefbeefbeef", + "timestamp": 4294967295, + "token": "1jrx6DUu5q06oxykef2e2ZMyTcDRTQot9ZnwgifUtzAphGtjsxfbxXNhQyBEOGtpbkBgvIQx", + "msg": "0000000000000000", + "isValid": true + }, + { + "id": 5, + "comment": "Eight null bytes with November 27th timestamp", + "key": "73757065727365637265746b6579796f7573686f756c646e6f74636f6d6d6974", + "nonce": "beefbeefbeefbeefbeefbeefbeefbeefbeefbeefbeefbeef", + "timestamp": 123206400, + "token": "1jJDJOEjuwVb9Csz1Ypw1KBWSkr0YDpeBeJN6NzJWx1VgPLmcBhu2SbkpQ9JjZ3nfUf7Aytp", + "msg": "0000000000000000", + "isValid": true + }, + { + "id": 6, + "comment": "Empty payload", + "key": "73757065727365637265746b6579796f7573686f756c646e6f74636f6d6d6974", + "nonce": "beefbeefbeefbeefbeefbeefbeefbeefbeefbeefbeefbeef", + "timestamp": 0, + "token": "4sfD0vPFhIif8cy4nB3BQkHeJqkOkDvinI4zIhMjYX4YXZU5WIq9ycCVjGzB5", + "msg": "", + "isValid": true + }, + { + "id": 7, + "comment": "Non-UTF8 payload", + "key": "73757065727365637265746b6579796f7573686f756c646e6f74636f6d6d6974", + "nonce": "beefbeefbeefbeefbeefbeefbeefbeefbeefbeefbeefbeef", + "timestamp": 123206400, + "token": "K9u6d0zjXp8RXNUGDyXAsB9AtPo60CD3xxQ2ulL8aQoTzXbvockRff0y1eXoHm", + "msg": "80", + "isValid": true + } + ] + }, + { + "testType": "decoding", + "tests": [ + { + "id": 8, + "comment": "Hello world with zero timestamp", + "key": "73757065727365637265746b6579796f7573686f756c646e6f74636f6d6d6974", + "nonce": null, + "timestamp": 0, + "token": "870S4BYxgHw0KnP3W9fgVUHEhT5g86vJ17etaC5Kh5uIraWHCI1psNQGv298ZmjPwoYbjDQ9chy2z", + "msg": "48656c6c6f20776f726c6421", + "isValid": true + }, + { + "id": 9, + "comment": "Hello world with max timestamp", + "key": "73757065727365637265746b6579796f7573686f756c646e6f74636f6d6d6974", + "nonce": null, + "timestamp": 4294967295, + "token": "89i7YCwu5tWAJNHUDdmIqhzOi5hVHOd4afjZcGMcVmM4enl4yeLiDyYv41eMkNmTX6IwYEFErCSqr", + "msg": "48656c6c6f20776f726c6421", + "isValid": true + }, + { + "id": 10, + "comment": "Hello world with November 27 timestamp", + "key": "73757065727365637265746b6579796f7573686f756c646e6f74636f6d6d6974", + "nonce": null, + "timestamp": 123206400, + "token": "875GH23U0Dr6nHFA63DhOyd9LkYudBkX8RsCTOMz5xoYAMw9sMd5QwcEqLDRnTDHPenOX7nP2trlT", + "msg": "48656c6c6f20776f726c6421", + "isValid": true + }, + { + "id": 11, + "comment": "Eight null bytes with zero timestamp", + "key": "73757065727365637265746b6579796f7573686f756c646e6f74636f6d6d6974", + "nonce": null, + "timestamp": 0, + "token": "1jIBheHbDdkCDFQmtgw4RUZeQoOJgGwTFJSpwOAk3XYpJJr52DEpILLmmwYl4tjdSbbNqcF1", + "msg": "0000000000000000", + "isValid": true + }, + { + "id": 12, + "comment": "Eight null bytes with max timestamp", + "key": "73757065727365637265746b6579796f7573686f756c646e6f74636f6d6d6974", + "nonce": null, + "timestamp": 4294967295, + "token": "1jrx6DUu5q06oxykef2e2ZMyTcDRTQot9ZnwgifUtzAphGtjsxfbxXNhQyBEOGtpbkBgvIQx", + "msg": "0000000000000000", + "isValid": true + }, + { + "id": 13, + "comment": "Eight null bytes with November 27th timestamp", + "key": "73757065727365637265746b6579796f7573686f756c646e6f74636f6d6d6974", + "nonce": null, + "timestamp": 123206400, + "token": "1jJDJOEjuwVb9Csz1Ypw1KBWSkr0YDpeBeJN6NzJWx1VgPLmcBhu2SbkpQ9JjZ3nfUf7Aytp", + "msg": "0000000000000000", + "isValid": true + }, + { + "id": 14, + "comment": "Empty payload", + "key": "73757065727365637265746b6579796f7573686f756c646e6f74636f6d6d6974", + "nonce": null, + "timestamp": 0, + "token": "4sfD0vPFhIif8cy4nB3BQkHeJqkOkDvinI4zIhMjYX4YXZU5WIq9ycCVjGzB5", + "msg": "", + "isValid": true + }, + { + "id": 15, + "comment": "Non-UTF8 payload", + "key": "73757065727365637265746b6579796f7573686f756c646e6f74636f6d6d6974", + "nonce": null, + "timestamp": 123206400, + "token": "K9u6d0zjXp8RXNUGDyXAsB9AtPo60CD3xxQ2ulL8aQoTzXbvockRff0y1eXoHm", + "msg": "80", + "isValid": true + }, + { + "id": 16, + "comment": "Wrong version 0xBB", + "key": "73757065727365637265746b6579796f7573686f756c646e6f74636f6d6d6974", + "nonce": null, + "timestamp": 0, + "token": "89mvl3RkwXjpEj5WMxK7GUDEHEeeeZtwjMIOogTthvr44qBfYtQSIZH5MHOTC0GzoutDIeoPVZk3w", + "msg": "", + "isValid": false + }, + { + "id": 17, + "comment": "Invalid base62 characters", + "key": "73757065727365637265746b6579796f7573686f756c646e6f74636f6d6d6974", + "nonce": null, + "timestamp": 123206400, + "token": "875GH23U0Dr6nHFA63DhOyd9LkYudBkX8RsCTOMz5xoYAMw9sMd5QwcEqLDRnTDHPenOX7nP2trlT_", + "msg": "48656c6c6f20776f726c6421", + "isValid": false + }, + { + "id": 18, + "comment": "Modified version", + "key": "73757065727365637265746b6579796f7573686f756c646e6f74636f6d6d6974", + "nonce": null, + "timestamp": 0, + "token": "89mvl3S0BE0UCMIY94xxIux4eg1w5oXrhvCEXrDAjusSbO0Yk7AU6FjjTnbTWTqogLfNPJLzecHVb", + "msg": "48656c6c6f20776f726c6421", + "isValid": false + }, + { + "id": 19, + "comment": "Modified first byte of the nonce", + "key": "73757065727365637265746b6579796f7573686f756c646e6f74636f6d6d6974", + "nonce": null, + "timestamp": 0, + "token": "875GH233SUysT7fQ711EWd9BXpwOjB72ng3ZLnjWFrmOqVy49Bv93b78JU5331LbcY0EEzhLfpmSx", + "msg": "48656c6c6f20776f726c6421", + "isValid": false + }, + + { + "id": 20, + "comment": "Modified timestamp", + "key": "73757065727365637265746b6579796f7573686f756c646e6f74636f6d6d6974", + "nonce": null, + "timestamp": 0, + "token": "870g1RCk4lW1YInhaU3TP8u2hGtfol16ettLcTOSoA0JIpjCaQRW7tQeP6dQmTvFIB2s6wL5deMXr", + "msg": "48656c6c6f20776f726c6421", + "isValid": false + }, + + { + "id": 21, + "comment": "Modified last byte of the ciphertext", + "key": "73757065727365637265746b6579796f7573686f756c646e6f74636f6d6d6974", + "nonce": null, + "timestamp": 0, + "token": "875GH23U0Dr6nHFA63DhOyd9LkYudBkX8RsCTOMz5xoYAMw9sMd5Qw6Jpo96myliI3hHD7VbKZBYh", + "msg": "48656c6c6f20776f726c6421", + "isValid": false + }, + { + "id": 22, + "comment": "Modified last byte of the Poly1305 tag", + "key": "73757065727365637265746b6579796f7573686f756c646e6f74636f6d6d6974", + "nonce": null, + "timestamp": 0, + "token": "875GH23U0Dr6nHFA63DhOyd9LkYudBkX8RsCTOMz5xoYAMw9sMd5QwcEqLDRnTDHPenOX7nP2trk0", + "msg": "48656c6c6f20776f726c6421", + "isValid": false + }, + { + "id": 23, + "comment": "Wrong key", + "key": "77726f6e677365637265746b6579796f7573686f756c646e6f74636f6d6d6974", + "nonce": null, + "timestamp": 0, + "token": "870S4BYxgHw0KnP3W9fgVUHEhT5g86vJ17etaC5Kh5uIraWHCI1psNQGv298ZmjPwoYbjDQ9chy2z", + "msg": "48656c6c6f20776f726c6421", + "isValid": false + }, + { + "id": 24, + "comment": "Invalid key", + "key": "746f6f73686f72746b6579", + "nonce": null, + "timestamp": 0, + "token": "870S4BYxgHw0KnP3W9fgVUHEhT5g86vJ17etaC5Kh5uIraWHCI1psNQGv298ZmjPwoYbjDQ9chy2z", + "msg": "48656c6c6f20776f726c6421", + "isValid": false + } + ] + } + ] +} \ No newline at end of file