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

WIP WASM demo #24

Merged
merged 26 commits into from
Sep 27, 2023
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
161a077
WIP WASM demo
jschneider-bensch Sep 5, 2023
53aa922
Nonsense workspace member snuck in
jschneider-bensch Sep 5, 2023
501582a
Commit actual demo code
jschneider-bensch Sep 5, 2023
79775e6
Update `index.html`
jschneider-bensch Sep 5, 2023
b783163
Demo WIP Fixes
jschneider-bensch Sep 6, 2023
72946fb
Readme instructions how to run demo
jschneider-bensch Sep 6, 2023
8e39b36
Run `cargo fmt` on the workspace...
jschneider-bensch Sep 6, 2023
eee5b84
Update hacspec-scrambledb/scrambledb/wasm_demo/index.html
jschneider-bensch Sep 6, 2023
2ae8d19
Just to be sure: Test PRP inversion
jschneider-bensch Sep 7, 2023
114b9e9
coPRF tests
jschneider-bensch Sep 7, 2023
769b63d
coPRF: fix `derive_key`
jschneider-bensch Sep 7, 2023
bc5a41a
WIP Bug hunting
jschneider-bensch Sep 7, 2023
2d8fbed
Merge branch 'jonas/wasm-demo' of github.com:cryspen/atlas into jonas…
jschneider-bensch Sep 7, 2023
9c75048
Test utility
jschneider-bensch Sep 7, 2023
cb3b0f9
fix test deps
franziskuskiefer Sep 7, 2023
29cca5e
Fix test condition for `join`
jschneider-bensch Sep 7, 2023
963c546
Bug Fix: Use the right keys for blinding and enc/dec
jschneider-bensch Sep 7, 2023
0e58bf9
Merge branch 'jonas/wasm-demo' of github.com:cryspen/atlas into jonas…
jschneider-bensch Sep 7, 2023
1ffe049
Demo latest state
jschneider-bensch Sep 15, 2023
9a49e9d
Update hacspec-scrambledb/scrambledb/src/finalize.rs
jschneider-bensch Sep 26, 2023
0d4608b
Update hacspec-scrambledb/scrambledb/src/split.rs
jschneider-bensch Sep 26, 2023
366af60
Update hacspec-scrambledb/scrambledb/src/split.rs
jschneider-bensch Sep 26, 2023
a0cd6f5
Fix syntax error
jschneider-bensch Sep 26, 2023
7fb067f
Remove debug logs
jschneider-bensch Sep 26, 2023
131831e
Move feature switch
jschneider-bensch Sep 26, 2023
df13ded
Fmt
jschneider-bensch Sep 26, 2023
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
2 changes: 2 additions & 0 deletions hacspec-scrambledb/oprf/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@ p256.workspace = true
hash-to-curve.workspace = true
elgamal.workspace = true
hacspec_lib.workspace = true
sha256.workspace = true

[dev-dependencies]
serde_json = { version = "1.0.102" }
hex = { version = "0.4.3", features = ["serde"] }
serde = { version = "1.0.180", features = ["derive"] }
log = "0.4.19"
pretty_env_logger = "0.5.0"
rand = "0.8.5"
203 changes: 192 additions & 11 deletions hacspec-scrambledb/oprf/src/coprf/coprf_online.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,7 @@ use elgamal::Ciphertext;
use hacspec_lib::Randomness;

use super::coprf_setup::{BlindingPublicKey, CoPRFKey};
use crate::{
coprf::coprf_setup::{CoPRFReceiverContext, CoPRFRequesterContext},
p256_sha256, Error,
};
use crate::{coprf::coprf_setup::CoPRFReceiverContext, p256_sha256, Error};
use p256::{NatMod, P256Point};

