mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-01-09 14:48:08 -05:00
darkirc: Preliminary RLN code layout
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -1957,6 +1957,7 @@ dependencies = [
|
||||
"bs58",
|
||||
"crypto_box",
|
||||
"darkfi",
|
||||
"darkfi-sdk",
|
||||
"darkfi-serial",
|
||||
"easy-parallel",
|
||||
"futures",
|
||||
|
||||
@@ -9,7 +9,8 @@ homepage = "https://dark.fi"
|
||||
repository = "https://github.com/darkrenaissance/darkfi"
|
||||
|
||||
[dependencies]
|
||||
darkfi = {path = "../../", features = ["async-daemonize", "event-graph", "net", "util", "system", "rpc"]}
|
||||
darkfi = {path = "../../", features = ["async-daemonize", "event-graph", "net", "util", "system", "rpc", "zk"]}
|
||||
darkfi-sdk = {path = "../../src/sdk", features = ["async"]}
|
||||
darkfi-serial = {path = "../../src/serial", features = ["async"]}
|
||||
libc = "0.2.150"
|
||||
|
||||
|
||||
@@ -17,9 +17,17 @@ SRC = \
|
||||
|
||||
BIN = ../../darkirc
|
||||
|
||||
ZKAS = ../../zkas
|
||||
|
||||
ZKSRC = $(shell find proof -type f -name '*.zk')
|
||||
ZKBIN = $(ZKSRC:=.bin)
|
||||
|
||||
all: $(BIN)
|
||||
|
||||
$(BIN): $(SRC)
|
||||
$(ZKBIN): $(ZKAS) $(ZKSRC)
|
||||
$(ZKAS) $(basename $@) -o $@
|
||||
|
||||
$(BIN): $(ZKBIN) $(SRC)
|
||||
RUSTFLAGS="$(RUSTFLAGS)" $(CARGO) build --target=$(RUST_TARGET) --release --package darkirc
|
||||
cp -f ../../target/$(RUST_TARGET)/release/darkirc $@
|
||||
|
||||
|
||||
38
bin/darkirc/proof/signal.zk
Normal file
38
bin/darkirc/proof/signal.zk
Normal file
@@ -0,0 +1,38 @@
|
||||
k = 13;
|
||||
field = "pallas";
|
||||
|
||||
constant "RlnSignal" {}
|
||||
|
||||
witness "RlnSignal" {
|
||||
Base secret_key,
|
||||
MerklePath identity_path,
|
||||
Uint32 identity_leaf_pos,
|
||||
|
||||
# These are public so have to be properly constructed
|
||||
Base message_hash, # x
|
||||
Base epoch,
|
||||
Base rln_identifier,
|
||||
}
|
||||
|
||||
circuit "RlnSignal" {
|
||||
constrain_instance(epoch);
|
||||
constrain_instance(rln_identifier);
|
||||
constrain_instance(message_hash);
|
||||
|
||||
# This has to be the same constant used outside
|
||||
identity_derivation_path = witness_base(11);
|
||||
nullifier_derivation_path = witness_base(12);
|
||||
|
||||
identity_commit = poseidon_hash(identity_derivation_path, secret_key);
|
||||
root = merkle_root(identity_leaf_pos, identity_path, identity_commit);
|
||||
constrain_instance(root);
|
||||
|
||||
external_nullifier = poseidon_hash(epoch, rln_identifier);
|
||||
a_1 = poseidon_hash(secret_key, external_nullifier);
|
||||
internal_nullifier = poseidon_hash(nullifier_derivation_path, a_1);
|
||||
constrain_instance(internal_nullifier);
|
||||
|
||||
y_a = base_mul(a_1, message_hash);
|
||||
y = base_add(y_a, secret_key);
|
||||
constrain_instance(y);
|
||||
}
|
||||
18
bin/darkirc/proof/slash.zk
Normal file
18
bin/darkirc/proof/slash.zk
Normal file
@@ -0,0 +1,18 @@
|
||||
k = 13;
|
||||
field = "pallas";
|
||||
|
||||
constant "RlnSlash" {}
|
||||
|
||||
witness "RlnSlash" {
|
||||
Base secret_key,
|
||||
MerklePath identity_path,
|
||||
Uint32 identity_leaf_pos,
|
||||
}
|
||||
|
||||
circuit "RlnSlash" {
|
||||
identity_derivation_path = witness_base(11);
|
||||
|
||||
identity_commit = poseidon_hash(identity_derivation_path, secret_key);
|
||||
root = merkle_root(identity_leaf_pos, identity_path, identity_commit);
|
||||
constrain_instance(root);
|
||||
}
|
||||
@@ -45,6 +45,9 @@ use irc::server::IrcServer;
|
||||
/// Cryptography utilities
|
||||
mod crypto;
|
||||
|
||||
// RLN
|
||||
//mod rln;
|
||||
|
||||
/// JSON-RPC methods
|
||||
mod rpc;
|
||||
|
||||
@@ -108,7 +111,7 @@ struct Args {
|
||||
pub struct DarkIrc {
|
||||
/// P2P network pointer
|
||||
p2p: P2pPtr,
|
||||
/// Sled DB (also used in event_graph)
|
||||
/// Sled DB (also used in event_graph and for RLN)
|
||||
sled: sled::Db,
|
||||
/// Event Graph instance
|
||||
event_graph: EventGraphPtr,
|
||||
|
||||
113
bin/darkirc/src/rln.rs
Normal file
113
bin/darkirc/src/rln.rs
Normal file
@@ -0,0 +1,113 @@
|
||||
/* This file is part of DarkFi (https://dark.fi)
|
||||
*
|
||||
* Copyright (C) 2020-2023 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(100);
|
||||
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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user