frost/frost-ristretto255/src/tests/vectors.rs

148 lines
4.5 KiB
Rust

use std::{collections::HashMap, str::FromStr};
use curve25519_dalek::scalar::Scalar;
use hex::{self, FromHex};
use lazy_static::lazy_static;
use serde_json::Value;
use frost_core::{
frost::{keys::*, round1::*, round2::*, *},
VerifyingKey,
};
use crate::Ristretto255Sha512;
lazy_static! {
pub static ref RISTRETTO255_SHA512: Value =
serde_json::from_str(include_str!("vectors.json").trim())
.expect("Test vector is valid JSON");
}
#[allow(clippy::type_complexity)]
#[allow(dead_code)]
pub(crate) fn parse_test_vectors() -> (
VerifyingKey<Ristretto255Sha512>,
HashMap<u16, KeyPackage<Ristretto255Sha512>>,
&'static str,
Vec<u8>,
HashMap<u16, SigningNonces<Ristretto255Sha512>>,
HashMap<u16, SigningCommitments<Ristretto255Sha512>>,
Vec<u8>,
Rho<Ristretto255Sha512>,
HashMap<u16, SignatureShare<Ristretto255Sha512>>,
Vec<u8>, // Signature<Ristretto255Sha512>,
) {
type R = Ristretto255Sha512;
let inputs = &RISTRETTO255_SHA512["inputs"];
let message = inputs["message"].as_str().unwrap();
let message_bytes = hex::decode(message).unwrap();
let mut key_packages: HashMap<u16, KeyPackage<R>> = HashMap::new();
let possible_signers = RISTRETTO255_SHA512["inputs"]["signers"]
.as_object()
.unwrap()
.iter();
let group_public =
VerifyingKey::<R>::from_hex(inputs["group_public_key"].as_str().unwrap()).unwrap();
for (i, secret_share) in possible_signers {
let secret = Secret::<R>::from_hex(secret_share["signer_share"].as_str().unwrap()).unwrap();
let signer_public = secret.into();
let key_package = KeyPackage::<R> {
index: u16::from_str(i).unwrap(),
secret_share: secret,
public: signer_public,
group_public,
};
key_packages.insert(*key_package.index(), key_package);
}
// Round one outputs
let round_one_outputs = &RISTRETTO255_SHA512["round_one_outputs"];
let group_binding_factor_input = Vec::<u8>::from_hex(
round_one_outputs["group_binding_factor_input"]
.as_str()
.unwrap(),
)
.unwrap();
let group_binding_factor =
Rho::<R>::from_hex(round_one_outputs["group_binding_factor"].as_str().unwrap()).unwrap();
let mut signer_nonces: HashMap<u16, SigningNonces<R>> = HashMap::new();
let mut signer_commitments: HashMap<u16, SigningCommitments<R>> = HashMap::new();
for (i, signer) in round_one_outputs["signers"].as_object().unwrap().iter() {
let index = u16::from_str(i).unwrap();
let signing_nonces = SigningNonces::<R> {
hiding: Nonce::<R>::from_hex(signer["hiding_nonce"].as_str().unwrap()).unwrap(),
binding: Nonce::<R>::from_hex(signer["binding_nonce"].as_str().unwrap()).unwrap(),
};
signer_nonces.insert(index, signing_nonces);
let signing_commitments = SigningCommitments::<R> {
index,
hiding: NonceCommitment::from_hex(signer["hiding_nonce_commitment"].as_str().unwrap())
.unwrap(),
binding: NonceCommitment::from_hex(
signer["binding_nonce_commitment"].as_str().unwrap(),
)
.unwrap(),
};
signer_commitments.insert(index, signing_commitments);
}
// Round two outputs
let round_two_outputs = &RISTRETTO255_SHA512["round_two_outputs"];
let mut signature_shares: HashMap<u16, SignatureShare<R>> = HashMap::new();
for (i, signer) in round_two_outputs["signers"].as_object().unwrap().iter() {
let signature_share = SignatureShare::<R> {
index: u16::from_str(i).unwrap(),
signature: SignatureResponse {
z_share: Scalar::from_canonical_bytes(
hex::decode(signer["sig_share"].as_str().unwrap())
.unwrap()
.try_into()
.unwrap(),
)
.unwrap(),
},
};
signature_shares.insert(u16::from_str(i).unwrap(), signature_share);
}
// Final output
let final_output = &RISTRETTO255_SHA512["final_output"];
let signature_bytes = FromHex::from_hex(final_output["sig"].as_str().unwrap()).unwrap();
(
group_public,
key_packages,
message,
message_bytes,
signer_nonces,
signer_commitments,
group_binding_factor_input,
group_binding_factor,
signature_shares,
signature_bytes,
)
}