Эх сурвалжийг харах

[crypsinous zk/circuit/lead_contract] add nullifier prefix

mohab metwally 4 жил өмнө
parent
commit
346cb9046b

+ 35 - 6
bin/crypsinous/src/main.rs

@@ -8,18 +8,19 @@ use futures::executor::block_on;
 use url::Url;
 use std::thread;
 
-fn main()
+#[async_std::main]
+async fn main()
 {
-    let slots=22;
+    let slots=3;
     let epochs=3;
-    let ticks=22;
+    let ticks=10;
     let reward=1;
     let epoch_consensus = EpochConsensus::new(Some(slots), Some(epochs), Some(ticks), Some(reward));
     /// read n from the cmd
     let n = 3;
     /// initialize n stakeholders
     //let mut stakeholders = vec!();
-    let settings = Settings{
+    let alice_settings = Settings {
         inbound: Some(Url::parse("tls://127.0.0.1:12002").unwrap()),
         outbound_connections: 4,
         manual_attempt_limit: 0,
@@ -33,10 +34,38 @@ fn main()
                 Url::parse("tls://irc1.dark.fi:11001").unwrap()
         ].to_vec(),
     };
+    let bob_settings = Settings {
+        inbound: Some(Url::parse("tls://127.0.0.1:12003").unwrap()),
+        outbound_connections: 4,
+        manual_attempt_limit: 0,
+        seed_query_timeout_seconds: 8,
+        connect_timeout_seconds: 10,
+        channel_handshake_seconds: 4,
+        channel_heartbeat_seconds: 10,
+        external_addr: Some(Url::parse("tls://127.0.0.1:12003").unwrap()),
+        peers: [Url::parse("tls://127.0.0.1:12002").unwrap()].to_vec(),
+        seeds: [Url::parse("tls://irc0.dark.fi:11001").unwrap(),
+                Url::parse("tls://irc1.dark.fi:11001").unwrap()
+        ].to_vec(),
+    };
     let k : u32 = 13; //proof's number of rows
     let mut handles = vec!();
-    for i in 0..n {
-        let mut stakeholder = block_on(Stakeholder::new(epoch_consensus.clone(), settings.clone(), Some(k))).unwrap();
+    let path = "db";
+    for i in 0..2 {
+        let rel_path =  format!("{}{}",path, i.to_string());
+
+        let mut stakeholder = block_on(Stakeholder::new(epoch_consensus.clone(),
+                                                        if i==0 {
+                                                            alice_settings.clone()
+                                                        }
+                                                        else {
+                                                            bob_settings.clone()
+                                                        },
+                                                        &rel_path,
+                                                        i,
+                                                        Some(k))
+        ).unwrap();
+
         let handle = thread::spawn(move || {
             block_on(stakeholder.background());
         });

+ 9 - 23
example/lead.rs

@@ -22,7 +22,7 @@ use darkfi::{
     util::time::{Timestamp},
     crypto::{
         constants::MERKLE_DEPTH_ORCHARD,
-        leadcoin::LeadCoin,
+        leadcoin::{LeadCoin,LEAD_PUBLIC_INPUT_LEN},
         lead_proof,
         merkle_node::MerkleNode,
     },
@@ -58,7 +58,7 @@ fn main() {
     };
     let consensus = EpochConsensus::new(Some(22), Some(3), Some(22), Some(0));
 
-    let stakeholder : Stakeholder = block_on(Stakeholder::new(consensus, settings, Some(k))).unwrap();
+    let stakeholder : Stakeholder = block_on(Stakeholder::new(consensus, settings, "db", 0,  Some(k))).unwrap();
 
     let eta : pallas::Base = stakeholder.get_eta();
     let mut epoch = Epoch {
@@ -72,29 +72,15 @@ fn main() {
     let coin = coins[coin_idx];
     let contract = coin.create_contract();
 
-    /*
+    let public_inputs : [pallas::Base;LEAD_PUBLIC_INPUT_LEN] = coin.public_inputs_as_array();
+
     let lead_pk = stakeholder.get_provkingkey();
     let lead_vk = stakeholder.get_verifyingkey();
 
+    let proof = lead_proof::create_lead_proof(&lead_pk.clone(), coin.clone()).unwrap();
+    lead_proof::verify_lead_proof(&lead_vk, &proof, &public_inputs);
 
-    //
-    //let proof = lead_proof::create_lead_proof(lead_pk.clone(), coin.clone());
-
-    //TODO (fix) proof panics
-    let lead_tx = TransactionLeadProof::new(lead_pk, coin.clone());
-
-    //lead_tx.verify(lead_vk, coin);
-
-    let (st_id, st_hash)  = stakeholder.blockchain.last().unwrap();
-    let empty_txs : Vec<Transaction> = vec!();
-    let metadata = Metadata::new(Timestamp::current_time(), epoch.eta.to_repr(), lead_tx);
-    let sm = StreamletMetadata::new(vec!());
-    let bk_info = BlockInfo::new(st_hash, 1, 0, empty_txs, metadata, sm);
-    let blks = [bk_info];
-    stakeholder.blockchain.add(&blks);
-    */
-    // calculate public inputs
-    let public_inputs = coin.public_inputs();
-    let prover = MockProver::run(k, &contract, vec![public_inputs]).unwrap();
-    assert_eq!(prover.verify(), Ok(()));
+    //let prover = MockProver::run(k, &contract, vec![public_inputs.to_vec()]).unwrap();
+    //prover.assert_satisfied();
+    //assert_eq!(prover.verify(), Ok(()));
 }

+ 15 - 6
src/blockchain/epoch.rs

@@ -24,6 +24,8 @@ use crate::{
     },
 };
 
+const PRF_NULLIFIER_PREFIX : u64 = 0;
+
 const MERKLE_DEPTH: u8 = MERKLE_DEPTH_ORCHARD as u8;
 
 #[derive(Copy,Debug,Default,Clone)]
@@ -198,11 +200,12 @@ impl Epoch {
 
 
             let coin_commit_msg_input = [
+                pallas::Base::from(PRF_NULLIFIER_PREFIX),
                 c_pk,
                 c_v,
                 c_seed
             ];
-            let coin_commit_msg : pallas::Base = poseidon::Hash::<_, poseidon::P128Pow5T3, poseidon::ConstantLength<3>, 3, 2>::init().hash(coin_commit_msg_input);
+            let coin_commit_msg : pallas::Base = poseidon::Hash::<_, poseidon::P128Pow5T3, poseidon::ConstantLength<4>, 3, 2>::init().hash(coin_commit_msg_input);
             let c_cm: pallas::Point = pedersen_commitment_base(coin_commit_msg, c_cm1_blind);
             let c_cm_coordinates = c_cm.to_affine().coordinates().unwrap();
             let c_cm_base: pallas::Base = c_cm_coordinates.x() * c_cm_coordinates.y();
@@ -219,11 +222,12 @@ impl Epoch {
             let c_seed2 : pallas::Base = poseidon::Hash::<_, poseidon::P128Pow5T3, poseidon::ConstantLength<2>, 3, 2>::init().hash(coin_nonce2_msg);
 
             let coin2_commit_msg_input = [
+                pallas::Base::from(PRF_NULLIFIER_PREFIX),
                 c_pk,
                 c_v,
-                c_seed,
+                c_seed2,
             ];
-            let coin2_commit_msg : pallas::Base = poseidon::Hash::<_, poseidon::P128Pow5T3, poseidon::ConstantLength<3>, 3, 2>::init().hash(coin2_commit_msg_input);
+            let coin2_commit_msg : pallas::Base = poseidon::Hash::<_, poseidon::P128Pow5T3, poseidon::ConstantLength<4>, 3, 2>::init().hash(coin2_commit_msg_input);
             let c_cm2 = pedersen_commitment_base(coin2_commit_msg, c_cm2_blind);
 
             let c_root_sk = root_sks[i];
@@ -266,6 +270,9 @@ impl Epoch {
     /// see if the participant stakeholder of this epoch is
     /// winning the lottery, in case of success return True
     pub fn is_leader(&self, sl: u64) -> bool {
+        let slusize = sl as usize;
+        println!("slot: {}, coin len: {}", sl, self.coins.len());
+        assert!(slusize < self.coins.len()  && sl>=0);
         let coin = self.coins[sl as usize];
         let y_exp = [
             coin.root_sk.unwrap(),
@@ -274,12 +281,14 @@ impl Epoch {
         let y_exp_hash : pallas::Base = poseidon::Hash::<_, poseidon::P128Pow5T3, poseidon::ConstantLength<2>,3,2>::init().hash(y_exp);
         // pick x coordiante of y for comparison
         let y_x : pallas::Base = *pedersen_commitment_base(coin.y_mu.unwrap(), mod_r_p(y_exp_hash)).to_affine().coordinates().unwrap().x();
-        let ord = pallas::Base::from(1024); //TODO fine tune this scalar.
+        let ord = pallas::Base::from(10241024); //TODO fine tune this scalar.
         let target = ord*coin.value.unwrap();
-        y_x < target
+        println!("y_x: {:?}, target: {:?}", y_x, target);
+        //reversed for testing
+        target < y_x
     }
 
-    pub fn get_proof(&self, sl: u64, pk: ProvingKey) -> Proof {
+    pub fn get_proof(&self, sl: u64, pk: &ProvingKey) -> Proof {
         let coin = self.coins[sl as usize];
         lead_proof::create_lead_proof(pk, coin).unwrap()
     }

+ 4 - 3
src/consensus/metadata.rs

@@ -5,6 +5,7 @@ use crate::{
         time::Timestamp,
     },
     crypto::{
+        types::*,
         proof::{
             Proof,
             ProvingKey,
@@ -60,15 +61,15 @@ impl Default for TransactionLeadProof {
 }
 
 impl TransactionLeadProof {
-    pub fn new(pk : ProvingKey, coin: LeadCoin) -> Self
+    pub fn new(pk : &ProvingKey, coin: LeadCoin) -> Self
     {
         let proof = lead_proof::create_lead_proof(pk, coin.clone()).unwrap();
         Self { lead_proof: proof }
     }
 
-    pub fn verify(&self, vk : VerifyingKey, coin: LeadCoin) -> VerifyResult<()>
+    pub fn verify(&self, vk : VerifyingKey, public_inputs: &[DrkCircuitField]) -> VerifyResult<()>
     {
-        lead_proof::verify_lead_proof(&vk, &self.lead_proof, coin)
+        lead_proof::verify_lead_proof(&vk, &self.lead_proof, public_inputs)
     }
 }
 

+ 11 - 5
src/crypto/lead_proof.rs

@@ -11,6 +11,7 @@ use rand::rngs::OsRng;
 
 use crate::{
     crypto::{
+        types::*,
         leadcoin::LeadCoin,
         proof::{Proof, ProvingKey, VerifyingKey},
         util::mod_r_p,
@@ -21,20 +22,25 @@ use crate::{
 
 use rand::{thread_rng, Rng};
 
-#[allow(clippy::too_many_arguments)]
-pub fn create_lead_proof(pk: ProvingKey, coin: LeadCoin) -> Result<Proof> {
+//#[allow(clippy::too_many_arguments)]
+pub fn create_lead_proof(pk: &ProvingKey, coin: LeadCoin) -> Result<Proof> {
+    println!("[creating lead proof]");
     let contract = coin.create_contract();
     //let start = Instant::now();
+    println!("[creating lead proof] public inputs");
     let public_inputs = coin.public_inputs();
+    println!("[creating lead proof] Proof create");
     let proof = Proof::create(&pk, &[contract], &public_inputs, &mut OsRng)?;
+    println!("[creating lead proof] proof successfully created");
     //debug!("Prove lead: [{:?}]", start.elapsed());
     Ok(proof)
 }
 
-pub fn verify_lead_proof(vk: &VerifyingKey, proof: &Proof, coin: LeadCoin) -> VerifyResult<()> {
+pub fn verify_lead_proof(vk: &VerifyingKey,
+                         proof: &Proof,
+                         public_inputs: &[DrkCircuitField]) -> VerifyResult<()> {
     let start = Instant::now();
-    let public_inputs = coin.public_inputs();
-    match proof.verify(vk, &public_inputs) {
+    match proof.verify(vk, public_inputs) {
         Ok(()) => {Ok(())},
         Err(e) => {
             error!("lead verification failed: {}", e);

+ 12 - 3
src/crypto/leadcoin.rs

@@ -15,6 +15,8 @@ use pasta_curves::{arithmetic::CurveAffine, group::Curve};
 
 //use halo2_proofs::arithmetic::CurveAffine;
 
+pub const LEAD_PUBLIC_INPUT_LEN : usize = 8;
+
 #[derive(Debug, Default, Clone, Copy)]
 pub struct LeadCoin {
     pub value: Option<pallas::Base>, //stake
@@ -40,7 +42,7 @@ pub struct LeadCoin {
 }
 
 impl LeadCoin {
-    pub fn public_inputs(&self) -> Vec<pallas::Base> {
+    pub fn public_inputs_as_array(&self) -> [pallas::Base;LEAD_PUBLIC_INPUT_LEN] {
         let po_nonce = self.nonce_cm.unwrap();
         let _po_tau = pedersen_commitment_base(self.tau.unwrap(), self.root_cm.unwrap())
             .to_affine()
@@ -73,19 +75,26 @@ impl LeadCoin {
             }
             current
         };
-        let public_inputs: Vec<pallas::Base> = vec![
+        let public_inputs : [pallas::Base;LEAD_PUBLIC_INPUT_LEN] = [
             po_pk,
             po_sn,
+
             *po_cm.x(),
             *po_cm.y(),
+
             *po_cm2.x(),
             *po_cm2.y(),
+
             po_nonce,
-            //cm_root.0,
+            cm_root.0,
         ];
         public_inputs
     }
 
+    pub fn public_inputs(&self) -> Vec<pallas::Base> {
+        self.public_inputs_as_array().to_vec()
+    }
+
     pub fn create_contract(&self) -> LeadContract
     {
         let contract = LeadContract {

+ 0 - 1
src/crypto/proof.rs

@@ -52,7 +52,6 @@ impl AsRef<[u8]> for Proof {
         &self.0
     }
 }
-
 impl Proof {
     pub fn create(
         pk: &ProvingKey,

+ 36 - 10
src/stakeholder/stakeholder.rs

@@ -2,6 +2,10 @@ use async_executor::Executor;
 use async_trait::async_trait;
 use async_std::sync::Arc;
 use log::debug;
+use std::fmt;
+
+use std::time::Duration;
+use std::thread;
 
 use crate::zk::circuit::LeadContract;
 
@@ -10,6 +14,7 @@ use crate::{
     util::{
         time::Timestamp,
         clock::{Clock,Ticks},
+        expand_path,
     },
     system::{Subscriber, SubscriberPtr, Subscription},
     crypto::{
@@ -96,6 +101,7 @@ impl SlotWorkspace {
     }
 }
 
+
 pub struct Stakeholder
 {
     pub blockchain: Blockchain, // stakeholder view of the blockchain
@@ -108,6 +114,7 @@ pub struct Stakeholder
     pub vk : VerifyingKey,
     pub playing: bool,
     pub workspace : SlotWorkspace,
+    pub id: u8,
     //pub subscription: Subscription<Result<ChannelPtr>>,
     //pub chanptr : ChannelPtr,
     //pub msgsub : MessageSubscription::<BlockInfo>,
@@ -115,11 +122,12 @@ pub struct Stakeholder
 
 impl Stakeholder
 {
-    pub async fn new(consensus: EpochConsensus, settings: Settings, k: Option<u32>) -> Result<Self>
+    pub async fn new(consensus: EpochConsensus, settings: Settings, rel_path: &str, id: u8, k: Option<u32>) -> Result<Self>
     {
-        let path = "tmp";
-        let db = sled::open(path).unwrap();
-
+        let path = expand_path(&rel_path).unwrap();
+        println!("opening db");
+        let db = sled::open(&path)?;
+        println!("opend db");
         let ts = Timestamp::current_time();
         let genesis_hash = blake3::hash(b"");
         //TODO lisen and add transactions
@@ -131,16 +139,15 @@ impl Stakeholder
         let epoch = Epoch::new(consensus, eta);
 
         let lead_pk = ProvingKey::build(k.unwrap(), &LeadContract::default());
-
         let lead_vk = VerifyingKey::build(k.unwrap(), &LeadContract::default());
         let p2p = P2p::new(settings.clone()).await;
 
         //TODO
         let workspace = SlotWorkspace::default();
 
-
         //
         let clock = Clock::new(Some(consensus.get_epoch_len()), Some(consensus.get_slot_len()), Some(consensus.get_tick_len()), settings.peers);
+        println!("stakeholder constructed...");
         Ok(Self{blockchain: bc,
                 net: p2p,
                 clock: clock,
@@ -148,10 +155,11 @@ impl Stakeholder
                 // but should be populated from wallet db.
                 epoch: epoch,
                 epoch_consensus: consensus,
-                pk:lead_pk,
-                vk:lead_vk,
+                pk: lead_pk,
+                vk: lead_vk,
                 playing: true,
                 workspace: workspace,
+                id: id,
                 //subscription: subscription,
                 //chanptr: chanptr,
                 //msgsub: msg_sub,
@@ -260,7 +268,7 @@ impl Stakeholder
             //TODO if valid only.
             self.blockchain.add(&[blk.clone()]);
         } else {
-            debug!("received block is invalid!");
+            println!("received block is invalid!");
         }
     }
 
@@ -306,14 +314,19 @@ impl Stakeholder
                     self.sync_block();
                 }
             }
+            thread::sleep(Duration::from_millis(1000));
         }
     }
 
+    pub fn to_string(&self) -> String {
+        format!("stakeholder with id:{}", self.id.to_string())
+    }
     /// on the onset of the epoch, layout the new the competing coins
     /// assuming static stake during the epoch, enforced by the commitment to competing coins
     /// in the epoch's gen2esis data.
     fn new_epoch(&mut self)
     {
+        println!("[new epoch] 4 {}", self);
         let eta = self.get_eta();
         let mut epoch = Epoch::new(self.epoch_consensus, self.get_eta());
         epoch.create_coins(); // set epoch interal fields working space with competing coins
@@ -329,6 +342,7 @@ impl Stakeholder
     /// this will encourage each potential leader to play with honesty.
     fn new_slot(&mut self, e: u64, sl: u64)
     {
+        println!("[new slot] 4 {}\ne:{}, sl:{}", self, e, sl);
         let EMPTY_PTR = blake3::hash(b"");
         let st : blake3::Hash = if e>0 || (e==0&&sl>0) {
             self.workspace.block.blockhash()
@@ -338,7 +352,8 @@ impl Stakeholder
         let is_leader : bool = self.epoch.is_leader(sl);
         // if is leader create proof
         let proof = if is_leader {
-            self.epoch.get_proof(sl, self.pk.clone())
+            println!("<<<--- [[[leadership won]]] --->>>");
+            self.epoch.get_proof(sl, &self.pk.clone())
         } else {
             Proof::new(vec![])
         };
@@ -350,6 +365,7 @@ impl Stakeholder
         self.workspace.set_proof(proof.clone());
         //
         if is_leader {
+            println!("<<<--- [[[leadership won]]] --->>>");
             let metadata = Metadata::new(Timestamp::current_time(),
                                          self.get_eta().to_repr(),
                                          TransactionLeadProof::from(proof.clone()));
@@ -357,3 +373,13 @@ impl Stakeholder
         }
     }
 }
+
+impl fmt::Display
+
+
+
+for Stakeholder {
+    fn fmt(&self, formater : &mut fmt::Formatter) ->  fmt::Result {
+        formater.write_fmt(format_args!("stakeholder with id: {}", self.id))
+    }
+}

+ 45 - 15
src/util/clock.rs

@@ -1,8 +1,10 @@
 use url::Url;
 use log::debug;
+use std::time::Duration;
+use std::thread;
 use async_trait::async_trait;
 use crate::{
-    util::{time,Timestamp},
+    util::{time,Timestamp, NanoTimestamp},
     error,
     Result,
     error::Error
@@ -17,9 +19,8 @@ pub enum Ticks {
     OUTOFSYNC, //clock, and blockchain are out of sync
 }
 
-const BB_SL : u64 = u64::MAX; //big bang slot time (need to be negative value)
+const BB_SL : u64 = u64::MAX-1; //big bang slot time (need to be negative value)
 const BB_E : u64 = 0; //big bang epoch time.
-const GENESIS_TIME : i64 = 0;
 
 #[derive(Debug)]
 pub struct Clock {
@@ -29,16 +30,19 @@ pub struct Clock {
     pub sl_len: u64, // slot length in ticks
     pub e_len: u64, // epoch length in slots
     pub peers: Vec<Url>,
+    pub genesis_time: Timestamp,
 }
 
 impl Clock {
     pub fn new(e_len: Option<u64>, sl_len: Option<u64>, tick_len: Option<u64>, peers: Vec<Url>) -> Self{
+        let gt : Timestamp = Timestamp::current_time();
         Self { sl: BB_SL, //necessary for genesis slot
                e: BB_E,
                tick_len: tick_len.unwrap_or(22), // 22 seconds
                sl_len: sl_len.unwrap_or(22),// ~8 minutes
                e_len: e_len.unwrap_or(3), // 24.2 minutes
                peers: peers,
+               genesis_time: gt,
         }
     }
 
@@ -51,20 +55,36 @@ impl Clock {
     }
 
     async fn time(&self) -> Result<Timestamp> {
+        //TODO (fix) add more than ntp server to time.
+        /*
         match time::check_clock(self.peers.clone()).await {
             Ok(t) => {
                 Ok(time::ntp_request().await?)
             },
             Err(e) => {
-                Err(Error::ClockOutOfSync(e.to_string()
-))
+                Err(Error::ClockOutOfSync(e.to_string()))
             }
         }
+         */
+        //TODO (panics)
+        /*
+        match time::ntp_request().await.unwrap() {
+            t => {
+                Ok(t)
+            },
+            e => {
+                println!("ntp request failed: {}", e);
+                Err(Error::ClockOutOfSync(e.to_string()))
+            }
+    }
+         */
+        Ok(Timestamp::current_time())
     }
 
     /// time since genesis
     async fn time_to_genesis(&self) -> Timestamp {
-        let genesis_time : i64 = GENESIS_TIME;
+        //TODO this value need to be assigned to kickoff time.
+        let genesis_time : i64 = self.genesis_time.0;
         let abs_time = self.time().await.unwrap();
         Timestamp(abs_time.0 - genesis_time)
     }
@@ -72,14 +92,15 @@ impl Clock {
     async fn tick_time(&self) -> (u64, u64) {
         let time = self.time_to_genesis().await;
         let time_i = time.0 as u64;
-        let tick_abs: u64 = time_i / self.tick_len;
+        //let tick_abs: u64 = time_i / self.tick_len;
         let tick_rel: u64 = time_i % self.tick_len;
-        (tick_abs, tick_rel)
+        (time_i, tick_rel)
     }
 
     /// return true if the clock is at the begining (before 2/3 of the slot).
     async fn ticking(&self) -> bool {
         let (abs, rel) =  self.tick_time().await;
+        println!("abs ticks: {}, rel ticks: {}", abs, rel);
         rel < (self.tick_len) /3
     }
 
@@ -94,48 +115,57 @@ impl Clock {
     /// absolute zero based slot index
     async fn slot_abs(&self) -> u64 {
         let sl_abs = self.tick_time().await.0 / self.sl_len;
+        println!("[slot_abs] slot len: {} - slot abs: {}", self.sl_len, sl_abs);
         sl_abs
     }
 
     /// relative zero based slot index
     async fn  slot_relative(&self) -> u64 {
         let e_abs = self.slot_abs().await % self.e_len;
+        println!("[slot_relative] slot len: {} - slot relative: {}", self.sl_len, e_abs);
         e_abs
     }
 
     /// absolute zero based epoch index.
     async fn epoch_abs(&self) -> u64 {
         let res = self.slot_abs().await / self.e_len;
+        println!("[epoch_abs] epoch len: {} - epoch abs: {}", self.e_len, res);
         res
     }
 
     /// clock ticks return the ticks phase with corresponding phase parameters
     pub async fn ticks(&mut self) -> Ticks {
-        let prev_e = self.e;
-        let prev_sl = self.sl;
         let e = self.epoch_abs().await;
         let sl = self.slot_relative().await;
         if self.ticking().await {
-            if e==prev_e&&e==BB_E && sl==prev_sl && sl==BB_SL {
-                self.sl=sl; // 0
+            println!("e/e`: {}/{} sl/sl`: {}/{}, BB_E/BB_SL: {}/{}", e, self.e, sl, self.sl, BB_E, BB_SL);
+            if e==self.e&&e==BB_E &&  self.sl==BB_SL {
+                self.sl=sl+1; // 0
                 self.e=e; // 0
+                println!("new genesis");
                 Ticks::GENESIS{e:e, sl:sl}
-            } else if e==prev_e&&sl==prev_sl+1 {
+            } else if e==self.e&&sl==self.sl+1 {
                 self.sl=sl;
+                println!("new slot");
                 Ticks::NEWSLOT{e:e, sl:sl}
-            } else if e==prev_e+1 && sl==0 {
+            } else if e==self.e+1 && sl==0 {
                 self.e=e;
                 self.sl=sl;
+                println!("new epoch");
                 Ticks::NEWEPOCH{e:e, sl:sl}
             }
-            else if e==prev_e && sl==prev_sl {
+            else if e==self.e && sl==self.sl {
+                println!("clock is idle");
+                thread::sleep(Duration::from_millis(100));
                 Ticks::IDLE
             }
             else {
+                println!("clock is out of sync");
                 //clock is out of sync
                 Ticks::OUTOFSYNC
             }
         } else {
+            println!("tocks");
             Ticks::TOCKS
         }
     }

+ 58 - 55
src/zk/circuit/lead_contract.rs

@@ -42,10 +42,12 @@ const WINDOW_SIZE: usize = 3;
 const NUM_OF_BITS: usize = 254;
 const NUM_OF_WINDOWS: usize = 85;
 
+const PRF_NULLIFIER_PREFIX : u64 = 0;
+
 #[derive(Clone, Debug)]
 pub struct LeadConfig {
     primary: Column<InstanceColumn>,
-    advices: [Column<Advice>; 12],
+    advices: [Column<Advice>; 10],
     ecc_config: EccConfig<OrchardFixedBases>,
     poseidon_config: PoseidonConfig<pallas::Base, 3, 2>,
     merkle_config_1: MerkleConfig<OrchardHashDomains, OrchardCommitDomains, OrchardFixedBases>,
@@ -94,7 +96,7 @@ impl LeadConfig {
 
     fn arith_chip(&self) -> ArithChip {
         ArithChip::construct(self.arith_config.clone())
-    }
+     }
 }
 
 
@@ -161,8 +163,8 @@ impl Circuit<pallas::Base> for LeadContract {
             meta.advice_column(),
             meta.advice_column(),
             meta.advice_column(),
-            meta.advice_column(),
-            meta.advice_column(),
+            //meta.advice_column(),
+            //meta.advice_column(),
         ];
 
         let table_idx = meta.lookup_table_column();
@@ -236,6 +238,7 @@ impl Circuit<pallas::Base> for LeadContract {
 
         let k_values_table = meta.lookup_table_column();
 
+
         let lessthan_config = {
             let a = meta.advice_column();
             let b = meta.advice_column();
@@ -252,7 +255,8 @@ impl Circuit<pallas::Base> for LeadContract {
                 k_values_table,
             )
 
-        };
+    };
+
         //let evenbits_config = EvenBitsChip::<pallas::Base, WORD_BITS>::configure(meta);
 
         let arith_config = ArithChip::configure(meta, advices[7], advices[8], advices[6]);
@@ -267,43 +271,42 @@ impl Circuit<pallas::Base> for LeadContract {
             sinsemilla_config_1,
             _sinsemilla_config_2: sinsemilla_config_2,
             lessthan_config,
-            //evenbits_config,
             arith_config,
         }
     }
 
-    fn synthesize(
+    fn synthesize (
         &self,
         config: Self::Config,
         mut layouter: impl Layouter<pallas::Base>,
     ) -> Result<(), Error> {
-        let less_than_chip = config.lessthan_chip();
 
+        let less_than_chip = config.lessthan_chip();
         NativeRangeCheckChip::<WINDOW_SIZE, NUM_OF_BITS, NUM_OF_WINDOWS>::load_k_table(
             &mut layouter,
             config.lessthan_config.k_values_table,
         )?;
-
         SinsemillaChip::load(config.sinsemilla_config_1.clone(), &mut layouter)?;
         let ecc_chip = config.ecc_chip();
         let ar_chip = config.arith_chip();
         let _ps_chip = config.poseidon_chip();
 
-
-
-
         // ===============
         // load witnesses
         // ===============
 
-
-
         let one = self.load_private(
             layouter.namespace(|| "one"),
             config.advices[0],
             Value::known(pallas::Base::one()),
         )?;
 
+        let prf_nullifier_prefix_base = self.load_private(
+            layouter.namespace(|| "PRF NULLIFIER PREFIX BASE"),
+            config.advices[0],
+            Value::known(pallas::Base::from(PRF_NULLIFIER_PREFIX)),
+        )?;
+
         let zero = self.load_private(
             layouter.namespace(|| "one"),
             config.advices[0],
@@ -334,11 +337,12 @@ impl Circuit<pallas::Base> for LeadContract {
             self.coin_pk,
         )?;
 
+
         //used for fine tuning the leader election frequency
         let scalar = self.load_private(
             layouter.namespace(|| "load scalar "),
             config.advices[0],
-            Value::known(pallas::Base::from(1024)),
+            Value::known(pallas::Base::from(10241024)),
         )?;
         //leadership coefficient
 
@@ -348,29 +352,11 @@ impl Circuit<pallas::Base> for LeadContract {
             Value::known(pallas::Base::one()), // note! this parameter to be tuned.
         )?;
 
-        let _slot = self.load_private(layouter.namespace(|| ""), config.advices[0], self.slot)?;
 
         let _root_sk =
             self.load_private(layouter.namespace(|| ""), config.advices[0], self.root_sk)?;
 
-        // ===============
-        // nonce2  =  PRF_{root_sk}(coin_nonce)
-        // ===============
-        let coin2_nonce : AssignedCell<Fp,Fp> = {
-            let poseidon_message = [
-                coin_nonce.clone(),
-                _root_sk.clone()
-            ];
-            let poseidon_hasher = PoseidonHash::<_, _, poseidon::P128Pow5T3, poseidon::ConstantLength<2>, 3, 2>::init(
-                config.poseidon_chip(),
-                layouter.namespace(|| "Poseidon init"),
-            )?;
 
-            let poseidon_output =
-                poseidon_hasher.hash(layouter.namespace(|| "Poseidon hash"), poseidon_message)?;
-            let poseidon_output: AssignedCell<Fp, Fp> = poseidon_output;
-            poseidon_output
-        };
 
         // ================
         // coin public key pk=PRF_{root_sk}(tau)
@@ -428,24 +414,24 @@ impl Circuit<pallas::Base> for LeadContract {
             LEAD_COIN_SERIAL_NUMBER_OFFSET,
         )?;
 
+        let nullifier_msg : AssignedCell<Fp,Fp> = {
+            let poseidon_message =  [
+                prf_nullifier_prefix_base.clone(),
+                coin_pk.clone(),
+                coin_value.clone(),
+                coin_nonce.clone(),
+            ];
+            let poseidon_hasher = PoseidonHash::<_, _, poseidon::P128Pow5T3, poseidon::ConstantLength<4>, 3, 2>::init(
+                config.poseidon_chip(),
+                layouter.namespace(|| "Poseidon init"),
+            )?;
 
-        let com = {
-            let nullifier_msg : AssignedCell<Fp,Fp> = {
-                let poseidon_message = [
-                    coin_pk.clone(),
-                    coin_value.clone(),
-                    coin_nonce.clone(),
-                ];
-                let poseidon_hasher = PoseidonHash::<_, _, poseidon::P128Pow5T3, poseidon::ConstantLength<3>, 3, 2>::init(
-                    config.poseidon_chip(),
-                    layouter.namespace(|| "Poseidon init"),
-                )?;
+            let poseidon_output = poseidon_hasher.hash(layouter.namespace(|| "Poseidon hash"), poseidon_message)?;
+            let poseidon_output: AssignedCell<Fp, Fp> = poseidon_output;
+            poseidon_output
+        };
 
-                let poseidon_output =
-                    poseidon_hasher.hash(layouter.namespace(|| "Poseidon hash"), poseidon_message)?;
-                let poseidon_output: AssignedCell<Fp, Fp> = poseidon_output;
-                poseidon_output
-            };
+        let com = {
             // ================================================
             // coin commiment H=COMMIT(pk||V||nonce||r)
             // ================================================
@@ -473,6 +459,7 @@ impl Circuit<pallas::Base> for LeadContract {
             config.primary,
             LEAD_COIN_COMMIT_X_OFFSET,
         )?;
+
         // constrain coin's pub key y value
         layouter.constrain_instance(
             coin_commit_y.cell(),
@@ -483,15 +470,15 @@ impl Circuit<pallas::Base> for LeadContract {
         // ================================================
         // coin2 commiment H=COMMIT(pk||V||nonce2||r2)
         // ================================================
-
         let com2 = {
             let nullifier2_msg : AssignedCell<Fp,Fp> = {
                 let poseidon_message = [
+                    prf_nullifier_prefix_base.clone(),
                     coin_pk.clone(),
                     coin_value.clone(),
                     coin_nonce.clone(),
                 ];
-                let poseidon_hasher = PoseidonHash::<_, _, poseidon::P128Pow5T3, poseidon::ConstantLength<3>, 3, 2>::init(
+                let poseidon_hasher = PoseidonHash::<_, _, poseidon::P128Pow5T3, poseidon::ConstantLength<4>, 3, 2>::init(
                     config.poseidon_chip(),
                     layouter.namespace(|| "Poseidon init"),
                 )?;
@@ -531,7 +518,24 @@ impl Circuit<pallas::Base> for LeadContract {
             LEAD_COIN_COMMIT2_Y_OFFSET,
     )?;
 
+        // ===============
+        // nonce2  =  PRF_{root_sk}(coin_nonce)
+        // ===============
+        let coin2_nonce : AssignedCell<Fp,Fp> = {
+        let poseidon_message = [
+        coin_nonce.clone(),
+        _root_sk.clone()
+        ];
+        let poseidon_hasher = PoseidonHash::<_, _, poseidon::P128Pow5T3, poseidon::ConstantLength<2>, 3, 2>::init(
+        config.poseidon_chip(),
+        layouter.namespace(|| "Poseidon init"),
+    )?;
 
+        let poseidon_output =
+        poseidon_hasher.hash(layouter.namespace(|| "Poseidon hash"), poseidon_message)?;
+        let poseidon_output: AssignedCell<Fp, Fp> = poseidon_output;
+        poseidon_output
+    };
         layouter.constrain_instance(
         coin2_nonce.clone().cell(),
         config.primary,
@@ -565,13 +569,13 @@ impl Circuit<pallas::Base> for LeadContract {
         let computed_final_root = merkle_inputs
             .calculate_root(layouter.namespace(|| "calculate root"), coin_commit_prod)?;
 
-        /*
+
         layouter.constrain_instance(
             computed_final_root.cell(),
             config.primary,
             LEAD_COIN_COMMIT_PATH_OFFSET,
         )?;
-        */
+
         //================================
         // y as COMIT(root_sk*nonce, mau_y)
         //================================
@@ -636,7 +640,6 @@ impl Circuit<pallas::Base> for LeadContract {
         let _rho_commit = com.add(layouter.namespace(|| "nonce commit"), &blind)?;
         */
 
-
         let ord = ar_chip.mul(layouter.namespace(|| ""), &scalar, &c)?;
         let target = ar_chip.mul(layouter.namespace(|| "calculate target"), &ord, &coin_value.clone())?;
 
@@ -644,8 +647,8 @@ impl Circuit<pallas::Base> for LeadContract {
         let T : Value<pallas::Base> = target.value().cloned();
         less_than_chip.witness_less_than(
             layouter.namespace(|| "y < T"),
+            T, //reversed for testing
             y,
-            T,
             0,
             true
         )?;