瀏覽代碼

utils: complete doc comments

Lennart Braun 1 年之前
父節點
當前提交
7a58929ff3

+ 3 - 0
utils/src/bit_decompose.rs

@@ -1,5 +1,8 @@
+//! Functionality to compute the bit decomposition of integers.
+
 use num::PrimInt;
 
+/// Decompose an integer `x` into a vector of its bits.
 pub fn bit_decompose<T: PrimInt, U: From<bool>>(x: T, n_bits: usize) -> Vec<U> {
     assert!(n_bits as u32 == T::zero().count_zeros() || x < T::one() << n_bits);
     (0..n_bits)

+ 26 - 20
utils/src/cuckoo.rs

@@ -1,3 +1,5 @@
+//! Implementation of simple hashing and cuckoo hashing.
+
 use crate::hash::{HashFunction, HashFunctionValue};
 use bincode;
 use core::array;
@@ -8,8 +10,10 @@ use std::f64::consts::SQRT_2;
 use std::fmt;
 use std::fmt::Debug;
 
+/// Number of hash functions used for cuckoo hashing.
 pub const NUMBER_HASH_FUNCTIONS: usize = 3;
 
+/// Parameters for cuckoo hashing.
 pub struct Parameters<H: HashFunction<Value>, Value: HashFunctionValue>
 where
     <Value as TryInto<usize>>::Error: Debug,
@@ -93,7 +97,7 @@ where
     Value: HashFunctionValue,
     <Value as TryInto<usize>>::Error: Debug,
 {
-    /// Samples three hash functions from given seed
+    /// Samples three hash functions from given seed.
     pub fn from_seed(number_inputs: usize, seed: [u8; 32]) -> Self {
         let number_buckets = Self::compute_number_buckets(number_inputs);
         let mut rng = ChaCha12Rng::from_seed(seed);
@@ -107,7 +111,7 @@ where
         }
     }
 
-    /// Samples three hash functions randomly
+    /// Samples three hash functions randomly.
     pub fn sample(number_inputs: usize) -> Self {
         let number_buckets = Self::compute_number_buckets(number_inputs);
         let hash_function_descriptions =
@@ -120,15 +124,15 @@ where
         }
     }
 
-    /// Compute how many buckets we need for the cuckoo table
+    /// Compute how many buckets we need for the cuckoo table.
+    ///
+    /// This is based on
+    /// <https://github.com/ladnir/cryptoTools/blob/85da63e335c3ad3019af3958b48d3ff6750c3d92/cryptoTools/Common/CuckooIndex.cpp#L129-L150>.
     fn compute_number_buckets(number_inputs: usize) -> usize {
         assert_ne!(number_inputs, 0);
 
         let statistical_security_parameter = 40;
 
-        // computation taken from here:
-        // https://github.com/ladnir/cryptoTools/blob/85da63e335c3ad3019af3958b48d3ff6750c3d92/cryptoTools/Common/CuckooIndex.cpp#L129-L150
-
         let log_number_inputs = (number_inputs as f64).log2().ceil();
         let a_max = 123.5;
         let b_max = -130.0;
@@ -144,17 +148,18 @@ where
         (e * number_inputs as f64).ceil() as usize
     }
 
-    /// Return the number of buckets
+    /// Return the number of buckets.
     pub fn get_number_buckets(&self) -> usize {
         self.number_buckets
     }
 
-    /// Return the number of inputs these parameters are specified for
+    /// Return the number of inputs these parameters are specified for.
     pub fn get_number_inputs(&self) -> usize {
         self.number_inputs
     }
 }
 
+/// Hasher using a given hash function construction.
 pub struct Hasher<H: HashFunction<Value>, Value: HashFunctionValue>
 where
     <Value as TryInto<usize>>::Error: Debug,
