From 5b83ea19b8881742e83226560d2f8137f844f2c6 Mon Sep 17 00:00:00 2001 From: Bogdan Opanchuk Date: Fri, 5 Mar 2021 22:23:25 -0800 Subject: [PATCH] Introduce KeyFragID instead of using a Scalar for this purpose See #27 --- umbral-pre/src/capsule_frag.rs | 8 +++--- umbral-pre/src/hashing.rs | 18 ++++++------- umbral-pre/src/hashing_ds.rs | 5 ++-- umbral-pre/src/key_frag.rs | 49 +++++++++++++++++++++++++++------- 4 files changed, 56 insertions(+), 24 deletions(-) diff --git a/umbral-pre/src/capsule_frag.rs b/umbral-pre/src/capsule_frag.rs index 207fc43b..eeeddc35 100644 --- a/umbral-pre/src/capsule_frag.rs +++ b/umbral-pre/src/capsule_frag.rs @@ -2,7 +2,7 @@ use crate::capsule::Capsule; use crate::curve::{CurvePoint, CurveScalar}; use crate::curve::{PublicKey, Signature}; use crate::hashing::{ScalarDigest, SignatureDigest}; -use crate::key_frag::KeyFrag; +use crate::key_frag::{KeyFrag, KeyFragID}; use crate::traits::SerializableToArray; use generic_array::sequence::Concat; @@ -115,7 +115,7 @@ impl CapsuleFragProof { pub struct CapsuleFrag { pub(crate) point_e1: CurvePoint, pub(crate) point_v1: CurvePoint, - pub(crate) kfrag_id: CurveScalar, + pub(crate) kfrag_id: KeyFragID, pub(crate) precursor: CurvePoint, pub(crate) proof: CapsuleFragProof, } @@ -137,7 +137,7 @@ impl SerializableToArray for CapsuleFrag { fn from_array(arr: &GenericArray) -> Option { let (point_e1, rest) = CurvePoint::take(*arr)?; let (point_v1, rest) = CurvePoint::take(rest)?; - let (kfrag_id, rest) = CurveScalar::take(rest)?; + let (kfrag_id, rest) = KeyFragID::take(rest)?; let (precursor, rest) = CurvePoint::take(rest)?; let proof = CapsuleFragProof::take_last(rest)?; Some(Self { @@ -209,7 +209,7 @@ impl CapsuleFrag { let kfrag_id = self.kfrag_id; let valid_kfrag_signature = SignatureDigest::new() - .chain_scalar(&kfrag_id) + .chain_bytes(&kfrag_id) .chain_pubkey(delegating_pk) .chain_pubkey(receiving_pk) .chain_point(&u1) diff --git a/umbral-pre/src/hashing.rs b/umbral-pre/src/hashing.rs index 859bf3ef..9aaa3ef6 100644 --- a/umbral-pre/src/hashing.rs +++ b/umbral-pre/src/hashing.rs @@ -71,8 +71,8 @@ impl ScalarDigest { Self(digest::Digest::chain(self.0, bytes)) } - pub fn chain_bytes(self, bytes: &[u8]) -> Self { - self.chain_impl(bytes) + pub fn chain_bytes>(self, bytes: T) -> Self { + self.chain_impl(bytes.as_ref()) } pub fn chain_scalar(self, scalar: &CurveScalar) -> Self { @@ -108,8 +108,8 @@ impl SignatureDigest { Self(digest::Digest::chain(self.0, bytes)) } - pub fn chain_scalar(self, scalar: &CurveScalar) -> Self { - self.chain_impl(&scalar.to_array()) + pub fn chain_bytes>(self, bytes: T) -> Self { + self.chain_impl(bytes.as_ref()) } pub fn chain_point(self, point: &CurvePoint) -> Self { @@ -187,7 +187,7 @@ mod tests { fn test_signature_digest() { let p1 = CurvePoint::generator(); let p2 = &p1 + &p1; - let rs = CurveScalar::random_nonzero(); + let bytes = b"asdfghjk"; let b = true; let pk = PublicKey::from_secret_key(&SecretKey::random()); @@ -196,14 +196,14 @@ mod tests { let signature = SignatureDigest::new() .chain_point(&p2) - .chain_scalar(&rs) + .chain_bytes(&bytes) .chain_bool(b) .chain_pubkey(&pk) .sign(&signing_sk); let same_values_same_key = SignatureDigest::new() .chain_point(&p2) - .chain_scalar(&rs) + .chain_bytes(&bytes) .chain_bool(b) .chain_pubkey(&pk) .verify(&signing_pk, &signature); @@ -211,7 +211,7 @@ mod tests { let same_values_different_key = SignatureDigest::new() .chain_point(&p2) - .chain_scalar(&rs) + .chain_bytes(&bytes) .chain_bool(b) .chain_pubkey(&pk) .verify(&pk, &signature); @@ -220,7 +220,7 @@ mod tests { let different_values_same_key = SignatureDigest::new() .chain_point(&p1) - .chain_scalar(&rs) + .chain_bytes(&bytes) .chain_bool(b) .chain_pubkey(&pk) .verify(&signing_pk, &signature); diff --git a/umbral-pre/src/hashing_ds.rs b/umbral-pre/src/hashing_ds.rs index 1b5f8edf..c0ea7590 100644 --- a/umbral-pre/src/hashing_ds.rs +++ b/umbral-pre/src/hashing_ds.rs @@ -3,19 +3,20 @@ use crate::curve::{CurvePoint, CurveScalar}; use crate::hashing::ScalarDigest; +use crate::key_frag::KeyFragID; // TODO (#39): Ideally this should return a non-zero scalar. pub(crate) fn hash_to_polynomial_arg( precursor: &CurvePoint, pubkey: &CurvePoint, dh_point: &CurvePoint, - id: &CurveScalar, + kfrag_id: &KeyFragID, ) -> CurveScalar { ScalarDigest::new_with_dst(b"POLYNOMIAL_ARG") .chain_point(precursor) .chain_point(pubkey) .chain_point(dh_point) - .chain_scalar(id) + .chain_bytes(kfrag_id) .finalize() } diff --git a/umbral-pre/src/key_frag.rs b/umbral-pre/src/key_frag.rs index 4b92e996..9f2e846b 100644 --- a/umbral-pre/src/key_frag.rs +++ b/umbral-pre/src/key_frag.rs @@ -10,7 +10,39 @@ use alloc::vec::Vec; use generic_array::sequence::Concat; use generic_array::GenericArray; -use typenum::{op, U1}; +use rand_core::{OsRng, RngCore}; +use typenum::{op, U1, U32}; + +type KeyFragIDSize = U32; + +#[derive(Clone, Copy, Debug, PartialEq)] +pub(crate) struct KeyFragID(GenericArray); + +impl KeyFragID { + fn random() -> Self { + let mut bytes = GenericArray::::default(); + OsRng.fill_bytes(&mut bytes); + Self(bytes) + } +} + +impl AsRef<[u8]> for KeyFragID { + fn as_ref(&self) -> &[u8] { + self.0.as_ref() + } +} + +impl SerializableToArray for KeyFragID { + type Size = KeyFragIDSize; + + fn to_array(&self) -> GenericArray { + self.0 + } + + fn from_array(arr: &GenericArray) -> Option { + Some(Self(*arr)) + } +} #[derive(Clone, Debug, PartialEq)] pub(crate) struct KeyFragProof { @@ -59,7 +91,7 @@ impl KeyFragProof { #[allow(clippy::too_many_arguments)] fn new( params: &Parameters, - kfrag_id: &CurveScalar, + kfrag_id: &KeyFragID, kfrag_key: &CurveScalar, kfrag_precursor: &CurvePoint, signing_sk: &SecretKey, @@ -71,7 +103,7 @@ impl KeyFragProof { let commitment = ¶ms.u * kfrag_key; let signature_for_bob = SignatureDigest::new() - .chain_scalar(kfrag_id) + .chain_bytes(kfrag_id) .chain_pubkey(delegating_pk) .chain_pubkey(receiving_pk) .chain_point(&commitment) @@ -79,7 +111,7 @@ impl KeyFragProof { .sign(signing_sk); let mut digest_for_proxy = SignatureDigest::new() - .chain_scalar(kfrag_id) + .chain_bytes(kfrag_id) .chain_point(&commitment) .chain_point(kfrag_precursor) .chain_bool(sign_delegating_key) @@ -113,7 +145,7 @@ impl KeyFragProof { #[derive(Clone, Debug, PartialEq)] pub struct KeyFrag { params: Parameters, - pub(crate) id: CurveScalar, + pub(crate) id: KeyFragID, pub(crate) key: CurveScalar, pub(crate) precursor: CurvePoint, pub(crate) proof: KeyFragProof, @@ -135,7 +167,7 @@ impl SerializableToArray for KeyFrag { fn from_array(arr: &GenericArray) -> Option { let (params, rest) = Parameters::take(*arr)?; - let (id, rest) = CurveScalar::take(rest)?; + let (id, rest) = KeyFragID::take(rest)?; let (key, rest) = CurveScalar::take(rest)?; let (precursor, rest) = CurvePoint::take(rest)?; let proof = KeyFragProof::take_last(rest)?; @@ -151,8 +183,7 @@ impl SerializableToArray for KeyFrag { impl KeyFrag { fn new(factory: &KeyFragFactory, sign_delegating_key: bool, sign_receiving_key: bool) -> Self { - // Was: `os.urandom(bn_size)`. But it seems we just want a scalar? - let kfrag_id = CurveScalar::random_nonzero(); + let kfrag_id = KeyFragID::random(); // The index of the re-encryption key share (which in Shamir's Secret // Sharing corresponds to x in the tuple (x, f(x)), with f being the @@ -221,7 +252,7 @@ impl KeyFrag { let correct_commitment = commitment == &u * &key; let mut digest = SignatureDigest::new() - .chain_scalar(&kfrag_id) + .chain_bytes(&kfrag_id) .chain_point(&commitment) .chain_point(&precursor) .chain_bool(self.proof.delegating_key_signed)