Supply a RecommendedTranscript type of DT<Blake2b512>

This commit is contained in:
Luke Parker
2022-06-24 18:58:24 -04:00
parent 963d9eab10
commit a46524f0ce
12 changed files with 40 additions and 31 deletions

View File

@@ -23,7 +23,7 @@ curve25519-dalek = { version = "3", features = ["std"] }
group = { version = "0.12", optional = true } group = { version = "0.12", optional = true }
dalek-ff-group = { path = "../../crypto/dalek-ff-group", optional = true } dalek-ff-group = { path = "../../crypto/dalek-ff-group", optional = true }
transcript = { package = "transcript-trait", path = "../../crypto/transcript", optional = true } transcript = { package = "transcript-trait", path = "../../crypto/transcript", features = ["recommended"], optional = true }
frost = { package = "modular-frost", path = "../../crypto/frost", features = ["ed25519"], optional = true } frost = { package = "modular-frost", path = "../../crypto/frost", features = ["ed25519"], optional = true }
monero = "0.16" monero = "0.16"

View File

@@ -9,15 +9,13 @@ use curve25519_dalek::{
edwards::EdwardsPoint as DPoint edwards::EdwardsPoint as DPoint
}; };
use transcript::{Transcript as TranscriptTrait, DigestTranscript}; use transcript::{Transcript, RecommendedTranscript};
use frost::Curve; use frost::curves::Curve;
pub use frost::curves::dalek::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;
pub type Transcript = DigestTranscript::<blake2::Blake2b512>;
#[derive(Clone, Error, Debug)] #[derive(Clone, Error, Debug)]
pub enum MultisigError { pub enum MultisigError {
#[error("internal error ({0})")] #[error("internal error ({0})")]
@@ -43,7 +41,7 @@ impl DLEqProof {
// the proper order if they want to reach consensus // the proper order if they want to reach consensus
// It'd be a poor API to have CLSAG define a new transcript solely to pass here, just to try to // It'd be a poor API to have CLSAG define a new transcript solely to pass here, just to try to
// merge later in some form, when it should instead just merge xH (as it does) // merge later in some form, when it should instead just merge xH (as it does)
let mut transcript = Transcript::new(b"DLEq Proof"); let mut transcript = RecommendedTranscript::new(b"DLEq Proof");
// Bit redundant, keeps things consistent // Bit redundant, keeps things consistent
transcript.domain_separate(b"DLEq"); transcript.domain_separate(b"DLEq");
// Doesn't include G which is constant, does include H which isn't, even though H manipulation // Doesn't include G which is constant, does include H which isn't, even though H manipulation

View File

@@ -13,18 +13,18 @@ use curve25519_dalek::{
use group::Group; use group::Group;
use transcript::Transcript as TranscriptTrait; use transcript::{Transcript, RecommendedTranscript};
use frost::{FrostError, MultisigView, algorithm::Algorithm}; use frost::{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::{Transcript, MultisigError, Ed25519, DLEqProof, read_dleq}, frost::{MultisigError, Ed25519, DLEqProof, read_dleq},
ringct::clsag::{ClsagInput, Clsag} ringct::clsag::{ClsagInput, Clsag}
}; };
impl ClsagInput { impl ClsagInput {
fn transcript<T: TranscriptTrait>(&self, transcript: &mut T) { fn transcript<T: Transcript>(&self, transcript: &mut T) {
// Doesn't domain separate as this is considered part of the larger CLSAG proof // Doesn't domain separate as this is considered part of the larger CLSAG proof
// Ring index // Ring index
@@ -72,7 +72,7 @@ struct Interim {
#[allow(non_snake_case)] #[allow(non_snake_case)]
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct ClsagMultisig { pub struct ClsagMultisig {
transcript: Transcript, transcript: RecommendedTranscript,
H: EdwardsPoint, H: EdwardsPoint,
// Merged here as CLSAG needs it, passing it would be a mess, yet having it beforehand requires a round // Merged here as CLSAG needs it, passing it would be a mess, yet having it beforehand requires a round
@@ -87,7 +87,7 @@ pub struct ClsagMultisig {
impl ClsagMultisig { impl ClsagMultisig {
pub fn new( pub fn new(
transcript: Transcript, transcript: RecommendedTranscript,
details: Arc<RwLock<Option<ClsagDetails>>> details: Arc<RwLock<Option<ClsagDetails>>>
) -> Result<ClsagMultisig, MultisigError> { ) -> Result<ClsagMultisig, MultisigError> {
Ok( Ok(
@@ -120,7 +120,7 @@ impl ClsagMultisig {
} }
impl Algorithm<Ed25519> for ClsagMultisig { impl Algorithm<Ed25519> for ClsagMultisig {
type Transcript = Transcript; type Transcript = RecommendedTranscript;
type Signature = (Clsag, EdwardsPoint); type Signature = (Clsag, EdwardsPoint);
fn preprocess_addendum<R: RngCore + CryptoRng>( fn preprocess_addendum<R: RngCore + CryptoRng>(

View File

@@ -5,6 +5,9 @@ use rand::{RngCore, rngs::OsRng};
use curve25519_dalek::{constants::ED25519_BASEPOINT_TABLE, scalar::Scalar}; use curve25519_dalek::{constants::ED25519_BASEPOINT_TABLE, scalar::Scalar};
#[cfg(feature = "multisig")]
use transcript::RecommendedTranscript;
use crate::{ use crate::{
Commitment, Commitment,
random_scalar, generate_key_image, random_scalar, generate_key_image,
@@ -12,7 +15,7 @@ use crate::{
ringct::clsag::{ClsagInput, Clsag} ringct::clsag::{ClsagInput, Clsag}
}; };
#[cfg(feature = "multisig")] #[cfg(feature = "multisig")]
use crate::{frost::{Ed25519, MultisigError, Transcript}, ringct::clsag::{ClsagDetails, ClsagMultisig}}; use crate::{frost::{Ed25519, 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};
@@ -96,7 +99,7 @@ fn clsag_multisig() -> Result<(), MultisigError> {
algorithm_machines( algorithm_machines(
&mut OsRng, &mut OsRng,
ClsagMultisig::new( ClsagMultisig::new(
Transcript::new(b"Monero Serai CLSAG Test"), RecommendedTranscript::new(b"Monero Serai CLSAG Test"),
Arc::new(RwLock::new(Some( Arc::new(RwLock::new(Some(
ClsagDetails::new( ClsagDetails::new(
ClsagInput::new( ClsagInput::new(

View File

@@ -5,7 +5,7 @@ use rand_chacha::ChaCha12Rng;
use curve25519_dalek::{traits::Identity, scalar::Scalar, edwards::{EdwardsPoint, CompressedEdwardsY}}; use curve25519_dalek::{traits::Identity, scalar::Scalar, edwards::{EdwardsPoint, CompressedEdwardsY}};
use transcript::Transcript as TranscriptTrait; use transcript::{Transcript, RecommendedTranscript};
use frost::{ use frost::{
FrostError, MultisigKeys, FrostError, MultisigKeys,
sign::{ sign::{
@@ -15,7 +15,7 @@ use frost::{
}; };
use crate::{ use crate::{
frost::{Transcript, Ed25519}, 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,
@@ -26,7 +26,7 @@ pub struct TransactionMachine {
signable: SignableTransaction, signable: SignableTransaction,
i: u16, i: u16,
included: Vec<u16>, included: Vec<u16>,
transcript: Transcript, transcript: RecommendedTranscript,
decoys: Vec<Decoys>, decoys: Vec<Decoys>,
@@ -38,7 +38,7 @@ pub struct TransactionSignMachine {
signable: SignableTransaction, signable: SignableTransaction,
i: u16, i: u16,
included: Vec<u16>, included: Vec<u16>,
transcript: Transcript, transcript: RecommendedTranscript,
decoys: Vec<Decoys>, decoys: Vec<Decoys>,
@@ -58,7 +58,7 @@ impl SignableTransaction {
self, self,
rpc: &Rpc, rpc: &Rpc,
keys: MultisigKeys<Ed25519>, keys: MultisigKeys<Ed25519>,
mut transcript: Transcript, mut transcript: RecommendedTranscript,
height: usize, height: usize,
mut included: Vec<u16> mut included: Vec<u16>
) -> Result<TransactionMachine, TransactionError> { ) -> Result<TransactionMachine, TransactionError> {

View File

@@ -27,7 +27,9 @@ mod rpc;
use crate::rpc::{rpc, mine_block}; use crate::rpc::{rpc, mine_block};
#[cfg(feature = "multisig")] #[cfg(feature = "multisig")]
use monero_serai::frost::{Transcript, Ed25519}; 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(());
@@ -147,7 +149,7 @@ async fn send_core(test: usize, multisig: bool) {
signable.clone().multisig( signable.clone().multisig(
&rpc, &rpc,
(*keys[&i]).clone(), (*keys[&i]).clone(),
Transcript::new(b"Monero Serai Test Transaction"), RecommendedTranscript::new(b"Monero Serai Test Transaction"),
rpc.get_height().await.unwrap() - 10, rpc.get_height().await.unwrap() - 10,
(1 ..= THRESHOLD).collect::<Vec<_>>() (1 ..= THRESHOLD).collect::<Vec<_>>()
).await.unwrap() ).await.unwrap()

View File

@@ -11,7 +11,9 @@ edition = "2021"
[dependencies] [dependencies]
digest = "0.10" digest = "0.10"
blake2 = { version = "0.10", optional = true }
merlin = { version = "3", optional = true } merlin = { version = "3", optional = true }
[features] [features]
recommended = ["blake2"]
merlin = ["dep:merlin"] merlin = ["dep:merlin"]

View File

@@ -74,3 +74,6 @@ impl<D: Digest + Clone> Transcript for DigestTranscript<D>
seed seed
} }
} }
#[cfg(feature = "recommended")]
pub type RecommendedTranscript = DigestTranscript<blake2::Blake2b512>;

View File

@@ -18,7 +18,7 @@ serde_json = "1.0"
curve25519-dalek = { version = "3", features = ["std"] } curve25519-dalek = { version = "3", features = ["std"] }
blake2 = "0.10" blake2 = "0.10"
transcript = { package = "transcript-trait", path = "../crypto/transcript" } transcript = { package = "transcript-trait", path = "../crypto/transcript", features = ["recommended"] }
dalek-ff-group = { path = "../crypto/dalek-ff-group" } dalek-ff-group = { path = "../crypto/dalek-ff-group" }
frost = { package = "modular-frost", path = "../crypto/frost" } frost = { package = "modular-frost", path = "../crypto/frost" }

View File

@@ -5,6 +5,7 @@ use async_trait::async_trait;
use curve25519_dalek::{constants::ED25519_BASEPOINT_TABLE, scalar::Scalar}; 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 frost::MultisigKeys; use frost::MultisigKeys;
use monero::{PublicKey, network::Network, util::address::Address}; use monero::{PublicKey, network::Network, util::address::Address};
@@ -15,7 +16,7 @@ use monero_serai::{
wallet::{Fee, SpendableOutput, SignableTransaction as MSignableTransaction, TransactionMachine} wallet::{Fee, SpendableOutput, SignableTransaction as MSignableTransaction, TransactionMachine}
}; };
use crate::{Transcript, CoinError, Output as OutputTrait, Coin, view_key}; use crate::{CoinError, Output as OutputTrait, Coin, view_key};
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Output(SpendableOutput); pub struct Output(SpendableOutput);
@@ -51,7 +52,7 @@ impl From<SpendableOutput> for Output {
#[derive(Debug)] #[derive(Debug)]
pub struct SignableTransaction( pub struct SignableTransaction(
Arc<MultisigKeys<Ed25519>>, Arc<MultisigKeys<Ed25519>>,
Transcript, RecommendedTranscript,
usize, usize,
MSignableTransaction MSignableTransaction
); );
@@ -129,7 +130,7 @@ impl Coin for Monero {
async fn prepare_send( async fn prepare_send(
&self, &self,
keys: Arc<MultisigKeys<Ed25519>>, keys: Arc<MultisigKeys<Ed25519>>,
transcript: Transcript, transcript: RecommendedTranscript,
height: usize, height: usize,
mut inputs: Vec<Output>, mut inputs: Vec<Output>,
payments: &[(Address, u64)], payments: &[(Address, u64)],

View File

@@ -5,7 +5,7 @@ use thiserror::Error;
use frost::{Curve, FrostError, MultisigKeys, sign::PreprocessMachine}; use frost::{Curve, FrostError, MultisigKeys, sign::PreprocessMachine};
pub(crate) use monero_serai::frost::Transcript; use transcript::RecommendedTranscript;
mod coins; mod coins;
mod wallet; mod wallet;
@@ -80,7 +80,7 @@ pub trait Coin {
async fn prepare_send( async fn prepare_send(
&self, &self,
keys: Arc<MultisigKeys<Self::Curve>>, keys: Arc<MultisigKeys<Self::Curve>>,
transcript: Transcript, transcript: RecommendedTranscript,
height: usize, height: usize,
inputs: Vec<Self::Output>, inputs: Vec<Self::Output>,
payments: &[(Self::Address, u64)], payments: &[(Self::Address, u64)],

View File

@@ -2,11 +2,11 @@ use std::{sync::Arc, collections::HashMap};
use rand_core::OsRng; use rand_core::OsRng;
use transcript::Transcript as TranscriptTrait; use transcript::{Transcript, RecommendedTranscript};
use frost::{Curve, MultisigKeys, sign::{PreprocessMachine, SignMachine, SignatureMachine}}; use frost::{Curve, MultisigKeys, sign::{PreprocessMachine, SignMachine, SignatureMachine}};
use crate::{Transcript, CoinError, SignError, Output, Coin, Network}; use crate::{CoinError, SignError, Output, Coin, Network};
pub struct WalletKeys<C: Curve> { pub struct WalletKeys<C: Curve> {
keys: MultisigKeys<C>, keys: MultisigKeys<C>,
@@ -28,7 +28,7 @@ impl<C: Curve> WalletKeys<C> {
// 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]) -> MultisigKeys<C> {
const DST: &[u8] = b"Serai Processor Wallet Chain Bind"; const DST: &[u8] = b"Serai Processor Wallet Chain Bind";
let mut transcript = Transcript::new(DST); let mut transcript = RecommendedTranscript::new(DST);
transcript.append_message(b"chain", chain); transcript.append_message(b"chain", chain);
transcript.append_message(b"curve", C::ID); transcript.append_message(b"curve", C::ID);
transcript.append_message(b"group_key", &C::G_to_bytes(&self.keys.group_key())); transcript.append_message(b"group_key", &C::G_to_bytes(&self.keys.group_key()));
@@ -308,7 +308,7 @@ impl<D: CoinDb, C: Coin> Wallet<D, C> {
} }
// Create the transcript for this transaction // Create the transcript for this transaction
let mut transcript = Transcript::new(b"Serai Processor Wallet Send"); let mut transcript = RecommendedTranscript::new(b"Serai Processor Wallet Send");
transcript.append_message( transcript.append_message(
b"canonical_height", b"canonical_height",
&u64::try_from(canonical).unwrap().to_le_bytes() &u64::try_from(canonical).unwrap().to_le_bytes()