mirror of
https://github.com/Qortal/pirate-librustzcash.git
synced 2025-02-23 14:15:46 +00:00
44 lines
1.2 KiB
Rust
44 lines
1.2 KiB
Rust
|
use jubjub::*;
|
||
|
use pairing::*;
|
||
|
use blake2::{Blake2s};
|
||
|
use digest::{FixedOutput, Input};
|
||
|
|
||
|
/// Produces an (x, y) pair (Montgomery) for a
|
||
|
/// random point in the Jubjub curve. The point
|
||
|
/// is guaranteed to be prime order and not the
|
||
|
/// identity.
|
||
|
pub fn group_hash<E: JubjubEngine>(
|
||
|
tag: &[u8],
|
||
|
params: &E::Params
|
||
|
) -> Option<(E::Fr, E::Fr)>
|
||
|
{
|
||
|
// Check to see that scalar field is 255 bits
|
||
|
assert!(E::Fr::NUM_BITS == 255);
|
||
|
|
||
|
let mut h = Blake2s::new_keyed(&[], 32);
|
||
|
h.process(tag);
|
||
|
let mut h = h.fixed_result().to_vec();
|
||
|
assert!(h.len() == 32);
|
||
|
|
||
|
// Take first/unset first bit of hash
|
||
|
let s = h[0] >> 7 == 1; // get s
|
||
|
h[0] &= 0b0111_1111; // unset s from h
|
||
|
|
||
|
// cast to prime field representation
|
||
|
let mut x0 = <E::Fr as PrimeField>::Repr::default();
|
||
|
x0.read_be(&h[..]).expect("hash is sufficiently large");
|
||
|
|
||
|
if let Ok(x0) = E::Fr::from_repr(x0) {
|
||
|
if let Some(p) = montgomery::Point::<E, _>::get_for_x(x0, s, params) {
|
||
|
// Enter into the prime order subgroup
|
||
|
let p = p.mul_by_cofactor(params);
|
||
|
|
||
|
p.into_xy()
|
||
|
} else {
|
||
|
None
|
||
|
}
|
||
|
} else {
|
||
|
None
|
||
|
}
|
||
|
}
|