Skip to content

Commit

Permalink
Hashing over owned/borrowed data without explicit type parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
andyleiserson committed Sep 5, 2024
1 parent 095fabd commit 7ff58c2
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 29 deletions.
46 changes: 27 additions & 19 deletions ipa-core/src/helpers/hashing.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{borrow::Borrow, convert::Infallible};
use std::convert::Infallible;

use generic_array::GenericArray;
use sha2::{
Expand Down Expand Up @@ -29,6 +29,22 @@ impl Serializable for Hash {
}
}

pub trait SerializeAs<T: Serializable> {
fn serialize(self, buf: &mut GenericArray<u8, T::Size>);
}

impl<T: Serializable> SerializeAs<T> for T {
fn serialize(self, buf: &mut GenericArray<u8, <T as Serializable>::Size>) {
<T as Serializable>::serialize(&self, buf);
}
}

impl<'a, T: Serializable> SerializeAs<T> for &'a T {
fn serialize(self, buf: &mut GenericArray<u8, <T as Serializable>::Size>) {
<T as Serializable>::serialize(self, buf);
}
}

impl MpcMessage for Hash {}

/// Computes Hash of serializable values from an iterator
Expand All @@ -38,7 +54,7 @@ impl MpcMessage for Hash {}
pub fn compute_hash<I, T, S>(input: I) -> Hash
where
I: IntoIterator<Item = T>,
T: Borrow<S>,
T: SerializeAs<S>,
S: Serializable,
{
// set up hash
Expand All @@ -49,7 +65,7 @@ where
// set state
for x in input {
is_empty = false;
x.borrow().serialize(&mut buf);
x.serialize(&mut buf);
sha.update(&buf);
}

Expand Down Expand Up @@ -91,7 +107,7 @@ where
);

// set state
let combine = compute_hash::<_, _, Hash>([left, right]);
let combine = compute_hash([left, right]);
let mut buf = GenericArray::default();
combine.serialize(&mut buf);

Expand Down Expand Up @@ -122,7 +138,7 @@ mod test {
let mut rng = thread_rng();
let list: GenericArray<Fp32BitPrime, U8> =
GenericArray::generate(|_| rng.gen::<Fp32BitPrime>());
let hash: Hash = compute_hash::<_, _, Fp32BitPrime>(&list);
let hash: Hash = compute_hash(list);
let mut buf: GenericArray<u8, _> = GenericArray::default();
hash.serialize(&mut buf);
let deserialized_hash = Hash::deserialize(&buf);
Expand All @@ -139,7 +155,7 @@ mod test {
for _ in 0..LIST_LENGTH {
list.push(rng.gen::<Fp31>());
}
let hash_1 = compute_hash::<_, _, Fp31>(&list);
let hash_1 = compute_hash(&list);

// modify one, randomly selected element in the list
let random_index = rng.gen::<usize>() % LIST_LENGTH;
Expand All @@ -149,7 +165,7 @@ mod test {
}
list[random_index] = different_field_element;

let hash_2 = compute_hash::<_, _, Fp31>(&list);
let hash_2 = compute_hash(&list);

assert_ne!(
hash_1, hash_2,
Expand All @@ -171,7 +187,7 @@ mod test {
}
list.swap(index_1, index_2);

let hash_3 = compute_hash::<_, _, Fp31>(&list);
let hash_3 = compute_hash(&list);

assert_ne!(
hash_2, hash_3,
Expand All @@ -192,11 +208,7 @@ mod test {
left.push(rng.gen::<Fp32BitPrime>());
right.push(rng.gen::<Fp32BitPrime>());
}
let r1: Fp32BitPrime = hash_to_field(
&compute_hash::<_, _, Fp32BitPrime>(&left),
&compute_hash::<_, _, Fp32BitPrime>(&right),
EXCLUDE,
);
let r1: Fp32BitPrime = hash_to_field(&compute_hash(&left), &compute_hash(&right), EXCLUDE);

// modify one, randomly selected element in the list
let random_index = rng.gen::<usize>() % LIST_LENGTH;
Expand All @@ -208,11 +220,7 @@ mod test {
right[random_index] = modified_value;
}

let r2: Fp32BitPrime = hash_to_field(
&compute_hash::<_, _, Fp32BitPrime>(&left),
&compute_hash::<_, _, Fp32BitPrime>(&right),
EXCLUDE,
);
let r2: Fp32BitPrime = hash_to_field(&compute_hash(&left), &compute_hash(&right), EXCLUDE);

assert_ne!(
r1, r2,
Expand All @@ -224,6 +232,6 @@ mod test {
fn check_hash_from_owned_values() {
let mut rng = thread_rng();
let vec = (0..100).map(|_| rng.gen::<Fp31>()).collect::<Vec<_>>();
assert_eq!(compute_hash::<_, _, Fp31>(&vec), compute_hash(vec));
assert_eq!(compute_hash(&vec), compute_hash(vec));
}
}
4 changes: 2 additions & 2 deletions ipa-core/src/protocol/basics/share_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ where
S: SharedValue,
{
// compute hash of `left`
let hash_left = compute_hash::<_, _, S>(input_left);
let hash_left = compute_hash(input_left);

// set up context
let ctx_new = &(ctx.set_total_records(TotalRecords::ONE));
Expand All @@ -45,7 +45,7 @@ where

let ((), hash_received) = try_join(
// send hash
send_channel.send(RecordId::FIRST, compute_hash::<_, _, S>(input_right)),
send_channel.send(RecordId::FIRST, compute_hash(input_right)),
receive_channel.receive(RecordId::FIRST),
)
.await?;
Expand Down
4 changes: 2 additions & 2 deletions ipa-core/src/protocol/ipa_prf/malicious_security/prover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,8 +157,8 @@ impl<F: PrimeField, const L: usize, const P: usize, const M: usize> ProofGenerat
B: Borrow<([F; L], [F; L])>,
{
let r: F = hash_to_field(
&compute_hash::<_, _, F>(proof_left),
&compute_hash::<_, _, F>(proof_right),
&compute_hash(proof_left),
&compute_hash(proof_right),
L.try_into().unwrap(),
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -305,12 +305,8 @@ impl ProofHashes {
};

Self {
hashes: once(compute_hash::<_, _, Fp61BitPrime>(first_proof))
.chain(
other_proofs
.iter()
.map(|proof| compute_hash::<_, _, Fp61BitPrime>(proof.iter())),
)
hashes: once(compute_hash(first_proof))
.chain(other_proofs.iter().map(|proof| compute_hash(proof.iter())))
.collect::<Vec<_>>(),
}
}
Expand Down

0 comments on commit 7ff58c2

Please sign in to comment.