Skip to content

Commit

Permalink
Apply multiscalar optimization
Browse files Browse the repository at this point in the history
  • Loading branch information
survived committed Apr 16, 2024
1 parent 42a32a7 commit c3dd3d0
Show file tree
Hide file tree
Showing 9 changed files with 40 additions and 25 deletions.
12 changes: 6 additions & 6 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion givre/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ edition = "2021"
cggmp21-keygen = { version = "0.1", optional = true }
key-share = { version = "0.2.2", default-features = false }

generic-ec = { version = "0.2", default-features = false }
generic-ec = { version = "0.2.4", default-features = false }

rand_core = { version = "0.6", default-features = false }
digest = { version = "0.10", default-features = false }
Expand Down
7 changes: 7 additions & 0 deletions givre/src/ciphersuite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,13 @@ pub trait Ciphersuite: Sized + Clone + Copy + core::fmt::Debug {
/// Digest that's used to feed data into [H4](Self::h4) and [H5](Self::h5) hash functions
type Digest: digest::Update + digest::FixedOutput + Clone;

/// Preferred [multiscalar multiplication](generic_ec::multiscalar) algorithm
///
/// Multiscalar multiplication optimization greatly improves performace of FROST protocol.
/// By default, we set it to [`generic_ec::multiscalar::Default`] which uses the fastest
/// algorithm available in [`generic_ec`] crate.
type MultiscalarMul: generic_ec::multiscalar::MultiscalarMul<Self::Curve>;

/// `H1` hash function as defined in the draft
///
/// Accepts a list of bytestring, that'll be contatenated before hashing.
Expand Down
1 change: 1 addition & 0 deletions givre/src/ciphersuite/bitcoin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ impl Ciphersuite for Bitcoin {
const NAME: &'static str = "DFNS-bitcoin-SHA256-v1";
type Curve = <Secp256k1 as Ciphersuite>::Curve;
type Digest = <Secp256k1 as Ciphersuite>::Digest;
type MultiscalarMul = generic_ec::multiscalar::Default;

fn h1(msg: &[&[u8]]) -> generic_ec::Scalar<Self::Curve> {
Secp256k1::h1(msg)
Expand Down
1 change: 1 addition & 0 deletions givre/src/ciphersuite/ed25519.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ impl Ciphersuite for Ed25519 {

type Curve = generic_ec::curves::Ed25519;
type Digest = sha2::Sha512;
type MultiscalarMul = generic_ec::multiscalar::Default;

fn h1(msg: &[&[u8]]) -> generic_ec::Scalar<Self::Curve> {
let mut hash = sha2::Sha512::new()
Expand Down
1 change: 1 addition & 0 deletions givre/src/ciphersuite/secp256k1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ impl Ciphersuite for Secp256k1 {

type Curve = generic_ec::curves::Secp256k1;
type Digest = sha2::Sha256;
type MultiscalarMul = generic_ec::multiscalar::Default;

fn h1(msg: &[&[u8]]) -> generic_ec::Scalar<Self::Curve> {
hash_to_scalar(msg, &[Self::NAME.as_bytes(), b"rho"])
Expand Down
2 changes: 1 addition & 1 deletion givre/src/signing/aggregate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ pub fn aggregate<C: Ciphersuite>(
// --- The Aggregation
let binding_factor_list =
utils::compute_binding_factors::<C>(key_info.shared_public_key, &comm_list, msg);
let group_commitment = utils::compute_group_commitment(&comm_list, &binding_factor_list);
let group_commitment = utils::compute_group_commitment::<C>(&comm_list, &binding_factor_list);
let z = signers
.iter()
.map(|(_j, _comm, sig_share)| sig_share.0)
Expand Down
2 changes: 1 addition & 1 deletion givre/src/signing/round2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ pub fn sign<C: Ciphersuite>(
let binding_factor = binding_factor_list.get(i).ok_or(Bug::OwnBindingFactor)?.1;
debug_assert_eq!(binding_factor_list[i].0, signer_id);

let group_commitment = utils::compute_group_commitment(&comm_list, &binding_factor_list);
let group_commitment = utils::compute_group_commitment::<C>(&comm_list, &binding_factor_list);
let nonce_share = nonce.hiding_nonce + (nonce.binding_nonce * binding_factor);

let (group_commitment, nonce_share) = match NormalizedPoint::try_normalize(group_commitment) {
Expand Down
37 changes: 21 additions & 16 deletions givre/src/signing/utils.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use alloc::vec::Vec;

use digest::{FixedOutput, Update};
use generic_ec::{Curve, NonZero, Point, Scalar};
use generic_ec::{NonZero, Point, Scalar};

use crate::ciphersuite::Ciphersuite;

Expand Down Expand Up @@ -76,21 +76,26 @@ pub fn compute_binding_factors<C: Ciphersuite>(
/// Differences compared to the draft:
/// * Assumes that commitments and binding factors come in the same order, i.e. `commitment_list[i].0 == binding_factor_list[i].0`
/// for all i. Assumtion is enforced via debug assertation.
pub fn compute_group_commitment<'a, E: Curve>(
commitment_list: impl IntoIterator<Item = &'a (NonZero<Scalar<E>>, PublicCommitments<E>)>,
binding_factor_list: impl IntoIterator<Item = &'a (NonZero<Scalar<E>>, Scalar<E>)>,
) -> Point<E> {
commitment_list
.into_iter()
.zip(binding_factor_list)
.map(|((i, comm), (_i, factor))| {
debug_assert_eq!(i, _i);
(*i, *comm, *factor)
})
.fold(Point::zero(), |acc, (_i, comm, binding_factor)| {
let binding_nonce = comm.binding_comm * binding_factor;
acc + comm.hiding_comm + binding_nonce
})
pub fn compute_group_commitment<C: Ciphersuite>(
commitment_list: &[(NonZero<Scalar<C::Curve>>, PublicCommitments<C::Curve>)],
binding_factor_list: &[(NonZero<Scalar<C::Curve>>, Scalar<C::Curve>)],
) -> Point<C::Curve> {
use generic_ec::multiscalar::MultiscalarMul;
debug_assert_eq!(commitment_list.len(), binding_factor_list.len());

// binding_nonces = \sum_i commitment_list[i].1.binding_comm * binding_factor_list[i].1
let binding_nonces =
C::MultiscalarMul::multiscalar_mul(commitment_list.iter().zip(binding_factor_list).map(
|((i, comm), (_i, factor))| {
debug_assert_eq!(i, _i);
(*factor, comm.binding_comm)
},
));
binding_nonces
+ commitment_list
.iter()
.map(|(_, comm)| comm.hiding_comm)
.sum::<Point<_>>()
}

pub fn is_sorted<T: Ord>(slice: &[T]) -> bool {
Expand Down

0 comments on commit c3dd3d0

Please sign in to comment.