| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- /* This file is part of DarkFi (https://dark.fi)
- *
- * Copyright (C) 2020-2024 Dyne.org foundation
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
- //! <https://darkrenaissance.github.io/darkfi/crypto/rln.html>
- use darkfi::{
- zk::{empty_witnesses, halo2::Field, ProvingKey, VerifyingKey, ZkCircuit},
- zkas::ZkBinary,
- Result,
- };
- use darkfi_sdk::{crypto::MerkleTree, pasta::pallas};
- use darkfi_serial::serialize_async;
- use log::info;
- const RLN_IDENTIFIER: pallas::Base = pallas::Base::from_raw([0, 0, 42, 42]);
- const IDENTITY_DERIVATION_PATH: pallas::Base = pallas::Base::from_raw([0, 0, 42, 11]);
- const NULLIFIER_DERIVATION_PATH: pallas::Base = pallas::Base::from_raw([0, 0, 42, 12]);
- /// Rate-Limit-Nullifiers
- ///
- /// This mechanism is used for spam protection on the IRC network.
- pub struct Rln {
- /// DB holding identity commitments and the membership Merkle tree
- /// The scheme is `(k=identity_commitment, v=leaf_position)`
- identities: sled::Tree,
- /// DB holding identity roots
- identity_roots: sled::Tree,
- /// DB holding banned roots
- banned_roots: sled::Tree,
- /// Proving key for the signalling circuit
- signal_pk: ProvingKey,
- /// Verifying key for the signalling circuit
- signal_vk: VerifyingKey,
- /// Proving key for the slashing circuit
- slash_pk: ProvingKey,
- /// Verifying key for the slashing circuit
- slash_vk: VerifyingKey,
- }
- impl Rln {
- /// Create a new Rln instance
- pub async fn new(sled_db: &sled::Db) -> Result<Self> {
- let identities = sled_db.open_tree("identities")?;
- let identity_roots = sled_db.open_tree("identity_roots")?;
- let banned_roots = sled_db.open_tree("banned_roots")?;
- if !identities.contains_key(b"identity_tree")? {
- info!("Creating RLN membership tree");
- let membership_tree = MerkleTree::new(1);
- identities.insert(b"identity_tree", serialize_async(&membership_tree).await)?;
- }
- let signal_zkbin = include_bytes!("../proof/signal.zk.bin");
- let slash_zkbin = include_bytes!("../proof/slash.zk.bin");
- info!("Building RLN signal proving key");
- let signal_zkbin = ZkBinary::decode(signal_zkbin).unwrap();
- let signal_circuit = ZkCircuit::new(empty_witnesses(&signal_zkbin)?, &signal_zkbin);
- let signal_pk = ProvingKey::build(signal_zkbin.k, &signal_circuit);
- info!("Building RLN signal verifying key");
- let signal_vk = VerifyingKey::build(signal_zkbin.k, &signal_circuit);
- info!("Building RLN slash proving key");
- let slash_zkbin = ZkBinary::decode(slash_zkbin).unwrap();
- let slash_circuit = ZkCircuit::new(empty_witnesses(&slash_zkbin)?, &slash_zkbin);
- let slash_pk = ProvingKey::build(slash_zkbin.k, &slash_circuit);
- info!("Building RLN slash verifying key");
- let slash_vk = VerifyingKey::build(slash_zkbin.k, &slash_circuit);
- Ok(Self {
- identities,
- identity_roots,
- banned_roots,
- signal_pk,
- signal_vk,
- slash_pk,
- slash_vk,
- })
- }
- /// Recover a secret from given secret shares
- pub fn sss_recover(shares: &[(pallas::Base, pallas::Base)]) -> pallas::Base {
- let mut secret = pallas::Base::zero();
- for (j, share_j) in shares.iter().enumerate() {
- let mut prod = pallas::Base::one();
- for (i, share_i) in shares.iter().enumerate() {
- if i != j {
- prod *= share_i.0 * (share_i.0 - share_j.0).invert().unwrap();
- }
- }
- prod *= share_j.1;
- secret += prod;
- }
- secret
- }
- }
|