Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Factor out rerandomizing encryption scheme #56

Merged
merged 1 commit into from
Feb 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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(
jschneider-bensch marked this conversation as resolved.
Show resolved Hide resolved
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
Loading