@@ -167,9 +172,10 @@ impl<H: HashFunction<Value>, Value: HashFunctionValue> Hasher<H, Value>
 where
     <Value as TryInto<usize>>::Error: Debug,
 {
+    /// Sentinel value to mark an unoccupied bucket.
     pub const UNOCCUPIED: u64 = u64::MAX;
 
-    /// Create `Hasher` object with given parameters
+    /// Create `Hasher` object with given parameters.
     pub fn new(parameters: Parameters<H, Value>) -> Self {
         let hash_functions =
             array::from_fn(|i| H::from_description(parameters.hash_function_descriptions[i]));
@@ -179,29 +185,29 @@ where
         }
     }
 
-    /// Return the parameters
+    /// Return the parameters.
     pub fn get_parameters(&self) -> &Parameters<H, Value> {
         &self.parameters
     }
 
-    /// Hash a single item with the given hash function
+    /// Hash a single item with the given hash function.
     pub fn hash_single(&self, hash_function_index: usize, item: u64) -> Value {
         assert!(hash_function_index < NUMBER_HASH_FUNCTIONS);
         self.hash_functions[hash_function_index].hash_single(item)
     }
 
-    /// Hash the whole domain [0, domain_size) with all three hash functions
+    /// Hash the whole domain [0, domain_size) with all three hash functions.
     pub fn hash_domain(&self, domain_size: u64) -> [Vec<Value>; NUMBER_HASH_FUNCTIONS] {
         array::from_fn(|i| self.hash_functions[i].hash_range(0..domain_size))
     }
 
-    /// Hash the given items with all three hash functions
+    /// Hash the given items with all three hash functions.
     pub fn hash_items(&self, items: &[u64]) -> [Vec<Value>; NUMBER_HASH_FUNCTIONS] {
         array::from_fn(|i| self.hash_functions[i].hash_slice(items))
     }
 
     /// Hash the whole domain [0, domain_size) into buckets with all three hash functions
-    /// using precomputed hashes
+    /// using precomputed hashes.
     pub fn hash_domain_into_buckets_given_hashes(
         &self,
         domain_size: u64,
@@ -219,12 +225,12 @@ where
         hash_table
     }
 
-    /// Hash the whole domain [0, domain_size) into buckets with all three hash functions
+    /// Hash the whole domain [0, domain_size) into buckets with all three hash functions.
     pub fn hash_domain_into_buckets(&self, domain_size: u64) -> Vec<Vec<u64>> {
         self.hash_domain_into_buckets_given_hashes(domain_size, &self.hash_domain(domain_size))
     }
 
-    /// Hash the given items into buckets all three hash functions
+    /// Hash the given items into buckets all three hash functions.
     pub fn hash_items_into_buckets(&self, items: &[u64]) -> Vec<Vec<u64>> {
         let mut hash_table = vec![Vec::new(); self.parameters.number_buckets];
         let hashes = self.hash_items(items);
@@ -238,7 +244,7 @@ where
         hash_table
     }
 
-    /// Compute a vector of the sizes of all buckets
+    /// Compute a vector of the sizes of all buckets.
     pub fn compute_bucket_sizes(hash_table: &[Vec<u64>]) -> Vec<usize> {
         hash_table.iter().map(|v| v.len()).collect()
     }
@@ -266,7 +272,7 @@ where
         lookup_table
     }
 
