Struct rln::public::RLN

source ·
pub struct RLN<'a> { /* private fields */ }
Expand description

The RLN object.

It implements the methods required to update the internal Merkle Tree, generate and verify RLN ZK proofs.

I/O is mostly done using writers and readers implementing std::io::Write and std::io::Read, respectively.

Implementations§

source§

impl RLN<'_>

source

pub fn new<R: Read>(tree_height: usize, input_data: R) -> Result<RLN<'static>>

Creates a new RLN object by loading circuit resources from a folder.

Input parameters are

  • tree_height: the height of the internal Merkle tree
  • input_data: a reader for the string path of the resource folder containing the ZK circuit (rln.wasm), the proving key (rln_final.zkey) and the verification key (verification_key.json).

Example:

use std::io::Cursor;

let tree_height = 20;
let resources = Cursor::new(json!({"resources_folder": "tree_height_20"});

// We create a new RLN instance
let mut rln = RLN::new(tree_height, resources);
source

pub fn new_with_params<R: Read>( tree_height: usize, circom_vec: Vec<u8>, zkey_vec: Vec<u8>, vk_vec: Vec<u8>, tree_config_input: R ) -> Result<RLN<'static>>

Creates a new RLN object by passing circuit resources as byte vectors.

Input parameters are

  • tree_height: the height of the internal Merkle tree
  • circom_vec: a byte vector containing the ZK circuit (rln.wasm) as binary file
  • zkey_vec: a byte vector containing to the proving key (rln_final.zkey) as binary file
  • vk_vec: a byte vector containing to the verification key (verification_key.json) as binary file
  • tree_config: a reader for a string containing a json with the merkle tree configuration

Example:

use std::fs::File;
use std::io::Read;

let tree_height = 20;
let resources_folder = "./resources/tree_height_20/";

let mut resources: Vec<Vec<u8>> = Vec::new();
for filename in ["rln.wasm", "rln_final.zkey", "verification_key.json"] {
    let fullpath = format!("{resources_folder}{filename}");
    let mut file = File::open(&fullpath).expect("no file found");
    let metadata = std::fs::metadata(&fullpath).expect("unable to read metadata");
    let mut buffer = vec![0; metadata.len() as usize];
    file.read_exact(&mut buffer).expect("buffer overflow");
    resources.push(buffer);
    let tree_config = "{}".to_string();
    let tree_config_buffer = &Buffer::from(tree_config.as_bytes());
}

let mut rln = RLN::new_with_params(
    tree_height,
    resources[0].clone(),
    resources[1].clone(),
    resources[2].clone(),
    tree_config_buffer,
);
source

pub fn set_tree(&mut self, tree_height: usize) -> Result<()>

Initializes the internal Merkle tree.

Leaves are set to the default value implemented in PoseidonTree implementation.

Input values are:

  • tree_height: the height of the Merkle tree.
source

pub fn set_leaf<R: Read>(&mut self, index: usize, input_data: R) -> Result<()>

Sets a leaf value at position index in the internal Merkle tree.

Input values are:

  • index: the index of the leaf
  • input_data: a reader for the serialization of the leaf value (serialization done with rln::utils::fr_to_bytes_le)

Example:

use crate::protocol::*;

// We generate a random identity secret hash and commitment pair
let (identity_secret_hash, id_commitment) = keygen();

// We define the tree index where rate_commitment will be added
let id_index = 10;
let user_message_limit = 1;

let rate_commitment = poseidon_hash(&[id_commitment, user_message_limit]);

// We serialize rate_commitment and pass it to set_leaf
let mut buffer = Cursor::new(serialize_field_element(rate_commitment));
rln.set_leaf(id_index, &mut buffer).unwrap();
source

pub fn get_leaf<W: Write>(&self, index: usize, output_data: W) -> Result<()>

Gets a leaf value at position index in the internal Merkle tree. The leaf value is written to output_data. Input values are:

  • index: the index of the leaf

Example:

use crate::protocol::*;
use std::io::Cursor;

let id_index = 10;
let mut buffer = Cursor::new(Vec::<u8>::new());
rln.get_leaf(id_index, &mut buffer).unwrap();
let rate_commitment = deserialize_field_element(&buffer.into_inner()).unwrap();
source

pub fn set_leaves_from<R: Read>( &mut self, index: usize, input_data: R ) -> Result<()>

Sets multiple leaves starting from position index in the internal Merkle tree.

If n leaves are passed as input, these will be set at positions index, index+1, …, index+n-1 respectively.

This function updates the internal Merkle tree next_index value indicating the next available index corresponding to a never-set leaf as next_index = max(next_index, index + n)`.

Input values are:

  • index: the index of the first leaf to be set
  • input_data: a reader for the serialization of multiple leaf values (serialization done with rln::utils::vec_fr_to_bytes_le)

Example:

use rln::circuit::Fr;
use rln::utils::*;

let start_index = 10;
let no_of_leaves = 256;

// We generate a vector of random leaves
let mut leaves: Vec<Fr> = Vec::new();
let mut rng = thread_rng();
for _ in 0..no_of_leaves {
    let (_, id_commitment) = keygen();
    let rate_commitment = poseidon_hash(&[id_commitment, 1.into()]);
    leaves.push(rate_commitment);
}

// We add leaves in a batch into the tree
let mut buffer = Cursor::new(vec_fr_to_bytes_le(&leaves));
rln.set_leaves_from(index, &mut buffer).unwrap();
source

pub fn init_tree_with_leaves<R: Read>(&mut self, input_data: R) -> Result<()>

Resets the tree state to default and sets multiple leaves starting from index 0.

In contrast to set_leaves_from, this function resets to 0 the internal next_index value, before setting the input leaves values.

Input values are:

source

pub fn atomic_operation<R: Read>( &mut self, index: usize, input_leaves: R, input_indices: R ) -> Result<()>

Sets multiple leaves starting from position index in the internal Merkle tree. Also accepts an array of indices to remove from the tree.

If n leaves are passed as input, these will be set at positions index, index+1, …, index+n-1 respectively. If m indices are passed as input, these will be removed from the tree.

This function updates the internal Merkle tree next_index value indicating the next available index corresponding to a never-set leaf as next_index = max(next_index, index + n)`.

Input values are:

  • index: the index of the first leaf to be set
  • input_leaves: a reader for the serialization of multiple leaf values (serialization done with rln::utils::vec_fr_to_bytes_le)
  • input_indices: a reader for the serialization of multiple indices to remove (serialization done with rln::utils::vec_u8_to_bytes_le)

Example:

use rln::circuit::Fr;
use rln::utils::*;

let start_index = 10;
let no_of_leaves = 256;

// We generate a vector of random leaves
let mut leaves: Vec<Fr> = Vec::new();
let mut rng = thread_rng();
for _ in 0..no_of_leaves {
    let (_, id_commitment) = keygen();
    let rate_commitment = poseidon_hash(&[id_commitment, 1.into()]);
    leaves.push(rate_commitment);
}

let mut indices: Vec<u8> = Vec::new();
for i in 0..no_of_leaves {
   if i % 2 == 0 {
      indices.push(i as u8);
  }
}

// We atomically add leaves and remove indices from the tree
let mut leaves_buffer = Cursor::new(vec_fr_to_bytes_le(&leaves));
let mut indices_buffer = Cursor::new(vec_u8_to_bytes_le(&indices));
rln.set_leaves_from(index, &mut leaves_buffer, indices_buffer).unwrap();
source

pub fn set_next_leaf<R: Read>(&mut self, input_data: R) -> Result<()>

Sets a leaf value at the next available never-set leaf index.

This function updates the internal Merkle tree next_index value indicating the next available index corresponding to a never-set leaf as next_index = next_index + 1.

Input values are:

Example:

use rln::circuit::Fr;
use rln::utils::*;

let tree_height = 20;
let start_index = 10;
let no_of_leaves = 256;

// We reset the tree
rln.set_tree(tree_height).unwrap();

// Internal Merkle tree next_index value is now 0

// We generate a vector of random leaves
let mut leaves: Vec<Fr> = Vec::new();
let mut rng = thread_rng();
for _ in 0..no_of_leaves {
    let (_, id_commitment) = keygen();
    let rate_commitment = poseidon_hash(&[id_commitment, 1.into()]);
    leaves.push(rate_commitment);
}

// We add leaves in a batch into the tree
let mut buffer = Cursor::new(vec_fr_to_bytes_le(&leaves));
rln.set_leaves_from(index, &mut buffer).unwrap();

// We set 256 leaves starting from index 10: next_index value is now max(0, 256+10) = 266

// We set a leaf on next available index
// rate_commitment will be set at index 266
let (_, id_commitment) = keygen();
let rate_commitment = poseidon_hash(&[id_commitment, 1.into()]);
let mut buffer = Cursor::new(fr_to_bytes_le(&rate_commitment));
rln.set_next_leaf(&mut buffer).unwrap();
source

pub fn delete_leaf(&mut self, index: usize) -> Result<()>

Sets the value of the leaf at position index to the harcoded default value.

This function does not change the internal Merkle tree next_index value.

Input values are:

  • index: the index of the leaf whose value will be reset

Example


let index = 10;
rln.delete_leaf(index).unwrap();
source

pub fn set_metadata(&mut self, metadata: &[u8]) -> Result<()>

Sets some metadata that a consuming application may want to store in the RLN object. This metadata is not used by the RLN module.

Input values are:

  • metadata: a byte vector containing the metadata

Example

let metadata = b"some metadata";
rln.set_metadata(metadata).unwrap();
source

pub fn get_metadata<W: Write>(&self, output_data: W) -> Result<()>

Returns the metadata stored in the RLN object.

Output values are:

  • output_data: a writer receiving the serialization of the metadata

Example

use std::io::Cursor;

let mut buffer = Cursor::new(Vec::<u8>::new());
rln.get_metadata(&mut buffer).unwrap();
let metadata = buffer.into_inner();
source

pub fn get_root<W: Write>(&self, output_data: W) -> Result<()>

Returns the Merkle tree root

Output values are:

Example

use rln::utils::*;

let mut buffer = Cursor::new(Vec::<u8>::new());
rln.get_root(&mut buffer).unwrap();
let (root, _) = bytes_le_to_fr(&buffer.into_inner());
source

pub fn get_proof<W: Write>(&self, index: usize, output_data: W) -> Result<()>

Returns the Merkle proof of the leaf at position index

Input values are:

  • index: the index of the leaf

Output values are:

Example

use rln::utils::*;

let index = 10;

let mut buffer = Cursor::new(Vec::<u8>::new());
rln.get_proof(index, &mut buffer).unwrap();

let buffer_inner = buffer.into_inner();
let (path_elements, read) = bytes_le_to_vec_fr(&buffer_inner);
let (identity_path_index, _) = bytes_le_to_vec_u8(&buffer_inner[read..].to_vec());
source

pub fn prove<R: Read, W: Write>( &mut self, input_data: R, output_data: W ) -> Result<()>

Computes a zkSNARK RLN proof using a RLNWitnessInput.

Input values are:

Output values are:

  • output_data: a writer receiving the serialization of the zkSNARK proof

Example:

use rln::protocol::*;

let rln_witness = random_rln_witness(tree_height);
let proof_values = proof_values_from_witness(&rln_witness);

// We compute a Groth16 proof
let mut input_buffer = Cursor::new(serialize_witness(&rln_witness));
let mut output_buffer = Cursor::new(Vec::<u8>::new());
rln.prove(&mut input_buffer, &mut output_buffer).unwrap();
let zk_proof = output_buffer.into_inner();
source

pub fn verify<R: Read>(&self, input_data: R) -> Result<bool>

Verifies a zkSNARK RLN proof.

Input values are:

  • input_data: a reader for the serialization of the RLN zkSNARK proof concatenated with a serialization of the circuit output values, i.e. [ proof<128> | root<32> | epoch<32> | share_x<32> | share_y<32> | nullifier<32> | rln_identifier<32> ], where <_> indicates the byte length.

The function returns true if the zkSNARK proof is valid with respect to the provided circuit output values, false otherwise.

Example:

use rln::protocol::*;

let rln_witness = random_rln_witness(tree_height);

// We compute a Groth16 proof
let mut input_buffer = Cursor::new(serialize_witness(&rln_witness));
let mut output_buffer = Cursor::new(Vec::<u8>::new());
rln.prove(&mut input_buffer, &mut output_buffer).unwrap();
let zk_proof = output_buffer.into_inner();

// We prepare the input to prove API, consisting of zk_proof (compressed, 4*32 bytes) || proof_values (6*32 bytes)
// In this example, we compute proof values directly from witness using the utility proof_values_from_witness
let proof_values = proof_values_from_witness(&rln_witness);
let serialized_proof_values = serialize_proof_values(&proof_values);

// We build the input to the verify method
let mut verify_data = Vec::<u8>::new();
verify_data.extend(&zk_proof);
verify_data.extend(&proof_values);
let mut input_buffer = Cursor::new(verify_data);

// We verify the Groth16 proof against the provided zk-proof and proof values
let verified = rln.verify(&mut input_buffer).unwrap();

assert!(verified);
source

pub fn generate_rln_proof<R: Read, W: Write>( &mut self, input_data: R, output_data: W ) -> Result<()>

Computes a zkSNARK RLN proof from the identity secret, the Merkle tree index, the epoch and signal.

Input values are:

  • input_data: a reader for the serialization of [ identity_secret<32> | id_index<8> | epoch<32> | signal_len<8> | signal<var> ]

Output values are:

  • output_data: a writer receiving the serialization of the zkSNARK proof and the circuit evaluations outputs, i.e. [ proof<128> | root<32> | epoch<32> | share_x<32> | share_y<32> | nullifier<32> | rln_identifier<32> ]

Example

use rln::protocol::*:
use rln::utils::*;

// Generate identity pair
let (identity_secret_hash, id_commitment) = keygen();

// We set as leaf rate_commitment after storing its index
let identity_index = 10;
let rate_commitment = poseidon_hash(&[id_commitment, 1.into()]);
let mut buffer = Cursor::new(fr_to_bytes_le(&rate_commitment));
rln.set_leaf(identity_index, &mut buffer).unwrap();

// We generate a random signal
let mut rng = rand::thread_rng();
let signal: [u8; 32] = rng.gen();
// We generate a random epoch
let epoch = hash_to_field(b"test-epoch");

// We prepare input for generate_rln_proof API
// input_data is [ identity_secret<32> | id_index<8> | epoch<32> | signal_len<8> | signal<var> ]
let mut serialized: Vec<u8> = Vec::new();
serialized.append(&mut fr_to_bytes_le(&identity_secret_hash));
serialized.append(&mut normalize_usize(identity_index));
serialized.append(&mut fr_to_bytes_le(&epoch));
serialized.append(&mut normalize_usize(signal_len).resize(8,0));
serialized.append(&mut signal.to_vec());

let mut input_buffer = Cursor::new(serialized);
let mut output_buffer = Cursor::new(Vec::<u8>::new());
rln.generate_rln_proof(&mut input_buffer, &mut output_buffer)
    .unwrap();

// proof_data is [ proof<128> | root<32> | epoch<32> | share_x<32> | share_y<32> | nullifier<32> |  rln_identifier<32> ]
let mut proof_data = output_buffer.into_inner();
source

pub fn verify_rln_proof<R: Read>(&self, input_data: R) -> Result<bool>

Verifies a zkSNARK RLN proof against the provided proof values and the state of the internal Merkle tree.

Input values are:

  • input_data: a reader for the serialization of the RLN zkSNARK proof concatenated with a serialization of the circuit output values and the signal information, i.e. [ proof<128> | root<32> | epoch<32> | share_x<32> | share_y<32> | nullifier<32> | rln_identifier<32> | signal_len<8> | signal<var> ]

The function returns true if the zkSNARK proof is valid with respect to the provided circuit output values and signal. Returns false otherwise.

Note that contrary to verify, this function takes additionaly as input the signal and further verifies if

  • the Merkle tree root corresponds to the root provided as input;
  • the input signal corresponds to the Shamir’s x coordinate provided as input
  • the hardcoded application RLN identifier corresponds to the RLN identifier provided as input

Example

// proof_data is computed as in the example code snippet provided for rln::public::RLN::generate_rln_proof

// We prepare input for verify_rln_proof API
// input_data is [ proof<128> | share_y<32> | nullifier<32> | root<32> | epoch<32> | share_x<32> | rln_identifier<32> | signal_len<8> | signal<var> ]
// that is [ proof_data || signal_len<8> | signal<var> ]
proof_data.append(&mut normalize_usize(signal_len));
proof_data.append(&mut signal.to_vec());

let mut input_buffer = Cursor::new(proof_data);
let verified = rln.verify_rln_proof(&mut input_buffer).unwrap();

assert!(verified);
source

pub fn verify_with_roots<R: Read>( &self, input_data: R, roots_data: R ) -> Result<bool>

Verifies a zkSNARK RLN proof against the provided proof values and a set of allowed Merkle tree roots.

Input values are:

  • input_data: a reader for the serialization of the RLN zkSNARK proof concatenated with a serialization of the circuit output values and the signal information, i.e. [ proof<128> | root<32> | epoch<32> | share_x<32> | share_y<32> | nullifier<32> | rln_identifier<32> | signal_len<8> | signal<var> ]
  • roots_data: a reader for the serialization of a vector of roots, i.e. [ number_of_roots<8> | root_1<32> | ... | root_n<32> ] (number_of_roots is a uint64 in little-endian, roots are serialized using rln::utils::fr_to_bytes_le))

