diff --git a/src/grouphash/mod.rs b/src/grouphash/mod.rs new file mode 100644 index 000000000..8e699167e --- /dev/null +++ b/src/grouphash/mod.rs @@ -0,0 +1,30 @@ +// 64 zeros, substitute with random future determined string like a blockhash, or randomness beacom +const U: [u8; 64] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + +// option to return None or point +fn grouphash(tag: &[u8], params: &E::Params) -> Option> { + // Check to see that scalar field is 255 bits + assert! (E::Fr::NUM_BITS == 255); + + // Perform hash, get random 32-byte string + let mut h = Blake2s::new_keyed(&[], 32); + h.process(&U); + h.process(tag); + let h = h.fixed_result(); + + // Take first unset first bit of hash + let sign = (h[0] >> 7) == 1; + h[0] &= 0b01111111; + + // cast to prime field representation + let mut x0 = ::Repr::default(); + x0.read_be(&h[..]).unwrap(); + + match E::Fr::from_repr(x0) { + Ok(x0) => { + let tmp = montgomery::Point::get_for_x(x0, sign, params).mul_by_cofactor(params); + if tmp == mongomery::Point.zero() { None } else { Some(tmp) }; + } + Err(_) => None + } +} diff --git a/src/lib.rs b/src/lib.rs index 552fe0154..efce8410d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,4 +6,4 @@ extern crate rand; pub mod jubjub; pub mod circuit; - +pub mod grouphash;