Rename MultisigParams/MultisigKeys/MultisigView to Frost*

This commit is contained in:
Luke Parker 2022-06-28 00:06:12 -04:00
parent 7c86e4593a
commit ac17645fc8
No known key found for this signature in database
GPG key ID: F9F1386DB1E119B6
13 changed files with 79 additions and 78 deletions

View file

@ -14,7 +14,7 @@ use curve25519_dalek::{
use group::Group; use group::Group;
use transcript::{Transcript, RecommendedTranscript}; use transcript::{Transcript, RecommendedTranscript};
use frost::{curve::Ed25519, FrostError, MultisigView, algorithm::Algorithm}; use frost::{curve::Ed25519, FrostError, FrostView, algorithm::Algorithm};
use dalek_ff_group as dfg; use dalek_ff_group as dfg;
use crate::{ use crate::{
@ -126,7 +126,7 @@ impl Algorithm<Ed25519> for ClsagMultisig {
fn preprocess_addendum<R: RngCore + CryptoRng>( fn preprocess_addendum<R: RngCore + CryptoRng>(
&mut self, &mut self,
rng: &mut R, rng: &mut R,
view: &MultisigView<Ed25519>, view: &FrostView<Ed25519>,
nonces: &[dfg::Scalar; 2] nonces: &[dfg::Scalar; 2]
) -> Vec<u8> { ) -> Vec<u8> {
self.H = hash_to_point(&view.group_key().0); self.H = hash_to_point(&view.group_key().0);
@ -144,7 +144,7 @@ impl Algorithm<Ed25519> for ClsagMultisig {
fn process_addendum( fn process_addendum(
&mut self, &mut self,
view: &MultisigView<Ed25519>, view: &FrostView<Ed25519>,
l: u16, l: u16,
commitments: &[dfg::EdwardsPoint; 2], commitments: &[dfg::EdwardsPoint; 2],
serialized: &[u8] serialized: &[u8]
@ -192,7 +192,7 @@ impl Algorithm<Ed25519> for ClsagMultisig {
fn sign_share( fn sign_share(
&mut self, &mut self,
view: &MultisigView<Ed25519>, view: &FrostView<Ed25519>,
nonce_sum: dfg::EdwardsPoint, nonce_sum: dfg::EdwardsPoint,
b: dfg::Scalar, b: dfg::Scalar,
nonce: dfg::Scalar, nonce: dfg::Scalar,

View file

@ -8,7 +8,7 @@ use curve25519_dalek::{traits::Identity, scalar::Scalar, edwards::{EdwardsPoint,
use transcript::{Transcript, RecommendedTranscript}; use transcript::{Transcript, RecommendedTranscript};
use frost::{ use frost::{
curve::Ed25519, curve::Ed25519,
FrostError, MultisigKeys, FrostError, FrostKeys,
sign::{ sign::{
PreprocessMachine, SignMachine, SignatureMachine, PreprocessMachine, SignMachine, SignatureMachine,
AlgorithmMachine, AlgorithmSignMachine, AlgorithmSignatureMachine AlgorithmMachine, AlgorithmSignMachine, AlgorithmSignatureMachine
@ -57,7 +57,7 @@ impl SignableTransaction {
pub async fn multisig( pub async fn multisig(
self, self,
rpc: &Rpc, rpc: &Rpc,
keys: MultisigKeys<Ed25519>, keys: FrostKeys<Ed25519>,
mut transcript: RecommendedTranscript, mut transcript: RecommendedTranscript,
height: usize, height: usize,
mut included: Vec<u16> mut included: Vec<u16>

View file

@ -4,7 +4,7 @@ use rand_core::{RngCore, CryptoRng};
use transcript::Transcript; use transcript::Transcript;
use crate::{Curve, FrostError, MultisigView, schnorr}; use crate::{Curve, FrostError, FrostView, schnorr};
pub use schnorr::SchnorrSignature; pub use schnorr::SchnorrSignature;
/// Algorithm to use FROST with /// Algorithm to use FROST with
@ -19,14 +19,14 @@ pub trait Algorithm<C: Curve>: Clone {
fn preprocess_addendum<R: RngCore + CryptoRng>( fn preprocess_addendum<R: RngCore + CryptoRng>(
&mut self, &mut self,
rng: &mut R, rng: &mut R,
params: &MultisigView<C>, params: &FrostView<C>,
nonces: &[C::F; 2], nonces: &[C::F; 2],
) -> Vec<u8>; ) -> Vec<u8>;
/// Proccess the addendum for the specified participant. Guaranteed to be ordered /// Proccess the addendum for the specified participant. Guaranteed to be ordered
fn process_addendum( fn process_addendum(
&mut self, &mut self,
params: &MultisigView<C>, params: &FrostView<C>,
l: u16, l: u16,
commitments: &[C::G; 2], commitments: &[C::G; 2],
serialized: &[u8], serialized: &[u8],
@ -38,7 +38,7 @@ pub trait Algorithm<C: Curve>: Clone {
/// The nonce will already have been processed into the combined form d + (e * p) /// The nonce will already have been processed into the combined form d + (e * p)
fn sign_share( fn sign_share(
&mut self, &mut self,
params: &MultisigView<C>, params: &FrostView<C>,
nonce_sum: C::G, nonce_sum: C::G,
binding: C::F, binding: C::F,
nonce: C::F, nonce: C::F,
@ -114,7 +114,7 @@ impl<C: Curve, H: Hram<C>> Algorithm<C> for Schnorr<C, H> {
fn preprocess_addendum<R: RngCore + CryptoRng>( fn preprocess_addendum<R: RngCore + CryptoRng>(
&mut self, &mut self,
_: &mut R, _: &mut R,
_: &MultisigView<C>, _: &FrostView<C>,
_: &[C::F; 2], _: &[C::F; 2],
) -> Vec<u8> { ) -> Vec<u8> {
vec![] vec![]
@ -122,7 +122,7 @@ impl<C: Curve, H: Hram<C>> Algorithm<C> for Schnorr<C, H> {
fn process_addendum( fn process_addendum(
&mut self, &mut self,
_: &MultisigView<C>, _: &FrostView<C>,
_: u16, _: u16,
_: &[C::G; 2], _: &[C::G; 2],
_: &[u8], _: &[u8],
@ -132,7 +132,7 @@ impl<C: Curve, H: Hram<C>> Algorithm<C> for Schnorr<C, H> {
fn sign_share( fn sign_share(
&mut self, &mut self,
params: &MultisigView<C>, params: &FrostView<C>,
nonce_sum: C::G, nonce_sum: C::G,
_: C::F, _: C::F,
nonce: C::F, nonce: C::F,

View file

@ -8,7 +8,7 @@ use multiexp::{multiexp_vartime, BatchVerifier};
use crate::{ use crate::{
curve::Curve, curve::Curve,
FrostError, MultisigParams, MultisigKeys, FrostError, FrostParams, FrostKeys,
schnorr::{self, SchnorrSignature}, schnorr::{self, SchnorrSignature},
validate_map validate_map
}; };
@ -29,7 +29,7 @@ fn challenge<C: Curve>(context: &str, l: u16, R: &[u8], Am: &[u8]) -> C::F {
// the serialized commitments to be broadcasted over an authenticated channel to all parties // the serialized commitments to be broadcasted over an authenticated channel to all parties
fn generate_key_r1<R: RngCore + CryptoRng, C: Curve>( fn generate_key_r1<R: RngCore + CryptoRng, C: Curve>(
rng: &mut R, rng: &mut R,
params: &MultisigParams, params: &FrostParams,
context: &str, context: &str,
) -> (Vec<C::F>, Vec<u8>) { ) -> (Vec<C::F>, Vec<u8>) {
let t = usize::from(params.t); let t = usize::from(params.t);
@ -72,7 +72,7 @@ fn generate_key_r1<R: RngCore + CryptoRng, C: Curve>(
// Verify the received data from the first round of key generation // Verify the received data from the first round of key generation
fn verify_r1<R: RngCore + CryptoRng, C: Curve>( fn verify_r1<R: RngCore + CryptoRng, C: Curve>(
rng: &mut R, rng: &mut R,
params: &MultisigParams, params: &FrostParams,
context: &str, context: &str,
our_commitments: Vec<u8>, our_commitments: Vec<u8>,
mut serialized: HashMap<u16, Vec<u8>>, mut serialized: HashMap<u16, Vec<u8>>,
@ -149,7 +149,7 @@ fn polynomial<F: PrimeField>(
// counterparty to receive // counterparty to receive
fn generate_key_r2<R: RngCore + CryptoRng, C: Curve>( fn generate_key_r2<R: RngCore + CryptoRng, C: Curve>(
rng: &mut R, rng: &mut R,
params: &MultisigParams, params: &FrostParams,
context: &str, context: &str,
coefficients: Vec<C::F>, coefficients: Vec<C::F>,
our_commitments: Vec<u8>, our_commitments: Vec<u8>,
@ -190,12 +190,12 @@ fn generate_key_r2<R: RngCore + CryptoRng, C: Curve>(
/// broadcasted initially /// broadcasted initially
fn complete_r2<R: RngCore + CryptoRng, C: Curve>( fn complete_r2<R: RngCore + CryptoRng, C: Curve>(
rng: &mut R, rng: &mut R,
params: MultisigParams, params: FrostParams,
mut secret_share: C::F, mut secret_share: C::F,
commitments: HashMap<u16, Vec<C::G>>, commitments: HashMap<u16, Vec<C::G>>,
// Vec to preserve ownership // Vec to preserve ownership
mut serialized: HashMap<u16, Vec<u8>>, mut serialized: HashMap<u16, Vec<u8>>,
) -> Result<MultisigKeys<C>, FrostError> { ) -> Result<FrostKeys<C>, FrostError> {
validate_map( validate_map(
&mut serialized, &mut serialized,
&(1 ..= params.n()).into_iter().collect::<Vec<_>>(), &(1 ..= params.n()).into_iter().collect::<Vec<_>>(),
@ -256,12 +256,13 @@ fn complete_r2<R: RngCore + CryptoRng, C: Curve>(
for i in 1 ..= params.n() { for i in 1 ..= params.n() {
verification_shares.insert(i, multiexp_vartime(&exponential(i, &stripes), C::LITTLE_ENDIAN)); verification_shares.insert(i, multiexp_vartime(&exponential(i, &stripes), C::LITTLE_ENDIAN));
} }
// Removing this check would enable optimizing the above from t + (n * t) to t + ((n - 1) * t)
debug_assert_eq!(C::GENERATOR_TABLE * secret_share, verification_shares[&params.i()]); debug_assert_eq!(C::GENERATOR_TABLE * secret_share, verification_shares[&params.i()]);
// TODO: Clear serialized and shares // TODO: Clear serialized and shares
Ok( Ok(
MultisigKeys { FrostKeys {
params, params,
secret_share, secret_share,
group_key: stripes[0], group_key: stripes[0],
@ -272,20 +273,20 @@ fn complete_r2<R: RngCore + CryptoRng, C: Curve>(
} }
pub struct KeyGenMachine<C: Curve> { pub struct KeyGenMachine<C: Curve> {
params: MultisigParams, params: FrostParams,
context: String, context: String,
_curve: PhantomData<C>, _curve: PhantomData<C>,
} }
pub struct SecretShareMachine<C: Curve> { pub struct SecretShareMachine<C: Curve> {
params: MultisigParams, params: FrostParams,
context: String, context: String,
coefficients: Vec<C::F>, coefficients: Vec<C::F>,
our_commitments: Vec<u8>, our_commitments: Vec<u8>,
} }
pub struct KeyMachine<C: Curve> { pub struct KeyMachine<C: Curve> {
params: MultisigParams, params: FrostParams,
secret: C::F, secret: C::F,
commitments: HashMap<u16, Vec<C::G>>, commitments: HashMap<u16, Vec<C::G>>,
} }
@ -293,7 +294,7 @@ pub struct KeyMachine<C: Curve> {
impl<C: Curve> KeyGenMachine<C> { impl<C: Curve> KeyGenMachine<C> {
/// Creates a new machine to generate a key for the specified curve in the specified multisig /// Creates a new machine to generate a key for the specified curve in the specified multisig
// The context string must be unique among multisigs // The context string must be unique among multisigs
pub fn new(params: MultisigParams, context: String) -> KeyGenMachine<C> { pub fn new(params: FrostParams, context: String) -> KeyGenMachine<C> {
KeyGenMachine { params, context, _curve: PhantomData } KeyGenMachine { params, context, _curve: PhantomData }
} }
@ -351,7 +352,7 @@ impl<C: Curve> KeyMachine<C> {
self, self,
rng: &mut R, rng: &mut R,
shares: HashMap<u16, Vec<u8>>, shares: HashMap<u16, Vec<u8>>,
) -> Result<MultisigKeys<C>, FrostError> { ) -> Result<FrostKeys<C>, FrostError> {
complete_r2(rng, self.params, self.secret, self.commitments, shares) complete_r2(rng, self.params, self.secret, self.commitments, shares)
} }
} }

View file

@ -18,7 +18,7 @@ pub mod tests;
/// Parameters for a multisig /// Parameters for a multisig
// These fields can not be made public as they should be static // These fields can not be made public as they should be static
#[derive(Clone, Copy, PartialEq, Eq, Debug)] #[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub struct MultisigParams { pub struct FrostParams {
/// Participants needed to sign on behalf of the group /// Participants needed to sign on behalf of the group
t: u16, t: u16,
/// Amount of participants /// Amount of participants
@ -27,12 +27,12 @@ pub struct MultisigParams {
i: u16, i: u16,
} }
impl MultisigParams { impl FrostParams {
pub fn new( pub fn new(
t: u16, t: u16,
n: u16, n: u16,
i: u16 i: u16
) -> Result<MultisigParams, FrostError> { ) -> Result<FrostParams, FrostError> {
if (t == 0) || (n == 0) { if (t == 0) || (n == 0) {
Err(FrostError::ZeroParameter(t, n))?; Err(FrostError::ZeroParameter(t, n))?;
} }
@ -46,7 +46,7 @@ impl MultisigParams {
Err(FrostError::InvalidParticipantIndex(n, i))?; Err(FrostError::InvalidParticipantIndex(n, i))?;
} }
Ok(MultisigParams{ t, n, i }) Ok(FrostParams{ t, n, i })
} }
pub fn t(&self) -> u16 { self.t } pub fn t(&self) -> u16 { self.t }
@ -86,14 +86,14 @@ pub enum FrostError {
// View of keys passable to algorithm implementations // View of keys passable to algorithm implementations
#[derive(Clone)] #[derive(Clone)]
pub struct MultisigView<C: Curve> { pub struct FrostView<C: Curve> {
group_key: C::G, group_key: C::G,
included: Vec<u16>, included: Vec<u16>,
secret_share: C::F, secret_share: C::F,
verification_shares: HashMap<u16, C::G>, verification_shares: HashMap<u16, C::G>,
} }
impl<C: Curve> MultisigView<C> { impl<C: Curve> FrostView<C> {
pub fn group_key(&self) -> C::G { pub fn group_key(&self) -> C::G {
self.group_key self.group_key
} }
@ -134,9 +134,9 @@ pub fn lagrange<F: PrimeField>(
} }
#[derive(Clone, PartialEq, Eq, Debug)] #[derive(Clone, PartialEq, Eq, Debug)]
pub struct MultisigKeys<C: Curve> { pub struct FrostKeys<C: Curve> {
/// Multisig Parameters /// FROST Parameters
params: MultisigParams, params: FrostParams,
/// Secret share key /// Secret share key
secret_share: C::F, secret_share: C::F,
@ -149,12 +149,12 @@ pub struct MultisigKeys<C: Curve> {
offset: Option<C::F>, offset: Option<C::F>,
} }
impl<C: Curve> MultisigKeys<C> { impl<C: Curve> FrostKeys<C> {
/// Offset the keys by a given scalar to allow for account and privacy schemes /// Offset the keys by a given scalar to allow for account and privacy schemes
/// This offset is ephemeral and will not be included when these keys are serialized /// This offset is ephemeral and will not be included when these keys are serialized
/// Keys offset multiple times will form a new offset of their sum /// Keys offset multiple times will form a new offset of their sum
/// Not IETF compliant /// Not IETF compliant
pub fn offset(&self, offset: C::F) -> MultisigKeys<C> { pub fn offset(&self, offset: C::F) -> FrostKeys<C> {
let mut res = self.clone(); let mut res = self.clone();
// Carry any existing offset // Carry any existing offset
// Enables schemes like Monero's subaddresses which have a per-subaddress offset and then a // Enables schemes like Monero's subaddresses which have a per-subaddress offset and then a
@ -164,7 +164,7 @@ impl<C: Curve> MultisigKeys<C> {
res res
} }
pub fn params(&self) -> MultisigParams { pub fn params(&self) -> FrostParams {
self.params self.params
} }
@ -180,7 +180,7 @@ impl<C: Curve> MultisigKeys<C> {
self.verification_shares.clone() self.verification_shares.clone()
} }
pub fn view(&self, included: &[u16]) -> Result<MultisigView<C>, FrostError> { pub fn view(&self, included: &[u16]) -> Result<FrostView<C>, FrostError> {
if (included.len() < self.params.t.into()) || (usize::from(self.params.n) < included.len()) { if (included.len() < self.params.t.into()) || (usize::from(self.params.n) < included.len()) {
Err(FrostError::InvalidSigningSet("invalid amount of participants included".to_string()))?; Err(FrostError::InvalidSigningSet("invalid amount of participants included".to_string()))?;
} }
@ -189,7 +189,7 @@ impl<C: Curve> MultisigKeys<C> {
let offset = self.offset.unwrap_or(C::F::zero()); let offset = self.offset.unwrap_or(C::F::zero());
let offset_share = offset * C::F::from(included.len().try_into().unwrap()).invert().unwrap(); let offset_share = offset * C::F::from(included.len().try_into().unwrap()).invert().unwrap();
Ok(MultisigView { Ok(FrostView {
group_key: self.group_key, group_key: self.group_key,
secret_share: secret_share + offset_share, secret_share: secret_share + offset_share,
verification_shares: self.verification_shares.iter().map( verification_shares: self.verification_shares.iter().map(
@ -207,7 +207,7 @@ impl<C: Curve> MultisigKeys<C> {
} }
pub fn serialize(&self) -> Vec<u8> { pub fn serialize(&self) -> Vec<u8> {
let mut serialized = Vec::with_capacity(MultisigKeys::<C>::serialized_len(self.params.n)); let mut serialized = Vec::with_capacity(FrostKeys::<C>::serialized_len(self.params.n));
serialized.extend(u64::try_from(C::ID.len()).unwrap().to_be_bytes()); serialized.extend(u64::try_from(C::ID.len()).unwrap().to_be_bytes());
serialized.extend(C::ID); serialized.extend(C::ID);
serialized.extend(&self.params.t.to_be_bytes()); serialized.extend(&self.params.t.to_be_bytes());
@ -221,7 +221,7 @@ impl<C: Curve> MultisigKeys<C> {
serialized serialized
} }
pub fn deserialize(serialized: &[u8]) -> Result<MultisigKeys<C>, FrostError> { pub fn deserialize(serialized: &[u8]) -> Result<FrostKeys<C>, FrostError> {
let mut start = u64::try_from(C::ID.len()).unwrap().to_be_bytes().to_vec(); let mut start = u64::try_from(C::ID.len()).unwrap().to_be_bytes().to_vec();
start.extend(C::ID); start.extend(C::ID);
let mut cursor = start.len(); let mut cursor = start.len();
@ -229,7 +229,7 @@ impl<C: Curve> MultisigKeys<C> {
if serialized.len() < (cursor + 4) { if serialized.len() < (cursor + 4) {
Err( Err(
FrostError::InternalError( FrostError::InternalError(
"MultisigKeys serialization is missing its curve/participant quantities".to_string() "FrostKeys serialization is missing its curve/participant quantities".to_string()
) )
)?; )?;
} }
@ -246,7 +246,7 @@ impl<C: Curve> MultisigKeys<C> {
let n = u16::from_be_bytes(serialized[cursor .. (cursor + 2)].try_into().unwrap()); let n = u16::from_be_bytes(serialized[cursor .. (cursor + 2)].try_into().unwrap());
cursor += 2; cursor += 2;
if serialized.len() != MultisigKeys::<C>::serialized_len(n) { if serialized.len() != FrostKeys::<C>::serialized_len(n) {
Err(FrostError::InternalError("incorrect serialization length".to_string()))?; Err(FrostError::InternalError("incorrect serialization length".to_string()))?;
} }
@ -271,8 +271,8 @@ impl<C: Curve> MultisigKeys<C> {
} }
Ok( Ok(
MultisigKeys { FrostKeys {
params: MultisigParams::new(t, n, i) params: FrostParams::new(t, n, i)
.map_err(|_| FrostError::InternalError("invalid parameters".to_string()))?, .map_err(|_| FrostError::InternalError("invalid parameters".to_string()))?,
secret_share, secret_share,
group_key, group_key,

View file

@ -10,24 +10,24 @@ use transcript::Transcript;
use crate::{ use crate::{
curve::Curve, curve::Curve,
FrostError, FrostError,
MultisigParams, MultisigKeys, MultisigView, FrostParams, FrostKeys, FrostView,
algorithm::Algorithm, algorithm::Algorithm,
validate_map validate_map
}; };
/// Pairing of an Algorithm with a MultisigKeys instance and this specific signing set /// Pairing of an Algorithm with a FrostKeys instance and this specific signing set
#[derive(Clone)] #[derive(Clone)]
pub struct Params<C: Curve, A: Algorithm<C>> { pub struct Params<C: Curve, A: Algorithm<C>> {
algorithm: A, algorithm: A,
keys: Arc<MultisigKeys<C>>, keys: Arc<FrostKeys<C>>,
view: MultisigView<C>, view: FrostView<C>,
} }
// Currently public to enable more complex operations as desired, yet solely used in testing // Currently public to enable more complex operations as desired, yet solely used in testing
impl<C: Curve, A: Algorithm<C>> Params<C, A> { impl<C: Curve, A: Algorithm<C>> Params<C, A> {
pub fn new( pub fn new(
algorithm: A, algorithm: A,
keys: Arc<MultisigKeys<C>>, keys: Arc<FrostKeys<C>>,
included: &[u16], included: &[u16],
) -> Result<Params<C, A>, FrostError> { ) -> Result<Params<C, A>, FrostError> {
let mut included = included.to_vec(); let mut included = included.to_vec();
@ -60,11 +60,11 @@ impl<C: Curve, A: Algorithm<C>> Params<C, A> {
Ok(Params { algorithm, view: keys.view(&included).unwrap(), keys }) Ok(Params { algorithm, view: keys.view(&included).unwrap(), keys })
} }
pub fn multisig_params(&self) -> MultisigParams { pub fn multisig_params(&self) -> FrostParams {
self.keys.params self.keys.params
} }
pub fn view(&self) -> MultisigView<C> { pub fn view(&self) -> FrostView<C> {
self.view.clone() self.view.clone()
} }
} }
@ -291,7 +291,7 @@ impl<C: Curve, A: Algorithm<C>> AlgorithmMachine<C, A> {
/// Creates a new machine to generate a key for the specified curve in the specified multisig /// Creates a new machine to generate a key for the specified curve in the specified multisig
pub fn new( pub fn new(
algorithm: A, algorithm: A,
keys: Arc<MultisigKeys<C>>, keys: Arc<FrostKeys<C>>,
included: &[u16], included: &[u16],
) -> Result<AlgorithmMachine<C, A>, FrostError> { ) -> Result<AlgorithmMachine<C, A>, FrostError> {
Ok(AlgorithmMachine { params: Params::new(algorithm, keys, included)? }) Ok(AlgorithmMachine { params: Params::new(algorithm, keys, included)? })

View file

@ -2,7 +2,7 @@ use rand_core::{RngCore, CryptoRng};
use group::{ff::Field, Group}; use group::{ff::Field, Group};
use crate::{Curve, MultisigKeys, tests::key_gen}; use crate::{Curve, FrostKeys, tests::key_gen};
// Test generation of FROST keys // Test generation of FROST keys
fn key_generation<R: RngCore + CryptoRng, C: Curve>(rng: &mut R) { fn key_generation<R: RngCore + CryptoRng, C: Curve>(rng: &mut R) {
@ -13,7 +13,7 @@ fn key_generation<R: RngCore + CryptoRng, C: Curve>(rng: &mut R) {
// Test serialization of generated keys // Test serialization of generated keys
fn keys_serialization<R: RngCore + CryptoRng, C: Curve>(rng: &mut R) { fn keys_serialization<R: RngCore + CryptoRng, C: Curve>(rng: &mut R) {
for (_, keys) in key_gen::<_, C>(rng) { for (_, keys) in key_gen::<_, C>(rng) {
assert_eq!(&MultisigKeys::<C>::deserialize(&keys.serialize()).unwrap(), &*keys); assert_eq!(&FrostKeys::<C>::deserialize(&keys.serialize()).unwrap(), &*keys);
} }
} }
@ -35,7 +35,7 @@ pub fn test_curve<R: RngCore + CryptoRng, C: Curve>(rng: &mut R) {
} }
} }
// Test FROST key generation and serialization of MultisigKeys works as expected // Test FROST key generation and serialization of FrostKeys works as expected
key_generation::<_, C>(rng); key_generation::<_, C>(rng);
keys_serialization::<_, C>(rng); keys_serialization::<_, C>(rng);
} }

View file

@ -6,7 +6,7 @@ use group::ff::Field;
use crate::{ use crate::{
Curve, Curve,
MultisigParams, MultisigKeys, FrostParams, FrostKeys,
lagrange, lagrange,
key_gen::KeyGenMachine, key_gen::KeyGenMachine,
algorithm::Algorithm, algorithm::Algorithm,
@ -36,12 +36,12 @@ pub fn clone_without<K: Clone + std::cmp::Eq + std::hash::Hash, V: Clone>(
pub fn key_gen<R: RngCore + CryptoRng, C: Curve>( pub fn key_gen<R: RngCore + CryptoRng, C: Curve>(
rng: &mut R rng: &mut R
) -> HashMap<u16, Arc<MultisigKeys<C>>> { ) -> HashMap<u16, Arc<FrostKeys<C>>> {
let mut machines = HashMap::new(); let mut machines = HashMap::new();
let mut commitments = HashMap::new(); let mut commitments = HashMap::new();
for i in 1 ..= PARTICIPANTS { for i in 1 ..= PARTICIPANTS {
let machine = KeyGenMachine::<C>::new( let machine = KeyGenMachine::<C>::new(
MultisigParams::new(THRESHOLD, PARTICIPANTS, i).unwrap(), FrostParams::new(THRESHOLD, PARTICIPANTS, i).unwrap(),
"FROST Test key_gen".to_string() "FROST Test key_gen".to_string()
); );
let (machine, these_commitments) = machine.generate_coefficients(rng); let (machine, these_commitments) = machine.generate_coefficients(rng);
@ -89,7 +89,7 @@ pub fn key_gen<R: RngCore + CryptoRng, C: Curve>(
}).collect::<HashMap<_, _>>() }).collect::<HashMap<_, _>>()
} }
pub fn recover<C: Curve>(keys: &HashMap<u16, MultisigKeys<C>>) -> C::F { pub fn recover<C: Curve>(keys: &HashMap<u16, FrostKeys<C>>) -> C::F {
let first = keys.values().next().expect("no keys provided"); let first = keys.values().next().expect("no keys provided");
assert!(keys.len() >= first.params().t().into(), "not enough keys provided"); assert!(keys.len() >= first.params().t().into(), "not enough keys provided");
let included = keys.keys().cloned().collect::<Vec<_>>(); let included = keys.keys().cloned().collect::<Vec<_>>();
@ -105,7 +105,7 @@ pub fn recover<C: Curve>(keys: &HashMap<u16, MultisigKeys<C>>) -> C::F {
pub fn algorithm_machines<R: RngCore, C: Curve, A: Algorithm<C>>( pub fn algorithm_machines<R: RngCore, C: Curve, A: Algorithm<C>>(
rng: &mut R, rng: &mut R,
algorithm: A, algorithm: A,
keys: &HashMap<u16, Arc<MultisigKeys<C>>>, keys: &HashMap<u16, Arc<FrostKeys<C>>>,
) -> HashMap<u16, AlgorithmMachine<C, A>> { ) -> HashMap<u16, AlgorithmMachine<C, A>> {
let mut included = vec![]; let mut included = vec![];
while included.len() < usize::from(keys[&1].params().t()) { while included.len() < usize::from(keys[&1].params().t()) {

View file

@ -5,7 +5,7 @@ use rand_core::{RngCore, CryptoRng};
use group::ff::Field; use group::ff::Field;
use crate::{ use crate::{
Curve, MultisigKeys, schnorr::{self, SchnorrSignature}, algorithm::{Hram, Schnorr}, Curve, FrostKeys, schnorr::{self, SchnorrSignature}, algorithm::{Hram, Schnorr},
tests::{key_gen, algorithm_machines, sign as sign_test} tests::{key_gen, algorithm_machines, sign as sign_test}
}; };
@ -80,7 +80,7 @@ pub(crate) fn core_batch_verify<R: RngCore + CryptoRng, C: Curve>(rng: &mut R) {
fn sign_core<R: RngCore + CryptoRng, C: Curve>( fn sign_core<R: RngCore + CryptoRng, C: Curve>(
rng: &mut R, rng: &mut R,
group_key: C::G, group_key: C::G,
keys: &HashMap<u16, Arc<MultisigKeys<C>>> keys: &HashMap<u16, Arc<FrostKeys<C>>>
) { ) {
const MESSAGE: &'static [u8] = b"Hello, World!"; const MESSAGE: &'static [u8] = b"Hello, World!";

View file

@ -3,7 +3,7 @@ use std::{sync::Arc, collections::HashMap};
use rand_core::{RngCore, CryptoRng}; use rand_core::{RngCore, CryptoRng};
use crate::{ use crate::{
Curve, MultisigKeys, Curve, FrostKeys,
algorithm::{Schnorr, Hram}, algorithm::{Schnorr, Hram},
sign::{PreprocessPackage, SignMachine, SignatureMachine, AlgorithmMachine}, sign::{PreprocessPackage, SignMachine, SignatureMachine, AlgorithmMachine},
tests::{curve::test_curve, schnorr::test_schnorr, recover} tests::{curve::test_curve, schnorr::test_schnorr, recover}
@ -22,8 +22,8 @@ pub struct Vectors {
pub sig: String pub sig: String
} }
// Load these vectors into MultisigKeys using a custom serialization it'll deserialize // Load these vectors into FrostKeys using a custom serialization it'll deserialize
fn vectors_to_multisig_keys<C: Curve>(vectors: &Vectors) -> HashMap<u16, MultisigKeys<C>> { fn vectors_to_multisig_keys<C: Curve>(vectors: &Vectors) -> HashMap<u16, FrostKeys<C>> {
let shares = vectors.shares.iter().map( let shares = vectors.shares.iter().map(
|secret| C::F_from_slice(&hex::decode(secret).unwrap()).unwrap() |secret| C::F_from_slice(&hex::decode(secret).unwrap()).unwrap()
).collect::<Vec<_>>(); ).collect::<Vec<_>>();
@ -45,7 +45,7 @@ fn vectors_to_multisig_keys<C: Curve>(vectors: &Vectors) -> HashMap<u16, Multisi
serialized.extend(&C::G_to_bytes(share)); serialized.extend(&C::G_to_bytes(share));
} }
let these_keys = MultisigKeys::<C>::deserialize(&serialized).unwrap(); let these_keys = FrostKeys::<C>::deserialize(&serialized).unwrap();
assert_eq!(these_keys.params().t(), vectors.threshold); assert_eq!(these_keys.params().t(), vectors.threshold);
assert_eq!(usize::from(these_keys.params().n()), shares.len()); assert_eq!(usize::from(these_keys.params().n()), shares.len());
assert_eq!(these_keys.params().i(), i); assert_eq!(these_keys.params().i(), i);

View file

@ -4,7 +4,7 @@ use async_trait::async_trait;
use thiserror::Error; use thiserror::Error;
use transcript::RecommendedTranscript; use transcript::RecommendedTranscript;
use frost::{curve::Curve, MultisigKeys, sign::PreprocessMachine}; use frost::{curve::Curve, FrostKeys, sign::PreprocessMachine};
pub mod monero; pub mod monero;
pub use self::monero::Monero; pub use self::monero::Monero;
@ -57,7 +57,7 @@ pub trait Coin {
async fn prepare_send( async fn prepare_send(
&self, &self,
keys: Arc<MultisigKeys<Self::Curve>>, keys: Arc<FrostKeys<Self::Curve>>,
transcript: RecommendedTranscript, transcript: RecommendedTranscript,
height: usize, height: usize,
inputs: Vec<Self::Output>, inputs: Vec<Self::Output>,

View file

@ -6,7 +6,7 @@ use curve25519_dalek::scalar::Scalar;
use dalek_ff_group as dfg; use dalek_ff_group as dfg;
use transcript::RecommendedTranscript; use transcript::RecommendedTranscript;
use frost::{curve::Ed25519, MultisigKeys}; use frost::{curve::Ed25519, FrostKeys};
use monero_serai::{ use monero_serai::{
transaction::{Timelock, Transaction}, transaction::{Timelock, Transaction},
@ -52,7 +52,7 @@ impl From<SpendableOutput> for Output {
#[derive(Debug)] #[derive(Debug)]
pub struct SignableTransaction( pub struct SignableTransaction(
Arc<MultisigKeys<Ed25519>>, Arc<FrostKeys<Ed25519>>,
RecommendedTranscript, RecommendedTranscript,
usize, usize,
MSignableTransaction MSignableTransaction
@ -140,7 +140,7 @@ impl Coin for Monero {
async fn prepare_send( async fn prepare_send(
&self, &self,
keys: Arc<MultisigKeys<Ed25519>>, keys: Arc<FrostKeys<Ed25519>>,
transcript: RecommendedTranscript, transcript: RecommendedTranscript,
height: usize, height: usize,
mut inputs: Vec<Output>, mut inputs: Vec<Output>,

View file

@ -4,17 +4,17 @@ use rand_core::OsRng;
use transcript::{Transcript, RecommendedTranscript}; use transcript::{Transcript, RecommendedTranscript};
use frost::{curve::Curve, MultisigKeys, sign::{PreprocessMachine, SignMachine, SignatureMachine}}; use frost::{curve::Curve, FrostKeys, sign::{PreprocessMachine, SignMachine, SignatureMachine}};
use crate::{coin::{CoinError, Output, Coin}, SignError, Network}; use crate::{coin::{CoinError, Output, Coin}, SignError, Network};
pub struct WalletKeys<C: Curve> { pub struct WalletKeys<C: Curve> {
keys: MultisigKeys<C>, keys: FrostKeys<C>,
creation_height: usize creation_height: usize
} }
impl<C: Curve> WalletKeys<C> { impl<C: Curve> WalletKeys<C> {
pub fn new(keys: MultisigKeys<C>, creation_height: usize) -> WalletKeys<C> { pub fn new(keys: FrostKeys<C>, creation_height: usize) -> WalletKeys<C> {
WalletKeys { keys, creation_height } WalletKeys { keys, creation_height }
} }
@ -26,7 +26,7 @@ impl<C: Curve> WalletKeys<C> {
// system, there are potentially other benefits to binding this to a specific group key // system, there are potentially other benefits to binding this to a specific group key
// It's no longer possible to influence group key gen to key cancel without breaking the hash // It's no longer possible to influence group key gen to key cancel without breaking the hash
// function as well, although that degree of influence means key gen is broken already // function as well, although that degree of influence means key gen is broken already
fn bind(&self, chain: &[u8]) -> MultisigKeys<C> { fn bind(&self, chain: &[u8]) -> FrostKeys<C> {
const DST: &[u8] = b"Serai Processor Wallet Chain Bind"; const DST: &[u8] = b"Serai Processor Wallet Chain Bind";
let mut transcript = RecommendedTranscript::new(DST); let mut transcript = RecommendedTranscript::new(DST);
transcript.append_message(b"chain", chain); transcript.append_message(b"chain", chain);
@ -200,8 +200,8 @@ fn select_inputs_outputs<C: Coin>(
pub struct Wallet<D: CoinDb, C: Coin> { pub struct Wallet<D: CoinDb, C: Coin> {
db: D, db: D,
coin: C, coin: C,
keys: Vec<(Arc<MultisigKeys<C::Curve>>, Vec<C::Output>)>, keys: Vec<(Arc<FrostKeys<C::Curve>>, Vec<C::Output>)>,
pending: Vec<(usize, MultisigKeys<C::Curve>)> pending: Vec<(usize, FrostKeys<C::Curve>)>
} }
impl<D: CoinDb, C: Coin> Wallet<D, C> { impl<D: CoinDb, C: Coin> Wallet<D, C> {