The function returns true if the zkSNARK proof is valid with respect to the provided circuit output values, signal and roots. Returns false otherwise.

Note that contrary to verify_rln_proof, this function does not check if the internal Merkle tree root corresponds to the root provided as input, but rather checks if the root provided as input in input_data corresponds to one of the roots serialized in roots_data.

If roots_data contains no root (is empty), root validation is skipped and the proof will be correctly verified only if the other proof values results valid (i.e., zk-proof, signal, x-coordinate, RLN identifier)

Example

// proof_data is computed as in the example code snippet provided for rln::public::RLN::generate_rln_proof

// If no roots is provided, proof validation is skipped and if the remaining proof values are valid, the proof will be correctly verified
let mut input_buffer = Cursor::new(proof_data);
let mut roots_serialized: Vec<u8> = Vec::new();
let mut roots_buffer = Cursor::new(roots_serialized.clone());
let verified = rln
    .verify_with_roots(&mut input_buffer.clone(), &mut roots_buffer)
    .unwrap();

assert!(verified);

// We serialize in the roots buffer some random values and we check that the proof is not verified since doesn't contain the correct root the proof refers to
for _ in 0..5 {
    roots_serialized.append(&mut fr_to_bytes_le(&Fr::rand(&mut rng)));
}
roots_buffer = Cursor::new(roots_serialized.clone());
let verified = rln
    .verify_with_roots(&mut input_buffer.clone(), &mut roots_buffer)
    .unwrap();

