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<'_>
impl RLN<'_>
sourcepub fn new<R: Read>(tree_height: usize, input_data: R) -> Result<RLN<'static>>
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 treeinput_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);
sourcepub 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>>
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 treecircom_vec
: a byte vector containing the ZK circuit (rln.wasm
) as binary filezkey_vec
: a byte vector containing to the proving key (rln_final.zkey
) as binary filevk_vec
: a byte vector containing to the verification key (verification_key.json
) as binary filetree_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,
);
sourcepub fn set_tree(&mut self, tree_height: usize) -> Result<()>
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.
sourcepub fn set_leaf<R: Read>(&mut self, index: usize, input_data: R) -> Result<()>
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 leafinput_data
: a reader for the serialization of the leaf value (serialization done withrln::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();
sourcepub fn get_leaf<W: Write>(&self, index: usize, output_data: W) -> Result<()>
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();
sourcepub fn set_leaves_from<R: Read>(
&mut self,
index: usize,
input_data: R
) -> Result<()>
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 setinput_data
: a reader for the serialization of multiple leaf values (serialization done withrln::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();
sourcepub fn init_tree_with_leaves<R: Read>(&mut self, input_data: R) -> Result<()>
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:
input_data
: a reader for the serialization of multiple leaf values (serialization done withrln::utils::vec_fr_to_bytes_le
)
sourcepub fn atomic_operation<R: Read>(
&mut self,
index: usize,
input_leaves: R,
input_indices: R
) -> Result<()>
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 setinput_leaves
: a reader for the serialization of multiple leaf values (serialization done withrln::utils::vec_fr_to_bytes_le
)input_indices
: a reader for the serialization of multiple indices to remove (serialization done withrln::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();
sourcepub fn set_next_leaf<R: Read>(&mut self, input_data: R) -> Result<()>
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:
input_data
: a reader for the serialization of multiple leaf values (serialization done withrln::utils::vec_fr_to_bytes_le
)
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();
sourcepub fn delete_leaf(&mut self, index: usize) -> Result<()>
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();
sourcepub fn set_metadata(&mut self, metadata: &[u8]) -> Result<()>
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();
sourcepub fn get_metadata<W: Write>(&self, output_data: W) -> Result<()>
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();
sourcepub fn get_root<W: Write>(&self, output_data: W) -> Result<()>
pub fn get_root<W: Write>(&self, output_data: W) -> Result<()>
Returns the Merkle tree root
Output values are:
output_data
: a writer receiving the serialization of the root value (serialization done withrln::utils::fr_to_bytes_le
)
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());
sourcepub fn get_proof<W: Write>(&self, index: usize, output_data: W) -> Result<()>
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:
output_data
: a writer receiving the serialization of the path elements and path indexes (serialization done withrln::utils::vec_fr_to_bytes_le
andrln::utils::vec_u8_to_bytes_le
, respectively)
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());
sourcepub fn prove<R: Read, W: Write>(
&mut self,
input_data: R,
output_data: W
) -> Result<()>
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:
input_data
: a reader for the serialization of aRLNWitnessInput
object, containing the public and private inputs to the ZK circuits (serialization done usingrln::protocol::serialize_witness
)
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();
sourcepub fn verify<R: Read>(&self, input_data: R) -> Result<bool>
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);
sourcepub fn generate_rln_proof<R: Read, W: Write>(
&mut self,
input_data: R,
output_data: W
) -> Result<()>
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();
sourcepub fn verify_rln_proof<R: Read>(&self, input_data: R) -> Result<bool>
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);
sourcepub fn verify_with_roots<R: Read>(
&self,
input_data: R,
roots_data: R
) -> Result<bool>
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 usingrln::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);
sourcepub fn key_gen<W: Write>(&self, output_data: W) -> Result<()>
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 withrln::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());
sourcepub fn extended_key_gen<W: Write>(&self, output_data: W) -> Result<()>
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 withrln::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());
sourcepub fn seeded_key_gen<R: Read, W: Write>(
&self,
input_data: R,
output_data: W
) -> Result<()>
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 withrln::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());
sourcepub fn seeded_extended_key_gen<R: Read, W: Write>(
&self,
input_data: R,
output_data: W
) -> Result<()>
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 withrln::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());
sourcepub fn recover_id_secret<R: Read, W: Write>(
&self,
input_proof_data_1: R,
input_proof_data_2: R,
output_data: W
) -> Result<()>
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 ofgenerate_rln_proof
and input ofverify_rln_proof
)input_proof_data_2
: same asinput_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 withrln::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);
sourcepub fn get_serialized_rln_witness<R: Read>(
&mut self,
input_data: R
) -> Result<Vec<u8>>
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
).
sourcepub fn get_rln_witness_json(
&mut self,
serialized_witness: &[u8]
) -> Result<Value>
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:
serialized_witness
: the byte serialization of aRLNWitnessInput
object (serialization done withrln::protocol::serialize_witness
).
The function returns the corresponding JSON encoding of the input RLNWitnessInput
object.
Trait Implementations§
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§
§impl<T> ArchivePointee for T
impl<T> ArchivePointee for T
§type ArchivedMetadata = ()
type ArchivedMetadata = ()
§fn pointer_metadata(
_: &<T as ArchivePointee>::ArchivedMetadata
) -> <T as Pointee>::Metadata
fn pointer_metadata( _: &<T as ArchivePointee>::ArchivedMetadata ) -> <T as Pointee>::Metadata
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<F, W, T, D> Deserialize<With<T, W>, D> for Fwhere
W: DeserializeWith<F, T, D>,
D: Fallible + ?Sized,
F: ?Sized,
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>
fn deserialize( &self, deserializer: &mut D ) -> Result<With<T, W>, <D as Fallible>::Error>
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
§impl<D> OwoColorize for D
impl<D> OwoColorize for D
§fn fg<C>(&self) -> FgColorDisplay<'_, C, Self>where
C: Color,
fn fg<C>(&self) -> FgColorDisplay<'_, C, Self>where C: Color,
§fn bg<C>(&self) -> BgColorDisplay<'_, C, Self>where
C: Color,
fn bg<C>(&self) -> BgColorDisplay<'_, C, Self>where C: Color,
§fn on_yellow<'a>(&'a self) -> BgColorDisplay<'a, Yellow, Self>
fn on_yellow<'a>(&'a self) -> BgColorDisplay<'a, Yellow, Self>
§fn magenta<'a>(&'a self) -> FgColorDisplay<'a, Magenta, Self>
fn magenta<'a>(&'a self) -> FgColorDisplay<'a, Magenta, Self>
§fn on_magenta<'a>(&'a self) -> BgColorDisplay<'a, Magenta, Self>
fn on_magenta<'a>(&'a self) -> BgColorDisplay<'a, Magenta, Self>
§fn on_purple<'a>(&'a self) -> BgColorDisplay<'a, Magenta, Self>
fn on_purple<'a>(&'a self) -> BgColorDisplay<'a, Magenta, Self>
§fn default_color<'a>(&'a self) -> FgColorDisplay<'a, Default, Self>
fn default_color<'a>(&'a self) -> FgColorDisplay<'a, Default, Self>
§fn on_default_color<'a>(&'a self) -> BgColorDisplay<'a, Default, Self>
fn on_default_color<'a>(&'a self) -> BgColorDisplay<'a, Default, Self>
§fn bright_black<'a>(&'a self) -> FgColorDisplay<'a, BrightBlack, Self>
fn bright_black<'a>(&'a self) -> FgColorDisplay<'a, BrightBlack, Self>
§fn on_bright_black<'a>(&'a self) -> BgColorDisplay<'a, BrightBlack, Self>
fn on_bright_black<'a>(&'a self) -> BgColorDisplay<'a, BrightBlack, Self>
§fn bright_red<'a>(&'a self) -> FgColorDisplay<'a, BrightRed, Self>
fn bright_red<'a>(&'a self) -> FgColorDisplay<'a, BrightRed, Self>
§fn on_bright_red<'a>(&'a self) -> BgColorDisplay<'a, BrightRed, Self>
fn on_bright_red<'a>(&'a self) -> BgColorDisplay<'a, BrightRed, Self>
§fn bright_green<'a>(&'a self) -> FgColorDisplay<'a, BrightGreen, Self>
fn bright_green<'a>(&'a self) -> FgColorDisplay<'a, BrightGreen, Self>
§fn on_bright_green<'a>(&'a self) -> BgColorDisplay<'a, BrightGreen, Self>
fn on_bright_green<'a>(&'a self) -> BgColorDisplay<'a, BrightGreen, Self>
§fn bright_yellow<'a>(&'a self) -> FgColorDisplay<'a, BrightYellow, Self>
fn bright_yellow<'a>(&'a self) -> FgColorDisplay<'a, BrightYellow, Self>
§fn on_bright_yellow<'a>(&'a self) -> BgColorDisplay<'a, BrightYellow, Self>
fn on_bright_yellow<'a>(&'a self) -> BgColorDisplay<'a, BrightYellow, Self>
§fn bright_blue<'a>(&'a self) -> FgColorDisplay<'a, BrightBlue, Self>
fn bright_blue<'a>(&'a self) -> FgColorDisplay<'a, BrightBlue, Self>
§fn on_bright_blue<'a>(&'a self) -> BgColorDisplay<'a, BrightBlue, Self>
fn on_bright_blue<'a>(&'a self) -> BgColorDisplay<'a, BrightBlue, Self>
§fn bright_magenta<'a>(&'a self) -> FgColorDisplay<'a, BrightMagenta, Self>
fn bright_magenta<'a>(&'a self) -> FgColorDisplay<'a, BrightMagenta, Self>
§fn on_bright_magenta<'a>(&'a self) -> BgColorDisplay<'a, BrightMagenta, Self>
fn on_bright_magenta<'a>(&'a self) -> BgColorDisplay<'a, BrightMagenta, Self>
§fn bright_purple<'a>(&'a self) -> FgColorDisplay<'a, BrightMagenta, Self>
fn bright_purple<'a>(&'a self) -> FgColorDisplay<'a, BrightMagenta, Self>
§fn on_bright_purple<'a>(&'a self) -> BgColorDisplay<'a, BrightMagenta, Self>
fn on_bright_purple<'a>(&'a self) -> BgColorDisplay<'a, BrightMagenta, Self>
§fn bright_cyan<'a>(&'a self) -> FgColorDisplay<'a, BrightCyan, Self>
fn bright_cyan<'a>(&'a self) -> FgColorDisplay<'a, BrightCyan, Self>
§fn on_bright_cyan<'a>(&'a self) -> BgColorDisplay<'a, BrightCyan, Self>
fn on_bright_cyan<'a>(&'a self) -> BgColorDisplay<'a, BrightCyan, Self>
§fn bright_white<'a>(&'a self) -> FgColorDisplay<'a, BrightWhite, Self>
fn bright_white<'a>(&'a self) -> FgColorDisplay<'a, BrightWhite, Self>
§fn on_bright_white<'a>(&'a self) -> BgColorDisplay<'a, BrightWhite, Self>
fn on_bright_white<'a>(&'a self) -> BgColorDisplay<'a, BrightWhite, Self>
§fn blink_fast<'a>(&'a self) -> BlinkFastDisplay<'a, Self>
fn blink_fast<'a>(&'a self) -> BlinkFastDisplay<'a, Self>
§fn strikethrough<'a>(&'a self) -> StrikeThroughDisplay<'a, Self>
fn strikethrough<'a>(&'a self) -> StrikeThroughDisplay<'a, Self>
§fn color<Color>(&self, color: Color) -> FgDynColorDisplay<'_, Color, Self>where
Color: DynColor,
fn color<Color>(&self, color: Color) -> FgDynColorDisplay<'_, Color, Self>where Color: DynColor,
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,
fn on_color<Color>(&self, color: Color) -> BgDynColorDisplay<'_, Color, Self>where Color: DynColor,
OwoColorize::bg
or
a color-specific method, such as OwoColorize::on_yellow
, Read more