From a115c341ee7d9cb0c1a6bfde9bb8e2713faeb07c Mon Sep 17 00:00:00 2001 From: Manuthor Date: Tue, 27 Jun 2023 14:09:28 +0200 Subject: [PATCH] feat: update crypto_core to 8 --- .pre-commit-config.yaml | 53 ++++----- Cargo.toml | 5 +- src/callbacks.rs | 16 +-- src/chain_table.rs | 81 +++++++------- src/compact.rs | 73 +++++------- src/compact_live.rs | 60 ++++------ src/entry_table.rs | 233 +++++++++++++++++---------------------- src/in_memory_example.rs | 22 ++-- src/keys.rs | 25 ++--- src/macros.rs | 7 +- src/parameters.rs | 7 +- src/search.rs | 67 ++++------- src/structs.rs | 7 +- src/upsert.rs | 40 +++---- 14 files changed, 284 insertions(+), 412 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7f31437f..e733a167 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -17,7 +17,7 @@ repos: args: [] # optional: list of Conventional Commits types to allow e.g. [feat, fix, ci, chore, test] - repo: https://github.com/pre-commit/mirrors-prettier - rev: v3.0.0-alpha.4 + rev: v3.0.0-alpha.6 hooks: - id: prettier stages: [commit] @@ -26,10 +26,10 @@ repos: - markdown - repo: https://github.com/igorshubovych/markdownlint-cli - rev: v0.32.2 + rev: v0.33.0 hooks: - id: markdownlint-fix - args: [--disable=MD013, --disable=MD024, --disable=MD041, --disable=MD046] + args: [--disable=MD004, --disable=MD013, --disable=MD024, --disable=MD041] - repo: https://github.com/Lucas-C/pre-commit-hooks-nodejs rev: v1.1.2 @@ -37,7 +37,6 @@ repos: - id: htmlhint - id: dockerfile_lint - id: markdown-toc - args: [--bullets='-'] # comment this to refresh TOC - repo: https://github.com/jumanjihouse/pre-commit-hook-yamlfmt rev: 0.2.2 @@ -46,18 +45,12 @@ repos: args: [--mapping, '2', --sequence, '4', --offset, '2'] - repo: https://github.com/crate-ci/typos - rev: v1.13.6 + rev: v1.14.4 hooks: - id: typos - - repo: https://github.com/python-jsonschema/check-jsonschema - rev: 0.19.2 - hooks: - - id: check-github-actions - - id: check-github-workflows - - repo: https://github.com/Lucas-C/pre-commit-hooks - rev: v1.3.1 + rev: v1.5.1 hooks: - id: forbid-crlf - id: remove-crlf @@ -67,7 +60,7 @@ repos: exclude: ^.git/ - repo: https://github.com/sirosen/texthooks - rev: 0.4.0 + rev: 0.5.0 hooks: - id: fix-smartquotes - id: fix-ligatures @@ -85,22 +78,6 @@ repos: hooks: - id: cargo-check - - repo: https://github.com/Cosmian/git-hooks.git - rev: v1.0.7 - hooks: - - id: dprint-toml-fix - - id: cargo-format - - id: cargo-tests-all - - id: cargo-update - - id: cargo-outdated - - id: clippy-autofix-all - - id: clippy-autofix-pedantic - - id: clippy-autofix-nursery - - id: clippy-autofix-others - - id: clippy-all-targets-all-features - - id: cargo-dry-publish - args: [--allow-dirty] - - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.4.0 hooks: @@ -133,8 +110,24 @@ repos: - id: trailing-whitespace - repo: https://github.com/psf/black - rev: 22.12.0 + rev: 23.3.0 hooks: - id: black # avoid clash with `double-quote-string-fixer` args: [--skip-string-normalization] + + - repo: https://github.com/Cosmian/git-hooks.git + rev: v1.0.10 + hooks: + - id: dprint-toml-fix + - id: cargo-format + - id: cargo-update + - id: cargo-outdated + - id: cargo-udeps + - id: cargo-tests-all + - id: cargo-test-doc + - id: clippy-autofix-all + - id: clippy-autofix-pedantic + - id: clippy-autofix-nursery + - id: clippy-autofix-others + - id: clippy-all-targets-all-features diff --git a/Cargo.toml b/Cargo.toml index 3e0746f1..fe752e0d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cosmian_findex" -version = "4.0.1" +version = "4.1.0" authors = [ "Chloé Hébant ", "Bruno Grieder ", @@ -29,8 +29,7 @@ in_memory = [] live_compact = [] [dependencies] -cosmian_crypto_core = "7.0.0" -futures = "0.3" +cosmian_crypto_core = { git = "https://github.com/Cosmian/crypto_core.git", branch = "findex_integration", features = ["aes", "sha3"] } rand = "0.8" tiny-keccak = { version = "2.0.2", features = ["kmac", "sha3"] } zeroize = "1.5" diff --git a/src/callbacks.rs b/src/callbacks.rs index 57f44224..481ebb32 100644 --- a/src/callbacks.rs +++ b/src/callbacks.rs @@ -1,7 +1,5 @@ use std::collections::{HashMap, HashSet}; -use cosmian_crypto_core::symmetric_crypto::Dem; - use crate::{ chain_table::{ChainTableValue, KwiChainUids}, CallbackError, EncryptedTable, Error, IndexedValue, KeyingMaterial, Keyword, Location, Uid, @@ -182,8 +180,6 @@ pub trait FetchChains< const BLOCK_LENGTH: usize, const CHAIN_TABLE_WIDTH: usize, const KWI_LENGTH: usize, - const DEM_KEY_LENGTH: usize, - DemScheme: Dem, CustomError: std::error::Error + CallbackError, >: FindexCallbacks { @@ -206,13 +202,13 @@ pub trait FetchChains< Error, > { // Collect to a `HashSet` to mix UIDs between chains. - let chain_table_uids = kwi_chain_table_uids.values().flatten().cloned().collect(); + let chain_table_uids = kwi_chain_table_uids.values().flatten().copied().collect(); let encrypted_items = self.fetch_chain_table(chain_table_uids).await?; let mut res = HashMap::with_capacity(kwi_chain_table_uids.len()); - for (kwi, chain_table_uids) in kwi_chain_table_uids.into_iter() { - let kwi_value = kwi.derive_dem_key(CHAIN_TABLE_KEY_DERIVATION_INFO); + for (kwi, chain_table_uids) in kwi_chain_table_uids { + let kwi_value = kwi.derive_dem_key(CHAIN_TABLE_KEY_DERIVATION_INFO)?; // Use a vector not to shuffle the chain. This is important because indexed // values can be divided in blocks that span several lines in the chain. @@ -222,11 +218,7 @@ pub trait FetchChains< if let Some(encrypted_value) = encrypted_items.get(&uid) { chain.push(( uid, - ChainTableValue::decrypt::( - &kwi_value, - encrypted_value, - ) - .map_err(|err| { + ChainTableValue::decrypt(&kwi_value, encrypted_value).map_err(|err| { Error::::CryptoError(format!( "fail to decrypt one of the `value` returned by the fetch chains \ callback (uid was '{uid:?}', value was {}, crypto error was \ diff --git a/src/chain_table.rs b/src/chain_table.rs index 6f2751ef..9aa80508 100644 --- a/src/chain_table.rs +++ b/src/chain_table.rs @@ -23,7 +23,7 @@ use std::{ use cosmian_crypto_core::{ bytes_ser_de::{Deserializer, Serializable, Serializer}, reexport::rand_core::CryptoRngCore, - symmetric_crypto::{Dem, SymKey}, + Aes256Gcm, Dem, Instantiable, Nonce, RandomFixedSizeCBytes, SymmetricKey, }; use crate::{ @@ -94,24 +94,35 @@ impl /// /// - `rng` : random number generator /// - `kwi_value` : DEM key used to encrypt the value - pub fn encrypt>( + pub fn encrypt( &self, rng: &mut impl CryptoRngCore, - kwi_value: &DEM::Key, + kwi_value: &SymmetricKey<{ Aes256Gcm::KEY_LENGTH }>, ) -> Result, Error> { - let bytes = self.try_to_bytes()?; - DEM::encrypt(rng, kwi_value, &bytes, None).map_err(Error::from) + let nonce = Nonce::new(rng); + let plaintext = self.serialize()?; + let mut result = Vec::with_capacity( + nonce.as_bytes().len() + plaintext.len() + Aes256Gcm::ENCRYPTION_OVERHEAD, + ); + result.extend(nonce.as_bytes()); + result.extend( + Aes256Gcm::new(kwi_value) + .encrypt(&nonce, &plaintext, None) + .map_err(Error::from)?, + ); + Ok(result) } /// Decrypts the Chain Table value using the given DEM key. /// /// - `kwi_value` : DEM key used to encrypt the value /// - `ciphertext` : encrypted Chain Table value - pub fn decrypt>( - kwi_value: &DEM::Key, + pub fn decrypt( + kwi_value: &SymmetricKey<{ Aes256Gcm::KEY_LENGTH }>, ciphertext: &[u8], ) -> Result { - let max_ciphertext_length = 1 + TABLE_WIDTH * (1 + BLOCK_LENGTH) + DEM::ENCRYPTION_OVERHEAD; + let max_ciphertext_length = + 1 + TABLE_WIDTH * (1 + BLOCK_LENGTH) + Aes256Gcm::ENCRYPTION_OVERHEAD; if max_ciphertext_length != ciphertext.len() { return Err(Error::CryptoError(format!( "invalid ciphertext length: given {}, should be {}", @@ -119,8 +130,8 @@ impl max_ciphertext_length ))); } - let bytes = DEM::decrypt(kwi_value, ciphertext, None)?; - Self::try_from_bytes(&bytes) + let (nonce, ct) = ciphertext.split_at(Aes256Gcm::NONCE_LENGTH); + Self::deserialize(&Aes256Gcm::new(kwi_value).decrypt(&Nonce::try_from(nonce)?, ct, None)?) } } @@ -185,8 +196,8 @@ impl>( - key: &KmacKey, + pub fn generate_uid( + key: &SymmetricKey, bytes: &[u8], ) -> Uid { kmac!( @@ -304,11 +315,7 @@ impl KwiChainUids::default(); for block in indexed_value_1.to_blocks(BlockType::Addition).unwrap() { chain_table_value.try_pushing_blocks(&[block]).unwrap(); } - let bytes = chain_table_value.try_to_bytes().unwrap(); + let bytes = chain_table_value.serialize().unwrap(); assert_eq!(chain_table_value.length(), bytes.len()); - let res = ChainTableValue::try_from_bytes(&bytes).unwrap(); + let res = ChainTableValue::deserialize(&bytes).unwrap(); assert_eq!(chain_table_value, res); for block in indexed_value_2.to_blocks(BlockType::Addition).unwrap() { chain_table_value.try_pushing_blocks(&[block]).unwrap(); } - let bytes = chain_table_value.try_to_bytes().unwrap(); + let bytes = chain_table_value.serialize().unwrap(); assert_eq!(chain_table_value.length(), bytes.len()); - let res = ChainTableValue::try_from_bytes(&bytes).unwrap(); + let res = ChainTableValue::deserialize(&bytes).unwrap(); assert_eq!(chain_table_value, res); } @@ -345,11 +352,13 @@ mod tests { fn test_encryption() { let mut rng = CsRng::from_entropy(); let kwi = KeyingMaterial::::new(&mut rng); - let kwi_value: >::Key = - kwi.derive_kmac_key(CHAIN_TABLE_KEY_DERIVATION_INFO); - let keyword = Keyword::from("Robert".as_bytes()); - let location = Location::from("Robert's location".as_bytes()); + let kwi_value = kwi + .derive_kmac_key(CHAIN_TABLE_KEY_DERIVATION_INFO) + .unwrap(); + + let keyword = Keyword::from("Robert"); + let location = Location::from("Robert's location"); let indexed_value1 = IndexedValue::from(keyword); let indexed_value2 = IndexedValue::from(location); @@ -370,21 +379,11 @@ mod tests { // The indexed values should be short enough to fit in a single block. assert_eq!(chain_table_value2.length, 1); - let c1 = chain_table_value1 - .encrypt::<{ Aes256GcmCrypto::KEY_LENGTH }, Aes256GcmCrypto>(&mut rng, &kwi_value) - .unwrap(); - let c2 = chain_table_value2 - .encrypt::<{ Aes256GcmCrypto::KEY_LENGTH }, Aes256GcmCrypto>(&mut rng, &kwi_value) - .unwrap(); + let c1 = chain_table_value1.encrypt(&mut rng, &kwi_value).unwrap(); + let c2 = chain_table_value2.encrypt(&mut rng, &kwi_value).unwrap(); - let res1 = ChainTableValue::decrypt::<{ Aes256GcmCrypto::KEY_LENGTH }, Aes256GcmCrypto>( - &kwi_value, &c1, - ) - .unwrap(); - let res2 = ChainTableValue::decrypt::<{ Aes256GcmCrypto::KEY_LENGTH }, Aes256GcmCrypto>( - &kwi_value, &c2, - ) - .unwrap(); + let res1 = ChainTableValue::decrypt(&kwi_value, &c1).unwrap(); + let res2 = ChainTableValue::decrypt(&kwi_value, &c2).unwrap(); assert_eq!( chain_table_value1, res1, diff --git a/src/compact.rs b/src/compact.rs index 806acebf..6c79189d 100644 --- a/src/compact.rs +++ b/src/compact.rs @@ -2,11 +2,7 @@ use std::collections::HashMap; -use cosmian_crypto_core::{ - reexport::rand_core::SeedableRng, - symmetric_crypto::{Dem, SymKey}, - CsRng, -}; +use cosmian_crypto_core::{reexport::rand_core::SeedableRng, CsRng, SymmetricKey}; use rand::seq::IteratorRandom; use crate::{ @@ -30,25 +26,14 @@ pub trait FindexCompact< const MASTER_KEY_LENGTH: usize, const KWI_LENGTH: usize, const KMAC_KEY_LENGTH: usize, - const DEM_KEY_LENGTH: usize, - KmacKey: SymKey, - DemScheme: Dem, CustomError: std::error::Error + CallbackError, >: FindexCallbacks - + FetchChains< - UID_LENGTH, - BLOCK_LENGTH, - CHAIN_TABLE_WIDTH, - KWI_LENGTH, - DEM_KEY_LENGTH, - DemScheme, - CustomError, - > + + FetchChains { /// Replaces all the Index Entry Table UIDs and values. New UIDs are derived /// using the given label and the KMAC key derived from the new master key. - /// The values are dectypted using the DEM key derived from the master key + /// The values are decrypted using the DEM key derived from the master key /// and re-encrypted using the DEM key derived from the new master key. /// /// Randomly selects index entries and recompact their associated chains. @@ -89,9 +74,10 @@ pub trait FindexCompact< // Decrypt using `k_value`, generate new UIDs using `new_k_uid` and encrypt // using `new_k_value`. // - let k_value = master_key.derive_dem_key(ENTRY_TABLE_KEY_DERIVATION_INFO); - let new_k_uid = new_master_key.derive_kmac_key(ENTRY_TABLE_KEY_DERIVATION_INFO); - let new_k_value = new_master_key.derive_dem_key(ENTRY_TABLE_KEY_DERIVATION_INFO); + let k_value = master_key.derive_dem_key(ENTRY_TABLE_KEY_DERIVATION_INFO)?; + let new_k_uid: SymmetricKey = + new_master_key.derive_kmac_key(ENTRY_TABLE_KEY_DERIVATION_INFO)?; + let new_k_value = new_master_key.derive_dem_key(ENTRY_TABLE_KEY_DERIVATION_INFO)?; // We need to fetch all the Entry Table to re-encrypt it. // First, fetch all UIds of the Entry table @@ -101,8 +87,7 @@ pub trait FindexCompact< // The goal of this function is to build these two data sets (along with // `chain_table_uids_to_remove`) and send them to the callback to update the // database. - let mut entry_table = - EntryTable::decrypt::(&k_value, &encrypted_entry_table)?; + let mut entry_table = EntryTable::decrypt(&k_value, &encrypted_entry_table)?; let mut chain_table_adds = EncryptedTable::default(); // Entry Table items indexing empty chains should be removed. @@ -120,7 +105,7 @@ pub trait FindexCompact< .keys() .choose_multiple(&mut rng, n_lines) .into_iter() - .cloned() + .copied() .collect::>(); // Unchain the Entry Table entries to be reindexed. @@ -128,15 +113,9 @@ pub trait FindexCompact< KwiChainUids::::with_capacity(entry_table.len()); for (uid, value) in entry_table.iter() { if entry_table_items_to_reindex.contains(uid) { - let k_uid = value.kwi.derive_kmac_key(CHAIN_TABLE_KEY_DERIVATION_INFO); - let chain = value.unchain::< - CHAIN_TABLE_WIDTH, - BLOCK_LENGTH, - KMAC_KEY_LENGTH, - DEM_KEY_LENGTH, - KmacKey, - DemScheme - >(&k_uid)?; + let k_uid = value.kwi.derive_kmac_key(CHAIN_TABLE_KEY_DERIVATION_INFO)?; + let chain = + value.unchain::(&k_uid)?; kwi_chain_table_uids.insert(value.kwi.clone(), chain); } } @@ -155,7 +134,7 @@ pub trait FindexCompact< let chain_table_uids_to_remove = chains_to_reindex .values() .flat_map(|chain| chain.iter().map(|(k, _)| k)) - .cloned() + .copied() .collect(); // Get the values stored in the reindexed chains. @@ -224,30 +203,28 @@ pub trait FindexCompact< // Derive the new keys. let kwi_uid = new_entry_table_value .kwi - .derive_kmac_key(CHAIN_TABLE_KEY_DERIVATION_INFO); + .derive_kmac_key(CHAIN_TABLE_KEY_DERIVATION_INFO)?; let kwi_value = new_entry_table_value .kwi - .derive_dem_key(CHAIN_TABLE_KEY_DERIVATION_INFO); + .derive_dem_key(CHAIN_TABLE_KEY_DERIVATION_INFO)?; let mut new_chains = ChainTable::default(); // Upsert each remaining location in the Chain Table. for remaining_location in remaining_indexed_values_for_this_keyword { - new_entry_table_value.upsert_indexed_value::( - &kwi_uid, - BlockType::Addition, - &remaining_location, - &mut new_chains, - )?; + new_entry_table_value + .upsert_indexed_value::( + &kwi_uid, + BlockType::Addition, + &remaining_location, + &mut new_chains, + )?; } let encrypted_new_chains = new_chains .into_iter() .map(|(uid, value)| -> Result<_, _> { - Ok(( - uid, - value.encrypt::(&mut rng, &kwi_value)?, - )) + Ok((uid, value.encrypt(&mut rng, &kwi_value)?)) }) .collect::, Error>>()?; @@ -256,11 +233,11 @@ pub trait FindexCompact< } entry_table.retain(|uid, _| !entry_table_uids_to_drop.contains(uid)); - entry_table.refresh_uids::(&new_k_uid, label); + entry_table.refresh_uids(&new_k_uid, label); self.update_lines( chain_table_uids_to_remove, - entry_table.encrypt::(&mut rng, &new_k_value)?, + entry_table.encrypt(&mut rng, &new_k_value)?, chain_table_adds, )?; diff --git a/src/compact_live.rs b/src/compact_live.rs index b1db41b3..ee7c6a11 100644 --- a/src/compact_live.rs +++ b/src/compact_live.rs @@ -4,8 +4,7 @@ use std::collections::{HashMap, HashSet}; use cosmian_crypto_core::{ reexport::rand_core::{CryptoRngCore, SeedableRng}, - symmetric_crypto::{Dem, SymKey}, - CsRng, + Aes256Gcm, CsRng, SymmetricKey, }; use crate::{ @@ -33,25 +32,25 @@ const GAMMA: f64 = 0.577; /// /// The Entry Table line: /// -/// | UID | -> | H(w) | K_w | UID_5 | +/// | UID | -> | H(w) | `K_w` | `UID_5` | /// /// becomes: /// -/// | UID | -> | H(w) | K_w' | UID_1' | +/// | UID | -> | H(w) | `K_w`' | `UID_1`' | /// /// and the old chain (values are chosen arbitrarily in the aim to illustrate /// different properties and `B1` ... `B4` are the non-padding blocks indexed /// for the keyword `w`): /// -/// | UID_1 | -> Enc(K_w, | B1 (Add) | B2 (Add) | Padding |) -/// | UID_2 | -> Enc(K_w, | B2 (Add) | Padding | Padding |) -/// | UID_3 | -> Enc(K_w, | B1 (Del) | B3 (Add) | B4 (Add) |) -/// | UID_4 | -> Enc(K_w, | B2 (Del) | Padding | Padding |) -/// | UID_5 | -> Enc(K_w, | B2 (Add) | B3 (Add) | B4 (Add) |) +/// | `UID_1` | -> Enc(`K_w`, | B1 (Add) | B2 (Add) | Padding |) +/// | `UID_2` | -> Enc(`K_w`, | B2 (Add) | Padding | Padding |) +/// | `UID_3` | -> Enc(`K_w`, | B1 (Del) | B3 (Add) | B4 (Add) |) +/// | `UID_4` | -> Enc(`K_w`, | B2 (Del) | Padding | Padding |) +/// | `UID_5` | -> Enc(`K_w`, | B2 (Add) | B3 (Add) | B4 (Add) |) /// /// becomes: /// -/// | UID_1' | -> Enc(K_w', | B2 (Add) | B3 (Add) | B4 (Add) |) +/// | `UID_1`' | -> Enc(`K_w`', | B2 (Add) | B3 (Add) | B4 (Add) |) /// /// The following operations have been applied: /// - a new random ephemeral key `K_w'` is drawn; @@ -71,9 +70,6 @@ pub trait FindexLiveCompact< const MASTER_KEY_LENGTH: usize, const KWI_LENGTH: usize, const KMAC_KEY_LENGTH: usize, - const DEM_KEY_LENGTH: usize, - KmacKey: SymKey, - DemScheme: Dem, CustomError: std::error::Error + CallbackError, >: FindexCallbacks @@ -85,9 +81,6 @@ pub trait FindexLiveCompact< MASTER_KEY_LENGTH, KWI_LENGTH, KMAC_KEY_LENGTH, - DEM_KEY_LENGTH, - KmacKey, - DemScheme, CustomError, > { @@ -103,7 +96,7 @@ pub trait FindexLiveCompact< /// These sets are mutually exclusive and the ratio of the cardinal of the noise set over the /// target set is given by `Self::NOISE_RATIO`. /// - /// Returns the target set and the noise set. A HashSet is used for the noise set to allow fast + /// Returns the target set and the noise set. A `HashSet` is used for the noise set to allow fast /// lookups and a list is used for the target set to avoid hashing. /// /// # Parameters @@ -186,29 +179,26 @@ pub trait FindexLiveCompact< /// - `encrypted_entry_table` : encrypted Entry Table async fn fetch_chain_data( &self, - k_value: &DemScheme::Key, + k_value: &SymmetricKey<{ Aes256Gcm::KEY_LENGTH }>, encrypted_entry_table: &EncryptedTable, ) -> Result< ChainData, Error, > { let entry_table: EntryTable = - EntryTable::decrypt::(k_value, encrypted_entry_table)?; + EntryTable::decrypt(k_value, encrypted_entry_table)?; let mut chains = ChainData::with_capacity(entry_table.len()); // Unchain all Entry Table UIDs. let kwi_chain_table_uids: KwiChainUids = entry_table.iter().map(|(_, value)| -> Result<_, _>{ - let k_uid = value.kwi.derive_kmac_key(CHAIN_TABLE_KEY_DERIVATION_INFO); + let k_uid = value.kwi.derive_kmac_key(CHAIN_TABLE_KEY_DERIVATION_INFO)?; Ok(( value.kwi.clone(), value.unchain::< CHAIN_TABLE_WIDTH, BLOCK_LENGTH, KMAC_KEY_LENGTH, - DEM_KEY_LENGTH, - KmacKey, - DemScheme >(&k_uid)? )) }).collect::>>()?; @@ -222,7 +212,7 @@ pub trait FindexLiveCompact< .ok_or(Error::::CryptoError(format!( "no matching Kwi in `kwi_chain_table_uids` ({:?})", v.kwi - )))?.to_vec(), + )))?.clone(), ); } @@ -232,7 +222,7 @@ pub trait FindexLiveCompact< .await?; // Convert the blocks of the given chains into indexed values. - for (entry_table_uid, entry_table_value) in entry_table.into_iter() { + for (entry_table_uid, entry_table_value) in entry_table { let chain = chain_values .get(&entry_table_value.kwi) @@ -268,7 +258,7 @@ pub trait FindexLiveCompact< fn compact_chains( &self, rng: &mut impl CryptoRngCore, - k_value: &DemScheme::Key, + k_value: &SymmetricKey<{ Aes256Gcm::KEY_LENGTH }>, noise: &HashSet>, noisy_remaining_locations: &HashSet, noisy_encrypted_entry_table: &EncryptedTable, @@ -285,7 +275,7 @@ pub trait FindexLiveCompact< let mut cache = HashMap::with_capacity(noisy_chain_values.len() - noise.len()); for (uid, encrypted_value) in noisy_encrypted_entry_table.iter() { - let entry_table_value = EntryTableValue::decrypt::( + let entry_table_value = EntryTableValue::decrypt( k_value, encrypted_value )?; @@ -325,9 +315,6 @@ pub trait FindexLiveCompact< CHAIN_TABLE_WIDTH, BLOCK_LENGTH, KMAC_KEY_LENGTH, - DEM_KEY_LENGTH, - KmacKey, - DemScheme >(rng, &compacted_chains)?; Ok((noisy_entry_table, compacted_chain_table)) @@ -342,7 +329,7 @@ pub trait FindexLiveCompact< async fn live_compact_uids( &mut self, rng: &mut impl CryptoRngCore, - k_value: &DemScheme::Key, + k_value: &SymmetricKey<{ Aes256Gcm::KEY_LENGTH }>, mixed_uids: HashSet>, noise_uids: &HashSet>, ) -> Result<(), Error> { @@ -364,7 +351,7 @@ pub trait FindexLiveCompact< let noisy_locations = chains.chain_values .iter() .flat_map(|(_, values)| values) - .filter_map(|value| value.get_location()) + .filter_map(IndexedValue::get_location) .cloned() .collect(); let noisy_remaining_locations = self.filter_removed_locations(noisy_locations)?; @@ -387,7 +374,7 @@ pub trait FindexLiveCompact< // Try upserting the new Entry Table. let upsert_data = UpsertData::new( &encrypted_entry_table, - noisy_entry_table.encrypt::(rng, k_value)?, + noisy_entry_table.encrypt(rng, k_value)?, ); // Delete unused chains (at least one chain value per entry line): @@ -439,10 +426,7 @@ pub trait FindexLiveCompact< num_reindexing_before_full_set: u32, ) -> Result<(), Error> { let mut rng = CsRng::from_entropy(); - let k_value = master_key.derive_dem_key::< - DEM_KEY_LENGTH, - DemScheme::Key - >(ENTRY_TABLE_KEY_DERIVATION_INFO); + let k_value = master_key.derive_dem_key(ENTRY_TABLE_KEY_DERIVATION_INFO)?; let (mixed_uids, noise_uids) = self.select_uids_with_noise(&mut rng, num_reindexing_before_full_set).await?; @@ -451,7 +435,7 @@ pub trait FindexLiveCompact< self.live_compact_uids( &mut rng, &k_value, - batch.iter().cloned().collect(), + batch.iter().copied().collect(), &noise_uids, ).await?; } diff --git a/src/entry_table.rs b/src/entry_table.rs index 4dba3687..fb7c534b 100644 --- a/src/entry_table.rs +++ b/src/entry_table.rs @@ -13,7 +13,7 @@ use std::{ use cosmian_crypto_core::{ bytes_ser_de::{Deserializer, Serializer}, reexport::rand_core::CryptoRngCore, - symmetric_crypto::{Dem, SymKey}, + Aes256Gcm, Dem, Instantiable, Nonce, RandomFixedSizeCBytes, SymmetricKey, }; use crate::{ @@ -67,14 +67,9 @@ impl EntryTableValue, - >( + pub(crate) fn next_chain_table_uid( &mut self, - kwi_uid: &KmacKey, + kwi_uid: &SymmetricKey<{ Aes256Gcm::KEY_LENGTH }>, ) -> &Uid { let new_uid = match &self.chain_table_uid { Some(old_uid) => { @@ -109,10 +104,9 @@ impl EntryTableValue, >( &mut self, - kwi_uid: &KmacKey, + kwi_uid: &SymmetricKey<{ Aes256Gcm::KEY_LENGTH }>, insertion_type: BlockType, indexed_value: &IndexedValue, chain_table: &mut ChainTable, @@ -137,10 +131,8 @@ impl EntryTableValue( - kwi_uid, - ); + let new_chain_uid = + self.next_chain_table_uid::(kwi_uid); let mut new_chain_value = ChainTableValue::default(); let n_additions = CHAIN_TABLE_WIDTH.min(new_blocks.len() - index); new_chain_value.try_pushing_blocks(&new_blocks[index..index + n_additions])?; @@ -160,10 +152,10 @@ impl EntryTableValue>( + pub(crate) fn encrypt( &self, rng: &mut impl CryptoRngCore, - k_value: &DemScheme::Key, + k_value: &SymmetricKey<{ Aes256Gcm::KEY_LENGTH }>, ) -> Result, Error> { let mut ser = Serializer::new(); if let Some(chain_table_uid) = &self.chain_table_uid { @@ -173,18 +165,32 @@ impl EntryTableValue>( - k_value: &DemScheme::Key, + pub(crate) fn decrypt( + k_value: &SymmetricKey<{ Aes256Gcm::KEY_LENGTH }>, ciphertext: &[u8], ) -> Result { - let bytes = DemScheme::decrypt(k_value, ciphertext, None)?; + let (nonce, ct) = ciphertext.split_at(Aes256Gcm::NONCE_LENGTH); + let bytes = Aes256Gcm::new(k_value).decrypt(&Nonce::try_from(nonce)?, ct, None)?; let mut de = Deserializer::new(&bytes); let chain_table_uid = de.read_array::()?; @@ -215,17 +221,15 @@ impl EntryTableValue, - DemScheme: Dem, >( &self, - kwi_uid: &KmacKey, + kwi_uid: &SymmetricKey, ) -> Result>, Error> { let mut chain = Vec::new(); @@ -259,11 +263,11 @@ impl EntryTableValue | -/// +-----------+-------+-------+-------------------+ +/// +-----------+------------------------------------------+ +/// | Key | Value | +/// +-----------+-------+-------+--------------------------+ +/// | UID | `K_wi` | `H_wi` | `Option` | +/// +-----------+-------+-------+--------------------------+ /// /// with: /// - `UID_LENGTH` is the length of `UID` and `UID_last` @@ -275,7 +279,7 @@ impl EntryTableValue( HashMap, EntryTableValue>, @@ -322,8 +326,8 @@ impl EntryTable>( - key: &KmacKey, + pub fn generate_uid( + key: &SymmetricKey, keyword_hash: &KeywordHash, label: &Label, ) -> Uid { @@ -334,27 +338,24 @@ impl EntryTable>( - k_value: &DemScheme::Key, + pub fn decrypt( + k_value: &SymmetricKey<{ Aes256Gcm::KEY_LENGTH }>, encrypted_entry_table: &EncryptedTable, ) -> Result { let mut entry_table = Self::with_capacity(encrypted_entry_table.len()); for (k, v) in encrypted_entry_table.iter() { - let decrypted_value = EntryTableValue::::decrypt::< - DEM_KEY_LENGTH, - DemScheme, - >(k_value, v) - .map_err(|err| { - Error::CryptoError(format!( - "fail to decrypt one of the `value` returned by the fetch entries callback \ - (uid was '{k:?}', value was {}, crypto error was '{err}')", - if v.is_empty() { - "empty".to_owned() - } else { - format!("'{v:?}'") - }, - )) - })?; + let decrypted_value = EntryTableValue::::decrypt(k_value, v) + .map_err(|err| { + Error::CryptoError(format!( + "fail to decrypt one of the `value` returned by the fetch entries \ + callback (uid was '{k:?}', value was {}, crypto error was '{err}')", + if v.is_empty() { + "empty".to_owned() + } else { + format!("'{v:?}'") + }, + )) + })?; entry_table.insert(*k, decrypted_value); } @@ -365,14 +366,14 @@ impl EntryTable>( + pub fn encrypt( &self, rng: &mut impl CryptoRngCore, - k_value: &DemScheme::Key, + k_value: &SymmetricKey<{ Aes256Gcm::KEY_LENGTH }>, ) -> Result, Error> { let mut encrypted_entry_table = EncryptedTable::with_capacity(self.len()); for (k, v) in self.iter() { - encrypted_entry_table.insert(*k, v.encrypt::(rng, k_value)?); + encrypted_entry_table.insert(*k, v.encrypt(rng, k_value)?); } Ok(encrypted_entry_table) } @@ -382,9 +383,9 @@ impl EntryTable>( + pub fn refresh_uids( &mut self, - k_uid: &KmacKey, + k_uid: &SymmetricKey, label: &Label, ) { let mut res = Self::with_capacity(self.len()); @@ -414,9 +415,6 @@ impl EntryTable, - DemScheme: Dem, >( &mut self, rng: &mut impl CryptoRngCore, @@ -433,10 +431,10 @@ impl EntryTable EntryTable(&kwi_uid, *block_type, indexed_value, &mut new_chain_table_entries)?; } let encrypted_chain_table_additions = new_chain_table_entries .into_iter() - .map(|(uid, value)| -> Result<_, _> { - Ok(( - uid, - value.encrypt::(rng, &kwi_value)?, - )) - }) + .map(|(uid, value)| -> Result<_, _> { Ok((uid, value.encrypt(rng, &kwi_value)?)) }) .collect::>()?; chain_table_additions.insert(*entry_table_uid, encrypted_chain_table_additions); @@ -473,56 +466,48 @@ mod tests { use cosmian_crypto_core::{ reexport::rand_core::{RngCore, SeedableRng}, - symmetric_crypto::{aes_256_gcm_pure::Aes256GcmCrypto, Dem}, CsRng, }; use super::*; use crate::{ - chain_table::KwiChainUids, parameters::*, structs::Location, Keyword, - ENTRY_TABLE_KEY_DERIVATION_INFO, + chain_table::KwiChainUids, + parameters::{ + BLOCK_LENGTH, CHAIN_TABLE_WIDTH, KMAC_KEY_LENGTH, KWI_LENGTH, MASTER_KEY_LENGTH, + UID_LENGTH, + }, + structs::Location, + Keyword, ENTRY_TABLE_KEY_DERIVATION_INFO, }; #[test] fn test_encryption() { let mut rng = CsRng::from_entropy(); let k = KeyingMaterial::::new(&mut rng); - let k_value = k.derive_kmac_key(ENTRY_TABLE_KEY_DERIVATION_INFO); + let k_value = k.derive_kmac_key(ENTRY_TABLE_KEY_DERIVATION_INFO).unwrap(); - let keyword = Keyword::from("Robert".as_bytes()); + let keyword = Keyword::from("Robert"); let mut entry_table_value = EntryTableValue::::new::< CHAIN_TABLE_WIDTH, BLOCK_LENGTH, >(&mut rng, keyword.hash()); - let c = entry_table_value - .encrypt::<{ Aes256GcmCrypto::KEY_LENGTH }, Aes256GcmCrypto>(&mut rng, &k_value) - .unwrap(); + let c = entry_table_value.encrypt(&mut rng, &k_value).unwrap(); - let res = EntryTableValue::decrypt::<{ Aes256GcmCrypto::KEY_LENGTH }, Aes256GcmCrypto>( - &k_value, &c, - ) - .unwrap(); + let res = EntryTableValue::decrypt(&k_value, &c).unwrap(); assert_eq!(entry_table_value, res); let kwi_uid = entry_table_value .kwi - .derive_kmac_key(CHAIN_TABLE_KEY_DERIVATION_INFO); - entry_table_value - .next_chain_table_uid::( - &kwi_uid, - ); - - let c = entry_table_value - .encrypt::<{ Aes256GcmCrypto::KEY_LENGTH }, Aes256GcmCrypto>(&mut rng, &k_value) + .derive_kmac_key(CHAIN_TABLE_KEY_DERIVATION_INFO) .unwrap(); + entry_table_value.next_chain_table_uid::(&kwi_uid); + + let c = entry_table_value.encrypt(&mut rng, &k_value).unwrap(); - let res = EntryTableValue::decrypt::<{ Aes256GcmCrypto::KEY_LENGTH }, Aes256GcmCrypto>( - &k_value, &c, - ) - .unwrap(); + let res = EntryTableValue::decrypt(&k_value, &c).unwrap(); assert_eq!(entry_table_value, res); } @@ -530,7 +515,7 @@ mod tests { #[test] fn test_upsert_many_values() { let mut rng = CsRng::from_entropy(); - let keyword = Keyword::from("Robert".as_bytes()); + let keyword = Keyword::from("Robert"); let mut entry_table_value = EntryTableValue::::new::< CHAIN_TABLE_WIDTH, @@ -539,16 +524,17 @@ mod tests { let kwi_uid = entry_table_value .kwi - .derive_kmac_key(CHAIN_TABLE_KEY_DERIVATION_INFO); + .derive_kmac_key(CHAIN_TABLE_KEY_DERIVATION_INFO) + .unwrap(); // Upsert TABLE_WIDTH + 1 values. let mut chain_table = ChainTable::default(); - for i in 0..(CHAIN_TABLE_WIDTH + 1) { + for i in 0..=CHAIN_TABLE_WIDTH { let location = Location::from(format!("Robert's location nb {i}").as_bytes()); let indexed_value = IndexedValue::from(location); entry_table_value - .upsert_indexed_value::( + .upsert_indexed_value::( &kwi_uid, BlockType::Addition, &indexed_value, @@ -560,22 +546,18 @@ mod tests { // Recover Chain Table UIDs associated to the Entry Table value. let k_uid = entry_table_value .kwi - .derive_kmac_key(CHAIN_TABLE_KEY_DERIVATION_INFO); + .derive_kmac_key(CHAIN_TABLE_KEY_DERIVATION_INFO) + .unwrap(); - let chain = entry_table_value.unchain::< - CHAIN_TABLE_WIDTH, - BLOCK_LENGTH, - KMAC_KEY_LENGTH, - {Aes256GcmCrypto::KEY_LENGTH}, - KmacKey, - Aes256GcmCrypto - >(&k_uid).unwrap(); + let chain = entry_table_value + .unchain::(&k_uid) + .unwrap(); // Recover the indexed values from the Chain Table blocks. let blocks = chain .iter() .filter_map(|uid| chain_table.get(uid)) - .flat_map(|chain_table_value| chain_table_value.as_blocks()); + .flat_map(ChainTableValue::as_blocks); let indexed_values = IndexedValue::from_blocks(blocks).unwrap(); // Assert the correct indexed values have been recovered. @@ -591,7 +573,7 @@ mod tests { let location = Location::from(format!("Robert's location nb {i}").as_bytes()); let indexed_value = IndexedValue::from(location); entry_table_value - .upsert_indexed_value::( + .upsert_indexed_value::( &kwi_uid, BlockType::Deletion, &indexed_value, @@ -601,26 +583,21 @@ mod tests { } // Recover Chain Table UIDs associated to the Entry Table value. - let chain = entry_table_value.unchain::< - CHAIN_TABLE_WIDTH, - BLOCK_LENGTH, - KMAC_KEY_LENGTH, - {Aes256GcmCrypto::KEY_LENGTH}, - KmacKey, - Aes256GcmCrypto - >(&k_uid).unwrap(); + let chain = entry_table_value + .unchain::(&k_uid) + .unwrap(); // Recover the indexed values from the Chain Table blocks. let blocks = chain .iter() .filter_map(|uid| chain_table.get(uid)) - .flat_map(|chain_table_value| chain_table_value.as_blocks()); + .flat_map(ChainTableValue::as_blocks); let indexed_values = IndexedValue::from_blocks(blocks).unwrap(); // Assert the correct indexed values have been recovered. assert_eq!(indexed_values.len(), 1); assert!(indexed_values.contains(&IndexedValue::from(Location::from( - "Robert's location nb 0".as_bytes() + "Robert's location nb 0" )))); } @@ -644,11 +621,12 @@ mod tests { let kwi_uid = entry_table_value .kwi - .derive_kmac_key(CHAIN_TABLE_KEY_DERIVATION_INFO); + .derive_kmac_key(CHAIN_TABLE_KEY_DERIVATION_INFO) + .unwrap(); let mut chain_table = ChainTable::default(); entry_table_value - .upsert_indexed_value::( + .upsert_indexed_value::( &kwi_uid, BlockType::Addition, &long_location, @@ -659,17 +637,14 @@ mod tests { let mut kwi_chain_table_uids = KwiChainUids::default(); let k_uid = entry_table_value .kwi - .derive_kmac_key(CHAIN_TABLE_KEY_DERIVATION_INFO); + .derive_kmac_key(CHAIN_TABLE_KEY_DERIVATION_INFO) + .unwrap(); - kwi_chain_table_uids.insert(entry_table_value.kwi.clone(), - entry_table_value.unchain::< - CHAIN_TABLE_WIDTH, - BLOCK_LENGTH, - KMAC_KEY_LENGTH, - {Aes256GcmCrypto::KEY_LENGTH}, - KmacKey, - Aes256GcmCrypto - >(&k_uid).unwrap() + kwi_chain_table_uids.insert( + entry_table_value.kwi.clone(), + entry_table_value + .unchain::(&k_uid) + .unwrap(), ); // Only one keyword is indexed. @@ -679,7 +654,7 @@ mod tests { let blocks = kwi_chain_table_uids[&entry_table_value.kwi] .iter() .filter_map(|uid| chain_table.get(uid)) - .flat_map(|chain_table_value| chain_table_value.as_blocks()); + .flat_map(ChainTableValue::as_blocks); let indexed_values = IndexedValue::from_blocks(blocks).unwrap(); diff --git a/src/in_memory_example.rs b/src/in_memory_example.rs index 26541987..889cb01b 100644 --- a/src/in_memory_example.rs +++ b/src/in_memory_example.rs @@ -11,7 +11,10 @@ use crate::{ FindexSearch, FindexUpsert, IndexedValue, Keyword, Location, Uid, UpsertData, }; #[cfg(feature = "live_compact")] -use crate::{compact_live::FindexLiveCompact, parameters::*}; +use crate::{ + compact_live::FindexLiveCompact, + parameters::{BLOCK_LENGTH, CHAIN_TABLE_WIDTH, KMAC_KEY_LENGTH, KWI_LENGTH, MASTER_KEY_LENGTH}, +}; #[derive(Debug)] pub struct ExampleError(String); @@ -98,7 +101,7 @@ impl FindexCallbacks } async fn fetch_all_entry_table_uids(&self) -> Result>, ExampleError> { - let uids = self.entry_table.keys().cloned().collect(); + let uids = self.entry_table.keys().copied().collect(); Ok(uids) } @@ -210,16 +213,8 @@ impl FindexCallbacks } } -impl - FetchChains< - UID_LENGTH, - BLOCK_LENGTH, - CHAIN_TABLE_WIDTH, - KWI_LENGTH, - DEM_KEY_LENGTH, - DemScheme, - ExampleError, - > for FindexInMemory +impl FetchChains + for FindexInMemory { } @@ -238,9 +233,6 @@ impl MASTER_KEY_LENGTH, KWI_LENGTH, KMAC_KEY_LENGTH, - DEM_KEY_LENGTH, - KmacKey, - DemScheme, ExampleError, > for FindexInMemory { diff --git a/src/keys.rs b/src/keys.rs index 653fc2e3..d94bf20d 100644 --- a/src/keys.rs +++ b/src/keys.rs @@ -1,14 +1,15 @@ //! This module defines the structures and methods dedicated to key generation. //! In Findex, DEM is used to encrypt values and KMAC is used to derive UIDs. - use cosmian_crypto_core::{ bytes_ser_de::{Deserializer, Serializable, Serializer}, - kdf, + kdf256, reexport::rand_core::CryptoRngCore, - symmetric_crypto::SymKey, + Aes256Gcm, FixedSizeCBytes, SymmetricKey, }; use zeroize::{Zeroize, ZeroizeOnDrop}; +use crate::error::CoreError as Error; + /// Keying Material (KM) used to derive Findex keys. #[must_use] #[derive(Clone, Debug, Hash, Eq, PartialEq)] @@ -32,13 +33,12 @@ impl KeyingMaterial { /// /// The input key material should be of at least 128 bits in order to /// guarantee the 128 bits of security. - #[must_use] - pub fn derive_kmac_key>( + pub fn derive_kmac_key( &self, info: &[u8], - ) -> KmacKey { - let bytes = kdf!(KMAC_KEY_LENGTH, self, info, b"KMAC key"); - KmacKey::from_bytes(bytes) + ) -> Result, Error> { + let bytes = kdf256!(KMAC_KEY_LENGTH, self, info, b"KMAC key"); + Ok(SymmetricKey::try_from_bytes(bytes)?) } /// Derives a DEM key from this keying material. @@ -47,13 +47,12 @@ impl KeyingMaterial { /// /// The input key material should be of at least 128 bits in order to /// guarantee the 128 bits of security. - #[must_use] - pub fn derive_dem_key>( + pub fn derive_dem_key( &self, info: &[u8], - ) -> DemKey { - let bytes = kdf!(DEM_KEY_LENGTH, self, info, b"DEM key"); - DemKey::from_bytes(bytes) + ) -> Result, Error> { + let bytes = kdf256!(Aes256Gcm::KEY_LENGTH, self, info, b"DEM key"); + Ok(SymmetricKey::try_from_bytes(bytes)?) } } diff --git a/src/macros.rs b/src/macros.rs index e35e3dca..13eb1b97 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -66,12 +66,12 @@ macro_rules! impl_byte_vector { Ok(Self::from(de.read_vec()?)) } - fn try_to_bytes(&self) -> Result, Self::Error> { + fn serialize(&self) -> Result, Self::Error> { // don't call `write()` to avoir writing size Ok(self.0.to_vec()) } - fn try_from_bytes(bytes: &[u8]) -> Result { + fn deserialize(bytes: &[u8]) -> Result { // don't call `read()` since there is no leading size Ok(Self(bytes.to_vec())) } @@ -168,9 +168,6 @@ macro_rules! impl_findex_trait { { $crate::parameters::MASTER_KEY_LENGTH }, { $crate::parameters::KWI_LENGTH }, { $crate::parameters::KMAC_KEY_LENGTH }, - { $crate::parameters::DEM_KEY_LENGTH }, - $crate::parameters::KmacKey, - $crate::parameters::DemScheme, $error, > for $findex { diff --git a/src/parameters.rs b/src/parameters.rs index 074b7629..84162bd4 100644 --- a/src/parameters.rs +++ b/src/parameters.rs @@ -1,6 +1,6 @@ //! Defines generic parameters used in Findex interfaces. -use cosmian_crypto_core::symmetric_crypto::{aes_256_gcm_pure::Aes256GcmCrypto, key::Key}; +use cosmian_crypto_core::SymmetricKey; use crate::{chain_table::ChainTableValue, structs::Block}; @@ -27,10 +27,7 @@ pub const KMAC_KEY_LENGTH: usize = 32; pub const DEM_KEY_LENGTH: usize = 32; /// KMAC key type. -pub type KmacKey = Key; - -/// DEM used in Findex. -pub type DemScheme = Aes256GcmCrypto; +pub type KmacKey = SymmetricKey; /// Checks some constraints on constant generics at compile time. pub const fn check_parameter_constraints< diff --git a/src/search.rs b/src/search.rs index d3631b6c..acd36c78 100644 --- a/src/search.rs +++ b/src/search.rs @@ -2,7 +2,7 @@ use std::collections::{HashMap, HashSet}; -use cosmian_crypto_core::symmetric_crypto::{Dem, SymKey}; +use cosmian_crypto_core::{Aes256Gcm, SymmetricKey}; use crate::{ callbacks::{FetchChains, FindexCallbacks}, @@ -22,22 +22,11 @@ pub trait FindexSearch< const MASTER_KEY_LENGTH: usize, const KWI_LENGTH: usize, const KMAC_KEY_LENGTH: usize, - const DEM_KEY_LENGTH: usize, - KmacKey: SymKey, - DemScheme: Dem, CustomError: std::error::Error + CallbackError, >: Sized + FindexCallbacks - + FetchChains< - UID_LENGTH, - BLOCK_LENGTH, - CHAIN_TABLE_WIDTH, - KWI_LENGTH, - DEM_KEY_LENGTH, - DemScheme, - CustomError, - > + + FetchChains { /// Searches for a set of `Keyword`s, returning the corresponding /// `IndexedValue`s. @@ -50,8 +39,8 @@ pub trait FindexSearch< /// - `keywords` : keywords to search async fn core_search( &mut self, - k_uid: &KmacKey, - k_value: &DemScheme::Key, + k_uid: &SymmetricKey, + k_value: &SymmetricKey<{ Aes256Gcm::KEY_LENGTH }>, label: &Label, keywords: &HashSet, ) -> Result>, Error> { @@ -78,37 +67,29 @@ pub trait FindexSearch< // Unchain all Entry Table values. let mut kwi_chain_table_uids = KwiChainUids::with_capacity(entry_table.len()); let mut kwi_to_keyword = HashMap::with_capacity(entry_table.len()); - for (uid, encrypted_value) in entry_table.into_iter() { + for (uid, encrypted_value) in entry_table { let keyword = entry_table_uid_map.get(&uid).ok_or_else(|| { Error::::CryptoError(format!( "Could not find keyword associated to UID {uid:?}." )) })?; - let value = EntryTableValue::::decrypt::< - DEM_KEY_LENGTH, - DemScheme, - >(k_value, &encrypted_value) - .map_err(|_| { - Error::::CryptoError(format!( - "fail to decrypt one of the `value` returned by the fetch entries callback \ - (uid was '{uid:?}', value was {})", - if encrypted_value.is_empty() { - "empty".to_owned() - } else { - format!("'{encrypted_value:?}'") - }, - )) - })?; + let value = + EntryTableValue::::decrypt(k_value, &encrypted_value) + .map_err(|_| { + Error::::CryptoError(format!( + "fail to decrypt one of the `value` returned by the fetch entries \ + callback (uid was '{uid:?}', value was {})", + if encrypted_value.is_empty() { + "empty".to_owned() + } else { + format!("'{encrypted_value:?}'") + }, + )) + })?; kwi_to_keyword.insert(value.kwi.clone(), *keyword); - let k_uid = value.kwi.derive_kmac_key(CHAIN_TABLE_KEY_DERIVATION_INFO); - let chain = value.unchain::< - CHAIN_TABLE_WIDTH, - BLOCK_LENGTH, - KMAC_KEY_LENGTH, - DEM_KEY_LENGTH, - KmacKey, - DemScheme - >(&k_uid)?; + let k_uid = value.kwi.derive_kmac_key(CHAIN_TABLE_KEY_DERIVATION_INFO)?; + let chain = + value.unchain::(&k_uid)?; kwi_chain_table_uids.insert(value.kwi, chain); } @@ -153,8 +134,8 @@ pub trait FindexSearch< label: &Label, mut keywords: HashSet, ) -> Result>, Error> { - let k_uid = master_key.derive_kmac_key(ENTRY_TABLE_KEY_DERIVATION_INFO); - let k_value = master_key.derive_dem_key(ENTRY_TABLE_KEY_DERIVATION_INFO); + let k_uid = master_key.derive_kmac_key(ENTRY_TABLE_KEY_DERIVATION_INFO)?; + let k_value = master_key.derive_dem_key(ENTRY_TABLE_KEY_DERIVATION_INFO)?; let mut graph = HashMap::with_capacity(keywords.len()); @@ -172,7 +153,7 @@ pub trait FindexSearch< .flat_map(|indexed_values| { indexed_values .iter() - .filter_map(|value| value.get_keyword()) + .filter_map(IndexedValue::get_keyword) .filter(|next_keyword| !graph.contains_key(*next_keyword)) .cloned() }) diff --git a/src/structs.rs b/src/structs.rs index f051393b..9d330290 100644 --- a/src/structs.rs +++ b/src/structs.rs @@ -262,7 +262,7 @@ impl IndexedValue { if length != 0 { // This block is not padding. byte_vector.extend(&block.data[..length]); - let value = Self::try_from_bytes(&byte_vector)?; + let value = Self::deserialize(&byte_vector)?; if BlockType::Addition == block_type { indexed_values.insert(value); } else { @@ -419,12 +419,12 @@ impl Serializable for IndexedValue { Self::try_from(de.read_vec()?.as_slice()) } - fn try_to_bytes(&self) -> Result, Self::Error> { + fn serialize(&self) -> Result, Self::Error> { // don't call `write()` to avoir writing size Ok(self.to_vec()) } - fn try_from_bytes(bytes: &[u8]) -> Result { + fn deserialize(bytes: &[u8]) -> Result { // don't call `read()` since there is no leading size Self::try_from(bytes) } @@ -448,6 +448,7 @@ impl EncryptedTable { Self(HashMap::with_capacity(capacity)) } + #[must_use] pub fn into_keys(self) -> IntoKeys, Vec> { self.0.into_keys() } diff --git a/src/upsert.rs b/src/upsert.rs index 8984234a..813b509a 100644 --- a/src/upsert.rs +++ b/src/upsert.rs @@ -3,11 +3,7 @@ use std::collections::{HashMap, HashSet}; -use cosmian_crypto_core::{ - reexport::rand_core::SeedableRng, - symmetric_crypto::{Dem, SymKey}, - CsRng, -}; +use cosmian_crypto_core::{reexport::rand_core::SeedableRng, CsRng, SymmetricKey}; use crate::{ entry_table::EntryTable, @@ -28,9 +24,6 @@ pub trait FindexUpsert< const MASTER_KEY_LENGTH: usize, const KWI_LENGTH: usize, const KMAC_KEY_LENGTH: usize, - const DEM_KEY_LENGTH: usize, - KmacKey: SymKey, - DemScheme: Dem, CustomError: std::error::Error + CallbackError, >: FindexCallbacks { @@ -85,8 +78,9 @@ pub trait FindexUpsert< check_parameter_constraints::(); let mut rng = CsRng::from_entropy(); - let k_uid: KmacKey = master_key.derive_kmac_key(ENTRY_TABLE_KEY_DERIVATION_INFO); - let k_value = master_key.derive_dem_key(ENTRY_TABLE_KEY_DERIVATION_INFO); + let k_uid: SymmetricKey = + master_key.derive_kmac_key(ENTRY_TABLE_KEY_DERIVATION_INFO)?; + let k_value = master_key.derive_dem_key(ENTRY_TABLE_KEY_DERIVATION_INFO)?; let mut new_chains = HashMap::>::with_capacity( @@ -125,36 +119,28 @@ pub trait FindexUpsert< // Query the Entry Table for these UIDs. let mut encrypted_entry_table = self - .fetch_entry_table(new_chains.keys().cloned().collect()) + .fetch_entry_table(new_chains.keys().copied().collect()) .await? .try_into()?; while !new_chains.is_empty() { // Decrypt the Entry Table once and for all. - let mut entry_table = EntryTable::::decrypt::< - DEM_KEY_LENGTH, - DemScheme, - >(&k_value, &encrypted_entry_table)?; + let mut entry_table = + EntryTable::::decrypt(&k_value, &encrypted_entry_table)?; // Build the chains and update the Entry Table. - let chain_table_additions = entry_table.upsert::< - CHAIN_TABLE_WIDTH, - BLOCK_LENGTH, - KMAC_KEY_LENGTH, - DEM_KEY_LENGTH, - KmacKey, - DemScheme, - >( - &mut rng, - &new_chains, - )?; + let chain_table_additions = entry_table + .upsert::( + &mut rng, + &new_chains, + )?; // Finally write new indexes in database. Get the new values of the Entry Table // lines that failed to be upserted. encrypted_entry_table = self .write_indexes( encrypted_entry_table, - entry_table.encrypt::(&mut rng, &k_value)?, + entry_table.encrypt(&mut rng, &k_value)?, chain_table_additions, ) .await?;