assert!(verified == false);

// We get the root of the tree obtained adding one leaf per time
let mut buffer = Cursor::new(Vec::<u8>::new());
rln.get_root(&mut buffer).unwrap();
let (root, _) = bytes_le_to_fr(&buffer.into_inner());

// We add the real root and we check if now the proof is verified
roots_serialized.append(&mut fr_to_bytes_le(&root));
roots_buffer = Cursor::new(roots_serialized.clone());
let verified = rln
    .verify_with_roots(&mut input_buffer.clone(), &mut roots_buffer)
    .unwrap();

assert!(verified);
source

pub fn key_gen<W: Write>(&self, output_data: W) -> Result<()>

Returns an identity secret and identity commitment pair.

The identity commitment is the Poseidon hash of the identity secret.

Output values are:

  • output_data: a writer receiving the serialization of the identity secret and identity commitment (serialization done with rln::utils::fr_to_bytes_le)

Example

use rln::protocol::*;

// We generate an identity pair
let mut buffer = Cursor::new(Vec::<u8>::new());
rln.key_gen(&mut buffer).unwrap();

// We serialize_compressed the keygen output
let (identity_secret_hash, id_commitment) = deserialize_identity_pair(buffer.into_inner());
source

pub fn extended_key_gen<W: Write>(&self, output_data: W) -> Result<()>

