improve sign() performance by caching SigningCommitments (#493)

This commit is contained in:
Conrado Gouvea 2023-09-02 01:59:52 -03:00 committed by GitHub
parent 7c8a872603
commit 0fb4824e4b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 29 additions and 17 deletions

View File

@ -207,6 +207,12 @@ pub struct SigningNonces<C: Ciphersuite> {
pub(crate) hiding: Nonce<C>,
/// The binding [`Nonce`].
pub(crate) binding: Nonce<C>,
/// The commitments to the nonces. This is precomputed to improve
/// sign() performance, since it needs to check if the commitments
/// to the participant's nonces are included in the commitments sent
/// by the Coordinator, and this prevents having to recompute them.
#[zeroize(skip)]
pub(crate) commitments: SigningCommitments<C>,
}
impl<C> SigningNonces<C>
@ -221,12 +227,26 @@ where
where
R: CryptoRng + RngCore,
{
// The values of 'hiding' and 'binding' must be non-zero so that commitments are
// not the identity.
let hiding = Nonce::<C>::new(secret, rng);
let binding = Nonce::<C>::new(secret, rng);
Self { hiding, binding }
Self::from_nonces(hiding, binding)
}
/// Generates a new [`SigningNonces`] from a pair of [`Nonce`]. This is
/// useful internally since [`SigningNonces`] precompute the respective
/// commitments.
#[cfg_attr(test, visibility::make(pub))]
pub(crate) fn from_nonces(hiding: Nonce<C>, binding: Nonce<C>) -> Self {
let hiding_commitment = (&hiding).into();
let binding_commitment = (&binding).into();
let commitments = SigningCommitments::new(hiding_commitment, binding_commitment);
Self {
hiding,
binding,
commitments,
}
}
/// Gets the hiding [`Nonce`]
@ -295,11 +315,7 @@ where
C: Ciphersuite,
{
fn from(nonces: &SigningNonces<C>) -> Self {
Self {
hiding: nonces.hiding.clone().into(),
binding: nonces.binding.clone().into(),
ciphersuite: (),
}
nonces.commitments
}
}

View File

@ -11,8 +11,6 @@ use crate::{
#[cfg(feature = "serde")]
use crate::ScalarSerialization;
use super::round1::SigningCommitments;
// Used to help encoding a SignatureShare. Since it has a Scalar<C> it can't
// be directly encoded with serde, so we use this struct to wrap the scalar.
#[cfg(feature = "serde")]
@ -195,10 +193,8 @@ pub fn sign<C: Ciphersuite>(
.get(&key_package.identifier)
.ok_or(Error::MissingCommitment)?;
let signing_commitments = SigningCommitments::from(signer_nonces);
// Validate if the signer's commitment exists
if &signing_commitments != commitment {
if &signer_nonces.commitments != commitment {
return Err(Error::IncorrectCommitment);
}

View File

@ -96,10 +96,10 @@ pub fn parse_test_vectors<C: Ciphersuite>(json_vectors: &Value) -> TestVectors<C
hex::decode(signer["binding_nonce_randomness"].as_str().unwrap()).unwrap();
binding_nonces_randomness.insert(identifier, binding_nonce_randomness);
let signing_nonces = SigningNonces::<C> {
hiding: Nonce::<C>::from_hex(signer["hiding_nonce"].as_str().unwrap()).unwrap(),
binding: Nonce::<C>::from_hex(signer["binding_nonce"].as_str().unwrap()).unwrap(),
};
let signing_nonces = SigningNonces::<C>::from_nonces(
Nonce::<C>::from_hex(signer["hiding_nonce"].as_str().unwrap()).unwrap(),
Nonce::<C>::from_hex(signer["binding_nonce"].as_str().unwrap()).unwrap(),
);
signer_nonces.insert(identifier, signing_nonces);