less_than.rs 4.7 KB

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