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