expand serde tests (#409)

using samples in serde tests
This commit is contained in:
Conrado Gouvea 2023-06-23 11:22:33 -03:00 committed by GitHub
parent c851bbb8fa
commit 7358b667ca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 2345 additions and 163 deletions

View File

@ -43,6 +43,7 @@ serde_json = "1.0"
[features]
nightly = []
default = []
serde = ["frost-core/serde"]
[lib]
# Disables non-criterion benchmark which is not used; prevents errors

View File

@ -13,6 +13,9 @@ use sha2::{Digest, Sha512};
use frost_core::frost;
#[cfg(feature = "serde")]
use frost_core::serde;
#[cfg(test)]
mod tests;
@ -147,6 +150,8 @@ const CONTEXT_STRING: &str = "FROST-ED25519-SHA512-v11";
/// An implementation of the FROST(Ed25519, SHA-512) ciphersuite.
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(crate = "self::serde"))]
pub struct Ed25519Sha512;
impl Ciphersuite for Ed25519Sha512 {

View File

@ -0,0 +1,6 @@
{
"identifier": "2a00000000000000000000000000000000000000000000000000000000000000",
"element1": "5866666666666666666666666666666666666666666666666666666666666666",
"element2": "c9a3f86aae465f0e56513864510f3997561fa2c9e85ea21dc2292309f3cd6022",
"scalar1": "498d4e9311420c903913a56c94a694b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0a"
}

View File

@ -26,9 +26,9 @@ fn element2() -> Element<C> {
fn scalar1() -> Scalar<C> {
let one = <<C as Ciphersuite>::Group as Group>::Field::one();
let two = one + one;
// To return a fixed non-small number, get the inverse of 2
<<C as Ciphersuite>::Group as Group>::Field::invert(&two)
let three = one + one + one;
// To return a fixed non-small number, get the inverse of 3
<<C as Ciphersuite>::Group as Group>::Field::invert(&three)
.expect("nonzero elements have inverses")
}

View File

@ -0,0 +1,548 @@
#![cfg(feature = "serde")]
mod helpers;
use frost_ed25519::{
keys::{
dkg::{round1, round2},
KeyPackage, PublicKeyPackage, SecretShare,
},
round1::SigningCommitments,
round2::SignatureShare,
SigningPackage,
};
use helpers::samples;
#[test]
fn check_signing_commitments_serialization() {
let commitments = samples::signing_commitments();
let json = serde_json::to_string_pretty(&commitments).unwrap();
println!("{}", json);
let decoded_commitments: SigningCommitments = serde_json::from_str(&json).unwrap();
assert!(commitments == decoded_commitments);
let json = r#"{
"identifier": "2a00000000000000000000000000000000000000000000000000000000000000",
"hiding": "5866666666666666666666666666666666666666666666666666666666666666",
"binding": "c9a3f86aae465f0e56513864510f3997561fa2c9e85ea21dc2292309f3cd6022",
"ciphersuite": "FROST(Ed25519, SHA-512)"
}"#;
let decoded_commitments: SigningCommitments = serde_json::from_str(json).unwrap();
assert!(commitments == decoded_commitments);
let invalid_json = "{}";
assert!(serde_json::from_str::<SigningCommitments>(invalid_json).is_err());
// Wrong ciphersuite
let invalid_json = r#"{
"identifier": "2a00000000000000000000000000000000000000000000000000000000000000",
"hiding": "5866666666666666666666666666666666666666666666666666666666666666",
"binding": "c9a3f86aae465f0e56513864510f3997561fa2c9e85ea21dc2292309f3cd6022",
"ciphersuite": "FROST(Wrong, SHA-512)"
}"#;
assert!(serde_json::from_str::<SigningCommitments>(invalid_json).is_err());
// Invalid identifier
let invalid_json = r#"{
"identifier": "0000000000000000000000000000000000000000000000000000000000000000",
"hiding": "5866666666666666666666666666666666666666666666666666666666666666",
"binding": "c9a3f86aae465f0e56513864510f3997561fa2c9e85ea21dc2292309f3cd6022"
}"#;
assert!(serde_json::from_str::<SigningCommitments>(invalid_json).is_err());
// Invalid field
let invalid_json = r#"{
"foo": "0000000000000000000000000000000000000000000000000000000000000000",
"hiding": "5866666666666666666666666666666666666666666666666666666666666666",
"binding": "c9a3f86aae465f0e56513864510f3997561fa2c9e85ea21dc2292309f3cd6022"
}"#;
assert!(serde_json::from_str::<SigningCommitments>(invalid_json).is_err());
// Missing field
let invalid_json = r#"{
"foo": "0000000000000000000000000000000000000000000000000000000000000000",
"binding": "c9a3f86aae465f0e56513864510f3997561fa2c9e85ea21dc2292309f3cd6022"
}"#;
assert!(serde_json::from_str::<SigningCommitments>(invalid_json).is_err());
// Extra field
let invalid_json = r#"{
"identifier": "2a00000000000000000000000000000000000000000000000000000000000000",
"hiding": "5866666666666666666666666666666666666666666666666666666666666666",
"binding": "c9a3f86aae465f0e56513864510f3997561fa2c9e85ea21dc2292309f3cd6022",
"extra": 1
}"#;
assert!(serde_json::from_str::<SigningCommitments>(invalid_json).is_err());
}
#[test]
fn check_signing_package_serialization() {
let signing_package = samples::signing_package();
let json = serde_json::to_string_pretty(&signing_package).unwrap();
println!("{}", json);
let decoded_signing_package: SigningPackage = serde_json::from_str(&json).unwrap();
assert!(signing_package == decoded_signing_package);
let invalid_json = "{}";
assert!(serde_json::from_str::<SigningPackage>(invalid_json).is_err());
let json = r#"{
"signing_commitments": {
"2a00000000000000000000000000000000000000000000000000000000000000": {
"identifier": "2a00000000000000000000000000000000000000000000000000000000000000",
"hiding": "5866666666666666666666666666666666666666666666666666666666666666",
"binding": "c9a3f86aae465f0e56513864510f3997561fa2c9e85ea21dc2292309f3cd6022",
"ciphersuite": "FROST(Ed25519, SHA-512)"
}
},
"message": "68656c6c6f20776f726c64",
"ciphersuite": "FROST(Ed25519, SHA-512)"
}"#;
let decoded_signing_package: SigningPackage = serde_json::from_str(json).unwrap();
assert!(signing_package == decoded_signing_package);
// Invalid identifier
let invalid_json = r#"{
"signing_commitments": {
"0000000000000000000000000000000000000000000000000000000000000000": {
"identifier": "0000000000000000000000000000000000000000000000000000000000000000",
"hiding": "5866666666666666666666666666666666666666666666666666666666666666",
"binding": "c9a3f86aae465f0e56513864510f3997561fa2c9e85ea21dc2292309f3cd6022",
"ciphersuite": "FROST(Ed25519, SHA-512)"
}
},
"message": "68656c6c6f20776f726c64",
"ciphersuite": "FROST(Ed25519, SHA-512)"
}"#;
assert!(serde_json::from_str::<SigningPackage>(invalid_json).is_err());
// Invalid field
let invalid_json = r#"{
"signing_commitments": {
"2a00000000000000000000000000000000000000000000000000000000000000": {
"identifier": "2a00000000000000000000000000000000000000000000000000000000000000",
"foo": "5866666666666666666666666666666666666666666666666666666666666666",
"binding": "c9a3f86aae465f0e56513864510f3997561fa2c9e85ea21dc2292309f3cd6022",
"ciphersuite": "FROST(Ed25519, SHA-512)"
}
},
"message": "68656c6c6f20776f726c64",
"ciphersuite": "FROST(Ed25519, SHA-512)"
}"#;
assert!(serde_json::from_str::<SigningPackage>(invalid_json).is_err());
// Missing field
let invalid_json = r#"{
"signing_commitments": {
"2a00000000000000000000000000000000000000000000000000000000000000": {
"identifier": "2a00000000000000000000000000000000000000000000000000000000000000",
"binding": "c9a3f86aae465f0e56513864510f3997561fa2c9e85ea21dc2292309f3cd6022",
"ciphersuite": "FROST(Ed25519, SHA-512)"
}
},
"message": "68656c6c6f20776f726c64",
"ciphersuite": "FROST(Ed25519, SHA-512)"
}"#;
assert!(serde_json::from_str::<SigningPackage>(invalid_json).is_err());
// Extra field
let invalid_json = r#"{
"signing_commitments": {
"2a00000000000000000000000000000000000000000000000000000000000000": {
"identifier": "2a00000000000000000000000000000000000000000000000000000000000000",
"hiding": "5866666666666666666666666666666666666666666666666666666666666666",
"binding": "c9a3f86aae465f0e56513864510f3997561fa2c9e85ea21dc2292309f3cd6022",
"ciphersuite": "FROST(Ed25519, SHA-512)"
}
},
"message": "68656c6c6f20776f726c64",
"extra": 1,
"ciphersuite": "FROST(Ed25519, SHA-512)"
}
"#;
assert!(serde_json::from_str::<SigningPackage>(invalid_json).is_err());
}
#[test]
fn check_signature_share_serialization() {
let signature_share = samples::signature_share();
let json = serde_json::to_string_pretty(&signature_share).unwrap();
println!("{}", json);
let decoded_signature_share: SignatureShare = serde_json::from_str(&json).unwrap();
assert!(signature_share == decoded_signature_share);
let json = r#"{
"identifier": "2a00000000000000000000000000000000000000000000000000000000000000",
"signature": "498d4e9311420c903913a56c94a694b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0a",
"ciphersuite": "FROST(Ed25519, SHA-512)"
}"#;
let decoded_commitments: SignatureShare = serde_json::from_str(json).unwrap();
assert!(signature_share == decoded_commitments);
let invalid_json = "{}";
assert!(serde_json::from_str::<SignatureShare>(invalid_json).is_err());
// Invalid identifier
let invalid_json = r#"{
"identifier": "0000000000000000000000000000000000000000000000000000000000000000",
"signature": "498d4e9311420c903913a56c94a694b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0a",
"ciphersuite": "FROST(Ed25519, SHA-512)"
}"#;
assert!(serde_json::from_str::<SignatureShare>(invalid_json).is_err());
// Invalid field
let invalid_json = r#"{
"identifier": "2a00000000000000000000000000000000000000000000000000000000000000",
"foo": "498d4e9311420c903913a56c94a694b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0a",
"ciphersuite": "FROST(Ed25519, SHA-512)"
}"#;
assert!(serde_json::from_str::<SignatureShare>(invalid_json).is_err());
// Missing field
let invalid_json = r#"{
"identifier": "2a00000000000000000000000000000000000000000000000000000000000000",,
"ciphersuite": "FROST(Ed25519, SHA-512)"
}"#;
assert!(serde_json::from_str::<SignatureShare>(invalid_json).is_err());
// Extra field
let invalid_json = r#"{
"identifier": "2a00000000000000000000000000000000000000000000000000000000000000",
"signature": "498d4e9311420c903913a56c94a694b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0a",
"extra": 1,
"ciphersuite": "FROST(Ed25519, SHA-512)"
}"#;
assert!(serde_json::from_str::<SignatureShare>(invalid_json).is_err());
}
#[test]
fn check_secret_share_serialization() {
let secret_share = samples::secret_share();
let json = serde_json::to_string_pretty(&secret_share).unwrap();
println!("{}", json);
let decoded_secret_share: SecretShare = serde_json::from_str(&json).unwrap();
assert!(secret_share == decoded_secret_share);
let json = r#"{
"identifier": "2a00000000000000000000000000000000000000000000000000000000000000",
"value": "498d4e9311420c903913a56c94a694b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0a",
"commitment": [
"5866666666666666666666666666666666666666666666666666666666666666"
],
"ciphersuite": "FROST(Ed25519, SHA-512)"
}"#;
let decoded_secret_share: SecretShare = serde_json::from_str(json).unwrap();
assert!(secret_share == decoded_secret_share);
let invalid_json = "{}";
assert!(serde_json::from_str::<SecretShare>(invalid_json).is_err());
// Invalid identifier
let invalid_json = r#"{
"identifier": "0000000000000000000000000000000000000000000000000000000000000000",
"value": "498d4e9311420c903913a56c94a694b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0a",
"commitment": [
"5866666666666666666666666666666666666666666666666666666666666666"
],
"ciphersuite": "FROST(Ed25519, SHA-512)"
}"#;
assert!(serde_json::from_str::<SecretShare>(invalid_json).is_err());
// Invalid field
let invalid_json = r#"{
"identifier": "2a00000000000000000000000000000000000000000000000000000000000000",
"foo": "498d4e9311420c903913a56c94a694b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0a",
"commitment": [
"5866666666666666666666666666666666666666666666666666666666666666"
],
"ciphersuite": "FROST(Ed25519, SHA-512)"
}"#;
assert!(serde_json::from_str::<SecretShare>(invalid_json).is_err());
// Missing field
let invalid_json = r#"{
"identifier": "2a00000000000000000000000000000000000000000000000000000000000000",
"commitment": [
"5866666666666666666666666666666666666666666666666666666666666666"
],
"ciphersuite": "FROST(Ed25519, SHA-512)"
}"#;
assert!(serde_json::from_str::<SecretShare>(invalid_json).is_err());
// Extra field
let invalid_json = r#"{
"identifier": "2a00000000000000000000000000000000000000000000000000000000000000",
"value": "498d4e9311420c903913a56c94a694b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0a",
"commitment": [
"5866666666666666666666666666666666666666666666666666666666666666"
],
"extra": 1,
"ciphersuite": "FROST(Ed25519, SHA-512)"
}"#;
assert!(serde_json::from_str::<SecretShare>(invalid_json).is_err());
}
#[test]
fn check_key_package_serialization() {
let key_package = samples::key_package();
let json = serde_json::to_string_pretty(&key_package).unwrap();
println!("{}", json);
let decoded_key_package: KeyPackage = serde_json::from_str(&json).unwrap();
assert!(key_package == decoded_key_package);
let json = r#"{
"identifier": "2a00000000000000000000000000000000000000000000000000000000000000",
"secret_share": "498d4e9311420c903913a56c94a694b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0a",
"public": "5866666666666666666666666666666666666666666666666666666666666666",
"group_public": "5866666666666666666666666666666666666666666666666666666666666666",
"ciphersuite": "FROST(Ed25519, SHA-512)"
}"#;
let decoded_key_package: KeyPackage = serde_json::from_str(json).unwrap();
assert!(key_package == decoded_key_package);
let invalid_json = "{}";
assert!(serde_json::from_str::<KeyPackage>(invalid_json).is_err());
// Invalid identifier
let invalid_json = r#"{
"identifier": "0000000000000000000000000000000000000000000000000000000000000000",
"secret_share": "498d4e9311420c903913a56c94a694b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0a",
"public": "5866666666666666666666666666666666666666666666666666666666666666",
"group_public": "5866666666666666666666666666666666666666666666666666666666666666",
"ciphersuite": "FROST(Ed25519, SHA-512)"
}"#;
assert!(serde_json::from_str::<KeyPackage>(invalid_json).is_err());
// Invalid field
let invalid_json = r#"{
"identifier": "2a00000000000000000000000000000000000000000000000000000000000000",
"foo": "498d4e9311420c903913a56c94a694b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0a",
"public": "5866666666666666666666666666666666666666666666666666666666666666",
"group_public": "5866666666666666666666666666666666666666666666666666666666666666",
"ciphersuite": "FROST(Ed25519, SHA-512)"
}"#;
assert!(serde_json::from_str::<KeyPackage>(invalid_json).is_err());
// Missing field
let invalid_json = r#"{
"identifier": "2a00000000000000000000000000000000000000000000000000000000000000",
"public": "5866666666666666666666666666666666666666666666666666666666666666",
"group_public": "5866666666666666666666666666666666666666666666666666666666666666",
"ciphersuite": "FROST(Ed25519, SHA-512)"
}"#;
assert!(serde_json::from_str::<KeyPackage>(invalid_json).is_err());
// Extra field
let invalid_json = r#"{
"identifier": "2a00000000000000000000000000000000000000000000000000000000000000",
"secret_share": "498d4e9311420c903913a56c94a694b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0a",
"public": "5866666666666666666666666666666666666666666666666666666666666666",
"group_public": "5866666666666666666666666666666666666666666666666666666666666666",
"extra_field": 1,
"ciphersuite": "FROST(Ed25519, SHA-512)"
}"#;
assert!(serde_json::from_str::<KeyPackage>(invalid_json).is_err());
}
#[test]
fn check_public_key_package_serialization() {
let public_key_package = samples::public_key_package();
let json = serde_json::to_string_pretty(&public_key_package).unwrap();
println!("{}", json);
let decoded_public_key_package: PublicKeyPackage = serde_json::from_str(&json).unwrap();
assert!(public_key_package == decoded_public_key_package);
let json = r#"{
"signer_pubkeys": {
"2a00000000000000000000000000000000000000000000000000000000000000": "5866666666666666666666666666666666666666666666666666666666666666"
},
"group_public": "5866666666666666666666666666666666666666666666666666666666666666",
"ciphersuite": "FROST(Ed25519, SHA-512)"
}"#;
let decoded_public_key_package: PublicKeyPackage = serde_json::from_str(json).unwrap();
assert!(public_key_package == decoded_public_key_package);
let invalid_json = "{}";
assert!(serde_json::from_str::<PublicKeyPackage>(invalid_json).is_err());
// Invalid identifier
let invalid_json = r#"{
"signer_pubkeys": {
"0000000000000000000000000000000000000000000000000000000000000000": "5866666666666666666666666666666666666666666666666666666666666666"
},
"group_public": "5866666666666666666666666666666666666666666666666666666666666666",
"ciphersuite": "FROST(Ed25519, SHA-512)"
}"#;
assert!(serde_json::from_str::<PublicKeyPackage>(invalid_json).is_err());
// Invalid field
let invalid_json = r#"{
"signer_pubkeys": {
"2a00000000000000000000000000000000000000000000000000000000000000": "5866666666666666666666666666666666666666666666666666666666666666"
},
"foo": "5866666666666666666666666666666666666666666666666666666666666666",
"ciphersuite": "FROST(Ed25519, SHA-512)"
}"#;
assert!(serde_json::from_str::<PublicKeyPackage>(invalid_json).is_err());
// Missing field
let invalid_json = r#"{
"signer_pubkeys": {
"2a00000000000000000000000000000000000000000000000000000000000000": "5866666666666666666666666666666666666666666666666666666666666666"
},
"ciphersuite": "FROST(Ed25519, SHA-512)"
}"#;
assert!(serde_json::from_str::<PublicKeyPackage>(invalid_json).is_err());
// Extra field
let invalid_json = r#"{
"signer_pubkeys": {
"2a00000000000000000000000000000000000000000000000000000000000000": "5866666666666666666666666666666666666666666666666666666666666666"
},
"group_public": "5866666666666666666666666666666666666666666666666666666666666666",
"extra": 1,
"ciphersuite": "FROST(Ed25519, SHA-512)"
}"#;
assert!(serde_json::from_str::<PublicKeyPackage>(invalid_json).is_err());
}
#[test]
fn check_round1_package_serialization() {
let round1_package = samples::round1_package();
let json = serde_json::to_string_pretty(&round1_package).unwrap();
println!("{}", json);
let decoded_round1_package: round1::Package = serde_json::from_str(&json).unwrap();
assert!(round1_package == decoded_round1_package);
let json = r#"{
"sender_identifier": "2a00000000000000000000000000000000000000000000000000000000000000",
"commitment": [
"5866666666666666666666666666666666666666666666666666666666666666"
],
"proof_of_knowledge": "5866666666666666666666666666666666666666666666666666666666666666498d4e9311420c903913a56c94a694b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0a",
"ciphersuite": "FROST(Ed25519, SHA-512)"
}"#;
let decoded_round1_package: round1::Package = serde_json::from_str(json).unwrap();
assert!(round1_package == decoded_round1_package);
let invalid_json = "{}";
assert!(serde_json::from_str::<round1::Package>(invalid_json).is_err());
// Invalid identifier
let invalid_json = r#"{
"sender_identifier": "0000000000000000000000000000000000000000000000000000000000000000",
"commitment": [
"5866666666666666666666666666666666666666666666666666666666666666"
],
"proof_of_knowledge": "5866666666666666666666666666666666666666666666666666666666666666498d4e9311420c903913a56c94a694b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0a",
"ciphersuite": "FROST(Ed25519, SHA-512)"
}"#;
assert!(serde_json::from_str::<round1::Package>(invalid_json).is_err());
// Invalid field
let invalid_json = r#"{
"sender_identifier": "2a00000000000000000000000000000000000000000000000000000000000000",
"commitment": [
"5866666666666666666666666666666666666666666666666666666666666666"
],
"foo": "5866666666666666666666666666666666666666666666666666666666666666498d4e9311420c903913a56c94a694b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0a",
"ciphersuite": "FROST(Ed25519, SHA-512)"
}"#;
assert!(serde_json::from_str::<round1::Package>(invalid_json).is_err());
// Missing field
let invalid_json = r#"{
"sender_identifier": "2a00000000000000000000000000000000000000000000000000000000000000",
"commitment": [
"5866666666666666666666666666666666666666666666666666666666666666"
],
"ciphersuite": "FROST(Ed25519, SHA-512)"
}"#;
assert!(serde_json::from_str::<round1::Package>(invalid_json).is_err());
// Extra field
let invalid_json = r#"{
"sender_identifier": "2a00000000000000000000000000000000000000000000000000000000000000",
"commitment": [
"5866666666666666666666666666666666666666666666666666666666666666"
],
"proof_of_knowledge": "5866666666666666666666666666666666666666666666666666666666666666498d4e9311420c903913a56c94a694b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0a",
"extra": 1,
"ciphersuite": "FROST(Ed25519, SHA-512)"
}"#;
assert!(serde_json::from_str::<round1::Package>(invalid_json).is_err());
}
#[test]
fn check_round2_package_serialization() {
let round2_package = samples::round2_package();
let json = serde_json::to_string_pretty(&round2_package).unwrap();
println!("{}", json);
let decoded_round2_package: round2::Package = serde_json::from_str(&json).unwrap();
assert!(round2_package == decoded_round2_package);
let json = r#"{
"sender_identifier": "2a00000000000000000000000000000000000000000000000000000000000000",
"receiver_identifier": "2a00000000000000000000000000000000000000000000000000000000000000",
"secret_share": "498d4e9311420c903913a56c94a694b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0a",
"ciphersuite": "FROST(Ed25519, SHA-512)"
}"#;
let decoded_round2_package: round2::Package = serde_json::from_str(json).unwrap();
assert!(round2_package == decoded_round2_package);
let invalid_json = "{}";
assert!(serde_json::from_str::<round2::Package>(invalid_json).is_err());
// Invalid identifier
let invalid_json = r#"{
"sender_identifier": "0000000000000000000000000000000000000000000000000000000000000000",
"receiver_identifier": "2a00000000000000000000000000000000000000000000000000000000000000",
"secret_share": "498d4e9311420c903913a56c94a694b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0a",
"ciphersuite": "FROST(Ed25519, SHA-512)"
}"#;
assert!(serde_json::from_str::<round2::Package>(invalid_json).is_err());
// Invalid field
let invalid_json = r#"{
"sender_identifier": "2a00000000000000000000000000000000000000000000000000000000000000",
"foo": "2a00000000000000000000000000000000000000000000000000000000000000",
"secret_share": "498d4e9311420c903913a56c94a694b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0a",
"ciphersuite": "FROST(Ed25519, SHA-512)"
}"#;
assert!(serde_json::from_str::<round2::Package>(invalid_json).is_err());
// Missing field
let invalid_json = r#"{
"sender_identifier": "2a00000000000000000000000000000000000000000000000000000000000000",
"secret_share": "498d4e9311420c903913a56c94a694b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0a",
"ciphersuite": "FROST(Ed25519, SHA-512)"
}"#;
assert!(serde_json::from_str::<round2::Package>(invalid_json).is_err());
// Extra field
let invalid_json = r#"{
"sender_identifier": "2a00000000000000000000000000000000000000000000000000000000000000",
"receiver_identifier": "2a00000000000000000000000000000000000000000000000000000000000000",
"secret_share": "498d4e9311420c903913a56c94a694b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0a",
"extra": 1,
"ciphersuite": "FROST(Ed25519, SHA-512)"
}"#;
assert!(serde_json::from_str::<round2::Package>(invalid_json).is_err());
}

