Skip to content

Commit

Permalink
do modulo on u128, update compile check for TAG_SIZE
Browse files Browse the repository at this point in the history
  • Loading branch information
eriktaubeneck committed Oct 18, 2024
1 parent 10419d3 commit 0e34c1c
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 12 deletions.
1 change: 1 addition & 0 deletions ipa-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ ipa-step = { version = "*", path = "../ipa-step" }
ipa-step-derive = { version = "*", path = "../ipa-step-derive" }

aes = "0.8.3"
assertions = "0.1.0"
async-trait = "0.1.79"
async-scoped = { version = "0.9.0", features = ["use-tokio"], optional = true }
axum = { version = "0.7.5", optional = true, features = ["http2", "macros"] }
Expand Down
23 changes: 11 additions & 12 deletions ipa-core/src/report/hybrid.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::{collections::HashSet, convert::Infallible, ops::Add};

use assertions::const_assert;
use bytes::Bytes;
use generic_array::{ArrayLength, GenericArray};
use rand_core::{CryptoRng, RngCore};
Expand Down Expand Up @@ -180,6 +181,12 @@ impl UniqueBytes for EncryptedHybridReport {
}

impl UniqueTag {
fn _compile_check() {
// This will vaild at compile time if TAG_SIZE doesn't match U16
// the macro expansion needs to be wrapped in a function
const_assert!(TAG_SIZE == 16);
}

// Function to attempt to create a UniqueTag from a UniqueBytes implementor
pub fn from_unique_bytes<T: UniqueBytes>(item: &T) -> Self {
UniqueTag {
Expand All @@ -188,26 +195,18 @@ impl UniqueTag {
}

/// Maps the tag into a consistent shard.
/// Note that `ShardIndex` is limited to u32, so we only use the first 4 bytes.
///
/// ## Panics
/// if the `TAG_SIZE < 4`
/// if the `TAG_SIZE != 16`
/// note: ~10 below this, we have a compile time check that `TAG_SIZE = 16`
#[must_use]
pub fn shard_picker(&self, shard_count: ShardIndex) -> ShardIndex {
let num = u32::from_le_bytes(
self.bytes[0..4]
.try_into()
.expect("This is larger than 4 bytes"),
);
let shard_count = u32::from(shard_count);
ShardIndex::from(num % shard_count)
let num = u128::from_le_bytes(self.bytes);
let shard_count = u128::from(shard_count);
ShardIndex::try_from(num % shard_count).expect("Modulo a u32 will fit in u32")
}
}

// This will vaild at compile time if TAG_SIZE doesn't match U16
const _: [(); 16] = [(); TAG_SIZE];

impl Serializable for UniqueTag {
type Size = U16; // This must match TAG_SIZE
type DeserializationError = Infallible;
Expand Down
8 changes: 8 additions & 0 deletions ipa-core/src/sharding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,14 @@ impl TryFrom<usize> for ShardIndex {
}
}

impl TryFrom<u128> for ShardIndex {
type Error = TryFromIntError;

fn try_from(value: u128) -> Result<Self, Self::Error> {
u32::try_from(value).map(Self)
}
}

#[cfg(all(test, unit_test))]
mod tests {
use std::iter::empty;
Expand Down

0 comments on commit 0e34c1c

Please sign in to comment.