Jelajahi Sumber

Merge branch 'master' of github.com:darkrenaissance/darkfi

lunar-mining 3 tahun lalu
induk
melakukan
3bdf42afc0
9 mengubah file dengan 183 tambahan dan 7 penghapusan
  1. 1 1
      Makefile
  2. 1 1
      bin/tau/taud_config.toml
  3. 2 1
      contrib/zk.lua
  4. 1 1
      contrib/zk.vim
  5. 2 0
      proof/opcodes.zk
  6. 6 3
      src/zk/gadget/mod.rs
  7. 143 0
      src/zk/gadget/small_range_check.rs
  8. 20 0
      src/zk/vm.rs
  9. 7 0
      src/zkas/opcode.rs

+ 1 - 1
Makefile

@@ -31,7 +31,7 @@ PROOFS_BIN = $(PROOFS:=.bin)
 
 
 all: zkas $(PROOFS_BIN) $(BINS)
 all: zkas $(PROOFS_BIN) $(BINS)
 
 
-zkas:
+zkas: $(BINDEPS)
 	RUSTFLAGS="$(RUSTFLAGS)" $(CARGO) build --all-features --release --package $@
 	RUSTFLAGS="$(RUSTFLAGS)" $(CARGO) build --all-features --release --package $@
 	cp -f target/release/$@ $@
 	cp -f target/release/$@ $@
 
 

+ 1 - 1
bin/tau/taud_config.toml

@@ -22,7 +22,7 @@ outbound_connections=5
 #peers = ["tls://127.0.0.1:23331"]
 #peers = ["tls://127.0.0.1:23331"]
 
 
 ## Seed nodes to connect to 
 ## Seed nodes to connect to 
-seeds=["tls://lilith0.dark.fi:23331", "tls://lilith1.dark.fi:23331"]
+seeds=["tls://tau0.dark.fi:23331", "tls://tau1.dark.fi:23331"]
 
 
 # Prefered transports for outbound connections
 # Prefered transports for outbound connections
 #transports = ["tls", "tcp"]
 #transports = ["tls", "tcp"]

+ 2 - 1
contrib/zk.lua

@@ -43,7 +43,8 @@ local instruction = token('instruction', word_match{
   'ec_get_x', 'ec_get_y',
   'ec_get_x', 'ec_get_y',
   'base_add', 'base_mul', 'base_sub', 'greater_than',
   'base_add', 'base_mul', 'base_sub', 'greater_than',
   'poseidon_hash', 'merkle_root', 'constrain_instance',
   'poseidon_hash', 'merkle_root', 'constrain_instance',
-  'range_check', 'less_than', 'witness_base',
+  'range_check', 'less_than', 'bool_check',
+  'witness_base',
 })
 })
 
 
 -- Identifiers.
 -- Identifiers.

+ 1 - 1
contrib/zk.vim

@@ -23,7 +23,7 @@ syn keyword zkasInstruction
     \ ec_get_x ec_get_y
     \ ec_get_x ec_get_y
     \ base_add base_mul base_sub
     \ base_add base_mul base_sub
     \ poseidon_hash merkle_root constrain_instance
     \ poseidon_hash merkle_root constrain_instance
-    \ range_check less_than witness_base
+    \ range_check less_than bool_check witness_base
 
 
 syn region zkasString start='"' end='"' contained
 syn region zkasString start='"' end='"' contained
 
 

+ 2 - 0
proof/opcodes.zk

@@ -45,4 +45,6 @@ circuit "Opcodes" {
 	public = ec_mul_base(secret, NULLIFIER_K);
 	public = ec_mul_base(secret, NULLIFIER_K);
 	constrain_instance(ec_get_x(public));
 	constrain_instance(ec_get_x(public));
 	constrain_instance(ec_get_y(public));
 	constrain_instance(ec_get_y(public));
+
+	bool_check(one);
 }
 }

+ 6 - 3
src/zk/gadget/mod.rs

@@ -1,10 +1,13 @@
-/// Base field scalar arithmetic
+/// Base field arithmetic gadget
 pub mod arithmetic;
 pub mod arithmetic;
 
 
-/// Field-native range check gadget;
+/// Small range check, 0..8 bits
+pub mod small_range_check;
+
+/// Field-native range check gadget with a lookup table
 pub mod native_range_check;
 pub mod native_range_check;
 
 
-// Field-native less than comparison gadget
+/// Field-native less than comparison gadget with a lookup table
 pub mod less_than;
 pub mod less_than;
 
 
 /// is_zero comparison gadget
 /// is_zero comparison gadget

+ 143 - 0
src/zk/gadget/small_range_check.rs

