Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Various improvements #1

Merged
merged 2 commits into from
Jul 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "wycheproof"
version = "0.1.0"
version = "0.2.0"
edition = "2018"
authors = ["Jack Lloyd <jack@randombit.net>"]
license = "Apache-2.0"
Expand Down
12 changes: 12 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@

## 0.2.0

* Add `TestName` enums to allow better typechecking
* Split up into several modules; now everything is of the form
`wycheproof::foo::{TestName, TestSet, TestGroup, Test, TestFlag}`
* Some data was inadvertantly not `pub`

## 0.1.0 2021-06-26

* First release

46 changes: 1 addition & 45 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,51 +16,7 @@ to do on previous attempts, like decoding the hex and base64 during
deserializion, using enums to aid type checking, verifies that schemas match the
expected one, etc.

Wycheproof uses a general schema where "test sets" in turn contain "test groups"
and each group has a list of tests along with some amount of configuration
information specific to that group of tests. By calling
`FooTestSet::load("...")` you can request the named test set. For example to
iterate over the GCM tests and print the data

```
use hex::encode as hex_encode;

fn print_gcm() {
let test_set = wycheproof::AeadTestSet::load("aes_gcm").unwrap();

for test_group in test_set.test_groups {
println!(
"* Group key size:{} tag size:{} nonce size:{}",
test_group.key_size, test_group.tag_size, test_group.nonce_size,
);
for test in test_group.tests {
println!(
"Test:{} Key:{} AAD:{} PT:{} CT:{} Tag:{}",
test.tc_id,
hex_encode(test.key),
hex_encode(test.aad),
hex_encode(test.pt),
hex_encode(test.ct),
hex_encode(test.tag)
);
}
}
}
```

You get the idea.

Comments and patches are welcome. Since the intent of this crate is to be just a
deserializion of the Wycheproof tests, the possible scope for changes seems
limited.

One issue I'd like to fix is that discoverability of test sets is nil; you just
have to somehow know that say "ecdsa_secp224r1_sha3_512" is a valid name for a
test set. Also you have to just somehow know which TestSet type is associated
with that name, and this is not always obvious. Perhaps naming every test using
test-type specific enums is the correct approach.

Further macro magic to reduce code duplication would be nice as well.
Comments and patches are welcome.

This crate is licensed Apache 2.0-only, just as Wycheproof itself is. The files
in `src/data` are taken from
Expand Down
68 changes: 68 additions & 0 deletions src/aead.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
use super::*;

define_test_set!("AEAD", "aead_test_schema.json");

define_test_set_names!(
Aegis128 => "aegis128",
Aegis128L => "aegis128L",
Aegis256 => "aegis256",
AesCcm => "aes_ccm",
AesEax => "aes_eax",
AesGcm => "aes_gcm",
AesGcmSiv => "aes_gcm_siv",
AesSivCmac => "aead_aes_siv_cmac",
ChaCha20Poly1305 => "chacha20_poly1305",
XChaCha20Poly1305 => "xchacha20_poly1305"
);

#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Deserialize)]
pub enum TestFlag {
BadPadding,
ConstructedIv,
CounterWrap,
EdgeCaseSiv,
InvalidNonceSize,
InvalidTagSize,
LongIv,
OldVersion,
SmallIv,
ZeroLengthIv,
}

define_typeid!(TestGroupTypeId => "AeadTest");

#[derive(Debug, Clone, Hash, Eq, PartialEq, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct TestGroup {
#[serde(rename = "ivSize")]
pub nonce_size: usize,
#[serde(rename = "keySize")]
pub key_size: usize,
#[serde(rename = "tagSize")]
pub tag_size: usize,
#[serde(rename = "type")]
typ: TestGroupTypeId,
pub tests: Vec<Test>,
}

#[derive(Debug, Clone, Hash, Eq, PartialEq, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct Test {
#[serde(rename = "tcId")]
pub tc_id: usize,
pub comment: String,
#[serde(deserialize_with = "vec_from_hex")]
pub key: Vec<u8>,
#[serde(deserialize_with = "vec_from_hex", rename = "iv")]
pub nonce: Vec<u8>,
#[serde(deserialize_with = "vec_from_hex")]
pub aad: Vec<u8>,
#[serde(deserialize_with = "vec_from_hex", rename = "msg")]
pub pt: Vec<u8>,
#[serde(deserialize_with = "vec_from_hex")]
pub ct: Vec<u8>,
#[serde(deserialize_with = "vec_from_hex")]
pub tag: Vec<u8>,
pub result: TestResult,
pub flags: Vec<TestFlag>,
}
45 changes: 45 additions & 0 deletions src/cipher.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
use super::*;

define_test_set!("Cipher", "ind_cpa_test_schema.json");

define_test_set_names!(
AesCbcPkcs5 => "aes_cbc_pkcs5"
);

#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Deserialize)]
pub enum TestFlag {
BadPadding,
}

define_typeid!(TestGroupTypeId => "IndCpaTest");

#[derive(Debug, Clone, Hash, Eq, PartialEq, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct TestGroup {
#[serde(rename = "ivSize")]
pub nonce_size: usize,
#[serde(rename = "keySize")]
pub key_size: usize,
#[serde(rename = "type")]
typ: TestGroupTypeId,
pub tests: Vec<Test>,
}

#[derive(Debug, Clone, Hash, Eq, PartialEq, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct Test {
#[serde(rename = "tcId")]
pub tc_id: usize,
pub comment: String,
#[serde(deserialize_with = "vec_from_hex")]
pub iv: Vec<u8>,
#[serde(deserialize_with = "vec_from_hex")]
pub key: Vec<u8>,
#[serde(deserialize_with = "vec_from_hex", rename = "msg")]
pub pt: Vec<u8>,
#[serde(deserialize_with = "vec_from_hex")]
pub ct: Vec<u8>,
pub result: TestResult,
#[serde(default)]
pub flags: Vec<TestFlag>,
}
43 changes: 43 additions & 0 deletions src/daead.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
use super::*;

define_test_set!("DAEAD", "daead_test_schema.json");

define_test_set_names!(
AesGcmSiv => "aes_siv_cmac"
);

#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Deserialize)]
pub enum TestFlag {
EdgeCaseSiv,
}

define_typeid!(TestGroupTypeId => "DaeadTest");

#[derive(Debug, Clone, Hash, Eq, PartialEq, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct TestGroup {
#[serde(rename = "keySize")]
pub key_size: usize,
#[serde(rename = "type")]
typ: TestGroupTypeId,
pub tests: Vec<Test>,
}

#[derive(Debug, Clone, Hash, Eq, PartialEq, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct Test {
#[serde(rename = "tcId")]
pub tc_id: usize,
pub comment: String,
#[serde(deserialize_with = "vec_from_hex")]
pub key: Vec<u8>,
#[serde(deserialize_with = "vec_from_hex")]
pub aad: Vec<u8>,
#[serde(deserialize_with = "vec_from_hex", rename = "msg")]
pub pt: Vec<u8>,
#[serde(deserialize_with = "vec_from_hex")]
pub ct: Vec<u8>,
pub result: TestResult,
#[serde(default)]
pub flags: Vec<TestFlag>,
}