Compare commits

...

4 Commits

Author SHA1 Message Date
sydhds
e0f6912ed0 Cargo clippy fixes 2025-06-13 10:37:42 +02:00
sydhds
4cf4d0b600 Add Deref for IdSecret 2025-06-13 10:36:34 +02:00
sydhds
0cef5c85e3 Cargo fmt pass 2025-06-13 09:39:50 +02:00
sydhds
1c8ea3b7a3 Add IdSecret to wrap identity_secret_hash + Zeroize support 2025-06-12 17:13:13 +02:00
9 changed files with 168 additions and 49 deletions

23
Cargo.lock generated
View File

@@ -828,6 +828,27 @@ dependencies = [
"syn 1.0.109",
]
[[package]]
name = "derive_more"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678"
dependencies = [
"derive_more-impl",
]
[[package]]
name = "derive_more-impl"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.101",
"unicode-xid",
]
[[package]]
name = "digest"
version = "0.9.0"
@@ -1640,6 +1661,7 @@ dependencies = [
"byteorder",
"cfg-if",
"criterion",
"derive_more",
"document-features",
"lazy_static",
"num-bigint",
@@ -1653,6 +1675,7 @@ dependencies = [
"serde_json",
"thiserror",
"tiny-keccak",
"zeroize",
"zerokit_utils",
]

View File

@@ -12,7 +12,7 @@ use rln::{
hashers::{hash_to_field, poseidon_hash},
protocol::{keygen, prepare_prove_input, prepare_verify_input},
public::RLN,
utils::{bytes_le_to_fr, fr_to_bytes_le, generate_input_buffer},
utils::{bytes_le_to_fr, fr_to_bytes_le, generate_input_buffer, IdSecret},
};
const MESSAGE_LIMIT: u32 = 1;
@@ -44,7 +44,7 @@ enum Commands {
#[derive(Debug, Clone)]
struct Identity {
identity_secret_hash: Fr,
identity_secret_hash: IdSecret,
id_commitment: Fr,
}
@@ -143,7 +143,7 @@ impl RLNSystem {
};
let serialized = prepare_prove_input(
identity.identity_secret_hash,
identity.identity_secret_hash.clone(),
user_index,
Fr::from(MESSAGE_LIMIT),
Fr::from(message_id),
@@ -211,7 +211,8 @@ impl RLNSystem {
{
Ok(_) => {
let output_data = output.into_inner();
let (leaked_identity_secret_hash, _) = bytes_le_to_fr(&output_data);
let (leaked_identity_secret_hash_, _) = bytes_le_to_fr(&output_data);
let leaked_identity_secret_hash = IdSecret::from(leaked_identity_secret_hash_);
if let Some((user_index, identity)) = self
.local_identities
@@ -221,7 +222,7 @@ impl RLNSystem {
})
.map(|(index, identity)| (*index, identity))
{
let real_identity_secret_hash = identity.identity_secret_hash;
let real_identity_secret_hash = identity.identity_secret_hash.clone();
if leaked_identity_secret_hash != real_identity_secret_hash {
Err(eyre!("identity secret hash mismatch {leaked_identity_secret_hash} != {real_identity_secret_hash}"))
} else {

View File

@@ -54,6 +54,8 @@ rand_chacha = "0.3.1"
ruint = { version = "1.15.0", features = ["rand", "serde", "ark-ff-04"] }
tiny-keccak = { version = "2.0.2", features = ["keccak"] }
utils = { package = "zerokit_utils", version = "0.6.0", path = "../utils", default-features = false }
zeroize = "1.8.1"
derive_more = { version = "2.0.1", features = ["from", "into", "display"] }
# serialization
prost = "0.13.5"

View File

@@ -10,9 +10,8 @@ use num_bigint::BigInt;
use rand::{Rng, SeedableRng};
use rand_chacha::ChaCha20Rng;
use serde::{Deserialize, Serialize};
#[cfg(test)]
use std::time::Instant;
use tiny_keccak::{Hasher as _, Keccak};
use zeroize::Zeroize;
use crate::circuit::{calculate_rln_witness, qap::CircomReduction, Curve};
use crate::error::{ComputeIdSecretError, ConversionError, ProofError, ProtocolError};
@@ -21,8 +20,10 @@ use crate::poseidon_tree::{MerkleProof, PoseidonTree};
use crate::public::RLN_IDENTIFIER;
use crate::utils::{
bytes_le_to_fr, bytes_le_to_vec_fr, bytes_le_to_vec_u8, fr_byte_size, fr_to_bytes_le,
normalize_usize, to_bigint, vec_fr_to_bytes_le, vec_u8_to_bytes_le,
normalize_usize, to_bigint, vec_fr_to_bytes_le, vec_u8_to_bytes_le, IdSecret,
};
#[cfg(test)]
use std::time::Instant;
use utils::{ZerokitMerkleProof, ZerokitMerkleTree};
///////////////////////////////////////////////////////
// RLN Witness data structure and utility functions
@@ -31,7 +32,7 @@ use utils::{ZerokitMerkleProof, ZerokitMerkleTree};
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct RLNWitnessInput {
#[serde(serialize_with = "ark_se", deserialize_with = "ark_de")]
identity_secret: Fr,
identity_secret: IdSecret,
#[serde(serialize_with = "ark_se", deserialize_with = "ark_de")]
user_message_limit: Fr,
#[serde(serialize_with = "ark_se", deserialize_with = "ark_de")]
@@ -132,7 +133,9 @@ pub fn serialize_witness(rln_witness: &RLNWitnessInput) -> Result<Vec<u8>, Proto
pub fn deserialize_witness(serialized: &[u8]) -> Result<(RLNWitnessInput, usize), ProtocolError> {
let mut all_read: usize = 0;
let (identity_secret, read) = bytes_le_to_fr(&serialized[all_read..]);
let (mut identity_secret_, read) = bytes_le_to_fr(&serialized[all_read..]);
let identity_secret = IdSecret::from(identity_secret_);
identity_secret_.zeroize();
all_read += read;
let (user_message_limit, read) = bytes_le_to_fr(&serialized[all_read..]);
@@ -183,7 +186,10 @@ pub fn proof_inputs_to_rln_witness(
) -> Result<(RLNWitnessInput, usize), ProtocolError> {
let mut all_read: usize = 0;
let (identity_secret, read) = bytes_le_to_fr(&serialized[all_read..]);
let (mut identity_secret_, read) = bytes_le_to_fr(&serialized[all_read..]);
let identity_secret = IdSecret::from(identity_secret_);
identity_secret_.zeroize();
all_read += read;
let id_index = usize::try_from(u64::from_le_bytes(
@@ -239,7 +245,7 @@ pub fn proof_inputs_to_rln_witness(
///
/// Returns an error if `message_id` is not within `user_message_limit`.
pub fn rln_witness_from_values(
identity_secret: Fr,
identity_secret: IdSecret,
merkle_proof: &MerkleProof,
x: Fr,
external_nullifier: Fr,
@@ -265,7 +271,9 @@ pub fn rln_witness_from_values(
pub fn random_rln_witness(tree_height: usize) -> RLNWitnessInput {
let mut rng = thread_rng();
let identity_secret = hash_to_field(&rng.gen::<[u8; 32]>());
let mut identity_secret_ = hash_to_field(&rng.gen::<[u8; 32]>());
let identity_secret = IdSecret::from(identity_secret_);
identity_secret_.zeroize();
let x = hash_to_field(&rng.gen::<[u8; 32]>());
let epoch = hash_to_field(&rng.gen::<[u8; 32]>());
let rln_identifier = hash_to_field(RLN_IDENTIFIER); //hash_to_field(&rng.gen::<[u8; 32]>());
@@ -298,9 +306,10 @@ pub fn proof_values_from_witness(
message_id_range_check(&rln_witness.message_id, &rln_witness.user_message_limit)?;
// y share
let a_0 = rln_witness.identity_secret;
let a_1 = poseidon_hash(&[a_0, rln_witness.external_nullifier, rln_witness.message_id]);
let y = a_0 + rln_witness.x * a_1;
let a_0: &Fr = &rln_witness.identity_secret;
let mut a_1 = poseidon_hash(&[*a_0, rln_witness.external_nullifier, rln_witness.message_id]);
let y = *a_0 + rln_witness.x * a_1;
a_1.zeroize();
// Nullifier
let nullifier = poseidon_hash(&[a_1]);
@@ -371,7 +380,7 @@ pub fn deserialize_proof_values(serialized: &[u8]) -> (RLNProofValues, usize) {
// input_data is [ identity_secret<32> | id_index<8> | user_message_limit<32> | message_id<32> | external_nullifier<32> | signal_len<8> | signal<var> ]
pub fn prepare_prove_input(
identity_secret: Fr,
identity_secret: IdSecret,
id_index: usize,
user_message_limit: Fr,
message_id: Fr,
@@ -415,12 +424,12 @@ pub fn prepare_verify_input(proof_data: Vec<u8>, signal: &[u8]) -> Vec<u8> {
///////////////////////////////////////////////////////
pub fn compute_tree_root(
identity_secret: &Fr,
identity_secret: &IdSecret,
user_message_limit: &Fr,
path_elements: &[Fr],
identity_path_index: &[u8],
) -> Fr {
let id_commitment = poseidon_hash(&[*identity_secret]);
let id_commitment = poseidon_hash(&[**identity_secret]);
let mut root = poseidon_hash(&[id_commitment, *user_message_limit]);
for i in 0..identity_path_index.len() {
@@ -441,11 +450,11 @@ pub fn compute_tree_root(
// Generates a tuple (identity_secret_hash, id_commitment) where
// identity_secret_hash is random and id_commitment = PoseidonHash(identity_secret_hash)
// RNG is instantiated using thread_rng()
pub fn keygen() -> (Fr, Fr) {
pub fn keygen() -> (IdSecret, Fr) {
let mut rng = thread_rng();
let identity_secret_hash = Fr::rand(&mut rng);
let id_commitment = poseidon_hash(&[identity_secret_hash]);
(identity_secret_hash, id_commitment)
(IdSecret::from(identity_secret_hash), id_commitment)
}
// Generates a tuple (identity_trapdoor, identity_nullifier, identity_secret_hash, id_commitment) where
@@ -454,12 +463,14 @@ pub fn keygen() -> (Fr, Fr) {
// id_commitment = PoseidonHash(identity_secret_hash),
// RNG is instantiated using thread_rng()
// Generated credentials are compatible with Semaphore credentials
pub fn extended_keygen() -> (Fr, Fr, Fr, Fr) {
pub fn extended_keygen() -> (Fr, Fr, IdSecret, Fr) {
let mut rng = thread_rng();
let identity_trapdoor = Fr::rand(&mut rng);
let identity_nullifier = Fr::rand(&mut rng);
let identity_secret_hash = poseidon_hash(&[identity_trapdoor, identity_nullifier]);
let id_commitment = poseidon_hash(&[identity_secret_hash]);
let mut identity_secret_hash_ = poseidon_hash(&[identity_trapdoor, identity_nullifier]);
let identity_secret_hash = IdSecret::from(identity_secret_hash_);
let id_commitment = poseidon_hash(&[identity_secret_hash_]);
identity_secret_hash_.zeroize();
(
identity_trapdoor,
identity_nullifier,
@@ -471,7 +482,7 @@ pub fn extended_keygen() -> (Fr, Fr, Fr, Fr) {
// Generates a tuple (identity_secret_hash, id_commitment) where
// identity_secret_hash is random and id_commitment = PoseidonHash(identity_secret_hash)
// RNG is instantiated using 20 rounds of ChaCha seeded with the hash of the input
pub fn seeded_keygen(signal: &[u8]) -> (Fr, Fr) {
pub fn seeded_keygen(signal: &[u8]) -> (IdSecret, Fr) {
// ChaCha20 requires a seed of exactly 32 bytes.
// We first hash the input seed signal to a 32 bytes array and pass this as seed to ChaCha20
let mut seed = [0; 32];
@@ -480,8 +491,11 @@ pub fn seeded_keygen(signal: &[u8]) -> (Fr, Fr) {
hasher.finalize(&mut seed);
let mut rng = ChaCha20Rng::from_seed(seed);
let identity_secret_hash = Fr::rand(&mut rng);
let id_commitment = poseidon_hash(&[identity_secret_hash]);
let mut identity_secret_hash_ = Fr::rand(&mut rng);
let id_commitment = poseidon_hash(&[identity_secret_hash_]);
let identity_secret_hash = IdSecret::from(identity_secret_hash_);
identity_secret_hash_.zeroize();
(identity_secret_hash, id_commitment)
}
@@ -491,7 +505,7 @@ pub fn seeded_keygen(signal: &[u8]) -> (Fr, Fr) {
// id_commitment = PoseidonHash(identity_secret_hash),
// RNG is instantiated using 20 rounds of ChaCha seeded with the hash of the input
// Generated credentials are compatible with Semaphore credentials
pub fn extended_seeded_keygen(signal: &[u8]) -> (Fr, Fr, Fr, Fr) {
pub fn extended_seeded_keygen(signal: &[u8]) -> (Fr, Fr, IdSecret, Fr) {
// ChaCha20 requires a seed of exactly 32 bytes.
// We first hash the input seed signal to a 32 bytes array and pass this as seed to ChaCha20
let mut seed = [0; 32];
@@ -502,8 +516,11 @@ pub fn extended_seeded_keygen(signal: &[u8]) -> (Fr, Fr, Fr, Fr) {
let mut rng = ChaCha20Rng::from_seed(seed);
let identity_trapdoor = Fr::rand(&mut rng);
let identity_nullifier = Fr::rand(&mut rng);
let identity_secret_hash = poseidon_hash(&[identity_trapdoor, identity_nullifier]);
let id_commitment = poseidon_hash(&[identity_secret_hash]);
let mut identity_secret_hash_ = poseidon_hash(&[identity_trapdoor, identity_nullifier]);
let id_commitment = poseidon_hash(&[identity_secret_hash_]);
let identity_secret_hash = IdSecret::from(identity_secret_hash_);
identity_secret_hash_.zeroize();
(
identity_trapdoor,
identity_nullifier,
@@ -512,7 +529,10 @@ pub fn extended_seeded_keygen(signal: &[u8]) -> (Fr, Fr, Fr, Fr) {
)
}
pub fn compute_id_secret(share1: (Fr, Fr), share2: (Fr, Fr)) -> Result<Fr, ComputeIdSecretError> {
pub fn compute_id_secret(
share1: (Fr, Fr),
share2: (Fr, Fr),
) -> Result<IdSecret, ComputeIdSecretError> {
// Assuming a0 is the identity secret and a1 = poseidonHash([a0, external_nullifier]),
// a (x,y) share satisfies the following relation
// y = a_0 + x * a_1
@@ -528,7 +548,7 @@ pub fn compute_id_secret(share1: (Fr, Fr), share2: (Fr, Fr)) -> Result<Fr, Compu
let a_0 = y1 - x1 * a_1;
// If shares come from the same polynomial, a0 is correctly recovered and a1 = poseidonHash([a0, external_nullifier])
Ok(a_0)
Ok(IdSecret::from(a_0))
} else {
Err(ComputeIdSecretError::DivisionByZero)
}
@@ -618,7 +638,11 @@ pub fn inputs_for_witness_calculation(
.for_each(|v| identity_path_index.push(Fr::from(*v)));
Ok([
("identitySecret", vec![rln_witness.identity_secret]),
// FIXME ?
(
"identitySecret",
vec![rln_witness.identity_secret.clone().into()],
),
("userMessageLimit", vec![rln_witness.user_message_limit]),
("messageId", vec![rln_witness.message_id]),
("pathElements", rln_witness.path_elements.clone()),
@@ -782,8 +806,10 @@ pub fn rln_witness_to_bigint_json(
.iter()
.for_each(|v| identity_path_index.push(BigInt::from(*v).to_str_radix(10)));
let mut identity_secret: Fr = rln_witness.identity_secret.clone().into();
let inputs = serde_json::json!({
"identitySecret": to_bigint(&rln_witness.identity_secret).to_str_radix(10),
"identitySecret": to_bigint(&identity_secret).to_str_radix(10),
"userMessageLimit": to_bigint(&rln_witness.user_message_limit).to_str_radix(10),
"messageId": to_bigint(&rln_witness.message_id).to_str_radix(10),
"pathElements": path_elements,
@@ -792,6 +818,8 @@ pub fn rln_witness_to_bigint_json(
"externalNullifier": to_bigint(&rln_witness.external_nullifier).to_str_radix(10),
});
identity_secret.zeroize();
Ok(inputs)
}

View File

@@ -37,6 +37,7 @@ use ark_serialize::{CanonicalDeserialize, CanonicalSerialize, Read, Write};
use num_bigint::BigInt;
use std::io::Cursor;
use utils::error::ZerokitMerkleTreeError;
use zeroize::Zeroize;
/// The application-specific RLN identifier.
///
@@ -1133,7 +1134,9 @@ impl RLN {
/// ```
pub fn key_gen<W: Write>(&self, mut output_data: W) -> Result<(), RLNError> {
let (identity_secret_hash, id_commitment) = keygen();
output_data.write_all(&fr_to_bytes_le(&identity_secret_hash))?;
let mut identity_secret_hash_: Fr = identity_secret_hash.into();
output_data.write_all(&fr_to_bytes_le(&identity_secret_hash_))?;
identity_secret_hash_.zeroize();
output_data.write_all(&fr_to_bytes_le(&id_commitment))?;
Ok(())
@@ -1324,7 +1327,7 @@ impl RLN {
compute_id_secret(share1, share2).map_err(RLNError::RecoverSecret)?;
// If an identity secret hash is recovered, we write it to output_data, otherwise nothing will be written.
output_data.write_all(&fr_to_bytes_le(&recovered_identity_secret_hash))?;
output_data.write_all(&fr_to_bytes_le(&recovered_identity_secret_hash.into()))?;
}
Ok(())

View File

@@ -880,7 +880,7 @@ mod tree_test {
// We prepare input for generate_rln_proof API
// input_data is [ identity_secret<32> | id_index<8> | user_message_limit<32> | message_id<32> | external_nullifier<32> | signal_len<8> | signal<var> ]
let prove_input1 = prepare_prove_input(
identity_secret_hash,
identity_secret_hash.clone(),
identity_index,
user_message_limit,
message_id,
@@ -889,7 +889,7 @@ mod tree_test {
);
let prove_input2 = prepare_prove_input(
identity_secret_hash,
identity_secret_hash.clone(),
identity_index,
user_message_limit,
message_id,
@@ -932,7 +932,10 @@ mod tree_test {
// We check if the recovered identity secret hash corresponds to the original one
let (recovered_identity_secret_hash, _) = bytes_le_to_fr(&serialized_identity_secret_hash);
assert_eq!(recovered_identity_secret_hash, identity_secret_hash);
assert_eq!(
recovered_identity_secret_hash,
identity_secret_hash.clone().into()
);
// We now test that computing identity_secret_hash is unsuccessful if shares computed from two different identity secret hashes but within same epoch are passed
@@ -982,7 +985,10 @@ mod tree_test {
// ensure that the recovered secret does not match with either of the
// used secrets in proof generation
assert_ne!(recovered_identity_secret_hash_new, identity_secret_hash_new);
assert_ne!(
recovered_identity_secret_hash_new,
identity_secret_hash_new.into()
);
}
}

View File

@@ -3,10 +3,16 @@
use crate::circuit::Fr;
use crate::error::ConversionError;
use ark_ff::PrimeField;
use ark_serialize::{
CanonicalDeserialize, CanonicalSerialize, Compress, SerializationError, Valid, Validate,
};
use derive_more::{Display, From, Into};
use num_bigint::{BigInt, BigUint};
use num_traits::Num;
use serde_json::json;
use std::io::Cursor;
use std::io::{Cursor, Read, Write};
use std::ops::Deref;
use zeroize::{Zeroize, ZeroizeOnDrop};
#[inline(always)]
pub fn to_bigint(el: &Fr) -> BigInt {
@@ -150,3 +156,44 @@ pub fn normalize_usize(input: usize) -> [u8; 8] {
pub fn generate_input_buffer() -> Cursor<String> {
Cursor::new(json!({}).to_string())
}
#[derive(Debug, Zeroize, ZeroizeOnDrop, From, Into, Clone, PartialEq, Display)]
pub struct IdSecret(ark_bn254::Fr);
impl Deref for IdSecret {
type Target = Fr;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl CanonicalSerialize for IdSecret {
fn serialize_with_mode<W: Write>(
&self,
writer: W,
compress: Compress,
) -> Result<(), SerializationError> {
todo!()
}
fn serialized_size(&self, compress: Compress) -> usize {
todo!()
}
}
impl Valid for IdSecret {
fn check(&self) -> Result<(), SerializationError> {
self.0.check()
}
}
impl CanonicalDeserialize for IdSecret {
fn deserialize_with_mode<R: Read>(
reader: R,
compress: Compress,
validate: Validate,
) -> Result<Self, SerializationError> {
todo!()
}
}

View File

@@ -49,15 +49,16 @@ mod test {
root
}
fn identity_pair_gen(rln_pointer: &mut RLN) -> (Fr, Fr) {
fn identity_pair_gen(rln_pointer: &mut RLN) -> (IdSecret, Fr) {
let mut output_buffer = MaybeUninit::<Buffer>::uninit();
let success = key_gen(rln_pointer, output_buffer.as_mut_ptr());
assert!(success, "key gen call failed");
let output_buffer = unsafe { output_buffer.assume_init() };
let result_data = <&[u8]>::from(&output_buffer).to_vec();
// FIXME: zeroize?
let (identity_secret_hash, read) = bytes_le_to_fr(&result_data);
let (id_commitment, _) = bytes_le_to_fr(&result_data[read..].to_vec());
(identity_secret_hash, id_commitment)
(IdSecret::from(identity_secret_hash), id_commitment)
}
fn rln_proof_gen(rln_pointer: &mut RLN, serialized: &[u8]) -> Vec<u8> {
@@ -273,6 +274,7 @@ mod test {
// generate identity
let identity_secret_hash = hash_to_field(b"test-merkle-proof");
let id_commitment = utils_poseidon_hash(&[identity_secret_hash]);
let identity_secret_hash = IdSecret::from(identity_secret_hash);
let user_message_limit = Fr::from(100);
let rate_commitment = utils_poseidon_hash(&[id_commitment, user_message_limit]);
@@ -674,7 +676,7 @@ mod test {
// We prepare input for generate_rln_proof API
// input_data is [ identity_secret<32> | id_index<8> | user_message_limit<32> | message_id<32> | external_nullifier<32> | signal_len<8> | signal<var> ]
let prove_input1 = prepare_prove_input(
identity_secret_hash,
identity_secret_hash.clone(),
identity_index,
user_message_limit,
message_id,
@@ -683,7 +685,7 @@ mod test {
);
let prove_input2 = prepare_prove_input(
identity_secret_hash,
identity_secret_hash.clone(),
identity_index,
user_message_limit,
message_id,
@@ -718,7 +720,10 @@ mod test {
// We check if the recovered identity secret hash corresponds to the original one
let (recovered_identity_secret_hash, _) = bytes_le_to_fr(&serialized_identity_secret_hash);
assert_eq!(recovered_identity_secret_hash, identity_secret_hash);
assert_eq!(
recovered_identity_secret_hash,
identity_secret_hash.clone().into()
);
// We now test that computing identity_secret_hash is unsuccessful if shares computed from two different identity secret hashes but within same epoch are passed
@@ -741,7 +746,7 @@ mod test {
// input_data is [ identity_secret<32> | id_index<8> | epoch<32> | signal_len<8> | signal<var> ]
// Note that epoch is the same as before
let prove_input3 = prepare_prove_input(
identity_secret_hash,
identity_secret_hash.clone(),
identity_index_new,
user_message_limit,
message_id,
@@ -772,7 +777,10 @@ mod test {
// ensure that the recovered secret does not match with either of the
// used secrets in proof generation
assert_ne!(recovered_identity_secret_hash_new, identity_secret_hash_new);
assert_ne!(
recovered_identity_secret_hash_new,
identity_secret_hash_new.into()
);
}
#[test]

View File

@@ -10,7 +10,7 @@ mod test {
use rand::Rng;
use rln::circuit::Fr;
use rln::hashers::{hash_to_field, poseidon_hash as utils_poseidon_hash, ROUND_PARAMS};
use rln::protocol::deserialize_identity_tuple;
use rln::protocol::{deserialize_identity_tuple, IdSecret};
use rln::public::{hash as public_hash, poseidon_hash as public_poseidon_hash, RLN};
use rln::utils::{
bytes_le_to_fr, bytes_le_to_vec_fr, bytes_le_to_vec_u8, bytes_le_to_vec_usize,
@@ -30,6 +30,7 @@ mod test {
// generate identity
let identity_secret_hash = hash_to_field(b"test-merkle-proof");
let id_commitment = utils_poseidon_hash(&vec![identity_secret_hash]);
let identity_secret_hash = IdSecret::from(identity_secret_hash);
let rate_commitment = utils_poseidon_hash(&[id_commitment, user_message_limit.into()]);
// check that leaves indices is empty