@@ -0,0 +1,143 @@
+use halo2_proofs::{
+    arithmetic::FieldExt,
+    circuit::{AssignedCell, Chip, Layouter},
+    pasta::pallas,
+    plonk,
+    plonk::{Advice, Column, ConstraintSystem, Constraints, Expression, Selector},
+    poly::Rotation,
+};
+
+/// Checks that an expression is in the small range [0..range),
+/// i.e. 0 ≤ word < range.
+pub fn range_check<F: FieldExt>(word: Expression<F>, range: u8) -> Expression<F> {
+    (1..(range as usize))
+        .fold(word.clone(), |acc, i| acc * (Expression::Constant(F::from(i as u64)) - word.clone()))
+}
+
+#[derive(Clone, Debug)]
+pub struct SmallRangeCheckConfig {
+    pub z: Column<Advice>,
+    pub selector: Selector,
+}
+
+#[derive(Clone, Debug)]
+pub struct SmallRangeCheckChip {
+    config: SmallRangeCheckConfig,
+}
+
+impl Chip<pallas::Base> for SmallRangeCheckChip {
+    type Config = SmallRangeCheckConfig;
+    type Loaded = ();
+
+    fn config(&self) -> &Self::Config {
+        &self.config
+    }
+
+    fn loaded(&self) -> &Self::Loaded {
+        &()
+    }
+}
+
+impl SmallRangeCheckChip {
+    pub fn construct(config: SmallRangeCheckConfig) -> Self {
+        Self { config }
+    }
+
+    pub fn configure(
+        meta: &mut ConstraintSystem<pallas::Base>,
+        z: Column<Advice>,
+        range: u8,
+    ) -> SmallRangeCheckConfig {
+        // Enable permutation on z column
+        meta.enable_equality(z);
+
+        let selector = meta.selector();
+
+        meta.create_gate("bool check", |meta| {
+            let selector = meta.query_selector(selector);
+            let advice = meta.query_advice(z, Rotation::cur());
+            Constraints::with_selector(selector, Some(range_check(advice, range)))
+        });
+
+        SmallRangeCheckConfig { z, selector }
+    }
+
+    pub fn small_range_check(
+        &self,
+        mut layouter: impl Layouter<pallas::Base>,
+        value: AssignedCell<pallas::Base, pallas::Base>,
+    ) -> Result<(), plonk::Error> {
+        layouter.assign_region(
+            || "small range constrain",
+            |mut region| {
+                self.config.selector.enable(&mut region, 0)?;
+                value.copy_advice(|| "z_0", &mut region, self.config.z, 0)?;
+                Ok(())
+            },
+        )
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use crate::zk::assign_free_advice;
+    use halo2_proofs::{
+        circuit::{floor_planner, Value},
+        dev::MockProver,
+        plonk,
+        plonk::Circuit,
+    };
+
+    #[derive(Default)]
+    struct SmallRangeCircuit {
+        value: Value<pallas::Base>,
+    }
+
+    impl Circuit<pallas::Base> for SmallRangeCircuit {
+        type Config = (SmallRangeCheckConfig, Column<Advice>);
+        type FloorPlanner = floor_planner::V1;
+
+        fn without_witnesses(&self) -> Self {
+            Self::default()
+        }
+
+        fn configure(meta: &mut ConstraintSystem<pallas::Base>) -> Self::Config {
+            let w = meta.advice_column();
+            let z = meta.advice_column();
+
+            meta.enable_equality(w);
+
+            // One bit
+            let config = SmallRangeCheckChip::configure(meta, z, 2);
+
+            (config, w)
+        }
+
+        fn synthesize(
+            &self,
+            config: Self::Config,
+            mut layouter: impl Layouter<pallas::Base>,
+        ) -> Result<(), plonk::Error> {
+            let chip = SmallRangeCheckChip::construct(config.0.clone());
+            let value = assign_free_advice(layouter.namespace(|| "val"), config.1, self.value)?;
+            chip.small_range_check(layouter.namespace(|| "boolean check"), value)?;
+            Ok(())
+        }
+    }
+
+    #[test]
+    fn boolean_range_check() {
+        let k = 3;
+
+        for i in 0..2 {
+            let circuit = SmallRangeCircuit { value: Value::known(pallas::Base::from(i as u64)) };
+            let prover = MockProver::run(k, &circuit, vec![]).unwrap();
+            prover.assert_satisfied();
+        }
+
+        let circuit = SmallRangeCircuit { value: Value::known(pallas::Base::from(2)) };
+        let prover = MockProver::run(k, &circuit, vec![]).unwrap();
+        assert!(prover.verify().is_err());
+    }
+}

+ 20 - 0
src/zk/vm.rs

@@ -31,6 +31,7 @@ use super::{
         arithmetic::{ArithChip, ArithConfig, ArithInstruction},
         arithmetic::{ArithChip, ArithConfig, ArithInstruction},
         less_than::{LessThanChip, LessThanConfig},
         less_than::{LessThanChip, LessThanConfig},
         native_range_check::{NativeRangeCheckChip, NativeRangeCheckConfig},
         native_range_check::{NativeRangeCheckChip, NativeRangeCheckConfig},
+        small_range_check::{SmallRangeCheckChip, SmallRangeCheckConfig},
     },
     },
 };
 };
 use crate::{
 use crate::{
@@ -59,6 +60,7 @@ pub struct VmConfig {
     native_64_range_check_config: NativeRangeCheckConfig<3, 64, 22>,
     native_64_range_check_config: NativeRangeCheckConfig<3, 64, 22>,
     native_253_range_check_config: NativeRangeCheckConfig<3, 253, 85>,
     native_253_range_check_config: NativeRangeCheckConfig<3, 253, 85>,
     lessthan_config: LessThanConfig<3, 253, 85>,
     lessthan_config: LessThanConfig<3, 253, 85>,
+    boolcheck_config: SmallRangeCheckConfig,
 }
 }
 
 
 impl VmConfig {
 impl VmConfig {
@@ -232,6 +234,10 @@ impl Circuit<pallas::Base> for ZkCircuit {
             k_values_table_253,
             k_values_table_253,
         );
         );
 
 
+        // Configuration for boolean checks, it uses the small_range_check
+        // chip with a range of 2, which enforces one bit, i.e. 0 or 1.
+        let boolcheck_config = SmallRangeCheckChip::configure(meta, advices[9], 2);
+
         VmConfig {
         VmConfig {
             primary,
             primary,
             advices,
             advices,
@@ -245,6 +251,7 @@ impl Circuit<pallas::Base> for ZkCircuit {
             native_64_range_check_config,
             native_64_range_check_config,
             native_253_range_check_config,
             native_253_range_check_config,
             lessthan_config,
             lessthan_config,
+            boolcheck_config,
         }
         }
     }
     }
 
 
@@ -300,6 +307,9 @@ impl Circuit<pallas::Base> for ZkCircuit {
         // Construct the Arithmetic chip.
         // Construct the Arithmetic chip.
         let arith_chip = config.arithmetic_chip();
         let arith_chip = config.arithmetic_chip();
 
 
+        // Construct the boolean check chip.
+        let boolcheck_chip = SmallRangeCheckChip::construct(config.boolcheck_config.clone());
+
         // ==========================
         // ==========================
         // Constants setup
         // Constants setup
         // ==========================
         // ==========================
@@ -697,6 +707,16 @@ impl Circuit<pallas::Base> for ZkCircuit {
                     )?;
                     )?;
                 }
                 }
 
 
