148 lines
4.5 KiB
Rust
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,
|
|
)
|
|
}
|