hash arbitrary array size (chunks of 5), add hash_bytes

This commit is contained in:
2019-09-01 16:03:57 +02:00
parent 6537a8d55e
commit 9ab4654572
2 changed files with 60 additions and 2 deletions

View File

@@ -1,9 +1,9 @@
# poseidon-rs [![Build Status](https://travis-ci.org/arnaucube/poseidon-rs.svg?branch=master)](https://travis-ci.org/arnaucube/poseidon-rs)
Poseidon hash implementation in Rust
Poseidon hash implementation in Rust, a zkSNARK friendly hash function.
https://eprint.iacr.org/2019/458.pdf
Compatible with the Poseidon Go implementation from https://github.com/iden3/go-iden3-crypto
Compatible with the Poseidon Go implementation done in https://github.com/iden3/go-iden3-crypto
## Warning
Do not use in production

View File

@@ -203,6 +203,46 @@ impl Poseidon {
Ok(state[0].clone())
}
pub fn hash(&self, inp: Vec<BigInt>) -> Result<BigInt, String> {
// check if arr elements are inside the finite field over R
if !check_bigint_array_in_field(&inp, &self.constants.r) {
return Err("elements not inside the finite field over R".to_string());
}
let mut r: BigInt = Zero::zero();
for i in (0..inp.len()).step_by(5) {
let mut five_elems: Vec<BigInt> = Vec::new();
for j in 0..5 {
if i + j < inp.len() {
five_elems.push(inp[i + j].clone());
} else {
five_elems.push(Zero::zero());
}
}
let ph = &self.poseidon_hash(five_elems);
match ph {
Result::Err(err) => return Err(err.to_string()),
Result::Ok(res) => {
r = modulus(&(r + res), &self.constants.r);
}
}
}
Ok(r)
}
pub fn hash_bytes(&self, b: Vec<u8>) -> Result<BigInt, String> {
let n = 31;
let mut ints: Vec<BigInt> = Vec::new();
for i in 0..b.len() / n {
let v: BigInt = BigInt::from_bytes_le(Sign::Plus, &b[n * i..n * (i + 1)]);
ints.push(v);
}
if b.len() % n != 0 {
let v: BigInt = BigInt::from_bytes_le(Sign::Plus, &b[(b.len() / n) * n..]);
ints.push(v);
}
self.hash(ints)
}
}
#[cfg(test)]
@@ -246,4 +286,22 @@ mod tests {
"17185195740979599334254027721507328033796809509313949281114643312710535000993"
);
}
#[test]
fn test_hash_bytes() {
let msg = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
let poseidon = Poseidon::new();
let h = poseidon.hash_bytes(msg.as_bytes().to_vec()).unwrap();
assert_eq!(
h.to_string(),
"11821124228916291136371255062457365369197326845706357273715164664419275913793"
);
let msg2 = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet.";
let h2 = poseidon.hash_bytes(msg2.as_bytes().to_vec()).unwrap();
assert_eq!(
h2.to_string(),
"10747013384255785702102976082726575658403084163954725275481577373644732938016"
);
}
}