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.

238 lines
7.2 KiB

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