Returns an identity trapdoor, nullifier, secret and commitment tuple.

The identity secret is the Poseidon hash of the identity trapdoor and identity nullifier.

The identity commitment is the Poseidon hash of the identity secret.

Generated credentials are compatible with Semaphore’s credentials.

Output values are:

  • output_data: a writer receiving the serialization of the identity tapdoor, identity nullifier, identity secret and identity commitment (serialization done with rln::utils::fr_to_bytes_le)

Example

use rln::protocol::*;

// We generate an identity tuple
let mut buffer = Cursor::new(Vec::<u8>::new());
rln.extended_key_gen(&mut buffer).unwrap();

// We serialize_compressed the keygen output
let (identity_trapdoor, identity_nullifier, identity_secret_hash, id_commitment) = deserialize_identity_tuple(buffer.into_inner());
source

pub fn seeded_key_gen<R: Read, W: Write>( &self, input_data: R, output_data: W ) -> Result<()>

Returns an identity secret and identity commitment pair generated using a seed.

The identity commitment is the Poseidon hash of the identity secret.

Input values are:

  • input_data: a reader for the byte vector containing the seed

Output values are:

  • output_data: a writer receiving the serialization of the identity secret and identity commitment (serialization done with rln::utils::fr_to_bytes_le)

Example

use rln::protocol::*;

