1use std::collections::BTreeMap;
20
21use async_trait::async_trait;
22use darkfi_sdk::pasta::pallas;
23
24use std::io::Cursor;
25
26use darkfi_sdk::crypto::{pasta_prelude::FromUniformBytes, poseidon_hash, smt::SmtMemoryFp};
27use darkfi_serial::{FutAsyncWriteExt, SerialDecodable, SerialEncodable};
28use halo2_proofs::{arithmetic::Field, circuit::Value};
29use rand::rngs::OsRng;
30use sled_overlay::sled;
31use tracing::info;
32
33use crate::{
34 event_graph::Event,
35 zk::{empty_witnesses, Proof, ProvingKey, VerifyingKey, Witness, ZkCircuit},
36 zkas::ZkBinary,
37 Error, Result,
38};
39
40pub const RLN2_REGISTER_ZKBIN: &[u8] = include_bytes!("proof/rlnv2-diff-register.zk.bin");
41pub const RLN2_SIGNAL_ZKBIN: &[u8] = include_bytes!("proof/rlnv2-diff-signal.zk.bin");
42pub const RLN2_SLASH_ZKBIN: &[u8] = include_bytes!("proof/rlnv2-diff-slash.zk.bin");
43
44pub const RLN_GENESIS: u64 = 1_738_688_400_000;
46pub const RLN_EPOCH_LEN: u64 = 600_000; #[derive(SerialEncodable, SerialDecodable)]
50pub struct Blob {
51 pub proof: Proof,
52 pub y: pallas::Base,
53 pub internal_nullifier: pallas::Base,
54 pub user_msg_limit: u64,
55}
56
57pub fn hash_event(event: &Event) -> pallas::Base {
109 let mut buf = [0u8; 64];
110 buf[..blake3::OUT_LEN].copy_from_slice(event.header.id().as_bytes());
111 pallas::Base::from_uniform_bytes(&buf)
112}
113
114pub fn closest_epoch(timestamp: u64) -> u64 {
116 let time_diff = timestamp - RLN_GENESIS;
117 let epoch_idx = time_diff as f64 / RLN_EPOCH_LEN as f64;
118 let rounded = epoch_idx.round() as i64;
119 RLN_GENESIS + (rounded * RLN_EPOCH_LEN as i64) as u64
120}
121
122#[derive(Debug, Clone)]
123struct ShareData {
124 pub x_shares: Vec<pallas::Base>,
125 pub y_shares: Vec<pallas::Base>,
126}
127
128impl ShareData {
129 fn new() -> Self {
130 Self { x_shares: vec![], y_shares: vec![] }
131 }
132}
133
134#[derive(Debug, Default)]
135pub struct MessageMetadata {
136 data: BTreeMap<pallas::Base, BTreeMap<pallas::Base, ShareData>>,
137}
138
139impl MessageMetadata {
140 pub fn new() -> Self {
141 Self { data: BTreeMap::new() }
142 }
143
144 pub fn add_share(
145 &mut self,
146 external_nullifier: pallas::Base,
147 internal_nullifier: pallas::Base,
148 x: pallas::Base,
149 y: pallas::Base,
150 ) -> Result<()> {
151 let inner_map = self.data.entry(external_nullifier).or_default();
152 let share_data = inner_map.entry(internal_nullifier).or_insert_with(ShareData::new);
153
154 share_data.x_shares.push(x);
155 share_data.y_shares.push(y);
156
157 Ok(())
158 }
159
160 pub fn get_shares(
161 &self,
162 external_nullifier: &pallas::Base,
163 internal_nullifier: &pallas::Base,
164 ) -> Vec<(pallas::Base, pallas::Base)> {
165 if let Some(inner_map) = self.data.get(external_nullifier) {
166 if let Some(share_data) = inner_map.get(internal_nullifier) {
167 return share_data
168 .x_shares
169 .iter()
170 .cloned()
171 .zip(share_data.y_shares.iter().cloned())
172 .collect()
173 }
174 }
175
176 vec![]
177 }
178
179 pub fn is_duplicate(
181 &self,
182 external_nullifier: &pallas::Base,
183 internal_nullifier: &pallas::Base,
184 x: &pallas::Base,
185 y: &pallas::Base,
186 ) -> bool {
187 if let Some(inner_map) = self.data.get(external_nullifier) {
188 if let Some(share_data) = inner_map.get(internal_nullifier) {
189 return share_data.x_shares.contains(x) && share_data.y_shares.contains(y);
190 }
191 }
192
193 false
194 }
195
196 pub fn is_reused(
198 &self,
199 external_nullifier: &pallas::Base,
200 internal_nullifier: &pallas::Base,
201 ) -> bool {
202 if let Some(inner_map) = self.data.get(external_nullifier) {
203 return inner_map.get(internal_nullifier).is_some()
204 }
205 false
206 }
207}
208
209#[derive(Clone, Debug, SerialEncodable, SerialDecodable)]
210pub enum RLNNode {
211 Registration(pallas::Base),
212 Slashing(pallas::Base),
213}
214
215pub fn process_commitment(node: RLNNode, identity_tree: &mut SmtMemoryFp) -> Result<()> {
216 match node {
217 RLNNode::Registration(commitment) => {
218 let commitment = vec![commitment];
220 let commitment: Vec<_> = commitment.into_iter().map(|l| (l, l)).collect();
221 identity_tree.insert_batch(commitment)?;
222 }
223 RLNNode::Slashing(commitment) => {
224 let commitment = vec![commitment];
226 let commitment: Vec<_> = commitment.into_iter().map(|l| (l, l)).collect();
227 identity_tree.remove_leaves(commitment)?;
228 }
229 }
230
231 Ok(())
232}
233
234pub fn create_slash_proof(
235 secret: pallas::Base,
236 user_msg_limit: u64,
237 identities_tree: &mut SmtMemoryFp,
238 slash_pk: &ProvingKey,
239) -> Result<(Proof, pallas::Base)> {
240 let identity_secret_hash = poseidon_hash([secret, user_msg_limit.into()]);
241 let commitment = poseidon_hash([identity_secret_hash]);
242
243 let identity_root = identities_tree.root();
244 let identity_path = identities_tree.prove_membership(&commitment);
245 assert!(identity_path.verify(&identity_root, &commitment, &commitment));
247
248 let witnesses = vec![
249 Witness::Base(Value::known(secret)),
250 Witness::Base(Value::known(pallas::Base::from(user_msg_limit))),
251 Witness::SparseMerklePath(Value::known(identity_path.path)),
252 ];
253
254 let public_inputs = vec![secret, pallas::Base::from(user_msg_limit), identity_root];
255
256 let slash_zkbin = ZkBinary::decode(RLN2_SLASH_ZKBIN, false)?;
257 let slash_circuit = ZkCircuit::new(witnesses, &slash_zkbin);
258
259 let proof = Proof::create(slash_pk, &[slash_circuit], &public_inputs, &mut OsRng).unwrap();
260
261 Ok((proof, identity_root))
262}
263
264pub fn sss_recover(shares: &[(pallas::Base, pallas::Base)]) -> pallas::Base {
266 let mut secret = pallas::Base::zero();
267 for (j, share_j) in shares.iter().enumerate() {
268 let mut prod = pallas::Base::one();
269 for (i, share_i) in shares.iter().enumerate() {
270 if i != j {
271 prod *= share_i.0 * (share_i.0 - share_j.0).invert().unwrap();
272 }
273 }
274
275 prod *= share_j.1;
276 secret += prod;
277 }
278
279 secret
280}
281
282pub(super) fn build_register_vk(sled_db: &sled::Db) -> Result<()> {
284 if sled_db.get("rlnv2-diff-register-vk")?.is_some() {
286 return Ok(())
287 }
288 let register_zkbin = ZkBinary::decode(RLN2_REGISTER_ZKBIN, false).unwrap();
289 let register_empty_circuit =
290 ZkCircuit::new(empty_witnesses(®ister_zkbin).unwrap(), ®ister_zkbin);
291
292 info!(target: "irc::server", "[RLN] Creating RlnV2_Diff_Register VerifyingKey");
293 let verifyingkey = VerifyingKey::build(register_zkbin.k, ®ister_empty_circuit);
294 let mut buf = vec![];
295 verifyingkey.write(&mut buf)?;
296 sled_db.insert("rlnv2-diff-register-vk", buf)?;
297 Ok(())
298}
299
300pub(super) fn read_register_vk(sled_db: &sled::Db) -> Result<VerifyingKey> {
302 if let Some(vk) = sled_db.get("rlnv2-diff-register-vk")? {
303 let register_zkbin = ZkBinary::decode(RLN2_REGISTER_ZKBIN, false).unwrap();
304 let register_empty_circuit =
305 ZkCircuit::new(empty_witnesses(®ister_zkbin).unwrap(), ®ister_zkbin);
306 let mut reader = Cursor::new(vk);
307 Ok(VerifyingKey::read(&mut reader, register_empty_circuit)?)
308 } else {
309 Err(Error::Custom("Error reading register verifying key".to_owned()))
310 }
311}
312
313pub(super) fn build_signal_vk(sled_db: &sled::Db) -> Result<()> {
315 if sled_db.get("rlnv2-diff-signal-vk")?.is_some() {
317 return Ok(())
318 }
319 let signal_zkbin = ZkBinary::decode(RLN2_SIGNAL_ZKBIN, false).unwrap();
320 let signal_empty_circuit =
321 ZkCircuit::new(empty_witnesses(&signal_zkbin).unwrap(), &signal_zkbin);
322
323 info!(target: "irc::server", "[RLN] Creating RlnV2_Diff_Signal VerifyingKey");
324 let verifyingkey = VerifyingKey::build(signal_zkbin.k, &signal_empty_circuit);
325 let mut buf = vec![];
326 verifyingkey.write(&mut buf)?;
327 sled_db.insert("rlnv2-diff-signal-vk", buf)?;
328 Ok(())
329}
330
331pub(super) fn read_signal_vk(sled_db: &sled::Db) -> Result<VerifyingKey> {
333 if let Some(vk) = sled_db.get("rlnv2-diff-signal-vk")? {
334 let signal_zkbin = ZkBinary::decode(RLN2_SIGNAL_ZKBIN, false).unwrap();
335 let signal_empty_circuit =
336 ZkCircuit::new(empty_witnesses(&signal_zkbin).unwrap(), &signal_zkbin);
337 let mut reader = Cursor::new(vk);
338 Ok(VerifyingKey::read(&mut reader, signal_empty_circuit)?)
339 } else {
340 Err(Error::Custom("Error Reading signal verifying key".to_owned()))
341 }
342}
343
344pub(super) fn build_slash_pk(sled_db: &sled::Db) -> Result<()> {
346 if sled_db.get("rlnv2-diff-slash-pk")?.is_some() {
348 return Ok(())
349 }
350 let slash_zkbin = ZkBinary::decode(RLN2_SLASH_ZKBIN, false).unwrap();
351 let slash_empty_circuit = ZkCircuit::new(empty_witnesses(&slash_zkbin).unwrap(), &slash_zkbin);
352
353 info!(target: "irc::server", "[RLN] Creating RlnV2_Diff_Slash ProvingKey");
354 let verifyingkey = VerifyingKey::build(slash_zkbin.k, &slash_empty_circuit);
355 let mut buf = vec![];
356 verifyingkey.write(&mut buf)?;
357 sled_db.insert("rlnv2-diff-slash-pk", buf)?;
358 Ok(())
359}
360
361pub(super) fn read_slash_pk(sled_db: &sled::Db) -> Result<ProvingKey> {
363 if let Some(vk) = sled_db.get("rlnv2-diff-slash-pk")? {
364 let slash_zkbin = ZkBinary::decode(RLN2_SLASH_ZKBIN, false).unwrap();
365 let slash_empty_circuit =
366 ZkCircuit::new(empty_witnesses(&slash_zkbin).unwrap(), &slash_zkbin);
367 let mut reader = Cursor::new(vk);
368 Ok(ProvingKey::read(&mut reader, slash_empty_circuit)?)
369 } else {
370 Err(Error::Custom("Error Reading slash proving key".to_owned()))
371 }
372}
373
374pub(super) fn build_slash_vk(sled_db: &sled::Db) -> Result<()> {
376 if sled_db.get("rlnv2-diff-slash-vk")?.is_some() {
378 return Ok(())
379 }
380 let slash_zkbin = ZkBinary::decode(RLN2_SLASH_ZKBIN, false).unwrap();
381 let slash_empty_circuit = ZkCircuit::new(empty_witnesses(&slash_zkbin).unwrap(), &slash_zkbin);
382
383 info!(target: "irc::server", "[RLN] Creating RlnV2_Diff_Slash VerifyingKey");
384 let verifyingkey = VerifyingKey::build(slash_zkbin.k, &slash_empty_circuit);
385 let mut buf = vec![];
386 verifyingkey.write(&mut buf)?;
387 sled_db.insert("rlnv2-diff-slash-vk", buf)?;
388 Ok(())
389}
390
391pub(super) fn read_slash_vk(sled_db: &sled::Db) -> Result<VerifyingKey> {
393 if let Some(vk) = sled_db.get("rlnv2-diff-slash-pk")? {
394 let slash_zkbin = ZkBinary::decode(RLN2_SLASH_ZKBIN, false).unwrap();
395 let slash_empty_circuit =
396 ZkCircuit::new(empty_witnesses(&slash_zkbin).unwrap(), &slash_zkbin);
397 let mut reader = Cursor::new(vk);
398 Ok(VerifyingKey::read(&mut reader, slash_empty_circuit)?)
399 } else {
400 Err(Error::Custom("Error Reading slash verifying key".to_owned()))
401 }
402}