1+ use std:: num:: NonZeroI64 ;
12use std:: num:: NonZeroU64 ;
23
4+ use std:: str:: FromStr ;
5+
36use crate :: GroupElement ;
47use crate :: {
58 committee:: * ,
@@ -9,9 +12,13 @@ use crate::{
912 TallyOptimizationTable ,
1013} ;
1114use base64:: { engine:: general_purpose, Engine as _} ;
15+
16+ use bigdecimal:: BigDecimal ;
17+ use bigdecimal:: ToPrimitive ;
1218use cryptoxide:: blake2b:: Blake2b ;
1319use cryptoxide:: digest:: Digest ;
14- use num_integer:: Roots ;
20+
21+ use std:: env;
1522
1623use rand_core:: { CryptoRng , RngCore } ;
1724
@@ -158,14 +165,21 @@ impl EncryptedTally {
158165 assert_eq ! ( ballot. vote( ) . len( ) , self . r. len( ) ) ;
159166 assert_eq ! ( ballot. fingerprint( ) , & self . fingerprint) ;
160167
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) ;
164178
165179 for ( ri, ci) in self . r . iter_mut ( ) . zip ( ballot. vote ( ) . iter ( ) ) {
166- * ri = & * ri + & ( ci * weight_gammad ) ;
180+ * ri = & * ri + & ( ci * weight ) ;
167181 }
168- self . max_stake += weight_gammad ;
182+ self . max_stake += weight ;
169183 }
170184
171185 /// Given a single committee member's `secret_key`, returns a partial decryption of
0 commit comments