-    /// Use the lookup table for the position map
+    /// Use the lookup table for the position map.
     pub fn pos_lookup(lookup_table: &[[(usize, usize); 3]], bucket_i: usize, item: u64) -> u64 {
         for k in 0..NUMBER_HASH_FUNCTIONS {
             if lookup_table[item as usize][k].0 == bucket_i {
@@ -276,8 +282,8 @@ where
         panic!("logic error");
     }
 
-    /// Perform cuckoo hashing to place the given items into a vector
-    /// NB: number of items must match the number of items used to generate the parameters
+    /// Perform cuckoo hashing to place the given items into a vector.
+    /// NB: number of items must match the number of items used to generate the parameters.
     pub fn cuckoo_hash_items(&self, items: &[u64]) -> (Vec<u64>, Vec<usize>) {
         let number_inputs = self.parameters.number_inputs;
         let number_buckets = self.parameters.number_buckets;

+ 31 - 6
utils/src/field.rs

@@ -1,3 +1,8 @@
+//! Implementation of the prime field used in Ramen.
+
+#![allow(missing_docs)] // Otherwise, there will be a warning originating from the PrimeField
+                        // derive macro ...
+
 use crate::fixed_key_aes::FixedKeyAes;
 use bincode;
 use blake3;
@@ -6,11 +11,11 @@ use num;
 use rand::{thread_rng, Rng};
 use rug;
 
+/// Prime number `p` defining [`Fp`].
 #[allow(non_upper_case_globals)]
 pub const p: u128 = 340282366920938462946865773367900766209;
 
-/// Prime field with modulus
-/// p = 340282366920938462946865773367900766209.
+/// Prime field with modulus [`p`].
 #[derive(PrimeField)]
 #[PrimeFieldModulus = "340282366920938462946865773367900766209"]
 #[PrimeFieldGenerator = "7"]
@@ -50,44 +55,61 @@ impl num::traits::Zero for Fp {
     }
 }
 
+/// Specifies that Self is the range of a PRF.
 pub trait FromPrf {
+    /// Key type of the PRF.
     type PrfKey: Copy;
-    /// PRF key generation
+
+    /// PRF key generation.
     fn prf_key_gen() -> Self::PrfKey;
-    /// PRF into Fp
+
+    /// PRF: `[u64] -> Self`.
     fn prf(key: &Self::PrfKey, input: u64) -> Self;
-    /// PRF into vector of Fp
+
+    /// PRF into vector of Self.
     fn prf_vector(key: &Self::PrfKey, input: u64, size: usize) -> Vec<Self>
     where
         Self: Sized;
 }
 
+/// Specifies that Self can be obtained from a PRG.
 pub trait FromPrg {
+    /// Expand a seed given as 128 bit integer.
     fn expand(input: u128) -> Self;
+
+    /// Expand a seed given as byte slice of length 16.
     fn expand_bytes(input: &[u8]) -> Self;
 }
 
+/// Trait for prime fields where the modulus can be provided as a 128 bit integer.
 pub trait Modulus128 {
     /// Modulus of the prime field
     const MOD: u128;
 }
+
 impl Modulus128 for Fp {
     const MOD: u128 = p;
 }
 
+/// Specifies that Self can be hashed into.
 pub trait FromHash {
-    /// Hash into Fp
+    /// Hash a 64 bit integer into Self.
     fn hash(input: u64) -> Self;
+
+    /// Hash a byte slice into Self.
     fn hash_bytes(input: &[u8]) -> Self;
 }
 
+/// Definies the Legendre symbol in a prime field.
 pub trait LegendreSymbol: PrimeField {
     /// Return an arbitrary QNR.
     fn get_non_random_qnr() -> Self;
+
     /// Compute the Legendre Symbol (p/a)
     fn legendre_symbol(a: Self) -> i8;
 }
 
+/// Simple implementation of the legendre symbol using exponentiation.
 pub fn legendre_symbol_exp(a: Fp) -> i8 {
     // handle 65x even
     let mut x = a;
@@ -125,6 +147,7 @@ pub fn legendre_symbol_exp(a: Fp) -> i8 {
     }
 }
 
+/// Faster implementation of the legendre symbol using the `rug` library.
 pub fn legendre_symbol_rug(a: Fp) -> i8 {
     let bytes = a.to_le_bytes();
     let a_int = rug::Integer::from_digits(&bytes, rug::integer::Order::LsfLe);
@@ -168,6 +191,7 @@ impl Fp {
         }
     }
 
+    /// Convert a field element into 16 bytes using little endian byte order.
     pub fn to_le_bytes(&self) -> [u8; 16] {
         let mut bytes = [0u8; 16];
         let repr = self.to_repr();
@@ -176,6 +200,7 @@ impl Fp {
         bytes
     }
 
+    /// Create a field element from 16 bytes using little endian byte order.
     pub fn from_le_bytes_vartime(bytes: &[u8; 16]) -> Option<Self> {
         let mut repr = <Self as PrimeField>::Repr::default();
         debug_assert_eq!(repr.as_ref(), &[0u8; 24]);

+ 15 - 6
utils/src/fixed_key_aes.rs

@@ -1,10 +1,12 @@
+//! Functionality for AES in fixed-key mode.
+
 use aes::cipher::crypto_common::Block;
 use aes::cipher::{BlockEncrypt, KeyInit};
 use aes::Aes128;
 use rand::{thread_rng, Rng};
 
 /// Fixed-key AES implementation.  Implements the ((tweakable) circular) correlation robust hash
-/// functions from Guo et al. eprint 2019/074
+/// functions from [Guo et al. (ePrint 2019/074)](https://eprint.iacr.org/2019/074).
 #[derive(Clone, Debug)]
 pub struct FixedKeyAes {
     /// AES object including expanded key.
@@ -12,25 +14,29 @@ pub struct FixedKeyAes {
 }
 
 impl FixedKeyAes {
+    /// Create a new instance with a given key.
     pub fn new(key: [u8; 16]) -> Self {
         Self {
             aes: Aes128::new_from_slice(&key).expect("does not fail since key has the right size"),
         }
     }
 
+    /// Create a new instance with a randomly sampled key.
     pub fn sample() -> Self {
         let key: [u8; 16] = thread_rng().gen();
         Self::new(key)
     }
 
-    /// Permutation sigma(x) = (x.high64 ^ x.low64, x.high64).
+    /// Permutation `sigma(x) = (x.high64 ^ x.low64, x.high64)`.
+    #[inline(always)]
     fn sigma(x: u128) -> u128 {
         let low = x & 0xffffffffffffffff;
         let high = x >> 64;
         ((high ^ low) << 64) | high
     }
 
-    /// Random permutation pi(x) = AES(k, x)
+    /// Random permutation `pi(x) = AES(k, x)`.
+    #[inline(always)]
     pub fn pi(&self, x: u128) -> u128 {
         let mut block = Block::<Aes128>::clone_from_slice(&x.to_le_bytes());
         self.aes.encrypt_block(&mut block);
@@ -42,18 +48,21 @@ impl FixedKeyAes {
         )
     }
 
-    /// MMO function pi(x) ^ x
+    /// MMO function `pi(x) ^ x`.
+    #[inline(always)]
     pub fn hash_cr(&self, x: u128) -> u128 {
         self.pi(x) ^ x
     }
 
-    /// MMO-hat function pi(sigma(x)) ^ sigma(x)
+    /// MMO-hat function `pi(sigma(x)) ^ sigma(x)`.
+    #[inline(always)]
     pub fn hash_ccr(&self, x: u128) -> u128 {
         let sigma_x = Self::sigma(x);
         self.pi(sigma_x) ^ sigma_x
     }
 
-    /// TMMO function pi(pi(x) ^ i) ^ pi(x)
+    /// TMMO function `pi(pi(x) ^ i) ^ pi(x)`.
+    #[inline(always)]
     pub fn hash_tccr(&self, x: u128, tweak: u128) -> u128 {
         let pi_x = self.pi(x);
         self.pi(pi_x ^ tweak) ^ pi_x

+ 11 - 4
utils/src/hash.rs

@@ -1,3 +1,5 @@
+//! Functionality for hash functions.
+
 use crate::fixed_key_aes::FixedKeyAes;
 use bincode;
 use core::fmt::Debug;
@@ -7,7 +9,7 @@ use rand::{thread_rng, Rng, SeedableRng};
 use rand_chacha::ChaCha12Rng;
 use std::marker::PhantomData;
 
-pub trait HashFunctionParameters {}
+/// Defines required properties of hash function values.
 pub trait HashFunctionValue: Integral + TryInto<usize>
 where
     <Self as TryInto<usize>>::Error: Debug,
@@ -18,12 +20,13 @@ impl HashFunctionValue for u16 {}
 impl HashFunctionValue for u32 {}
 impl HashFunctionValue for u64 {}
 
+/// Trait for hash functions `[u64] -> {0, ..., range_size}`.
 pub trait HashFunction<Value: HashFunctionValue>
 where
     <Value as TryInto<usize>>::Error: Debug,
 {
-    // type Domain;
-
+    /// Description type that can be used to pass a small description of a hash function to another
+    /// party.
     type Description: Copy + Debug + PartialEq + Eq;
 
     /// Sample a random hash function.
@@ -32,7 +35,10 @@ where
     /// Sample a hash function using a given seed.
     fn from_seed(range_size: usize, seed: [u8; 32]) -> Self;
 
+    /// Create new hash function instance from a description.
     fn from_description(description: Self::Description) -> Self;
+
+    /// Convert this instance into an equivalent description.
     fn to_description(&self) -> Self::Description;
 
     /// Return the number of elements n in the range [0, n).
@@ -62,7 +68,7 @@ where
     }
 }
 
-/// Fixed-key AES hashing using a circular correlation robust hash function
+/// Fixed-key AES hashing using a circular correlation robust hash function.
 #[derive(Clone, Debug)]
 pub struct AesHashFunction<Value> {
     description: AesHashFunctionDescription,
@@ -71,6 +77,7 @@ pub struct AesHashFunction<Value> {
     _phantom: PhantomData<Value>,
 }
 
+/// Description type for [`AesHashFunction`].
 #[derive(Clone, Copy, Debug, PartialEq, Eq, bincode::Encode, bincode::Decode)]
 pub struct AesHashFunctionDescription {
     /// Size of the range.

+ 4 - 0
utils/src/lib.rs

@@ -1,3 +1,7 @@
+//! Miscellaneous functionality for the Ramen project.
+
+#![warn(missing_docs)]
+
 pub mod bit_decompose;
 pub mod cuckoo;
 pub mod field;

+ 13 - 2
utils/src/permutation.rs

@@ -1,20 +1,31 @@
+//! Functionality for random permutations.
+
 use bincode;
 use rand::{thread_rng, Rng, SeedableRng};
 use rand_chacha::ChaCha20Rng;
 
 /// Trait that models a random permutation.
 pub trait Permutation {
+    /// Key type that defines the permutation.
     type Key: Copy;
 
+    /// Sample a random key for a permutation with the given domain size.
     fn sample(domain_size: usize) -> Self::Key;
+
+    /// Instantiate a permutation object from a given key.
     fn from_key(key: Self::Key) -> Self;
+
+    /// Get the key for this permutation instance.
     fn get_key(&self) -> Self::Key;
+
+    /// Return the domain size of this permutation.
     fn get_domain_size(&self) -> usize;
+
+    /// Apply the permutation to index `x`.
     fn permute(&self, x: usize) -> usize;
-    // fn inverse(&self, x: usize) -> usize;
-    // fn permuted_vector() -> Vec<usize>;
 }
 
+/// Key type for a [`FisherYatesPermutation`].
 #[derive(Clone, Copy, Debug, PartialEq, Eq, bincode::Encode, bincode::Decode)]
 pub struct FisherYatesPermutationKey {
     domain_size: usize,

+ 8 - 0
utils/src/pseudorandom_conversion.rs

@@ -1,10 +1,18 @@
+//! Functionality to convert random seeds into a pseudorandom value.
+//!
+//! Used for the Half-Tree implementation.
+
 use crate::field::FromPrg;
 use core::num::Wrapping;
 
+/// Trait describing a functionality to convert a 128 bit random seed into a pseudorandom value of
+/// type `T`.
 pub trait PRConvertTo<T> {
+    /// Convert random seed into an instance of type `T`.
     fn convert(randomness: u128) -> T;
 }
 
+/// Helper struct for the pseudorandom conversion.
 pub struct PRConverter {}
 
 impl PRConvertTo<u8> for PRConverter {