View File

@ -40,6 +40,7 @@ serde_json = "1.0"
[features]
nightly = []
default = []
serde = ["frost-core/serde"]
[lib]
# Disables non-criterion benchmark which is not used; prevents errors

View File

@ -14,6 +14,9 @@ use sha3::{
use frost_core::frost;
#[cfg(feature = "serde")]
use frost_core::serde;
#[cfg(test)]
mod tests;
@ -142,6 +145,8 @@ const CONTEXT_STRING: &str = "FROST-ED448-SHAKE256-v11";
/// An implementation of the FROST(Ed448, SHAKE256) ciphersuite.
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(crate = "self::serde"))]
pub struct Ed448Shake256;
impl Ciphersuite for Ed448Shake256 {

View File

@ -0,0 +1,6 @@
{
"identifier": "2a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"element1": "14fa30f25b790898adc8d74e2c13bdfdc4397ce61cffd33ad7c2a0051e9c78874098a36c7373ea4b62c7c9563720768824bcb66e71463f6900",
"element2": "ed8693eacdfbeada6ba0cdd1beb2bcbb98302a3a8365650db8c4d88a726de3b7d74d8835a0d76e03b0c2865020d659b38d04d74a63e905ae80",
"scalar1": "4d83e51cb78150c2380ad9b3a18148166024e4c9db3cdf82466d3153aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2a00"
}

View File

@ -26,9 +26,9 @@ fn element2() -> Element<C> {
fn scalar1() -> Scalar<C> {
let one = <<C as Ciphersuite>::Group as Group>::Field::one();
let two = one + one;
// To return a fixed non-small number, get the inverse of 2
<<C as Ciphersuite>::Group as Group>::Field::invert(&two)
let three = one + one + one;
// To return a fixed non-small number, get the inverse of 3
<<C as Ciphersuite>::Group as Group>::Field::invert(&three)
.expect("nonzero elements have inverses")
}

View File

@ -0,0 +1,548 @@
#![cfg(feature = "serde")]
mod helpers;
use frost_ed448::{
keys::{
dkg::{round1, round2},
KeyPackage, PublicKeyPackage, SecretShare,
},
round1::SigningCommitments,
round2::SignatureShare,
SigningPackage,
};
use helpers::samples;
#[test]
fn check_signing_commitments_serialization() {
let commitments = samples::signing_commitments();
let json = serde_json::to_string_pretty(&commitments).unwrap();
println!("{}", json);
let decoded_commitments: SigningCommitments = serde_json::from_str(&json).unwrap();
assert!(commitments == decoded_commitments);
let json = r#"{
"identifier": "2a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"hiding": "14fa30f25b790898adc8d74e2c13bdfdc4397ce61cffd33ad7c2a0051e9c78874098a36c7373ea4b62c7c9563720768824bcb66e71463f6900",
"binding": "ed8693eacdfbeada6ba0cdd1beb2bcbb98302a3a8365650db8c4d88a726de3b7d74d8835a0d76e03b0c2865020d659b38d04d74a63e905ae80",
"ciphersuite": "FROST(Ed448, SHAKE256)"
}"#;
let decoded_commitments: SigningCommitments = serde_json::from_str(json).unwrap();
assert!(commitments == decoded_commitments);
let invalid_json = "{}";
assert!(serde_json::from_str::<SigningCommitments>(invalid_json).is_err());
// Wrong ciphersuite
let invalid_json = r#"{
"identifier": "2a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"hiding": "14fa30f25b790898adc8d74e2c13bdfdc4397ce61cffd33ad7c2a0051e9c78874098a36c7373ea4b62c7c9563720768824bcb66e71463f6900",
"binding": "ed8693eacdfbeada6ba0cdd1beb2bcbb98302a3a8365650db8c4d88a726de3b7d74d8835a0d76e03b0c2865020d659b38d04d74a63e905ae80",
"ciphersuite": "FROST(Wrong, SHA-512)"
}"#;
assert!(serde_json::from_str::<SigningCommitments>(invalid_json).is_err());
// Invalid identifier
let invalid_json = r#"{
"identifier": "0000000000000000000000000000000000000000000000000000000000000000",
"hiding": "14fa30f25b790898adc8d74e2c13bdfdc4397ce61cffd33ad7c2a0051e9c78874098a36c7373ea4b62c7c9563720768824bcb66e71463f6900",
"binding": "ed8693eacdfbeada6ba0cdd1beb2bcbb98302a3a8365650db8c4d88a726de3b7d74d8835a0d76e03b0c2865020d659b38d04d74a63e905ae80"
}"#;
assert!(serde_json::from_str::<SigningCommitments>(invalid_json).is_err());
// Invalid field
let invalid_json = r#"{
"foo": "0000000000000000000000000000000000000000000000000000000000000000",
"hiding": "14fa30f25b790898adc8d74e2c13bdfdc4397ce61cffd33ad7c2a0051e9c78874098a36c7373ea4b62c7c9563720768824bcb66e71463f6900",
"binding": "ed8693eacdfbeada6ba0cdd1beb2bcbb98302a3a8365650db8c4d88a726de3b7d74d8835a0d76e03b0c2865020d659b38d04d74a63e905ae80"
}"#;
assert!(serde_json::from_str::<SigningCommitments>(invalid_json).is_err());
// Missing field
let invalid_json = r#"{
"foo": "0000000000000000000000000000000000000000000000000000000000000000",
"binding": "ed8693eacdfbeada6ba0cdd1beb2bcbb98302a3a8365650db8c4d88a726de3b7d74d8835a0d76e03b0c2865020d659b38d04d74a63e905ae80"
}"#;
assert!(serde_json::from_str::<SigningCommitments>(invalid_json).is_err());
// Extra field
let invalid_json = r#"{
"identifier": "2a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"hiding": "14fa30f25b790898adc8d74e2c13bdfdc4397ce61cffd33ad7c2a0051e9c78874098a36c7373ea4b62c7c9563720768824bcb66e71463f6900",
"binding": "ed8693eacdfbeada6ba0cdd1beb2bcbb98302a3a8365650db8c4d88a726de3b7d74d8835a0d76e03b0c2865020d659b38d04d74a63e905ae80",
"extra": 1
}"#;
assert!(serde_json::from_str::<SigningCommitments>(invalid_json).is_err());
}
#[test]
fn check_signing_package_serialization() {
let signing_package = samples::signing_package();
let json = serde_json::to_string_pretty(&signing_package).unwrap();
println!("{}", json);
let decoded_signing_package: SigningPackage = serde_json::from_str(&json).unwrap();
assert!(signing_package == decoded_signing_package);
let invalid_json = "{}";
assert!(serde_json::from_str::<SigningPackage>(invalid_json).is_err());
let json = r#"{
"signing_commitments": {
"2a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000": {
"identifier": "2a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"hiding": "14fa30f25b790898adc8d74e2c13bdfdc4397ce61cffd33ad7c2a0051e9c78874098a36c7373ea4b62c7c9563720768824bcb66e71463f6900",
"binding": "ed8693eacdfbeada6ba0cdd1beb2bcbb98302a3a8365650db8c4d88a726de3b7d74d8835a0d76e03b0c2865020d659b38d04d74a63e905ae80",
"ciphersuite": "FROST(Ed448, SHAKE256)"
}
},
"message": "68656c6c6f20776f726c64",
"ciphersuite": "FROST(Ed448, SHAKE256)"
}"#;
let decoded_signing_package: SigningPackage = serde_json::from_str(json).unwrap();
assert!(signing_package == decoded_signing_package);
// Invalid identifier
let invalid_json = r#"{
"signing_commitments": {
"0000000000000000000000000000000000000000000000000000000000000000": {
"identifier": "0000000000000000000000000000000000000000000000000000000000000000",
"hiding": "14fa30f25b790898adc8d74e2c13bdfdc4397ce61cffd33ad7c2a0051e9c78874098a36c7373ea4b62c7c9563720768824bcb66e71463f6900",
"binding": "ed8693eacdfbeada6ba0cdd1beb2bcbb98302a3a8365650db8c4d88a726de3b7d74d8835a0d76e03b0c2865020d659b38d04d74a63e905ae80",
"ciphersuite": "FROST(Ed448, SHAKE256)"
}
},
"message": "68656c6c6f20776f726c64",
"ciphersuite": "FROST(Ed448, SHAKE256)"
}"#;
assert!(serde_json::from_str::<SigningPackage>(invalid_json).is_err());
// Invalid field
let invalid_json = r#"{
"signing_commitments": {
"2a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000": {
"identifier": "2a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"foo": "14fa30f25b790898adc8d74e2c13bdfdc4397ce61cffd33ad7c2a0051e9c78874098a36c7373ea4b62c7c9563720768824bcb66e71463f6900",
"binding": "ed8693eacdfbeada6ba0cdd1beb2bcbb98302a3a8365650db8c4d88a726de3b7d74d8835a0d76e03b0c2865020d659b38d04d74a63e905ae80",
"ciphersuite": "FROST(Ed448, SHAKE256)"
}
},
"message": "68656c6c6f20776f726c64",
"ciphersuite": "FROST(Ed448, SHAKE256)"
}"#;
assert!(serde_json::from_str::<SigningPackage>(invalid_json).is_err());
// Missing field
let invalid_json = r#"{
"signing_commitments": {
"2a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000": {
"identifier": "2a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"binding": "ed8693eacdfbeada6ba0cdd1beb2bcbb98302a3a8365650db8c4d88a726de3b7d74d8835a0d76e03b0c2865020d659b38d04d74a63e905ae80",
"ciphersuite": "FROST(Ed448, SHAKE256)"
}
},
"message": "68656c6c6f20776f726c64",
"ciphersuite": "FROST(Ed448, SHAKE256)"
}"#;
assert!(serde_json::from_str::<SigningPackage>(invalid_json).is_err());
// Extra field
let invalid_json = r#"{
"signing_commitments": {
"2a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000": {
"identifier": "2a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"hiding": "14fa30f25b790898adc8d74e2c13bdfdc4397ce61cffd33ad7c2a0051e9c78874098a36c7373ea4b62c7c9563720768824bcb66e71463f6900",
"binding": "ed8693eacdfbeada6ba0cdd1beb2bcbb98302a3a8365650db8c4d88a726de3b7d74d8835a0d76e03b0c2865020d659b38d04d74a63e905ae80",
"ciphersuite": "FROST(Ed448, SHAKE256)"
}
},
"message": "68656c6c6f20776f726c64",
"extra": 1,
"ciphersuite": "FROST(Ed448, SHAKE256)"
}
"#;
assert!(serde_json::from_str::<SigningPackage>(invalid_json).is_err());
}
#[test]
fn check_signature_share_serialization() {
let signature_share = samples::signature_share();
let json = serde_json::to_string_pretty(&signature_share).unwrap();
println!("{}", json);
let decoded_signature_share: SignatureShare = serde_json::from_str(&json).unwrap();
assert!(signature_share == decoded_signature_share);
let json = r#"{
"identifier": "2a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"signature": "4d83e51cb78150c2380ad9b3a18148166024e4c9db3cdf82466d3153aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2a00",
"ciphersuite": "FROST(Ed448, SHAKE256)"
}"#;
let decoded_commitments: SignatureShare = serde_json::from_str(json).unwrap();
assert!(signature_share == decoded_commitments);
let invalid_json = "{}";
assert!(serde_json::from_str::<SignatureShare>(invalid_json).is_err());
// Invalid identifier
let invalid_json = r#"{
"identifier": "0000000000000000000000000000000000000000000000000000000000000000",
"signature": "4d83e51cb78150c2380ad9b3a18148166024e4c9db3cdf82466d3153aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2a00",
"ciphersuite": "FROST(Ed448, SHAKE256)"
}"#;
assert!(serde_json::from_str::<SignatureShare>(invalid_json).is_err());
// Invalid field
let invalid_json = r#"{
"identifier": "2a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"foo": "4d83e51cb78150c2380ad9b3a18148166024e4c9db3cdf82466d3153aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2a00",
"ciphersuite": "FROST(Ed448, SHAKE256)"
}"#;
assert!(serde_json::from_str::<SignatureShare>(invalid_json).is_err());
// Missing field
let invalid_json = r#"{
"identifier": "2a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",,
"ciphersuite": "FROST(Ed448, SHAKE256)"
}"#;
assert!(serde_json::from_str::<SignatureShare>(invalid_json).is_err());
// Extra field
let invalid_json = r#"{
"identifier": "2a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"signature": "4d83e51cb78150c2380ad9b3a18148166024e4c9db3cdf82466d3153aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2a00",
"extra": 1,
"ciphersuite": "FROST(Ed448, SHAKE256)"
}"#;
assert!(serde_json::from_str::<SignatureShare>(invalid_json).is_err());
}
#[test]
fn check_secret_share_serialization() {
let secret_share = samples::secret_share();
let json = serde_json::to_string_pretty(&secret_share).unwrap();
println!("{}", json);
let decoded_secret_share: SecretShare = serde_json::from_str(&json).unwrap();
assert!(secret_share == decoded_secret_share);
let json = r#"{
"identifier": "2a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"value": "4d83e51cb78150c2380ad9b3a18148166024e4c9db3cdf82466d3153aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2a00",
"commitment": [
"14fa30f25b790898adc8d74e2c13bdfdc4397ce61cffd33ad7c2a0051e9c78874098a36c7373ea4b62c7c9563720768824bcb66e71463f6900"
],
"ciphersuite": "FROST(Ed448, SHAKE256)"
}"#;
let decoded_secret_share: SecretShare = serde_json::from_str(json).unwrap();
assert!(secret_share == decoded_secret_share);
let invalid_json = "{}";
assert!(serde_json::from_str::<SecretShare>(invalid_json).is_err());
// Invalid identifier
let invalid_json = r#"{
"identifier": "0000000000000000000000000000000000000000000000000000000000000000",
"value": "4d83e51cb78150c2380ad9b3a18148166024e4c9db3cdf82466d3153aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2a00",
"commitment": [
"14fa30f25b790898adc8d74e2c13bdfdc4397ce61cffd33ad7c2a0051e9c78874098a36c7373ea4b62c7c9563720768824bcb66e71463f6900"
],
"ciphersuite": "FROST(Ed448, SHAKE256)"
}"#;
assert!(serde_json::from_str::<SecretShare>(invalid_json).is_err());
// Invalid field
let invalid_json = r#"{
"identifier": "2a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"foo": "4d83e51cb78150c2380ad9b3a18148166024e4c9db3cdf82466d3153aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2a00",
"commitment": [
"14fa30f25b790898adc8d74e2c13bdfdc4397ce61cffd33ad7c2a0051e9c78874098a36c7373ea4b62c7c9563720768824bcb66e71463f6900"
],
"ciphersuite": "FROST(Ed448, SHAKE256)"
}"#;
assert!(serde_json::from_str::<SecretShare>(invalid_json).is_err());
// Missing field
let invalid_json = r#"{
"identifier": "2a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"commitment": [
"14fa30f25b790898adc8d74e2c13bdfdc4397ce61cffd33ad7c2a0051e9c78874098a36c7373ea4b62c7c9563720768824bcb66e71463f6900"
],
"ciphersuite": "FROST(Ed448, SHAKE256)"
}"#;
assert!(serde_json::from_str::<SecretShare>(invalid_json).is_err());
// Extra field
let invalid_json = r#"{
"identifier": "2a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"value": "4d83e51cb78150c2380ad9b3a18148166024e4c9db3cdf82466d3153aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2a00",
"commitment": [
"14fa30f25b790898adc8d74e2c13bdfdc4397ce61cffd33ad7c2a0051e9c78874098a36c7373ea4b62c7c9563720768824bcb66e71463f6900"
],
"extra": 1,
"ciphersuite": "FROST(Ed448, SHAKE256)"
}"#;
assert!(serde_json::from_str::<SecretShare>(invalid_json).is_err());
}
#[test]
fn check_key_package_serialization() {
let key_package = samples::key_package();
let json = serde_json::to_string_pretty(&key_package).unwrap();
println!("{}", json);
let decoded_key_package: KeyPackage = serde_json::from_str(&json).unwrap();
assert!(key_package == decoded_key_package);
let json = r#"{
"identifier": "2a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"secret_share": "4d83e51cb78150c2380ad9b3a18148166024e4c9db3cdf82466d3153aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2a00",
"public": "14fa30f25b790898adc8d74e2c13bdfdc4397ce61cffd33ad7c2a0051e9c78874098a36c7373ea4b62c7c9563720768824bcb66e71463f6900",
"group_public": "14fa30f25b790898adc8d74e2c13bdfdc4397ce61cffd33ad7c2a0051e9c78874098a36c7373ea4b62c7c9563720768824bcb66e71463f6900",
"ciphersuite": "FROST(Ed448, SHAKE256)"
}"#;
let decoded_key_package: KeyPackage = serde_json::from_str(json).unwrap();
assert!(key_package == decoded_key_package);
let invalid_json = "{}";
assert!(serde_json::from_str::<KeyPackage>(invalid_json).is_err());
// Invalid identifier
let invalid_json = r#"{
"identifier": "0000000000000000000000000000000000000000000000000000000000000000",
"secret_share": "4d83e51cb78150c2380ad9b3a18148166024e4c9db3cdf82466d3153aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2a00",
"public": "14fa30f25b790898adc8d74e2c13bdfdc4397ce61cffd33ad7c2a0051e9c78874098a36c7373ea4b62c7c9563720768824bcb66e71463f6900",
"group_public": "14fa30f25b790898adc8d74e2c13bdfdc4397ce61cffd33ad7c2a0051e9c78874098a36c7373ea4b62c7c9563720768824bcb66e71463f6900",
"ciphersuite": "FROST(Ed448, SHAKE256)"
}"#;
assert!(serde_json::from_str::<KeyPackage>(invalid_json).is_err());
// Invalid field
let invalid_json = r#"{
"identifier": "2a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"foo": "4d83e51cb78150c2380ad9b3a18148166024e4c9db3cdf82466d3153aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2a00",
"public": "14fa30f25b790898adc8d74e2c13bdfdc4397ce61cffd33ad7c2a0051e9c78874098a36c7373ea4b62c7c9563720768824bcb66e71463f6900",
"group_public": "14fa30f25b790898adc8d74e2c13bdfdc4397ce61cffd33ad7c2a0051e9c78874098a36c7373ea4b62c7c9563720768824bcb66e71463f6900",
"ciphersuite": "FROST(Ed448, SHAKE256)"
}"#;
assert!(serde_json::from_str::<KeyPackage>(invalid_json).is_err());
// Missing field
let invalid_json = r#"{
"identifier": "2a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"public": "14fa30f25b790898adc8d74e2c13bdfdc4397ce61cffd33ad7c2a0051e9c78874098a36c7373ea4b62c7c9563720768824bcb66e71463f6900",
"group_public": "14fa30f25b790898adc8d74e2c13bdfdc4397ce61cffd33ad7c2a0051e9c78874098a36c7373ea4b62c7c9563720768824bcb66e71463f6900",
"ciphersuite": "FROST(Ed448, SHAKE256)"
}"#;
assert!(serde_json::from_str::<KeyPackage>(invalid_json).is_err());
// Extra field
let invalid_json = r#"{
"identifier": "2a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"secret_share": "4d83e51cb78150c2380ad9b3a18148166024e4c9db3cdf82466d3153aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2a00",
"public": "14fa30f25b790898adc8d74e2c13bdfdc4397ce61cffd33ad7c2a0051e9c78874098a36c7373ea4b62c7c9563720768824bcb66e71463f6900",
"group_public": "14fa30f25b790898adc8d74e2c13bdfdc4397ce61cffd33ad7c2a0051e9c78874098a36c7373ea4b62c7c9563720768824bcb66e71463f6900",
"extra_field": 1,
"ciphersuite": "FROST(Ed448, SHAKE256)"
}"#;
assert!(serde_json::from_str::<KeyPackage>(invalid_json).is_err());
}
#[test]
fn check_public_key_package_serialization() {
let public_key_package = samples::public_key_package();
let json = serde_json::to_string_pretty(&public_key_package).unwrap();
println!("{}", json);
let decoded_public_key_package: PublicKeyPackage = serde_json::from_str(&json).unwrap();
assert!(public_key_package == decoded_public_key_package);
let json = r#"{
"signer_pubkeys": {
"2a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000": "14fa30f25b790898adc8d74e2c13bdfdc4397ce61cffd33ad7c2a0051e9c78874098a36c7373ea4b62c7c9563720768824bcb66e71463f6900"
},
"group_public": "14fa30f25b790898adc8d74e2c13bdfdc4397ce61cffd33ad7c2a0051e9c78874098a36c7373ea4b62c7c9563720768824bcb66e71463f6900",
"ciphersuite": "FROST(Ed448, SHAKE256)"
}"#;
let decoded_public_key_package: PublicKeyPackage = serde_json::from_str(json).unwrap();
assert!(public_key_package == decoded_public_key_package);
let invalid_json = "{}";
assert!(serde_json::from_str::<PublicKeyPackage>(invalid_json).is_err());
// Invalid identifier
let invalid_json = r#"{
"signer_pubkeys": {
"0000000000000000000000000000000000000000000000000000000000000000": "14fa30f25b790898adc8d74e2c13bdfdc4397ce61cffd33ad7c2a0051e9c78874098a36c7373ea4b62c7c9563720768824bcb66e71463f6900"
},
"group_public": "14fa30f25b790898adc8d74e2c13bdfdc4397ce61cffd33ad7c2a0051e9c78874098a36c7373ea4b62c7c9563720768824bcb66e71463f6900",
"ciphersuite": "FROST(Ed448, SHAKE256)"
}"#;
assert!(serde_json::from_str::<PublicKeyPackage>(invalid_json).is_err());
// Invalid field
let invalid_json = r#"{
"signer_pubkeys": {
"2a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000": "14fa30f25b790898adc8d74e2c13bdfdc4397ce61cffd33ad7c2a0051e9c78874098a36c7373ea4b62c7c9563720768824bcb66e71463f6900"
},
"foo": "14fa30f25b790898adc8d74e2c13bdfdc4397ce61cffd33ad7c2a0051e9c78874098a36c7373ea4b62c7c9563720768824bcb66e71463f6900",
"ciphersuite": "FROST(Ed448, SHAKE256)"
}"#;
assert!(serde_json::from_str::<PublicKeyPackage>(invalid_json).is_err());
// Missing field
let invalid_json = r#"{
"signer_pubkeys": {
"2a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000": "14fa30f25b790898adc8d74e2c13bdfdc4397ce61cffd33ad7c2a0051e9c78874098a36c7373ea4b62c7c9563720768824bcb66e71463f6900"
},
"ciphersuite": "FROST(Ed448, SHAKE256)"
}"#;
assert!(serde_json::from_str::<PublicKeyPackage>(invalid_json).is_err());
// Extra field
let invalid_json = r#"{
"signer_pubkeys": {
"2a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000": "14fa30f25b790898adc8d74e2c13bdfdc4397ce61cffd33ad7c2a0051e9c78874098a36c7373ea4b62c7c9563720768824bcb66e71463f6900"
},
"group_public": "14fa30f25b790898adc8d74e2c13bdfdc4397ce61cffd33ad7c2a0051e9c78874098a36c7373ea4b62c7c9563720768824bcb66e71463f6900",
"extra": 1,
"ciphersuite": "FROST(Ed448, SHAKE256)"
}"#;
assert!(serde_json::from_str::<PublicKeyPackage>(invalid_json).is_err());
}
#[test]
fn check_round1_package_serialization() {
let round1_package = samples::round1_package();
let json = serde_json::to_string_pretty(&round1_package).unwrap();
println!("{}", json);
let decoded_round1_package: round1::Package = serde_json::from_str(&json).unwrap();
assert!(round1_package == decoded_round1_package);
let json = r#"{
"sender_identifier": "2a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"commitment": [
"14fa30f25b790898adc8d74e2c13bdfdc4397ce61cffd33ad7c2a0051e9c78874098a36c7373ea4b62c7c9563720768824bcb66e71463f6900"
],
"proof_of_knowledge": "14fa30f25b790898adc8d74e2c13bdfdc4397ce61cffd33ad7c2a0051e9c78874098a36c7373ea4b62c7c9563720768824bcb66e71463f69004d83e51cb78150c2380ad9b3a18148166024e4c9db3cdf82466d3153aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2a00",
"ciphersuite": "FROST(Ed448, SHAKE256)"
}"#;
let decoded_round1_package: round1::Package = serde_json::from_str(json).unwrap();
assert!(round1_package == decoded_round1_package);
let invalid_json = "{}";
assert!(serde_json::from_str::<round1::Package>(invalid_json).is_err());
// Invalid identifier
let invalid_json = r#"{
"sender_identifier": "0000000000000000000000000000000000000000000000000000000000000000",
"commitment": [
"14fa30f25b790898adc8d74e2c13bdfdc4397ce61cffd33ad7c2a0051e9c78874098a36c7373ea4b62c7c9563720768824bcb66e71463f6900"
],
"proof_of_knowledge": "14fa30f25b790898adc8d74e2c13bdfdc4397ce61cffd33ad7c2a0051e9c78874098a36c7373ea4b62c7c9563720768824bcb66e71463f69004d83e51cb78150c2380ad9b3a18148166024e4c9db3cdf82466d3153aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2a00",
"ciphersuite": "FROST(Ed448, SHAKE256)"
}"#;
assert!(serde_json::from_str::<round1::Package>(invalid_json).is_err());
// Invalid field
let invalid_json = r#"{
"sender_identifier": "2a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"commitment": [
"14fa30f25b790898adc8d74e2c13bdfdc4397ce61cffd33ad7c2a0051e9c78874098a36c7373ea4b62c7c9563720768824bcb66e71463f6900"
],
"foo": "14fa30f25b790898adc8d74e2c13bdfdc4397ce61cffd33ad7c2a0051e9c78874098a36c7373ea4b62c7c9563720768824bcb66e71463f69004d83e51cb78150c2380ad9b3a18148166024e4c9db3cdf82466d3153aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2a00",
"ciphersuite": "FROST(Ed448, SHAKE256)"
}"#;
assert!(serde_json::from_str::<round1::Package>(invalid_json).is_err());
// Missing field
let invalid_json = r#"{
"sender_identifier": "2a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"commitment": [
"14fa30f25b790898adc8d74e2c13bdfdc4397ce61cffd33ad7c2a0051e9c78874098a36c7373ea4b62c7c9563720768824bcb66e71463f6900"
],
"ciphersuite": "FROST(Ed448, SHAKE256)"
}"#;
assert!(serde_json::from_str::<round1::Package>(invalid_json).is_err());
// Extra field
let invalid_json = r#"{
"sender_identifier": "2a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"commitment": [
"14fa30f25b790898adc8d74e2c13bdfdc4397ce61cffd33ad7c2a0051e9c78874098a36c7373ea4b62c7c9563720768824bcb66e71463f6900"
],
"proof_of_knowledge": "14fa30f25b790898adc8d74e2c13bdfdc4397ce61cffd33ad7c2a0051e9c78874098a36c7373ea4b62c7c9563720768824bcb66e71463f69004d83e51cb78150c2380ad9b3a18148166024e4c9db3cdf82466d3153aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2a00",
"extra": 1,
"ciphersuite": "FROST(Ed448, SHAKE256)"
}"#;
assert!(serde_json::from_str::<round1::Package>(invalid_json).is_err());
}
#[test]
fn check_round2_package_serialization() {
let round2_package = samples::round2_package();
let json = serde_json::to_string_pretty(&round2_package).unwrap();
println!("{}", json);
let decoded_round2_package: round2::Package = serde_json::from_str(&json).unwrap();
assert!(round2_package == decoded_round2_package);
let json = r#"{
"sender_identifier": "2a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"receiver_identifier": "2a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"secret_share": "4d83e51cb78150c2380ad9b3a18148166024e4c9db3cdf82466d3153aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2a00",
"ciphersuite": "FROST(Ed448, SHAKE256)"
}"#;
let decoded_round2_package: round2::Package = serde_json::from_str(json).unwrap();
assert!(round2_package == decoded_round2_package);
let invalid_json = "{}";
assert!(serde_json::from_str::<round2::Package>(invalid_json).is_err());
// Invalid identifier
let invalid_json = r#"{
"sender_identifier": "0000000000000000000000000000000000000000000000000000000000000000",
"receiver_identifier": "2a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"secret_share": "4d83e51cb78150c2380ad9b3a18148166024e4c9db3cdf82466d3153aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2a00",
"ciphersuite": "FROST(Ed448, SHAKE256)"
}"#;
assert!(serde_json::from_str::<round2::Package>(invalid_json).is_err());
// Invalid field
let invalid_json = r#"{
"sender_identifier": "2a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"foo": "2a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"secret_share": "4d83e51cb78150c2380ad9b3a18148166024e4c9db3cdf82466d3153aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2a00",
"ciphersuite": "FROST(Ed448, SHAKE256)"
}"#;
assert!(serde_json::from_str::<round2::Package>(invalid_json).is_err());
// Missing field
let invalid_json = r#"{
"sender_identifier": "2a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"secret_share": "4d83e51cb78150c2380ad9b3a18148166024e4c9db3cdf82466d3153aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2a00",
"ciphersuite": "FROST(Ed448, SHAKE256)"
}"#;
assert!(serde_json::from_str::<round2::Package>(invalid_json).is_err());
// Extra field
let invalid_json = r#"{
"sender_identifier": "2a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"receiver_identifier": "2a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"secret_share": "4d83e51cb78150c2380ad9b3a18148166024e4c9db3cdf82466d3153aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2a00",
"extra": 1,
"ciphersuite": "FROST(Ed448, SHAKE256)"
}"#;
assert!(serde_json::from_str::<round2::Package>(invalid_json).is_err());
}

