Skip to content

Commit

Permalink
Merge pull request #56 from cryspen/jonas/double-enc-feature
Browse files Browse the repository at this point in the history
Factor out rerandomizing encryption scheme
  • Loading branch information
jschneider-bensch authored Feb 1, 2024
2 parents 3f82eb0 + cd0092a commit fd560b8
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 33 deletions.
84 changes: 68 additions & 16 deletions hacspec-scrambledb/scrambledb/src/data_transformations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@ use oprf::coprf::{
coprf_setup::{derive_key, BlindingPublicKey, CoPRFEvaluatorContext},
};

use crate::{data_types::*, error::Error, setup::StoreContext};

use self::double_hpke::{hpke_open_level_2, hpke_seal_level_1, hpke_seal_level_2};
use crate::{
data_types::*,
error::Error,
setup::{StoreContext, StoreEncryptionKey},
};

pub(crate) mod double_hpke;

Expand All @@ -37,7 +39,7 @@ const PSEUDONYMIZATION_CONTEXT: &[u8] = b"CoPRF-Context-Pseudonymization";
/// level-1 encrypted.
pub fn blind_identifiable_datum(
bpk: &BlindingPublicKey,
ek: &[u8],
ek: &StoreEncryptionKey,
datum: &IdentifiableData,
randomness: &mut Randomness,
) -> Result<BlindedIdentifiableData, Error> {
Expand All @@ -49,15 +51,33 @@ pub fn blind_identifiable_datum(
randomness,
)?);

// Level-1 encrypt data value towards receiver.
let encrypted_data_value = hpke_seal_level_1(&datum.data_value, ek, randomness)?;
// Encrypt data value towards receiver.
let encrypted_data_value = encrypt_data_value(&datum.data_value, ek, randomness)?;

Ok(BlindedIdentifiableData {
blinded_handle,
encrypted_data_value,
})
}

/// Encrypt a data value towards a data store.
///
/// Inputs:
/// - `data`: The data value to encrypt.
/// - `ek`: The receiver's public encryption key.
/// - `randomness`: Random bytes
///
/// Output:
/// A new [EncryptedDataValue], the encryption of `data`.
fn encrypt_data_value(
data: &DataValue,
ek: &StoreEncryptionKey,
randomness: &mut Randomness,
) -> Result<EncryptedDataValue, Error> {
let encrypted_data_value = double_hpke::hpke_seal_level_1(&data, &ek.0, randomness)?;
Ok(encrypted_data_value)
}