let seed_bytes: &[u8] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

let mut input_buffer = Cursor::new(&seed_bytes);
let mut output_buffer = Cursor::new(Vec::<u8>::new());
rln.seeded_key_gen(&mut input_buffer, &mut output_buffer)
    .unwrap();

// We serialize_compressed the keygen output
let (identity_secret_hash, id_commitment) = deserialize_identity_pair(output_buffer.into_inner());
source

pub fn seeded_extended_key_gen<R: Read, W: Write>( &self, input_data: R, output_data: W ) -> Result<()>

Returns an identity trapdoor, nullifier, secret and commitment tuple generated using a seed.

The identity secret is the Poseidon hash of the identity trapdoor and identity nullifier.

The identity commitment is the Poseidon hash of the identity secret.

Generated credentials are compatible with Semaphore’s credentials.

Input values are:

  • input_data: a reader for the byte vector containing the seed

Output values are:

  • output_data: a writer receiving the serialization of the identity tapdoor, identity nullifier, identity secret and identity commitment (serialization done with rln::utils::fr_to_bytes_le)

Example

use rln::protocol::*;

let seed_bytes: &[u8] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

let mut input_buffer = Cursor::new(&seed_bytes);
let mut output_buffer = Cursor::new(Vec::<u8>::new());
rln.seeded_key_gen(&mut input_buffer, &mut output_buffer)
    .unwrap();

