mirror of
https://github.com/serai-dex/serai.git
synced 2024-11-16 17:07:35 +00:00
Update to FROST v11
Ensures random functions never return zero. This, combined with a check commitments aren't 0, causes no serialized elements to be 0. Also directly reads their vectors.
This commit is contained in:
parent
b334c96906
commit
a0a54eb0de
19 changed files with 491 additions and 257 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -4578,8 +4578,10 @@ dependencies = [
|
|||
"multiexp",
|
||||
"p256",
|
||||
"rand_core 0.6.4",
|
||||
"serde_json",
|
||||
"sha2 0.10.6",
|
||||
"sha3 0.10.5",
|
||||
"subtle",
|
||||
"thiserror",
|
||||
"zeroize",
|
||||
]
|
||||
|
|
|
@ -18,6 +18,7 @@ thiserror = "1"
|
|||
rand_core = "0.6"
|
||||
|
||||
zeroize = { version = "1.5", features = ["zeroize_derive"] }
|
||||
subtle = "2"
|
||||
|
||||
hex = "0.4"
|
||||
|
||||
|
@ -44,6 +45,7 @@ dleq = { path = "../dleq", version = "0.1", features = ["serialize"] }
|
|||
[dev-dependencies]
|
||||
sha2 = "0.10"
|
||||
dalek-ff-group = { path = "../dalek-ff-group", version = "^0.1.2" }
|
||||
serde_json = "1"
|
||||
|
||||
[features]
|
||||
dalek = ["sha2", "dalek-ff-group"]
|
||||
|
|
|
@ -74,7 +74,7 @@ dalek_curve!(
|
|||
IetfRistrettoHram,
|
||||
RistrettoPoint,
|
||||
b"ristretto",
|
||||
b"FROST-RISTRETTO255-SHA512-v10",
|
||||
b"FROST-RISTRETTO255-SHA512-v11",
|
||||
b"chal",
|
||||
);
|
||||
|
||||
|
@ -85,6 +85,6 @@ dalek_curve!(
|
|||
IetfEd25519Hram,
|
||||
EdwardsPoint,
|
||||
b"edwards25519",
|
||||
b"FROST-ED25519-SHA512-v10",
|
||||
b"FROST-ED25519-SHA512-v11",
|
||||
b"",
|
||||
);
|
||||
|
|
|
@ -7,7 +7,7 @@ use minimal_ed448::{scalar::Scalar, point::Point};
|
|||
|
||||
use crate::{curve::Curve, algorithm::Hram};
|
||||
|
||||
const CONTEXT: &[u8] = b"FROST-ED448-SHAKE256-v10";
|
||||
const CONTEXT: &[u8] = b"FROST-ED448-SHAKE256-v11";
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug, Zeroize)]
|
||||
pub struct Ed448;
|
||||
|
@ -53,8 +53,8 @@ impl Ietf8032Ed448Hram {
|
|||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct NonIetfEd448Hram;
|
||||
impl Hram<Ed448> for NonIetfEd448Hram {
|
||||
pub struct IetfEd448Hram;
|
||||
impl Hram<Ed448> for IetfEd448Hram {
|
||||
#[allow(non_snake_case)]
|
||||
fn hram(R: &Point, A: &Point, m: &[u8]) -> Scalar {
|
||||
Ietf8032Ed448Hram::hram(&[], R, A, m)
|
||||
|
|
|
@ -92,7 +92,7 @@ macro_rules! kp_curve {
|
|||
}
|
||||
|
||||
#[cfg(feature = "p256")]
|
||||
kp_curve!("p256", p256, P256, IetfP256Hram, b"P-256", b"FROST-P256-SHA256-v10");
|
||||
kp_curve!("p256", p256, P256, IetfP256Hram, b"P-256", b"FROST-P256-SHA256-v11");
|
||||
|
||||
#[cfg(feature = "secp256k1")]
|
||||
kp_curve!(
|
||||
|
@ -101,5 +101,5 @@ kp_curve!(
|
|||
Secp256k1,
|
||||
IetfSecp256k1Hram,
|
||||
b"secp256k1",
|
||||
b"FROST-secp256k1-SHA256-v10"
|
||||
b"FROST-secp256k1-SHA256-v11"
|
||||
);
|
||||
|
|
|
@ -6,8 +6,9 @@ use thiserror::Error;
|
|||
use rand_core::{RngCore, CryptoRng};
|
||||
|
||||
use zeroize::Zeroize;
|
||||
use subtle::ConstantTimeEq;
|
||||
|
||||
use ff::{PrimeField, PrimeFieldBits};
|
||||
use ff::{Field, PrimeField, PrimeFieldBits};
|
||||
use group::{Group, GroupOps, GroupEncoding, prime::PrimeGroup};
|
||||
|
||||
#[cfg(any(test, feature = "dalek"))]
|
||||
|
@ -27,7 +28,7 @@ pub use kp256::{P256, IetfP256Hram};
|
|||
#[cfg(feature = "ed448")]
|
||||
mod ed448;
|
||||
#[cfg(feature = "ed448")]
|
||||
pub use ed448::{Ed448, Ietf8032Ed448Hram, NonIetfEd448Hram};
|
||||
pub use ed448::{Ed448, Ietf8032Ed448Hram, IetfEd448Hram};
|
||||
|
||||
/// Set of errors for curve-related operations, namely encoding and decoding.
|
||||
#[derive(Clone, Error, Debug)]
|
||||
|
@ -49,7 +50,7 @@ pub trait Curve: Clone + Copy + PartialEq + Eq + Debug + Zeroize {
|
|||
// This is available via G::Scalar yet `C::G::Scalar` is ambiguous, forcing horrific accesses
|
||||
type F: PrimeField + PrimeFieldBits + Zeroize;
|
||||
/// Group element type.
|
||||
type G: Group<Scalar = Self::F> + GroupOps + PrimeGroup + Zeroize;
|
||||
type G: Group<Scalar = Self::F> + GroupOps + PrimeGroup + Zeroize + ConstantTimeEq;
|
||||
|
||||
/// ID for this curve.
|
||||
const ID: &'static [u8];
|
||||
|
@ -81,6 +82,16 @@ pub trait Curve: Clone + Copy + PartialEq + Eq + Debug + Zeroize {
|
|||
Self::hash_to_F(b"rho", binding)
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
fn random_F<R: RngCore + CryptoRng>(rng: &mut R) -> Self::F {
|
||||
let mut res;
|
||||
while {
|
||||
res = Self::F::random(&mut *rng);
|
||||
res.ct_eq(&Self::F::zero()).into()
|
||||
} {}
|
||||
res
|
||||
}
|
||||
|
||||
/// Securely generate a random nonce. H3 from the IETF draft.
|
||||
fn random_nonce<R: RngCore + CryptoRng>(mut secret: Self::F, rng: &mut R) -> Self::F {
|
||||
let mut seed = vec![0; 32];
|
||||
|
@ -89,12 +100,18 @@ pub trait Curve: Clone + Copy + PartialEq + Eq + Debug + Zeroize {
|
|||
let mut repr = secret.to_repr();
|
||||
secret.zeroize();
|
||||
|
||||
seed.extend(repr.as_ref());
|
||||
let mut res;
|
||||
while {
|
||||
seed.extend(repr.as_ref());
|
||||
res = Self::hash_to_F(b"nonce", &seed);
|
||||
res.ct_eq(&Self::F::zero()).into()
|
||||
} {
|
||||
rng.fill_bytes(&mut seed);
|
||||
}
|
||||
|
||||
for i in repr.as_mut() {
|
||||
i.zeroize();
|
||||
}
|
||||
|
||||
let res = Self::hash_to_F(b"nonce", &seed);
|
||||
seed.zeroize();
|
||||
res
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ fn generate_key_r1<R: RngCore + CryptoRng, C: Curve>(
|
|||
|
||||
for i in 0 .. t {
|
||||
// Step 1: Generate t random values to form a polynomial with
|
||||
coefficients.push(C::F::random(&mut *rng));
|
||||
coefficients.push(C::random_F(&mut *rng));
|
||||
// Step 3: Generate public commitments
|
||||
commitments.push(C::generator() * coefficients[i]);
|
||||
// Serialize them for publication
|
||||
|
@ -56,7 +56,7 @@ fn generate_key_r1<R: RngCore + CryptoRng, C: Curve>(
|
|||
}
|
||||
|
||||
// Step 2: Provide a proof of knowledge
|
||||
let mut r = C::F::random(rng);
|
||||
let mut r = C::random_F(rng);
|
||||
serialized.extend(
|
||||
schnorr::sign::<C>(
|
||||
coefficients[0],
|
||||
|
|
|
@ -7,6 +7,7 @@ use std::{
|
|||
use rand_core::{RngCore, CryptoRng};
|
||||
|
||||
use zeroize::{Zeroize, ZeroizeOnDrop};
|
||||
use subtle::ConstantTimeEq;
|
||||
|
||||
use transcript::Transcript;
|
||||
|
||||
|
@ -97,8 +98,6 @@ impl<C: Curve> Drop for PreprocessPackage<C> {
|
|||
}
|
||||
impl<C: Curve> ZeroizeOnDrop for PreprocessPackage<C> {}
|
||||
|
||||
// This library unifies the preprocessing step with signing due to security concerns and to provide
|
||||
// a simpler UX
|
||||
fn preprocess<R: RngCore + CryptoRng, C: Curve, A: Algorithm<C>>(
|
||||
rng: &mut R,
|
||||
params: &mut Params<C, A>,
|
||||
|
@ -202,14 +201,20 @@ fn sign_with_share<Re: Read, C: Curve, A: Algorithm<C>>(
|
|||
// consistency. While this is suboptimal, it maintains IETF compliance, and Algorithm is
|
||||
// documented accordingly
|
||||
let transcript = |t: &mut A::Transcript, commitments: [C::G; 2]| {
|
||||
if commitments[0].ct_eq(&C::G::identity()).into() ||
|
||||
commitments[1].ct_eq(&C::G::identity()).into()
|
||||
{
|
||||
Err(FrostError::InvalidCommitment(*l))?;
|
||||
}
|
||||
t.append_message(b"commitment_D", commitments[0].to_bytes().as_ref());
|
||||
t.append_message(b"commitment_E", commitments[1].to_bytes().as_ref());
|
||||
Ok(())
|
||||
};
|
||||
|
||||
if *l == params.keys.params().i {
|
||||
for nonce_commitments in &our_preprocess.commitments {
|
||||
for commitments in nonce_commitments {
|
||||
transcript(params.algorithm.transcript(), *commitments);
|
||||
transcript(params.algorithm.transcript(), *commitments).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -227,7 +232,7 @@ fn sign_with_share<Re: Read, C: Curve, A: Algorithm<C>>(
|
|||
commitments.push(Vec::with_capacity(nonce_generators.len()));
|
||||
for _ in 0 .. nonce_generators.len() {
|
||||
commitments[n].push(read_D_E::<_, C>(&mut cursor, *l)?);
|
||||
transcript(params.algorithm.transcript(), commitments[n][commitments[n].len() - 1]);
|
||||
transcript(params.algorithm.transcript(), commitments[n][commitments[n].len() - 1])?;
|
||||
}
|
||||
|
||||
if nonce_generators.len() >= 2 {
|
||||
|
|
|
@ -2,7 +2,7 @@ use std::io::Cursor;
|
|||
|
||||
use rand_core::{RngCore, CryptoRng};
|
||||
|
||||
use group::{ff::Field, Group};
|
||||
use group::Group;
|
||||
|
||||
use crate::{Curve, FrostCore, tests::core_gen};
|
||||
|
||||
|
@ -27,7 +27,7 @@ pub fn test_multiexp<R: RngCore + CryptoRng, C: Curve>(rng: &mut R) {
|
|||
let mut sum = C::G::identity();
|
||||
for _ in 0 .. 10 {
|
||||
for _ in 0 .. 100 {
|
||||
pairs.push((C::F::random(&mut *rng), C::generator() * C::F::random(&mut *rng)));
|
||||
pairs.push((C::random_F(&mut *rng), C::generator() * C::random_F(&mut *rng)));
|
||||
sum += pairs[pairs.len() - 1].1 * pairs[pairs.len() - 1].0;
|
||||
}
|
||||
assert_eq!(multiexp::multiexp(&pairs), sum);
|
||||
|
|
|
@ -10,35 +10,12 @@ use crate::{
|
|||
fn ristretto_vectors() {
|
||||
test_with_vectors::<_, curve::Ristretto, curve::IetfRistrettoHram>(
|
||||
&mut OsRng,
|
||||
Vectors {
|
||||
threshold: 2,
|
||||
shares: &[
|
||||
"5c3430d391552f6e60ecdc093ff9f6f4488756aa6cebdbad75a768010b8f830e",
|
||||
"b06fc5eac20b4f6e1b271d9df2343d843e1e1fb03c4cbb673f2872d459ce6f01",
|
||||
"f17e505f0e2581c6acfe54d3846a622834b5e7b50cad9a2109a97ba7a80d5c04",
|
||||
],
|
||||
group_secret: "1b25a55e463cfd15cf14a5d3acc3d15053f08da49c8afcf3ab265f2ebc4f970b",
|
||||
group_key: "e2a62f39eede11269e3bd5a7d97554f5ca384f9f6d3dd9c3c0d05083c7254f57",
|
||||
|
||||
msg: "74657374",
|
||||
included: &[1, 3],
|
||||
nonces: &[
|
||||
[
|
||||
"de3e8f526dcb51a1b9b48cc284aeca27c385aa3ba1a92a0c8440d51e1a1d2f00",
|
||||
"fa8dca5ec7a05d5a7b782be847ba3dde1509de1dbcf0569fc980cff795db5404",
|
||||
],
|
||||
[
|
||||
"e07061a9ab6735de9a75b0c64f086c5b999894611d0cdc03f85c4e87c8aae602",
|
||||
"38b17578e8e6ad4077071ce6b0bf9cb85ac35fee7868dcb6d9bfa97f0e153e0e",
|
||||
],
|
||||
],
|
||||
sig_shares: &[
|
||||
"a5f046916a6a111672111e47f9825586e1188da8a0f3b7c61f2b6b432c636e07",
|
||||
"4c175c7e43bd197980c2021774036eb288f54179f079fbf21b7d2f9f52846401",
|
||||
],
|
||||
sig: "94b11def3f919503c3544452ad2a59f198f64cc323bd758bb1c65b42032a7473".to_owned() +
|
||||
"f107a30fae272b8ff2d3205e6d86c3386a0ecf21916db3b93ba89ae27ee7d208",
|
||||
},
|
||||
Vectors::from(
|
||||
serde_json::from_str::<serde_json::Value>(include_str!(
|
||||
"vectors/frost-ristretto255-sha512.json"
|
||||
))
|
||||
.unwrap(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -47,34 +24,9 @@ fn ristretto_vectors() {
|
|||
fn ed25519_vectors() {
|
||||
test_with_vectors::<_, curve::Ed25519, curve::IetfEd25519Hram>(
|
||||
&mut OsRng,
|
||||
Vectors {
|
||||
threshold: 2,
|
||||
shares: &[
|
||||
"929dcc590407aae7d388761cddb0c0db6f5627aea8e217f4a033f2ec83d93509",
|
||||
"a91e66e012e4364ac9aaa405fcafd370402d9859f7b6685c07eed76bf409e80d",
|
||||
"d3cb090a075eb154e82fdb4b3cb507f110040905468bb9c46da8bdea643a9a02",
|
||||
],
|
||||
group_secret: "7b1c33d3f5291d85de664833beb1ad469f7fb6025a0ec78b3a790c6e13a98304",
|
||||
group_key: "15d21ccd7ee42959562fc8aa63224c8851fb3ec85a3faf66040d380fb9738673",
|
||||
|
||||
msg: "74657374",
|
||||
included: &[1, 3],
|
||||
nonces: &[
|
||||
[
|
||||
"4e64f59e90a3b9cdce346fae68eb0e459532c8ca1ad59a566c3ee2c67bf0100b",
|
||||
"470c660895c6db164ee6564120eec71023fa5297f09c663bb8171646c5632d00",
|
||||
],
|
||||
[
|
||||
"6fc516495dbb364b807cdd0c2e5e3f58aa4914a53fed33cc340033979bb07304",
|
||||
"0837e770a88147d41ff39138ca23b35d6cf303a4f148294755ede4b7e760d701",
|
||||
],
|
||||
],
|
||||
sig_shares: &[
|
||||
"3f2eb12735e5b39da97e884a6caadf6bb83f1efcec709d6f66333d0d67ebe707",
|
||||
"79e572b8632fbb928519dd2eff793de8784a56d582ae48c807d39b0dc5b93509",
|
||||
],
|
||||
sig: "e31e69a4e10d5ca2307c4a0d12cd86e3fceee550e55cb5b3f47c7ad6dbb38884".to_owned() +
|
||||
"cb3f2e837eb15cd858fb6dd68c2a3e3f318a74d16f1fe6376e06d91a2ca51d01",
|
||||
},
|
||||
Vectors::from(
|
||||
serde_json::from_str::<serde_json::Value>(include_str!("vectors/frost-ed25519-sha512.json"))
|
||||
.unwrap(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ use std::io::Cursor;
|
|||
use rand_core::OsRng;
|
||||
|
||||
use crate::{
|
||||
curve::{Curve, Ed448, Ietf8032Ed448Hram, NonIetfEd448Hram},
|
||||
curve::{Curve, Ed448, Ietf8032Ed448Hram, IetfEd448Hram},
|
||||
schnorr::{SchnorrSignature, verify},
|
||||
tests::vectors::{Vectors, test_with_vectors},
|
||||
};
|
||||
|
@ -48,88 +48,12 @@ fn ed448_8032_vector() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn ed448_non_ietf() {
|
||||
test_with_vectors::<_, Ed448, NonIetfEd448Hram>(
|
||||
fn ed448_vectors() {
|
||||
test_with_vectors::<_, Ed448, IetfEd448Hram>(
|
||||
&mut OsRng,
|
||||
Vectors {
|
||||
threshold: 2,
|
||||
shares: &[
|
||||
concat!(
|
||||
"4a2b2f5858a932ad3d3b18bd16e76ced3070d72fd79ae4402df201f5",
|
||||
"25e754716a1bc1b87a502297f2a99d89ea054e0018eb55d39562fd01",
|
||||
"00"
|
||||
),
|
||||
concat!(
|
||||
"2503d56c4f516444a45b080182b8a2ebbe4d9b2ab509f25308c88c0e",
|
||||
"a7ccdc44e2ef4fc4f63403a11b116372438a1e287265cadeff1fcb07",
|
||||
"00"
|
||||
),
|
||||
concat!(
|
||||
"00db7a8146f995db0a7cf844ed89d8e94c2b5f259378ff66e39d1728",
|
||||
"28b264185ac4decf7219e4aa4478285b9c0eef4fccdf3eea69dd980d",
|
||||
"00"
|
||||
),
|
||||
],
|
||||
group_secret: concat!(
|
||||
"6298e1eef3c379392caaed061ed8a31033c9e9e3420726f23b404158",
|
||||
"a401cd9df24632adfe6b418dc942d8a091817dd8bd70e1c72ba52f3c",
|
||||
"00"
|
||||
),
|
||||
group_key: concat!(
|
||||
"3832f82fda00ff5365b0376df705675b63d2a93c24c6e81d40801ba2",
|
||||
"65632be10f443f95968fadb70d10786827f30dc001c8d0f9b7c1d1b0",
|
||||
"00"
|
||||
),
|
||||
|
||||
msg: "74657374",
|
||||
included: &[1, 3],
|
||||
nonces: &[
|
||||
[
|
||||
concat!(
|
||||
"06f2e15b05d29a50f0686a890259f4dcf66147a80809ed9e50926f5f",
|
||||
"173fe23a0627561efa003724dc270effc47a30bc4d80aba30725401d",
|
||||
"00"
|
||||
),
|
||||
concat!(
|
||||
"e0482e611c34f191d1c13a09bc8bbf4bda68db4de32aa7908849b02b",
|
||||
"a912cfba46c805e2d8560ab9437e343e1dde6b481a2bae527e111b2c",
|
||||
"00"
|
||||
),
|
||||
],
|
||||
[
|
||||
concat!(
|
||||
"295c56447c070157e6bc3c83ed2afca194569e07d0ad27d28a40dec2",
|
||||
"c4107c07d507db20da1be62ea6976b8e53ab5d26e225c663f2e71511",
|
||||
"00"
|
||||
),
|
||||
concat!(
|
||||
"b97303a6c5ab12b6ad310834361033a19d99dfdf93109da721da35c3",
|
||||
"abbc5f29df33b3402692bef9f005bb8ea00af5ba20cc688360fd8831",
|
||||
"00"
|
||||
),
|
||||
],
|
||||
],
|
||||
sig_shares: &[
|
||||
concat!(
|
||||
"5b65641e27007ec71509c6af5cf8527eb01fee5b2b07d8beecf6646e",
|
||||
"b7e7e27d85119b74f895b56ba7561834a1b0c42639b122160a0b6208",
|
||||
"00"
|
||||
),
|
||||
concat!(
|
||||
"821b7ac04d7c01d970b0b3ba4ae8f737a5bac934aed1600b1cad7601",
|
||||
"1c240629bce6a4671a1b6f572cec708ec161a72a5ca04e50eabdfc25",
|
||||
"00"
|
||||
),
|
||||
],
|
||||
sig: concat!(
|
||||
"c7ad7ad9fcfeef9d1492361ba641400bd3a3c8335a83cdffbdd8867d",
|
||||
"2849bb4419dcc3e594baa731081a1a00cd3dea9219a81ecba4646e95",
|
||||
"00",
|
||||
"dd80dede747c7fa086b9796aa7e04ab655dab790d9d838ca08a4db6f",
|
||||
"d30be9a641f83fdc12b124c3d34289c262126c5195517166f4c85e2e",
|
||||
"00"
|
||||
)
|
||||
.to_string(),
|
||||
},
|
||||
Vectors::from(
|
||||
serde_json::from_str::<serde_json::Value>(include_str!("vectors/frost-ed448-shake256.json"))
|
||||
.unwrap(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -13,35 +13,12 @@ use crate::curve::{P256, IetfP256Hram};
|
|||
fn secp256k1_vectors() {
|
||||
test_with_vectors::<_, Secp256k1, IetfSecp256k1Hram>(
|
||||
&mut OsRng,
|
||||
Vectors {
|
||||
threshold: 2,
|
||||
shares: &[
|
||||
"08f89ffe80ac94dcb920c26f3f46140bfc7f95b493f8310f5fc1ea2b01f4254c",
|
||||
"04f0feac2edcedc6ce1253b7fab8c86b856a797f44d83d82a385554e6e401984",
|
||||
"00e95d59dd0d46b0e303e500b62b7ccb0e555d49f5b849f5e748c071da8c0dbc",
|
||||
],
|
||||
group_secret: "0d004150d27c3bf2a42f312683d35fac7394b1e9e318249c1bfe7f0795a83114",
|
||||
group_key: "02f37c34b66ced1fb51c34a90bdae006901f10625cc06c4f64663b0eae87d87b4f",
|
||||
|
||||
msg: "74657374",
|
||||
included: &[1, 3],
|
||||
nonces: &[
|
||||
[
|
||||
"36d5c4185c40b02b5e4673e2531a10e6ff9883840a68ec08dbeb896467e21355",
|
||||
"7b3f573ca0a28f9f94522be4748df0ed04de8a83085aff4be7b01aa53fb6ac1b",
|
||||
],
|
||||
[
|
||||
"ba4f8b8e587b2c9fc61a6156885f0bc67654b5e068c9e7749f75c09a98f17c13",
|
||||
"316de06639051ac7869e5ac4458eda1fef90ce93fa3c490556c4192e4fa550d0",
|
||||
],
|
||||
],
|
||||
sig_shares: &[
|
||||
"f9ee00d5ac0c746b751dde99f71d86f8f0300a81bd0336ca6649ef597239e13f",
|
||||
"61048ca334ac6a6cb59d6b3ea2b25b7098e204adc09e2f88b024531b081d1d6f",
|
||||
],
|
||||
sig: "023cf76388f92d403aa937af2e3cb3e7a2350e40400c16a282e330af2c60eeb85a".to_owned() +
|
||||
"5af28d78e0b8ded82abb49d899cfe26ace633248ce58c617569be3e7aa20bd6d",
|
||||
},
|
||||
Vectors::from(
|
||||
serde_json::from_str::<serde_json::Value>(include_str!(
|
||||
"vectors/frost-secp256k1-sha256.json"
|
||||
))
|
||||
.unwrap(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -50,34 +27,9 @@ fn secp256k1_vectors() {
|
|||
fn p256_vectors() {
|
||||
test_with_vectors::<_, P256, IetfP256Hram>(
|
||||
&mut OsRng,
|
||||
Vectors {
|
||||
threshold: 2,
|
||||
shares: &[
|
||||
"0c9c1a0fe806c184add50bbdcac913dda73e482daf95dcb9f35dbb0d8a9f7731",
|
||||
"8d8e787bef0ff6c2f494ca45f4dad198c6bee01212d6c84067159c52e1863ad5",
|
||||
"0e80d6e8f6192c003b5488ce1eec8f5429587d48cf001541e713b2d53c09d928",
|
||||
],
|
||||
group_secret: "8ba9bba2e0fd8c4767154d35a0b7562244a4aaf6f36c8fb8735fa48b301bd8de",
|
||||
group_key: "023a309ad94e9fe8a7ba45dfc58f38bf091959d3c99cfbd02b4dc00585ec45ab70",
|
||||
|
||||
msg: "74657374",
|
||||
included: &[1, 3],
|
||||
nonces: &[
|
||||
[
|
||||
"9aa66350b0f72b27ce4668323b4280cd49709177ed8373977c22a75546c9995d",
|
||||
"bd8b05d7fd0ff5a5ed65b1f105478f7718a981741fa8fa9b55ac6d3c8fc59a05",
|
||||
],
|
||||
[
|
||||
"4c1aec8e84c496b80af98415fada2e6a4b1f902d4bc6c9682699b8aeffd97419",
|
||||
"eeaf5ef7af01e55050fb8acafc9c9306ef1cc13214677ba33e7bc51e8677e892",
|
||||
],
|
||||
],
|
||||
sig_shares: &[
|
||||
"ec5b8ab47d55903698492a07bb322ab6e7d3cf32581dcedf43c4fa18b46f3e10",
|
||||
"c97da3580560e88725a8e393d46fee18ecd2e00148e5e303d4a510fae9c11da5",
|
||||
],
|
||||
sig: "036b3eba585ff5d40df29893fb6f60572803aef97800cfaaaa5cf0f0f19d8237f7".to_owned() +
|
||||
"b5d92e0d82b678bcbdf20d9b8fa218d017bfb485f9ec135e24b04050a1cd3664",
|
||||
},
|
||||
Vectors::from(
|
||||
serde_json::from_str::<serde_json::Value>(include_str!("vectors/frost-p256-sha256.json"))
|
||||
.unwrap(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
{
|
||||
"config": {
|
||||
"MAX_PARTICIPANTS": "3",
|
||||
"NUM_PARTICIPANTS": "2",
|
||||
"MIN_PARTICIPANTS": "2",
|
||||
"name": "FROST(Ed25519, SHA-512)",
|
||||
"group": "ed25519",
|
||||
"hash": "SHA-512"
|
||||
},
|
||||
"inputs": {
|
||||
"group_secret_key": "7b1c33d3f5291d85de664833beb1ad469f7fb6025a0ec78b3a790c6e13a98304",
|
||||
"group_public_key": "15d21ccd7ee42959562fc8aa63224c8851fb3ec85a3faf66040d380fb9738673",
|
||||
"message": "74657374",
|
||||
"share_polynomial_coefficients": [
|
||||
"178199860edd8c62f5212ee91eff1295d0d670ab4ed4506866bae57e7030b204"
|
||||
],
|
||||
"participants": {
|
||||
"1": {
|
||||
"participant_share": "929dcc590407aae7d388761cddb0c0db6f5627aea8e217f4a033f2ec83d93509"
|
||||
},
|
||||
"2": {
|
||||
"participant_share": "a91e66e012e4364ac9aaa405fcafd370402d9859f7b6685c07eed76bf409e80d"
|
||||
},
|
||||
"3": {
|
||||
"participant_share": "d3cb090a075eb154e82fdb4b3cb507f110040905468bb9c46da8bdea643a9a02"
|
||||
}
|
||||
}
|
||||
},
|
||||
"round_one_outputs": {
|
||||
"participant_list": "1,3",
|
||||
"participants": {
|
||||
"1": {
|
||||
"hiding_nonce_randomness": "9d06a6381c7a4493929761a73692776772b274236fb5cfcc7d1b48ac3a9c249f",
|
||||
"binding_nonce_randomness": "db184d7bc01a3417fe1f2eb3cf5479bb027145e6369a5f879f32d334ab256b23",
|
||||
"hiding_nonce": "70652da3e8d7533a0e4b9e9104f01b48c396b5b553717784ed8d05c6a36b9609",
|
||||
"binding_nonce": "4f9e1ad260b5c0e4fe0e0719c6324f89fecd053758f77c957f56967e634a710e",
|
||||
"hiding_nonce_commitment": "44105304351ceddc58e15ddea35b2cb48e60ced54ceb22c3b0e5d42d098aa1d8",
|
||||
"binding_nonce_commitment": "b8274b18a12f2cef74ae42f876cec1e31daab5cb162f95a56cd2487409c9d1dd",
|
||||
"binding_factor_input": "c5b95020cba31a9035835f074f718d0c3af02a318d6b4723bbd1c088f4889dd7b9ff8e79f9a67a9d27605144259a7af18b7cca2539ffa5c4f1366a98645da8f4e077d604fff64f20e2377a37e5a10ce152194d62fe856ef4cd935d4f1cb0088c2083a2722ad3f5a84d778e257da0df2a7cadb004b1f5528352af778b94ee1c2a0100000000000000000000000000000000000000000000000000000000000000",
|
||||
"binding_factor": "2d5630c36d33258b1208c4205fa759b762d09bfa06b29cf792cf98758c0b3305"
|
||||
},
|
||||
"3": {
|
||||
"hiding_nonce_randomness": "31ca9b07936d6b342a43d97f23b7bec5a5f5a09575a075393868dd8df5c05a54",
|
||||
"binding_nonce_randomness": "c1db96a85d8b593e14fdb869c0955625478afa6a987ad217e7f2261dcab26819",
|
||||
"hiding_nonce": "233adcb0ec0eddba5f1cc5268f3f4e6fc1dd97fb1e4a1754e6ddc92ed834ca0b",
|
||||
"binding_nonce": "b59fc8a32fe02ec0a44c4671f3d1f82ea3924b7c7c0179398fc9137e82757803",
|
||||
"hiding_nonce_commitment": "d31bd81ce216b1c83912803a574a0285796275cb8b14f6dc92c8b09a6951f0a2",
|
||||
"binding_nonce_commitment": "e1c863cfd08df775b6747ef2456e9bf9a03cc281a479a95261dc39137fcf0967",
|
||||
"binding_factor_input": "c5b95020cba31a9035835f074f718d0c3af02a318d6b4723bbd1c088f4889dd7b9ff8e79f9a67a9d27605144259a7af18b7cca2539ffa5c4f1366a98645da8f4e077d604fff64f20e2377a37e5a10ce152194d62fe856ef4cd935d4f1cb0088c2083a2722ad3f5a84d778e257da0df2a7cadb004b1f5528352af778b94ee1c2a0300000000000000000000000000000000000000000000000000000000000000",
|
||||
"binding_factor": "1137be5cdf3d18e44367acee8485e9a66c3164077af80619b6291e3943bbef04"
|
||||
}
|
||||
}
|
||||
},
|
||||
"round_two_outputs": {
|
||||
"participant_list": "1,3",
|
||||
"participants": {
|
||||
"1": {
|
||||
"sig_share": "c4b26af1e91fbc8440a0dad253e72620da624553c5b625fd51e6ea179fc09f05"
|
||||
},
|
||||
"3": {
|
||||
"sig_share": "9369640967d0cb98f4dedfde58a845e0e18e0a7164396358439060ed282b4e08"
|
||||
}
|
||||
}
|
||||
},
|
||||
"final_output": {
|
||||
"sig": "ae11c539fdc709b78fef5ee1f5a2250297e3e1b62a86a86c26d93c389934ba0e571ccffa50f0871d357fbab1ac8f6c00bcf14fc429f0885595764b05c8ebed0d"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
{
|
||||
"config": {
|
||||
"MAX_PARTICIPANTS": "3",
|
||||
"NUM_PARTICIPANTS": "2",
|
||||
"MIN_PARTICIPANTS": "2",
|
||||
"name": "FROST(Ed448, SHAKE256)",
|
||||
"group": "ed448",
|
||||
"hash": "SHAKE256"
|
||||
},
|
||||
"inputs": {
|
||||
"group_secret_key": "6298e1eef3c379392caaed061ed8a31033c9e9e3420726f23b404158a401cd9df24632adfe6b418dc942d8a091817dd8bd70e1c72ba52f3c00",
|
||||
"group_public_key": "3832f82fda00ff5365b0376df705675b63d2a93c24c6e81d40801ba265632be10f443f95968fadb70d10786827f30dc001c8d0f9b7c1d1b000",
|
||||
"message": "74657374",
|
||||
"share_polynomial_coefficients": [
|
||||
"dbd7a514f7a731976620f0436bd135fe8dddc3fadd6e0d13dbd58a1981e587d377d48e0b7ce4e0092967c5e85884d0275a7a740b6abdcd0500"
|
||||
],
|
||||
"participants": {
|
||||
"1": {
|
||||
"participant_share": "4a2b2f5858a932ad3d3b18bd16e76ced3070d72fd79ae4402df201f525e754716a1bc1b87a502297f2a99d89ea054e0018eb55d39562fd0100"
|
||||
},
|
||||
"2": {
|
||||
"participant_share": "2503d56c4f516444a45b080182b8a2ebbe4d9b2ab509f25308c88c0ea7ccdc44e2ef4fc4f63403a11b116372438a1e287265cadeff1fcb0700"
|
||||
},
|
||||
"3": {
|
||||
"participant_share": "00db7a8146f995db0a7cf844ed89d8e94c2b5f259378ff66e39d172828b264185ac4decf7219e4aa4478285b9c0eef4fccdf3eea69dd980d00"
|
||||
}
|
||||
}
|
||||
},
|
||||
"round_one_outputs": {
|
||||
"participant_list": "1,3",
|
||||
"participants": {
|
||||
"1": {
|
||||
"hiding_nonce_randomness": "89bf16040081ff2990336b200613787937ebe1f024b8cdff90eb6f1c741d91c1",
|
||||
"binding_nonce_randomness": "cd646348bb98fd2a4b2f27fb7d6da18201c161847352576b4bf125190e965483",
|
||||
"hiding_nonce": "67a6f023e77361707c6e894c625e809e80f33fdb310810053ae29e28e7011f3193b9020e73c183a98cc3a519160ed759376dd92c9483162200",
|
||||
"binding_nonce": "4812e8d7c8b7a50ced80b507902d074ef8647bc1146979683da8d0fecd93fa3c8230cade2fb4344600aa04bd4b7a21d046c5b63ee865b12a00",
|
||||
"hiding_nonce_commitment": "649c6a53b109897d962d033f23d01fd4e1053dddf3746d2ddce9bd66aea38ccfc3df061df03ca399eb806312ab3037c0c31523142956ada780",
|
||||
"binding_nonce_commitment": "0064cc729a8e2fcf417e43788ecec37b10e9e1dcb3ae90854efbfaad00a0ef3cdd52e18d56f073c8ff0947cb71ff0bb17c3d45d096409ddb00",
|
||||
"binding_factor_input": "106dadce87ca867018702d69a02effd165e1ac1a511c957cff1897ceff2e34ca212fe798d84f0bde6054bf0fa77fd4cd4bc4853d6dc8dbd19d340923f0ebbbb35172df4ab865a45d55af31fa0e6606ea97cf8513022b2b133d0f9f6b8d3be184221fc4592bf12bd7fb4127bb67e51a6dc9e5f1ed5243362fb46a6da552418ca967d43d9bc811a21917a3018de58f11c25f6b9ad8bec3699e06b87dd3ab67a7326c30878c7c55ec1a45802af65da193ce99634158539e38c232a627895c5f14e2e20d487382ccc9c99cd0a0df266a292f283bb9b6854e344ecc32d5e1852fdde5fde77798010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"binding_factor": "3412ac894a91a6bc0e3e7c790f3e8ef5d1288e54de780aba384cbb3081b602dd188010e5b0c9ac2b5dca0aae54cfd0f5c391cece8092131d00"
|
||||
},
|
||||
"3": {
|
||||
"hiding_nonce_randomness": "3718dabb4fd3d7dd9adad4878c6de8b33c8841cfe7cc95a85592952a2c9c554d",
|
||||
"binding_nonce_randomness": "3becbc90798211a0f52543dd1f24869a143fdf743409581af4db30f045773d64",
|
||||
"hiding_nonce": "4f2666770317d14ec9f7fd6690c075c34b4cde7f6d9bceda9e9433ec8c0f2dc983ff1622c3a54916ce7c161381d263fad62539cddab2101600",
|
||||
"binding_nonce": "88f66df8bb66389932721a40de4aa5754f632cac114abc1052688104d19f3b1a010880ebcd0c4c0f8cf567d887e5b0c3c0dc78821166550f00",
|
||||
"hiding_nonce_commitment": "8dcf049167e28d5f53fa7ebbbd136abcaf2be9f2c02448c8979002f92577b22027640def7ddd5b98f9540c2280f36a92d4747bbade0b0c4280",
|
||||
"binding_nonce_commitment": "12e837b89a2c085481fcf0ca640a17a24b6fc96b032d40e4301c78e7232a9f49ffdcad2c21acbc992e79dfc3c6c07cb94e4680b3dcc9935580",
|
||||
"binding_factor_input": "106dadce87ca867018702d69a02effd165e1ac1a511c957cff1897ceff2e34ca212fe798d84f0bde6054bf0fa77fd4cd4bc4853d6dc8dbd19d340923f0ebbbb35172df4ab865a45d55af31fa0e6606ea97cf8513022b2b133d0f9f6b8d3be184221fc4592bf12bd7fb4127bb67e51a6dc9e5f1ed5243362fb46a6da552418ca967d43d9bc811a21917a3018de58f11c25f6b9ad8bec3699e06b87dd3ab67a7326c30878c7c55ec1a45802af65da193ce99634158539e38c232a627895c5f14e2e20d487382ccc9c99cd0a0df266a292f283bb9b6854e344ecc32d5e1852fdde5fde77798030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"binding_factor": "6aa48a3635d7b962489283ee1ccda8ea66e5677b1e17f2f475eb565e3ae8ea73360f24c04e3775dadd1f2923adcda3d105536ad28c3c561100"
|
||||
}
|
||||
}
|
||||
},
|
||||
"round_two_outputs": {
|
||||
"participant_list": "1,3",
|
||||
"participants": {
|
||||
"1": {
|
||||
"sig_share": "c5057c80d13e565545dac6f3aa333065c809a14a94fea3c8e4e87e386a9cb89602de7355c5d19ebb09d553b100ef1858104fc7c43992d83400"
|
||||
},
|
||||
"3": {
|
||||
"sig_share": "2b490ea08411f78c620c668fff8ba70b25b7c89436f20cc45419213de70f93fb6c9094c79293697d72e741b68d2e493446005145d0b7fc3500"
|
||||
}
|
||||
}
|
||||
},
|
||||
"final_output": {
|
||||
"sig": "83ac141d289a5171bc894b058aee2890316280719a870fc5c1608b77403023155d7a9dc15a2b7920bb5826dd540bf76336be99536cebe36280fd093275c38dd4be525767f537fd6a4f5d8a9330811562c84fded5f851ac4b926f6e081d586508397cbc95678e1d628c564f180a0a4ad52a00"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
{
|
||||
"config": {
|
||||
"MAX_PARTICIPANTS": "3",
|
||||
"NUM_PARTICIPANTS": "2",
|
||||
"MIN_PARTICIPANTS": "2",
|
||||
"name": "FROST(P-256, SHA-256)",
|
||||
"group": "P-256",
|
||||
"hash": "SHA-256"
|
||||
},
|
||||
"inputs": {
|
||||
"group_secret_key": "8ba9bba2e0fd8c4767154d35a0b7562244a4aaf6f36c8fb8735fa48b301bd8de",
|
||||
"group_public_key": "023a309ad94e9fe8a7ba45dfc58f38bf091959d3c99cfbd02b4dc00585ec45ab70",
|
||||
"message": "74657374",
|
||||
"share_polynomial_coefficients": [
|
||||
"80f25e6c0709353e46bfbe882a11bdbb1f8097e46340eb8673b7e14556e6c3a4"
|
||||
],
|
||||
"participants": {
|
||||
"1": {
|
||||
"participant_share": "0c9c1a0fe806c184add50bbdcac913dda73e482daf95dcb9f35dbb0d8a9f7731"
|
||||
},
|
||||
"2": {
|
||||
"participant_share": "8d8e787bef0ff6c2f494ca45f4dad198c6bee01212d6c84067159c52e1863ad5"
|
||||
},
|
||||
"3": {
|
||||
"participant_share": "0e80d6e8f6192c003b5488ce1eec8f5429587d48cf001541e713b2d53c09d928"
|
||||
}
|
||||
}
|
||||
},
|
||||
"round_one_outputs": {
|
||||
"participant_list": "1,3",
|
||||
"participants": {
|
||||
"1": {
|
||||
"hiding_nonce_randomness": "f4e8cf80aec3f888d997900ac7e3e349944b5a6b47649fc32186d2f1238103c6",
|
||||
"binding_nonce_randomness": "a7f220770b6f10ff54ec6afa55f99bd08cc92fa1a488c86e9bf493e9cb894cdf",
|
||||
"hiding_nonce": "f871dfcf6bcd199342651adc361b92c941cb6a0d8c8c1a3b91d79e2c1bf3722d",
|
||||
"binding_nonce": "bd3ece3634a1b303dea0586ed67a91fe68510f11ebe66e8868309b1551ef2388",
|
||||
"hiding_nonce_commitment": "03987febbc67a8ed735affdff4d3a5adf22c05c80f97f311ab7437a3027372deb3",
|
||||
"binding_nonce_commitment": "02a1960477d139035b986d6adcb06491378beb92ccd097ad94e76291c52343849d",
|
||||
"binding_factor_input": "350c8b523feea9bb35720e9fbe0405ed48d78caa4fb60869f34367e144c68bb0fc77bf512409ad8b91e2ace4909229891a446c45683f5eb2f843dbec224527dc0000000000000000000000000000000000000000000000000000000000000001",
|
||||
"binding_factor": "cb415dd1d866493ee7d2db7cb33929d7e430e84d80c58070e2bbb1fdbf76a9c8"
|
||||
},
|
||||
"3": {
|
||||
"hiding_nonce_randomness": "1b6149d252a0a0a6618b8d22a1c49897f9b0d23a48f19598e191e05dc7b7ae33",
|
||||
"binding_nonce_randomness": "e13994bb75aafe337c32afdbfd08ae60dd108fc768845edaa871992044cabf1b",
|
||||
"hiding_nonce": "802e9321f9f63688c6c1a9681a4a4661f71770e0cef92b8a5997155d18fb82ef",
|
||||
"binding_nonce": "8b6b692ae634a24536f45dda95b2398af71cd605fb7a0bbdd9408d211ab99eba",
|
||||
"hiding_nonce_commitment": "0212cac45ebd4100c97506939391f9be4ffc3ca2960e2ef95aeaa38abdede204ca",
|
||||
"binding_nonce_commitment": "03017ce754d310eabda0f5681e61ce3d713cdd337070faa6a68471af49694a4e7e",
|
||||
"binding_factor_input": "350c8b523feea9bb35720e9fbe0405ed48d78caa4fb60869f34367e144c68bb0fc77bf512409ad8b91e2ace4909229891a446c45683f5eb2f843dbec224527dc0000000000000000000000000000000000000000000000000000000000000003",
|
||||
"binding_factor": "dfd82467569334e952edecb10d92adf85b8e299db0b40be3131a12efdfa3e796"
|
||||
}
|
||||
}
|
||||
},
|
||||
"round_two_outputs": {
|
||||
"participant_list": "1,3",
|
||||
"participants": {
|
||||
"1": {
|
||||
"sig_share": "c5acd980310aaf87cb7a9a90428698ef3e6b1e5860f7fb06329bc0efe3f14ca5"
|
||||
},
|
||||
"3": {
|
||||
"sig_share": "1e064fbd35467377eb3fe161ff975e9ec3ed8e2e0d4c73f3a6b0a023777e1264"
|
||||
}
|
||||
}
|
||||
},
|
||||
"final_output": {
|
||||
"sig": "029e07d4171dbf9a730ed95e9d95bda06fa4db76c88c519f7f3ca5483019f46cb0e3b3293d665122ffb6ba7bf2421df78e0258ac866e446ef9d94c61135b6f5f09"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
{
|
||||
"config": {
|
||||
"MAX_PARTICIPANTS": "3",
|
||||
"NUM_PARTICIPANTS": "2",
|
||||
"MIN_PARTICIPANTS": "2",
|
||||
"name": "FROST(ristretto255, SHA-512)",
|
||||
"group": "ristretto255",
|
||||
"hash": "SHA-512"
|
||||
},
|
||||
"inputs": {
|
||||
"group_secret_key": "1b25a55e463cfd15cf14a5d3acc3d15053f08da49c8afcf3ab265f2ebc4f970b",
|
||||
"group_public_key": "e2a62f39eede11269e3bd5a7d97554f5ca384f9f6d3dd9c3c0d05083c7254f57",
|
||||
"message": "74657374",
|
||||
"share_polynomial_coefficients": [
|
||||
"410f8b744b19325891d73736923525a4f596c805d060dfb9c98009d34e3fec02"
|
||||
],
|
||||
"participants": {
|
||||
"1": {
|
||||
"participant_share": "5c3430d391552f6e60ecdc093ff9f6f4488756aa6cebdbad75a768010b8f830e"
|
||||
},
|
||||
"2": {
|
||||
"participant_share": "b06fc5eac20b4f6e1b271d9df2343d843e1e1fb03c4cbb673f2872d459ce6f01"
|
||||
},
|
||||
"3": {
|
||||
"participant_share": "f17e505f0e2581c6acfe54d3846a622834b5e7b50cad9a2109a97ba7a80d5c04"
|
||||
}
|
||||
}
|
||||
},
|
||||
"round_one_outputs": {
|
||||
"participant_list": "1,3",
|
||||
"participants": {
|
||||
"1": {
|
||||
"hiding_nonce_randomness": "81800157bb554f299fe0b6bd658e4c4591d74168b5177bf55e8dceed59dc80c7",
|
||||
"binding_nonce_randomness": "e9b37de02fde28f601f09051ed9a277b02ac81c803a5c72492d58635001fe355",
|
||||
"hiding_nonce": "40f58e8df202b21c94f826e76e4647efdb0ea3ca7ae7e3689bc0cbe2e2f6660c",
|
||||
"binding_nonce": "373dd42b5fe80e88edddf82e03744b6a12d59256f546de612d4bbd91a6b1df06",
|
||||
"hiding_nonce_commitment": "b8c7319a56b296537436e5a6f509a871a3c74eff1534ec1e2f539ccd8b322411",
|
||||
"binding_nonce_commitment": "7af5d4bece8763ce3630370adbd978699402f624fd3a7d2c71ea5839efc3cf54",
|
||||
"binding_factor_input": "9c245d5fc2e451c5c5a617cc6f2a20629fb317d9b1c1915ab4bfa319d4ebf922c54dd1a5b3b754550c72734ac9255db8107a2b01f361754d9f13f428c2f6de9e4f609ae0dbe8bd1f95bee9f9ea219154d567ef174390bac737bb67ee1787c8a34279728d4aa99a6de2d5ce6deb86afe6bc68178f01223bb5eb934c8a23b6354e0100000000000000000000000000000000000000000000000000000000000000",
|
||||
"binding_factor": "607df5e2e3a8b5e2704716693e18f548100a32b86a5685d3932a774c3f107e06"
|
||||
},
|
||||
"3": {
|
||||
"hiding_nonce_randomness": "daeb223c4a913943cff2fb0b0e638dfcc281e1e8936ee6c3fef4d49ad9cbfaa0",
|
||||
"binding_nonce_randomness": "c425768d952ab8f18b9720c54b93e612ba2cca170bb7518cac080896efa7429b",
|
||||
"hiding_nonce": "491477c9dbe8717c77c6c1e2c5f4cec636c7c154313a44c91fea63e309f3e100",
|
||||
"binding_nonce": "3ae1bba7d6f2076f81596912dd916efae5b3c2ef896956321194fdd2e52ebc0f",
|
||||
"hiding_nonce_commitment": "e4466b7670ac4f9d9b7b67655860dd1ab341be18a654bb1966df53c76c85d511",
|
||||
"binding_nonce_commitment": "ce47cd595d25d7effc3c095efa2a687a1728a5ecab402b39e0c0ad9a525ea54f",
|
||||
"binding_factor_input": "9c245d5fc2e451c5c5a617cc6f2a20629fb317d9b1c1915ab4bfa319d4ebf922c54dd1a5b3b754550c72734ac9255db8107a2b01f361754d9f13f428c2f6de9e4f609ae0dbe8bd1f95bee9f9ea219154d567ef174390bac737bb67ee1787c8a34279728d4aa99a6de2d5ce6deb86afe6bc68178f01223bb5eb934c8a23b6354e0300000000000000000000000000000000000000000000000000000000000000",
|
||||
"binding_factor": "2bd27271c28746eb93e2114d6778c12b44c9287d84b85dc780eb08da6f689900"
|
||||
}
|
||||
}
|
||||
},
|
||||
"round_two_outputs": {
|
||||
"participant_list": "1,3",
|
||||
"participants": {
|
||||
"1": {
|
||||
"sig_share": "c38f438c325ce6bfa4272b37e7707caaeb57fa8c7ddcc05e0725acb8a7d9cd0c"
|
||||
},
|
||||
"3": {
|
||||
"sig_share": "4cb9917be3bd53f1d60f1c3d1a3ff563565fa15a391133e7f980e55d3aeb7904"
|
||||
}
|
||||
}
|
||||
},
|
||||
"final_output": {
|
||||
"sig": "204d5d93aa486192ecf2f64ce7dbc1db76948fb1077d1a719ae1ecca6143501e2275dfaafbb62759a59a4fd122b692f941b79be7b6edf34501a69116e2c44701"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
{
|
||||
"config": {
|
||||
"MAX_PARTICIPANTS": "3",
|
||||
"NUM_PARTICIPANTS": "2",
|
||||
"MIN_PARTICIPANTS": "2",
|
||||
"name": "FROST(secp256k1, SHA-256)",
|
||||
"group": "secp256k1",
|
||||
"hash": "SHA-256"
|
||||
},
|
||||
"inputs": {
|
||||
"group_secret_key": "0d004150d27c3bf2a42f312683d35fac7394b1e9e318249c1bfe7f0795a83114",
|
||||
"group_public_key": "02f37c34b66ced1fb51c34a90bdae006901f10625cc06c4f64663b0eae87d87b4f",
|
||||
"message": "74657374",
|
||||
"share_polynomial_coefficients": [
|
||||
"fbf85eadae3058ea14f19148bb72b45e4399c0b16028acaf0395c9b03c823579"
|
||||
],
|
||||
"participants": {
|
||||
"1": {
|
||||
"participant_share": "08f89ffe80ac94dcb920c26f3f46140bfc7f95b493f8310f5fc1ea2b01f4254c"
|
||||
},
|
||||
"2": {
|
||||
"participant_share": "04f0feac2edcedc6ce1253b7fab8c86b856a797f44d83d82a385554e6e401984"
|
||||
},
|
||||
"3": {
|
||||
"participant_share": "00e95d59dd0d46b0e303e500b62b7ccb0e555d49f5b849f5e748c071da8c0dbc"
|
||||
}
|
||||
}
|
||||
},
|
||||
"round_one_outputs": {
|
||||
"participant_list": "1,3",
|
||||
"participants": {
|
||||
"1": {
|
||||
"hiding_nonce_randomness": "80cbea5e405d169999d8c4b30b755fedb26ab07ec8198cda4873ed8ce5e16773",
|
||||
"binding_nonce_randomness": "f6d5b38197843046b68903048c1feba433e3500145281fa8bb1e26fdfeef5e7f",
|
||||
"hiding_nonce": "acc83278035223c1ba464e2d11bfacfc872b2b23e1041cf5f6130da21e4d8068",
|
||||
"binding_nonce": "c3ef169995bc3d2c2d48f30b83d0c63751e67ceb057695bcb2a6aa40ed5d926b",
|
||||
"hiding_nonce_commitment": "036673d68a928793c33ae07776908eae8ea15dd947ed81284e939aaba118573a5e",
|
||||
"binding_nonce_commitment": "03d2a96dd4ec1ee29dc22067109d1290dabd8016cb41856ee8ff9281c3fa1baffd",
|
||||
"binding_factor_input": "a645d8249457bbcac34fa7b740f66bcce08fc39506b8bbf1a1c81092f6272eda82ae39234d714f87a7b91dd67d124a06561a36817c1ecaa255c3527d694fc4f10000000000000000000000000000000000000000000000000000000000000001",
|
||||
"binding_factor": "d7bcbd29408dedc9e138262d99b09d8b5705d76eb5de2369d9103e4423f8ac79"
|
||||
},
|
||||
"3": {
|
||||
"hiding_nonce_randomness": "b9794047604beda0c5c0529ac9dfd83c0a80399a7bdf4c3e23cef2faf69cdcc3",
|
||||
"binding_nonce_randomness": "c28ce6252631620b84c2702b34774fab365e286ebc77030a112ebccccbffa78b",
|
||||
"hiding_nonce": "cb3387defef07fc9010c0564ba6495ed41876626ed86b886ca26cbbd3566ffbc",
|
||||
"binding_nonce": "4559459735eb68e8c16319a9fd9a14016053957cb8cea273a24b7c7bc1ee26f6",
|
||||
"hiding_nonce_commitment": "030278e6e6055fb963b40e0c3c37099f803f3f38930fc89092517f8ce1b47e8d6b",
|
||||
"binding_nonce_commitment": "028eb6d238c6c0fc6216906706ad0ff9943c6c1d6079cdf74f674481ebb2485db3",
|
||||
"binding_factor_input": "a645d8249457bbcac34fa7b740f66bcce08fc39506b8bbf1a1c81092f6272eda82ae39234d714f87a7b91dd67d124a06561a36817c1ecaa255c3527d694fc4f10000000000000000000000000000000000000000000000000000000000000003",
|
||||
"binding_factor": "ecc057259f3c8b195308c9b73aaaf840660a37eb264ebce342412c58102ee437"
|
||||
}
|
||||
}
|
||||
},
|
||||
"round_two_outputs": {
|
||||
"participant_list": "1,3",
|
||||
"participants": {
|
||||
"1": {
|
||||
"sig_share": "1750b2a314a81b66fd81366583617aaafcffa68f14495204795aa0434b907aa3"
|
||||
},
|
||||
"3": {
|
||||
"sig_share": "e4dbbbbbcb035eb3512918b0368c4ab2c836a92dccff3251efa7a4aacc7d3790"
|
||||
}
|
||||
}
|
||||
},
|
||||
"final_output": {
|
||||
"sig": "0259696aac722558e8638485d252bb2556f6241a7adfdf284c8c87a3428d46448dfc2c6e5edfab7a1a4eaa4f15b9edc55dc5364fbce1488456690244ee180db233"
|
||||
}
|
||||
}
|
|
@ -12,9 +12,9 @@ use crate::{
|
|||
};
|
||||
|
||||
pub(crate) fn core_sign<R: RngCore + CryptoRng, C: Curve>(rng: &mut R) {
|
||||
let private_key = C::F::random(&mut *rng);
|
||||
let nonce = C::F::random(&mut *rng);
|
||||
let challenge = C::F::random(rng); // Doesn't bother to craft an HRAM
|
||||
let private_key = C::random_F(&mut *rng);
|
||||
let nonce = C::random_F(&mut *rng);
|
||||
let challenge = C::random_F(rng); // Doesn't bother to craft an HRAm
|
||||
assert!(schnorr::verify::<C>(
|
||||
C::generator() * private_key,
|
||||
challenge,
|
||||
|
@ -27,8 +27,8 @@ pub(crate) fn core_sign<R: RngCore + CryptoRng, C: Curve>(rng: &mut R) {
|
|||
// random
|
||||
pub(crate) fn core_verify<R: RngCore + CryptoRng, C: Curve>(rng: &mut R) {
|
||||
assert!(!schnorr::verify::<C>(
|
||||
C::generator() * C::F::random(&mut *rng),
|
||||
C::F::random(rng),
|
||||
C::generator() * C::random_F(&mut *rng),
|
||||
C::random_F(rng),
|
||||
&SchnorrSignature { R: C::G::identity(), s: C::F::zero() }
|
||||
));
|
||||
}
|
||||
|
@ -39,9 +39,9 @@ pub(crate) fn core_batch_verify<R: RngCore + CryptoRng, C: Curve>(rng: &mut R) {
|
|||
let mut challenges = vec![];
|
||||
let mut sigs = vec![];
|
||||
for i in 0 .. 5 {
|
||||
keys.push(C::F::random(&mut *rng));
|
||||
challenges.push(C::F::random(&mut *rng));
|
||||
sigs.push(schnorr::sign::<C>(keys[i], C::F::random(&mut *rng), challenges[i]));
|
||||
keys.push(C::random_F(&mut *rng));
|
||||
challenges.push(C::random_F(&mut *rng));
|
||||
sigs.push(schnorr::sign::<C>(keys[i], C::random_F(&mut *rng), challenges[i]));
|
||||
}
|
||||
|
||||
// Batch verify
|
||||
|
@ -66,7 +66,7 @@ pub(crate) fn core_batch_verify<R: RngCore + CryptoRng, C: Curve>(rng: &mut R) {
|
|||
// Make sure a completely invalid signature fails when included
|
||||
for i in 0 .. 5 {
|
||||
let mut triplets = triplets.clone();
|
||||
triplets[i].3.s = C::F::random(&mut *rng);
|
||||
triplets[i].3.s = C::random_F(&mut *rng);
|
||||
if let Err(blame) = schnorr::batch_verify(rng, &triplets) {
|
||||
assert_eq!(blame, u16::try_from(i + 1).unwrap());
|
||||
} else {
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
use std::{io::Cursor, collections::HashMap};
|
||||
#[cfg(test)]
|
||||
use std::str::FromStr;
|
||||
|
||||
use rand_core::{RngCore, CryptoRng};
|
||||
|
||||
|
@ -16,17 +18,61 @@ use crate::{
|
|||
|
||||
pub struct Vectors {
|
||||
pub threshold: u16,
|
||||
pub shares: &'static [&'static str],
|
||||
pub group_secret: &'static str,
|
||||
pub group_key: &'static str,
|
||||
|
||||
pub msg: &'static str,
|
||||
pub included: &'static [u16],
|
||||
pub nonces: &'static [[&'static str; 2]],
|
||||
pub sig_shares: &'static [&'static str],
|
||||
pub group_secret: String,
|
||||
pub group_key: String,
|
||||
pub shares: Vec<String>,
|
||||
|
||||
pub msg: String,
|
||||
pub included: Vec<u16>,
|
||||
pub nonces: Vec<[String; 2]>,
|
||||
|
||||
pub sig_shares: Vec<String>,
|
||||
|
||||
pub sig: String,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
impl From<serde_json::Value> for Vectors {
|
||||
fn from(value: serde_json::Value) -> Vectors {
|
||||
let to_str = |value: &serde_json::Value| dbg!(value).as_str().unwrap().to_string();
|
||||
Vectors {
|
||||
threshold: u16::from_str(value["config"]["NUM_PARTICIPANTS"].as_str().unwrap()).unwrap(),
|
||||
|
||||
group_secret: to_str(&value["inputs"]["group_secret_key"]),
|
||||
group_key: to_str(&value["inputs"]["group_public_key"]),
|
||||
shares: value["inputs"]["participants"]
|
||||
.as_object()
|
||||
.unwrap()
|
||||
.values()
|
||||
.map(|share| to_str(&share["participant_share"]))
|
||||
.collect(),
|
||||
|
||||
msg: to_str(&value["inputs"]["message"]),
|
||||
included: to_str(&value["round_one_outputs"]["participant_list"])
|
||||
.split(",")
|
||||
.map(u16::from_str)
|
||||
.collect::<Result<_, _>>()
|
||||
.unwrap(),
|
||||
nonces: value["round_one_outputs"]["participants"]
|
||||
.as_object()
|
||||
.unwrap()
|
||||
.values()
|
||||
.map(|value| [to_str(&value["hiding_nonce"]), to_str(&value["binding_nonce"])])
|
||||
.collect(),
|
||||
|
||||
sig_shares: value["round_two_outputs"]["participants"]
|
||||
.as_object()
|
||||
.unwrap()
|
||||
.values()
|
||||
.map(|value| to_str(&value["sig_share"]))
|
||||
.collect(),
|
||||
|
||||
sig: to_str(&value["final_output"]["sig"]),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Load these vectors into FrostKeys using a custom serialization it'll deserialize
|
||||
fn vectors_to_multisig_keys<C: Curve>(vectors: &Vectors) -> HashMap<u16, FrostKeys<C>> {
|
||||
let shares = vectors
|
||||
|
@ -54,7 +100,7 @@ fn vectors_to_multisig_keys<C: Curve>(vectors: &Vectors) -> HashMap<u16, FrostKe
|
|||
assert_eq!(usize::from(these_keys.params().n()), shares.len());
|
||||
assert_eq!(these_keys.params().i(), i);
|
||||
assert_eq!(these_keys.secret_share(), shares[usize::from(i - 1)]);
|
||||
assert_eq!(&hex::encode(these_keys.group_key().to_bytes().as_ref()), vectors.group_key);
|
||||
assert_eq!(hex::encode(these_keys.group_key().to_bytes().as_ref()), vectors.group_key);
|
||||
keys.insert(i, FrostKeys::new(these_keys));
|
||||
}
|
||||
|
||||
|
@ -67,26 +113,20 @@ pub fn test_with_vectors<R: RngCore + CryptoRng, C: Curve, H: Hram<C>>(
|
|||
) {
|
||||
// Do basic tests before trying the vectors
|
||||
test_curve::<_, C>(&mut *rng);
|
||||
test_schnorr::<_, C>(rng);
|
||||
test_schnorr::<_, C>(&mut *rng);
|
||||
test_promotion::<_, C>(rng);
|
||||
|
||||
// Test against the vectors
|
||||
let keys = vectors_to_multisig_keys::<C>(&vectors);
|
||||
let group_key = C::read_G(&mut Cursor::new(hex::decode(vectors.group_key).unwrap())).unwrap();
|
||||
assert_eq!(
|
||||
C::generator() *
|
||||
C::read_F(&mut Cursor::new(hex::decode(vectors.group_secret).unwrap())).unwrap(),
|
||||
group_key
|
||||
);
|
||||
assert_eq!(
|
||||
recover(&keys),
|
||||
C::read_F(&mut Cursor::new(hex::decode(vectors.group_secret).unwrap())).unwrap()
|
||||
);
|
||||
let group_key = C::read_G(&mut Cursor::new(hex::decode(&vectors.group_key).unwrap())).unwrap();
|
||||
let secret = C::read_F(&mut Cursor::new(hex::decode(&vectors.group_secret).unwrap())).unwrap();
|
||||
assert_eq!(C::generator() * secret, group_key);
|
||||
assert_eq!(recover(&keys), secret);
|
||||
|
||||
let mut machines = vec![];
|
||||
for i in vectors.included {
|
||||
for i in &vectors.included {
|
||||
machines.push((
|
||||
*i,
|
||||
i,
|
||||
AlgorithmMachine::new(
|
||||
Schnorr::<C, H>::new(),
|
||||
keys[i].clone(),
|
||||
|
@ -102,8 +142,8 @@ pub fn test_with_vectors<R: RngCore + CryptoRng, C: Curve, H: Hram<C>>(
|
|||
.drain(..)
|
||||
.map(|(i, machine)| {
|
||||
let nonces = [
|
||||
C::read_F(&mut Cursor::new(hex::decode(vectors.nonces[c][0]).unwrap())).unwrap(),
|
||||
C::read_F(&mut Cursor::new(hex::decode(vectors.nonces[c][1]).unwrap())).unwrap(),
|
||||
C::read_F(&mut Cursor::new(hex::decode(&vectors.nonces[c][0]).unwrap())).unwrap(),
|
||||
C::read_F(&mut Cursor::new(hex::decode(&vectors.nonces[c][1]).unwrap())).unwrap(),
|
||||
];
|
||||
c += 1;
|
||||
let these_commitments = vec![[C::generator() * nonces[0], C::generator() * nonces[1]]];
|
||||
|
@ -114,7 +154,7 @@ pub fn test_with_vectors<R: RngCore + CryptoRng, C: Curve, H: Hram<C>>(
|
|||
});
|
||||
|
||||
commitments.insert(
|
||||
i,
|
||||
*i,
|
||||
Cursor::new(
|
||||
[
|
||||
these_commitments[0][0].to_bytes().as_ref(),
|
||||
|
@ -134,18 +174,18 @@ pub fn test_with_vectors<R: RngCore + CryptoRng, C: Curve, H: Hram<C>>(
|
|||
.drain(..)
|
||||
.map(|(i, machine)| {
|
||||
let (machine, share) =
|
||||
machine.sign(clone_without(&commitments, &i), &hex::decode(vectors.msg).unwrap()).unwrap();
|
||||
machine.sign(clone_without(&commitments, i), &hex::decode(&vectors.msg).unwrap()).unwrap();
|
||||
|
||||
assert_eq!(share, hex::decode(vectors.sig_shares[c]).unwrap());
|
||||
assert_eq!(share, hex::decode(&vectors.sig_shares[c]).unwrap());
|
||||
c += 1;
|
||||
|
||||
shares.insert(i, Cursor::new(share));
|
||||
shares.insert(*i, Cursor::new(share));
|
||||
(i, machine)
|
||||
})
|
||||
.collect::<HashMap<_, _>>();
|
||||
|
||||
for (i, machine) in machines.drain() {
|
||||
let sig = machine.complete(clone_without(&shares, &i)).unwrap();
|
||||
let sig = machine.complete(clone_without(&shares, i)).unwrap();
|
||||
let mut serialized = sig.R.to_bytes().as_ref().to_vec();
|
||||
serialized.extend(sig.s.to_repr().as_ref());
|
||||
assert_eq!(hex::encode(serialized), vectors.sig);
|
||||
|
|
Loading…
Reference in a new issue