ark_nonnative_field/
params.rs1use crate::NonNativeFieldParams;
2
3#[must_use]
5pub const fn get_params(
6 target_field_size: usize,
7 base_field_size: usize,
8 optimization_type: OptimizationType,
9) -> NonNativeFieldParams {
10 let (num_of_limbs, limb_size) =
11 find_parameters(base_field_size, target_field_size, optimization_type);
12 NonNativeFieldParams {
13 num_limbs: num_of_limbs,
14 bits_per_limb: limb_size,
15 }
16}
17
18#[derive(Clone, Copy, Debug, PartialEq, Eq)]
19pub enum OptimizationType {
21 Constraints,
23 Weight,
25}
26
27pub const fn find_parameters(
29 base_field_prime_length: usize,
30 target_field_prime_bit_length: usize,
31 optimization_type: OptimizationType,
32) -> (usize, usize) {
33 let mut found = false;
34 let mut min_cost = 0usize;
35 let mut min_cost_limb_size = 0usize;
36 let mut min_cost_num_of_limbs = 0usize;
37
38 let surfeit = 10;
39 let mut max_limb_size = (base_field_prime_length - 1 - surfeit - 1) / 2 - 1;
40 if max_limb_size > target_field_prime_bit_length {
41 max_limb_size = target_field_prime_bit_length;
42 }
43 let mut limb_size = 1;
44
45 while limb_size <= max_limb_size {
46 let num_of_limbs = (target_field_prime_bit_length + limb_size - 1) / limb_size;
47
48 let group_size =
49 (base_field_prime_length - 1 - surfeit - 1 - 1 - limb_size + limb_size - 1) / limb_size;
50 let num_of_groups = (2 * num_of_limbs - 1 + group_size - 1) / group_size;
51
52 let mut this_cost = 0;
53
54 match optimization_type {
55 OptimizationType::Constraints => {
56 this_cost += 2 * num_of_limbs - 1;
57 }
58 OptimizationType::Weight => {
59 this_cost += 6 * num_of_limbs * num_of_limbs;
60 }
61 };
62
63 match optimization_type {
64 OptimizationType::Constraints => {
65 this_cost += target_field_prime_bit_length; this_cost += target_field_prime_bit_length + num_of_limbs; this_cost += num_of_groups + (num_of_groups - 1) * (limb_size * 2 + surfeit) + 1;
69 }
71 OptimizationType::Weight => {
72 this_cost += target_field_prime_bit_length * 3 + target_field_prime_bit_length; this_cost += target_field_prime_bit_length * 3
74 + target_field_prime_bit_length
75 + num_of_limbs; this_cost += num_of_limbs * num_of_limbs + 2 * (2 * num_of_limbs - 1); this_cost += num_of_limbs
78 + num_of_groups
79 + 6 * num_of_groups
80 + (num_of_groups - 1) * (2 * limb_size + surfeit) * 4
81 + 2; }
83 };
84
85 if !found || this_cost < min_cost {
86 found = true;
87 min_cost = this_cost;
88 min_cost_limb_size = limb_size;
89 min_cost_num_of_limbs = num_of_limbs;
90 }
91
92 limb_size += 1;
93 }
94
95 (min_cost_num_of_limbs, min_cost_limb_size)
96}