// We serialize_compressed the keygen output
let (identity_trapdoor, identity_nullifier, identity_secret_hash, id_commitment) = deserialize_identity_tuple(buffer.into_inner());
source

pub fn recover_id_secret<R: Read, W: Write>( &self, input_proof_data_1: R, input_proof_data_2: R, output_data: W ) -> Result<()>

Recovers the identity secret from two set of proof values computed for same secret in same epoch.

Input values are:

  • input_proof_data_1: a reader for the serialization of a RLN zkSNARK proof concatenated with a serialization of the circuit output values and -optionally- the signal information, i.e. either [ proof<128> | root<32> | epoch<32> | share_x<32> | share_y<32> | nullifier<32> | rln_identifier<32> ] or [ proof<128> | root<32> | epoch<32> | share_x<32> | share_y<32> | nullifier<32> | rln_identifier<32> | signal_len<8> | signal<var> ] (to maintain compatibility with both output of generate_rln_proof and input of verify_rln_proof)
  • input_proof_data_2: same as input_proof_data_1

Output values are:

  • output_data: a writer receiving the serialization of the recovered identity secret hash field element if correctly recovered (serialization done with rln::utils::fr_to_bytes_le), a writer receiving an empty byte vector if not.

Example

// identity_secret_hash, proof_data_1 and proof_data_2 are computed as in the example code snippet provided for rln::public::RLN::generate_rln_proof using same identity secret and epoch (but not necessarily same signal)

let mut input_proof_data_1 = Cursor::new(proof_data_1);
let mut input_proof_data_2 = Cursor::new(proof_data_2);
let mut output_buffer = Cursor::new(Vec::<u8>::new());
rln.recover_id_secret(
    &mut input_proof_data_1,
    &mut input_proof_data_2,
    &mut output_buffer,
)
.unwrap();

let serialized_identity_secret_hash = output_buffer.into_inner();

// We ensure that a non-empty value is written to output_buffer
assert!(!serialized_identity_secret_hash.is_empty());

// 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);
source

pub fn get_serialized_rln_witness<R: Read>( &mut self, input_data: R ) -> Result<Vec<u8>>

Returns the serialization of a RLNWitnessInput populated from the identity secret, the Merkle tree index, the epoch and signal.

Input values are:

  • input_data: a reader for the serialization of [ identity_secret<32> | id_index<8> | epoch<32> | signal_len<8> | signal<var> ]

The function returns the corresponding RLNWitnessInput object serialized using rln::protocol::serialize_witness).

source

pub fn get_rln_witness_json( &mut self, serialized_witness: &[u8] ) -> Result<Value>

Converts a byte serialization of a RLNWitnessInput object to the corresponding JSON serialization.

Input values are:

The function returns the corresponding JSON encoding of the input RLNWitnessInput object.

source

pub fn flush(&mut self) -> Result<()>

Closes the connection to the Merkle tree database. This function should be called before the RLN object is dropped. If not called, the connection will be closed when the RLN object is dropped. This improves robustness of the tree.

Trait Implementations§

source§

impl Default for RLN<'_>

source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl<'a> !RefUnwindSafe for RLN<'a>

§

impl<'a> Send for RLN<'a>

§

impl<'a> Sync for RLN<'a>

§

impl<'a> Unpin for RLN<'a>

§

