gt.rs 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. use darkfi::zk::{
  2. arith_chip::{ArithmeticChipConfig, ArithmeticChip},
  3. even_bits::{EvenBitsChip, EvenBitsConfig, EvenBitsLookup},
  4. greater_than::{GreaterThanChip, GreaterThanConfig, GreaterThanInstruction},
  5. };
  6. use halo2_gadgets::utilities::UtilitiesInstructions;
  7. use halo2_proofs::{
  8. circuit::{AssignedCell, Layouter, SimpleFloorPlanner},
  9. dev::MockProver,
  10. plonk,
  11. plonk::{Advice, Circuit, Column, ConstraintSystem, Instance as InstanceColumn},
  12. };
  13. use pasta_curves::{pallas, Fp, vesta, Fq};
  14. const WORD_BITS: u32 = 24;
  15. #[derive(Clone)]
  16. struct ZkConfig {
  17. primary: Column<InstanceColumn>,
  18. advices: [Column<Advice>; 3],
  19. evenbits_config: EvenBitsConfig,
  20. greaterthan_config: GreaterThanConfig,
  21. arith_config: ArithmeticChipConfig
  22. }
  23. impl ZkConfig {
  24. fn evenbits_chip(&self) -> EvenBitsChip<pallas::Base, WORD_BITS> {
  25. EvenBitsChip::construct(self.evenbits_config.clone())
  26. }
  27. fn greaterthan_chip(&self) -> GreaterThanChip<pallas::Base, WORD_BITS> {
  28. GreaterThanChip::construct(self.greaterthan_config.clone())
  29. }
  30. fn arith_chip(&self) -> ArithmeticChip {
  31. ArithmeticChip::construct(self.arith_config.clone())
  32. }
  33. }
  34. struct ZkCircuit {
  35. y: Option<pallas::Base>,
  36. v: Option<pallas::Base>,
  37. f: Option<pallas::Base>,
  38. }
  39. impl UtilitiesInstructions<pallas::Base> for ZkCircuit {
  40. type Var = AssignedCell<Fp, Fp>;
  41. }
  42. impl Circuit<pallas::Base> for ZkCircuit {
  43. type Config = ZkConfig;
  44. type FloorPlanner = SimpleFloorPlanner;
  45. fn without_witnesses(&self) -> Self {
  46. Self { y: None, v: None, f:None }
  47. }
  48. fn configure(meta: &mut ConstraintSystem<pallas::Base>) -> Self::Config {
  49. let advices = [meta.advice_column(), meta.advice_column(), meta.advice_column()];
  50. // Instance column used for public inputs
  51. let primary = meta.instance_column();
  52. meta.enable_equality(primary);
  53. for advice in advices.iter() {
  54. meta.enable_equality(*advice);
  55. }
  56. let evenbits_config = EvenBitsChip::<pallas::Base, WORD_BITS>::configure(meta);
  57. let greaterthan_config = GreaterThanChip::<pallas::Base, WORD_BITS>::configure(meta, [advices[1], advices[2]], primary);
  58. let arith_config = ArithmeticChip::configure(meta);
  59. ZkConfig { primary, advices, evenbits_config, greaterthan_config, arith_config }
  60. }
  61. fn synthesize(
  62. &self,
  63. config: Self::Config,
  64. mut layouter: impl Layouter<pallas::Base>,
  65. ) -> Result<(), plonk::Error> {
  66. let eb_chip = config.evenbits_chip();
  67. eb_chip.alloc_table(&mut layouter.namespace(|| "alloc table"))?;
  68. let gt_chip = config.greaterthan_chip();
  69. let ar_chip = config.arith_chip();
  70. let y = self.load_private(layouter.namespace(|| "Witness y"), config.advices[0], self.y)?;
  71. let v = self.load_private(layouter.namespace(|| "Witness v"), config.advices[0], self.v)?;
  72. let f = self.load_private(layouter.namespace(|| "Witness t"), config.advices[0], self.f)?;
  73. let t = ar_chip.mul(layouter.namespace(|| "target value"), v, f)?;
  74. eb_chip.decompose(layouter.namespace(|| "y range check"), y.clone())?;
  75. eb_chip.decompose(layouter.namespace(|| "t range check"), t.clone())?;
  76. let (helper, greater_than) = gt_chip.greater_than(layouter.namespace(|| "y > t"), y.into(), t.into())?;
  77. eb_chip.decompose(layouter.namespace(|| "helper range check"), helper.0)?;
  78. layouter.constrain_instance(greater_than.0.cell(), config.primary, 0)?;
  79. Ok(())
  80. }
  81. }
  82. fn main() {
  83. let k = 13;
  84. let y = pallas::Base::from(2);
  85. let v = pallas::Base::from(3);
  86. let f = pallas::Base::from(1);
  87. //
  88. let c = pallas::Base::from(0);
  89. let circuit = ZkCircuit {
  90. y: Some(y),
  91. v: Some(v),
  92. f: Some(f),
  93. };
  94. let mut public_inputs = vec![c];
  95. let prover = MockProver::run(k, &circuit, vec![public_inputs]).unwrap();
  96. assert_eq!(prover.verify(), Ok(()));
  97. }