Skip to content

Commit

Permalink
feat: update crypto_core to 8
Browse files Browse the repository at this point in the history
  • Loading branch information
Manuthor committed Jun 27, 2023
1 parent 8e0899a commit a115c34
Show file tree
Hide file tree
Showing 14 changed files with 284 additions and 412 deletions.
53 changes: 23 additions & 30 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand All @@ -26,18 +26,17 @@ 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
hooks:
- 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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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:
Expand Down Expand Up @@ -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
5 changes: 2 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "cosmian_findex"
version = "4.0.1"
version = "4.1.0"
authors = [
"Chloé Hébant <[email protected]>",
"Bruno Grieder <[email protected]>",
Expand Down Expand Up @@ -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"
Expand Down
16 changes: 4 additions & 12 deletions src/callbacks.rs
Original file line number Diff line number Diff line change
@@ -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,
Expand Down Expand Up @@ -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<DEM_KEY_LENGTH>,
CustomError: std::error::Error + CallbackError,
>: FindexCallbacks<CustomError, UID_LENGTH>
{
Expand All @@ -206,13 +202,13 @@ pub trait FetchChains<
Error<CustomError>,
> {
// 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.
Expand All @@ -222,11 +218,7 @@ pub trait FetchChains<
if let Some(encrypted_value) = encrypted_items.get(&uid) {
chain.push((
uid,
ChainTableValue::decrypt::<DEM_KEY_LENGTH, DemScheme>(
&kwi_value,
encrypted_value,
)
.map_err(|err| {
ChainTableValue::decrypt(&kwi_value, encrypted_value).map_err(|err| {
Error::<CustomError>::CryptoError(format!(
"fail to decrypt one of the `value` returned by the fetch chains \
callback (uid was '{uid:?}', value was {}, crypto error was \
Expand Down
81 changes: 40 additions & 41 deletions src/chain_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{
Expand Down Expand Up @@ -94,33 +94,44 @@ impl<const TABLE_WIDTH: usize, const BLOCK_LENGTH: usize>
///
/// - `rng` : random number generator
/// - `kwi_value` : DEM key used to encrypt the value
pub fn encrypt<const KEY_LENGTH: usize, DEM: Dem<KEY_LENGTH>>(
pub fn encrypt(
&self,
rng: &mut impl CryptoRngCore,
kwi_value: &DEM::Key,
kwi_value: &SymmetricKey<{ Aes256Gcm::KEY_LENGTH }>,
) -> Result<Vec<u8>, 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<const DEM_KEY_LENGTH: usize, DEM: Dem<DEM_KEY_LENGTH>>(
kwi_value: &DEM::Key,
pub fn decrypt(
kwi_value: &SymmetricKey<{ Aes256Gcm::KEY_LENGTH }>,
ciphertext: &[u8],
) -> Result<Self, Error> {
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 {}",
ciphertext.len(),
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)?)
}
}

Expand Down Expand Up @@ -185,8 +196,8 @@ impl<const UID_LENGTH: usize, const TABLE_WIDTH: usize, const BLOCK_LENGTH: usiz
///
/// - `key` : KMAC key
/// - `bytes` : bytes from which to derive the UID
pub fn generate_uid<const KMAC_KEY_LENGTH: usize, KmacKey: SymKey<KMAC_KEY_LENGTH>>(
key: &KmacKey,
pub fn generate_uid<const KMAC_KEY_LENGTH: usize>(
key: &SymmetricKey<KMAC_KEY_LENGTH>,
bytes: &[u8],
) -> Uid<UID_LENGTH> {
kmac!(
Expand Down Expand Up @@ -304,11 +315,7 @@ impl<const UID_LENGTH: usize, const KEY_LENGTH: usize> KwiChainUids<UID_LENGTH,

#[cfg(test)]
mod tests {
use cosmian_crypto_core::{
reexport::rand_core::SeedableRng,
symmetric_crypto::{aes_256_gcm_pure::Aes256GcmCrypto, Dem},
CsRng,
};
use cosmian_crypto_core::{reexport::rand_core::SeedableRng, CsRng};

use super::*;
use crate::{
Expand All @@ -322,34 +329,36 @@ mod tests {

#[test]
fn test_serialization() {
let indexed_value_1 = IndexedValue::from(Location::from("location1".as_bytes()));
let indexed_value_2 = IndexedValue::from(Location::from("location2".as_bytes()));
let indexed_value_1 = IndexedValue::from(Location::from("location1"));
let indexed_value_2 = IndexedValue::from(Location::from("location2"));
let mut chain_table_value = ChainTableValue::<CHAIN_TABLE_WIDTH, BLOCK_LENGTH>::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);
}

#[test]
fn test_encryption() {
let mut rng = CsRng::from_entropy();
let kwi = KeyingMaterial::<KWI_LENGTH>::new(&mut rng);
let kwi_value: <Aes256GcmCrypto as Dem<{ Aes256GcmCrypto::KEY_LENGTH }>>::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);

Expand All @@ -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,
Expand Down
Loading

0 comments on commit a115c34

Please sign in to comment.