impl<'a> !UnwindSafe for RLN<'a>

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<T> ArchivePointee for T

§

type ArchivedMetadata = ()

The archived version of the pointer metadata for this type.
§

fn pointer_metadata( _: &<T as ArchivePointee>::ArchivedMetadata ) -> <T as Pointee>::Metadata

Converts some archived metadata to the pointer metadata for itself.
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<F, W, T, D> Deserialize<With<T, W>, D> for Fwhere W: DeserializeWith<F, T, D>, D: Fallible + ?Sized, F: ?Sized,

§

fn deserialize( &self, deserializer: &mut D ) -> Result<With<T, W>, <D as Fallible>::Error>

Deserializes using the given deserializer
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for Twhere U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

§

impl<D> OwoColorize for D

§

fn fg<C>(&self) -> FgColorDisplay<'_, C, Self>where C: Color,

Set the foreground color generically Read more
§

fn bg<C>(&self) -> BgColorDisplay<'_, C, Self>where C: Color,

Set the background color generically. Read more
§

fn black<'a>(&'a self) -> FgColorDisplay<'a, Black, Self>

Change the foreground color to black
§

fn on_black<'a>(&'a self) -> BgColorDisplay<'a, Black, Self>

Change the background color to black
§

fn red<'a>(&'a self) -> FgColorDisplay<'a, Red, Self>

Change the foreground color to red
§

fn on_red<'a>(&'a self) -> BgColorDisplay<'a, Red, Self>

Change the background color to red
§

fn green<'a>(&'a self) -> FgColorDisplay<'a, Green, Self>

Change the foreground color to green
§

fn on_green<'a>(&'a self) -> BgColorDisplay<'a, Green, Self>

Change the background color to green
§

fn yellow<'a>(&'a self) -> FgColorDisplay<'a, Yellow, Self>

Change the foreground color to yellow
§

fn on_yellow<'a>(&'a self) -> BgColorDisplay<'a, Yellow, Self>

Change the background color to yellow
§

fn blue<'a>(&'a self) -> FgColorDisplay<'a, Blue, Self>

Change the foreground color to blue
§

fn on_blue<'a>(&'a self) -> BgColorDisplay<'a, Blue, Self>

Change the background color to blue
§

fn magenta<'a>(&'a self) -> FgColorDisplay<'a, Magenta, Self>

Change the foreground color to magenta
§

fn on_magenta<'a>(&'a self) -> BgColorDisplay<'a, Magenta, Self>

Change the background color to magenta
§

fn purple<'a>(&'a self) -> FgColorDisplay<'a, Magenta, Self>

Change the foreground color to purple
§

fn on_purple<'a>(&'a self) -> BgColorDisplay<'a, Magenta, Self>

Change the background color to purple
§

fn cyan<'a>(&'a self) -> FgColorDisplay<'a, Cyan, Self>

Change the foreground color to cyan
§

fn on_cyan<'a>(&'a self) -> BgColorDisplay<'a, Cyan, Self>

Change the background color to cyan
§

fn white<'a>(&'a self) -> FgColorDisplay<'a, White, Self>

Change the foreground color to white
§

fn on_white<'a>(&'a self) -> BgColorDisplay<'a, White, Self>

Change the background color to white
§

fn default_color<'a>(&'a self) -> FgColorDisplay<'a, Default, Self>

Change the foreground color to the terminal default
§

fn on_default_color<'a>(&'a self) -> BgColorDisplay<'a, Default, Self>

Change the background color to the terminal default
§

fn bright_black<'a>(&'a self) -> FgColorDisplay<'a, BrightBlack, Self>

Change the foreground color to bright black
§

fn on_bright_black<'a>(&'a self) -> BgColorDisplay<'a, BrightBlack, Self>

Change the background color to bright black
§

fn bright_red<'a>(&'a self) -> FgColorDisplay<'a, BrightRed, Self>

Change the foreground color to bright red
§

fn on_bright_red<'a>(&'a self) -> BgColorDisplay<'a, BrightRed, Self>

Change the background color to bright red
§

fn bright_green<'a>(&'a self) -> FgColorDisplay<'a, BrightGreen, Self>

Change the foreground color to bright green
§

fn on_bright_green<'a>(&'a self) -> BgColorDisplay<'a, BrightGreen, Self>

Change the background color to bright green
§

fn bright_yellow<'a>(&'a self) -> FgColorDisplay<'a, BrightYellow, Self>

Change the foreground color to bright yellow
§

