Adding deterministic_blind_unchecked functionality under danger feature (#30)
This commit is contained in:
+3
-14
@@ -87,20 +87,9 @@ impl Group for RistrettoPoint {
|
||||
fn random_nonzero_scalar<R: RngCore + CryptoRng>(rng: &mut R) -> Self::Scalar {
|
||||
loop {
|
||||
let scalar = {
|
||||
#[cfg(not(test))]
|
||||
{
|
||||
let mut scalar_bytes = [0u8; 64];
|
||||
rng.fill_bytes(&mut scalar_bytes);
|
||||
Scalar::from_bytes_mod_order_wide(&scalar_bytes)
|
||||
}
|
||||
|
||||
// Tests need an exact conversion from bytes to scalar, sampling only 32 bytes from rng
|
||||
#[cfg(test)]
|
||||
{
|
||||
let mut scalar_bytes = [0u8; 32];
|
||||
rng.fill_bytes(&mut scalar_bytes);
|
||||
Scalar::from_bytes_mod_order(scalar_bytes)
|
||||
}
|
||||
let mut scalar_bytes = [0u8; 64];
|
||||
rng.fill_bytes(&mut scalar_bytes);
|
||||
Scalar::from_bytes_mod_order_wide(&scalar_bytes)
|
||||
};
|
||||
|
||||
if scalar != Scalar::zero() {
|
||||
|
||||
@@ -173,9 +173,12 @@ fn test_base_blind<G: Group, H: BlockInput + Digest>(
|
||||
) -> Result<(), InternalError> {
|
||||
for parameters in tvs {
|
||||
for i in 0..parameters.input.len() {
|
||||
let mut rng = CycleRng::new(parameters.blind[i].to_vec());
|
||||
let client_result =
|
||||
NonVerifiableClient::<G, H>::blind(parameters.input[i].clone(), &mut rng)?;
|
||||
let blind =
|
||||
G::from_scalar_slice(&GenericArray::clone_from_slice(¶meters.blind[i]))?;
|
||||
let client_result = NonVerifiableClient::<G, H>::deterministic_blind_unchecked(
|
||||
parameters.input[i].clone(),
|
||||
blind,
|
||||
)?;
|
||||
|
||||
assert_eq!(
|
||||
¶meters.blind[i],
|
||||
@@ -196,9 +199,12 @@ fn test_verifiable_blind<G: Group, H: BlockInput + Digest>(
|
||||
) -> Result<(), InternalError> {
|
||||
for parameters in tvs {
|
||||
for i in 0..parameters.input.len() {
|
||||
let mut rng = CycleRng::new(parameters.blind[i].to_vec());
|
||||
let client_blind_result =
|
||||
VerifiableClient::<G, H>::blind(parameters.input[i].clone(), &mut rng)?;
|
||||
let blind =
|
||||
G::from_scalar_slice(&GenericArray::clone_from_slice(¶meters.blind[i]))?;
|
||||
let client_blind_result = VerifiableClient::<G, H>::deterministic_blind_unchecked(
|
||||
parameters.input[i].clone(),
|
||||
blind,
|
||||
)?;
|
||||
|
||||
assert_eq!(
|
||||
¶meters.blind[i],
|
||||
@@ -291,7 +297,7 @@ fn test_verifiable_finalize<G: Group, H: BlockInput + Digest>(
|
||||
for parameters in tvs {
|
||||
let mut clients = vec![];
|
||||
for i in 0..parameters.input.len() {
|
||||
let client = VerifiableClient::<G, H>::from_data_and_blind(
|
||||
let client = VerifiableClient::<G, H>::from_data_and_blind_and_element(
|
||||
¶meters.input[i],
|
||||
<G as Group>::from_scalar_slice(&GenericArray::clone_from_slice(
|
||||
¶meters.blind[i],
|
||||
|
||||
+67
-3
@@ -165,6 +165,32 @@ impl<G: Group, H: BlockInput + Digest> NonVerifiableClient<G, H> {
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(feature = "danger")]
|
||||
/// Computes the first step for the multiplicative blinding version of DH-OPRF,
|
||||
/// taking a blinding factor scalar as input instead of sampling from an RNG.
|
||||
///
|
||||
/// # Caution
|
||||
///
|
||||
/// This should be used with caution, since
|
||||
/// it does not perform any checks on the validity of the blinding factor!
|
||||
pub fn deterministic_blind_unchecked(
|
||||
input: Vec<u8>,
|
||||
blind: <G as Group>::Scalar,
|
||||
) -> Result<NonVerifiableClientBlindResult<G, H>, InternalError> {
|
||||
let blinded_element = deterministic_blind_unchecked::<G, H>(&input, &blind, Mode::Base)?;
|
||||
Ok(NonVerifiableClientBlindResult {
|
||||
state: Self {
|
||||
data: input,
|
||||
blind,
|
||||
hash: PhantomData,
|
||||
},
|
||||
message: BlindedElement {
|
||||
value: blinded_element,
|
||||
hash: PhantomData,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
/// Computes the third step for the multiplicative blinding version of DH-OPRF, in which
|
||||
/// the client unblinds the server's message.
|
||||
pub fn finalize(
|
||||
@@ -221,6 +247,34 @@ impl<G: Group, H: BlockInput + Digest> VerifiableClient<G, H> {
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(feature = "danger")]
|
||||
/// Computes the first step for the multiplicative blinding version of DH-OPRF,
|
||||
/// taking a blinding factor scalar as input instead of sampling from an RNG.
|
||||
///
|
||||
/// # Caution
|
||||
///
|
||||
/// This should be used with caution, since
|
||||
/// it does not perform any checks on the validity of the blinding factor!
|
||||
pub fn deterministic_blind_unchecked(
|
||||
input: Vec<u8>,
|
||||
blind: <G as Group>::Scalar,
|
||||
) -> Result<VerifiableClientBlindResult<G, H>, InternalError> {
|
||||
let blinded_element =
|
||||
deterministic_blind_unchecked::<G, H>(&input, &blind, Mode::Verifiable)?;
|
||||
Ok(VerifiableClientBlindResult {
|
||||
state: Self {
|
||||
data: input,
|
||||
blind,
|
||||
blinded_element,
|
||||
hash: PhantomData,
|
||||
},
|
||||
message: BlindedElement {
|
||||
value: blinded_element,
|
||||
hash: PhantomData,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
/// Computes the third step for the multiplicative blinding version of DH-OPRF, in which
|
||||
/// the client unblinds the server's message.
|
||||
pub fn finalize(
|
||||
@@ -303,7 +357,7 @@ impl<G: Group, H: BlockInput + Digest> VerifiableClient<G, H> {
|
||||
|
||||
#[cfg(test)]
|
||||
/// Only used for test functions
|
||||
pub fn from_data_and_blind(
|
||||
pub fn from_data_and_blind_and_element(
|
||||
data: &[u8],
|
||||
blind: <G as Group>::Scalar,
|
||||
blinded_element: G,
|
||||
@@ -622,10 +676,20 @@ fn blind<G: Group, H: BlockInput + Digest, R: RngCore + CryptoRng>(
|
||||
) -> Result<(<G as Group>::Scalar, G), InternalError> {
|
||||
// Choose a random scalar that must be non-zero
|
||||
let blind = <G as Group>::random_nonzero_scalar(blinding_factor_rng);
|
||||
let blinded_element = deterministic_blind_unchecked::<G, H>(input, &blind, mode)?;
|
||||
Ok((blind, blinded_element))
|
||||
}
|
||||
|
||||
// Inner function for blind that assumes that the blinding factor has already been chosen,
|
||||
// and therefore takes it as input. Does not check if the blinding factor is non-zero.
|
||||
fn deterministic_blind_unchecked<G: Group, H: BlockInput + Digest>(
|
||||
input: &[u8],
|
||||
blind: &<G as Group>::Scalar,
|
||||
mode: Mode,
|
||||
) -> Result<G, InternalError> {
|
||||
let dst = GenericArray::from(*STR_HASH_TO_GROUP).concat(get_context_string::<G>(mode)?);
|
||||
let hashed_point = <G as Group>::hash_to_curve::<H, _>(input, dst)?;
|
||||
let blinded_element = hashed_point * &blind;
|
||||
Ok((blind, blinded_element))
|
||||
Ok(hashed_point * blind)
|
||||
}
|
||||
|
||||
fn verifiable_unblind<'a, G: 'a + Group, H: 'a + BlockInput + Digest, I>(
|
||||
|
||||
Reference in New Issue
Block a user