gt.rs 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. use darkfi::zk::gadget::{
  2. arith_chip::{ArithChip, ArithConfig, ArithInstruction},
  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};
  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: ArithConfig,
  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) -> ArithChip {
  31. ArithChip::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(
  58. meta,
  59. [advices[1], advices[2]],
  60. primary,
  61. );
  62. let arith_config = ArithChip::configure(meta, advices[1], advices[2], advices[0]);
  63. ZkConfig { primary, advices, evenbits_config, greaterthan_config, arith_config }
  64. }
  65. fn synthesize(
  66. &self,
  67. config: Self::Config,
  68. mut layouter: impl Layouter<pallas::Base>,
  69. ) -> Result<(), plonk::Error> {
  70. let eb_chip = config.evenbits_chip();
  71. eb_chip.alloc_table(&mut layouter.namespace(|| "alloc table"))?;
  72. let gt_chip = config.greaterthan_chip();
  73. let ar_chip = config.arith_chip();
  74. let y = self.load_private(layouter.namespace(|| "Witness y"), config.advices[0], self.y)?;
  75. let v = self.load_private(layouter.namespace(|| "Witness v"), config.advices[0], self.v)?;
  76. let f = self.load_private(layouter.namespace(|| "Witness t"), config.advices[0], self.f)?;
  77. let t = ar_chip.mul(layouter.namespace(|| "target value"), &v, &f)?;
  78. eb_chip.decompose(layouter.namespace(|| "y range check"), y.clone())?;
  79. eb_chip.decompose(layouter.namespace(|| "t range check"), t.clone())?;
  80. let (helper, greater_than) =
  81. gt_chip.greater_than(layouter.namespace(|| "y > t"), y.into(), t.into())?;
  82. eb_chip.decompose(layouter.namespace(|| "helper range check"), helper.0)?;
  83. layouter.constrain_instance(greater_than.0.cell(), config.primary, 0)?;
  84. Ok(())
  85. }
  86. }
  87. fn main() {
  88. let k = 13;
  89. let y = pallas::Base::from(2);
  90. let v = pallas::Base::from(3);
  91. let f = pallas::Base::from(1);
  92. //
  93. let c = pallas::Base::from(0);
  94. let circuit = ZkCircuit { y: Some(y), v: Some(v), f: Some(f) };
  95. let public_inputs: Vec<pallas::Base> = vec![c];
  96. let prover = MockProver::run(k, &circuit, vec![public_inputs]).unwrap();
  97. assert_eq!(prover.verify(), Ok(()));
  98. }