View File

@ -43,6 +43,7 @@ serde_json = "1.0"
[features]
nightly = []
default = []
serde = ["frost-core/serde"]
[lib]
# Disables non-criterion benchmark which is not used; prevents errors

View File

@ -15,6 +15,9 @@ use sha2::{Digest, Sha256};
use frost_core::frost;
#[cfg(feature = "serde")]
use frost_core::serde;
#[cfg(test)]
mod tests;
@ -167,6 +170,8 @@ const CONTEXT_STRING: &str = "FROST-P256-SHA256-v11";
/// An implementation of the FROST(P-256, SHA-256) ciphersuite.
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(crate = "self::serde"))]
pub struct P256Sha256;
impl Ciphersuite for P256Sha256 {

View File

@ -0,0 +1,6 @@
{
"identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"element1": "036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
"element2": "037cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978",
"scalar1": "aaaaaaaa00000000aaaaaaaaaaaaaaaa7def51c91a0fbf034d26872ca84218e1"
}

View File

@ -26,9 +26,9 @@ fn element2() -> Element<C> {
fn scalar1() -> Scalar<C> {
let one = <<C as Ciphersuite>::Group as Group>::Field::one();
let two = one + one;
// To return a fixed non-small number, get the inverse of 2
<<C as Ciphersuite>::Group as Group>::Field::invert(&two)
let three = one + one + one;
// To return a fixed non-small number, get the inverse of 3
<<C as Ciphersuite>::Group as Group>::Field::invert(&three)
.expect("nonzero elements have inverses")
}

View File

@ -0,0 +1,548 @@
#![cfg(feature = "serde")]
mod helpers;
use frost_p256::{
keys::{
dkg::{round1, round2},
KeyPackage, PublicKeyPackage, SecretShare,
},
round1::SigningCommitments,
round2::SignatureShare,
SigningPackage,
};
use helpers::samples;
#[test]
fn check_signing_commitments_serialization() {
let commitments = samples::signing_commitments();
let json = serde_json::to_string_pretty(&commitments).unwrap();
println!("{}", json);
let decoded_commitments: SigningCommitments = serde_json::from_str(&json).unwrap();
assert!(commitments == decoded_commitments);
let json = r#"{
"identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"hiding": "036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
"binding": "037cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978",
"ciphersuite": "FROST(P-256, SHA-256)"
}"#;
let decoded_commitments: SigningCommitments = serde_json::from_str(json).unwrap();
assert!(commitments == decoded_commitments);
let invalid_json = "{}";
assert!(serde_json::from_str::<SigningCommitments>(invalid_json).is_err());
// Wrong ciphersuite
let invalid_json = r#"{
"identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"hiding": "036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
"binding": "037cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978",
"ciphersuite": "FROST(Wrong, SHA-512)"
}"#;
assert!(serde_json::from_str::<SigningCommitments>(invalid_json).is_err());
// Invalid identifier
let invalid_json = r#"{
"identifier": "0000000000000000000000000000000000000000000000000000000000000000",
"hiding": "036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
"binding": "037cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978"
}"#;
assert!(serde_json::from_str::<SigningCommitments>(invalid_json).is_err());
// Invalid field
let invalid_json = r#"{
"foo": "0000000000000000000000000000000000000000000000000000000000000000",
"hiding": "036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
"binding": "037cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978"
}"#;
assert!(serde_json::from_str::<SigningCommitments>(invalid_json).is_err());
// Missing field
let invalid_json = r#"{
"foo": "0000000000000000000000000000000000000000000000000000000000000000",
"binding": "037cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978"
}"#;
assert!(serde_json::from_str::<SigningCommitments>(invalid_json).is_err());
// Extra field
let invalid_json = r#"{
"identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"hiding": "036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
"binding": "037cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978",
"extra": 1
}"#;
assert!(serde_json::from_str::<SigningCommitments>(invalid_json).is_err());
}
#[test]
fn check_signing_package_serialization() {
let signing_package = samples::signing_package();
let json = serde_json::to_string_pretty(&signing_package).unwrap();
println!("{}", json);
let decoded_signing_package: SigningPackage = serde_json::from_str(&json).unwrap();
assert!(signing_package == decoded_signing_package);
let invalid_json = "{}";
assert!(serde_json::from_str::<SigningPackage>(invalid_json).is_err());
let json = r#"{
"signing_commitments": {
"000000000000000000000000000000000000000000000000000000000000002a": {
"identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"hiding": "036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
"binding": "037cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978",
"ciphersuite": "FROST(P-256, SHA-256)"
}
},
"message": "68656c6c6f20776f726c64",
"ciphersuite": "FROST(P-256, SHA-256)"
}"#;
let decoded_signing_package: SigningPackage = serde_json::from_str(json).unwrap();
assert!(signing_package == decoded_signing_package);
// Invalid identifier
let invalid_json = r#"{
"signing_commitments": {
"0000000000000000000000000000000000000000000000000000000000000000": {
"identifier": "0000000000000000000000000000000000000000000000000000000000000000",
"hiding": "036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
"binding": "037cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978",
"ciphersuite": "FROST(P-256, SHA-256)"
}
},
"message": "68656c6c6f20776f726c64",
"ciphersuite": "FROST(P-256, SHA-256)"
}"#;
assert!(serde_json::from_str::<SigningPackage>(invalid_json).is_err());
// Invalid field
let invalid_json = r#"{
"signing_commitments": {
"000000000000000000000000000000000000000000000000000000000000002a": {
"identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"foo": "036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
"binding": "037cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978",
"ciphersuite": "FROST(P-256, SHA-256)"
}
},
"message": "68656c6c6f20776f726c64",
"ciphersuite": "FROST(P-256, SHA-256)"
}"#;
assert!(serde_json::from_str::<SigningPackage>(invalid_json).is_err());
// Missing field
let invalid_json = r#"{
"signing_commitments": {
"000000000000000000000000000000000000000000000000000000000000002a": {
"identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"binding": "037cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978",
"ciphersuite": "FROST(P-256, SHA-256)"
}
},
"message": "68656c6c6f20776f726c64",
"ciphersuite": "FROST(P-256, SHA-256)"
}"#;
assert!(serde_json::from_str::<SigningPackage>(invalid_json).is_err());
// Extra field
let invalid_json = r#"{
"signing_commitments": {
"000000000000000000000000000000000000000000000000000000000000002a": {
"identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"hiding": "036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
"binding": "037cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978",
"ciphersuite": "FROST(P-256, SHA-256)"
}
},
"message": "68656c6c6f20776f726c64",
"extra": 1,
"ciphersuite": "FROST(P-256, SHA-256)"
}
"#;
assert!(serde_json::from_str::<SigningPackage>(invalid_json).is_err());
}
#[test]
fn check_signature_share_serialization() {
let signature_share = samples::signature_share();
let json = serde_json::to_string_pretty(&signature_share).unwrap();
println!("{}", json);
let decoded_signature_share: SignatureShare = serde_json::from_str(&json).unwrap();
assert!(signature_share == decoded_signature_share);
let json = r#"{
"identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"signature": "aaaaaaaa00000000aaaaaaaaaaaaaaaa7def51c91a0fbf034d26872ca84218e1",
"ciphersuite": "FROST(P-256, SHA-256)"
}"#;
let decoded_commitments: SignatureShare = serde_json::from_str(json).unwrap();
assert!(signature_share == decoded_commitments);
let invalid_json = "{}";
assert!(serde_json::from_str::<SignatureShare>(invalid_json).is_err());
// Invalid identifier
let invalid_json = r#"{
"identifier": "0000000000000000000000000000000000000000000000000000000000000000",
"signature": "aaaaaaaa00000000aaaaaaaaaaaaaaaa7def51c91a0fbf034d26872ca84218e1",
"ciphersuite": "FROST(P-256, SHA-256)"
}"#;
assert!(serde_json::from_str::<SignatureShare>(invalid_json).is_err());
// Invalid field
let invalid_json = r#"{
"identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"foo": "aaaaaaaa00000000aaaaaaaaaaaaaaaa7def51c91a0fbf034d26872ca84218e1",
"ciphersuite": "FROST(P-256, SHA-256)"
}"#;
assert!(serde_json::from_str::<SignatureShare>(invalid_json).is_err());
// Missing field
let invalid_json = r#"{
"identifier": "000000000000000000000000000000000000000000000000000000000000002a",,
"ciphersuite": "FROST(P-256, SHA-256)"
}"#;
assert!(serde_json::from_str::<SignatureShare>(invalid_json).is_err());
// Extra field
let invalid_json = r#"{
"identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"signature": "aaaaaaaa00000000aaaaaaaaaaaaaaaa7def51c91a0fbf034d26872ca84218e1",
"extra": 1,
"ciphersuite": "FROST(P-256, SHA-256)"
}"#;
assert!(serde_json::from_str::<SignatureShare>(invalid_json).is_err());
}
#[test]
fn check_secret_share_serialization() {
let secret_share = samples::secret_share();
let json = serde_json::to_string_pretty(&secret_share).unwrap();
println!("{}", json);
let decoded_secret_share: SecretShare = serde_json::from_str(&json).unwrap();
assert!(secret_share == decoded_secret_share);
let json = r#"{
"identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"value": "aaaaaaaa00000000aaaaaaaaaaaaaaaa7def51c91a0fbf034d26872ca84218e1",
"commitment": [
"036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296"
],
"ciphersuite": "FROST(P-256, SHA-256)"
}"#;
let decoded_secret_share: SecretShare = serde_json::from_str(json).unwrap();
assert!(secret_share == decoded_secret_share);
let invalid_json = "{}";
assert!(serde_json::from_str::<SecretShare>(invalid_json).is_err());
// Invalid identifier
let invalid_json = r#"{
"identifier": "0000000000000000000000000000000000000000000000000000000000000000",
"value": "aaaaaaaa00000000aaaaaaaaaaaaaaaa7def51c91a0fbf034d26872ca84218e1",
"commitment": [
"036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296"
],
"ciphersuite": "FROST(P-256, SHA-256)"
}"#;
assert!(serde_json::from_str::<SecretShare>(invalid_json).is_err());
// Invalid field
let invalid_json = r#"{
"identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"foo": "aaaaaaaa00000000aaaaaaaaaaaaaaaa7def51c91a0fbf034d26872ca84218e1",
"commitment": [
"036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296"
],
"ciphersuite": "FROST(P-256, SHA-256)"
}"#;
assert!(serde_json::from_str::<SecretShare>(invalid_json).is_err());
// Missing field
let invalid_json = r#"{
"identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"commitment": [
"036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296"
],
"ciphersuite": "FROST(P-256, SHA-256)"
}"#;
assert!(serde_json::from_str::<SecretShare>(invalid_json).is_err());
// Extra field
let invalid_json = r#"{
"identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"value": "aaaaaaaa00000000aaaaaaaaaaaaaaaa7def51c91a0fbf034d26872ca84218e1",
"commitment": [
"036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296"
],
"extra": 1,
"ciphersuite": "FROST(P-256, SHA-256)"
}"#;
assert!(serde_json::from_str::<SecretShare>(invalid_json).is_err());
}
#[test]
fn check_key_package_serialization() {
let key_package = samples::key_package();
let json = serde_json::to_string_pretty(&key_package).unwrap();
println!("{}", json);
let decoded_key_package: KeyPackage = serde_json::from_str(&json).unwrap();
assert!(key_package == decoded_key_package);
let json = r#"{
"identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"secret_share": "aaaaaaaa00000000aaaaaaaaaaaaaaaa7def51c91a0fbf034d26872ca84218e1",
"public": "036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
"group_public": "036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
"ciphersuite": "FROST(P-256, SHA-256)"
}"#;
let decoded_key_package: KeyPackage = serde_json::from_str(json).unwrap();
assert!(key_package == decoded_key_package);
let invalid_json = "{}";
assert!(serde_json::from_str::<KeyPackage>(invalid_json).is_err());
// Invalid identifier
let invalid_json = r#"{
"identifier": "0000000000000000000000000000000000000000000000000000000000000000",
"secret_share": "aaaaaaaa00000000aaaaaaaaaaaaaaaa7def51c91a0fbf034d26872ca84218e1",
"public": "036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
"group_public": "036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
"ciphersuite": "FROST(P-256, SHA-256)"
}"#;
assert!(serde_json::from_str::<KeyPackage>(invalid_json).is_err());
// Invalid field
let invalid_json = r#"{
"identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"foo": "aaaaaaaa00000000aaaaaaaaaaaaaaaa7def51c91a0fbf034d26872ca84218e1",
"public": "036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
"group_public": "036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
"ciphersuite": "FROST(P-256, SHA-256)"
}"#;
assert!(serde_json::from_str::<KeyPackage>(invalid_json).is_err());
// Missing field
let invalid_json = r#"{
"identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"public": "036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
"group_public": "036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
"ciphersuite": "FROST(P-256, SHA-256)"
}"#;
assert!(serde_json::from_str::<KeyPackage>(invalid_json).is_err());
// Extra field
let invalid_json = r#"{
"identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"secret_share": "aaaaaaaa00000000aaaaaaaaaaaaaaaa7def51c91a0fbf034d26872ca84218e1",
"public": "036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
"group_public": "036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
"extra_field": 1,
"ciphersuite": "FROST(P-256, SHA-256)"
}"#;
assert!(serde_json::from_str::<KeyPackage>(invalid_json).is_err());
}
#[test]
fn check_public_key_package_serialization() {
let public_key_package = samples::public_key_package();
let json = serde_json::to_string_pretty(&public_key_package).unwrap();
println!("{}", json);
let decoded_public_key_package: PublicKeyPackage = serde_json::from_str(&json).unwrap();
assert!(public_key_package == decoded_public_key_package);
let json = r#"{
"signer_pubkeys": {
"000000000000000000000000000000000000000000000000000000000000002a": "036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296"
},
"group_public": "036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
"ciphersuite": "FROST(P-256, SHA-256)"
}"#;
let decoded_public_key_package: PublicKeyPackage = serde_json::from_str(json).unwrap();
assert!(public_key_package == decoded_public_key_package);
let invalid_json = "{}";
assert!(serde_json::from_str::<PublicKeyPackage>(invalid_json).is_err());
// Invalid identifier
let invalid_json = r#"{
"signer_pubkeys": {
"0000000000000000000000000000000000000000000000000000000000000000": "036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296"
},
"group_public": "036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
"ciphersuite": "FROST(P-256, SHA-256)"
}"#;
assert!(serde_json::from_str::<PublicKeyPackage>(invalid_json).is_err());
// Invalid field
let invalid_json = r#"{
"signer_pubkeys": {
"000000000000000000000000000000000000000000000000000000000000002a": "036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296"
},
"foo": "036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
"ciphersuite": "FROST(P-256, SHA-256)"
}"#;
assert!(serde_json::from_str::<PublicKeyPackage>(invalid_json).is_err());
// Missing field
let invalid_json = r#"{
"signer_pubkeys": {
"000000000000000000000000000000000000000000000000000000000000002a": "036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296"
},
"ciphersuite": "FROST(P-256, SHA-256)"
}"#;
assert!(serde_json::from_str::<PublicKeyPackage>(invalid_json).is_err());
// Extra field
let invalid_json = r#"{
"signer_pubkeys": {
"000000000000000000000000000000000000000000000000000000000000002a": "036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296"
},
"group_public": "036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
"extra": 1,
"ciphersuite": "FROST(P-256, SHA-256)"
}"#;
assert!(serde_json::from_str::<PublicKeyPackage>(invalid_json).is_err());
}
#[test]
fn check_round1_package_serialization() {
let round1_package = samples::round1_package();
let json = serde_json::to_string_pretty(&round1_package).unwrap();
println!("{}", json);
let decoded_round1_package: round1::Package = serde_json::from_str(&json).unwrap();
assert!(round1_package == decoded_round1_package);
let json = r#"{
"sender_identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"commitment": [
"036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296"
],
"proof_of_knowledge": "036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296aaaaaaaa00000000aaaaaaaaaaaaaaaa7def51c91a0fbf034d26872ca84218e1",
"ciphersuite": "FROST(P-256, SHA-256)"
}"#;
let decoded_round1_package: round1::Package = serde_json::from_str(json).unwrap();
assert!(round1_package == decoded_round1_package);
let invalid_json = "{}";
assert!(serde_json::from_str::<round1::Package>(invalid_json).is_err());
// Invalid identifier
let invalid_json = r#"{
"sender_identifier": "0000000000000000000000000000000000000000000000000000000000000000",
"commitment": [
"036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296"
],
"proof_of_knowledge": "036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296aaaaaaaa00000000aaaaaaaaaaaaaaaa7def51c91a0fbf034d26872ca84218e1",
"ciphersuite": "FROST(P-256, SHA-256)"
}"#;
assert!(serde_json::from_str::<round1::Package>(invalid_json).is_err());
// Invalid field
let invalid_json = r#"{
"sender_identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"commitment": [
"036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296"
],
"foo": "036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296aaaaaaaa00000000aaaaaaaaaaaaaaaa7def51c91a0fbf034d26872ca84218e1",
"ciphersuite": "FROST(P-256, SHA-256)"
}"#;
assert!(serde_json::from_str::<round1::Package>(invalid_json).is_err());
// Missing field
let invalid_json = r#"{
"sender_identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"commitment": [
"036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296"
],
"ciphersuite": "FROST(P-256, SHA-256)"
}"#;
assert!(serde_json::from_str::<round1::Package>(invalid_json).is_err());
// Extra field
let invalid_json = r#"{
"sender_identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"commitment": [
"036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296"
],
"proof_of_knowledge": "036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296aaaaaaaa00000000aaaaaaaaaaaaaaaa7def51c91a0fbf034d26872ca84218e1",
"extra": 1,
"ciphersuite": "FROST(P-256, SHA-256)"
}"#;
assert!(serde_json::from_str::<round1::Package>(invalid_json).is_err());
}
#[test]
fn check_round2_package_serialization() {
let round2_package = samples::round2_package();
let json = serde_json::to_string_pretty(&round2_package).unwrap();
println!("{}", json);
let decoded_round2_package: round2::Package = serde_json::from_str(&json).unwrap();
assert!(round2_package == decoded_round2_package);
let json = r#"{
"sender_identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"receiver_identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"secret_share": "aaaaaaaa00000000aaaaaaaaaaaaaaaa7def51c91a0fbf034d26872ca84218e1",
"ciphersuite": "FROST(P-256, SHA-256)"
}"#;
let decoded_round2_package: round2::Package = serde_json::from_str(json).unwrap();
assert!(round2_package == decoded_round2_package);
let invalid_json = "{}";
assert!(serde_json::from_str::<round2::Package>(invalid_json).is_err());
// Invalid identifier
let invalid_json = r#"{
"sender_identifier": "0000000000000000000000000000000000000000000000000000000000000000",
"receiver_identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"secret_share": "aaaaaaaa00000000aaaaaaaaaaaaaaaa7def51c91a0fbf034d26872ca84218e1",
"ciphersuite": "FROST(P-256, SHA-256)"
}"#;
assert!(serde_json::from_str::<round2::Package>(invalid_json).is_err());
// Invalid field
let invalid_json = r#"{
"sender_identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"foo": "000000000000000000000000000000000000000000000000000000000000002a",
"secret_share": "aaaaaaaa00000000aaaaaaaaaaaaaaaa7def51c91a0fbf034d26872ca84218e1",
"ciphersuite": "FROST(P-256, SHA-256)"
}"#;
assert!(serde_json::from_str::<round2::Package>(invalid_json).is_err());
// Missing field
let invalid_json = r#"{
"sender_identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"secret_share": "aaaaaaaa00000000aaaaaaaaaaaaaaaa7def51c91a0fbf034d26872ca84218e1",
"ciphersuite": "FROST(P-256, SHA-256)"
}"#;
assert!(serde_json::from_str::<round2::Package>(invalid_json).is_err());
// Extra field
let invalid_json = r#"{
"sender_identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"receiver_identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"secret_share": "aaaaaaaa00000000aaaaaaaaaaaaaaaa7def51c91a0fbf034d26872ca84218e1",
"extra": 1,
"ciphersuite": "FROST(P-256, SHA-256)"
}"#;
assert!(serde_json::from_str::<round2::Package>(invalid_json).is_err());
}

