1
+ use std:: num:: NonZeroI64 ;
1
2
use std:: num:: NonZeroU64 ;
2
3
4
+ use std:: str:: FromStr ;
5
+
3
6
use crate :: GroupElement ;
4
7
use crate :: {
5
8
committee:: * ,
@@ -9,9 +12,13 @@ use crate::{
9
12
TallyOptimizationTable ,
10
13
} ;
11
14
use base64:: { engine:: general_purpose, Engine as _} ;
15
+
16
+ use bigdecimal:: BigDecimal ;
17
+ use bigdecimal:: ToPrimitive ;
12
18
use cryptoxide:: blake2b:: Blake2b ;
13
19
use cryptoxide:: digest:: Digest ;
14
- use num_integer:: Roots ;
20
+
21
+ use std:: env;
15
22
16
23
use rand_core:: { CryptoRng , RngCore } ;
17
24
@@ -158,14 +165,21 @@ impl EncryptedTally {
158
165
assert_eq ! ( ballot. vote( ) . len( ) , self . r. len( ) ) ;
159
166
assert_eq ! ( ballot. fingerprint( ) , & self . fingerprint) ;
160
167
161
- // Returns the truncated principal square root of an integer – ⌊√x⌋
162
- // This is solving for r in r² = x, rounding toward zero. The result will satisfy r² ≤ x < (r+1)²
163
- let weight_gammad = weight. sqrt ( ) ;
168
+ const SCALE_FACTOR : & str = "QUADRATIC_VOTING_SCALING_FACTOR" ;
169
+ const PRECISION : & str = "QUADRATIC_VOTING_PRECISION" ;
170
+
171
+ let scaling_factor = env:: var ( SCALE_FACTOR ) . unwrap_or ( 1 . to_string ( ) ) ;
172
+ let precision = i64:: from_str ( & env:: var ( PRECISION ) . unwrap_or ( 1 . to_string ( ) ) ) . unwrap_or ( 1 ) ;
173
+
174
+ let gamma = BigDecimal :: from_str ( & scaling_factor) . unwrap_or ( BigDecimal :: from ( 1 ) ) ;
175
+ let stake = BigDecimal :: from ( weight) ;
176
+
177
+ let weight = ( gamma * stake) . round ( precision) . to_u64 ( ) . unwrap_or ( weight) ;
164
178
165
179
for ( ri, ci) in self . r . iter_mut ( ) . zip ( ballot. vote ( ) . iter ( ) ) {
166
- * ri = & * ri + & ( ci * weight_gammad ) ;
180
+ * ri = & * ri + & ( ci * weight ) ;
167
181
}
168
- self . max_stake += weight_gammad ;
182
+ self . max_stake += weight ;
169
183
}
170
184
171
185
/// Given a single committee member's `secret_key`, returns a partial decryption of
0 commit comments