fn on_bright_yellow<'a>(&'a self) -> BgColorDisplay<'a, BrightYellow, Self>

Change the background color to bright yellow
§

fn bright_blue<'a>(&'a self) -> FgColorDisplay<'a, BrightBlue, Self>

Change the foreground color to bright blue
§

fn on_bright_blue<'a>(&'a self) -> BgColorDisplay<'a, BrightBlue, Self>

Change the background color to bright blue
§

fn bright_magenta<'a>(&'a self) -> FgColorDisplay<'a, BrightMagenta, Self>

Change the foreground color to bright magenta
§

fn on_bright_magenta<'a>(&'a self) -> BgColorDisplay<'a, BrightMagenta, Self>

Change the background color to bright magenta
§

fn bright_purple<'a>(&'a self) -> FgColorDisplay<'a, BrightMagenta, Self>

Change the foreground color to bright purple
§

fn on_bright_purple<'a>(&'a self) -> BgColorDisplay<'a, BrightMagenta, Self>

Change the background color to bright purple
§

fn bright_cyan<'a>(&'a self) -> FgColorDisplay<'a, BrightCyan, Self>

Change the foreground color to bright cyan
§

fn on_bright_cyan<'a>(&'a self) -> BgColorDisplay<'a, BrightCyan, Self>

Change the background color to bright cyan
§

fn bright_white<'a>(&'a self) -> FgColorDisplay<'a, BrightWhite, Self>

Change the foreground color to bright white
§

fn on_bright_white<'a>(&'a self) -> BgColorDisplay<'a, BrightWhite, Self>

Change the background color to bright white
§

fn bold<'a>(&'a self) -> BoldDisplay<'a, Self>

Make the text bold
§

fn dimmed<'a>(&'a self) -> DimDisplay<'a, Self>

Make the text dim
§

fn italic<'a>(&'a self) -> ItalicDisplay<'a, Self>

Make the text italicized
§

fn underline<'a>(&'a self) -> UnderlineDisplay<'a, Self>

Make the text italicized
Make the text blink
Make the text blink (but fast!)
§

fn reversed<'a>(&'a self) -> ReversedDisplay<'a, Self>

Swap the foreground and background colors
§

fn hidden<'a>(&'a self) -> HiddenDisplay<'a, Self>

Hide the text
§

fn strikethrough<'a>(&'a self) -> StrikeThroughDisplay<'a, Self>

Cross out the text
§

fn color<Color>(&self, color: Color) -> FgDynColorDisplay<'_, Color, Self>where Color: DynColor,

Set the foreground color at runtime. Only use if you do not know which color will be used at compile-time. If the color is constant, use either OwoColorize::fg or a color-specific method, such as OwoColorize::green, Read more
§

fn on_color<Color>(&self, color: Color) -> BgDynColorDisplay<'_, Color, Self>where Color: DynColor,

Set the background color at runtime. Only use if you do not know what color to use at compile-time. If the color is constant, use either OwoColorize::bg or a color-specific method, such as OwoColorize::on_yellow, Read more
§

fn fg_rgb<const R: u8, const G: u8, const B: u8>( &self ) -> FgColorDisplay<'_, CustomColor<R, G, B>, Self>

Set the foreground color to a specific RGB value.
§

fn bg_rgb<const R: u8, const G: u8, const B: u8>( &self ) -> BgColorDisplay<'_, CustomColor<R, G, B>, Self>

Set the background color to a specific RGB value.
§

fn truecolor(&self, r: u8, g: u8, b: u8) -> FgDynColorDisplay<'_, Rgb, Self>

Sets the foreground color to an RGB value.
§

fn on_truecolor(&self, r: u8, g: u8, b: u8) -> BgDynColorDisplay<'_, Rgb, Self>

Sets the background color to an RGB value.
§

fn style(&self, style: Style) -> Styled<&Self>

Apply a runtime-determined style
§

impl<T> Pointable for T

§

const ALIGN: usize = _

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
§

impl<T> Pointee for T

§

type Metadata = ()

The type for metadata in pointers and references to Self.
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> Upcastable for Twhere T: Any + Send + Sync + 'static,

§

fn upcast_any_ref(&self) -> &(dyn Any + 'static)

upcast ref
§

fn upcast_any_mut(&mut self) -> &mut (dyn Any + 'static)

upcast mut ref
§

fn upcast_any_box(self: Box<T>) -> Box<dyn Any>

upcast boxed dyn
§

impl<V, T> VZip<V> for Twhere V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more