View File

@ -1 +1,5 @@
// Required since each integration test is compiled as a separated crate,
// and each one uses only part of the module.
#![allow(dead_code)]
pub mod samples;

View File

@ -0,0 +1,6 @@
{
"identifier": "2a00000000000000000000000000000000000000000000000000000000000000",
"element1": "e2f2ae0a6abc4e71a884a961c500515f58e30b6aa582dd8db6a65945e08d2d76",
"element2": "6a493210f7499cd17fecb510ae0cea23a110e8d5b901f8acadd3095c73a3b919",
"scalar1": "498d4e9311420c903913a56c94a694b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0a"
}

View File

@ -26,9 +26,9 @@ fn element2() -> Element<C> {
fn scalar1() -> Scalar<C> {
let one = <<C as Ciphersuite>::Group as Group>::Field::one();
let two = one + one;
// To return a fixed non-small number, get the inverse of 2
<<C as Ciphersuite>::Group as Group>::Field::invert(&two)
let three = one + one + one;
// To return a fixed non-small number, get the inverse of 3
<<C as Ciphersuite>::Group as Group>::Field::invert(&three)
.expect("nonzero elements have inverses")
}

View File

@ -1,42 +1,22 @@
#![cfg(feature = "serde")]
use std::collections::HashMap;
mod helpers;
use frost_core::{
frost::keys::{SigningShare, VerifyingShare},
Ciphersuite, Group,
};
use frost_ristretto255::{
keys::{
dkg::{round1, round2},
KeyPackage, PublicKeyPackage, SecretShare, VerifiableSecretSharingCommitment,
KeyPackage, PublicKeyPackage, SecretShare,
},
round1::{NonceCommitment, SigningCommitments},
round2::{SignatureResponse, SignatureShare},
Signature, SigningPackage, VerifyingKey,
round1::SigningCommitments,
round2::SignatureShare,
SigningPackage,
};
type C = frost_ristretto255::Ristretto255Sha512;
fn build_sample_signing_commitments() -> SigningCommitments {
let element1 = <C as Ciphersuite>::Group::generator();
let element2 = element1 + element1;
let serialized_element1 = <C as Ciphersuite>::Group::serialize(&element1);
let serialized_element2 = <C as Ciphersuite>::Group::serialize(&element2);
let hiding_nonce_commitment = NonceCommitment::from_bytes(serialized_element1).unwrap();
let binding_nonce_commitment = NonceCommitment::from_bytes(serialized_element2).unwrap();
let identifier = 42u16.try_into().unwrap();
SigningCommitments::new(
identifier,
hiding_nonce_commitment,
binding_nonce_commitment,
)
}
use helpers::samples;
#[test]
fn check_signing_commitments_serialization() {
let commitments = build_sample_signing_commitments();
let commitments = samples::signing_commitments();
let json = serde_json::to_string_pretty(&commitments).unwrap();
println!("{}", json);
@ -61,7 +41,7 @@ fn check_signing_commitments_serialization() {
"identifier": "2a00000000000000000000000000000000000000000000000000000000000000",
"hiding": "e2f2ae0a6abc4e71a884a961c500515f58e30b6aa582dd8db6a65945e08d2d76",
"binding": "6a493210f7499cd17fecb510ae0cea23a110e8d5b901f8acadd3095c73a3b919",
"ciphersuite": "FROST(Ed25519, SHA-512)"
"ciphersuite": "FROST(Wrong, SHA-512)"
}"#;
assert!(serde_json::from_str::<SigningCommitments>(invalid_json).is_err());
@ -100,10 +80,7 @@ fn check_signing_commitments_serialization() {
#[test]
fn check_signing_package_serialization() {
let commitments = build_sample_signing_commitments();
let message = "hello world".as_bytes();
let signing_package = SigningPackage::new(vec![commitments], message);
let signing_package = samples::signing_package();
let json = serde_json::to_string_pretty(&signing_package).unwrap();
println!("{}", json);
@ -193,15 +170,7 @@ fn check_signing_package_serialization() {
#[test]
fn check_signature_share_serialization() {
let identifier = 42u16.try_into().unwrap();
let serialized_scalar =
hex::decode("a0bdb9f6bf7b44c092dc285e66ee0484bce85c2d83babe03442510ab37603b0f")
.unwrap()
.try_into()
.unwrap();
let signature_response = SignatureResponse::from_bytes(serialized_scalar).unwrap();
let signature_share = SignatureShare::new(identifier, signature_response);
let signature_share = samples::signature_share();
let json = serde_json::to_string_pretty(&signature_share).unwrap();
println!("{}", json);
@ -211,7 +180,7 @@ fn check_signature_share_serialization() {
let json = r#"{
"identifier": "2a00000000000000000000000000000000000000000000000000000000000000",
"signature": "a0bdb9f6bf7b44c092dc285e66ee0484bce85c2d83babe03442510ab37603b0f",
"signature": "498d4e9311420c903913a56c94a694b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0a",
"ciphersuite": "FROST(ristretto255, SHA-512)"
}"#;
let decoded_commitments: SignatureShare = serde_json::from_str(json).unwrap();
@ -223,7 +192,7 @@ fn check_signature_share_serialization() {
// Invalid identifier
let invalid_json = r#"{
"identifier": "0000000000000000000000000000000000000000000000000000000000000000",
"signature": "e660b88149e1dd06d7cace3c5ee32a71b4b718e2719583630ba916579fe8320d",
"signature": "498d4e9311420c903913a56c94a694b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0a",
"ciphersuite": "FROST(ristretto255, SHA-512)"
}"#;
assert!(serde_json::from_str::<SignatureShare>(invalid_json).is_err());
@ -231,7 +200,7 @@ fn check_signature_share_serialization() {
// Invalid field
let invalid_json = r#"{
"identifier": "2a00000000000000000000000000000000000000000000000000000000000000",
"foo": "e660b88149e1dd06d7cace3c5ee32a71b4b718e2719583630ba916579fe8320d",
"foo": "498d4e9311420c903913a56c94a694b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0a",
"ciphersuite": "FROST(ristretto255, SHA-512)"
}"#;
assert!(serde_json::from_str::<SignatureShare>(invalid_json).is_err());
@ -246,7 +215,7 @@ fn check_signature_share_serialization() {
// Extra field
let invalid_json = r#"{
"identifier": "2a00000000000000000000000000000000000000000000000000000000000000",
"signature": "e660b88149e1dd06d7cace3c5ee32a71b4b718e2719583630ba916579fe8320d",
"signature": "498d4e9311420c903913a56c94a694b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0a",
"extra": 1,
"ciphersuite": "FROST(ristretto255, SHA-512)"
}"#;
@ -255,22 +224,7 @@ fn check_signature_share_serialization() {
#[test]
fn check_secret_share_serialization() {
let identifier = 42u16.try_into().unwrap();
let serialized_scalar =
hex::decode("a0bdb9f6bf7b44c092dc285e66ee0484bce85c2d83babe03442510ab37603b0f")
.unwrap()
.try_into()
.unwrap();
let serialized_element =
hex::decode("e2f2ae0a6abc4e71a884a961c500515f58e30b6aa582dd8db6a65945e08d2d76")
.unwrap()
.try_into()
.unwrap();
let signing_share = SigningShare::from_bytes(serialized_scalar).unwrap();
let vss_commitment =
VerifiableSecretSharingCommitment::deserialize(vec![serialized_element]).unwrap();
let secret_share = SecretShare::new(identifier, signing_share, vss_commitment);
let secret_share = samples::secret_share();
let json = serde_json::to_string_pretty(&secret_share).unwrap();
println!("{}", json);
@ -280,7 +234,7 @@ fn check_secret_share_serialization() {
let json = r#"{
"identifier": "2a00000000000000000000000000000000000000000000000000000000000000",
"value": "a0bdb9f6bf7b44c092dc285e66ee0484bce85c2d83babe03442510ab37603b0f",
"value": "498d4e9311420c903913a56c94a694b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0a",
"commitment": [
"e2f2ae0a6abc4e71a884a961c500515f58e30b6aa582dd8db6a65945e08d2d76"
],
@ -295,7 +249,7 @@ fn check_secret_share_serialization() {
// Invalid identifier
let invalid_json = r#"{
"identifier": "0000000000000000000000000000000000000000000000000000000000000000",
"value": "a0bdb9f6bf7b44c092dc285e66ee0484bce85c2d83babe03442510ab37603b0f",
"value": "498d4e9311420c903913a56c94a694b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0a",
"commitment": [
"e2f2ae0a6abc4e71a884a961c500515f58e30b6aa582dd8db6a65945e08d2d76"
],
@ -306,7 +260,7 @@ fn check_secret_share_serialization() {
// Invalid field
let invalid_json = r#"{
"identifier": "2a00000000000000000000000000000000000000000000000000000000000000",
"foo": "a0bdb9f6bf7b44c092dc285e66ee0484bce85c2d83babe03442510ab37603b0f",
"foo": "498d4e9311420c903913a56c94a694b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0a",
"commitment": [
"e2f2ae0a6abc4e71a884a961c500515f58e30b6aa582dd8db6a65945e08d2d76"
],
@ -327,7 +281,7 @@ fn check_secret_share_serialization() {
// Extra field
let invalid_json = r#"{
"identifier": "2a00000000000000000000000000000000000000000000000000000000000000",
"value": "a0bdb9f6bf7b44c092dc285e66ee0484bce85c2d83babe03442510ab37603b0f",
"value": "498d4e9311420c903913a56c94a694b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0a",
"commitment": [
"e2f2ae0a6abc4e71a884a961c500515f58e30b6aa582dd8db6a65945e08d2d76"
],
@ -339,22 +293,7 @@ fn check_secret_share_serialization() {
#[test]
fn check_key_package_serialization() {
let identifier = 42u16.try_into().unwrap();
let serialized_scalar =
hex::decode("a0bdb9f6bf7b44c092dc285e66ee0484bce85c2d83babe03442510ab37603b0f")
.unwrap()
.try_into()
.unwrap();
let serialized_element =
hex::decode("e2f2ae0a6abc4e71a884a961c500515f58e30b6aa582dd8db6a65945e08d2d76")
.unwrap()
.try_into()
.unwrap();
let signing_share = SigningShare::from_bytes(serialized_scalar).unwrap();
let verifying_share = VerifyingShare::from_bytes(serialized_element).unwrap();
let verifying_key = VerifyingKey::from_bytes(serialized_element).unwrap();
let key_package = KeyPackage::new(identifier, signing_share, verifying_share, verifying_key);
let key_package = samples::key_package();
let json = serde_json::to_string_pretty(&key_package).unwrap();
println!("{}", json);
@ -364,7 +303,7 @@ fn check_key_package_serialization() {
let json = r#"{
"identifier": "2a00000000000000000000000000000000000000000000000000000000000000",
"secret_share": "a0bdb9f6bf7b44c092dc285e66ee0484bce85c2d83babe03442510ab37603b0f",
"secret_share": "498d4e9311420c903913a56c94a694b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0a",
"public": "e2f2ae0a6abc4e71a884a961c500515f58e30b6aa582dd8db6a65945e08d2d76",
"group_public": "e2f2ae0a6abc4e71a884a961c500515f58e30b6aa582dd8db6a65945e08d2d76",
"ciphersuite": "FROST(ristretto255, SHA-512)"
@ -378,7 +317,7 @@ fn check_key_package_serialization() {
// Invalid identifier
let invalid_json = r#"{
"identifier": "0000000000000000000000000000000000000000000000000000000000000000",
"secret_share": "a0bdb9f6bf7b44c092dc285e66ee0484bce85c2d83babe03442510ab37603b0f",
"secret_share": "498d4e9311420c903913a56c94a694b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0a",
"public": "e2f2ae0a6abc4e71a884a961c500515f58e30b6aa582dd8db6a65945e08d2d76",
"group_public": "e2f2ae0a6abc4e71a884a961c500515f58e30b6aa582dd8db6a65945e08d2d76",
"ciphersuite": "FROST(ristretto255, SHA-512)"
@ -388,7 +327,7 @@ fn check_key_package_serialization() {
// Invalid field
let invalid_json = r#"{
"identifier": "2a00000000000000000000000000000000000000000000000000000000000000",
"foo": "a0bdb9f6bf7b44c092dc285e66ee0484bce85c2d83babe03442510ab37603b0f",
"foo": "498d4e9311420c903913a56c94a694b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0a",
"public": "e2f2ae0a6abc4e71a884a961c500515f58e30b6aa582dd8db6a65945e08d2d76",
"group_public": "e2f2ae0a6abc4e71a884a961c500515f58e30b6aa582dd8db6a65945e08d2d76",
"ciphersuite": "FROST(ristretto255, SHA-512)"
@ -407,7 +346,7 @@ fn check_key_package_serialization() {
// Extra field
let invalid_json = r#"{
"identifier": "2a00000000000000000000000000000000000000000000000000000000000000",
"secret_share": "a0bdb9f6bf7b44c092dc285e66ee0484bce85c2d83babe03442510ab37603b0f",
"secret_share": "498d4e9311420c903913a56c94a694b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0a",
"public": "e2f2ae0a6abc4e71a884a961c500515f58e30b6aa582dd8db6a65945e08d2d76",
"group_public": "e2f2ae0a6abc4e71a884a961c500515f58e30b6aa582dd8db6a65945e08d2d76",
"extra_field": 1,
@ -418,19 +357,7 @@ fn check_key_package_serialization() {
#[test]
fn check_public_key_package_serialization() {
let identifier = 42u16.try_into().unwrap();
let serialized_element =
hex::decode("e2f2ae0a6abc4e71a884a961c500515f58e30b6aa582dd8db6a65945e08d2d76")
.unwrap()
.try_into()
.unwrap();
let verifying_share = VerifyingShare::from_bytes(serialized_element).unwrap();
let verifying_key = VerifyingKey::from_bytes(serialized_element).unwrap();
let public_key_package = PublicKeyPackage::new(
HashMap::from([(identifier, verifying_share)]),
verifying_key,
);
let public_key_package = samples::public_key_package();
let json = serde_json::to_string_pretty(&public_key_package).unwrap();
println!("{}", json);
@ -494,29 +421,7 @@ fn check_public_key_package_serialization() {
#[test]
fn check_round1_package_serialization() {
let identifier = 42u16.try_into().unwrap();
let serialized_scalar: [u8; 32] =
hex::decode("a0bdb9f6bf7b44c092dc285e66ee0484bce85c2d83babe03442510ab37603b0f")
.unwrap()
.try_into()
.unwrap();
let serialized_element: [u8; 32] =
hex::decode("e2f2ae0a6abc4e71a884a961c500515f58e30b6aa582dd8db6a65945e08d2d76")
.unwrap()
.try_into()
.unwrap();
let serialized_signature: [u8; 64] = serialized_element
.iter()
.chain(serialized_scalar.iter())
.cloned()
.collect::<Vec<u8>>()
.try_into()
.unwrap();
let vss_commitment =
VerifiableSecretSharingCommitment::deserialize(vec![serialized_element]).unwrap();
let signature = Signature::from_bytes(serialized_signature).unwrap();
let round1_package = round1::Package::new(identifier, vss_commitment, signature);
let round1_package = samples::round1_package();
let json = serde_json::to_string_pretty(&round1_package).unwrap();
println!("{}", json);
@ -529,7 +434,7 @@ fn check_round1_package_serialization() {
"commitment": [
"e2f2ae0a6abc4e71a884a961c500515f58e30b6aa582dd8db6a65945e08d2d76"
],
"proof_of_knowledge": "e2f2ae0a6abc4e71a884a961c500515f58e30b6aa582dd8db6a65945e08d2d76a0bdb9f6bf7b44c092dc285e66ee0484bce85c2d83babe03442510ab37603b0f",
"proof_of_knowledge": "e2f2ae0a6abc4e71a884a961c500515f58e30b6aa582dd8db6a65945e08d2d76498d4e9311420c903913a56c94a694b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0a",
"ciphersuite": "FROST(ristretto255, SHA-512)"
}"#;
let decoded_round1_package: round1::Package = serde_json::from_str(json).unwrap();
@ -544,7 +449,7 @@ fn check_round1_package_serialization() {
"commitment": [
"e2f2ae0a6abc4e71a884a961c500515f58e30b6aa582dd8db6a65945e08d2d76"
],
"proof_of_knowledge": "e2f2ae0a6abc4e71a884a961c500515f58e30b6aa582dd8db6a65945e08d2d76a0bdb9f6bf7b44c092dc285e66ee0484bce85c2d83babe03442510ab37603b0f",
"proof_of_knowledge": "e2f2ae0a6abc4e71a884a961c500515f58e30b6aa582dd8db6a65945e08d2d76498d4e9311420c903913a56c94a694b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0a",
"ciphersuite": "FROST(ristretto255, SHA-512)"
}"#;
assert!(serde_json::from_str::<round1::Package>(invalid_json).is_err());
@ -555,7 +460,7 @@ fn check_round1_package_serialization() {
"commitment": [
"e2f2ae0a6abc4e71a884a961c500515f58e30b6aa582dd8db6a65945e08d2d76"
],
"foo": "e2f2ae0a6abc4e71a884a961c500515f58e30b6aa582dd8db6a65945e08d2d76a0bdb9f6bf7b44c092dc285e66ee0484bce85c2d83babe03442510ab37603b0f",
"foo": "e2f2ae0a6abc4e71a884a961c500515f58e30b6aa582dd8db6a65945e08d2d76498d4e9311420c903913a56c94a694b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0a",
"ciphersuite": "FROST(ristretto255, SHA-512)"
}"#;
assert!(serde_json::from_str::<round1::Package>(invalid_json).is_err());
@ -576,7 +481,7 @@ fn check_round1_package_serialization() {
"commitment": [
"e2f2ae0a6abc4e71a884a961c500515f58e30b6aa582dd8db6a65945e08d2d76"
],
"proof_of_knowledge": "e2f2ae0a6abc4e71a884a961c500515f58e30b6aa582dd8db6a65945e08d2d76a0bdb9f6bf7b44c092dc285e66ee0484bce85c2d83babe03442510ab37603b0f",
"proof_of_knowledge": "e2f2ae0a6abc4e71a884a961c500515f58e30b6aa582dd8db6a65945e08d2d76498d4e9311420c903913a56c94a694b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0a",
"extra": 1,
"ciphersuite": "FROST(ristretto255, SHA-512)"
}"#;
@ -585,15 +490,7 @@ fn check_round1_package_serialization() {
#[test]
fn check_round2_package_serialization() {
let identifier = 42u16.try_into().unwrap();
let serialized_scalar: [u8; 32] =
hex::decode("a0bdb9f6bf7b44c092dc285e66ee0484bce85c2d83babe03442510ab37603b0f")
.unwrap()
.try_into()
.unwrap();
let signing_share = SigningShare::from_bytes(serialized_scalar).unwrap();
let round2_package = round2::Package::new(identifier, identifier, signing_share);
let round2_package = samples::round2_package();
let json = serde_json::to_string_pretty(&round2_package).unwrap();
println!("{}", json);
@ -604,7 +501,7 @@ fn check_round2_package_serialization() {
let json = r#"{
"sender_identifier": "2a00000000000000000000000000000000000000000000000000000000000000",
"receiver_identifier": "2a00000000000000000000000000000000000000000000000000000000000000",
"secret_share": "a0bdb9f6bf7b44c092dc285e66ee0484bce85c2d83babe03442510ab37603b0f",
"secret_share": "498d4e9311420c903913a56c94a694b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0a",
"ciphersuite": "FROST(ristretto255, SHA-512)"
}"#;
let decoded_round2_package: round2::Package = serde_json::from_str(json).unwrap();
@ -617,7 +514,7 @@ fn check_round2_package_serialization() {
let invalid_json = r#"{
"sender_identifier": "0000000000000000000000000000000000000000000000000000000000000000",
"receiver_identifier": "2a00000000000000000000000000000000000000000000000000000000000000",
"secret_share": "a0bdb9f6bf7b44c092dc285e66ee0484bce85c2d83babe03442510ab37603b0f",
"secret_share": "498d4e9311420c903913a56c94a694b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0a",
"ciphersuite": "FROST(ristretto255, SHA-512)"
}"#;
assert!(serde_json::from_str::<round2::Package>(invalid_json).is_err());
@ -626,7 +523,7 @@ fn check_round2_package_serialization() {
let invalid_json = r#"{
"sender_identifier": "2a00000000000000000000000000000000000000000000000000000000000000",
"foo": "2a00000000000000000000000000000000000000000000000000000000000000",
"secret_share": "a0bdb9f6bf7b44c092dc285e66ee0484bce85c2d83babe03442510ab37603b0f",
"secret_share": "498d4e9311420c903913a56c94a694b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0a",
"ciphersuite": "FROST(ristretto255, SHA-512)"
}"#;
assert!(serde_json::from_str::<round2::Package>(invalid_json).is_err());
@ -634,7 +531,7 @@ fn check_round2_package_serialization() {
// Missing field
let invalid_json = r#"{
"sender_identifier": "2a00000000000000000000000000000000000000000000000000000000000000",
"secret_share": "a0bdb9f6bf7b44c092dc285e66ee0484bce85c2d83babe03442510ab37603b0f",
"secret_share": "498d4e9311420c903913a56c94a694b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0a",
"ciphersuite": "FROST(ristretto255, SHA-512)"
}"#;
assert!(serde_json::from_str::<round2::Package>(invalid_json).is_err());
@ -643,7 +540,7 @@ fn check_round2_package_serialization() {
let invalid_json = r#"{
"sender_identifier": "2a00000000000000000000000000000000000000000000000000000000000000",
"receiver_identifier": "2a00000000000000000000000000000000000000000000000000000000000000",
"secret_share": "a0bdb9f6bf7b44c092dc285e66ee0484bce85c2d83babe03442510ab37603b0f",
"secret_share": "498d4e9311420c903913a56c94a694b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0a",
"extra": 1,
"ciphersuite": "FROST(ristretto255, SHA-512)"
}"#;

View File

@ -24,7 +24,6 @@ features = ["nightly"]
frost-core = { path = "../frost-core", version = "0.4.0", features = ["test-impl"] }
k256 = { version = "0.13.0", features = ["arithmetic", "expose-field", "hash2curve"] }
rand_core = "0.6"
serde = { version = "1.0.160", features = ["derive"] }
sha2 = "0.10.2"
[dev-dependencies]
@ -43,6 +42,7 @@ serde_json = "1.0"
[features]
nightly = []
default = []
serde = ["frost-core/serde"]
[lib]
# Disables non-criterion benchmark which is not used; prevents errors

View File

@ -12,11 +12,13 @@ use k256::{
AffinePoint, ProjectivePoint, Scalar,
};
use rand_core::{CryptoRng, RngCore};
use serde::{Deserialize, Serialize};
use sha2::{Digest, Sha256};
use frost_core::frost;
#[cfg(feature = "serde")]
use frost_core::serde;
#[cfg(test)]
mod tests;
@ -168,7 +170,9 @@ fn hash_to_scalar(domain: &[u8], msg: &[u8]) -> Scalar {
const CONTEXT_STRING: &str = "FROST-secp256k1-SHA256-v11";
/// An implementation of the FROST(secp256k1, SHA-256) ciphersuite.
#[derive(Clone, Copy, PartialEq, Eq, Debug, Deserialize, Serialize)]
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(crate = "self::serde"))]
pub struct Secp256K1Sha256;
impl Ciphersuite for Secp256K1Sha256 {

View File

@ -0,0 +1,6 @@
{
"identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"element1": "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
"element2": "02c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5",
"scalar1": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9d1c9e899ca306ad27fe1945de0242b81"
}

View File

@ -26,9 +26,9 @@ fn element2() -> Element<C> {
fn scalar1() -> Scalar<C> {
let one = <<C as Ciphersuite>::Group as Group>::Field::one();
let two = one + one;
// To return a fixed non-small number, get the inverse of 2
<<C as Ciphersuite>::Group as Group>::Field::invert(&two)
let three = one + one + one;
// To return a fixed non-small number, get the inverse of 3
<<C as Ciphersuite>::Group as Group>::Field::invert(&three)
.expect("nonzero elements have inverses")
}

View File

@ -0,0 +1,548 @@
#![cfg(feature = "serde")]
mod helpers;
use frost_secp256k1::{
keys::{
dkg::{round1, round2},
KeyPackage, PublicKeyPackage, SecretShare,
},
round1::SigningCommitments,
round2::SignatureShare,
SigningPackage,
};
use helpers::samples;
#[test]
fn check_signing_commitments_serialization() {
let commitments = samples::signing_commitments();
let json = serde_json::to_string_pretty(&commitments).unwrap();
println!("{}", json);
let decoded_commitments: SigningCommitments = serde_json::from_str(&json).unwrap();
assert!(commitments == decoded_commitments);
let json = r#"{
"identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"hiding": "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
"binding": "02c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5",
"ciphersuite": "FROST(secp256k1, SHA-256)"
}"#;
let decoded_commitments: SigningCommitments = serde_json::from_str(json).unwrap();
assert!(commitments == decoded_commitments);
let invalid_json = "{}";
assert!(serde_json::from_str::<SigningCommitments>(invalid_json).is_err());
// Wrong ciphersuite
let invalid_json = r#"{
"identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"hiding": "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
"binding": "02c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5",
"ciphersuite": "FROST(Wrong, SHA-512)"
}"#;
assert!(serde_json::from_str::<SigningCommitments>(invalid_json).is_err());
// Invalid identifier
let invalid_json = r#"{
"identifier": "0000000000000000000000000000000000000000000000000000000000000000",
"hiding": "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
"binding": "02c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5"
}"#;
assert!(serde_json::from_str::<SigningCommitments>(invalid_json).is_err());
// Invalid field
let invalid_json = r#"{
"foo": "0000000000000000000000000000000000000000000000000000000000000000",
"hiding": "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
"binding": "02c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5"
}"#;
assert!(serde_json::from_str::<SigningCommitments>(invalid_json).is_err());
// Missing field
let invalid_json = r#"{
"foo": "0000000000000000000000000000000000000000000000000000000000000000",
"binding": "02c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5"
}"#;
assert!(serde_json::from_str::<SigningCommitments>(invalid_json).is_err());
// Extra field
let invalid_json = r#"{
"identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"hiding": "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
"binding": "02c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5",
"extra": 1
}"#;
assert!(serde_json::from_str::<SigningCommitments>(invalid_json).is_err());
}
#[test]
fn check_signing_package_serialization() {
let signing_package = samples::signing_package();
let json = serde_json::to_string_pretty(&signing_package).unwrap();
println!("{}", json);
let decoded_signing_package: SigningPackage = serde_json::from_str(&json).unwrap();
assert!(signing_package == decoded_signing_package);
let invalid_json = "{}";
assert!(serde_json::from_str::<SigningPackage>(invalid_json).is_err());
let json = r#"{
"signing_commitments": {
"000000000000000000000000000000000000000000000000000000000000002a": {
"identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"hiding": "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
"binding": "02c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5",
"ciphersuite": "FROST(secp256k1, SHA-256)"
}
},
"message": "68656c6c6f20776f726c64",
"ciphersuite": "FROST(secp256k1, SHA-256)"
}"#;
let decoded_signing_package: SigningPackage = serde_json::from_str(json).unwrap();
assert!(signing_package == decoded_signing_package);
// Invalid identifier
let invalid_json = r#"{
"signing_commitments": {
"0000000000000000000000000000000000000000000000000000000000000000": {
"identifier": "0000000000000000000000000000000000000000000000000000000000000000",
"hiding": "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
"binding": "02c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5",
"ciphersuite": "FROST(secp256k1, SHA-256)"
}
},
"message": "68656c6c6f20776f726c64",
"ciphersuite": "FROST(secp256k1, SHA-256)"
}"#;
assert!(serde_json::from_str::<SigningPackage>(invalid_json).is_err());
// Invalid field
let invalid_json = r#"{
"signing_commitments": {
"000000000000000000000000000000000000000000000000000000000000002a": {
"identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"foo": "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
"binding": "02c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5",
"ciphersuite": "FROST(secp256k1, SHA-256)"
}
},
"message": "68656c6c6f20776f726c64",
"ciphersuite": "FROST(secp256k1, SHA-256)"
}"#;
assert!(serde_json::from_str::<SigningPackage>(invalid_json).is_err());
// Missing field
let invalid_json = r#"{
"signing_commitments": {
"000000000000000000000000000000000000000000000000000000000000002a": {
"identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"binding": "02c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5",
"ciphersuite": "FROST(secp256k1, SHA-256)"
}
},
"message": "68656c6c6f20776f726c64",
"ciphersuite": "FROST(secp256k1, SHA-256)"
}"#;
assert!(serde_json::from_str::<SigningPackage>(invalid_json).is_err());
// Extra field
let invalid_json = r#"{
"signing_commitments": {
"000000000000000000000000000000000000000000000000000000000000002a": {
"identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"hiding": "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
"binding": "02c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5",
"ciphersuite": "FROST(secp256k1, SHA-256)"
}
},
"message": "68656c6c6f20776f726c64",
"extra": 1,
"ciphersuite": "FROST(secp256k1, SHA-256)"
}
"#;
assert!(serde_json::from_str::<SigningPackage>(invalid_json).is_err());
}
#[test]
fn check_signature_share_serialization() {
let signature_share = samples::signature_share();
let json = serde_json::to_string_pretty(&signature_share).unwrap();
println!("{}", json);
let decoded_signature_share: SignatureShare = serde_json::from_str(&json).unwrap();
assert!(signature_share == decoded_signature_share);
let json = r#"{
"identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"signature": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9d1c9e899ca306ad27fe1945de0242b81",
"ciphersuite": "FROST(secp256k1, SHA-256)"
}"#;
let decoded_commitments: SignatureShare = serde_json::from_str(json).unwrap();
assert!(signature_share == decoded_commitments);
let invalid_json = "{}";
assert!(serde_json::from_str::<SignatureShare>(invalid_json).is_err());
// Invalid identifier
let invalid_json = r#"{
"identifier": "0000000000000000000000000000000000000000000000000000000000000000",
"signature": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9d1c9e899ca306ad27fe1945de0242b81",
"ciphersuite": "FROST(secp256k1, SHA-256)"
}"#;
assert!(serde_json::from_str::<SignatureShare>(invalid_json).is_err());
// Invalid field
let invalid_json = r#"{
"identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"foo": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9d1c9e899ca306ad27fe1945de0242b81",
"ciphersuite": "FROST(secp256k1, SHA-256)"
}"#;
assert!(serde_json::from_str::<SignatureShare>(invalid_json).is_err());
// Missing field
let invalid_json = r#"{
"identifier": "000000000000000000000000000000000000000000000000000000000000002a",,
"ciphersuite": "FROST(secp256k1, SHA-256)"
}"#;
assert!(serde_json::from_str::<SignatureShare>(invalid_json).is_err());
// Extra field
let invalid_json = r#"{
"identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"signature": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9d1c9e899ca306ad27fe1945de0242b81",
"extra": 1,
"ciphersuite": "FROST(secp256k1, SHA-256)"
}"#;
assert!(serde_json::from_str::<SignatureShare>(invalid_json).is_err());
}
#[test]
fn check_secret_share_serialization() {
let secret_share = samples::secret_share();
let json = serde_json::to_string_pretty(&secret_share).unwrap();
println!("{}", json);
let decoded_secret_share: SecretShare = serde_json::from_str(&json).unwrap();
assert!(secret_share == decoded_secret_share);
let json = r#"{
"identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"value": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9d1c9e899ca306ad27fe1945de0242b81",
"commitment": [
"0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"
],
"ciphersuite": "FROST(secp256k1, SHA-256)"
}"#;
let decoded_secret_share: SecretShare = serde_json::from_str(json).unwrap();
assert!(secret_share == decoded_secret_share);
let invalid_json = "{}";
assert!(serde_json::from_str::<SecretShare>(invalid_json).is_err());
// Invalid identifier
let invalid_json = r#"{
"identifier": "0000000000000000000000000000000000000000000000000000000000000000",
"value": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9d1c9e899ca306ad27fe1945de0242b81",
"commitment": [
"0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"
],
"ciphersuite": "FROST(secp256k1, SHA-256)"
}"#;
assert!(serde_json::from_str::<SecretShare>(invalid_json).is_err());
// Invalid field
let invalid_json = r#"{
"identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"foo": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9d1c9e899ca306ad27fe1945de0242b81",
"commitment": [
"0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"
],
"ciphersuite": "FROST(secp256k1, SHA-256)"
}"#;
assert!(serde_json::from_str::<SecretShare>(invalid_json).is_err());
// Missing field
let invalid_json = r#"{
"identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"commitment": [
"0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"
],
"ciphersuite": "FROST(secp256k1, SHA-256)"
}"#;
assert!(serde_json::from_str::<SecretShare>(invalid_json).is_err());
// Extra field
let invalid_json = r#"{
"identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"value": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9d1c9e899ca306ad27fe1945de0242b81",
"commitment": [
"0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"
],
"extra": 1,
"ciphersuite": "FROST(secp256k1, SHA-256)"
}"#;
assert!(serde_json::from_str::<SecretShare>(invalid_json).is_err());
}
#[test]
fn check_key_package_serialization() {
let key_package = samples::key_package();
let json = serde_json::to_string_pretty(&key_package).unwrap();
println!("{}", json);
let decoded_key_package: KeyPackage = serde_json::from_str(&json).unwrap();
assert!(key_package == decoded_key_package);
let json = r#"{
"identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"secret_share": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9d1c9e899ca306ad27fe1945de0242b81",
"public": "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
"group_public": "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
"ciphersuite": "FROST(secp256k1, SHA-256)"
}"#;
let decoded_key_package: KeyPackage = serde_json::from_str(json).unwrap();
assert!(key_package == decoded_key_package);
let invalid_json = "{}";
assert!(serde_json::from_str::<KeyPackage>(invalid_json).is_err());
// Invalid identifier
let invalid_json = r#"{
"identifier": "0000000000000000000000000000000000000000000000000000000000000000",
"secret_share": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9d1c9e899ca306ad27fe1945de0242b81",
"public": "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
"group_public": "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
"ciphersuite": "FROST(secp256k1, SHA-256)"
}"#;
assert!(serde_json::from_str::<KeyPackage>(invalid_json).is_err());
// Invalid field
let invalid_json = r#"{
"identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"foo": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9d1c9e899ca306ad27fe1945de0242b81",
"public": "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
"group_public": "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
"ciphersuite": "FROST(secp256k1, SHA-256)"
}"#;
assert!(serde_json::from_str::<KeyPackage>(invalid_json).is_err());
// Missing field
let invalid_json = r#"{
"identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"public": "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
"group_public": "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
"ciphersuite": "FROST(secp256k1, SHA-256)"
}"#;
assert!(serde_json::from_str::<KeyPackage>(invalid_json).is_err());
// Extra field
let invalid_json = r#"{
"identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"secret_share": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9d1c9e899ca306ad27fe1945de0242b81",
"public": "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
"group_public": "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
"extra_field": 1,
"ciphersuite": "FROST(secp256k1, SHA-256)"
}"#;
assert!(serde_json::from_str::<KeyPackage>(invalid_json).is_err());
}
#[test]
fn check_public_key_package_serialization() {
let public_key_package = samples::public_key_package();
let json = serde_json::to_string_pretty(&public_key_package).unwrap();
println!("{}", json);
let decoded_public_key_package: PublicKeyPackage = serde_json::from_str(&json).unwrap();
assert!(public_key_package == decoded_public_key_package);
let json = r#"{
"signer_pubkeys": {
"000000000000000000000000000000000000000000000000000000000000002a": "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"
},
"group_public": "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
"ciphersuite": "FROST(secp256k1, SHA-256)"
}"#;
let decoded_public_key_package: PublicKeyPackage = serde_json::from_str(json).unwrap();
assert!(public_key_package == decoded_public_key_package);
let invalid_json = "{}";
assert!(serde_json::from_str::<PublicKeyPackage>(invalid_json).is_err());
// Invalid identifier
let invalid_json = r#"{
"signer_pubkeys": {
"0000000000000000000000000000000000000000000000000000000000000000": "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"
},
"group_public": "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
"ciphersuite": "FROST(secp256k1, SHA-256)"
}"#;
assert!(serde_json::from_str::<PublicKeyPackage>(invalid_json).is_err());
// Invalid field
let invalid_json = r#"{
"signer_pubkeys": {
"000000000000000000000000000000000000000000000000000000000000002a": "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"
},
"foo": "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
"ciphersuite": "FROST(secp256k1, SHA-256)"
}"#;
assert!(serde_json::from_str::<PublicKeyPackage>(invalid_json).is_err());
// Missing field
let invalid_json = r#"{
"signer_pubkeys": {
"000000000000000000000000000000000000000000000000000000000000002a": "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"
},
"ciphersuite": "FROST(secp256k1, SHA-256)"
}"#;
assert!(serde_json::from_str::<PublicKeyPackage>(invalid_json).is_err());
// Extra field
let invalid_json = r#"{
"signer_pubkeys": {
"000000000000000000000000000000000000000000000000000000000000002a": "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"
},
"group_public": "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
"extra": 1,
"ciphersuite": "FROST(secp256k1, SHA-256)"
}"#;
assert!(serde_json::from_str::<PublicKeyPackage>(invalid_json).is_err());
}
#[test]
fn check_round1_package_serialization() {
let round1_package = samples::round1_package();
let json = serde_json::to_string_pretty(&round1_package).unwrap();
println!("{}", json);
let decoded_round1_package: round1::Package = serde_json::from_str(&json).unwrap();
assert!(round1_package == decoded_round1_package);
let json = r#"{
"sender_identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"commitment": [
"0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"
],
"proof_of_knowledge": "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9d1c9e899ca306ad27fe1945de0242b81",
"ciphersuite": "FROST(secp256k1, SHA-256)"
}"#;
let decoded_round1_package: round1::Package = serde_json::from_str(json).unwrap();
assert!(round1_package == decoded_round1_package);
let invalid_json = "{}";
assert!(serde_json::from_str::<round1::Package>(invalid_json).is_err());
// Invalid identifier
let invalid_json = r#"{
"sender_identifier": "0000000000000000000000000000000000000000000000000000000000000000",
"commitment": [
"0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"
],
"proof_of_knowledge": "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9d1c9e899ca306ad27fe1945de0242b81",
"ciphersuite": "FROST(secp256k1, SHA-256)"
}"#;
assert!(serde_json::from_str::<round1::Package>(invalid_json).is_err());
// Invalid field
let invalid_json = r#"{
"sender_identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"commitment": [
"0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"
],
"foo": "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9d1c9e899ca306ad27fe1945de0242b81",
"ciphersuite": "FROST(secp256k1, SHA-256)"
}"#;
assert!(serde_json::from_str::<round1::Package>(invalid_json).is_err());
// Missing field
let invalid_json = r#"{
"sender_identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"commitment": [
"0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"
],
"ciphersuite": "FROST(secp256k1, SHA-256)"
}"#;
assert!(serde_json::from_str::<round1::Package>(invalid_json).is_err());
// Extra field
let invalid_json = r#"{
"sender_identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"commitment": [
"0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"
],
"proof_of_knowledge": "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9d1c9e899ca306ad27fe1945de0242b81",
"extra": 1,
"ciphersuite": "FROST(secp256k1, SHA-256)"
}"#;
assert!(serde_json::from_str::<round1::Package>(invalid_json).is_err());
}
#[test]
fn check_round2_package_serialization() {
let round2_package = samples::round2_package();
let json = serde_json::to_string_pretty(&round2_package).unwrap();
println!("{}", json);
let decoded_round2_package: round2::Package = serde_json::from_str(&json).unwrap();
assert!(round2_package == decoded_round2_package);
let json = r#"{
"sender_identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"receiver_identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"secret_share": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9d1c9e899ca306ad27fe1945de0242b81",
"ciphersuite": "FROST(secp256k1, SHA-256)"
}"#;
let decoded_round2_package: round2::Package = serde_json::from_str(json).unwrap();
assert!(round2_package == decoded_round2_package);
let invalid_json = "{}";
assert!(serde_json::from_str::<round2::Package>(invalid_json).is_err());
// Invalid identifier
let invalid_json = r#"{
"sender_identifier": "0000000000000000000000000000000000000000000000000000000000000000",
"receiver_identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"secret_share": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9d1c9e899ca306ad27fe1945de0242b81",
"ciphersuite": "FROST(secp256k1, SHA-256)"
}"#;
assert!(serde_json::from_str::<round2::Package>(invalid_json).is_err());
// Invalid field
let invalid_json = r#"{
"sender_identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"foo": "000000000000000000000000000000000000000000000000000000000000002a",
"secret_share": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9d1c9e899ca306ad27fe1945de0242b81",
"ciphersuite": "FROST(secp256k1, SHA-256)"
}"#;
assert!(serde_json::from_str::<round2::Package>(invalid_json).is_err());
// Missing field
let invalid_json = r#"{
"sender_identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"secret_share": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9d1c9e899ca306ad27fe1945de0242b81",
"ciphersuite": "FROST(secp256k1, SHA-256)"
}"#;
assert!(serde_json::from_str::<round2::Package>(invalid_json).is_err());
// Extra field
let invalid_json = r#"{
"sender_identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"receiver_identifier": "000000000000000000000000000000000000000000000000000000000000002a",
"secret_share": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9d1c9e899ca306ad27fe1945de0242b81",
"extra": 1,
"ciphersuite": "FROST(secp256k1, SHA-256)"
}"#;
assert!(serde_json::from_str::<round2::Package>(invalid_json).is_err());
}

