mirror of
https://github.com/serai-dex/serai.git
synced 2025-01-09 12:29:27 +00:00
Reorganize FROST's handling of curves
This commit is contained in:
parent
6775fb471e
commit
60254a0171
18 changed files with 165 additions and 154 deletions
|
@ -10,8 +10,7 @@ use curve25519_dalek::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use transcript::{Transcript, RecommendedTranscript};
|
use transcript::{Transcript, RecommendedTranscript};
|
||||||
use frost::curves::Curve;
|
use frost::curve::{Curve, Ed25519};
|
||||||
pub use frost::curves::dalek::Ed25519;
|
|
||||||
use dalek_ff_group as dfg;
|
use dalek_ff_group as dfg;
|
||||||
|
|
||||||
use crate::random_scalar;
|
use crate::random_scalar;
|
||||||
|
|
|
@ -14,12 +14,12 @@ use curve25519_dalek::{
|
||||||
use group::Group;
|
use group::Group;
|
||||||
|
|
||||||
use transcript::{Transcript, RecommendedTranscript};
|
use transcript::{Transcript, RecommendedTranscript};
|
||||||
use frost::{FrostError, MultisigView, algorithm::Algorithm};
|
use frost::{curve::Ed25519, FrostError, MultisigView, algorithm::Algorithm};
|
||||||
use dalek_ff_group as dfg;
|
use dalek_ff_group as dfg;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
hash_to_point,
|
hash_to_point,
|
||||||
frost::{MultisigError, Ed25519, DLEqProof, read_dleq},
|
frost::{MultisigError, DLEqProof, read_dleq},
|
||||||
ringct::clsag::{ClsagInput, Clsag}
|
ringct::clsag::{ClsagInput, Clsag}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,8 @@ use curve25519_dalek::{constants::ED25519_BASEPOINT_TABLE, scalar::Scalar};
|
||||||
|
|
||||||
#[cfg(feature = "multisig")]
|
#[cfg(feature = "multisig")]
|
||||||
use transcript::RecommendedTranscript;
|
use transcript::RecommendedTranscript;
|
||||||
|
#[cfg(feature = "multisig")]
|
||||||
|
use frost::curve::Ed25519;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
Commitment,
|
Commitment,
|
||||||
|
@ -15,7 +17,7 @@ use crate::{
|
||||||
ringct::clsag::{ClsagInput, Clsag}
|
ringct::clsag::{ClsagInput, Clsag}
|
||||||
};
|
};
|
||||||
#[cfg(feature = "multisig")]
|
#[cfg(feature = "multisig")]
|
||||||
use crate::{frost::{Ed25519, MultisigError}, ringct::clsag::{ClsagDetails, ClsagMultisig}};
|
use crate::{frost::MultisigError, ringct::clsag::{ClsagDetails, ClsagMultisig}};
|
||||||
|
|
||||||
#[cfg(feature = "multisig")]
|
#[cfg(feature = "multisig")]
|
||||||
use frost::tests::{key_gen, algorithm_machines, sign};
|
use frost::tests::{key_gen, algorithm_machines, sign};
|
||||||
|
|
|
@ -7,6 +7,7 @@ use curve25519_dalek::{traits::Identity, scalar::Scalar, edwards::{EdwardsPoint,
|
||||||
|
|
||||||
use transcript::{Transcript, RecommendedTranscript};
|
use transcript::{Transcript, RecommendedTranscript};
|
||||||
use frost::{
|
use frost::{
|
||||||
|
curve::Ed25519,
|
||||||
FrostError, MultisigKeys,
|
FrostError, MultisigKeys,
|
||||||
sign::{
|
sign::{
|
||||||
PreprocessMachine, SignMachine, SignatureMachine,
|
PreprocessMachine, SignMachine, SignatureMachine,
|
||||||
|
@ -15,7 +16,6 @@ use frost::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
frost::Ed25519,
|
|
||||||
random_scalar, ringct::{clsag::{ClsagInput, ClsagDetails, ClsagMultisig}, bulletproofs::Bulletproofs, RctPrunable},
|
random_scalar, ringct::{clsag::{ClsagInput, ClsagDetails, ClsagMultisig}, bulletproofs::Bulletproofs, RctPrunable},
|
||||||
transaction::{Input, Transaction},
|
transaction::{Input, Transaction},
|
||||||
rpc::Rpc,
|
rpc::Rpc,
|
||||||
|
|
|
@ -14,7 +14,9 @@ use curve25519_dalek::constants::ED25519_BASEPOINT_TABLE;
|
||||||
#[cfg(feature = "multisig")]
|
#[cfg(feature = "multisig")]
|
||||||
use dalek_ff_group::Scalar;
|
use dalek_ff_group::Scalar;
|
||||||
#[cfg(feature = "multisig")]
|
#[cfg(feature = "multisig")]
|
||||||
use frost::tests::{THRESHOLD, key_gen, sign};
|
use transcript::RecommendedTranscript;
|
||||||
|
#[cfg(feature = "multisig")]
|
||||||
|
use frost::{curve::Ed25519, tests::{THRESHOLD, key_gen, sign}};
|
||||||
|
|
||||||
use monero::{
|
use monero::{
|
||||||
network::Network,
|
network::Network,
|
||||||
|
@ -26,11 +28,6 @@ use monero_serai::{random_scalar, wallet::SignableTransaction};
|
||||||
mod rpc;
|
mod rpc;
|
||||||
use crate::rpc::{rpc, mine_block};
|
use crate::rpc::{rpc, mine_block};
|
||||||
|
|
||||||
#[cfg(feature = "multisig")]
|
|
||||||
use transcript::RecommendedTranscript;
|
|
||||||
#[cfg(feature = "multisig")]
|
|
||||||
use monero_serai::frost::Ed25519;
|
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref SEQUENTIAL: Mutex<()> = Mutex::new(());
|
static ref SEQUENTIAL: Mutex<()> = Mutex::new(());
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ use group::{ff::PrimeField, Group};
|
||||||
|
|
||||||
use dalek_ff_group::Scalar;
|
use dalek_ff_group::Scalar;
|
||||||
|
|
||||||
use crate::{CurveError, Curve, algorithm::Hram};
|
use crate::{curve::{CurveError, Curve}, algorithm::Hram};
|
||||||
|
|
||||||
macro_rules! dalek_curve {
|
macro_rules! dalek_curve {
|
||||||
(
|
(
|
||||||
|
@ -125,22 +125,6 @@ macro_rules! dalek_curve {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "ed25519")]
|
|
||||||
dalek_curve!(
|
|
||||||
Ed25519,
|
|
||||||
IetfEd25519Hram,
|
|
||||||
EdwardsPoint,
|
|
||||||
CompressedEdwardsY,
|
|
||||||
EdwardsBasepointTable,
|
|
||||||
ED25519_BASEPOINT_POINT,
|
|
||||||
ED25519_BASEPOINT_TABLE,
|
|
||||||
|point: EdwardsPoint| !bool::from(point.is_torsion_free()),
|
|
||||||
b"edwards25519",
|
|
||||||
b"",
|
|
||||||
b"",
|
|
||||||
b"",
|
|
||||||
);
|
|
||||||
|
|
||||||
#[cfg(any(test, feature = "ristretto"))]
|
#[cfg(any(test, feature = "ristretto"))]
|
||||||
dalek_curve!(
|
dalek_curve!(
|
||||||
Ristretto,
|
Ristretto,
|
||||||
|
@ -156,3 +140,19 @@ dalek_curve!(
|
||||||
b"chal",
|
b"chal",
|
||||||
b"digest",
|
b"digest",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
#[cfg(feature = "ed25519")]
|
||||||
|
dalek_curve!(
|
||||||
|
Ed25519,
|
||||||
|
IetfEd25519Hram,
|
||||||
|
EdwardsPoint,
|
||||||
|
CompressedEdwardsY,
|
||||||
|
EdwardsBasepointTable,
|
||||||
|
ED25519_BASEPOINT_POINT,
|
||||||
|
ED25519_BASEPOINT_TABLE,
|
||||||
|
|point: EdwardsPoint| !bool::from(point.is_torsion_free()),
|
||||||
|
b"edwards25519",
|
||||||
|
b"",
|
||||||
|
b"",
|
||||||
|
b"",
|
||||||
|
);
|
|
@ -8,7 +8,7 @@ use group::{ff::{Field, PrimeField}, Group, GroupEncoding};
|
||||||
|
|
||||||
use elliptic_curve::{bigint::{Encoding, U384}, hash2curve::{Expander, ExpandMsg, ExpandMsgXmd}};
|
use elliptic_curve::{bigint::{Encoding, U384}, hash2curve::{Expander, ExpandMsg, ExpandMsgXmd}};
|
||||||
|
|
||||||
use crate::{curves::{CurveError, Curve}, algorithm::Hram};
|
use crate::{curve::{CurveError, Curve}, algorithm::Hram};
|
||||||
|
|
||||||
macro_rules! kp_curve {
|
macro_rules! kp_curve {
|
||||||
(
|
(
|
121
crypto/frost/src/curve/mod.rs
Normal file
121
crypto/frost/src/curve/mod.rs
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
use core::{ops::Mul, fmt::Debug};
|
||||||
|
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
|
use rand_core::{RngCore, CryptoRng};
|
||||||
|
|
||||||
|
use group::{ff::PrimeField, Group, GroupOps};
|
||||||
|
|
||||||
|
#[cfg(any(test, feature = "dalek"))]
|
||||||
|
mod dalek;
|
||||||
|
#[cfg(any(test, feature = "ristretto"))]
|
||||||
|
pub use dalek::{Ristretto, IetfRistrettoHram};
|
||||||
|
#[cfg(feature = "ed25519")]
|
||||||
|
pub use dalek::{Ed25519, IetfEd25519Hram};
|
||||||
|
|
||||||
|
#[cfg(feature = "kp256")]
|
||||||
|
mod kp256;
|
||||||
|
#[cfg(feature = "secp256k1")]
|
||||||
|
pub use kp256::{Secp256k1, NonIetfSecp256k1Hram};
|
||||||
|
#[cfg(feature = "p256")]
|
||||||
|
pub use kp256::{P256, IetfP256Hram};
|
||||||
|
|
||||||
|
/// Set of errors for curve-related operations, namely encoding and decoding
|
||||||
|
#[derive(Clone, Error, Debug)]
|
||||||
|
pub enum CurveError {
|
||||||
|
#[error("invalid length for data (expected {0}, got {0})")]
|
||||||
|
InvalidLength(usize, usize),
|
||||||
|
#[error("invalid scalar")]
|
||||||
|
InvalidScalar,
|
||||||
|
#[error("invalid point")]
|
||||||
|
InvalidPoint,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Unified trait to manage a field/group
|
||||||
|
// This should be moved into its own crate if the need for generic cryptography over ff/group
|
||||||
|
// continues, which is the exact reason ff/group exists (to provide a generic interface)
|
||||||
|
// elliptic-curve exists, yet it doesn't really serve the same role, nor does it use &[u8]/Vec<u8>
|
||||||
|
// It uses GenericArray which will hopefully be deprecated as Rust evolves and doesn't offer enough
|
||||||
|
// advantages in the modern day to be worth the hassle -- Kayaba
|
||||||
|
pub trait Curve: Clone + Copy + PartialEq + Eq + Debug {
|
||||||
|
/// Scalar field element type
|
||||||
|
// This is available via G::Scalar yet `C::G::Scalar` is ambiguous, forcing horrific accesses
|
||||||
|
type F: PrimeField;
|
||||||
|
/// Group element type
|
||||||
|
type G: Group<Scalar = Self::F> + GroupOps;
|
||||||
|
/// Precomputed table type
|
||||||
|
type T: Mul<Self::F, Output = Self::G>;
|
||||||
|
|
||||||
|
/// ID for this curve
|
||||||
|
const ID: &'static [u8];
|
||||||
|
|
||||||
|
/// Generator for the group
|
||||||
|
// While group does provide this in its API, privacy coins will want to use a custom basepoint
|
||||||
|
const GENERATOR: Self::G;
|
||||||
|
|
||||||
|
/// Table for the generator for the group
|
||||||
|
/// If there isn't a precomputed table available, the generator itself should be used
|
||||||
|
const GENERATOR_TABLE: Self::T;
|
||||||
|
|
||||||
|
/// If little endian is used for the scalar field's Repr
|
||||||
|
const LITTLE_ENDIAN: bool;
|
||||||
|
|
||||||
|
/// Securely generate a random nonce. H4 from the IETF draft
|
||||||
|
fn random_nonce<R: RngCore + CryptoRng>(secret: Self::F, rng: &mut R) -> Self::F;
|
||||||
|
|
||||||
|
/// Hash the message for the binding factor. H3 from the IETF draft
|
||||||
|
// This doesn't actually need to be part of Curve as it does nothing with the curve
|
||||||
|
// This also solely relates to FROST and with a proper Algorithm/HRAM, all projects using
|
||||||
|
// aggregatable signatures over this curve will work without issue
|
||||||
|
// It is kept here as Curve + H{1, 2, 3} is effectively a ciphersuite according to the IETF draft
|
||||||
|
// and moving it to Schnorr would force all of them into being ciphersuite-specific
|
||||||
|
// H2 is left to the Schnorr Algorithm as H2 is the H used in HRAM, which Schnorr further
|
||||||
|
// modularizes
|
||||||
|
fn hash_msg(msg: &[u8]) -> Vec<u8>;
|
||||||
|
|
||||||
|
/// Hash the commitments and message to calculate the binding factor. H1 from the IETF draft
|
||||||
|
fn hash_binding_factor(binding: &[u8]) -> Self::F;
|
||||||
|
|
||||||
|
// The following methods would optimally be F:: and G:: yet developers can't control F/G
|
||||||
|
// They can control a trait they pass into this library
|
||||||
|
|
||||||
|
/// Field element from hash. Used during key gen and by other crates under Serai as a general
|
||||||
|
/// utility
|
||||||
|
// Not parameterized by Digest as it's fine for it to use its own hash function as relevant to
|
||||||
|
// hash_msg and hash_binding_factor
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
fn hash_to_F(dst: &[u8], msg: &[u8]) -> Self::F;
|
||||||
|
|
||||||
|
/// Constant size of a serialized scalar field element
|
||||||
|
// The alternative way to grab this would be either serializing a junk element and getting its
|
||||||
|
// length or doing a naive division of its BITS property by 8 and assuming a lack of padding
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
fn F_len() -> usize;
|
||||||
|
|
||||||
|
/// Constant size of a serialized group element
|
||||||
|
// We could grab the serialization as described above yet a naive developer may use a
|
||||||
|
// non-constant size encoding, proving yet another reason to force this to be a provided constant
|
||||||
|
// A naive developer could still provide a constant for a variable length encoding, yet at least
|
||||||
|
// that is on them
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
fn G_len() -> usize;
|
||||||
|
|
||||||
|
/// Field element from slice. Preferred to be canonical yet does not have to be
|
||||||
|
// Required due to the lack of standardized encoding functions provided by ff/group
|
||||||
|
// While they do technically exist, their usage of Self::Repr breaks all potential library usage
|
||||||
|
// without helper functions like this
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
fn F_from_slice(slice: &[u8]) -> Result<Self::F, CurveError>;
|
||||||
|
|
||||||
|
/// Group element from slice. Must require canonicity or risks differing binding factors
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
fn G_from_slice(slice: &[u8]) -> Result<Self::G, CurveError>;
|
||||||
|
|
||||||
|
/// Obtain a vector of the byte encoding of F
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
fn F_to_bytes(f: &Self::F) -> Vec<u8>;
|
||||||
|
|
||||||
|
/// Obtain a vector of the byte encoding of G
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
fn G_to_bytes(g: &Self::G) -> Vec<u8>;
|
||||||
|
}
|
|
@ -1,5 +0,0 @@
|
||||||
#[cfg(any(test, feature = "dalek"))]
|
|
||||||
pub mod dalek;
|
|
||||||
|
|
||||||
#[cfg(feature = "kp256")]
|
|
||||||
pub mod kp256;
|
|
|
@ -7,7 +7,8 @@ use group::ff::{Field, PrimeField};
|
||||||
use multiexp::{multiexp_vartime, BatchVerifier};
|
use multiexp::{multiexp_vartime, BatchVerifier};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
Curve, MultisigParams, MultisigKeys, FrostError,
|
curve::Curve,
|
||||||
|
FrostError, MultisigParams, MultisigKeys,
|
||||||
schnorr::{self, SchnorrSignature},
|
schnorr::{self, SchnorrSignature},
|
||||||
validate_map
|
validate_map
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,122 +1,20 @@
|
||||||
use core::{ops::Mul, fmt::Debug};
|
use core::fmt::Debug;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
use rand_core::{RngCore, CryptoRng};
|
use group::ff::{Field, PrimeField};
|
||||||
|
|
||||||
use group::{ff::{Field, PrimeField}, Group, GroupOps};
|
|
||||||
|
|
||||||
mod schnorr;
|
mod schnorr;
|
||||||
|
|
||||||
|
pub mod curve;
|
||||||
|
use curve::Curve;
|
||||||
pub mod key_gen;
|
pub mod key_gen;
|
||||||
pub mod algorithm;
|
pub mod algorithm;
|
||||||
pub mod sign;
|
pub mod sign;
|
||||||
#[cfg(any(test, feature = "curves"))]
|
|
||||||
pub mod curves;
|
|
||||||
|
|
||||||
pub mod tests;
|
pub mod tests;
|
||||||
|
|
||||||
/// Set of errors for curve-related operations, namely encoding and decoding
|
|
||||||
#[derive(Clone, Error, Debug)]
|
|
||||||
pub enum CurveError {
|
|
||||||
#[error("invalid length for data (expected {0}, got {0})")]
|
|
||||||
InvalidLength(usize, usize),
|
|
||||||
#[error("invalid scalar")]
|
|
||||||
InvalidScalar,
|
|
||||||
#[error("invalid point")]
|
|
||||||
InvalidPoint,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Unified trait to manage a field/group
|
|
||||||
// This should be moved into its own crate if the need for generic cryptography over ff/group
|
|
||||||
// continues, which is the exact reason ff/group exists (to provide a generic interface)
|
|
||||||
// elliptic-curve exists, yet it doesn't really serve the same role, nor does it use &[u8]/Vec<u8>
|
|
||||||
// It uses GenericArray which will hopefully be deprecated as Rust evolves and doesn't offer enough
|
|
||||||
// advantages in the modern day to be worth the hassle -- Kayaba
|
|
||||||
pub trait Curve: Clone + Copy + PartialEq + Eq + Debug {
|
|
||||||
/// Scalar field element type
|
|
||||||
// This is available via G::Scalar yet `C::G::Scalar` is ambiguous, forcing horrific accesses
|
|
||||||
type F: PrimeField;
|
|
||||||
/// Group element type
|
|
||||||
type G: Group<Scalar = Self::F> + GroupOps;
|
|
||||||
/// Precomputed table type
|
|
||||||
type T: Mul<Self::F, Output = Self::G>;
|
|
||||||
|
|
||||||
/// ID for this curve
|
|
||||||
const ID: &'static [u8];
|
|
||||||
|
|
||||||
/// Generator for the group
|
|
||||||
// While group does provide this in its API, privacy coins will want to use a custom basepoint
|
|
||||||
const GENERATOR: Self::G;
|
|
||||||
|
|
||||||
/// Table for the generator for the group
|
|
||||||
/// If there isn't a precomputed table available, the generator itself should be used
|
|
||||||
const GENERATOR_TABLE: Self::T;
|
|
||||||
|
|
||||||
/// If little endian is used for the scalar field's Repr
|
|
||||||
const LITTLE_ENDIAN: bool;
|
|
||||||
|
|
||||||
/// Securely generate a random nonce. H4 from the IETF draft
|
|
||||||
fn random_nonce<R: RngCore + CryptoRng>(secret: Self::F, rng: &mut R) -> Self::F;
|
|
||||||
|
|
||||||
/// Hash the message for the binding factor. H3 from the IETF draft
|
|
||||||
// This doesn't actually need to be part of Curve as it does nothing with the curve
|
|
||||||
// This also solely relates to FROST and with a proper Algorithm/HRAM, all projects using
|
|
||||||
// aggregatable signatures over this curve will work without issue
|
|
||||||
// It is kept here as Curve + H{1, 2, 3} is effectively a ciphersuite according to the IETF draft
|
|
||||||
// and moving it to Schnorr would force all of them into being ciphersuite-specific
|
|
||||||
// H2 is left to the Schnorr Algorithm as H2 is the H used in HRAM, which Schnorr further
|
|
||||||
// modularizes
|
|
||||||
fn hash_msg(msg: &[u8]) -> Vec<u8>;
|
|
||||||
|
|
||||||
/// Hash the commitments and message to calculate the binding factor. H1 from the IETF draft
|
|
||||||
fn hash_binding_factor(binding: &[u8]) -> Self::F;
|
|
||||||
|
|
||||||
// The following methods would optimally be F:: and G:: yet developers can't control F/G
|
|
||||||
// They can control a trait they pass into this library
|
|
||||||
|
|
||||||
/// Field element from hash. Used during key gen and by other crates under Serai as a general
|
|
||||||
/// utility
|
|
||||||
// Not parameterized by Digest as it's fine for it to use its own hash function as relevant to
|
|
||||||
// hash_msg and hash_binding_factor
|
|
||||||
#[allow(non_snake_case)]
|
|
||||||
fn hash_to_F(dst: &[u8], msg: &[u8]) -> Self::F;
|
|
||||||
|
|
||||||
/// Constant size of a serialized scalar field element
|
|
||||||
// The alternative way to grab this would be either serializing a junk element and getting its
|
|
||||||
// length or doing a naive division of its BITS property by 8 and assuming a lack of padding
|
|
||||||
#[allow(non_snake_case)]
|
|
||||||
fn F_len() -> usize;
|
|
||||||
|
|
||||||
/// Constant size of a serialized group element
|
|
||||||
// We could grab the serialization as described above yet a naive developer may use a
|
|
||||||
// non-constant size encoding, proving yet another reason to force this to be a provided constant
|
|
||||||
// A naive developer could still provide a constant for a variable length encoding, yet at least
|
|
||||||
// that is on them
|
|
||||||
#[allow(non_snake_case)]
|
|
||||||
fn G_len() -> usize;
|
|
||||||
|
|
||||||
/// Field element from slice. Preferred to be canonical yet does not have to be
|
|
||||||
// Required due to the lack of standardized encoding functions provided by ff/group
|
|
||||||
// While they do technically exist, their usage of Self::Repr breaks all potential library usage
|
|
||||||
// without helper functions like this
|
|
||||||
#[allow(non_snake_case)]
|
|
||||||
fn F_from_slice(slice: &[u8]) -> Result<Self::F, CurveError>;
|
|
||||||
|
|
||||||
/// Group element from slice. Must require canonicity or risks differing binding factors
|
|
||||||
#[allow(non_snake_case)]
|
|
||||||
fn G_from_slice(slice: &[u8]) -> Result<Self::G, CurveError>;
|
|
||||||
|
|
||||||
/// Obtain a vector of the byte encoding of F
|
|
||||||
#[allow(non_snake_case)]
|
|
||||||
fn F_to_bytes(f: &Self::F) -> Vec<u8>;
|
|
||||||
|
|
||||||
/// Obtain a vector of the byte encoding of G
|
|
||||||
#[allow(non_snake_case)]
|
|
||||||
fn G_to_bytes(g: &Self::G) -> Vec<u8>;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 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)]
|
||||||
|
|
|
@ -8,7 +8,7 @@ use group::ff::Field;
|
||||||
use transcript::Transcript;
|
use transcript::Transcript;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
Curve,
|
curve::Curve,
|
||||||
FrostError,
|
FrostError,
|
||||||
MultisigParams, MultisigKeys, MultisigView,
|
MultisigParams, MultisigKeys, MultisigView,
|
||||||
algorithm::Algorithm,
|
algorithm::Algorithm,
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
use rand::rngs::OsRng;
|
use rand::rngs::OsRng;
|
||||||
|
|
||||||
use crate::{curves::dalek, tests::vectors::{Vectors, test_with_vectors}};
|
use crate::{curve, tests::vectors::{Vectors, test_with_vectors}};
|
||||||
|
|
||||||
#[cfg(any(test, feature = "ristretto"))]
|
#[cfg(any(test, feature = "ristretto"))]
|
||||||
#[test]
|
#[test]
|
||||||
fn ristretto_vectors() {
|
fn ristretto_vectors() {
|
||||||
test_with_vectors::<_, dalek::Ristretto, dalek::IetfRistrettoHram>(
|
test_with_vectors::<_, curve::Ristretto, curve::IetfRistrettoHram>(
|
||||||
&mut OsRng,
|
&mut OsRng,
|
||||||
Vectors {
|
Vectors {
|
||||||
threshold: 2,
|
threshold: 2,
|
||||||
|
@ -42,7 +42,7 @@ fn ristretto_vectors() {
|
||||||
#[cfg(feature = "ed25519")]
|
#[cfg(feature = "ed25519")]
|
||||||
#[test]
|
#[test]
|
||||||
fn ed25519_vectors() {
|
fn ed25519_vectors() {
|
||||||
test_with_vectors::<_, dalek::Ed25519, dalek::IetfEd25519Hram>(
|
test_with_vectors::<_, curve::Ed25519, curve::IetfEd25519Hram>(
|
||||||
&mut OsRng,
|
&mut OsRng,
|
||||||
Vectors {
|
Vectors {
|
||||||
threshold: 2,
|
threshold: 2,
|
||||||
|
|
|
@ -3,12 +3,12 @@ use rand::rngs::OsRng;
|
||||||
#[cfg(feature = "secp256k1")]
|
#[cfg(feature = "secp256k1")]
|
||||||
use crate::tests::{curve::test_curve, schnorr::test_schnorr};
|
use crate::tests::{curve::test_curve, schnorr::test_schnorr};
|
||||||
#[cfg(feature = "secp256k1")]
|
#[cfg(feature = "secp256k1")]
|
||||||
use crate::curves::kp256::Secp256k1;
|
use crate::curve::Secp256k1;
|
||||||
|
|
||||||
#[cfg(feature = "p256")]
|
#[cfg(feature = "p256")]
|
||||||
use crate::tests::vectors::{Vectors, test_with_vectors};
|
use crate::tests::vectors::{Vectors, test_with_vectors};
|
||||||
#[cfg(feature = "p256")]
|
#[cfg(feature = "p256")]
|
||||||
use crate::curves::kp256::{P256, IetfP256Hram};
|
use crate::curve::{P256, IetfP256Hram};
|
||||||
|
|
||||||
#[cfg(feature = "secp256k1")]
|
#[cfg(feature = "secp256k1")]
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -6,11 +6,10 @@ use curve25519_dalek::{constants::ED25519_BASEPOINT_TABLE, scalar::Scalar};
|
||||||
|
|
||||||
use dalek_ff_group as dfg;
|
use dalek_ff_group as dfg;
|
||||||
use transcript::RecommendedTranscript;
|
use transcript::RecommendedTranscript;
|
||||||
use frost::MultisigKeys;
|
use frost::{curve::Ed25519, MultisigKeys};
|
||||||
|
|
||||||
use monero::{PublicKey, network::Network, util::address::Address};
|
use monero::{PublicKey, network::Network, util::address::Address};
|
||||||
use monero_serai::{
|
use monero_serai::{
|
||||||
frost::Ed25519,
|
|
||||||
transaction::{Timelock, Transaction},
|
transaction::{Timelock, Transaction},
|
||||||
rpc::Rpc,
|
rpc::Rpc,
|
||||||
wallet::{Fee, SpendableOutput, SignableTransaction as MSignableTransaction, TransactionMachine}
|
wallet::{Fee, SpendableOutput, SignableTransaction as MSignableTransaction, TransactionMachine}
|
||||||
|
|
|
@ -3,9 +3,8 @@ use std::{marker::Send, sync::Arc, collections::HashMap};
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
use frost::{Curve, FrostError, MultisigKeys, sign::PreprocessMachine};
|
|
||||||
|
|
||||||
use transcript::RecommendedTranscript;
|
use transcript::RecommendedTranscript;
|
||||||
|
use frost::{curve::Curve, FrostError, MultisigKeys, sign::PreprocessMachine};
|
||||||
|
|
||||||
mod coins;
|
mod coins;
|
||||||
mod wallet;
|
mod wallet;
|
||||||
|
|
|
@ -6,7 +6,7 @@ use rand::rngs::OsRng;
|
||||||
|
|
||||||
use group::Group;
|
use group::Group;
|
||||||
|
|
||||||
use frost::Curve;
|
use frost::curve::Curve;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
NetworkError, Network,
|
NetworkError, Network,
|
||||||
|
|
|
@ -4,7 +4,7 @@ use rand_core::OsRng;
|
||||||
|
|
||||||
use transcript::{Transcript, RecommendedTranscript};
|
use transcript::{Transcript, RecommendedTranscript};
|
||||||
|
|
||||||
use frost::{Curve, MultisigKeys, sign::{PreprocessMachine, SignMachine, SignatureMachine}};
|
use frost::{curve::Curve, MultisigKeys, sign::{PreprocessMachine, SignMachine, SignatureMachine}};
|
||||||
|
|
||||||
use crate::{CoinError, SignError, Output, Coin, Network};
|
use crate::{CoinError, SignError, Output, Coin, Network};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue