Rename rho to binding factor (#153)

* use Identifier instead of index

* remove pub(crate) from the Identifier index

* Refreshed Identifier newtype of Scalar with traits

* Remove commented out lines

* add test vectors with indices larger than 1 byte

* add little_endian_serialize to implement Ord for Identifier

* rename rho to binding factor

* s/Rho/BindingFactor/

Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com>
This commit is contained in:
Conrado Gouvea 2022-10-26 01:21:04 -03:00 committed by GitHub
parent 255d79042a
commit 278630e183
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 36 additions and 35 deletions

View File

@ -35,31 +35,31 @@ pub use self::identifier::Identifier;
///
/// <https://github.com/cfrg/draft-irtf-cfrg-frost/blob/master/draft-irtf-cfrg-frost.md>
#[derive(Clone, PartialEq, Eq)]
pub struct Rho<C: Ciphersuite>(<<C::Group as Group>::Field as Field>::Scalar);
pub struct BindingFactor<C: Ciphersuite>(<<C::Group as Group>::Field as Field>::Scalar);
impl<C> Rho<C>
impl<C> BindingFactor<C>
where
C: Ciphersuite,
{
/// Deserializes [`Rho`] from bytes.
/// Deserializes [`BindingFactor`] from bytes.
pub fn from_bytes(
bytes: <<C::Group as Group>::Field as Field>::Serialization,
) -> Result<Self, Error> {
<<C::Group as Group>::Field as Field>::deserialize(&bytes).map(|scalar| Self(scalar))
}
/// Serializes [`Rho`] to bytes.
/// Serializes [`BindingFactor`] to bytes.
pub fn to_bytes(&self) -> <<C::Group as Group>::Field as Field>::Serialization {
<<C::Group as Group>::Field as Field>::serialize(&self.0)
}
}
impl<C> Debug for Rho<C>
impl<C> Debug for BindingFactor<C>
where
C: Ciphersuite,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_tuple("Rho")
f.debug_tuple("BindingFactor")
.field(&hex::encode(self.to_bytes()))
.finish()
}
@ -67,14 +67,14 @@ where
/// A list of binding factors and their associated identifiers.
#[derive(Clone)]
pub struct BindingFactorList<C: Ciphersuite>(Vec<(Identifier<C>, Rho<C>)>);
pub struct BindingFactorList<C: Ciphersuite>(Vec<(Identifier<C>, BindingFactor<C>)>);
impl<C> BindingFactorList<C>
where
C: Ciphersuite,
{
/// Return iterator through all factors.
pub fn iter(&self) -> impl Iterator<Item = &(Identifier<C>, Rho<C>)> {
pub fn iter(&self) -> impl Iterator<Item = &(Identifier<C>, BindingFactor<C>)> {
self.0.iter()
}
}
@ -83,7 +83,7 @@ impl<C> Index<Identifier<C>> for BindingFactorList<C>
where
C: Ciphersuite,
{
type Output = Rho<C>;
type Output = BindingFactor<C>;
// Get the binding factor of a participant in the list.
//
@ -110,21 +110,21 @@ where
//
// [`compute_binding_factors`]: https://www.ietf.org/archive/id/draft-irtf-cfrg-frost-11.html#section-4.4
fn from(signing_package: &SigningPackage<C>) -> BindingFactorList<C> {
let preimages = signing_package.rho_preimages();
let preimages = signing_package.binding_factor_preimages();
BindingFactorList(
preimages
.iter()
.map(|(identifier, preimage)| {
let binding_factor = C::H1(preimage);
(*identifier, Rho(binding_factor))
(*identifier, BindingFactor(binding_factor))
})
.collect(),
)
}
}
impl<C> FromHex for Rho<C>
impl<C> FromHex for BindingFactor<C>
where
C: Ciphersuite,
{
@ -225,24 +225,24 @@ where
&self.message
}
/// Compute the preimages to H3 to compute the per-signer rhos
/// Compute the preimages to H3 to compute the per-signer binding factors
// We separate this out into its own method so it can be tested
pub fn rho_preimages(&self) -> Vec<(Identifier<C>, Vec<u8>)> {
let mut rho_input_prefix = vec![];
pub fn binding_factor_preimages(&self) -> Vec<(Identifier<C>, Vec<u8>)> {
let mut binding_factor_input_prefix = vec![];
rho_input_prefix.extend_from_slice(C::H4(self.message.as_slice()).as_ref());
rho_input_prefix.extend_from_slice(
binding_factor_input_prefix.extend_from_slice(C::H4(self.message.as_slice()).as_ref());
binding_factor_input_prefix.extend_from_slice(
C::H5(&round1::encode_group_commitments(self.signing_commitments())[..]).as_ref(),
);
self.signing_commitments()
.iter()
.map(|c| {
let mut rho_input = vec![];
let mut binding_factor_input = vec![];
rho_input.extend_from_slice(&rho_input_prefix);
rho_input.extend_from_slice(c.identifier.serialize().as_ref());
(c.identifier, rho_input)
binding_factor_input.extend_from_slice(&binding_factor_input_prefix);
binding_factor_input.extend_from_slice(c.identifier.serialize().as_ref());
(c.identifier, binding_factor_input)
})
.collect()
}
@ -327,7 +327,7 @@ pub fn aggregate<C>(
where
C: Ciphersuite,
{
// Encodes the signing commitment list produced in round one as part of generating [`Rho`], the
// Encodes the signing commitment list produced in round one as part of generating [`BindingFactor`], the
// binding factor.
let binding_factor_list: BindingFactorList<C> = signing_package.into();
@ -353,12 +353,12 @@ where
// Compute Lagrange coefficient.
let lambda_i = derive_lagrange_coeff(&signature_share.identifier, signing_package)?;
let rho = binding_factor_list[signature_share.identifier].clone();
let binding_factor = binding_factor_list[signature_share.identifier].clone();
// Compute the commitment share.
let R_share = signing_package
.signing_commitment(&signature_share.identifier)
.to_group_commitment_share(&rho);
.to_group_commitment_share(&binding_factor);
// Compute relation values to verify this signature share.
signature_share.verify(&R_share, signer_pubkey, lambda_i, &challenge)?;

View File

@ -221,7 +221,7 @@ where
/// [signature commitment share]: https://www.ietf.org/archive/id/draft-irtf-cfrg-frost-11.html#name-signature-share-verificatio
pub(super) fn to_group_commitment_share(
self,
binding_factor: &frost::Rho<C>,
binding_factor: &frost::BindingFactor<C>,
) -> GroupCommitmentShare<C> {
GroupCommitmentShare::<C>(self.hiding.0 + (self.binding.0 * binding_factor.0))
}

View File

@ -133,10 +133,11 @@ pub fn sign<C: Ciphersuite>(
signer_nonces: &round1::SigningNonces<C>,
key_package: &frost::keys::KeyPackage<C>,
) -> Result<SignatureShare<C>, &'static str> {
// Encodes the signing commitment list produced in round one as part of generating [`Rho`], the
// Encodes the signing commitment list produced in round one as part of generating [`BindingFactor`], the
// binding factor.
let binding_factor_list: frost::BindingFactorList<C> = signing_package.into();
let rho: frost::Rho<C> = binding_factor_list[key_package.identifier].clone();
let binding_factor: frost::BindingFactor<C> =
binding_factor_list[key_package.identifier].clone();
// Compute the group commitment from signing commitments produced in round one.
let group_commitment = GroupCommitment::<C>::try_from(signing_package)?;
@ -153,7 +154,7 @@ pub fn sign<C: Ciphersuite>(
// Compute the Schnorr signature share.
let z_share: <<C::Group as Group>::Field as Field>::Scalar = signer_nonces.hiding.0
+ (signer_nonces.binding.0 * rho.0)
+ (signer_nonces.binding.0 * binding_factor.0)
+ (lambda_i * key_package.secret_share.0 * challenge.0);
let signature_share = SignatureShare::<C> {

View File

@ -22,7 +22,7 @@ pub struct TestVectors<C: Ciphersuite> {
signer_nonces: HashMap<Identifier<C>, SigningNonces<C>>,
signer_commitments: HashMap<Identifier<C>, SigningCommitments<C>>,
binding_factor_inputs: HashMap<Identifier<C>, Vec<u8>>,
binding_factors: HashMap<Identifier<C>, Rho<C>>,
binding_factors: HashMap<Identifier<C>, BindingFactor<C>>,
signature_shares: HashMap<Identifier<C>, SignatureShare<C>>,
signature_bytes: Vec<u8>,
}
@ -86,7 +86,7 @@ pub fn parse_test_vectors<C: Ciphersuite>(json_vectors: &Value) -> TestVectors<C
let mut signer_nonces: HashMap<Identifier<C>, SigningNonces<C>> = HashMap::new();
let mut signer_commitments: HashMap<Identifier<C>, SigningCommitments<C>> = HashMap::new();
let mut binding_factor_inputs: HashMap<Identifier<C>, Vec<u8>> = HashMap::new();
let mut binding_factors: HashMap<Identifier<C>, Rho<C>> = HashMap::new();
let mut binding_factors: HashMap<Identifier<C>, BindingFactor<C>> = HashMap::new();
for (i, signer) in round_one_outputs["participants"]
.as_object()
@ -128,7 +128,7 @@ pub fn parse_test_vectors<C: Ciphersuite>(json_vectors: &Value) -> TestVectors<C
binding_factor_inputs.insert(identifier, binding_factor_input);
let binding_factor =
Rho::<C>::from_hex(signer["binding_factor"].as_str().unwrap()).unwrap();
BindingFactor::<C>::from_hex(signer["binding_factor"].as_str().unwrap()).unwrap();
binding_factors.insert(identifier, binding_factor);
}
@ -281,14 +281,14 @@ pub fn check_sign_with_test_vectors<C: Ciphersuite>(json_vectors: &Value) {
let signing_package = frost::SigningPackage::new(signer_commitments_vec, message_bytes);
for (identifier, input) in signing_package.rho_preimages().iter() {
for (identifier, input) in signing_package.binding_factor_preimages().iter() {
assert_eq!(*input, binding_factor_inputs[identifier]);
}
let rho_list: frost::BindingFactorList<C> = (&signing_package).into();
let binding_factor_list: frost::BindingFactorList<C> = (&signing_package).into();
for (identifier, rho) in rho_list.iter() {
assert_eq!(*rho, binding_factors[identifier]);
for (identifier, binding_factor) in binding_factor_list.iter() {
assert_eq!(*binding_factor, binding_factors[identifier]);
}
let mut our_signature_shares: Vec<frost::round2::SignatureShare<C>> = Vec::new();