瀏覽代碼

research/rlnv2: Implement RLN2-DIFF

parazyd 1 年之前
父節點
當前提交
681a32cefc
共有 3 個文件被更改,包括 34 次插入48 次删除
  1. 0 4
      script/research/rln/rlnv2/Cargo.toml
  2. 10 10
      script/research/rln/rlnv2/signal.zk
  3. 24 34
      script/research/rln/rlnv2/src/main.rs

+ 0 - 4
script/research/rln/rlnv2/Cargo.toml

@@ -17,7 +17,3 @@ blake3 = "1.5.5"
 [patch.crates-io]
 halo2_proofs = {git="https://github.com/parazyd/halo2", branch="v4"}
 halo2_gadgets = {git="https://github.com/parazyd/halo2", branch="v4"}
-
-[lints]
-workspace = true
-

+ 10 - 10
script/research/rln/rlnv2/signal.zk

@@ -11,34 +11,34 @@ witness "RlnSignal" {
     Uint32 identity_leaf_pos,
 
     Base x, # The message hash
+    Base external_nullifier, # Hash(Epoch, RLN identifier)
+
     Base message_id,
-    Base message_limit,
+    Base user_message_limit,
 
-    # These are public
     Base epoch,
-    Base rln_identifier,
 }
 
 circuit "RlnSignal" {
-    constrain_instance(message_limit);
     constrain_instance(epoch);
-
-    external_nullifier = poseidon_hash(epoch, rln_identifier);
     constrain_instance(external_nullifier);
 
+    less_than_strict(message_id, user_message_limit);
+
+    # Identity secret hash
     a_0 = poseidon_hash(identity_nullifier, identity_trapdoor);
     a_1 = poseidon_hash(a_0, external_nullifier, message_id);
 
-    internal_nullifier = poseidon_hash(a_1);
-    constrain_instance(internal_nullifier);
-
     # y = a_0 + x * a_1
     x_a_1 = base_mul(x, a_1);
     y = base_add(a_0, x_a_1);
     constrain_instance(x);
     constrain_instance(y);
 
-    identity_commitment = poseidon_hash(a_0);
+    internal_nullifier = poseidon_hash(a_1);
+    constrain_instance(internal_nullifier);
+
+    identity_commitment = poseidon_hash(a_0, user_message_limit);
     root = merkle_root(identity_leaf_pos, identity_path, identity_commitment);
     constrain_instance(root);
 }

+ 24 - 34
script/research/rln/rlnv2/src/main.rs

@@ -36,25 +36,32 @@ struct Account {
     identity_nullifier: pallas::Base,
     identity_trapdoor: pallas::Base,
     identity_leaf_pos: Position,
-    msgid: pallas::Base,
+    user_message_limit: pallas::Base,
 }
 
 impl Account {
     fn register(
         membership_tree: &mut MerkleTree,
-        membership_map: &mut BTreeMap<Position, pallas::Base>,
+        membership_map: &mut BTreeMap<pallas::Base, Position>,
     ) -> Self {
         let identity_nullifier = pallas::Base::random(&mut OsRng);
         let identity_trapdoor = pallas::Base::random(&mut OsRng);
 
         let identity_secret_hash = poseidon_hash([identity_nullifier, identity_trapdoor]);
-        let identity_commitment = poseidon_hash([identity_secret_hash]);
+        let user_message_limit = pallas::Base::from(100);
+        let identity_commitment = poseidon_hash([identity_secret_hash, user_message_limit]);
 
         membership_tree.append(MerkleNode::from(identity_commitment));
         let identity_leaf_pos = membership_tree.mark().unwrap();
-        membership_map.insert(identity_leaf_pos, identity_commitment);
-
-        Self { identity_nullifier, identity_trapdoor, identity_leaf_pos }
+        membership_map.insert(identity_commitment, identity_leaf_pos);
+
+        Self {
+            identity_nullifier,
+            identity_trapdoor,
+            identity_leaf_pos,
+            // message id < user_message_limit
+            user_message_limit,
+        }
     }
 }
 
@@ -73,30 +80,18 @@ fn main() {
     // as the user registry.
     let mut membership_tree = MerkleTree::new(1);
     // Since bridgetree is append-only, we'll maintain a BTreeMap of all the
-    // identity commitments in their indexes and whenever some idenity is banned
+    // identity commitments and their indexes. Whenever some idenity is banned
     // we'll zero out that leaf and rebuild the bridgetree from the BTreeMap.
     let mut membership_map = BTreeMap::new();
 
-    // The global message limit per-account per-epoch
-    let message_limit = pallas::Base::from(3);
-
     // Per-app identifier
     let rln_identifier = pallas::Base::from(42);
 
     // Current epoch
     let epoch = pallas::Base::from(UNIX_EPOCH.elapsed().unwrap().as_secs() as u64);
 
-    // Register three accounts
+    // Register account
     let account0 = Account::register(&mut membership_tree, &mut membership_map);
-    let account0_msgid = pallas::Base::from(0);
-
-    /*
-    let account1 = Account::register(&mut membership_tree, &mut membership_map);
-    let account1_msgid = pallas::Base::from(0);
-
-    let account2 = Account::register(&mut membership_tree, &mut membership_map);
-    let account2_msgid = pallas::Base::from(0);
-    */
 
     // ==========
     // Signalling
@@ -121,13 +116,15 @@ fn main() {
     // =========================
 
     // 1. Construct share:
+    let message_id = pallas::Base::from(1);
     let external_nullifier = poseidon_hash([epoch, rln_identifier]);
     let a_0 = poseidon_hash([account0.identity_nullifier, account0.identity_trapdoor]);
-    let a_1 = poseidon_hash([a_0, external_nullifier, account0_msgid]);
-    let internal_nullifier = poseidon_hash([a_1]);
+    let a_1 = poseidon_hash([a_0, external_nullifier, message_id]);
     let x = hash_message("hello i wanna spam");
     let y = a_0 + x * a_1;
 
+    let internal_nullifier = poseidon_hash([a_1]);
+
     // 2. Create Merkle proof:
     let identity_root = membership_tree.root(0).unwrap();
     let identity_path = membership_tree.witness(account0.identity_leaf_pos, 0).unwrap();
@@ -139,21 +136,14 @@ fn main() {
         Witness::MerklePath(Value::known(identity_path.clone().try_into().unwrap())),
         Witness::Uint32(Value::known(u64::from(account0.identity_leaf_pos).try_into().unwrap())),
         Witness::Base(Value::known(x)),
-        Witness::Base(Value::known(account0_msgid)),
-        Witness::Base(Value::known(message_limit)),
+        Witness::Base(Value::known(external_nullifier)),
+        Witness::Base(Value::known(message_id)),
+        Witness::Base(Value::known(account0.user_message_limit)),
         Witness::Base(Value::known(epoch)),
-        Witness::Base(Value::known(rln_identifier)),
     ];
 
-    let public_inputs = vec![
-        message_limit,
-        epoch,
-        external_nullifier,
-        internal_nullifier,
-        x,
-        y,
-        identity_root.inner(),
-    ];
+    let public_inputs =
+        vec![epoch, external_nullifier, x, y, internal_nullifier, identity_root.inner()];
 
     print!("[Signal] Creating ZK proof for 0:0...");
     let now = Instant::now();