diff --git a/crypto/dalek-ff-group/src/lib.rs b/crypto/dalek-ff-group/src/lib.rs index eea21cfb..5340b7e2 100644 --- a/crypto/dalek-ff-group/src/lib.rs +++ b/crypto/dalek-ff-group/src/lib.rs @@ -1,3 +1,5 @@ +#![no_std] + use core::{ ops::{Deref, Add, AddAssign, Sub, SubAssign, Neg, Mul, MulAssign}, borrow::Borrow, diff --git a/crypto/frost/src/algorithm.rs b/crypto/frost/src/algorithm.rs index 21d51521..70f6cf92 100644 --- a/crypto/frost/src/algorithm.rs +++ b/crypto/frost/src/algorithm.rs @@ -62,6 +62,8 @@ pub trait Algorithm: Clone { #[derive(Clone, Debug)] pub struct IetfTranscript(Vec); impl Transcript for IetfTranscript { + type Challenge = Vec; + fn domain_separate(&mut self, _: &[u8]) {} fn append_message(&mut self, _: &'static [u8], message: &[u8]) { diff --git a/crypto/frost/src/sign.rs b/crypto/frost/src/sign.rs index ba2b8203..c01dbe63 100644 --- a/crypto/frost/src/sign.rs +++ b/crypto/frost/src/sign.rs @@ -164,7 +164,7 @@ fn sign_with_share>( transcript.append_message(b"message", &C::hash_msg(&msg)); // Calculate the binding factor - C::hash_binding_factor(&transcript.challenge(b"binding")) + C::hash_binding_factor(transcript.challenge(b"binding").as_ref()) }; // Process the addendums diff --git a/crypto/transcript/Cargo.toml b/crypto/transcript/Cargo.toml index a5d366c2..06790af4 100644 --- a/crypto/transcript/Cargo.toml +++ b/crypto/transcript/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "flexible-transcript" -version = "0.1.1" +version = "0.1.2" description = "A simple transcript trait definition, along with viable options" license = "MIT" repository = "https://github.com/serai-dex/serai" diff --git a/crypto/transcript/src/lib.rs b/crypto/transcript/src/lib.rs index f01215fb..c11dd38e 100644 --- a/crypto/transcript/src/lib.rs +++ b/crypto/transcript/src/lib.rs @@ -1,16 +1,18 @@ -use core::fmt::Debug; +#![no_std] -#[cfg(features = "merlin")] +#[cfg(feature = "merlin")] mod merlin; -#[cfg(features = "merlin")] -pub use merlin::MerlinTranscript; +#[cfg(feature = "merlin")] +pub use crate::merlin::MerlinTranscript; -use digest::{typenum::type_operators::IsGreaterOrEqual, consts::U256, Digest}; +use digest::{typenum::type_operators::IsGreaterOrEqual, consts::U256, Digest, Output}; pub trait Transcript { + type Challenge: Clone + Send + Sync + AsRef<[u8]>; + fn domain_separate(&mut self, label: &'static [u8]); fn append_message(&mut self, label: &'static [u8], message: &[u8]); - fn challenge(&mut self, label: &'static [u8]) -> Vec; + fn challenge(&mut self, label: &'static [u8]) -> Self::Challenge; fn rng_seed(&mut self, label: &'static [u8]) -> [u8; 32]; } @@ -34,10 +36,13 @@ impl DigestTranscriptMember { } } -#[derive(Clone, Debug)] -pub struct DigestTranscript(D) where D::OutputSize: IsGreaterOrEqual; +pub trait SecureDigest: Clone + Digest {} +impl SecureDigest for D where D::OutputSize: IsGreaterOrEqual {} -impl DigestTranscript where D::OutputSize: IsGreaterOrEqual { +#[derive(Clone, Debug)] +pub struct DigestTranscript(D); + +impl DigestTranscript { fn append(&mut self, kind: DigestTranscriptMember, value: &[u8]) { self.0.update(&[kind.as_u8()]); // Assumes messages don't exceed 16 exabytes @@ -52,8 +57,9 @@ impl DigestTranscript where D::OutputSize: IsGreaterOrEqua } } -impl Transcript for DigestTranscript - where D::OutputSize: IsGreaterOrEqual { +impl Transcript for DigestTranscript { + type Challenge = Output; + fn domain_separate(&mut self, label: &[u8]) { self.append(DigestTranscriptMember::Domain, label); } @@ -63,14 +69,14 @@ impl Transcript for DigestTranscript self.append(DigestTranscriptMember::Value, message); } - fn challenge(&mut self, label: &'static [u8]) -> Vec { + fn challenge(&mut self, label: &'static [u8]) -> Self::Challenge { self.append(DigestTranscriptMember::Challenge, label); - self.0.clone().finalize().to_vec() + self.0.clone().finalize() } fn rng_seed(&mut self, label: &'static [u8]) -> [u8; 32] { let mut seed = [0; 32]; - seed.copy_from_slice(&self.challenge(label)[0 .. 32]); + seed.copy_from_slice(&self.challenge(label)[.. 32]); seed } } diff --git a/crypto/transcript/src/merlin.rs b/crypto/transcript/src/merlin.rs index b3d2ab50..d0c60cc9 100644 --- a/crypto/transcript/src/merlin.rs +++ b/crypto/transcript/src/merlin.rs @@ -1,15 +1,22 @@ -use core::{marker::PhantomData, fmt::{Debug, Formatter}}; +use core::fmt::{Debug, Formatter}; -use digest::Digest; +use crate::Transcript; -#[derive(Clone, PartialEq)] +#[derive(Clone)] pub struct MerlinTranscript(pub merlin::Transcript); // Merlin doesn't implement Debug so provide a stub which won't panic impl Debug for MerlinTranscript { - fn fmt(&self, _: &mut Formatter<'_>) -> Result<(), std::fmt::Error> { Ok(()) } + fn fmt(&self, _: &mut Formatter<'_>) -> Result<(), core::fmt::Error> { Ok(()) } } impl Transcript for MerlinTranscript { + // Uses a challenge length of 64 bytes to support wide reduction on generated scalars + // From a security level standpoint, this should just be 32 bytes + // From a Merlin standpoint, this should be variable per call + // From a practical standpoint, this is a demo file not planned to be used and anything using + // this wrapper should be secure with this setting + type Challenge = [u8; 64]; + fn domain_separate(&mut self, label: &'static [u8]) { self.append_message(b"dom-sep", label); } @@ -18,21 +25,15 @@ impl Transcript for MerlinTranscript { self.0.append_message(label, message); } - fn challenge(&mut self, label: &'static [u8]) -> Vec { - let mut challenge = vec![]; - // Uses a challenge length of 64 bytes to support wide reduction on generated scalars - // From a security level standpoint, this should just be 32 bytes - // From a Merlin standpoint, this should be variable per call - // From a practical standpoint, this is a demo file not planned to be used and anything using - // this wrapper is fine without any settings it uses - challenge.resize(64, 0); + fn challenge(&mut self, label: &'static [u8]) -> Self::Challenge { + let mut challenge = [0; 64]; self.0.challenge_bytes(label, &mut challenge); challenge } fn rng_seed(&mut self, label: &'static [u8]) -> [u8; 32] { let mut seed = [0; 32]; - transcript.challenge_bytes(label, &mut seed); + seed.copy_from_slice(&self.challenge(label)[.. 32]); seed } }