/// Blind a pseudonymous datum as a first step in pseudonym
/// conversion.
///
Expand All @@ -76,7 +96,7 @@ pub fn blind_identifiable_datum(
pub fn blind_pseudonymized_datum(
store_context: &StoreContext,
bpk: &BlindingPublicKey,
ek: &[u8],
ek: &StoreEncryptionKey,
datum: &PseudonymizedData,
randomness: &mut Randomness,
) -> Result<BlindedPseudonymizedData, Error> {
Expand All @@ -87,8 +107,8 @@ pub fn blind_pseudonymized_datum(
randomness,
)?);

// Level-1 encrypt data value towards receiver.
let encrypted_data_value = hpke_seal_level_1(&datum.data_value, ek, randomness)?;
// Encrypt data value towards receiver.
let encrypted_data_value = encrypt_data_value(&datum.data_value, ek, randomness)?;

Ok(BlindedPseudonymizedData {
blinded_handle,
Expand All @@ -112,7 +132,7 @@ pub fn blind_pseudonymized_datum(
pub fn pseudonymize_blinded_datum(
coprf_context: &CoPRFEvaluatorContext,
bpk: &BlindingPublicKey,
ek: &[u8],
ek: &StoreEncryptionKey,
datum: &BlindedIdentifiableData,
randomness: &mut Randomness,
) -> Result<BlindedPseudonymizedData, Error> {
Expand All @@ -129,15 +149,32 @@ pub fn pseudonymize_blinded_datum(
randomness,
)?);

// Level-2 encrypt data value towards receiver.
let encrypted_data_value = hpke_seal_level_2(&datum.encrypted_data_value, ek, randomness)?;
// Rerandomize encrypted data value towards receiver.
let encrypted_data_value = rerandomize_encryption(&datum.encrypted_data_value, ek, randomness)?;

Ok(BlindedPseudonymizedData {
blinded_handle,
encrypted_data_value,
})
}

/// Rerandomize the encryption of an encrypted data value.
///
/// Inputs:
/// - `data`: The encrypted data value.
/// - `ek`: The receiver's public encryption key.
/// - `randomness`: Random bytes
///
/// Output:
/// A new, rerandomized [EncryptedDataValue].
fn rerandomize_encryption(
data: &EncryptedDataValue,
ek: &StoreEncryptionKey,
randomness: &mut Randomness,
) -> Result<EncryptedDataValue, Error> {
Ok(double_hpke::hpke_seal_level_2(&data, &ek.0, randomness)?)
}

/// Obliviously convert a blinded pseudonymous datum to a given target pseudonym key.
///
/// Inputs:
Expand All @@ -154,7 +191,7 @@ pub fn pseudonymize_blinded_datum(
pub fn convert_blinded_datum(
coprf_context: &CoPRFEvaluatorContext,
bpk: &BlindingPublicKey,
ek: &[u8],
ek: &StoreEncryptionKey,
conversion_target: &[u8],
datum: &BlindedPseudonymizedData,
randomness: &mut Randomness,
Expand All @@ -177,8 +214,8 @@ pub fn convert_blinded_datum(
randomness,
)?);

// Level-2 encrypt data value towards receiver.
let encrypted_data_value = hpke_seal_level_2(&datum.encrypted_data_value, ek, randomness)?;
// Rerandomize encrypted data value towards receiver.
let encrypted_data_value = rerandomize_encryption(&datum.encrypted_data_value, ek, randomness)?;

Ok(BlindedPseudonymizedData {
blinded_handle,
Expand Down Expand Up @@ -207,7 +244,22 @@ pub fn finalize_blinded_datum(
let handle = store_context.finalize_pseudonym(datum.blinded_handle)?;

// Decrypt data value for storage.
let data_value = hpke_open_level_2(&datum.encrypted_data_value, &store_context.hpke_sk)?;
let data_value = decrypt_data_value(&datum.encrypted_data_value, store_context)?;

Ok(PseudonymizedData { handle, data_value })
}

/// Decrypt an encrypted data value.
///
/// Inputs:
/// - `data`: The value to decrypt.
/// - `store_context`: The data store's long term private state, including in particular its decryption key.
///
/// Output:
/// The decrypted [DataValue] or an [Error] on decryption failure.
fn decrypt_data_value(
data: &EncryptedDataValue,
store_context: &StoreContext,
) -> Result<DataValue, Error> {
Ok(double_hpke::hpke_open_level_2(&data, &store_context.dk.0)?)
}
7 changes: 3 additions & 4 deletions hacspec-scrambledb/scrambledb/src/join.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
//! # Pseudonym Conversion
use hacspec_lib::Randomness;
use libcrux::hpke::HpkePublicKey;
use oprf::coprf::coprf_setup::BlindingPublicKey;

use crate::{
data_transformations::{blind_pseudonymized_datum, convert_blinded_datum},
data_types::{BlindedPseudonymizedData, PseudonymizedData},
error::Error,
setup::{ConverterContext, StoreContext},
setup::{ConverterContext, StoreContext, StoreEncryptionKey},
table::Table,
SECPAR_BYTES,
};
Expand All @@ -29,7 +28,7 @@ use crate::{
pub fn blind_pseudonymous_table(
store_context: &StoreContext,
bpk_receiver: BlindingPublicKey,
ek_receiver: &HpkePublicKey,
ek_receiver: &StoreEncryptionKey,
pseudonymized_table: Table<PseudonymizedData>,
randomness: &mut Randomness,
) -> Result<Table<BlindedPseudonymizedData>, Error> {
Expand Down Expand Up @@ -73,7 +72,7 @@ pub fn join_identifier(identifier: String) -> String {
pub fn convert_blinded_table(
converter_context: &ConverterContext,
bpk_receiver: BlindingPublicKey,
ek_receiver: &HpkePublicKey,
ek_receiver: &StoreEncryptionKey,
table: Table<BlindedPseudonymizedData>,
randomness: &mut Randomness,
) -> Result<Table<BlindedPseudonymizedData>, Error> {
Expand Down
31 changes: 22 additions & 9 deletions hacspec-scrambledb/scrambledb/src/setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,17 @@ pub struct ConverterContext {
pub(crate) coprf_context: CoPRFEvaluatorContext,
}

/// A data store's private decryption key.
pub struct StoreDecryptionKey(pub(crate) Vec<u8>);

/// A data store's public encryption key.
#[derive(Clone)]
pub struct StoreEncryptionKey(pub(crate) Vec<u8>);

pub struct StoreContext {
coprf_receiver_context: CoPRFReceiverContext,
pub(crate) hpke_sk: Vec<u8>,
hpke_pk: Vec<u8>,
pub(crate) dk: StoreDecryptionKey,
ek: StoreEncryptionKey,
k_prp: [u8; 32],
}

Expand Down Expand Up @@ -81,16 +88,14 @@ impl StoreContext {
pub fn setup(randomness: &mut Randomness) -> Result<Self, Error> {
let receiver_context = CoPRFReceiverContext::new(randomness);

let HPKEConfig(_, kem, _, _) = crate::HPKE_CONF;
let (hpke_sk, hpke_pk) =
GenerateKeyPair(kem, randomness.bytes(Nsk(kem)).unwrap().to_vec())?;
let (dk, ek) = generate_store_keys(randomness)?;

let k_prp = randomness.bytes(32)?.try_into()?;

Ok(Self {
coprf_receiver_context: receiver_context,
hpke_sk,
hpke_pk,
dk,
ek,
k_prp,
})
}
Expand All @@ -111,8 +116,8 @@ impl StoreContext {
/// let bpk = context.coprf_receiver_context.public_key()
/// return (ek, bpk);
/// ```
pub fn public_keys(&self) -> (Vec<u8>, BlindingPublicKey) {
(self.hpke_pk.clone(), self.coprf_receiver_context.get_bpk())
pub fn public_keys(&self) -> (StoreEncryptionKey, BlindingPublicKey) {
(self.ek.clone(), self.coprf_receiver_context.get_bpk())
}

/// - Finalize Pseudonym: As part of the finalization of a split or join
Expand Down Expand Up @@ -163,3 +168,11 @@ impl StoreContext {
P256Point::from_raw_bytes(prp::prp(pseudonym.0, &self.k_prp)).map_err(|e| e.into())
}
}

fn generate_store_keys(
randomness: &mut Randomness,
) -> Result<(StoreDecryptionKey, StoreEncryptionKey), Error> {
let HPKEConfig(_, kem, _, _) = crate::HPKE_CONF;
let (hpke_sk, hpke_pk) = GenerateKeyPair(kem, randomness.bytes(Nsk(kem)).unwrap().to_vec())?;
Ok((StoreDecryptionKey(hpke_sk), StoreEncryptionKey(hpke_pk)))
}
7 changes: 3 additions & 4 deletions hacspec-scrambledb/scrambledb/src/split.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
//! # Pseudonymization
use hacspec_lib::Randomness;
use libcrux::hpke::HpkePublicKey;
use oprf::coprf::coprf_setup::BlindingPublicKey;

use crate::{
data_transformations::{blind_identifiable_datum, pseudonymize_blinded_datum},
data_types::{BlindedIdentifiableData, BlindedPseudonymizedData, IdentifiableData},
error::Error,
setup::ConverterContext,
setup::{ConverterContext, StoreEncryptionKey},
table::Table,
};

Expand All @@ -25,7 +24,7 @@ use crate::{
/// Outputs:
/// A table of blinded identifiable data.
pub fn blind_orthonymous_table(
ek_receiver: &HpkePublicKey,
ek_receiver: &StoreEncryptionKey,
bpk_receiver: BlindingPublicKey,
table: Table<IdentifiableData>,
randomness: &mut Randomness,
Expand Down Expand Up @@ -59,7 +58,7 @@ pub fn blind_orthonymous_table(
pub fn pseudonymize_blinded_table(
converter_context: &ConverterContext,
bpk_receiver: BlindingPublicKey,
ek_receiver: &HpkePublicKey,
ek_receiver: &StoreEncryptionKey,
blinded_table: Table<BlindedIdentifiableData>,
randomness: &mut Randomness,
) -> Result<Table<BlindedPseudonymizedData>, Error> {
Expand Down

0 comments on commit fd560b8

Please sign in to comment.