diff --git a/Cargo.lock b/Cargo.lock index 8f1eec6842..58756bf061 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1216,6 +1216,7 @@ dependencies = [ "hex", "imhamt", "lazy_static", + "num-integer", "proptest", "quickcheck", "quickcheck_macros", @@ -1303,12 +1304,14 @@ dependencies = [ "const_format", "criterion", "cryptoxide 0.4.4", + "num-integer", "rand 0.8.5", "rand_chacha 0.3.1", "rand_core 0.6.4", "rayon", "smoke", "thiserror", + "tracing", ] [[package]] @@ -4023,9 +4026,9 @@ dependencies = [ [[package]] name = "lazy_static" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "lazycell" @@ -4739,25 +4742,24 @@ dependencies = [ [[package]] name = "num" -version = "0.4.1" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b05180d69e3da0e530ba2a1dae5110317e49e3b7f3d41be227dc5f92e49ee7af" +checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" dependencies = [ "num-bigint", "num-complex", "num-integer", "num-iter", - "num-rational 0.4.1", + "num-rational 0.4.2", "num-traits", ] [[package]] name = "num-bigint" -version = "0.4.4" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ - "autocfg", "num-integer", "num-traits", "serde", @@ -4765,9 +4767,9 @@ dependencies = [ [[package]] name = "num-complex" -version = "0.4.4" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ba157ca0885411de85d6ca030ba7e2a83a28636056c7c699b07c8b6f7383214" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" dependencies = [ "num-traits", "serde", @@ -4786,19 +4788,18 @@ dependencies = [ [[package]] name = "num-integer" -version = "0.1.45" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" dependencies = [ - "autocfg", "num-traits", ] [[package]] name = "num-iter" -version = "0.1.43" +version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" dependencies = [ "autocfg", "num-integer", @@ -4818,11 +4819,10 @@ dependencies = [ [[package]] name = "num-rational" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" dependencies = [ - "autocfg", "num-bigint", "num-integer", "num-traits", @@ -4831,9 +4831,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", "libm", diff --git a/src/chain-libs/chain-impl-mockchain/Cargo.toml b/src/chain-libs/chain-impl-mockchain/Cargo.toml index 83f4b2b74d..4523268cf1 100644 --- a/src/chain-libs/chain-impl-mockchain/Cargo.toml +++ b/src/chain-libs/chain-impl-mockchain/Cargo.toml @@ -32,6 +32,8 @@ criterion = { version = "0.3.0", optional = true } rand = "0.8" cryptoxide = "0.4" tracing.workspace = true +num-integer = "0.1" + [features] property-test-api = [ diff --git a/src/chain-libs/chain-impl-mockchain/src/vote/tally.rs b/src/chain-libs/chain-impl-mockchain/src/vote/tally.rs index 7d6a1c2f24..32c601ee5e 100644 --- a/src/chain-libs/chain-impl-mockchain/src/vote/tally.rs +++ b/src/chain-libs/chain-impl-mockchain/src/vote/tally.rs @@ -4,6 +4,7 @@ use crate::{ vote::{Choice, Options}, }; use chain_vote::EncryptedTally; +use num_integer::Roots; use std::fmt; use thiserror::Error; @@ -166,7 +167,11 @@ impl TallyResult { } else { let index = choice.as_byte() as usize; - self.results[index] = self.results[index].saturating_add(weight); + // Returns the truncated principal square root of an integer – ⌊√x⌋ + // This is solving for r in r² = x, rounding toward zero. The result will satisfy r² ≤ x < (r+1)² + let weight_gammad = weight.0.sqrt(); + + self.results[index] = self.results[index].saturating_add(Weight(weight_gammad)); Ok(()) } diff --git a/src/chain-libs/chain-vote/Cargo.toml b/src/chain-libs/chain-vote/Cargo.toml index 6d31e20b84..17b6628f4e 100644 --- a/src/chain-libs/chain-vote/Cargo.toml +++ b/src/chain-libs/chain-vote/Cargo.toml @@ -14,6 +14,9 @@ thiserror = "1.0" cryptoxide = "^0.4.2" const_format = "0.2" base64 = "0.21.0" +tracing = "0.1" +num-integer = "0.1" + [dev-dependencies] rand_chacha = "0.3" diff --git a/src/chain-libs/chain-vote/src/tally.rs b/src/chain-libs/chain-vote/src/tally.rs index d28543be17..644342266d 100644 --- a/src/chain-libs/chain-vote/src/tally.rs +++ b/src/chain-libs/chain-vote/src/tally.rs @@ -11,6 +11,8 @@ use crate::{ use base64::{engine::general_purpose, Engine as _}; use cryptoxide::blake2b::Blake2b; use cryptoxide::digest::Digest; +use num_integer::Roots; + use rand_core::{CryptoRng, RngCore}; /// Secret key for opening vote @@ -155,10 +157,15 @@ impl EncryptedTally { pub fn add(&mut self, ballot: &Ballot, weight: u64) { assert_eq!(ballot.vote().len(), self.r.len()); assert_eq!(ballot.fingerprint(), &self.fingerprint); + + // Returns the truncated principal square root of an integer – ⌊√x⌋ + // This is solving for r in r² = x, rounding toward zero. The result will satisfy r² ≤ x < (r+1)² + let weight_gammad = weight.sqrt(); + for (ri, ci) in self.r.iter_mut().zip(ballot.vote().iter()) { - *ri = &*ri + &(ci * weight); + *ri = &*ri + &(ci * weight_gammad); } - self.max_stake += weight; + self.max_stake += weight_gammad; } /// Given a single committee member's `secret_key`, returns a partial decryption of