mirror of
https://github.com/serai-dex/serai.git
synced 2024-12-22 19:49:22 +00:00
Remove RecommendedTranscript from DKG MuSig
Resolves #391. Given this code already wasn't modular/composable, this should be overall equivalent regarding functionality and security. It's much less opinionated though and has fewer dependencies.
This commit is contained in:
parent
bb8e034e68
commit
9f0790fb83
1 changed files with 18 additions and 15 deletions
|
@ -7,8 +7,6 @@ use std_shims::collections::HashMap;
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use zeroize::Zeroizing;
|
use zeroize::Zeroizing;
|
||||||
|
|
||||||
use transcript::{Transcript, RecommendedTranscript};
|
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use ciphersuite::group::ff::Field;
|
use ciphersuite::group::ff::Field;
|
||||||
use ciphersuite::{
|
use ciphersuite::{
|
||||||
|
@ -37,31 +35,36 @@ fn check_keys<C: Ciphersuite>(keys: &[C::G]) -> Result<u16, DkgError<()>> {
|
||||||
Ok(keys_len)
|
Ok(keys_len)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This function panics if called with keys whose length exceed 2**16.
|
||||||
|
// This is fine since it's internal and all calls occur after calling check_keys, which does check
|
||||||
|
// the keys' length.
|
||||||
fn binding_factor_transcript<C: Ciphersuite>(
|
fn binding_factor_transcript<C: Ciphersuite>(
|
||||||
context: &[u8],
|
context: &[u8],
|
||||||
keys: &[C::G],
|
keys: &[C::G],
|
||||||
) -> RecommendedTranscript {
|
) -> Result<Vec<u8>, DkgError<()>> {
|
||||||
let mut transcript = RecommendedTranscript::new(b"DKG MuSig v0.5");
|
let mut transcript = vec![];
|
||||||
transcript.append_message(b"context", context);
|
transcript.push(u8::try_from(context.len()).map_err(|_| DkgError::InvalidSigningSet)?);
|
||||||
transcript.domain_separate(b"keys");
|
transcript.extend(context);
|
||||||
|
transcript.extend(u16::try_from(keys.len()).unwrap().to_le_bytes());
|
||||||
for key in keys {
|
for key in keys {
|
||||||
transcript.append_message(b"key", key.to_bytes());
|
transcript.extend(key.to_bytes().as_ref());
|
||||||
}
|
}
|
||||||
transcript
|
Ok(transcript)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn binding_factor<C: Ciphersuite>(mut transcript: RecommendedTranscript, i: u16) -> C::F {
|
fn binding_factor<C: Ciphersuite>(mut transcript: Vec<u8>, i: u16) -> C::F {
|
||||||
transcript.domain_separate(b"participant");
|
transcript.extend(i.to_le_bytes());
|
||||||
transcript.append_message(b"participant", i.to_le_bytes());
|
C::hash_to_F(b"musig", &transcript)
|
||||||
C::hash_to_F(b"DKG-MuSig-binding_factor", &transcript.challenge(b"binding_factor"))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The group key resulting from using this library's MuSig key gen.
|
/// The group key resulting from using this library's MuSig key gen.
|
||||||
///
|
///
|
||||||
/// Creating an aggregate key with a list containing duplicated public keys returns an error.
|
/// This function will return an error if the context is longer than 255 bytes.
|
||||||
|
///
|
||||||
|
/// Creating an aggregate key with a list containing duplicated public keys will return an error.
|
||||||
pub fn musig_key<C: Ciphersuite>(context: &[u8], keys: &[C::G]) -> Result<C::G, DkgError<()>> {
|
pub fn musig_key<C: Ciphersuite>(context: &[u8], keys: &[C::G]) -> Result<C::G, DkgError<()>> {
|
||||||
let keys_len = check_keys::<C>(keys)?;
|
let keys_len = check_keys::<C>(keys)?;
|
||||||
let transcript = binding_factor_transcript::<C>(context, keys);
|
let transcript = binding_factor_transcript::<C>(context, keys)?;
|
||||||
let mut res = C::G::identity();
|
let mut res = C::G::identity();
|
||||||
for i in 1 ..= keys_len {
|
for i in 1 ..= keys_len {
|
||||||
res += keys[usize::from(i - 1)] * binding_factor::<C>(transcript.clone(), i);
|
res += keys[usize::from(i - 1)] * binding_factor::<C>(transcript.clone(), i);
|
||||||
|
@ -95,7 +98,7 @@ pub fn musig<C: Ciphersuite>(
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// Calculate the binding factor per-key
|
// Calculate the binding factor per-key
|
||||||
let transcript = binding_factor_transcript::<C>(context, keys);
|
let transcript = binding_factor_transcript::<C>(context, keys)?;
|
||||||
let mut binding = Vec::with_capacity(keys.len());
|
let mut binding = Vec::with_capacity(keys.len());
|
||||||
for i in 1 ..= keys_len {
|
for i in 1 ..= keys_len {
|
||||||
binding.push(binding_factor::<C>(transcript.clone(), i));
|
binding.push(binding_factor::<C>(transcript.clone(), i));
|
||||||
|
|
Loading…
Reference in a new issue