less_than.rs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. use halo2_proofs::{
  2. arithmetic::FieldExt,
  3. circuit::{AssignedCell, Chip, Layouter, Region, Value},
  4. pasta::pallas,
  5. plonk::{Circuit, Advice, Column, ConstraintSystem, Error, Expression, Selector, TableColumn},
  6. poly::Rotation,
  7. circuit::{floor_planner},
  8. dev::{CircuitLayout, MockProver},
  9. };
  10. use darkfi::{
  11. consensus::{utils::{fbig2base}, types::Float10},
  12. crypto::{Proof, proof::{ProvingKey, VerifyingKey}, },
  13. zk::gadget::{native_range_check::{NativeRangeCheckChip},
  14. less_than::{LessThanChip, LessThanConfig}},
  15. VerifyFailed
  16. };
  17. use log::{info, error};
  18. use rand::rngs::OsRng;
  19. const WINDOW_SIZE : usize= 3;
  20. const NUM_BITS : usize = 253;
  21. const NUM_WINDOWS : usize =85;
  22. #[derive(Default)]
  23. struct LessThanCircuit {
  24. a: Value<pallas::Base>,
  25. b: Value<pallas::Base>,
  26. }
  27. impl Circuit<pallas::Base> for LessThanCircuit {
  28. type Config =
  29. (LessThanConfig<WINDOW_SIZE, NUM_BITS, NUM_WINDOWS>, Column<Advice>);
  30. type FloorPlanner = floor_planner::V1;
  31. fn without_witnesses(&self) -> Self {
  32. Self { a: Value::unknown(), b: Value::unknown() }
  33. }
  34. fn configure(meta: &mut ConstraintSystem<pallas::Base>) -> Self::Config {
  35. let w = meta.advice_column();
  36. meta.enable_equality(w);
  37. let a = meta.advice_column();
  38. let b = meta.advice_column();
  39. let a_offset = meta.advice_column();
  40. let z1 = meta.advice_column();
  41. let z2 = meta.advice_column();
  42. let k_values_table = meta.lookup_table_column();
  43. let constants = meta.fixed_column();
  44. meta.enable_constant(constants);
  45. (
  46. LessThanChip::<WINDOW_SIZE, NUM_BITS, NUM_WINDOWS>::configure(
  47. meta,
  48. a,
  49. b,
  50. a_offset,
  51. z1,
  52. z2,
  53. k_values_table,
  54. ),
  55. w,
  56. )
  57. }
  58. fn synthesize(
  59. &self,
  60. config: Self::Config,
  61. mut layouter: impl Layouter<pallas::Base>,
  62. ) -> Result<(), Error> {
  63. let less_than_chip =
  64. LessThanChip::<WINDOW_SIZE, NUM_BITS, NUM_WINDOWS>::construct(
  65. config.0.clone(),
  66. );
  67. NativeRangeCheckChip::<WINDOW_SIZE, NUM_BITS, NUM_WINDOWS>::load_k_table(
  68. &mut layouter,
  69. config.0.k_values_table,
  70. )?;
  71. less_than_chip.witness_less_than(
  72. layouter.namespace(|| "a < b"),
  73. self.a,
  74. self.b,
  75. 0,
  76. true,
  77. )?;
  78. Ok(())
  79. }
  80. }
  81. fn simple_lessthan (k: u32) -> Result<(), halo2_proofs::plonk::Error>{
  82. let y : pallas::Base = pallas::Base::zero();
  83. let t : pallas::Base = pallas::Base::one();
  84. let circuit = LessThanCircuit { a: Value::known(y), b: Value::known(t) };
  85. let prover = MockProver::run(k, &circuit, vec![]).unwrap();
  86. prover.assert_satisfied();
  87. assert!(prover.verify().is_ok());
  88. let public_inputs : Vec<pallas::Base> = vec![];
  89. let pk = ProvingKey::build(k, &LessThanCircuit::default());
  90. let vk = VerifyingKey::build(k, &LessThanCircuit::default());
  91. let proof = Proof::create(&pk, &[circuit], &public_inputs, &mut OsRng)?;
  92. match proof.verify(&vk, &public_inputs) {
  93. Ok(()) => {
  94. info!("proof verified");
  95. Ok(())
  96. },
  97. Err(e) => {
  98. error!("verification failed: {}", e);
  99. return Err(e)
  100. }
  101. }
  102. }
  103. fn fullrange_lessthan (k: u32) -> Result<(), halo2_proofs::plonk::Error> {
  104. let y_str : &'static str = "0x057eaec1c805d808f70c4e2d2f173c72d091e9c9f78b11dddf52d072c30951ad";
  105. let t_str : &'static str = "0x2cb8d8aec6766dc83595602e3050b0b908191bbe59dcc3d1e2b7020a37339a14";
  106. let y : pallas::Base = fbig2base(Float10::from_str_native(y_str).unwrap().with_precision(74).value());
  107. let t : pallas::Base = fbig2base(Float10::from_str_native(t_str).unwrap().with_precision(74).value());
  108. let circuit = LessThanCircuit { a: Value::known(y), b: Value::known(t) };
  109. let prover = MockProver::run(k, &circuit, vec![]).unwrap();
  110. prover.assert_satisfied();
  111. assert!(prover.verify().is_ok());
  112. let public_inputs : Vec<pallas::Base> = vec![];
  113. let pk = ProvingKey::build(k, &LessThanCircuit::default());
  114. let vk = VerifyingKey::build(k, &LessThanCircuit::default());
  115. let proof = Proof::create(&pk, &[circuit], &public_inputs, &mut OsRng)?;
  116. match proof.verify(&vk, &public_inputs) {
  117. Ok(()) => {
  118. info!("proof verified");
  119. Ok(())
  120. },
  121. Err(e) => {
  122. error!("verification failed: {}", e);
  123. return Err(e)
  124. }
  125. }
  126. }
  127. fn main () {
  128. env_logger::init();
  129. let k = 11;
  130. let res_simple = simple_lessthan(k).unwrap();
  131. let res_fullrange = fullrange_lessthan(k).unwrap();
  132. }