/// CoPRF Inputs can be arbitrary byte strings.
Expand Down Expand Up @@ -100,23 +97,25 @@ pub fn prepare_blind_convert(
/// collusion-resistance.
pub fn blind_convert(
bpk: BlindingPublicKey,
key_i: CoPRFKey,
key_j: CoPRFKey,
key_from: CoPRFKey,
key_to: CoPRFKey,
blind_input: BlindInput,
randomness: &mut Randomness,
) -> Result<BlindOutput, Error> {
let delta = key_j * key_i.inv();
let delta = key_to * key_from.inv();
let ctx_rerandomized = elgamal::rerandomize(bpk, blind_input, randomness)?;
elgamal::scalar_mul_ciphertext(delta, ctx_rerandomized).map_err(|e| e.into())
}

#[cfg(test)]
mod tests {
use crate::coprf::coprf_setup::{derive_key, CoPRFEvaluatorContext};

use super::*;

// =========== Unblinded Operations ===========

/// The clear evaluation of the PRF based on the PRF by Naor, Pinkas, and Reingold:
/// The cleartext evaluation of the PRF based on the PRF by Naor, Pinkas, and Reingold:
///
/// ```text
/// PRF: K x X -> G
Expand Down Expand Up @@ -154,13 +153,195 @@ mod tests {
/// is performed by first computing a `delta` scalar from both evaluation
/// keys, which when mulitplied with the output to convert will cancel out
/// the original evaluation key and multiply by the target evaluation key.
pub fn convert(key_i: CoPRFKey, key_j: CoPRFKey, y: Output) -> Result<Output, Error> {
let delta = key_j * key_i.inv();
pub fn convert(
key_origin: CoPRFKey,
key_destination: CoPRFKey,
y: Output,
) -> Result<Output, Error> {
let delta = key_destination * key_origin.inv();
let result = p256::p256_point_mul(delta, y)?;

Ok(result)
}

fn generate_randomness() -> Randomness {
use rand::prelude::*;

let mut rng = rand::thread_rng();
let mut randomness = [0u8; 1000000];
rng.fill_bytes(&mut randomness);
let randomness = Randomness::new(randomness.to_vec());

randomness
}

#[test]
fn self_test_eval_convert() {
let mut randomness = generate_randomness();

let test_context = b"Test";
let test_input = b"TestInput";
let evaluator_context = CoPRFEvaluatorContext::new(&mut randomness).unwrap();

let key_origin1 = derive_key(&evaluator_context, b"1").unwrap();
let key_origin2 = derive_key(&evaluator_context, b"2").unwrap();
let key_destination = derive_key(&evaluator_context, b"3").unwrap();

let y_under_origin1 = evaluate(test_context, key_origin1, test_input).unwrap();
let y_under_origin2 = evaluate(test_context, key_origin2, test_input).unwrap();

let y_under_destination = evaluate(test_context, key_destination, test_input).unwrap();
let converted_y_from_1 = convert(key_origin1, key_destination, y_under_origin1).unwrap();
let converted_y_from_2 = convert(key_origin2, key_destination, y_under_origin2).unwrap();

assert_eq!(converted_y_from_1, converted_y_from_2);
assert_eq!(converted_y_from_1, y_under_destination);
}

#[test]
fn test_blind_evaluate() {
let mut randomness = generate_randomness();

let test_context = b"Test";
let test_input = b"TestInput";
let evaluator_context = CoPRFEvaluatorContext::new(&mut randomness).unwrap();
let receiver_context = CoPRFReceiverContext::new(&mut randomness);

let blind_input = blind(
receiver_context.get_bpk(),
test_input,
test_context.to_vec(),
&mut randomness,
)
.unwrap();

let evaluation_key = derive_key(&evaluator_context, b"TestKey").unwrap();
let blind_result = blind_evaluate(
evaluation_key,
receiver_context.get_bpk(),
blind_input,
&mut randomness,
)
.unwrap();

let unblinded_result = finalize(&receiver_context, blind_result).unwrap();

let expected_result = evaluate(test_context, evaluation_key, test_input).unwrap();

assert_eq!(unblinded_result, expected_result);
}

#[test]
fn test_name() {}
fn blind_convergence() {
let mut randomness = generate_randomness();

let test_context = b"Test";
let test_input = b"TestInput";
let evaluator_context = CoPRFEvaluatorContext::new(&mut randomness).unwrap();
let receiver_context = CoPRFReceiverContext::new(&mut randomness);

let key_origin1 = derive_key(&evaluator_context, b"1").unwrap();
let key_origin2 = derive_key(&evaluator_context, b"2").unwrap();
let key_destination = derive_key(&evaluator_context, b"3").unwrap();

let y_under_destination = evaluate(test_context, key_destination, test_input).unwrap();
let y1 = evaluate(test_context, key_origin1, test_input).unwrap();
let y2 = evaluate(test_context, key_origin2, test_input).unwrap();

let blind1 =
prepare_blind_convert(receiver_context.get_bpk(), y1, &mut randomness).unwrap();
let blind2 =
prepare_blind_convert(receiver_context.get_bpk(), y2, &mut randomness).unwrap();

let blind_result_1 = blind_convert(
receiver_context.get_bpk(),
key_origin1,
key_destination,
blind1,
&mut randomness,
)
.unwrap();

let blind_result_2 = blind_convert(
receiver_context.get_bpk(),
key_origin2,
key_destination,
blind2,
&mut randomness,
)
.unwrap();

let res1 = finalize(&receiver_context, blind_result_1).unwrap();
let res2 = finalize(&receiver_context, blind_result_2).unwrap();

assert_eq!(res1, res2);
assert_eq!(res1, y_under_destination);
}
#[test]
fn test_blind_conversion() {
let mut randomness = generate_randomness();

let test_context = b"Test";
let test_input = b"TestInput";
let evaluator_context = CoPRFEvaluatorContext::new(&mut randomness).unwrap();
let receiver_context = CoPRFReceiverContext::new(&mut randomness);

let blind_input = blind(
receiver_context.get_bpk(),
test_input,
test_context.to_vec(),
&mut randomness,
)
.unwrap();

let key_eval = derive_key(&evaluator_context, b"TestKey").unwrap();
let key_destination = derive_key(&evaluator_context, b"DestinationKey").unwrap();

let blind_result = blind_evaluate(
key_eval,
receiver_context.get_bpk(),
blind_input,
&mut randomness,
)
.unwrap();

let expected_result = evaluate(test_context, key_destination, test_input).unwrap();

// converting the blinded result directly
let blind_converted_result = blind_convert(
receiver_context.get_bpk(),
key_eval,
key_destination,
blind_result,
&mut randomness,
)
.unwrap();

let unblinded_converted_result =
finalize(&receiver_context, blind_converted_result).unwrap();
assert_eq!(expected_result, unblinded_converted_result);

// converting after unblinding and re-blinding
let unblinded_intermediate_result = finalize(&receiver_context, blind_result).unwrap();

let prepped_input = prepare_blind_convert(
receiver_context.get_bpk(),
unblinded_intermediate_result,
&mut randomness,
)
.unwrap();

let blind_converted_result = blind_convert(
receiver_context.get_bpk(),
key_eval,
key_destination,
prepped_input,
&mut randomness,
)
.unwrap();

let unblinded_converted_result =
finalize(&receiver_context, blind_converted_result).unwrap();
assert_eq!(expected_result, unblinded_converted_result);
}
}
12 changes: 8 additions & 4 deletions hacspec-scrambledb/oprf/src/coprf/coprf_setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ pub type BlindingPrivateKey = elgamal::DecryptionKey;
/// `Nsk` bytes of entropy is provided to the key derivation
/// algorithm, where `Nsk` is the number of bytes to represent a valid
/// private key, i.e. a P256 scalar in our case.
pub type CoPRFMasterSecret = [u8; 32];
pub type CoPRFMasterSecret = Vec<u8>;
const COPRF_MSK_BYTES: usize = 32;

/// A coPRF evaluation key is identified by a bytestring of arbitrary
/// length.
Expand Down Expand Up @@ -78,8 +79,9 @@ impl CoPRFEvaluatorContext {
/// ### E.1.2. Evaluator Setup
/// The coPRF evaluator holds the master secret as well as any PRF
/// evaluation keys derived from it.
pub fn new(msk: CoPRFMasterSecret) -> Self {
CoPRFEvaluatorContext { msk }
pub fn new(randomness: &mut Randomness) -> Result<Self, Error> {
let msk = randomness.bytes(COPRF_MSK_BYTES)?.to_vec();
Ok(CoPRFEvaluatorContext { msk })
}
}

Expand Down Expand Up @@ -120,5 +122,7 @@ pub fn derive_key(context: &CoPRFEvaluatorContext, key_id: &[u8]) -> Result<CoPR
let mut key_material = context.msk.to_vec();
key_material.extend_from_slice(key_id);

p256::random_scalar(&mut Randomness::new(key_material)).map_err(|e| e.into())
let random_bytes = sha256::hash(&key_material);

p256::random_scalar(&mut Randomness::new(random_bytes.to_vec())).map_err(|e| e.into())
}
7 changes: 7 additions & 0 deletions hacspec-scrambledb/oprf/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ pub enum Error {
CurveError,
HashToCurveError,
ElgamalError,
RandomnessError,
jschneider-bensch marked this conversation as resolved.
Show resolved Hide resolved
}

impl From<p256::Error> for Error {
Expand All @@ -27,6 +28,12 @@ impl From<elgamal::Error> for Error {
}
}

impl From<hacspec_lib::Error> for Error {
fn from(_value: hacspec_lib::Error) -> Self {
Self::RandomnessError
}
}

// 3. Protocol
pub mod protocol;

Expand Down
3 changes: 3 additions & 0 deletions hacspec-scrambledb/prp/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@ edition = "2021"

[dependencies]
hacspec_lib.workspace = true

[dev-dependencies]
rand = "0.8.5"
16 changes: 16 additions & 0 deletions hacspec-scrambledb/prp/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,3 +127,19 @@ pub fn prp(input: Block, key: &ChaChaKey) -> Block {
let state = chacha20_init(key, b"scrambledbiv", 1);
chacha20_encrypt_block(state, 2, &input)
}

#[cfg(test)]
mod tests {
use super::*;
use rand::prelude::*;

#[test]
fn test_inversion() {
let mut key = [0u8; 32];
rand::thread_rng().fill_bytes(&mut key);

let block = [1u8; 64];
assert_ne!(block, prp(block, &key));
assert_eq!(block, prp(prp(block, &key), &key));
}
}
33 changes: 33 additions & 0 deletions hacspec-scrambledb/scrambledb/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,42 @@ edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[lib]
crate-type = ["rlib", "cdylib"]

[dependencies]
oprf.workspace = true
elgamal.workspace = true
prp.workspace = true
p256.workspace = true
hacspec_lib.workspace = true
hash-to-curve.workspace = true

wasm-bindgen = { version = "0.2.87", optional = true }
rand = { version = "0.8.5", optional = true }
getrandom = { version = "0.2.10", features = ["js"], optional = true }
hex = { version = "0.4.3", optional = true }


gloo-utils = { version = "0.1", features = ["serde"] }
serde_json = "1.0.106"

[dependencies.web-sys]
franziskuskiefer marked this conversation as resolved.
Show resolved Hide resolved
version = "0.3.4"
optional = true
features = [
'Document',
'Element',
'HtmlElement',
'Node',
'Window',
'console',
'HtmlTableElement',
'HtmlTableRowElement',
]

[features]
wasm = ["wasm-bindgen", "getrandom", "web-sys", "rand", "hex"]

[dev-dependencies]
scrambledb = { path = ".", features = ["rand"] }
1 change: 1 addition & 0 deletions hacspec-scrambledb/scrambledb/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ impl From<oprf::Error> for Error {
oprf::Error::CurveError => Self::CorruptedData,
oprf::Error::HashToCurveError => Self::CorruptedData,
oprf::Error::ElgamalError => Self::RandomnessError,
oprf::Error::RandomnessError => Self::RandomnessError,
}
}
}
Expand Down
Loading