diff --git a/rln/Cargo.toml b/rln/Cargo.toml index 27c3545..4928858 100644 --- a/rln/Cargo.toml +++ b/rln/Cargo.toml @@ -48,3 +48,5 @@ serde_json = "1.0.48" once_cell = "1.8" poseidon-rs = "0.0.8" sha2 = "0.10.1" + +ff = { package="ff_ce", version="0.11"} diff --git a/rln/src/lib.rs b/rln/src/lib.rs index 767579a..6e0a937 100644 --- a/rln/src/lib.rs +++ b/rln/src/lib.rs @@ -1,2 +1,4 @@ pub mod ffi; pub mod public; +pub mod identity; +pub mod util; diff --git a/rln/src/util.rs b/rln/src/util.rs new file mode 100644 index 0000000..2f05683 --- /dev/null +++ b/rln/src/util.rs @@ -0,0 +1,34 @@ +// Adapted from +// https://github.com/worldcoin/semaphore-rs/blob/main/src/util.rs + +use ff::{PrimeField, PrimeFieldRepr}; +use num_bigint::{BigInt, Sign}; +use poseidon_rs::{Fr, FrRepr}; + +pub fn fr_to_bigint(fr: Fr) -> BigInt { + let mut bytes = [0_u8; 32]; + fr.into_repr().write_be(&mut bytes[..]).unwrap(); + BigInt::from_bytes_be(Sign::Plus, &bytes) +} + +pub fn bigint_to_fr(bi: &BigInt) -> Fr { + // dirty: have to force the point into the field manually, otherwise you get an + // error if bi not in field + let q = BigInt::parse_bytes( + b"21888242871839275222246405745257275088548364400416034343698204186575808495617", + 10, + ) + .unwrap(); + let m = bi.modpow(&BigInt::from(1), &q); + + let mut repr = FrRepr::default(); + let (_, mut res) = m.to_bytes_be(); + + // prepend zeros + res.reverse(); + res.resize(32, 0); + res.reverse(); + + repr.read_be(&res[..]).unwrap(); + Fr::from_repr(repr).unwrap() +}