lessthan.rs 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. use halo2_proofs::{
  2. circuit::{AssignedCell, Layouter, SimpleFloorPlanner, floor_planner, Value},
  3. plonk::{Advice, Circuit, Column, ConstraintSystem, Error, Instance as InstanceColumn},
  4. dev::{CircuitLayout, MockProver},
  5. pasta::pallas,
  6. };
  7. use darkfi:: {
  8. zk::gadget:: {
  9. less_than::{ LessThanConfig, LessThanChip},
  10. native_range_check::{NativeRangeCheckChip},
  11. },
  12. };
  13. #[derive(Default)]
  14. struct LessThanCircuit {
  15. a: Value<pallas::Base>,
  16. b: Value<pallas::Base>,
  17. }
  18. const WINDOW_SIZE: usize = 3;
  19. const NUM_OF_BITS: usize = 254;
  20. const NUM_OF_WINDOWS: usize = 85;
  21. impl Circuit<pallas::Base> for LessThanCircuit {
  22. type Config =
  23. (LessThanConfig<WINDOW_SIZE, NUM_OF_BITS, NUM_OF_WINDOWS>, Column<Advice>);
  24. type FloorPlanner = floor_planner::V1;
  25. fn without_witnesses(&self) -> Self {
  26. Self { a: Value::unknown(), b: Value::unknown() }
  27. }
  28. fn configure(meta: &mut ConstraintSystem<pallas::Base>) -> Self::Config {
  29. let w = meta.advice_column();
  30. meta.enable_equality(w);
  31. let a = meta.advice_column();
  32. let b = meta.advice_column();
  33. let a_offset = meta.advice_column();
  34. let k_values_table = meta.lookup_table_column();
  35. let constants = meta.fixed_column();
  36. meta.enable_constant(constants);
  37. (
  38. LessThanChip::<WINDOW_SIZE, NUM_OF_BITS, NUM_OF_WINDOWS>::configure(
  39. meta,
  40. a,
  41. b,
  42. a_offset,
  43. k_values_table,
  44. ),
  45. w,
  46. )
  47. }
  48. fn synthesize (
  49. &self,
  50. config: Self::Config,
  51. mut layouter: impl Layouter<pallas::Base>,
  52. ) -> Result<(), Error> {
  53. let less_than_chip =
  54. LessThanChip::<WINDOW_SIZE, NUM_OF_BITS, NUM_OF_WINDOWS>::construct(
  55. config.0.clone(),
  56. );
  57. NativeRangeCheckChip::<WINDOW_SIZE, NUM_OF_BITS, NUM_OF_WINDOWS>::load_k_table(
  58. &mut layouter,
  59. config.0.k_values_table,
  60. )?;
  61. less_than_chip.witness_less_than(
  62. layouter.namespace(|| "a < b"),
  63. self.a,
  64. self.b,
  65. 0,
  66. )?;
  67. Ok(())
  68. }
  69. }
  70. fn main() {
  71. let k = 13;
  72. let valid_a_vals = vec![
  73. pallas::Base::from(3),
  74. pallas::Base::zero(),
  75. pallas::Base::one()
  76. ];
  77. let valid_b_vals = vec![
  78. pallas::Base::from(5),
  79. pallas::Base::from(u64::MAX),
  80. pallas::Base::from(rand::random::<u64>()),
  81. ];
  82. let invalid_a_vals = vec![
  83. pallas::Base::from(14),
  84. pallas::Base::from(u64::MAX),
  85. pallas::Base::zero(),
  86. pallas::Base::one(),
  87. pallas::Base::from(u64::MAX),
  88. ];
  89. let invalid_b_vals = vec![
  90. pallas::Base::from(11),
  91. pallas::Base::zero(),
  92. pallas::Base::zero(),
  93. pallas::Base::one(),
  94. pallas::Base::from(u64::MAX),
  95. ];
  96. use plotters::prelude::*;
  97. let circuit = LessThanCircuit {
  98. a: Value::known(pallas::Base::zero()),
  99. b: Value::known(pallas::Base::one()),
  100. };
  101. let root = BitMapBackend::new("target/lessthan_circuit_layout.png", (3840, 2160))
  102. .into_drawing_area();
  103. CircuitLayout::default().render(k, &circuit, &root).unwrap();
  104. for i in 0..valid_a_vals.len() {
  105. let a = valid_a_vals[i];
  106. let b = valid_b_vals[i];
  107. println!("64 bit (valid) {:?} < {:?} check", a, b);
  108. let circuit = LessThanCircuit { a: Value::known(a), b: Value::known(b) };
  109. let prover = MockProver::run(k, &circuit, vec![]).unwrap();
  110. prover.assert_satisfied();
  111. }
  112. for i in 0..invalid_a_vals.len() {
  113. let a = invalid_a_vals[i];
  114. let b = invalid_b_vals[i];
  115. println!("64 bit (invalid) {:?} < {:?} check", a, b);
  116. let circuit = LessThanCircuit { a: Value::known(a), b: Value::known(b) };
  117. let prover = MockProver::run(k, &circuit, vec![]).unwrap();
  118. assert!(prover.verify().is_err())
  119. }
  120. }