diff --git a/.gitignore b/.gitignore index 0887ba5c8..4931d780f 100644 --- a/.gitignore +++ b/.gitignore @@ -13,7 +13,4 @@ Cargo.lock # MSVC Windows builds of rustc generate these, which store debugging information *.pdb -# macOS puts these everywhere -.DS_Store - -tlsn-mpc-circuits/compiled/* +tlsn-mpc-circuits/compiled/* \ No newline at end of file diff --git a/mpc-aio/examples/ot_ws.rs b/mpc-aio/examples/ot_ws.rs index f4bf6fdac..c3b2cf14a 100644 --- a/mpc-aio/examples/ot_ws.rs +++ b/mpc-aio/examples/ot_ws.rs @@ -4,7 +4,7 @@ use futures::{AsyncRead, AsyncWrite}; use mpc_aio::ot::{ ExtOTReceive, ExtOTSend, ExtReceiver, ExtSender, OTReceive, OTSend, Receiver, Sender, }; -use mpc_core::ot::{DhOtSender, ExtReceiverCore, ExtSenderCore, ReceiverCore}; +use mpc_core::ot::{ExtReceiverCore, ExtSenderCore, ReceiverCore, SenderCore}; use mpc_core::Block; use rand::{thread_rng, Rng}; use tokio; @@ -83,7 +83,7 @@ async fn send( let mut sender = ExtSender::new(ExtSenderCore::new(values.len()), stream); let _ = sender.send(&values).await; } else { - let mut sender = Sender::new(DhOtSender::new(values.len()), stream); + let mut sender = Sender::new(SenderCore::new(values.len()), stream); let _ = sender.send(&values).await; } diff --git a/mpc-aio/src/ot/base/receiver.rs b/mpc-aio/src/ot/base/receiver.rs index 2e3c1e18c..68805cbb0 100644 --- a/mpc-aio/src/ot/base/receiver.rs +++ b/mpc-aio/src/ot/base/receiver.rs @@ -56,10 +56,10 @@ where let setup = self.ot.setup(choice, setup)?; trace!("Sending ReceiverSetup: {:?}", &setup); - self.stream.send(Message::ReceiverChoices(setup)).await?; + self.stream.send(Message::ReceiverSetup(setup)).await?; let payload = match self.stream.next().await { - Some(Ok(Message::SenderOutput(m))) => m, + Some(Ok(Message::SenderPayload(m))) => m, Some(Ok(m)) => return Err(OTError::Unexpected(m)), Some(Err(e)) => return Err(e)?, None => return Err(IOError::new(ErrorKind::UnexpectedEof, ""))?, diff --git a/mpc-aio/src/ot/base/sender.rs b/mpc-aio/src/ot/base/sender.rs index 620c1a6d7..843bcd3ab 100644 --- a/mpc-aio/src/ot/base/sender.rs +++ b/mpc-aio/src/ot/base/sender.rs @@ -51,7 +51,7 @@ where self.stream.send(Message::SenderSetup(setup)).await?; let setup = match self.stream.next().await { - Some(Ok(Message::ReceiverChoices(m))) => m, + Some(Ok(Message::ReceiverSetup(m))) => m, Some(Ok(m)) => return Err(OTError::Unexpected(m)), Some(Err(e)) => return Err(e)?, None => return Err(IOError::new(ErrorKind::UnexpectedEof, ""))?, @@ -61,7 +61,7 @@ where let payload = self.ot.send(payload, setup)?; trace!("Sending SenderPayload: {:?}", &payload); - self.stream.send(Message::SenderOutput(payload)).await?; + self.stream.send(Message::SenderPayload(payload)).await?; Ok(()) } diff --git a/mpc-core/Cargo.toml b/mpc-core/Cargo.toml index a6f448076..75ba77cc2 100644 --- a/mpc-core/Cargo.toml +++ b/mpc-core/Cargo.toml @@ -33,7 +33,6 @@ anyhow = "1.0.55" elliptic-curve = { version = "0.11.12", optional = true } p256 = { version = "0.10.1", optional = true } derive_builder = "0.11.2" -merlin = "3.0.0" [dependencies.paillier] package = "kzen-paillier" diff --git a/mpc-core/benches/ot.rs b/mpc-core/benches/ot.rs index d434e7865..2a660c4e6 100644 --- a/mpc-core/benches/ot.rs +++ b/mpc-core/benches/ot.rs @@ -1,8 +1,8 @@ use criterion::{black_box, criterion_group, criterion_main, Criterion}; use mpc_core::block::{Block, BLOCK_ONES}; use mpc_core::ot::{ - DhOtSender, ExtReceiveCore, ExtReceiverCore, ExtSendCore, ExtSenderCore, ReceiveCore, - ReceiverCore, SendCore, + ExtReceiveCore, ExtReceiverCore, ExtSendCore, ExtSenderCore, ReceiveCore, ReceiverCore, + SendCore, SenderCore, }; use mpc_core::utils::u8vec_to_boolvec; use rand::RngCore; @@ -15,7 +15,7 @@ fn criterion_benchmark(c: &mut Criterion) { let choice = [false; 1024]; bench.iter(|| { - let mut sender = DhOtSender::new(1024); + let mut sender = SenderCore::new(1024); let sender_setup = sender.setup(); let mut receiver = ReceiverCore::new(1024); diff --git a/mpc-core/examples/ot.rs b/mpc-core/examples/ot.rs index bd70e391b..c1276b599 100644 --- a/mpc-core/examples/ot.rs +++ b/mpc-core/examples/ot.rs @@ -3,12 +3,9 @@ // For simplicity, this example shows how to use OT components in memory. use mpc_core::block::Block; -use mpc_core::ot::dh_ot::{DhOtReceiver, DhOtSender}; -use rand::thread_rng; +use mpc_core::ot::{ReceiveCore, ReceiverCore, SendCore, SenderCore}; pub fn main() { - let mut rng = thread_rng(); - // Receiver choice bits let choice = vec![false, true, false, false, true, true, false, true]; @@ -29,12 +26,12 @@ pub fn main() { println!("Sender inputs: {:?}", &inputs); // First the sender creates a setup message and passes it to sender - let mut sender = DhOtSender::default(); - let setup = sender.setup(&mut rng); + let mut sender = SenderCore::new(inputs.len()); + let setup = sender.setup(); // Receiver takes sender's setup and creates its own setup message - let mut receiver = DhOtReceiver::default(); - let setup = receiver.setup(&mut rng, &choice, setup).unwrap(); + let mut receiver = ReceiverCore::new(choice.len()); + let setup = receiver.setup(&choice, setup).unwrap(); // Finally, sender encrypts their inputs and sends them to receiver let payload = sender.send(&inputs, setup).unwrap(); diff --git a/mpc-core/examples/ote.rs b/mpc-core/examples/ote.rs index e0ae10872..d8d943e7f 100644 --- a/mpc-core/examples/ote.rs +++ b/mpc-core/examples/ote.rs @@ -3,10 +3,7 @@ // For simplicity, this example shows how to use OT components in memory. use mpc_core::block::Block; -use mpc_core::ot::extension::{ - kos15::{Kos15Receiver, Kos15Sender}, - ExtReceiveCore, ExtSendCore, -}; +use mpc_core::ot::{ExtReceiveCore, ExtReceiverCore, ExtSendCore, ExtSenderCore}; pub fn main() { // Receiver choice bits @@ -29,11 +26,11 @@ pub fn main() { println!("Sender inputs: {:?}", &inputs); // First the receiver creates a setup message and passes it to sender - let mut receiver = Kos15Receiver::new(inputs.len()); + let mut receiver = ExtReceiverCore::new(inputs.len()); let base_sender_setup = receiver.base_setup().unwrap(); // Sender takes receiver's setup and creates its own setup message - let mut sender = Kos15Sender::new(inputs.len()); + let mut sender = ExtSenderCore::new(inputs.len()); let base_receiver_setup = sender.base_setup(base_sender_setup).unwrap(); // Now the receiver generates some seeds from sender's setup and uses OT to transfer them diff --git a/mpc-core/examples/ote_random.rs b/mpc-core/examples/ote_random.rs index 5fb6beaa8..5a991b5c9 100644 --- a/mpc-core/examples/ote_random.rs +++ b/mpc-core/examples/ote_random.rs @@ -6,10 +6,7 @@ // For simplicity, this example shows how to use OT components in memory. use mpc_core::block::Block; -use mpc_core::ot::extension::{ - kos15::{Kos15Receiver, Kos15Sender}, - ExtRandomReceiveCore, ExtRandomSendCore, ExtReceiveCore, ExtSendCore, -}; +use mpc_core::ot::{ExtRandomReceiveCore, ExtRandomSendCore, ExtReceiverCore, ExtSenderCore}; pub fn main() { // Sender messages the receiver chooses from @@ -27,11 +24,11 @@ pub fn main() { println!("Sender inputs: {:?}", &inputs); // First the receiver creates a setup message and passes it to sender - let mut receiver = Kos15Receiver::new(inputs.len()); + let mut receiver = ExtReceiverCore::new(inputs.len()); let base_sender_setup = receiver.base_setup().unwrap(); // Sender takes receiver's setup and creates its own setup message - let mut sender = Kos15Sender::new(inputs.len()); + let mut sender = ExtSenderCore::new(inputs.len()); let base_receiver_setup = sender.base_setup(base_sender_setup).unwrap(); // Now the receiver generates some seeds from sender's setup and uses OT to transfer them @@ -39,7 +36,7 @@ pub fn main() { sender.base_receive(base_payload).unwrap(); // Receiver generates OT extension setup and passes it to sender - let receiver_setup = receiver.rand_extension_setup().unwrap(); + let receiver_setup = receiver.extension_setup().unwrap(); // Sender takes receiver's setup and runs its own extension setup sender.extension_setup(receiver_setup).unwrap(); @@ -50,13 +47,13 @@ pub fn main() { // their choices depending on what they received in earlier batches let initial_choices = vec![false, true]; let derandomize = receiver.derandomize(&initial_choices).unwrap(); - let initial_payload = sender.rand_send(&inputs[..2], derandomize).unwrap(); - received.append(&mut receiver.rand_receive(initial_payload).unwrap()); + let initial_payload = sender.send(&inputs[..2], derandomize).unwrap(); + received.append(&mut receiver.receive(initial_payload).unwrap()); for chunk in inputs[2..].chunks(2) { let received_sum: u128 = received.iter().map(|b| b.inner()).sum(); let choice = received_sum % 2 == 0; let derandomize = receiver.derandomize(&[choice, !choice]).unwrap(); - let payload = sender.rand_send(&chunk, derandomize).unwrap(); + let payload = sender.send(&chunk, derandomize).unwrap(); received.append(&mut receiver.receive(payload).unwrap()); } diff --git a/mpc-core/proto/ot.proto b/mpc-core/proto/ot.proto index 8a9a68d14..0ea015c84 100644 --- a/mpc-core/proto/ot.proto +++ b/mpc-core/proto/ot.proto @@ -13,13 +13,13 @@ message SenderSetup { // Message sent by OT Sender containing encrypted values message SenderPayload { // Encrypted values - repeated core.LabelPair ciphertexts = 1; + repeated core.LabelPair encrypted_values = 1; } // Setup message sent by Base OT Receiver message ReceiverSetup { - // The blinded choice bit sent by the receiver - repeated core.RistrettoPoint blinded_choices = 1; + // Keys used to encrypt values by Sender + repeated core.RistrettoPoint keys = 1; } // Setup message sent by OT Receiver @@ -38,7 +38,7 @@ message ExtDerandomize { message ExtSenderPayload { // Encrypted values - repeated core.LabelPair ciphertexts = 1; + repeated core.LabelPair encrypted_values = 1; } // Setup message sent by Base OT Sender in preparation for the OT extension @@ -75,4 +75,4 @@ message Message { BaseReceiverSetup base_receiver_setup = 8; BaseSenderPayload base_sender_payload = 9; } -} +} \ No newline at end of file diff --git a/mpc-core/src/block.rs b/mpc-core/src/block.rs index a6c57a9c5..91545613a 100644 --- a/mpc-core/src/block.rs +++ b/mpc-core/src/block.rs @@ -1,7 +1,9 @@ use cipher::{consts::U16, generic_array::GenericArray, BlockCipher, BlockEncrypt}; use core::ops::{BitAnd, BitXor}; +use curve25519_dalek::ristretto::RistrettoPoint; use rand::{CryptoRng, Rng}; use serde::{Deserialize, Serialize}; +use sha2::{Digest, Sha256}; use std::convert::{From, TryInto}; #[repr(transparent)] @@ -42,7 +44,7 @@ impl Block { // hash, i.e. instead of Hash(x, i) we must do C(C(x) xor i) xor C(x). pub fn hash_tweak + BlockEncrypt>( &self, - c: &C, + c: &mut C, tweak: usize, ) -> Self { let gid: [u8; 16] = (tweak as u128).to_be_bytes(); @@ -66,6 +68,17 @@ impl Block { Self::new(h) } + #[inline] + pub fn hash_point(point: &RistrettoPoint, tweak: u32) -> Self { + let mut hasher = Sha256::new(); + hasher.update(point.compress().as_bytes()); + hasher.update(tweak.to_be_bytes()); + let h: [u8; 16] = hasher.finalize()[..16] + .try_into() + .expect("Unable to convert hash to block"); + Self::from(h) + } + #[inline] pub fn zero() -> Self { Self(0) diff --git a/mpc-core/src/ot/base/dh_ot/mod.rs b/mpc-core/src/ot/base/dh_ot/mod.rs deleted file mode 100644 index bee767329..000000000 --- a/mpc-core/src/ot/base/dh_ot/mod.rs +++ /dev/null @@ -1,96 +0,0 @@ -//! This module implements the CO15 Oblivious Transfer protocol from -//! [ref1] https://eprint.iacr.org/2015/267.pdf (see Figure 1) - -pub mod receiver; -pub mod sender; - -pub use receiver::*; -pub use sender::*; - -use crate::{ot::base::ReceiverCoreError, Block}; -use curve25519_dalek::ristretto::RistrettoPoint; -use sha2::{Digest, Sha256}; - -pub(crate) const DOMAIN_SEP: &[u8] = b"CO15 DH-OT"; - -#[derive(Clone, Copy, Debug, PartialEq)] -pub struct SenderSetup { - pub public_key: RistrettoPoint, -} - -/// The final output of the sender to the receiver -#[derive(Clone, Debug, PartialEq)] -pub struct SenderPayload { - /// The pairs of ciphertexts output by the sender. At most one of these can be decrypted by the - /// receiver. - pub ciphertexts: Vec<[DhOtCiphertext; 2]>, -} - -#[derive(Clone, Debug, PartialEq)] -pub struct ReceiverChoices { - pub blinded_choices: Vec, -} - -/// Hashes a ristretto point to a symmetric key -pub(crate) fn hash_point(point: &RistrettoPoint, tweak: &[u8]) -> Block { - // Compute H(tweak || point) - let mut h = Sha256::new(); - h.update(&tweak); - h.update(point.compress().as_bytes()); - let digest = h.finalize(); - - // Copy the first 16 bytes into a Block - let mut block = [0u8; 16]; - block.copy_from_slice(&digest[..16]); - block.into() -} - -// We just do block encryption the ordinary way -pub(crate) type DhOtCiphertext = Block; - -// Encrypts an input: E_k(m) = k ⊕ m -fn encrypt_input(key: Block, input: Block) -> DhOtCiphertext { - key ^ input -} - -// Decrypts an input: D_k(c) = k ⊕ c -fn decrypt_input(key: Block, ct: DhOtCiphertext) -> Result { - Ok(key ^ ct) -} - -// Unclear if we need to do quasi-authenticated encryption as below. Relevant Github issue: -// https://github.com/emp-toolkit/emp-ot/issues/74#issuecomment-1151550188 -/* -// The encryption scheme in CO15 produces a ciphertext and a tag, both 16 bytes -pub(crate) type DhOtCiphertext = [Block; 2]; - -// Encrypts an input according to CO15: E_k(m) = (k[:16] ⊕ m, k[16:]) -fn encrypt_input(key: &[u8; 32], input: Block) -> DhOtCiphertext { - // Break the key into two blocks, α and β - let mut alpha_buf = [0u8; 16]; - let mut beta_buf = [0u8; 16]; - alpha_buf.copy_from_slice(&key[..16]); - beta_buf.copy_from_slice(&key[16..]); - let alpha = Block::from(alpha_buf); - let beta = Block::from(beta_buf); - - [input ^ alpha, beta] -} - -// Decrypts an input according to CO15: D_k(c) = k[:16] ⊕ c[:16] if k[16:] == c[:16], else ⊥ -fn decrypt_input(key: &[u8; 32], ct: &DhOtCiphertext) -> Result { - // Break the key into two blocks, α and β - let mut alpha_buf = [0u8; 16]; - let mut beta_buf = [0u8; 16]; - alpha_buf.copy_from_slice(&key[..16]); - beta_buf.copy_from_slice(&key[16..]); - let alpha = Block::from(alpha_buf); - let beta = Block::from(beta_buf); - - if !bool::from(beta.ct_eq(&ct[1])) { - Err(ReceiverCoreError::MalformedCiphertext) - } else { - Ok(alpha ^ ct[0]) - } -} -*/ diff --git a/mpc-core/src/ot/base/dh_ot/receiver.rs b/mpc-core/src/ot/base/dh_ot/receiver.rs deleted file mode 100644 index 42287537c..000000000 --- a/mpc-core/src/ot/base/dh_ot/receiver.rs +++ /dev/null @@ -1,127 +0,0 @@ -use crate::{ - ot::base::{ - dh_ot::{ - decrypt_input, hash_point, ReceiverChoices, ReceiverCoreError, SenderPayload, - SenderSetup, DOMAIN_SEP, - }, - ReceiverState, - }, - Block, -}; - -use curve25519_dalek::{ - constants::RISTRETTO_BASEPOINT_TABLE, - ristretto::{RistrettoBasepointTable, RistrettoPoint}, - scalar::Scalar, -}; -use merlin::Transcript; -use rand::{CryptoRng, RngCore}; - -pub struct DhOtReceiver { - /// The current state of the protocol - state: ReceiverState, - /// The transcript of the protocol so far - transcript: Transcript, - /// The keys used to decrypt the sender's responses - decryption_keys: Option>, - /// The bits that this receiver picked - choices: Option>, -} - -impl Default for DhOtReceiver { - fn default() -> Self { - DhOtReceiver { - state: ReceiverState::Initialized, - transcript: Transcript::new(DOMAIN_SEP), - decryption_keys: None, - choices: None, - } - } -} - -impl DhOtReceiver { - /// Returns current state of this OT protocol - pub fn state(&self) -> ReceiverState { - self.state - } - - /// Constructs all the blinded choices, given the sender's pubkey - pub fn setup( - &mut self, - rng: &mut R, - choices: &[bool], - sender_setup: SenderSetup, - ) -> Result { - // Log the sending of the pubkey - self.transcript - .append_message(b"pubkey", sender_setup.public_key.compress().as_bytes()); - - // point_table is A in [ref1] - let public_key = sender_setup.public_key; - let point_table = RistrettoBasepointTable::create(&public_key); - - // Construct the return value and compute the decryption keys in advance for the sender's - // response ciphertexts - let (blinded_choices, decryption_keys): (Vec, Vec) = choices - .iter() - .map(|c| { - let b = Scalar::random(rng); - // blinded_choice is B in [ref1] - let blinded_choice = if *c { - public_key + &b * &RISTRETTO_BASEPOINT_TABLE - } else { - &b * &RISTRETTO_BASEPOINT_TABLE - }; - - // Witness the blinded choice in the transcript - self.transcript - .append_message(b"B", blinded_choice.compress().as_bytes()); - - // Construct a tweak to domain-separate the ristretto point hashes - let mut tweak = [0u8; 16]; - self.transcript.challenge_bytes(b"tweak", &mut tweak); - - // dec_key is k_r in [ref1] == hash(A^b) - let dec_key = hash_point(&(&b * &point_table), &tweak); - // we send the choice values to the Sender and keep the h values - (blinded_choice, dec_key) - }) - .unzip(); - - // Update the state - self.decryption_keys = Some(decryption_keys); - self.choices = Some(Vec::from(choices)); - self.state = ReceiverState::Initialized; - - // Return the blinded choices - Ok(ReceiverChoices { blinded_choices }) - } - - /// Decrypts the OT sender's ciphertexts - pub fn receive(&mut self, payload: SenderPayload) -> Result, ReceiverCoreError> { - if self.state != ReceiverState::Initialized { - return Err(ReceiverCoreError::NotSetup); - } - - let keys = self.decryption_keys.as_ref().unwrap(); - let selected_inputs: Result, ReceiverCoreError> = self - .choices - .as_ref() - .unwrap() - .iter() - .zip(keys) - .zip(payload.ciphertexts.iter()) - .map(|((&c, &key), [ct0, ct1])| { - // Select an encrypted value based on the choices bit - let ct = if c { ct1 } else { ct0 }; - // Decrypt it with the corresponding key - decrypt_input(key, *ct) - }) - .collect(); - - // Update the state regardless of whether this OT succeeded or not - self.state = ReceiverState::Complete; - - selected_inputs - } -} diff --git a/mpc-core/src/ot/base/dh_ot/sender.rs b/mpc-core/src/ot/base/dh_ot/sender.rs deleted file mode 100644 index fca2a5e1d..000000000 --- a/mpc-core/src/ot/base/dh_ot/sender.rs +++ /dev/null @@ -1,106 +0,0 @@ -use crate::{ - ot::base::{ - dh_ot::{ - encrypt_input, hash_point, DhOtCiphertext, ReceiverChoices, SenderPayload, SenderSetup, - DOMAIN_SEP, - }, - SenderCoreError, SenderState, - }, - Block, -}; - -use curve25519_dalek::{ - constants::RISTRETTO_BASEPOINT_TABLE, ristretto::RistrettoPoint, scalar::Scalar, -}; -use merlin::Transcript; -use rand::{CryptoRng, RngCore}; - -pub struct DhOtSender { - /// The current state of the protocol - state: SenderState, - /// The transcript of the protocol so far - transcript: Transcript, - /// The private_key is random `a` in [ref1] - private_key: Option, - // The public_key is `A == g^a` in [ref1] - public_key: Option, -} - -impl Default for DhOtSender { - fn default() -> Self { - DhOtSender { - private_key: None, - public_key: None, - state: SenderState::Initialized, - transcript: Transcript::new(DOMAIN_SEP), - } - } -} - -impl DhOtSender { - /// Generates the keypair to be used by the sender for this OT - pub fn setup(&mut self, rng: &mut R) -> SenderSetup { - // Randomly sample a - let private_key = Scalar::random(rng); - // Compute the pubkey A = aG where G is a generator - let public_key = &private_key * &RISTRETTO_BASEPOINT_TABLE; - - // Update the state - self.private_key = Some(private_key); - self.public_key = Some(public_key); - self.state = SenderState::ReadyToSend; - - // Log the sending of the pubkey - self.transcript - .append_message(b"pubkey", public_key.compress().as_bytes()); - - // Return the pubkey - SenderSetup { public_key } - } - - /// For each i, sends `inputs[i][0]` or `inputs[i][1]` base on the corresponding receiver's - /// choices. Panics if `inputs.len() != receivers_choices.blinded_choices.len()`. - pub fn send( - &mut self, - inputs: &[[Block; 2]], - receivers_choices: ReceiverChoices, - ) -> Result { - // This sender needs to be ready to send, and the number of inputs needs to be equal to the - // number of choices - if self.state != SenderState::ReadyToSend { - return Err(SenderCoreError::NotSetup); - } - - let private_key = self.private_key.unwrap(); - - // ys is A^a in [ref1] - let ys = private_key * self.public_key.unwrap(); - - // Compute and collect all the OT ciphertexts - let ciphertexts: Vec<[DhOtCiphertext; 2]> = inputs - .iter() - .zip(receivers_choices.blinded_choices) - .map(|(input, receivers_choice)| { - // Witness the receiver's choice in the transcript - self.transcript - .append_message(b"B", &*receivers_choice.compress().as_bytes()); - - // Construct a tweak to domain-separate the ristretto point hashes - let mut tweak = [0u8; 16]; - self.transcript.challenge_bytes(b"tweak", &mut tweak); - - // yr is B^a in [ref1] - let yr = private_key * receivers_choice; - let k0 = hash_point(&yr, &tweak).into(); - // yr - ys == (B/A)^a in [ref1] - let k1 = hash_point(&(yr - ys), &tweak).into(); - - [encrypt_input(k0, input[0]), encrypt_input(k1, input[1])] - }) - .collect(); - - // Update the state and return the ciphertexts - self.state = SenderState::Complete; - Ok(SenderPayload { ciphertexts }) - } -} diff --git a/mpc-core/src/ot/base/errors.rs b/mpc-core/src/ot/base/errors.rs index 296ff5f1e..0f806efd4 100644 --- a/mpc-core/src/ot/base/errors.rs +++ b/mpc-core/src/ot/base/errors.rs @@ -16,6 +16,4 @@ pub enum ReceiverCoreError { NotSetup, #[error("Provided incorrect number of choice bits")] InvalidChoiceLength, - #[error("Sender's ciphertext is malformed")] - MalformedCiphertext, } diff --git a/mpc-core/src/ot/base/mod.rs b/mpc-core/src/ot/base/mod.rs index c1b6a7734..1d0ca6fbf 100644 --- a/mpc-core/src/ot/base/mod.rs +++ b/mpc-core/src/ot/base/mod.rs @@ -1,24 +1,37 @@ -//! This crate implements types and imple +//! this crate implements the CO15 Oblivious Transfer protocol from +//! [ref1] https://eprint.iacr.org/2015/267.pdf (see Figure 1) -pub mod dh_ot; pub mod errors; +pub mod receiver; +pub mod sender; pub use errors::*; -/// The state of an OT sender -#[derive(Clone, Copy, Debug, PartialEq)] -pub enum SenderState { - Initialized, - ReadyToSend, - Complete, +pub use receiver::{ReceiverCore, ReceiverSetup}; +pub use sender::{SenderCore, SenderPayload, SenderSetup}; + +pub trait SendCore { + fn state(&self) -> sender::State; + + fn setup(&mut self) -> SenderSetup; + + fn send( + &mut self, + inputs: &[[crate::Block; 2]], + receiver_setup: ReceiverSetup, + ) -> Result; } -/// The state of an OT receiver -#[derive(Clone, Copy, Debug, PartialEq)] -pub enum ReceiverState { - Initialized, - Setup, - Complete, +pub trait ReceiveCore { + fn state(&self) -> receiver::State; + + fn setup( + &mut self, + choice: &[bool], + sender_setup: SenderSetup, + ) -> Result; + + fn receive(&mut self, payload: SenderPayload) -> Result, ReceiverCoreError>; } #[cfg(test)] @@ -29,15 +42,12 @@ pub mod tests { use rand::{thread_rng, RngCore}; use rstest::*; - // We test the CO15 scheme only - use dh_ot::*; - pub mod fixtures { use super::*; pub struct Data { pub sender_setup: SenderSetup, - pub receiver_setup: ReceiverChoices, + pub receiver_setup: ReceiverSetup, pub sender_payload: SenderPayload, pub receiver_values: Vec, } @@ -62,14 +72,11 @@ pub mod tests { #[fixture] #[once] pub fn ot_core_data(choice: &Vec, values: &Vec<[Block; 2]>) -> Data { - let mut rng = thread_rng(); - - let mut sender = DhOtSender::default(); - let sender_setup = sender.setup(&mut rng); - - let mut receiver = DhOtReceiver::default(); - let receiver_setup = receiver.setup(&mut rng, choice, sender_setup).unwrap(); + let mut sender = SenderCore::new(values.len()); + let sender_setup = sender.setup(); + let mut receiver = ReceiverCore::new(choice.len()); + let receiver_setup = receiver.setup(choice, sender_setup).unwrap(); let sender_payload = sender.send(values, receiver_setup.clone()).unwrap(); let receiver_values = receiver.receive(sender_payload.clone()).unwrap(); @@ -97,13 +104,13 @@ pub mod tests { .map(|(input, choice)| input[*choice as usize]) .collect(); - let mut sender = DhOtSender::default(); - let sender_setup = sender.setup(&mut rng); + let mut sender = SenderCore::new(s_inputs.len()); + let sender_setup = sender.setup(); - let mut receiver = DhOtReceiver::default(); - let receiver_choices = receiver.setup(&mut rng, &choice, sender_setup).unwrap(); + let mut receiver = ReceiverCore::new(choice.len()); + let receiver_setup = receiver.setup(&choice, sender_setup).unwrap(); - let send = sender.send(&s_inputs, receiver_choices).unwrap(); + let send = sender.send(&s_inputs, receiver_setup).unwrap(); let receive = receiver.receive(send).unwrap(); assert_eq!(expected, receive); } diff --git a/mpc-core/src/ot/base/receiver.rs b/mpc-core/src/ot/base/receiver.rs new file mode 100644 index 000000000..8075a6ecc --- /dev/null +++ b/mpc-core/src/ot/base/receiver.rs @@ -0,0 +1,120 @@ +use curve25519_dalek::{ + constants::RISTRETTO_BASEPOINT_TABLE, + ristretto::{RistrettoBasepointTable, RistrettoPoint}, + scalar::Scalar, +}; +use rand::{CryptoRng, Rng, SeedableRng}; +use rand_chacha::ChaCha12Rng; + +use super::{ReceiveCore, ReceiverCoreError, SenderPayload, SenderSetup}; +use crate::Block; + +#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)] +pub enum State { + Initialized, + Setup, + Complete, +} + +pub struct ReceiverCore { + rng: R, + count: usize, + hashes: Option>, + choice: Option>, + state: State, +} + +#[derive(Clone, Debug, PartialEq)] +pub struct ReceiverSetup { + pub keys: Vec, +} + +impl ReceiverCore { + pub fn new(count: usize) -> Self { + Self { + rng: ChaCha12Rng::from_entropy(), + count, + hashes: None, + choice: None, + state: State::Initialized, + } + } +} + +impl ReceiverCore { + pub fn new_from_rng(rng: R, count: usize) -> Self { + Self { + rng, + count, + hashes: None, + choice: None, + state: State::Initialized, + } + } +} + +impl ReceiveCore for ReceiverCore { + fn state(&self) -> State { + self.state + } + + fn setup( + &mut self, + choice: &[bool], + sender_setup: SenderSetup, + ) -> Result { + if choice.len() != self.count { + return Err(ReceiverCoreError::InvalidChoiceLength); + } + // point_table is A in [ref1] + let point_table = RistrettoBasepointTable::create(&sender_setup.public_key); + let zero = &Scalar::zero() * &point_table; + let one = &Scalar::one() * &point_table; + let (keys, hashes): (Vec, Vec) = choice + .iter() + .enumerate() + .map(|(i, b)| { + // x is b in [ref1] + let x = Scalar::random(&mut self.rng); + let c = if *b { one } else { zero }; + // k is B in [ref1] + let k = c + &x * &RISTRETTO_BASEPOINT_TABLE; + // h is k_r in [ref1] == hash(A^b) + let h = Block::hash_point(&(&x * &point_table), i as u32); + // we send the k values to the Sender and keep the h values + (k, h) + }) + .unzip(); + self.hashes = Some(hashes); + self.choice = Some(Vec::from(choice)); + self.state = State::Setup; + + Ok(ReceiverSetup { keys }) + } + + fn receive(&mut self, payload: SenderPayload) -> Result, ReceiverCoreError> { + if self.state < State::Setup { + return Err(ReceiverCoreError::NotSetup); + } + + let hashes = self.hashes.as_ref().unwrap(); + let values: Vec = self + .choice + .as_ref() + .unwrap() + .iter() + .zip(hashes) + .zip(payload.encrypted_values.iter()) + .map(|((c, h), v)| { + // select an encrypted value based on the choice bit + let b = if *c { v[1] } else { v[0] }; + // decrypt it with the corresponding key (the key is a hash) + *h ^ b + }) + .collect(); + + self.state = State::Complete; + + Ok(values) + } +} diff --git a/mpc-core/src/ot/base/sender.rs b/mpc-core/src/ot/base/sender.rs new file mode 100644 index 000000000..76315f42d --- /dev/null +++ b/mpc-core/src/ot/base/sender.rs @@ -0,0 +1,106 @@ +use crate::Block; +use curve25519_dalek::{ + constants::RISTRETTO_BASEPOINT_TABLE, ristretto::RistrettoPoint, scalar::Scalar, +}; +use rand::{CryptoRng, Rng}; +use rand_chacha::ChaCha12Rng; +use rand_core::SeedableRng; + +use super::{ReceiverSetup, SendCore, SenderCoreError}; + +#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)] +pub enum State { + Initialized, + Setup, + Complete, +} + +pub struct SenderCore { + rng: R, + count: usize, + // private_key is random "a" in [ref1] + private_key: Option, + // public_key is A == g^a in [ref1] + public_key: Option, + state: State, +} + +#[derive(Clone, Copy, Debug, PartialEq)] +pub struct SenderSetup { + pub public_key: RistrettoPoint, +} + +#[derive(Clone, Debug, PartialEq)] +pub struct SenderPayload { + pub encrypted_values: Vec<[Block; 2]>, +} + +impl SenderCore { + pub fn new(count: usize) -> Self { + Self { + rng: ChaCha12Rng::from_entropy(), + count, + private_key: None, + public_key: None, + state: State::Initialized, + } + } +} + +impl SenderCore { + pub fn new_from_rng(rng: R, count: usize) -> Self { + Self { + rng, + count, + private_key: None, + public_key: None, + state: State::Initialized, + } + } +} + +impl SendCore for SenderCore { + fn state(&self) -> State { + self.state + } + + fn setup(&mut self) -> SenderSetup { + let private_key = Scalar::random(&mut self.rng); + self.public_key = Some(&private_key * &RISTRETTO_BASEPOINT_TABLE); + self.private_key = Some(private_key); + self.state = State::Setup; + SenderSetup { + public_key: self.public_key.unwrap(), + } + } + + fn send( + &mut self, + inputs: &[[Block; 2]], + receiver_setup: ReceiverSetup, + ) -> Result { + if self.state < State::Setup { + return Err(SenderCoreError::NotSetup); + } else if inputs.len() != self.count { + return Err(SenderCoreError::InvalidInputLength); + } + let private_key = self.private_key.unwrap(); + let ninputs = inputs.len(); + // ys is A^a in [ref1] + let ys = private_key * self.public_key.unwrap(); + let mut encrypted_values: Vec<[Block; 2]> = Vec::with_capacity(ninputs); + + for (i, (input, receiver_key)) in inputs.iter().zip(receiver_setup.keys).enumerate() { + // yr is B^a in [ref1] + let yr = private_key * receiver_key; + let k0 = Block::hash_point(&yr, i as u32); + // yr - ys == (B/A)^a in [ref1] + let k1 = Block::hash_point(&(yr - ys), i as u32); + encrypted_values.push([k0 ^ input[0], k1 ^ input[1]]); + } + + self.state = State::Complete; + + Ok(SenderPayload { encrypted_values }) + } +} diff --git a/mpc-core/src/ot/extension/kos15/mod.rs b/mpc-core/src/ot/extension/kos15/mod.rs deleted file mode 100644 index c48796278..000000000 --- a/mpc-core/src/ot/extension/kos15/mod.rs +++ /dev/null @@ -1,27 +0,0 @@ -use crate::Block; - -mod receiver; -mod sender; - -pub use receiver::*; -pub use sender::*; - -// We instantiate KOS15 w.r.t the DH-OT defined in CO15 -pub(crate) use crate::ot::base::dh_ot::{ - DhOtReceiver as BaseReceiver, DhOtSender as BaseSender, ReceiverChoices as ReceiverSetup, - SenderPayload, SenderSetup, -}; - -/// OT extension Sender plays the role of base OT Receiver and sends the -/// second message containing base OT setup and cointoss share -#[derive(Debug, Clone, PartialEq)] -pub struct BaseReceiverSetup { - pub setup: ReceiverSetup, - // Cointoss protocol's 2nd message: Receiver reveals share - pub cointoss_share: [u8; 32], -} - -#[derive(Clone, Debug, PartialEq)] -pub struct ExtSenderPayload { - pub ciphertexts: Vec<[Block; 2]>, -} diff --git a/mpc-core/src/ot/extension/mod.rs b/mpc-core/src/ot/extension/mod.rs index ffc578a9c..c2d6098cc 100644 --- a/mpc-core/src/ot/extension/mod.rs +++ b/mpc-core/src/ot/extension/mod.rs @@ -1,11 +1,17 @@ //! This crate implements the KOS15 Oblivious Transfer extension protocol. pub mod errors; -pub mod kos15; +pub mod receiver; +pub mod sender; +pub use crate::ot::base::{ReceiverSetup, SenderPayload, SenderSetup}; pub use crate::Block; pub use clmul::Clmul; pub use errors::*; +pub use receiver::{ + BaseSenderPayload, BaseSenderSetup, ExtDerandomize, ExtReceiverCore, ExtReceiverSetup, +}; +pub use sender::{BaseReceiverSetup, ExtSenderCore, ExtSenderPayload}; pub const BASE_COUNT: usize = 128; @@ -14,100 +20,119 @@ pub const BASE_COUNT: usize = 128; const K: usize = 40; pub trait ExtSendCore { - type State; - type BaseSenderSetup; - type BaseSenderPayload; - type BaseReceiverSetup; - type ExtSenderPayload; - type ExtReceiverSetup; - - fn state(&self) -> &Self::State; + fn state(&self) -> sender::State; + // fn base_setup( &mut self, - base_sender_setup: Self::BaseSenderSetup, - ) -> Result; + base_sender_setup: BaseSenderSetup, + ) -> Result; - fn base_receive(&mut self, payload: Self::BaseSenderPayload) -> Result<(), ExtSenderCoreError>; + fn base_receive(&mut self, payload: BaseSenderPayload) -> Result<(), ExtSenderCoreError>; fn extension_setup( &mut self, - receiver_setup: Self::ExtReceiverSetup, + receiver_setup: ExtReceiverSetup, ) -> Result<(), ExtSenderCoreError>; - fn send(&mut self, inputs: &[[Block; 2]]) - -> Result; + fn send(&mut self, inputs: &[[Block; 2]]) -> Result; fn is_complete(&self) -> bool; } pub trait ExtRandomSendCore: ExtSendCore { - type ExtDerandomize; + fn state(&self) -> sender::State { + ExtSendCore::state(self) + } - fn rand_send( + // Sender in OT extension acts as Receiver in base OT and receives a setup + // message from base OT Sender and responds with its own setup message. + fn base_setup( + &mut self, + base_sender_setup: BaseSenderSetup, + ) -> Result { + ExtSendCore::base_setup(self, base_sender_setup) + } + + fn base_receive(&mut self, payload: BaseSenderPayload) -> Result<(), ExtSenderCoreError> { + ExtSendCore::base_receive(self, payload) + } + + fn extension_setup( + &mut self, + receiver_setup: ExtReceiverSetup, + ) -> Result<(), ExtSenderCoreError> { + ExtSendCore::extension_setup(self, receiver_setup) + } + + fn send( &mut self, inputs: &[[Block; 2]], - derandomize: Self::ExtDerandomize, - ) -> Result; + derandomize: ExtDerandomize, + ) -> Result; + + fn is_complete(&self) -> bool { + ExtSendCore::is_complete(self) + } } pub trait ExtReceiveCore { - type State; - type BaseSenderSetup; - type BaseSenderPayload; - type BaseReceiverSetup; - type ExtSenderPayload; - type ExtReceiverSetup; - - fn state(&self) -> &Self::State; + fn state(&self) -> &receiver::State; // Receiver in OT extension acts as Sender in base OT and sends the first // base OT setup message. - fn base_setup(&mut self) -> Result; + fn base_setup(&mut self) -> Result; fn base_send( &mut self, - base_receiver_setup: Self::BaseReceiverSetup, - ) -> Result; + base_receiver_setup: BaseReceiverSetup, + ) -> Result; fn extension_setup( &mut self, choice: &[bool], - ) -> Result; + ) -> Result; - fn receive( - &mut self, - payload: Self::ExtSenderPayload, - ) -> Result, ExtReceiverCoreError>; + fn receive(&mut self, payload: ExtSenderPayload) -> Result, ExtReceiverCoreError>; fn is_complete(&self) -> bool; } pub trait ExtRandomReceiveCore: ExtReceiveCore { - type ExtDerandomize; + fn state(&self) -> &receiver::State { + ExtReceiveCore::state(self) + } - fn rand_extension_setup(&mut self) -> Result; + // Receiver in OT extension acts as Sender in base OT and sends the first + // base OT setup message. + fn base_setup(&mut self) -> Result { + ExtReceiveCore::base_setup(self) + } - fn rand_receive( + fn base_send( &mut self, - payload: Self::ExtSenderPayload, - ) -> Result, ExtReceiverCoreError>; + base_receiver_setup: BaseReceiverSetup, + ) -> Result { + ExtReceiveCore::base_send(self, base_receiver_setup) + } - fn derandomize( - &mut self, - choice: &[bool], - ) -> Result; + fn extension_setup(&mut self) -> Result; + + fn derandomize(&mut self, choice: &[bool]) -> Result; + + fn receive(&mut self, payload: ExtSenderPayload) -> Result, ExtReceiverCoreError>; + + fn is_complete(&self) -> bool { + ExtReceiveCore::is_complete(self) + } } #[cfg(test)] pub mod tests { + use super::errors::{ExtReceiverCoreError, ExtSenderCoreError}; use super::{ - errors::{ExtReceiverCoreError, ExtSenderCoreError}, - kos15::{ - BaseReceiverSetup, BaseSenderPayload, BaseSenderSetup, ExtDerandomize, - ExtSenderPayload, Kos15Receiver, Kos15Sender, - }, - ExtReceiveCore, ExtSendCore, + BaseReceiverSetup, BaseSenderPayload, BaseSenderSetup, ExtDerandomize, ExtReceiverCore, + ExtSenderCore, ExtSenderPayload, }; use crate::utils::u8vec_to_boolvec; use crate::Block; @@ -132,12 +157,11 @@ pub mod tests { #[once] pub fn ot_ext_core_data(choice: &Vec, values: &Vec<[Block; 2]>) -> Data { use crate::ot::extension::{ - kos15::{Kos15Receiver, Kos15Sender}, - ExtReceiveCore, ExtSendCore, + ExtReceiveCore, ExtReceiverCore, ExtSendCore, ExtSenderCore, }; - let mut sender = Kos15Sender::new(values.len()); - let mut receiver = Kos15Receiver::new(choice.len()); + let mut sender = ExtSenderCore::new(values.len()); + let mut receiver = ExtReceiverCore::new(choice.len()); let base_sender_setup = receiver.base_setup().unwrap(); let base_receiver_setup = sender.base_setup(base_sender_setup).unwrap(); let base_sender_payload = receiver.base_send(base_receiver_setup.clone()).unwrap(); @@ -151,20 +175,20 @@ pub mod tests { } #[fixture] - fn receiver() -> Kos15Receiver { - Kos15Receiver::new(16) + fn receiver() -> ExtReceiverCore { + ExtReceiverCore::new(16) } #[fixture] - fn sender() -> Kos15Sender { - Kos15Sender::new(16) + fn sender() -> ExtSenderCore { + ExtSenderCore::new(16) } #[fixture] fn pair_base_setup( - mut sender: Kos15Sender, - mut receiver: Kos15Receiver, - ) -> (Kos15Sender, Kos15Receiver) { + mut sender: ExtSenderCore, + mut receiver: ExtReceiverCore, + ) -> (ExtSenderCore, ExtReceiverCore) { use super::{ExtReceiveCore, ExtSendCore}; let base_sender_setup = receiver.base_setup().unwrap(); let base_receiver_setup = sender.base_setup(base_sender_setup).unwrap(); @@ -175,9 +199,10 @@ pub mod tests { #[fixture] fn random_pair_base_setup( - mut sender: Kos15Sender, - mut receiver: Kos15Receiver, - ) -> (Kos15Sender, Kos15Receiver) { + mut sender: ExtSenderCore, + mut receiver: ExtReceiverCore, + ) -> (ExtSenderCore, ExtReceiverCore) { + use super::{ExtRandomReceiveCore, ExtRandomSendCore}; let base_sender_setup = receiver.base_setup().unwrap(); let base_receiver_setup = sender.base_setup(base_sender_setup).unwrap(); let send_seeds = receiver.base_send(base_receiver_setup).unwrap(); @@ -186,7 +211,7 @@ pub mod tests { } #[rstest] - fn test_ext_ot(pair_base_setup: (Kos15Sender, Kos15Receiver)) { + fn test_ext_ot(pair_base_setup: (ExtSenderCore, ExtReceiverCore)) { use super::{ExtReceiveCore, ExtSendCore}; let (mut sender, mut receiver) = pair_base_setup; @@ -216,7 +241,7 @@ pub mod tests { #[rstest] // Test that the cointoss check fails on wrong data - fn test_ext_ot_cointoss_failure(mut sender: Kos15Sender, mut receiver: Kos15Receiver) { + fn test_ext_ot_cointoss_failure(mut sender: ExtSenderCore, mut receiver: ExtReceiverCore) { use super::{ExtReceiveCore, ExtSendCore}; let mut base_sender_setup = receiver.base_setup().unwrap(); @@ -229,7 +254,7 @@ pub mod tests { #[rstest] // Test that the KOS15 check fails on wrong data - fn test_ext_ot_kos_failure(pair_base_setup: (Kos15Sender, Kos15Receiver)) { + fn test_ext_ot_kos_failure(pair_base_setup: (ExtSenderCore, ExtReceiverCore)) { use super::{ExtReceiveCore, ExtSendCore}; let (mut sender, mut receiver) = pair_base_setup; @@ -246,7 +271,7 @@ pub mod tests { } #[rstest] - fn test_ext_ot_batch(pair_base_setup: (Kos15Sender, Kos15Receiver)) { + fn test_ext_ot_batch(pair_base_setup: (ExtSenderCore, ExtReceiverCore)) { use super::{ExtReceiveCore, ExtSendCore}; let (mut sender, mut receiver) = pair_base_setup; @@ -276,7 +301,7 @@ pub mod tests { let res = sender.send(&[[Block::random(&mut rng), Block::random(&mut rng)]]); assert_eq!(res, Err(ExtSenderCoreError::InvalidInputLength)); let p = ExtSenderPayload { - ciphertexts: vec![[Block::random(&mut rng), Block::random(&mut rng)]], + encrypted_values: vec![[Block::random(&mut rng), Block::random(&mut rng)]], }; let res = receiver.receive(p); assert_eq!(res, Err(ExtReceiverCoreError::AlreadyComplete)); @@ -291,7 +316,7 @@ pub mod tests { } #[rstest] - fn test_ext_random_ot(random_pair_base_setup: (Kos15Sender, Kos15Receiver)) { + fn test_ext_random_ot(random_pair_base_setup: (ExtSenderCore, ExtReceiverCore)) { use super::{ExtRandomReceiveCore, ExtRandomSendCore}; let (mut sender, mut receiver) = random_pair_base_setup; @@ -304,13 +329,13 @@ pub mod tests { .map(|_| [Block::random(&mut rng), Block::random(&mut rng)]) .collect(); - let receiver_setup = receiver.rand_extension_setup().unwrap(); + let receiver_setup = receiver.extension_setup().unwrap(); sender.extension_setup(receiver_setup).unwrap(); let derandomize = receiver.derandomize(&choice).unwrap(); - let payload = sender.rand_send(&inputs, derandomize).unwrap(); - let receive = receiver.rand_receive(payload).unwrap(); + let payload = sender.send(&inputs, derandomize).unwrap(); + let receive = receiver.receive(payload).unwrap(); let expected: Vec = inputs .iter() @@ -322,7 +347,7 @@ pub mod tests { } #[rstest] - fn test_ext_random_ot_batch(random_pair_base_setup: (Kos15Sender, Kos15Receiver)) { + fn test_ext_random_ot_batch(random_pair_base_setup: (ExtSenderCore, ExtReceiverCore)) { use super::{ExtRandomReceiveCore, ExtRandomSendCore}; let (mut sender, mut receiver) = random_pair_base_setup; @@ -335,7 +360,7 @@ pub mod tests { .map(|_| [Block::random(&mut rng), Block::random(&mut rng)]) .collect(); - let receiver_setup = receiver.rand_extension_setup().unwrap(); + let receiver_setup = receiver.extension_setup().unwrap(); sender.extension_setup(receiver_setup).unwrap(); let mut received: Vec = Vec::new(); @@ -343,18 +368,18 @@ pub mod tests { assert!(!sender.is_complete()); assert!(!receiver.is_complete()); let derandomize = receiver.derandomize(&choice).unwrap(); - let payload = sender.rand_send(&input, derandomize).unwrap(); - received.append(&mut receiver.rand_receive(payload).unwrap()); + let payload = sender.send(&input, derandomize).unwrap(); + received.append(&mut receiver.receive(payload).unwrap()); } assert!(sender.is_complete()); assert!(receiver.is_complete()); // Trying to send/receive more OTs should return an error let d = ExtDerandomize { flip: vec![true] }; - let res = sender.rand_send(&[[Block::random(&mut rng); 2]], d); + let res = sender.send(&[[Block::random(&mut rng); 2]], d); assert_eq!(res, Err(ExtSenderCoreError::InvalidInputLength)); let p = ExtSenderPayload { - ciphertexts: vec![[Block::random(&mut rng); 2]], + encrypted_values: vec![[Block::random(&mut rng); 2]], }; let res = receiver.receive(p); assert_eq!(res, Err(ExtReceiverCoreError::AlreadyComplete)); diff --git a/mpc-core/src/ot/extension/kos15/receiver.rs b/mpc-core/src/ot/extension/receiver.rs similarity index 82% rename from mpc-core/src/ot/extension/kos15/receiver.rs rename to mpc-core/src/ot/extension/receiver.rs index 4c3215263..3eecd4b56 100644 --- a/mpc-core/src/ot/extension/kos15/receiver.rs +++ b/mpc-core/src/ot/extension/receiver.rs @@ -4,18 +4,14 @@ use rand::{CryptoRng, Rng, RngCore, SeedableRng}; use rand_chacha::ChaCha12Rng; use std::convert::TryInto; -use super::BaseSender; -use crate::{ - ot::extension::{ - kos15::{ - sender::{BaseSenderPayload, BaseSenderSetup}, - BaseReceiverSetup, ExtSenderPayload, - }, - ExtRandomReceiveCore, ExtReceiveCore, ExtReceiverCoreError, BASE_COUNT, - }, - utils::{self, sha256, u8vec_to_boolvec, xor}, - Block, +use super::{ + BaseReceiverSetup, ExtRandomReceiveCore, ExtReceiveCore, ExtReceiverCoreError, + ExtSenderPayload, BASE_COUNT, }; +use crate::block::Block; +use crate::ot::base::{SenderPayload, SenderSetup}; +use crate::ot::{SendCore, SenderCore}; +use crate::utils::{self, sha256, u8vec_to_boolvec, xor}; use clmul::Clmul; #[derive(Clone, Debug, PartialEq)] @@ -33,10 +29,26 @@ pub enum State { Complete, } -pub struct Kos15Receiver { +/// OT extension Receiver plays the role of base OT Sender and sends the +/// first message containing base OT setup and cointoss commitment +#[derive(Debug, Clone, Copy, PartialEq)] +pub struct BaseSenderSetup { + pub setup: SenderSetup, + // Cointoss protocol's 1st message: sha256 commitment + pub cointoss_commit: [u8; 32], +} + +#[derive(Debug, Clone, PartialEq)] +pub struct BaseSenderPayload { + pub payload: SenderPayload, + // Cointoss protocol's 3rd message: Sender reveals share + pub cointoss_share: [u8; 32], +} + +pub struct ExtReceiverCore> { rng: R, cipher: C, - base: BaseSender, + base: OT, state: State, count: usize, // seeds are the result of running base OT setup. They are used to seed the @@ -66,14 +78,14 @@ pub struct ExtDerandomize { pub flip: Vec, } -impl Kos15Receiver { +impl ExtReceiverCore { pub fn new(count: usize) -> Self { let mut rng = ChaCha12Rng::from_entropy(); let cointoss_share = rng.gen(); Self { rng, cipher: Aes128::new_from_slice(&[0u8; 16]).unwrap(), - base: BaseSender::default(), + base: SenderCore::new(BASE_COUNT), state: State::Initialized, count, seeds: None, @@ -87,7 +99,7 @@ impl Kos15Receiver { fn decrypt_values + BlockEncrypt>( cipher: &mut C, - ciphertexts: &[[Block; 2]], + encrypted_values: &[[Block; 2]], table: &[Vec], choice: &[bool], ) -> Vec { @@ -96,9 +108,9 @@ fn decrypt_values + BlockEncrypt>( let t: [u8; 16] = table[j].clone().try_into().unwrap(); let t = Block::from(t); let y = if *b { - ciphertexts[j][1] + encrypted_values[j][1] } else { - ciphertexts[j][0] + encrypted_values[j][0] }; let y = y ^ t.hash_tweak(cipher, j); values.push(y); @@ -106,12 +118,13 @@ fn decrypt_values + BlockEncrypt>( values } -impl Kos15Receiver +impl ExtReceiverCore where R: Rng + CryptoRng, C: BlockCipher + BlockEncrypt, + OT: SendCore, { - pub fn new_with_custom(mut rng: R, cipher: C, base: BaseSender, count: usize) -> Self { + pub fn new_with_custom(mut rng: R, cipher: C, base: OT, count: usize) -> Self { let cointoss_share = rng.gen(); Self { rng, @@ -149,18 +162,12 @@ where } } -impl ExtReceiveCore for Kos15Receiver +impl ExtReceiveCore for ExtReceiverCore where R: Rng + CryptoRng + SeedableRng, C: BlockCipher + BlockEncrypt, + OT: SendCore, { - type State = State; - type BaseSenderSetup = BaseSenderSetup; - type BaseSenderPayload = BaseSenderPayload; - type BaseReceiverSetup = BaseReceiverSetup; - type ExtSenderPayload = ExtSenderPayload; - type ExtReceiverSetup = ExtReceiverSetup; - fn state(&self) -> &State { &self.state } @@ -175,7 +182,7 @@ where } self.state = State::BaseSetup; Ok(BaseSenderSetup { - setup: self.base.setup(&mut self.rng), + setup: self.base.setup(), cointoss_commit: sha256(&self.cointoss_share), }) } @@ -192,7 +199,9 @@ where seeds.push([Block::random(&mut self.rng), Block::random(&mut self.rng)]); } - let base_send = self.base.send(&seeds, base_receiver_setup.setup)?; + let base_send = self + .base + .send(seeds.as_slice(), base_receiver_setup.setup)?; self.set_seeds(seeds); let mut result = [0u8; 32]; @@ -213,7 +222,6 @@ where &mut self, choice: &[bool], ) -> Result { - println!("Doing extension setup with {} choices", choice.len()); if State::BaseSend != self.state { return Err(ExtReceiverCoreError::BaseOTNotSetup); } @@ -300,14 +308,6 @@ where choice: Vec::from(choice), derandomized: Vec::new(), }); - println!( - "self.state.choice.len() == {}", - if let State::Setup(ChoiceState { choice, .. }) = &self.state { - choice.len() - } else { - 0 - } - ); // remove the last 256 elements which were sacrificed ts.drain(ts.len() - 256..); self.table = Some(ts); @@ -327,23 +327,18 @@ where _ => return Err(ExtReceiverCoreError::NotSetup), }; - if payload.ciphertexts.len() > choice_state.choice.len() { - println!( - "Got {} payload ciphertexts with {} choices", - payload.ciphertexts.len(), - choice_state.choice.len() - ); + if payload.encrypted_values.len() > choice_state.choice.len() { return Err(ExtReceiverCoreError::InvalidPayloadSize); } let choice: Vec = choice_state .choice - .drain(..payload.ciphertexts.len()) + .drain(..payload.encrypted_values.len()) .collect(); let table = self.table.as_mut().ok_or(ExtReceiverCoreError::NotSetup)?; let table: Vec> = table.drain(..choice.len()).collect(); - let values = decrypt_values(&mut self.cipher, &payload.ciphertexts, &table, &choice); + let values = decrypt_values(&mut self.cipher, &payload.encrypted_values, &table, &choice); if (choice_state.choice.len() == 0) && (choice_state.derandomized.len() == 0) { self.state = State::Complete; @@ -353,14 +348,13 @@ where } } -impl ExtRandomReceiveCore for Kos15Receiver +impl ExtRandomReceiveCore for ExtReceiverCore where R: Rng + CryptoRng + SeedableRng, C: BlockCipher + BlockEncrypt, + OT: SendCore, { - type ExtDerandomize = ExtDerandomize; - - fn rand_extension_setup(&mut self) -> Result { + fn extension_setup(&mut self) -> Result { let n = self.count; // For random OT we generate random choice bits during setup then derandomize later let mut choice = vec![0u8; if n % 8 != 0 { n + (8 - n % 8) } else { n } / 8]; @@ -368,7 +362,6 @@ where let mut choice = u8vec_to_boolvec(&choice); choice.resize(n, false); - println!("In rand_extension_setup"); ExtReceiveCore::extension_setup(self, &choice) } @@ -394,27 +387,24 @@ where Ok(ExtDerandomize { flip }) } - fn rand_receive( - &mut self, - payload: ExtSenderPayload, - ) -> Result, ExtReceiverCoreError> { + fn receive(&mut self, payload: ExtSenderPayload) -> Result, ExtReceiverCoreError> { let choice_state = match &mut self.state { State::Setup(state) => state, State::Complete => return Err(ExtReceiverCoreError::AlreadyComplete), _ => return Err(ExtReceiverCoreError::NotSetup), }; - if payload.ciphertexts.len() > choice_state.derandomized.len() { + if payload.encrypted_values.len() > choice_state.derandomized.len() { return Err(ExtReceiverCoreError::NotDerandomized); } let choice: Vec = choice_state .derandomized - .drain(..payload.ciphertexts.len()) + .drain(..payload.encrypted_values.len()) .collect(); let table = self.table.as_mut().ok_or(ExtReceiverCoreError::NotSetup)?; let table: Vec> = table.drain(..choice.len()).collect(); - let values = decrypt_values(&mut self.cipher, &payload.ciphertexts, &table, &choice); + let values = decrypt_values(&mut self.cipher, &payload.encrypted_values, &table, &choice); if (choice_state.choice.len() == 0) && (choice_state.derandomized.len() == 0) { self.state = State::Complete; diff --git a/mpc-core/src/ot/extension/kos15/sender.rs b/mpc-core/src/ot/extension/sender.rs similarity index 81% rename from mpc-core/src/ot/extension/kos15/sender.rs rename to mpc-core/src/ot/extension/sender.rs index f2c2fc718..71723badf 100644 --- a/mpc-core/src/ot/extension/kos15/sender.rs +++ b/mpc-core/src/ot/extension/sender.rs @@ -1,20 +1,19 @@ -use crate::block::Block; -use crate::ot::extension::{ - kos15::{ - BaseReceiver, BaseReceiverSetup, ExtDerandomize, ExtReceiverSetup, ExtSenderPayload, - SenderPayload, SenderSetup, - }, - ExtRandomSendCore, ExtSendCore, ExtSenderCoreError, BASE_COUNT, -}; -use crate::utils::{self, sha256, xor}; - use aes::{Aes128, BlockCipher, BlockEncrypt, NewBlockCipher}; use cipher::consts::U16; -use clmul::Clmul; -use rand::{Rng, RngCore, SeedableRng}; +use rand::{thread_rng, Rng, RngCore, SeedableRng}; use rand_chacha::ChaCha12Rng; use std::convert::TryInto; +use super::{ + BaseSenderPayload, BaseSenderSetup, ExtDerandomize, ExtRandomSendCore, ExtReceiverSetup, + ExtSendCore, ExtSenderCoreError, BASE_COUNT, +}; +use crate::block::Block; +use crate::ot::base::ReceiverSetup; +use crate::ot::{ReceiveCore, ReceiverCore}; +use crate::utils::{self, sha256, xor}; +use clmul::Clmul; + #[derive(Clone, Copy, Debug, PartialEq, PartialOrd)] pub enum State { Initialized, @@ -24,10 +23,18 @@ pub enum State { Complete, } -pub struct Kos15Sender { - rng: ChaCha12Rng, +/// OT extension Sender plays the role of base OT Receiver and sends the +/// second message containing base OT setup and cointoss share +#[derive(Debug, Clone, std::cmp::PartialEq)] +pub struct BaseReceiverSetup { + pub setup: ReceiverSetup, + // Cointoss protocol's 2nd message: Receiver reveals share + pub cointoss_share: [u8; 32], +} + +pub struct ExtSenderCore> { cipher: C, - base: BaseReceiver, + base: OT, state: State, count: usize, sent: usize, @@ -52,20 +59,9 @@ pub struct Kos15Sender { cointoss_random: Option<[u8; 32]>, } -/// OT extension Receiver plays the role of base OT Sender and sends the -/// first message containing base OT setup and cointoss commitment -#[derive(Debug, Clone, Copy, PartialEq)] -pub struct BaseSenderSetup { - pub setup: SenderSetup, - // Cointoss protocol's 1st message: sha256 commitment - pub cointoss_commit: [u8; 32], -} - -#[derive(Debug, Clone, PartialEq)] -pub struct BaseSenderPayload { - pub payload: SenderPayload, - // Cointoss protocol's 3rd message: Sender reveals share - pub cointoss_share: [u8; 32], +#[derive(Clone, Debug, PartialEq)] +pub struct ExtSenderPayload { + pub encrypted_values: Vec<[Block; 2]>, } // Having 2 messages that Receiver chooses from, we encrypt each message with @@ -78,7 +74,7 @@ fn encrypt_values + BlockEncrypt>( base_choice: &[bool], flip: Option>, ) -> Vec<[Block; 2]> { - let mut ciphertexts: Vec<[Block; 2]> = Vec::with_capacity(table.len()); + let mut encrypted_values: Vec<[Block; 2]> = Vec::with_capacity(table.len()); let base_choice: [u8; 16] = utils::boolvec_to_u8vec(base_choice).try_into().unwrap(); let delta = Block::from(base_choice); // If Receiver used *random* choice bits during OT extension setup, he will now @@ -90,26 +86,22 @@ fn encrypt_values + BlockEncrypt>( let q = Block::from(q); let masks = [q.hash_tweak(cipher, j), (q ^ delta).hash_tweak(cipher, j)]; if flip { - ciphertexts.push([input[0] ^ masks[1], input[1] ^ masks[0]]); + encrypted_values.push([input[0] ^ masks[1], input[1] ^ masks[0]]); } else { - ciphertexts.push([input[0] ^ masks[0], input[1] ^ masks[1]]); + encrypted_values.push([input[0] ^ masks[0], input[1] ^ masks[1]]); } } - ciphertexts + encrypted_values } -impl Kos15Sender { +impl ExtSenderCore { pub fn new(count: usize) -> Self { let mut rng = ChaCha12Rng::from_entropy(); - - let cointoss_share = rng.gen(); let mut base_choice = vec![0u8; BASE_COUNT / 8]; rng.fill_bytes(&mut base_choice); - Self { - rng, cipher: Aes128::new_from_slice(&[0u8; 16]).unwrap(), - base: BaseReceiver::default(), + base: ReceiverCore::new(BASE_COUNT), state: State::Initialized, count, sent: 0, @@ -117,26 +109,23 @@ impl Kos15Sender { seeds: None, rngs: None, table: None, - cointoss_share, + cointoss_share: rng.gen(), receiver_cointoss_commit: None, cointoss_random: None, } } } -impl Kos15Sender +impl ExtSenderCore where C: BlockCipher + BlockEncrypt, + OT: ReceiveCore, { - pub fn new_from_custom(cipher: C, base: BaseReceiver, count: usize) -> Self { - let mut rng = ChaCha12Rng::from_entropy(); - - let cointoss_share = rng.gen(); + pub fn new_from_custom(cipher: C, base: OT, count: usize) -> Self { + let mut rng = thread_rng(); let mut base_choice = vec![0u8; BASE_COUNT / 8]; rng.fill_bytes(&mut base_choice); - Self { - rng, cipher, base, state: State::Initialized, @@ -146,7 +135,7 @@ where seeds: None, rngs: None, table: None, - cointoss_share, + cointoss_share: rng.gen(), receiver_cointoss_commit: None, cointoss_random: None, } @@ -169,19 +158,13 @@ where } } -impl ExtSendCore for Kos15Sender +impl ExtSendCore for ExtSenderCore where C: BlockCipher + BlockEncrypt, + OT: ReceiveCore, { - type State = State; - type BaseSenderSetup = BaseSenderSetup; - type BaseSenderPayload = BaseSenderPayload; - type BaseReceiverSetup = BaseReceiverSetup; - type ExtSenderPayload = ExtSenderPayload; - type ExtReceiverSetup = ExtReceiverSetup; - - fn state(&self) -> &State { - &self.state + fn state(&self) -> State { + self.state } fn is_complete(&self) -> bool { @@ -200,7 +183,7 @@ where Ok(BaseReceiverSetup { setup: self .base - .setup(&mut self.rng, &self.base_choice, base_sender_setup.setup)?, + .setup(&self.base_choice, base_sender_setup.setup)?, cointoss_share: self.cointoss_share, }) } @@ -308,7 +291,7 @@ where // KOS check qs.drain(qs.len() - 256..); self.table = Some(qs); - self.state = State::Initialized; + self.state = State::Setup; Ok(()) } @@ -317,31 +300,31 @@ where return Err(ExtSenderCoreError::InvalidInputLength); } match self.state { - State::Initialized => {} + State::Setup => {} State::Complete => return Err(ExtSenderCoreError::AlreadyComplete), _ => return Err(ExtSenderCoreError::NotSetup), }; let table = self.table.as_mut().ok_or(ExtSenderCoreError::NotSetup)?; let table: Vec> = table.drain(..inputs.len()).collect(); - let ciphertexts = encrypt_values(&mut self.cipher, inputs, &table, &self.base_choice, None); + let encrypted_values = + encrypt_values(&mut self.cipher, inputs, &table, &self.base_choice, None); self.sent += inputs.len(); if self.sent == self.count { self.state = State::Complete; } - Ok(ExtSenderPayload { ciphertexts }) + Ok(ExtSenderPayload { encrypted_values }) } } -impl ExtRandomSendCore for Kos15Sender +impl ExtRandomSendCore for ExtSenderCore where C: BlockCipher + BlockEncrypt, + OT: ReceiveCore, { - type ExtDerandomize = ExtDerandomize; - - fn rand_send( + fn send( &mut self, inputs: &[[Block; 2]], derandomize: ExtDerandomize, @@ -350,14 +333,14 @@ where return Err(ExtSenderCoreError::InvalidInputLength); } match self.state { - State::Initialized => {} + State::Setup => {} State::Complete => return Err(ExtSenderCoreError::AlreadyComplete), _ => return Err(ExtSenderCoreError::NotSetup), }; let table = self.table.as_mut().ok_or(ExtSenderCoreError::NotSetup)?; let table: Vec> = table.drain(..inputs.len()).collect(); - let ciphertexts = encrypt_values( + let encrypted_values = encrypt_values( &mut self.cipher, inputs, &table, @@ -370,6 +353,6 @@ where self.state = State::Complete; } - Ok(ExtSenderPayload { ciphertexts }) + Ok(ExtSenderPayload { encrypted_values }) } } diff --git a/mpc-core/src/ot/mod.rs b/mpc-core/src/ot/mod.rs index bfa76fc28..3eac3fe54 100644 --- a/mpc-core/src/ot/mod.rs +++ b/mpc-core/src/ot/mod.rs @@ -5,14 +5,14 @@ pub use base::*; pub use extension::*; #[derive(Debug, Clone)] -pub enum Kos15Message { - SenderSetup(dh_ot::SenderSetup), - BaseSenderSetup(kos15::BaseSenderSetup), - SenderPayload(dh_ot::SenderPayload), - BaseSenderPayload(kos15::BaseSenderPayload), - ReceiverSetup(dh_ot::ReceiverChoices), - BaseReceiverSetup(kos15::BaseReceiverSetup), - ExtReceiverSetup(kos15::ExtReceiverSetup), - ExtDerandomize(kos15::ExtDerandomize), - ExtSenderPayload(kos15::ExtSenderPayload), +pub enum Message { + SenderSetup(SenderSetup), + BaseSenderSetup(BaseSenderSetup), + SenderPayload(SenderPayload), + BaseSenderPayload(BaseSenderPayload), + ReceiverSetup(ReceiverSetup), + BaseReceiverSetup(BaseReceiverSetup), + ExtReceiverSetup(ExtReceiverSetup), + ExtDerandomize(ExtDerandomize), + ExtSenderPayload(ExtSenderPayload), } diff --git a/mpc-core/src/proto/core/ot.rs b/mpc-core/src/proto/core/ot.rs index 40ac0f670..f0707d0a2 100644 --- a/mpc-core/src/proto/core/ot.rs +++ b/mpc-core/src/proto/core/ot.rs @@ -1,6 +1,6 @@ #![cfg(feature = "ot")] -pub use crate::ot::{self, dh_ot, kos15}; +pub use crate::ot; use crate::utils::parse_ristretto_key; use std::convert::{TryFrom, TryInto}; use std::io::{Error, ErrorKind}; @@ -9,36 +9,34 @@ include!(concat!(env!("OUT_DIR"), "/core.ot.rs")); pub use message::Msg; -impl From for Message { +impl From for Message { #[inline] - fn from(m: ot::Kos15Message) -> Self { + fn from(m: ot::Message) -> Self { Self { msg: Some(match m { - ot::Kos15Message::ReceiverSetup(msg) => { + ot::Message::ReceiverSetup(msg) => { message::Msg::ReceiverSetup(ReceiverSetup::from(msg)) } - ot::Kos15Message::SenderSetup(msg) => { - message::Msg::SenderSetup(SenderSetup::from(msg)) - } - ot::Kos15Message::SenderPayload(msg) => { + ot::Message::SenderSetup(msg) => message::Msg::SenderSetup(SenderSetup::from(msg)), + ot::Message::SenderPayload(msg) => { message::Msg::SenderPayload(SenderPayload::from(msg)) } - ot::Kos15Message::ExtReceiverSetup(msg) => { + ot::Message::ExtReceiverSetup(msg) => { message::Msg::ExtReceiverSetup(ExtReceiverSetup::from(msg)) } - ot::Kos15Message::ExtDerandomize(msg) => { + ot::Message::ExtDerandomize(msg) => { message::Msg::ExtDerandomize(ExtDerandomize::from(msg)) } - ot::Kos15Message::ExtSenderPayload(msg) => { + ot::Message::ExtSenderPayload(msg) => { message::Msg::ExtSenderPayload(ExtSenderPayload::from(msg)) } - ot::Kos15Message::BaseSenderSetup(msg) => { + ot::Message::BaseSenderSetup(msg) => { message::Msg::BaseSenderSetup(BaseSenderSetup::from(msg)) } - ot::Kos15Message::BaseReceiverSetup(msg) => { + ot::Message::BaseReceiverSetup(msg) => { message::Msg::BaseReceiverSetup(BaseReceiverSetup::from(msg)) } - ot::Kos15Message::BaseSenderPayload(msg) => { + ot::Message::BaseSenderPayload(msg) => { message::Msg::BaseSenderPayload(BaseSenderPayload::from(msg)) } }), @@ -46,38 +44,38 @@ impl From for Message { } } -impl TryFrom for ot::Kos15Message { +impl TryFrom for ot::Message { type Error = std::io::Error; #[inline] fn try_from(m: Message) -> Result { if let Some(msg) = m.msg { let m = match msg { message::Msg::ReceiverSetup(msg) => { - ot::Kos15Message::ReceiverSetup(dh_ot::ReceiverChoices::try_from(msg)?) + ot::Message::ReceiverSetup(ot::ReceiverSetup::try_from(msg)?) } message::Msg::SenderSetup(msg) => { - ot::Kos15Message::SenderSetup(dh_ot::SenderSetup::try_from(msg)?) + ot::Message::SenderSetup(ot::SenderSetup::try_from(msg)?) } message::Msg::SenderPayload(msg) => { - ot::Kos15Message::SenderPayload(dh_ot::SenderPayload::from(msg)) + ot::Message::SenderPayload(ot::SenderPayload::from(msg)) } message::Msg::ExtReceiverSetup(msg) => { - ot::Kos15Message::ExtReceiverSetup(kos15::ExtReceiverSetup::try_from(msg)?) + ot::Message::ExtReceiverSetup(ot::ExtReceiverSetup::try_from(msg)?) } message::Msg::ExtDerandomize(msg) => { - ot::Kos15Message::ExtDerandomize(kos15::ExtDerandomize::from(msg)) + ot::Message::ExtDerandomize(ot::ExtDerandomize::from(msg)) } message::Msg::ExtSenderPayload(msg) => { - ot::Kos15Message::ExtSenderPayload(kos15::ExtSenderPayload::from(msg)) + ot::Message::ExtSenderPayload(ot::ExtSenderPayload::from(msg)) } message::Msg::BaseSenderSetup(msg) => { - ot::Kos15Message::BaseSenderSetup(kos15::BaseSenderSetup::try_from(msg)?) + ot::Message::BaseSenderSetup(ot::BaseSenderSetup::try_from(msg)?) } message::Msg::BaseReceiverSetup(msg) => { - ot::Kos15Message::BaseReceiverSetup(kos15::BaseReceiverSetup::try_from(msg)?) + ot::Message::BaseReceiverSetup(ot::BaseReceiverSetup::try_from(msg)?) } message::Msg::BaseSenderPayload(msg) => { - ot::Kos15Message::BaseSenderPayload(kos15::BaseSenderPayload::try_from(msg)?) + ot::Message::BaseSenderPayload(ot::BaseSenderPayload::try_from(msg)?) } }; Ok(m) @@ -87,16 +85,16 @@ impl TryFrom for ot::Kos15Message { } } -impl From for SenderSetup { +impl From for SenderSetup { #[inline] - fn from(s: dh_ot::SenderSetup) -> Self { + fn from(s: ot::SenderSetup) -> Self { Self { public_key: super::RistrettoPoint::from(s.public_key), } } } -impl TryFrom for dh_ot::SenderSetup { +impl TryFrom for ot::SenderSetup { type Error = Error; #[inline] @@ -107,12 +105,12 @@ impl TryFrom for dh_ot::SenderSetup { } } -impl From for SenderPayload { +impl From for SenderPayload { #[inline] - fn from(p: dh_ot::SenderPayload) -> Self { + fn from(p: ot::SenderPayload) -> Self { Self { - ciphertexts: p - .ciphertexts + encrypted_values: p + .encrypted_values .into_iter() .map(|b| super::LabelPair { low: super::Block::from(b[0]), @@ -123,12 +121,12 @@ impl From for SenderPayload { } } -impl From for dh_ot::SenderPayload { +impl From for ot::SenderPayload { #[inline] fn from(p: SenderPayload) -> Self { Self { - ciphertexts: p - .ciphertexts + encrypted_values: p + .encrypted_values .into_iter() .map(|pair| [crate::Block::from(pair.low), crate::Block::from(pair.high)]) .collect(), @@ -136,12 +134,12 @@ impl From for dh_ot::SenderPayload { } } -impl From for ReceiverSetup { +impl From for ReceiverSetup { #[inline] - fn from(s: dh_ot::ReceiverChoices) -> Self { + fn from(s: ot::ReceiverSetup) -> Self { Self { - blinded_choices: s - .blinded_choices + keys: s + .keys .into_iter() .map(super::RistrettoPoint::from) .collect(), @@ -149,23 +147,23 @@ impl From for ReceiverSetup { } } -impl TryFrom for dh_ot::ReceiverChoices { +impl TryFrom for ot::ReceiverSetup { type Error = Error; #[inline] fn try_from(s: ReceiverSetup) -> Result { - let mut blinded_choices: Vec = - Vec::with_capacity(s.blinded_choices.len()); - for key in s.blinded_choices.into_iter() { - blinded_choices.push(parse_ristretto_key(key.point)?); + let mut keys: Vec = + Vec::with_capacity(s.keys.len()); + for key in s.keys.into_iter() { + keys.push(parse_ristretto_key(key.point)?); } - Ok(Self { blinded_choices }) + Ok(Self { keys }) } } -impl From for ExtReceiverSetup { +impl From for ExtReceiverSetup { #[inline] - fn from(s: kos15::ExtReceiverSetup) -> Self { + fn from(s: ot::ExtReceiverSetup) -> Self { Self { ncols: s.ncols as u32, table: s.table, @@ -176,7 +174,7 @@ impl From for ExtReceiverSetup { } } -impl TryFrom for kos15::ExtReceiverSetup { +impl TryFrom for ot::ExtReceiverSetup { type Error = Error; #[inline] @@ -191,26 +189,26 @@ impl TryFrom for kos15::ExtReceiverSetup { } } -impl From for ExtDerandomize { +impl From for ExtDerandomize { #[inline] - fn from(d: kos15::ExtDerandomize) -> Self { + fn from(d: ot::ExtDerandomize) -> Self { Self { flip: d.flip } } } -impl From for kos15::ExtDerandomize { +impl From for ot::ExtDerandomize { #[inline] fn from(d: ExtDerandomize) -> Self { Self { flip: d.flip } } } -impl From for ExtSenderPayload { +impl From for ExtSenderPayload { #[inline] - fn from(p: kos15::ExtSenderPayload) -> Self { + fn from(p: ot::ExtSenderPayload) -> Self { Self { - ciphertexts: p - .ciphertexts + encrypted_values: p + .encrypted_values .into_iter() .map(|b| super::LabelPair { low: super::Block::from(b[0]), @@ -221,12 +219,12 @@ impl From for ExtSenderPayload { } } -impl From for kos15::ExtSenderPayload { +impl From for ot::ExtSenderPayload { #[inline] fn from(p: ExtSenderPayload) -> Self { Self { - ciphertexts: p - .ciphertexts + encrypted_values: p + .encrypted_values .into_iter() .map(|pair| [crate::Block::from(pair.low), crate::Block::from(pair.high)]) .collect(), @@ -234,9 +232,9 @@ impl From for kos15::ExtSenderPayload { } } -impl From for BaseSenderSetup { +impl From for BaseSenderSetup { #[inline] - fn from(s: kos15::BaseSenderSetup) -> Self { + fn from(s: ot::BaseSenderSetup) -> Self { Self { setup: SenderSetup::from(s.setup), cointoss_commit: s.cointoss_commit.to_vec(), @@ -244,7 +242,7 @@ impl From for BaseSenderSetup { } } -impl TryFrom for kos15::BaseSenderSetup { +impl TryFrom for ot::BaseSenderSetup { type Error = Error; #[inline] @@ -259,9 +257,9 @@ impl TryFrom for kos15::BaseSenderSetup { } } -impl From for BaseReceiverSetup { +impl From for BaseReceiverSetup { #[inline] - fn from(s: kos15::BaseReceiverSetup) -> Self { + fn from(s: ot::BaseReceiverSetup) -> Self { Self { setup: ReceiverSetup::from(s.setup), cointoss_share: s.cointoss_share.to_vec(), @@ -269,7 +267,7 @@ impl From for BaseReceiverSetup { } } -impl TryFrom for kos15::BaseReceiverSetup { +impl TryFrom for ot::BaseReceiverSetup { type Error = Error; #[inline] @@ -284,9 +282,9 @@ impl TryFrom for kos15::BaseReceiverSetup { } } -impl From for BaseSenderPayload { +impl From for BaseSenderPayload { #[inline] - fn from(s: kos15::BaseSenderPayload) -> Self { + fn from(s: ot::BaseSenderPayload) -> Self { Self { payload: SenderPayload::from(s.payload), cointoss_share: s.cointoss_share.to_vec(), @@ -294,7 +292,7 @@ impl From for BaseSenderPayload { } } -impl TryFrom for kos15::BaseSenderPayload { +impl TryFrom for ot::BaseSenderPayload { type Error = Error; #[inline] @@ -356,7 +354,7 @@ pub mod tests { #[rstest] fn test_proto_ot(proto_base_core_data: &fixtures::ProtoData, ot_core_data: &Data) { - let sender_setup: crate::ot::base::dh_ot::SenderSetup = proto_base_core_data + let sender_setup: crate::ot::base::SenderSetup = proto_base_core_data .sender_setup .clone() .try_into() @@ -364,7 +362,7 @@ pub mod tests { assert_eq!(sender_setup, ot_core_data.sender_setup); - let receiver_setup: crate::ot::base::dh_ot::ReceiverChoices = proto_base_core_data + let receiver_setup: crate::ot::base::ReceiverSetup = proto_base_core_data .receiver_setup .clone() .try_into() @@ -372,7 +370,7 @@ pub mod tests { assert_eq!(receiver_setup, ot_core_data.receiver_setup); - let sender_payload: crate::ot::base::dh_ot::SenderPayload = proto_base_core_data + let sender_payload: crate::ot::base::SenderPayload = proto_base_core_data .sender_payload .clone() .try_into() @@ -383,7 +381,7 @@ pub mod tests { #[rstest] fn test_proto_ext(proto_ext_core_data: &fixtures::ProtoExtData, ot_ext_core_data: &ExtData) { - let base_sender_setup: crate::ot::extension::kos15::BaseSenderSetup = proto_ext_core_data + let base_sender_setup: crate::ot::extension::BaseSenderSetup = proto_ext_core_data .base_sender_setup .clone() .try_into() @@ -391,21 +389,19 @@ pub mod tests { assert_eq!(base_sender_setup, ot_ext_core_data.base_sender_setup); - let base_receiver_setup: crate::ot::extension::kos15::BaseReceiverSetup = - proto_ext_core_data - .base_receiver_setup - .clone() - .try_into() - .unwrap(); + let base_receiver_setup: crate::ot::extension::BaseReceiverSetup = proto_ext_core_data + .base_receiver_setup + .clone() + .try_into() + .unwrap(); assert_eq!(base_receiver_setup, ot_ext_core_data.base_receiver_setup); - let base_sender_payload: crate::ot::extension::kos15::BaseSenderPayload = - proto_ext_core_data - .base_sender_payload - .clone() - .try_into() - .unwrap(); + let base_sender_payload: crate::ot::extension::BaseSenderPayload = proto_ext_core_data + .base_sender_payload + .clone() + .try_into() + .unwrap(); assert_eq!(base_sender_payload, ot_ext_core_data.base_sender_payload); }