You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

235 lines
7.2 KiB

  1. use ark_ff::PrimeField;
  2. use ark_r1cs_std::fields::nonnative::NonNativeFieldVar;
  3. use ark_r1cs_std::{alloc::AllocVar, eq::EqGadget, fields::FieldVar};
  4. use ark_relations::{
  5. ns,
  6. r1cs::{ConstraintSystem, ConstraintSystemRef, OptimizationGoal},
  7. };
  8. use ark_std::rand::RngCore;
  9. const NUM_REPETITIONS: usize = 1;
  10. fn get_density<BaseField: PrimeField>(cs: &ConstraintSystemRef<BaseField>) -> usize {
  11. match cs {
  12. ConstraintSystemRef::None => panic!("Constraint system is none."),
  13. ConstraintSystemRef::CS(r) => {
  14. let mut cs_bak = r.borrow().clone();
  15. cs_bak.finalize();
  16. let matrices = cs_bak.to_matrices().unwrap();
  17. matrices.a_num_non_zero + matrices.b_num_non_zero + matrices.c_num_non_zero
  18. },
  19. }
  20. }
  21. fn allocation<TargetField: PrimeField, BaseField: PrimeField, R: RngCore>(
  22. cs: ConstraintSystemRef<BaseField>,
  23. rng: &mut R,
  24. ) -> (usize, usize) {
  25. let a_native = TargetField::rand(rng);
  26. let constraints_before = cs.num_constraints();
  27. let nonzeros_before = get_density(&cs);
  28. // There will be a check that ensures it has the reasonable number of bits
  29. let _ = NonNativeFieldVar::<TargetField, BaseField>::new_witness(ns!(cs, "alloc a"), || {
  30. Ok(a_native)
  31. })
  32. .unwrap();
  33. let constraints_after = cs.num_constraints();
  34. let nonzeros_after = get_density(&cs);
  35. return (
  36. constraints_after - constraints_before,
  37. nonzeros_after - nonzeros_before,
  38. );
  39. }
  40. fn addition<TargetField: PrimeField, BaseField: PrimeField, R: RngCore>(
  41. cs: ConstraintSystemRef<BaseField>,
  42. rng: &mut R,
  43. ) -> (usize, usize) {
  44. let a_native = TargetField::rand(rng);
  45. let a = NonNativeFieldVar::<TargetField, BaseField>::new_witness(ns!(cs, "alloc a"), || {
  46. Ok(a_native)
  47. })
  48. .unwrap();
  49. let b_native = TargetField::rand(rng);
  50. let b = NonNativeFieldVar::<TargetField, BaseField>::new_witness(ns!(cs, "alloc b"), || {
  51. Ok(b_native)
  52. })
  53. .unwrap();
  54. let constraints_before = cs.num_constraints();
  55. let nonzeros_before = get_density(&cs);
  56. let _ = &a + &b;
  57. let constraints_after = cs.num_constraints();
  58. let nonzeros_after = get_density(&cs);
  59. return (
  60. constraints_after - constraints_before,
  61. nonzeros_after - nonzeros_before,
  62. );
  63. }
  64. fn equality<TargetField: PrimeField, BaseField: PrimeField, R: RngCore>(
  65. cs: ConstraintSystemRef<BaseField>,
  66. rng: &mut R,
  67. ) -> (usize, usize) {
  68. let a_native = TargetField::rand(rng);
  69. let a1 = NonNativeFieldVar::<TargetField, BaseField>::new_witness(ns!(cs, "alloc a1"), || {
  70. Ok(a_native)
  71. })
  72. .unwrap();
  73. let a2 = NonNativeFieldVar::<TargetField, BaseField>::new_witness(ns!(cs, "alloc a2"), || {
  74. Ok(a_native)
  75. })
  76. .unwrap();
  77. let constraints_before = cs.num_constraints();
  78. let nonzeros_before = get_density(&cs);
  79. a1.enforce_equal(&a2).unwrap();
  80. let constraints_after = cs.num_constraints();
  81. let nonzeros_after = get_density(&cs);
  82. return (
  83. constraints_after - constraints_before,
  84. nonzeros_after - nonzeros_before,
  85. );
  86. }
  87. fn multiplication<TargetField: PrimeField, BaseField: PrimeField, R: RngCore>(
  88. cs: ConstraintSystemRef<BaseField>,
  89. rng: &mut R,
  90. ) -> (usize, usize) {
  91. let a_native = TargetField::rand(rng);
  92. let a = NonNativeFieldVar::<TargetField, BaseField>::new_witness(ns!(cs, "initial a"), || {
  93. Ok(a_native)
  94. })
  95. .unwrap();
  96. let b_native = TargetField::rand(rng);
  97. let b = NonNativeFieldVar::<TargetField, BaseField>::new_witness(ns!(cs, "initial b"), || {
  98. Ok(b_native)
  99. })
  100. .unwrap();
  101. let constraints_before = cs.num_constraints();
  102. let nonzeros_before = get_density(&cs);
  103. let _ = &a * &b;
  104. let constraints_after = cs.num_constraints();
  105. let nonzeros_after = get_density(&cs);
  106. return (
  107. constraints_after - constraints_before,
  108. nonzeros_after - nonzeros_before,
  109. );
  110. }
  111. fn inverse<TargetField: PrimeField, BaseField: PrimeField, R: RngCore>(
  112. cs: ConstraintSystemRef<BaseField>,
  113. rng: &mut R,
  114. ) -> (usize, usize) {
  115. let num_native = TargetField::rand(rng);
  116. let num = NonNativeFieldVar::<TargetField, BaseField>::new_witness(ns!(cs, "alloc"), || {
  117. Ok(num_native)
  118. })
  119. .unwrap();
  120. let constraints_before = cs.num_constraints();
  121. let nonzeros_before = get_density(&cs);
  122. let _ = num.inverse().unwrap();
  123. let constraints_after = cs.num_constraints();
  124. let nonzeros_after = get_density(&cs);
  125. return (
  126. constraints_after - constraints_before,
  127. nonzeros_after - nonzeros_before,
  128. );
  129. }
  130. macro_rules! nonnative_bench_individual {
  131. ($bench_method:ident, $bench_name:ident, $bench_target_field:ty, $bench_base_field:ty) => {
  132. let rng = &mut ark_std::test_rng();
  133. let mut num_constraints = 0;
  134. let mut num_nonzeros = 0;
  135. for _ in 0..NUM_REPETITIONS {
  136. let cs_sys = ConstraintSystem::<$bench_base_field>::new();
  137. let cs = ConstraintSystemRef::new(cs_sys);
  138. cs.set_optimization_goal(OptimizationGoal::Constraints);
  139. let (cur_constraints, cur_nonzeros) =
  140. $bench_method::<$bench_target_field, $bench_base_field, _>(cs.clone(), rng);
  141. num_constraints += cur_constraints;
  142. num_nonzeros += cur_nonzeros;
  143. assert!(cs.is_satisfied().unwrap());
  144. }
  145. let average_constraints = num_constraints / NUM_REPETITIONS;
  146. let average_nonzeros = num_nonzeros / NUM_REPETITIONS;
  147. println!(
  148. "{} takes: {} constraints, {} non-zeros",
  149. stringify!($bench_method),
  150. average_constraints,
  151. average_nonzeros,
  152. );
  153. };
  154. }
  155. macro_rules! nonnative_bench {
  156. ($bench_name:ident, $bench_target_field:ty, $bench_base_field:ty) => {
  157. println!(
  158. "For {} to simulate {}",
  159. stringify!($bench_base_field),
  160. stringify!($bench_target_field),
  161. );
  162. nonnative_bench_individual!(
  163. allocation,
  164. $bench_name,
  165. $bench_target_field,
  166. $bench_base_field
  167. );
  168. nonnative_bench_individual!(
  169. addition,
  170. $bench_name,
  171. $bench_target_field,
  172. $bench_base_field
  173. );
  174. nonnative_bench_individual!(
  175. multiplication,
  176. $bench_name,
  177. $bench_target_field,
  178. $bench_base_field
  179. );
  180. nonnative_bench_individual!(
  181. equality,
  182. $bench_name,
  183. $bench_target_field,
  184. $bench_base_field
  185. );
  186. nonnative_bench_individual!(inverse, $bench_name, $bench_target_field, $bench_base_field);
  187. println!("----------------------")
  188. };
  189. }
  190. fn main() {
  191. nonnative_bench!(MNT46Small, ark_mnt4_298::Fr, ark_mnt6_298::Fr);
  192. nonnative_bench!(MNT64Small, ark_mnt6_298::Fr, ark_mnt4_298::Fr);
  193. nonnative_bench!(MNT46Big, ark_mnt4_753::Fr, ark_mnt6_753::Fr);
  194. nonnative_bench!(MNT64Big, ark_mnt6_753::Fr, ark_mnt4_753::Fr);
  195. nonnative_bench!(BLS12MNT4Small, ark_bls12_381::Fr, ark_mnt4_298::Fr);
  196. nonnative_bench!(BLS12, ark_bls12_381::Fq, ark_bls12_381::Fr);
  197. nonnative_bench!(MNT6BigMNT4Small, ark_mnt6_753::Fr, ark_mnt4_298::Fr);
  198. }