+                Opcode::BoolCheck => {
+                    debug!("Executing `BoolCheck{:?}` opcode", opcode.1);
+                    let args = &opcode.1;
+
+                    let w = stack[args[0].1].clone().into();
+
+                    boolcheck_chip
+                        .small_range_check(layouter.namespace(|| "copy boolean check"), w)?;
+                }
+
                 Opcode::ConstrainInstance => {
                 Opcode::ConstrainInstance => {
                     debug!("Executing `ConstrainInstance{:?}` opcode", opcode.1);
                     debug!("Executing `ConstrainInstance{:?}` opcode", opcode.1);
                     let args = &opcode.1;
                     let args = &opcode.1;

+ 7 - 0
src/zkas/opcode.rs

@@ -49,6 +49,9 @@ pub enum Opcode {
     /// Compare two Base field elements and see if a is less than b
     /// Compare two Base field elements and see if a is less than b
     LessThan = 0x51,
     LessThan = 0x51,
 
 
+    /// Check if a field element fits in a boolean (Either 0 or 1)
+    BoolCheck = 0x52,
+
     /// Constrain a Base field element to a circuit's public input
     /// Constrain a Base field element to a circuit's public input
     ConstrainInstance = 0xf0,
     ConstrainInstance = 0xf0,
 
 
@@ -73,6 +76,7 @@ impl Opcode {
             "witness_base" => Some(Self::WitnessBase),
             "witness_base" => Some(Self::WitnessBase),
             "range_check" => Some(Self::RangeCheck),
             "range_check" => Some(Self::RangeCheck),
             "less_than" => Some(Self::LessThan),
             "less_than" => Some(Self::LessThan),
+            "bool_check" => Some(Self::BoolCheck),
             "constrain_instance" => Some(Self::ConstrainInstance),
             "constrain_instance" => Some(Self::ConstrainInstance),
             "debug" => Some(Self::DebugPrint),
             "debug" => Some(Self::DebugPrint),
             _ => None,
             _ => None,
@@ -95,6 +99,7 @@ impl Opcode {
             0x40 => Some(Self::WitnessBase),
             0x40 => Some(Self::WitnessBase),
             0x50 => Some(Self::RangeCheck),
             0x50 => Some(Self::RangeCheck),
             0x51 => Some(Self::LessThan),
             0x51 => Some(Self::LessThan),
+            0x52 => Some(Self::BoolCheck),
             0xf0 => Some(Self::ConstrainInstance),
             0xf0 => Some(Self::ConstrainInstance),
             0xff => Some(Self::DebugPrint),
             0xff => Some(Self::DebugPrint),
             _ => None,
             _ => None,
@@ -141,6 +146,8 @@ impl Opcode {
 
 
             Opcode::LessThan => (vec![], vec![VarType::Base, VarType::Base]),
             Opcode::LessThan => (vec![], vec![VarType::Base, VarType::Base]),
 
 
+            Opcode::BoolCheck => (vec![], vec![VarType::Base]),
+
             Opcode::ConstrainInstance => (vec![], vec![VarType::Base]),
             Opcode::ConstrainInstance => (vec![], vec![VarType::Base]),
 
 
             Opcode::DebugPrint => (vec![], vec![]),
             Opcode::DebugPrint => (vec![], vec![]),