View File

@ -8,6 +8,7 @@ publish = false
[dependencies]
regex = "1.6.0"
serde_json = "1.0"
[[bin]]
name = "gencode"

View File

@ -206,7 +206,7 @@ fn main() -> ExitCode {
// ristretto255 as the canonical base.
let original_folder = "frost-ristretto255";
let original_strings = &[
let mut original_strings: Vec<String> = vec![
"Ristretto255Sha512",
"Ristretto group",
"Ristretto",
@ -214,9 +214,24 @@ fn main() -> ExitCode {
"ristretto255_sha512",
"ristretto255",
"<R>",
];
]
.iter()
.map(|x| x.to_string())
.collect();
let docs = read_docs("frost-ristretto255/src/lib.rs", original_strings);
// Some test use "sample" values. To make these tests work for another ciphersuites,
// these values must be replaced. To make it cleaner, the strings are
// specified in JSON files, and appended here to original_strings.
let samples: serde_json::Value = serde_json::from_str(
&std::fs::read_to_string(format!("{original_folder}/tests/helpers/samples.json")).unwrap(),
)
.unwrap();
for key in &["identifier", "element1", "element2", "scalar1"] {
original_strings.push(samples[key].as_str().unwrap().to_owned());
}
let original_strings: Vec<&str> = original_strings.iter().map(|s| s.as_ref()).collect();
let docs = read_docs("frost-ristretto255/src/lib.rs", &original_strings);
// To add a new ciphersuite, just copy a tuple and replace the required strings.
for (folder, replacement_strings) in [
@ -271,10 +286,30 @@ fn main() -> ExitCode {
],
),
] {
// Some test use "sample" values. To make these tests work for another ciphersuites,
// these values must be replaced. To make it cleaner, the strings are
// specified in JSON files, and appended here to replacement_strings.
let mut replacement_strings: Vec<String> =
replacement_strings.iter().map(|x| x.to_string()).collect();
let samples: serde_json::Value = serde_json::from_str(
&std::fs::read_to_string(format!("{folder}/tests/helpers/samples.json")).unwrap(),
)
.unwrap();
for key in &["identifier", "element1", "element2", "scalar1"] {
replacement_strings.push(samples[key].as_str().unwrap().to_owned());
}
let replacement_strings: Vec<&str> =
replacement_strings.iter().map(|s| s.as_ref()).collect();
let lib_filename = format!("{folder}/src/lib.rs");
// Copy the documentation of public items in Rust code, replacing ciphersuite-specific strings inside
// them in the process.
replaced |= write_docs(&docs, &lib_filename, original_strings, replacement_strings);
replaced |= write_docs(
&docs,
&lib_filename,
&original_strings,
&replacement_strings,
);
// Generate files based on a template with simple search & replace.
for filename in [
@ -287,13 +322,14 @@ fn main() -> ExitCode {
"src/tests/proptests.rs",
"src/tests/vss_commitment.rs",
"tests/recreation_tests.rs",
"tests/serde_tests.rs",
"tests/helpers/samples.rs",
] {
replaced |= copy_and_replace(
format!("{original_folder}/{filename}").as_str(),
format!("{folder}/{filename}").as_str(),
original_strings,
replacement_strings,
&original_strings,
&replacement_strings,
filename.ends_with(".rs"),
);
}