mirror of
https://github.com/tlsnotary/tlsn.git
synced 2026-01-09 14:48:13 -05:00
Undid reversion
This commit is contained in:
5
.gitignore
vendored
5
.gitignore
vendored
@@ -13,4 +13,7 @@ Cargo.lock
|
||||
# MSVC Windows builds of rustc generate these, which store debugging information
|
||||
*.pdb
|
||||
|
||||
tlsn-mpc-circuits/compiled/*
|
||||
# macOS puts these everywhere
|
||||
.DS_Store
|
||||
|
||||
tlsn-mpc-circuits/compiled/*
|
||||
|
||||
@@ -4,7 +4,7 @@ use futures::{AsyncRead, AsyncWrite};
|
||||
use mpc_aio::ot::{
|
||||
ExtOTReceive, ExtOTSend, ExtReceiver, ExtSender, OTReceive, OTSend, Receiver, Sender,
|
||||
};
|
||||
use mpc_core::ot::{ExtReceiverCore, ExtSenderCore, ReceiverCore, SenderCore};
|
||||
use mpc_core::ot::{DhOtSender, ExtReceiverCore, ExtSenderCore, ReceiverCore};
|
||||
use mpc_core::Block;
|
||||
use rand::{thread_rng, Rng};
|
||||
use tokio;
|
||||
@@ -83,7 +83,7 @@ async fn send<S: AsyncWrite + AsyncRead + Send + Unpin>(
|
||||
let mut sender = ExtSender::new(ExtSenderCore::new(values.len()), stream);
|
||||
let _ = sender.send(&values).await;
|
||||
} else {
|
||||
let mut sender = Sender::new(SenderCore::new(values.len()), stream);
|
||||
let mut sender = Sender::new(DhOtSender::new(values.len()), stream);
|
||||
let _ = sender.send(&values).await;
|
||||
}
|
||||
|
||||
|
||||
@@ -56,10 +56,10 @@ where
|
||||
let setup = self.ot.setup(choice, setup)?;
|
||||
|
||||
trace!("Sending ReceiverSetup: {:?}", &setup);
|
||||
self.stream.send(Message::ReceiverSetup(setup)).await?;
|
||||
self.stream.send(Message::ReceiverChoices(setup)).await?;
|
||||
|
||||
let payload = match self.stream.next().await {
|
||||
Some(Ok(Message::SenderPayload(m))) => m,
|
||||
Some(Ok(Message::SenderOutput(m))) => m,
|
||||
Some(Ok(m)) => return Err(OTError::Unexpected(m)),
|
||||
Some(Err(e)) => return Err(e)?,
|
||||
None => return Err(IOError::new(ErrorKind::UnexpectedEof, ""))?,
|
||||
|
||||
@@ -51,7 +51,7 @@ where
|
||||
self.stream.send(Message::SenderSetup(setup)).await?;
|
||||
|
||||
let setup = match self.stream.next().await {
|
||||
Some(Ok(Message::ReceiverSetup(m))) => m,
|
||||
Some(Ok(Message::ReceiverChoices(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::SenderPayload(payload)).await?;
|
||||
self.stream.send(Message::SenderOutput(payload)).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ 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"
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use criterion::{black_box, criterion_group, criterion_main, Criterion};
|
||||
use mpc_core::block::{Block, BLOCK_ONES};
|
||||
use mpc_core::ot::{
|
||||
ExtReceiveCore, ExtReceiverCore, ExtSendCore, ExtSenderCore, ReceiveCore, ReceiverCore,
|
||||
SendCore, SenderCore,
|
||||
DhOtSender, ExtReceiveCore, ExtReceiverCore, ExtSendCore, ExtSenderCore, ReceiveCore,
|
||||
ReceiverCore, SendCore,
|
||||
};
|
||||
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 = SenderCore::new(1024);
|
||||
let mut sender = DhOtSender::new(1024);
|
||||
let sender_setup = sender.setup();
|
||||
|
||||
let mut receiver = ReceiverCore::new(1024);
|
||||
|
||||
@@ -3,9 +3,12 @@
|
||||
// For simplicity, this example shows how to use OT components in memory.
|
||||
|
||||
use mpc_core::block::Block;
|
||||
use mpc_core::ot::{ReceiveCore, ReceiverCore, SendCore, SenderCore};
|
||||
use mpc_core::ot::dh_ot::{DhOtReceiver, DhOtSender};
|
||||
use rand::thread_rng;
|
||||
|
||||
pub fn main() {
|
||||
let mut rng = thread_rng();
|
||||
|
||||
// Receiver choice bits
|
||||
let choice = vec![false, true, false, false, true, true, false, true];
|
||||
|
||||
@@ -26,12 +29,12 @@ pub fn main() {
|
||||
println!("Sender inputs: {:?}", &inputs);
|
||||
|
||||
// First the sender creates a setup message and passes it to sender
|
||||
let mut sender = SenderCore::new(inputs.len());
|
||||
let setup = sender.setup();
|
||||
let mut sender = DhOtSender::default();
|
||||
let setup = sender.setup(&mut rng);
|
||||
|
||||
// Receiver takes sender's setup and creates its own setup message
|
||||
let mut receiver = ReceiverCore::new(choice.len());
|
||||
let setup = receiver.setup(&choice, setup).unwrap();
|
||||
let mut receiver = DhOtReceiver::default();
|
||||
let setup = receiver.setup(&mut rng, &choice, setup).unwrap();
|
||||
|
||||
// Finally, sender encrypts their inputs and sends them to receiver
|
||||
let payload = sender.send(&inputs, setup).unwrap();
|
||||
|
||||
@@ -3,7 +3,10 @@
|
||||
// For simplicity, this example shows how to use OT components in memory.
|
||||
|
||||
use mpc_core::block::Block;
|
||||
use mpc_core::ot::{ExtReceiveCore, ExtReceiverCore, ExtSendCore, ExtSenderCore};
|
||||
use mpc_core::ot::extension::{
|
||||
kos15::{Kos15Receiver, Kos15Sender},
|
||||
ExtReceiveCore, ExtSendCore,
|
||||
};
|
||||
|
||||
pub fn main() {
|
||||
// Receiver choice bits
|
||||
@@ -26,11 +29,11 @@ pub fn main() {
|
||||
println!("Sender inputs: {:?}", &inputs);
|
||||
|
||||
// First the receiver creates a setup message and passes it to sender
|
||||
let mut receiver = ExtReceiverCore::new(inputs.len());
|
||||
let mut receiver = Kos15Receiver::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 = ExtSenderCore::new(inputs.len());
|
||||
let mut sender = Kos15Sender::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
|
||||
|
||||
@@ -6,7 +6,10 @@
|
||||
// For simplicity, this example shows how to use OT components in memory.
|
||||
|
||||
use mpc_core::block::Block;
|
||||
use mpc_core::ot::{ExtRandomReceiveCore, ExtRandomSendCore, ExtReceiverCore, ExtSenderCore};
|
||||
use mpc_core::ot::extension::{
|
||||
kos15::{Kos15Receiver, Kos15Sender},
|
||||
ExtRandomReceiveCore, ExtRandomSendCore, ExtReceiveCore, ExtSendCore,
|
||||
};
|
||||
|
||||
pub fn main() {
|
||||
// Sender messages the receiver chooses from
|
||||
@@ -24,11 +27,11 @@ pub fn main() {
|
||||
println!("Sender inputs: {:?}", &inputs);
|
||||
|
||||
// First the receiver creates a setup message and passes it to sender
|
||||
let mut receiver = ExtReceiverCore::new(inputs.len());
|
||||
let mut receiver = Kos15Receiver::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 = ExtSenderCore::new(inputs.len());
|
||||
let mut sender = Kos15Sender::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
|
||||
@@ -36,7 +39,7 @@ pub fn main() {
|
||||
sender.base_receive(base_payload).unwrap();
|
||||
|
||||
// Receiver generates OT extension setup and passes it to sender
|
||||
let receiver_setup = receiver.extension_setup().unwrap();
|
||||
let receiver_setup = receiver.rand_extension_setup().unwrap();
|
||||
|
||||
// Sender takes receiver's setup and runs its own extension setup
|
||||
sender.extension_setup(receiver_setup).unwrap();
|
||||
@@ -47,13 +50,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.send(&inputs[..2], derandomize).unwrap();
|
||||
received.append(&mut receiver.receive(initial_payload).unwrap());
|
||||
let initial_payload = sender.rand_send(&inputs[..2], derandomize).unwrap();
|
||||
received.append(&mut receiver.rand_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.send(&chunk, derandomize).unwrap();
|
||||
let payload = sender.rand_send(&chunk, derandomize).unwrap();
|
||||
received.append(&mut receiver.receive(payload).unwrap());
|
||||
}
|
||||
|
||||
|
||||
@@ -13,13 +13,13 @@ message SenderSetup {
|
||||
// Message sent by OT Sender containing encrypted values
|
||||
message SenderPayload {
|
||||
// Encrypted values
|
||||
repeated core.LabelPair encrypted_values = 1;
|
||||
repeated core.LabelPair ciphertexts = 1;
|
||||
}
|
||||
|
||||
// Setup message sent by Base OT Receiver
|
||||
message ReceiverSetup {
|
||||
// Keys used to encrypt values by Sender
|
||||
repeated core.RistrettoPoint keys = 1;
|
||||
// The blinded choice bit sent by the receiver
|
||||
repeated core.RistrettoPoint blinded_choices = 1;
|
||||
}
|
||||
|
||||
// Setup message sent by OT Receiver
|
||||
@@ -38,7 +38,7 @@ message ExtDerandomize {
|
||||
|
||||
message ExtSenderPayload {
|
||||
// Encrypted values
|
||||
repeated core.LabelPair encrypted_values = 1;
|
||||
repeated core.LabelPair ciphertexts = 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
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)]
|
||||
@@ -44,7 +42,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<C: BlockCipher<BlockSize = U16> + BlockEncrypt>(
|
||||
&self,
|
||||
c: &mut C,
|
||||
c: &C,
|
||||
tweak: usize,
|
||||
) -> Self {
|
||||
let gid: [u8; 16] = (tweak as u128).to_be_bytes();
|
||||
@@ -68,17 +66,6 @@ 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)
|
||||
|
||||
96
mpc-core/src/ot/base/dh_ot/mod.rs
Normal file
96
mpc-core/src/ot/base/dh_ot/mod.rs
Normal file
@@ -0,0 +1,96 @@
|
||||
//! 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<RistrettoPoint>,
|
||||
}
|
||||
|
||||
/// 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<Block, ReceiverCoreError> {
|
||||
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<Block, ReceiverCoreError> {
|
||||
// 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])
|
||||
}
|
||||
}
|
||||
*/
|
||||
127
mpc-core/src/ot/base/dh_ot/receiver.rs
Normal file
127
mpc-core/src/ot/base/dh_ot/receiver.rs
Normal file
@@ -0,0 +1,127 @@
|
||||
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<Vec<Block>>,
|
||||
/// The bits that this receiver picked
|
||||
choices: Option<Vec<bool>>,
|
||||
}
|
||||
|
||||
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<R: CryptoRng + RngCore>(
|
||||
&mut self,
|
||||
rng: &mut R,
|
||||
choices: &[bool],
|
||||
sender_setup: SenderSetup,
|
||||
) -> Result<ReceiverChoices, ReceiverCoreError> {
|
||||
// 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<RistrettoPoint>, Vec<Block>) = 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<Vec<Block>, ReceiverCoreError> {
|
||||
if self.state != ReceiverState::Initialized {
|
||||
return Err(ReceiverCoreError::NotSetup);
|
||||
}
|
||||
|
||||
let keys = self.decryption_keys.as_ref().unwrap();
|
||||
let selected_inputs: Result<Vec<Block>, 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
|
||||
}
|
||||
}
|
||||
106
mpc-core/src/ot/base/dh_ot/sender.rs
Normal file
106
mpc-core/src/ot/base/dh_ot/sender.rs
Normal file
@@ -0,0 +1,106 @@
|
||||
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<Scalar>,
|
||||
// The public_key is `A == g^a` in [ref1]
|
||||
public_key: Option<RistrettoPoint>,
|
||||
}
|
||||
|
||||
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<R: CryptoRng + RngCore>(&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<SenderPayload, SenderCoreError> {
|
||||
// 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 })
|
||||
}
|
||||
}
|
||||
@@ -16,4 +16,6 @@ pub enum ReceiverCoreError {
|
||||
NotSetup,
|
||||
#[error("Provided incorrect number of choice bits")]
|
||||
InvalidChoiceLength,
|
||||
#[error("Sender's ciphertext is malformed")]
|
||||
MalformedCiphertext,
|
||||
}
|
||||
|
||||
@@ -1,37 +1,24 @@
|
||||
//! this crate implements the CO15 Oblivious Transfer protocol from
|
||||
//! [ref1] https://eprint.iacr.org/2015/267.pdf (see Figure 1)
|
||||
//! This crate implements types and imple
|
||||
|
||||
pub mod dh_ot;
|
||||
pub mod errors;
|
||||
pub mod receiver;
|
||||
pub mod sender;
|
||||
|
||||
pub use errors::*;
|
||||
|
||||
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<SenderPayload, SenderCoreError>;
|
||||
/// The state of an OT sender
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub enum SenderState {
|
||||
Initialized,
|
||||
ReadyToSend,
|
||||
Complete,
|
||||
}
|
||||
|
||||
pub trait ReceiveCore {
|
||||
fn state(&self) -> receiver::State;
|
||||
|
||||
fn setup(
|
||||
&mut self,
|
||||
choice: &[bool],
|
||||
sender_setup: SenderSetup,
|
||||
) -> Result<ReceiverSetup, ReceiverCoreError>;
|
||||
|
||||
fn receive(&mut self, payload: SenderPayload) -> Result<Vec<crate::Block>, ReceiverCoreError>;
|
||||
/// The state of an OT receiver
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub enum ReceiverState {
|
||||
Initialized,
|
||||
Setup,
|
||||
Complete,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -42,12 +29,15 @@ 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: ReceiverSetup,
|
||||
pub receiver_setup: ReceiverChoices,
|
||||
pub sender_payload: SenderPayload,
|
||||
pub receiver_values: Vec<Block>,
|
||||
}
|
||||
@@ -72,11 +62,14 @@ pub mod tests {
|
||||
#[fixture]
|
||||
#[once]
|
||||
pub fn ot_core_data(choice: &Vec<bool>, values: &Vec<[Block; 2]>) -> Data {
|
||||
let mut sender = SenderCore::new(values.len());
|
||||
let sender_setup = sender.setup();
|
||||
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 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();
|
||||
|
||||
@@ -104,13 +97,13 @@ pub mod tests {
|
||||
.map(|(input, choice)| input[*choice as usize])
|
||||
.collect();
|
||||
|
||||
let mut sender = SenderCore::new(s_inputs.len());
|
||||
let sender_setup = sender.setup();
|
||||
let mut sender = DhOtSender::default();
|
||||
let sender_setup = sender.setup(&mut rng);
|
||||
|
||||
let mut receiver = ReceiverCore::new(choice.len());
|
||||
let receiver_setup = receiver.setup(&choice, sender_setup).unwrap();
|
||||
let mut receiver = DhOtReceiver::default();
|
||||
let receiver_choices = receiver.setup(&mut rng, &choice, sender_setup).unwrap();
|
||||
|
||||
let send = sender.send(&s_inputs, receiver_setup).unwrap();
|
||||
let send = sender.send(&s_inputs, receiver_choices).unwrap();
|
||||
let receive = receiver.receive(send).unwrap();
|
||||
assert_eq!(expected, receive);
|
||||
}
|
||||
|
||||
@@ -1,120 +0,0 @@
|
||||
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<R = ChaCha12Rng> {
|
||||
rng: R,
|
||||
count: usize,
|
||||
hashes: Option<Vec<Block>>,
|
||||
choice: Option<Vec<bool>>,
|
||||
state: State,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct ReceiverSetup {
|
||||
pub keys: Vec<RistrettoPoint>,
|
||||
}
|
||||
|
||||
impl ReceiverCore {
|
||||
pub fn new(count: usize) -> Self {
|
||||
Self {
|
||||
rng: ChaCha12Rng::from_entropy(),
|
||||
count,
|
||||
hashes: None,
|
||||
choice: None,
|
||||
state: State::Initialized,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<R: Rng + CryptoRng> ReceiverCore<R> {
|
||||
pub fn new_from_rng(rng: R, count: usize) -> Self {
|
||||
Self {
|
||||
rng,
|
||||
count,
|
||||
hashes: None,
|
||||
choice: None,
|
||||
state: State::Initialized,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<R: Rng + CryptoRng> ReceiveCore for ReceiverCore<R> {
|
||||
fn state(&self) -> State {
|
||||
self.state
|
||||
}
|
||||
|
||||
fn setup(
|
||||
&mut self,
|
||||
choice: &[bool],
|
||||
sender_setup: SenderSetup,
|
||||
) -> Result<ReceiverSetup, ReceiverCoreError> {
|
||||
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<RistrettoPoint>, Vec<Block>) = 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<Vec<Block>, ReceiverCoreError> {
|
||||
if self.state < State::Setup {
|
||||
return Err(ReceiverCoreError::NotSetup);
|
||||
}
|
||||
|
||||
let hashes = self.hashes.as_ref().unwrap();
|
||||
let values: Vec<Block> = 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)
|
||||
}
|
||||
}
|
||||
@@ -1,106 +0,0 @@
|
||||
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<R = ChaCha12Rng> {
|
||||
rng: R,
|
||||
count: usize,
|
||||
// private_key is random "a" in [ref1]
|
||||
private_key: Option<Scalar>,
|
||||
// public_key is A == g^a in [ref1]
|
||||
public_key: Option<RistrettoPoint>,
|
||||
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<R: Rng + CryptoRng> SenderCore<R> {
|
||||
pub fn new_from_rng(rng: R, count: usize) -> Self {
|
||||
Self {
|
||||
rng,
|
||||
count,
|
||||
private_key: None,
|
||||
public_key: None,
|
||||
state: State::Initialized,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<R: Rng + CryptoRng> SendCore for SenderCore<R> {
|
||||
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<SenderPayload, SenderCoreError> {
|
||||
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 })
|
||||
}
|
||||
}
|
||||
27
mpc-core/src/ot/extension/kos15/mod.rs
Normal file
27
mpc-core/src/ot/extension/kos15/mod.rs
Normal file
@@ -0,0 +1,27 @@
|
||||
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]>,
|
||||
}
|
||||
@@ -4,14 +4,18 @@ use rand::{CryptoRng, Rng, RngCore, SeedableRng};
|
||||
use rand_chacha::ChaCha12Rng;
|
||||
use std::convert::TryInto;
|
||||
|
||||
use super::{
|
||||
BaseReceiverSetup, ExtRandomReceiveCore, ExtReceiveCore, ExtReceiverCoreError,
|
||||
ExtSenderPayload, BASE_COUNT,
|
||||
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 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)]
|
||||
@@ -29,26 +33,10 @@ pub enum State {
|
||||
Complete,
|
||||
}
|
||||
|
||||
/// 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<R = ChaCha12Rng, C = Aes128, OT = SenderCore<ChaCha12Rng>> {
|
||||
pub struct Kos15Receiver<R = ChaCha12Rng, C = Aes128> {
|
||||
rng: R,
|
||||
cipher: C,
|
||||
base: OT,
|
||||
base: BaseSender,
|
||||
state: State,
|
||||
count: usize,
|
||||
// seeds are the result of running base OT setup. They are used to seed the
|
||||
@@ -78,14 +66,14 @@ pub struct ExtDerandomize {
|
||||
pub flip: Vec<bool>,
|
||||
}
|
||||
|
||||
impl ExtReceiverCore {
|
||||
impl Kos15Receiver {
|
||||
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: SenderCore::new(BASE_COUNT),
|
||||
base: BaseSender::default(),
|
||||
state: State::Initialized,
|
||||
count,
|
||||
seeds: None,
|
||||
@@ -99,7 +87,7 @@ impl ExtReceiverCore {
|
||||
|
||||
fn decrypt_values<C: BlockCipher<BlockSize = U16> + BlockEncrypt>(
|
||||
cipher: &mut C,
|
||||
encrypted_values: &[[Block; 2]],
|
||||
ciphertexts: &[[Block; 2]],
|
||||
table: &[Vec<u8>],
|
||||
choice: &[bool],
|
||||
) -> Vec<Block> {
|
||||
@@ -108,9 +96,9 @@ fn decrypt_values<C: BlockCipher<BlockSize = U16> + BlockEncrypt>(
|
||||
let t: [u8; 16] = table[j].clone().try_into().unwrap();
|
||||
let t = Block::from(t);
|
||||
let y = if *b {
|
||||
encrypted_values[j][1]
|
||||
ciphertexts[j][1]
|
||||
} else {
|
||||
encrypted_values[j][0]
|
||||
ciphertexts[j][0]
|
||||
};
|
||||
let y = y ^ t.hash_tweak(cipher, j);
|
||||
values.push(y);
|
||||
@@ -118,13 +106,12 @@ fn decrypt_values<C: BlockCipher<BlockSize = U16> + BlockEncrypt>(
|
||||
values
|
||||
}
|
||||
|
||||
impl<R, C, OT> ExtReceiverCore<R, C, OT>
|
||||
impl<R, C> Kos15Receiver<R, C>
|
||||
where
|
||||
R: Rng + CryptoRng,
|
||||
C: BlockCipher<BlockSize = U16> + BlockEncrypt,
|
||||
OT: SendCore,
|
||||
{
|
||||
pub fn new_with_custom(mut rng: R, cipher: C, base: OT, count: usize) -> Self {
|
||||
pub fn new_with_custom(mut rng: R, cipher: C, base: BaseSender, count: usize) -> Self {
|
||||
let cointoss_share = rng.gen();
|
||||
Self {
|
||||
rng,
|
||||
@@ -162,12 +149,18 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<R, C, OT> ExtReceiveCore for ExtReceiverCore<R, C, OT>
|
||||
impl<R, C> ExtReceiveCore for Kos15Receiver<R, C>
|
||||
where
|
||||
R: Rng + CryptoRng + SeedableRng,
|
||||
C: BlockCipher<BlockSize = U16> + 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
|
||||
}
|
||||
@@ -182,7 +175,7 @@ where
|
||||
}
|
||||
self.state = State::BaseSetup;
|
||||
Ok(BaseSenderSetup {
|
||||
setup: self.base.setup(),
|
||||
setup: self.base.setup(&mut self.rng),
|
||||
cointoss_commit: sha256(&self.cointoss_share),
|
||||
})
|
||||
}
|
||||
@@ -199,9 +192,7 @@ where
|
||||
seeds.push([Block::random(&mut self.rng), Block::random(&mut self.rng)]);
|
||||
}
|
||||
|
||||
let base_send = self
|
||||
.base
|
||||
.send(seeds.as_slice(), base_receiver_setup.setup)?;
|
||||
let base_send = self.base.send(&seeds, base_receiver_setup.setup)?;
|
||||
|
||||
self.set_seeds(seeds);
|
||||
let mut result = [0u8; 32];
|
||||
@@ -222,6 +213,7 @@ where
|
||||
&mut self,
|
||||
choice: &[bool],
|
||||
) -> Result<ExtReceiverSetup, ExtReceiverCoreError> {
|
||||
println!("Doing extension setup with {} choices", choice.len());
|
||||
if State::BaseSend != self.state {
|
||||
return Err(ExtReceiverCoreError::BaseOTNotSetup);
|
||||
}
|
||||
@@ -308,6 +300,14 @@ 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,18 +327,23 @@ where
|
||||
_ => return Err(ExtReceiverCoreError::NotSetup),
|
||||
};
|
||||
|
||||
if payload.encrypted_values.len() > choice_state.choice.len() {
|
||||
if payload.ciphertexts.len() > choice_state.choice.len() {
|
||||
println!(
|
||||
"Got {} payload ciphertexts with {} choices",
|
||||
payload.ciphertexts.len(),
|
||||
choice_state.choice.len()
|
||||
);
|
||||
return Err(ExtReceiverCoreError::InvalidPayloadSize);
|
||||
}
|
||||
|
||||
let choice: Vec<bool> = choice_state
|
||||
.choice
|
||||
.drain(..payload.encrypted_values.len())
|
||||
.drain(..payload.ciphertexts.len())
|
||||
.collect();
|
||||
|
||||
let table = self.table.as_mut().ok_or(ExtReceiverCoreError::NotSetup)?;
|
||||
let table: Vec<Vec<u8>> = table.drain(..choice.len()).collect();
|
||||
let values = decrypt_values(&mut self.cipher, &payload.encrypted_values, &table, &choice);
|
||||
let values = decrypt_values(&mut self.cipher, &payload.ciphertexts, &table, &choice);
|
||||
|
||||
if (choice_state.choice.len() == 0) && (choice_state.derandomized.len() == 0) {
|
||||
self.state = State::Complete;
|
||||
@@ -348,13 +353,14 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<R, C, OT> ExtRandomReceiveCore for ExtReceiverCore<R, C, OT>
|
||||
impl<R, C> ExtRandomReceiveCore for Kos15Receiver<R, C>
|
||||
where
|
||||
R: Rng + CryptoRng + SeedableRng,
|
||||
C: BlockCipher<BlockSize = U16> + BlockEncrypt,
|
||||
OT: SendCore,
|
||||
{
|
||||
fn extension_setup(&mut self) -> Result<ExtReceiverSetup, ExtReceiverCoreError> {
|
||||
type ExtDerandomize = ExtDerandomize;
|
||||
|
||||
fn rand_extension_setup(&mut self) -> Result<ExtReceiverSetup, ExtReceiverCoreError> {
|
||||
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];
|
||||
@@ -362,6 +368,7 @@ where
|
||||
let mut choice = u8vec_to_boolvec(&choice);
|
||||
choice.resize(n, false);
|
||||
|
||||
println!("In rand_extension_setup");
|
||||
ExtReceiveCore::extension_setup(self, &choice)
|
||||
}
|
||||
|
||||
@@ -387,24 +394,27 @@ where
|
||||
Ok(ExtDerandomize { flip })
|
||||
}
|
||||
|
||||
fn receive(&mut self, payload: ExtSenderPayload) -> Result<Vec<Block>, ExtReceiverCoreError> {
|
||||
fn rand_receive(
|
||||
&mut self,
|
||||
payload: ExtSenderPayload,
|
||||
) -> Result<Vec<Block>, ExtReceiverCoreError> {
|
||||
let choice_state = match &mut self.state {
|
||||
State::Setup(state) => state,
|
||||
State::Complete => return Err(ExtReceiverCoreError::AlreadyComplete),
|
||||
_ => return Err(ExtReceiverCoreError::NotSetup),
|
||||
};
|
||||
|
||||
if payload.encrypted_values.len() > choice_state.derandomized.len() {
|
||||
if payload.ciphertexts.len() > choice_state.derandomized.len() {
|
||||
return Err(ExtReceiverCoreError::NotDerandomized);
|
||||
}
|
||||
|
||||
let choice: Vec<bool> = choice_state
|
||||
.derandomized
|
||||
.drain(..payload.encrypted_values.len())
|
||||
.drain(..payload.ciphertexts.len())
|
||||
.collect();
|
||||
let table = self.table.as_mut().ok_or(ExtReceiverCoreError::NotSetup)?;
|
||||
let table: Vec<Vec<u8>> = table.drain(..choice.len()).collect();
|
||||
let values = decrypt_values(&mut self.cipher, &payload.encrypted_values, &table, &choice);
|
||||
let values = decrypt_values(&mut self.cipher, &payload.ciphertexts, &table, &choice);
|
||||
|
||||
if (choice_state.choice.len() == 0) && (choice_state.derandomized.len() == 0) {
|
||||
self.state = State::Complete;
|
||||
@@ -1,19 +1,20 @@
|
||||
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 rand::{thread_rng, Rng, RngCore, SeedableRng};
|
||||
use clmul::Clmul;
|
||||
use rand::{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,
|
||||
@@ -23,18 +24,10 @@ pub enum State {
|
||||
Complete,
|
||||
}
|
||||
|
||||
/// 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<C = Aes128, OT = ReceiverCore<ChaCha12Rng>> {
|
||||
pub struct Kos15Sender<C = Aes128> {
|
||||
rng: ChaCha12Rng,
|
||||
cipher: C,
|
||||
base: OT,
|
||||
base: BaseReceiver,
|
||||
state: State,
|
||||
count: usize,
|
||||
sent: usize,
|
||||
@@ -59,9 +52,20 @@ pub struct ExtSenderCore<C = Aes128, OT = ReceiverCore<ChaCha12Rng>> {
|
||||
cointoss_random: Option<[u8; 32]>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct ExtSenderPayload {
|
||||
pub encrypted_values: Vec<[Block; 2]>,
|
||||
/// 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],
|
||||
}
|
||||
|
||||
// Having 2 messages that Receiver chooses from, we encrypt each message with
|
||||
@@ -74,7 +78,7 @@ fn encrypt_values<C: BlockCipher<BlockSize = U16> + BlockEncrypt>(
|
||||
base_choice: &[bool],
|
||||
flip: Option<Vec<bool>>,
|
||||
) -> Vec<[Block; 2]> {
|
||||
let mut encrypted_values: Vec<[Block; 2]> = Vec::with_capacity(table.len());
|
||||
let mut ciphertexts: 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
|
||||
@@ -86,22 +90,26 @@ fn encrypt_values<C: BlockCipher<BlockSize = U16> + BlockEncrypt>(
|
||||
let q = Block::from(q);
|
||||
let masks = [q.hash_tweak(cipher, j), (q ^ delta).hash_tweak(cipher, j)];
|
||||
if flip {
|
||||
encrypted_values.push([input[0] ^ masks[1], input[1] ^ masks[0]]);
|
||||
ciphertexts.push([input[0] ^ masks[1], input[1] ^ masks[0]]);
|
||||
} else {
|
||||
encrypted_values.push([input[0] ^ masks[0], input[1] ^ masks[1]]);
|
||||
ciphertexts.push([input[0] ^ masks[0], input[1] ^ masks[1]]);
|
||||
}
|
||||
}
|
||||
encrypted_values
|
||||
ciphertexts
|
||||
}
|
||||
|
||||
impl ExtSenderCore {
|
||||
impl Kos15Sender {
|
||||
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: ReceiverCore::new(BASE_COUNT),
|
||||
base: BaseReceiver::default(),
|
||||
state: State::Initialized,
|
||||
count,
|
||||
sent: 0,
|
||||
@@ -109,23 +117,26 @@ impl ExtSenderCore {
|
||||
seeds: None,
|
||||
rngs: None,
|
||||
table: None,
|
||||
cointoss_share: rng.gen(),
|
||||
cointoss_share,
|
||||
receiver_cointoss_commit: None,
|
||||
cointoss_random: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<C, OT> ExtSenderCore<C, OT>
|
||||
impl<C> Kos15Sender<C>
|
||||
where
|
||||
C: BlockCipher<BlockSize = U16> + BlockEncrypt,
|
||||
OT: ReceiveCore,
|
||||
{
|
||||
pub fn new_from_custom(cipher: C, base: OT, count: usize) -> Self {
|
||||
let mut rng = thread_rng();
|
||||
pub fn new_from_custom(cipher: C, base: BaseReceiver, 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,
|
||||
base,
|
||||
state: State::Initialized,
|
||||
@@ -135,7 +146,7 @@ where
|
||||
seeds: None,
|
||||
rngs: None,
|
||||
table: None,
|
||||
cointoss_share: rng.gen(),
|
||||
cointoss_share,
|
||||
receiver_cointoss_commit: None,
|
||||
cointoss_random: None,
|
||||
}
|
||||
@@ -158,13 +169,19 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<C, OT> ExtSendCore for ExtSenderCore<C, OT>
|
||||
impl<C> ExtSendCore for Kos15Sender<C>
|
||||
where
|
||||
C: BlockCipher<BlockSize = U16> + BlockEncrypt,
|
||||
OT: ReceiveCore,
|
||||
{
|
||||
fn state(&self) -> State {
|
||||
self.state
|
||||
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 is_complete(&self) -> bool {
|
||||
@@ -183,7 +200,7 @@ where
|
||||
Ok(BaseReceiverSetup {
|
||||
setup: self
|
||||
.base
|
||||
.setup(&self.base_choice, base_sender_setup.setup)?,
|
||||
.setup(&mut self.rng, &self.base_choice, base_sender_setup.setup)?,
|
||||
cointoss_share: self.cointoss_share,
|
||||
})
|
||||
}
|
||||
@@ -291,7 +308,7 @@ where
|
||||
// KOS check
|
||||
qs.drain(qs.len() - 256..);
|
||||
self.table = Some(qs);
|
||||
self.state = State::Setup;
|
||||
self.state = State::Initialized;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -300,31 +317,31 @@ where
|
||||
return Err(ExtSenderCoreError::InvalidInputLength);
|
||||
}
|
||||
match self.state {
|
||||
State::Setup => {}
|
||||
State::Initialized => {}
|
||||
State::Complete => return Err(ExtSenderCoreError::AlreadyComplete),
|
||||
_ => return Err(ExtSenderCoreError::NotSetup),
|
||||
};
|
||||
|
||||
let table = self.table.as_mut().ok_or(ExtSenderCoreError::NotSetup)?;
|
||||
let table: Vec<Vec<u8>> = table.drain(..inputs.len()).collect();
|
||||
let encrypted_values =
|
||||
encrypt_values(&mut self.cipher, inputs, &table, &self.base_choice, None);
|
||||
let ciphertexts = 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 { encrypted_values })
|
||||
Ok(ExtSenderPayload { ciphertexts })
|
||||
}
|
||||
}
|
||||
|
||||
impl<C, OT> ExtRandomSendCore for ExtSenderCore<C, OT>
|
||||
impl<C> ExtRandomSendCore for Kos15Sender<C>
|
||||
where
|
||||
C: BlockCipher<BlockSize = U16> + BlockEncrypt,
|
||||
OT: ReceiveCore,
|
||||
{
|
||||
fn send(
|
||||
type ExtDerandomize = ExtDerandomize;
|
||||
|
||||
fn rand_send(
|
||||
&mut self,
|
||||
inputs: &[[Block; 2]],
|
||||
derandomize: ExtDerandomize,
|
||||
@@ -333,14 +350,14 @@ where
|
||||
return Err(ExtSenderCoreError::InvalidInputLength);
|
||||
}
|
||||
match self.state {
|
||||
State::Setup => {}
|
||||
State::Initialized => {}
|
||||
State::Complete => return Err(ExtSenderCoreError::AlreadyComplete),
|
||||
_ => return Err(ExtSenderCoreError::NotSetup),
|
||||
};
|
||||
|
||||
let table = self.table.as_mut().ok_or(ExtSenderCoreError::NotSetup)?;
|
||||
let table: Vec<Vec<u8>> = table.drain(..inputs.len()).collect();
|
||||
let encrypted_values = encrypt_values(
|
||||
let ciphertexts = encrypt_values(
|
||||
&mut self.cipher,
|
||||
inputs,
|
||||
&table,
|
||||
@@ -353,6 +370,6 @@ where
|
||||
self.state = State::Complete;
|
||||
}
|
||||
|
||||
Ok(ExtSenderPayload { encrypted_values })
|
||||
Ok(ExtSenderPayload { ciphertexts })
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,11 @@
|
||||
//! This crate implements the KOS15 Oblivious Transfer extension protocol.
|
||||
|
||||
pub mod errors;
|
||||
pub mod receiver;
|
||||
pub mod sender;
|
||||
pub mod kos15;
|
||||
|
||||
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;
|
||||
|
||||
@@ -20,119 +14,100 @@ pub const BASE_COUNT: usize = 128;
|
||||
const K: usize = 40;
|
||||
|
||||
pub trait ExtSendCore {
|
||||
fn state(&self) -> sender::State;
|
||||
type State;
|
||||
type BaseSenderSetup;
|
||||
type BaseSenderPayload;
|
||||
type BaseReceiverSetup;
|
||||
type ExtSenderPayload;
|
||||
type ExtReceiverSetup;
|
||||
|
||||
fn state(&self) -> &Self::State;
|
||||
|
||||
//
|
||||
fn base_setup(
|
||||
&mut self,
|
||||
base_sender_setup: BaseSenderSetup,
|
||||
) -> Result<BaseReceiverSetup, ExtSenderCoreError>;
|
||||
base_sender_setup: Self::BaseSenderSetup,
|
||||
) -> Result<Self::BaseReceiverSetup, ExtSenderCoreError>;
|
||||
|
||||
fn base_receive(&mut self, payload: BaseSenderPayload) -> Result<(), ExtSenderCoreError>;
|
||||
fn base_receive(&mut self, payload: Self::BaseSenderPayload) -> Result<(), ExtSenderCoreError>;
|
||||
|
||||
fn extension_setup(
|
||||
&mut self,
|
||||
receiver_setup: ExtReceiverSetup,
|
||||
receiver_setup: Self::ExtReceiverSetup,
|
||||
) -> Result<(), ExtSenderCoreError>;
|
||||
|
||||
fn send(&mut self, inputs: &[[Block; 2]]) -> Result<ExtSenderPayload, ExtSenderCoreError>;
|
||||
fn send(&mut self, inputs: &[[Block; 2]])
|
||||
-> Result<Self::ExtSenderPayload, ExtSenderCoreError>;
|
||||
|
||||
fn is_complete(&self) -> bool;
|
||||
}
|
||||
|
||||
pub trait ExtRandomSendCore: ExtSendCore {
|
||||
fn state(&self) -> sender::State {
|
||||
ExtSendCore::state(self)
|
||||
}
|
||||
type ExtDerandomize;
|
||||
|
||||
// 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<BaseReceiverSetup, ExtSenderCoreError> {
|
||||
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(
|
||||
fn rand_send(
|
||||
&mut self,
|
||||
inputs: &[[Block; 2]],
|
||||
derandomize: ExtDerandomize,
|
||||
) -> Result<ExtSenderPayload, ExtSenderCoreError>;
|
||||
|
||||
fn is_complete(&self) -> bool {
|
||||
ExtSendCore::is_complete(self)
|
||||
}
|
||||
derandomize: Self::ExtDerandomize,
|
||||
) -> Result<Self::ExtSenderPayload, ExtSenderCoreError>;
|
||||
}
|
||||
|
||||
pub trait ExtReceiveCore {
|
||||
fn state(&self) -> &receiver::State;
|
||||
type State;
|
||||
type BaseSenderSetup;
|
||||
type BaseSenderPayload;
|
||||
type BaseReceiverSetup;
|
||||
type ExtSenderPayload;
|
||||
type ExtReceiverSetup;
|
||||
|
||||
fn state(&self) -> &Self::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<BaseSenderSetup, ExtReceiverCoreError>;
|
||||
fn base_setup(&mut self) -> Result<Self::BaseSenderSetup, ExtReceiverCoreError>;
|
||||
|
||||
fn base_send(
|
||||
&mut self,
|
||||
base_receiver_setup: BaseReceiverSetup,
|
||||
) -> Result<BaseSenderPayload, ExtReceiverCoreError>;
|
||||
base_receiver_setup: Self::BaseReceiverSetup,
|
||||
) -> Result<Self::BaseSenderPayload, ExtReceiverCoreError>;
|
||||
|
||||
fn extension_setup(
|
||||
&mut self,
|
||||
choice: &[bool],
|
||||
) -> Result<ExtReceiverSetup, ExtReceiverCoreError>;
|
||||
) -> Result<Self::ExtReceiverSetup, ExtReceiverCoreError>;
|
||||
|
||||
fn receive(&mut self, payload: ExtSenderPayload) -> Result<Vec<Block>, ExtReceiverCoreError>;
|
||||
fn receive(
|
||||
&mut self,
|
||||
payload: Self::ExtSenderPayload,
|
||||
) -> Result<Vec<Block>, ExtReceiverCoreError>;
|
||||
|
||||
fn is_complete(&self) -> bool;
|
||||
}
|
||||
|
||||
pub trait ExtRandomReceiveCore: ExtReceiveCore {
|
||||
fn state(&self) -> &receiver::State {
|
||||
ExtReceiveCore::state(self)
|
||||
}
|
||||
type ExtDerandomize;
|
||||
|
||||
// Receiver in OT extension acts as Sender in base OT and sends the first
|
||||
// base OT setup message.
|
||||
fn base_setup(&mut self) -> Result<BaseSenderSetup, ExtReceiverCoreError> {
|
||||
ExtReceiveCore::base_setup(self)
|
||||
}
|
||||
fn rand_extension_setup(&mut self) -> Result<Self::ExtReceiverSetup, ExtReceiverCoreError>;
|
||||
|
||||
fn base_send(
|
||||
fn rand_receive(
|
||||
&mut self,
|
||||
base_receiver_setup: BaseReceiverSetup,
|
||||
) -> Result<BaseSenderPayload, ExtReceiverCoreError> {
|
||||
ExtReceiveCore::base_send(self, base_receiver_setup)
|
||||
}
|
||||
payload: Self::ExtSenderPayload,
|
||||
) -> Result<Vec<Block>, ExtReceiverCoreError>;
|
||||
|
||||
fn extension_setup(&mut self) -> Result<ExtReceiverSetup, ExtReceiverCoreError>;
|
||||
|
||||
fn derandomize(&mut self, choice: &[bool]) -> Result<ExtDerandomize, ExtReceiverCoreError>;
|
||||
|
||||
fn receive(&mut self, payload: ExtSenderPayload) -> Result<Vec<Block>, ExtReceiverCoreError>;
|
||||
|
||||
fn is_complete(&self) -> bool {
|
||||
ExtReceiveCore::is_complete(self)
|
||||
}
|
||||
fn derandomize(
|
||||
&mut self,
|
||||
choice: &[bool],
|
||||
) -> Result<Self::ExtDerandomize, ExtReceiverCoreError>;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub mod tests {
|
||||
use super::errors::{ExtReceiverCoreError, ExtSenderCoreError};
|
||||
use super::{
|
||||
BaseReceiverSetup, BaseSenderPayload, BaseSenderSetup, ExtDerandomize, ExtReceiverCore,
|
||||
ExtSenderCore, ExtSenderPayload,
|
||||
errors::{ExtReceiverCoreError, ExtSenderCoreError},
|
||||
kos15::{
|
||||
BaseReceiverSetup, BaseSenderPayload, BaseSenderSetup, ExtDerandomize,
|
||||
ExtSenderPayload, Kos15Receiver, Kos15Sender,
|
||||
},
|
||||
ExtReceiveCore, ExtSendCore,
|
||||
};
|
||||
use crate::utils::u8vec_to_boolvec;
|
||||
use crate::Block;
|
||||
@@ -157,11 +132,12 @@ pub mod tests {
|
||||
#[once]
|
||||
pub fn ot_ext_core_data(choice: &Vec<bool>, values: &Vec<[Block; 2]>) -> Data {
|
||||
use crate::ot::extension::{
|
||||
ExtReceiveCore, ExtReceiverCore, ExtSendCore, ExtSenderCore,
|
||||
kos15::{Kos15Receiver, Kos15Sender},
|
||||
ExtReceiveCore, ExtSendCore,
|
||||
};
|
||||
|
||||
let mut sender = ExtSenderCore::new(values.len());
|
||||
let mut receiver = ExtReceiverCore::new(choice.len());
|
||||
let mut sender = Kos15Sender::new(values.len());
|
||||
let mut receiver = Kos15Receiver::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();
|
||||
@@ -175,20 +151,20 @@ pub mod tests {
|
||||
}
|
||||
|
||||
#[fixture]
|
||||
fn receiver() -> ExtReceiverCore {
|
||||
ExtReceiverCore::new(16)
|
||||
fn receiver() -> Kos15Receiver {
|
||||
Kos15Receiver::new(16)
|
||||
}
|
||||
|
||||
#[fixture]
|
||||
fn sender() -> ExtSenderCore {
|
||||
ExtSenderCore::new(16)
|
||||
fn sender() -> Kos15Sender {
|
||||
Kos15Sender::new(16)
|
||||
}
|
||||
|
||||
#[fixture]
|
||||
fn pair_base_setup(
|
||||
mut sender: ExtSenderCore,
|
||||
mut receiver: ExtReceiverCore,
|
||||
) -> (ExtSenderCore, ExtReceiverCore) {
|
||||
mut sender: Kos15Sender,
|
||||
mut receiver: Kos15Receiver,
|
||||
) -> (Kos15Sender, Kos15Receiver) {
|
||||
use super::{ExtReceiveCore, ExtSendCore};
|
||||
let base_sender_setup = receiver.base_setup().unwrap();
|
||||
let base_receiver_setup = sender.base_setup(base_sender_setup).unwrap();
|
||||
@@ -199,10 +175,9 @@ pub mod tests {
|
||||
|
||||
#[fixture]
|
||||
fn random_pair_base_setup(
|
||||
mut sender: ExtSenderCore,
|
||||
mut receiver: ExtReceiverCore,
|
||||
) -> (ExtSenderCore, ExtReceiverCore) {
|
||||
use super::{ExtRandomReceiveCore, ExtRandomSendCore};
|
||||
mut sender: Kos15Sender,
|
||||
mut receiver: Kos15Receiver,
|
||||
) -> (Kos15Sender, Kos15Receiver) {
|
||||
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();
|
||||
@@ -211,7 +186,7 @@ pub mod tests {
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
fn test_ext_ot(pair_base_setup: (ExtSenderCore, ExtReceiverCore)) {
|
||||
fn test_ext_ot(pair_base_setup: (Kos15Sender, Kos15Receiver)) {
|
||||
use super::{ExtReceiveCore, ExtSendCore};
|
||||
|
||||
let (mut sender, mut receiver) = pair_base_setup;
|
||||
@@ -241,7 +216,7 @@ pub mod tests {
|
||||
|
||||
#[rstest]
|
||||
// Test that the cointoss check fails on wrong data
|
||||
fn test_ext_ot_cointoss_failure(mut sender: ExtSenderCore, mut receiver: ExtReceiverCore) {
|
||||
fn test_ext_ot_cointoss_failure(mut sender: Kos15Sender, mut receiver: Kos15Receiver) {
|
||||
use super::{ExtReceiveCore, ExtSendCore};
|
||||
|
||||
let mut base_sender_setup = receiver.base_setup().unwrap();
|
||||
@@ -254,7 +229,7 @@ pub mod tests {
|
||||
|
||||
#[rstest]
|
||||
// Test that the KOS15 check fails on wrong data
|
||||
fn test_ext_ot_kos_failure(pair_base_setup: (ExtSenderCore, ExtReceiverCore)) {
|
||||
fn test_ext_ot_kos_failure(pair_base_setup: (Kos15Sender, Kos15Receiver)) {
|
||||
use super::{ExtReceiveCore, ExtSendCore};
|
||||
|
||||
let (mut sender, mut receiver) = pair_base_setup;
|
||||
@@ -271,7 +246,7 @@ pub mod tests {
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
fn test_ext_ot_batch(pair_base_setup: (ExtSenderCore, ExtReceiverCore)) {
|
||||
fn test_ext_ot_batch(pair_base_setup: (Kos15Sender, Kos15Receiver)) {
|
||||
use super::{ExtReceiveCore, ExtSendCore};
|
||||
|
||||
let (mut sender, mut receiver) = pair_base_setup;
|
||||
@@ -301,7 +276,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 {
|
||||
encrypted_values: vec![[Block::random(&mut rng), Block::random(&mut rng)]],
|
||||
ciphertexts: vec![[Block::random(&mut rng), Block::random(&mut rng)]],
|
||||
};
|
||||
let res = receiver.receive(p);
|
||||
assert_eq!(res, Err(ExtReceiverCoreError::AlreadyComplete));
|
||||
@@ -316,7 +291,7 @@ pub mod tests {
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
fn test_ext_random_ot(random_pair_base_setup: (ExtSenderCore, ExtReceiverCore)) {
|
||||
fn test_ext_random_ot(random_pair_base_setup: (Kos15Sender, Kos15Receiver)) {
|
||||
use super::{ExtRandomReceiveCore, ExtRandomSendCore};
|
||||
|
||||
let (mut sender, mut receiver) = random_pair_base_setup;
|
||||
@@ -329,13 +304,13 @@ pub mod tests {
|
||||
.map(|_| [Block::random(&mut rng), Block::random(&mut rng)])
|
||||
.collect();
|
||||
|
||||
let receiver_setup = receiver.extension_setup().unwrap();
|
||||
let receiver_setup = receiver.rand_extension_setup().unwrap();
|
||||
sender.extension_setup(receiver_setup).unwrap();
|
||||
|
||||
let derandomize = receiver.derandomize(&choice).unwrap();
|
||||
|
||||
let payload = sender.send(&inputs, derandomize).unwrap();
|
||||
let receive = receiver.receive(payload).unwrap();
|
||||
let payload = sender.rand_send(&inputs, derandomize).unwrap();
|
||||
let receive = receiver.rand_receive(payload).unwrap();
|
||||
|
||||
let expected: Vec<Block> = inputs
|
||||
.iter()
|
||||
@@ -347,7 +322,7 @@ pub mod tests {
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
fn test_ext_random_ot_batch(random_pair_base_setup: (ExtSenderCore, ExtReceiverCore)) {
|
||||
fn test_ext_random_ot_batch(random_pair_base_setup: (Kos15Sender, Kos15Receiver)) {
|
||||
use super::{ExtRandomReceiveCore, ExtRandomSendCore};
|
||||
|
||||
let (mut sender, mut receiver) = random_pair_base_setup;
|
||||
@@ -360,7 +335,7 @@ pub mod tests {
|
||||
.map(|_| [Block::random(&mut rng), Block::random(&mut rng)])
|
||||
.collect();
|
||||
|
||||
let receiver_setup = receiver.extension_setup().unwrap();
|
||||
let receiver_setup = receiver.rand_extension_setup().unwrap();
|
||||
sender.extension_setup(receiver_setup).unwrap();
|
||||
|
||||
let mut received: Vec<Block> = Vec::new();
|
||||
@@ -368,18 +343,18 @@ pub mod tests {
|
||||
assert!(!sender.is_complete());
|
||||
assert!(!receiver.is_complete());
|
||||
let derandomize = receiver.derandomize(&choice).unwrap();
|
||||
let payload = sender.send(&input, derandomize).unwrap();
|
||||
received.append(&mut receiver.receive(payload).unwrap());
|
||||
let payload = sender.rand_send(&input, derandomize).unwrap();
|
||||
received.append(&mut receiver.rand_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.send(&[[Block::random(&mut rng); 2]], d);
|
||||
let res = sender.rand_send(&[[Block::random(&mut rng); 2]], d);
|
||||
assert_eq!(res, Err(ExtSenderCoreError::InvalidInputLength));
|
||||
let p = ExtSenderPayload {
|
||||
encrypted_values: vec![[Block::random(&mut rng); 2]],
|
||||
ciphertexts: vec![[Block::random(&mut rng); 2]],
|
||||
};
|
||||
let res = receiver.receive(p);
|
||||
assert_eq!(res, Err(ExtReceiverCoreError::AlreadyComplete));
|
||||
|
||||
@@ -5,14 +5,14 @@ pub use base::*;
|
||||
pub use extension::*;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Message {
|
||||
SenderSetup(SenderSetup),
|
||||
BaseSenderSetup(BaseSenderSetup),
|
||||
SenderPayload(SenderPayload),
|
||||
BaseSenderPayload(BaseSenderPayload),
|
||||
ReceiverSetup(ReceiverSetup),
|
||||
BaseReceiverSetup(BaseReceiverSetup),
|
||||
ExtReceiverSetup(ExtReceiverSetup),
|
||||
ExtDerandomize(ExtDerandomize),
|
||||
ExtSenderPayload(ExtSenderPayload),
|
||||
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),
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#![cfg(feature = "ot")]
|
||||
|
||||
pub use crate::ot;
|
||||
pub use crate::ot::{self, dh_ot, kos15};
|
||||
use crate::utils::parse_ristretto_key;
|
||||
use std::convert::{TryFrom, TryInto};
|
||||
use std::io::{Error, ErrorKind};
|
||||
@@ -9,34 +9,36 @@ include!(concat!(env!("OUT_DIR"), "/core.ot.rs"));
|
||||
|
||||
pub use message::Msg;
|
||||
|
||||
impl From<ot::Message> for Message {
|
||||
impl From<ot::Kos15Message> for Message {
|
||||
#[inline]
|
||||
fn from(m: ot::Message) -> Self {
|
||||
fn from(m: ot::Kos15Message) -> Self {
|
||||
Self {
|
||||
msg: Some(match m {
|
||||
ot::Message::ReceiverSetup(msg) => {
|
||||
ot::Kos15Message::ReceiverSetup(msg) => {
|
||||
message::Msg::ReceiverSetup(ReceiverSetup::from(msg))
|
||||
}
|
||||
ot::Message::SenderSetup(msg) => message::Msg::SenderSetup(SenderSetup::from(msg)),
|
||||
ot::Message::SenderPayload(msg) => {
|
||||
ot::Kos15Message::SenderSetup(msg) => {
|
||||
message::Msg::SenderSetup(SenderSetup::from(msg))
|
||||
}
|
||||
ot::Kos15Message::SenderPayload(msg) => {
|
||||
message::Msg::SenderPayload(SenderPayload::from(msg))
|
||||
}
|
||||
ot::Message::ExtReceiverSetup(msg) => {
|
||||
ot::Kos15Message::ExtReceiverSetup(msg) => {
|
||||
message::Msg::ExtReceiverSetup(ExtReceiverSetup::from(msg))
|
||||
}
|
||||
ot::Message::ExtDerandomize(msg) => {
|
||||
ot::Kos15Message::ExtDerandomize(msg) => {
|
||||
message::Msg::ExtDerandomize(ExtDerandomize::from(msg))
|
||||
}
|
||||
ot::Message::ExtSenderPayload(msg) => {
|
||||
ot::Kos15Message::ExtSenderPayload(msg) => {
|
||||
message::Msg::ExtSenderPayload(ExtSenderPayload::from(msg))
|
||||
}
|
||||
ot::Message::BaseSenderSetup(msg) => {
|
||||
ot::Kos15Message::BaseSenderSetup(msg) => {
|
||||
message::Msg::BaseSenderSetup(BaseSenderSetup::from(msg))
|
||||
}
|
||||
ot::Message::BaseReceiverSetup(msg) => {
|
||||
ot::Kos15Message::BaseReceiverSetup(msg) => {
|
||||
message::Msg::BaseReceiverSetup(BaseReceiverSetup::from(msg))
|
||||
}
|
||||
ot::Message::BaseSenderPayload(msg) => {
|
||||
ot::Kos15Message::BaseSenderPayload(msg) => {
|
||||
message::Msg::BaseSenderPayload(BaseSenderPayload::from(msg))
|
||||
}
|
||||
}),
|
||||
@@ -44,38 +46,38 @@ impl From<ot::Message> for Message {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<Message> for ot::Message {
|
||||
impl TryFrom<Message> for ot::Kos15Message {
|
||||
type Error = std::io::Error;
|
||||
#[inline]
|
||||
fn try_from(m: Message) -> Result<Self, Self::Error> {
|
||||
if let Some(msg) = m.msg {
|
||||
let m = match msg {
|
||||
message::Msg::ReceiverSetup(msg) => {
|
||||
ot::Message::ReceiverSetup(ot::ReceiverSetup::try_from(msg)?)
|
||||
ot::Kos15Message::ReceiverSetup(dh_ot::ReceiverChoices::try_from(msg)?)
|
||||
}
|
||||
message::Msg::SenderSetup(msg) => {
|
||||
ot::Message::SenderSetup(ot::SenderSetup::try_from(msg)?)
|
||||
ot::Kos15Message::SenderSetup(dh_ot::SenderSetup::try_from(msg)?)
|
||||
}
|
||||
message::Msg::SenderPayload(msg) => {
|
||||
ot::Message::SenderPayload(ot::SenderPayload::from(msg))
|
||||
ot::Kos15Message::SenderPayload(dh_ot::SenderPayload::from(msg))
|
||||
}
|
||||
message::Msg::ExtReceiverSetup(msg) => {
|
||||
ot::Message::ExtReceiverSetup(ot::ExtReceiverSetup::try_from(msg)?)
|
||||
ot::Kos15Message::ExtReceiverSetup(kos15::ExtReceiverSetup::try_from(msg)?)
|
||||
}
|
||||
message::Msg::ExtDerandomize(msg) => {
|
||||
ot::Message::ExtDerandomize(ot::ExtDerandomize::from(msg))
|
||||
ot::Kos15Message::ExtDerandomize(kos15::ExtDerandomize::from(msg))
|
||||
}
|
||||
message::Msg::ExtSenderPayload(msg) => {
|
||||
ot::Message::ExtSenderPayload(ot::ExtSenderPayload::from(msg))
|
||||
ot::Kos15Message::ExtSenderPayload(kos15::ExtSenderPayload::from(msg))
|
||||
}
|
||||
message::Msg::BaseSenderSetup(msg) => {
|
||||
ot::Message::BaseSenderSetup(ot::BaseSenderSetup::try_from(msg)?)
|
||||
ot::Kos15Message::BaseSenderSetup(kos15::BaseSenderSetup::try_from(msg)?)
|
||||
}
|
||||
message::Msg::BaseReceiverSetup(msg) => {
|
||||
ot::Message::BaseReceiverSetup(ot::BaseReceiverSetup::try_from(msg)?)
|
||||
ot::Kos15Message::BaseReceiverSetup(kos15::BaseReceiverSetup::try_from(msg)?)
|
||||
}
|
||||
message::Msg::BaseSenderPayload(msg) => {
|
||||
ot::Message::BaseSenderPayload(ot::BaseSenderPayload::try_from(msg)?)
|
||||
ot::Kos15Message::BaseSenderPayload(kos15::BaseSenderPayload::try_from(msg)?)
|
||||
}
|
||||
};
|
||||
Ok(m)
|
||||
@@ -85,16 +87,16 @@ impl TryFrom<Message> for ot::Message {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ot::SenderSetup> for SenderSetup {
|
||||
impl From<dh_ot::SenderSetup> for SenderSetup {
|
||||
#[inline]
|
||||
fn from(s: ot::SenderSetup) -> Self {
|
||||
fn from(s: dh_ot::SenderSetup) -> Self {
|
||||
Self {
|
||||
public_key: super::RistrettoPoint::from(s.public_key),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<SenderSetup> for ot::SenderSetup {
|
||||
impl TryFrom<SenderSetup> for dh_ot::SenderSetup {
|
||||
type Error = Error;
|
||||
|
||||
#[inline]
|
||||
@@ -105,12 +107,12 @@ impl TryFrom<SenderSetup> for ot::SenderSetup {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ot::SenderPayload> for SenderPayload {
|
||||
impl From<dh_ot::SenderPayload> for SenderPayload {
|
||||
#[inline]
|
||||
fn from(p: ot::SenderPayload) -> Self {
|
||||
fn from(p: dh_ot::SenderPayload) -> Self {
|
||||
Self {
|
||||
encrypted_values: p
|
||||
.encrypted_values
|
||||
ciphertexts: p
|
||||
.ciphertexts
|
||||
.into_iter()
|
||||
.map(|b| super::LabelPair {
|
||||
low: super::Block::from(b[0]),
|
||||
@@ -121,12 +123,12 @@ impl From<ot::SenderPayload> for SenderPayload {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<SenderPayload> for ot::SenderPayload {
|
||||
impl From<SenderPayload> for dh_ot::SenderPayload {
|
||||
#[inline]
|
||||
fn from(p: SenderPayload) -> Self {
|
||||
Self {
|
||||
encrypted_values: p
|
||||
.encrypted_values
|
||||
ciphertexts: p
|
||||
.ciphertexts
|
||||
.into_iter()
|
||||
.map(|pair| [crate::Block::from(pair.low), crate::Block::from(pair.high)])
|
||||
.collect(),
|
||||
@@ -134,12 +136,12 @@ impl From<SenderPayload> for ot::SenderPayload {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ot::ReceiverSetup> for ReceiverSetup {
|
||||
impl From<dh_ot::ReceiverChoices> for ReceiverSetup {
|
||||
#[inline]
|
||||
fn from(s: ot::ReceiverSetup) -> Self {
|
||||
fn from(s: dh_ot::ReceiverChoices) -> Self {
|
||||
Self {
|
||||
keys: s
|
||||
.keys
|
||||
blinded_choices: s
|
||||
.blinded_choices
|
||||
.into_iter()
|
||||
.map(super::RistrettoPoint::from)
|
||||
.collect(),
|
||||
@@ -147,23 +149,23 @@ impl From<ot::ReceiverSetup> for ReceiverSetup {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<ReceiverSetup> for ot::ReceiverSetup {
|
||||
impl TryFrom<ReceiverSetup> for dh_ot::ReceiverChoices {
|
||||
type Error = Error;
|
||||
|
||||
#[inline]
|
||||
fn try_from(s: ReceiverSetup) -> Result<Self, Self::Error> {
|
||||
let mut keys: Vec<curve25519_dalek::ristretto::RistrettoPoint> =
|
||||
Vec::with_capacity(s.keys.len());
|
||||
for key in s.keys.into_iter() {
|
||||
keys.push(parse_ristretto_key(key.point)?);
|
||||
let mut blinded_choices: Vec<curve25519_dalek::ristretto::RistrettoPoint> =
|
||||
Vec::with_capacity(s.blinded_choices.len());
|
||||
for key in s.blinded_choices.into_iter() {
|
||||
blinded_choices.push(parse_ristretto_key(key.point)?);
|
||||
}
|
||||
Ok(Self { keys })
|
||||
Ok(Self { blinded_choices })
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ot::ExtReceiverSetup> for ExtReceiverSetup {
|
||||
impl From<kos15::ExtReceiverSetup> for ExtReceiverSetup {
|
||||
#[inline]
|
||||
fn from(s: ot::ExtReceiverSetup) -> Self {
|
||||
fn from(s: kos15::ExtReceiverSetup) -> Self {
|
||||
Self {
|
||||
ncols: s.ncols as u32,
|
||||
table: s.table,
|
||||
@@ -174,7 +176,7 @@ impl From<ot::ExtReceiverSetup> for ExtReceiverSetup {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<ExtReceiverSetup> for ot::ExtReceiverSetup {
|
||||
impl TryFrom<ExtReceiverSetup> for kos15::ExtReceiverSetup {
|
||||
type Error = Error;
|
||||
|
||||
#[inline]
|
||||
@@ -189,26 +191,26 @@ impl TryFrom<ExtReceiverSetup> for ot::ExtReceiverSetup {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ot::ExtDerandomize> for ExtDerandomize {
|
||||
impl From<kos15::ExtDerandomize> for ExtDerandomize {
|
||||
#[inline]
|
||||
fn from(d: ot::ExtDerandomize) -> Self {
|
||||
fn from(d: kos15::ExtDerandomize) -> Self {
|
||||
Self { flip: d.flip }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ExtDerandomize> for ot::ExtDerandomize {
|
||||
impl From<ExtDerandomize> for kos15::ExtDerandomize {
|
||||
#[inline]
|
||||
fn from(d: ExtDerandomize) -> Self {
|
||||
Self { flip: d.flip }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ot::ExtSenderPayload> for ExtSenderPayload {
|
||||
impl From<kos15::ExtSenderPayload> for ExtSenderPayload {
|
||||
#[inline]
|
||||
fn from(p: ot::ExtSenderPayload) -> Self {
|
||||
fn from(p: kos15::ExtSenderPayload) -> Self {
|
||||
Self {
|
||||
encrypted_values: p
|
||||
.encrypted_values
|
||||
ciphertexts: p
|
||||
.ciphertexts
|
||||
.into_iter()
|
||||
.map(|b| super::LabelPair {
|
||||
low: super::Block::from(b[0]),
|
||||
@@ -219,12 +221,12 @@ impl From<ot::ExtSenderPayload> for ExtSenderPayload {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ExtSenderPayload> for ot::ExtSenderPayload {
|
||||
impl From<ExtSenderPayload> for kos15::ExtSenderPayload {
|
||||
#[inline]
|
||||
fn from(p: ExtSenderPayload) -> Self {
|
||||
Self {
|
||||
encrypted_values: p
|
||||
.encrypted_values
|
||||
ciphertexts: p
|
||||
.ciphertexts
|
||||
.into_iter()
|
||||
.map(|pair| [crate::Block::from(pair.low), crate::Block::from(pair.high)])
|
||||
.collect(),
|
||||
@@ -232,9 +234,9 @@ impl From<ExtSenderPayload> for ot::ExtSenderPayload {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ot::BaseSenderSetup> for BaseSenderSetup {
|
||||
impl From<kos15::BaseSenderSetup> for BaseSenderSetup {
|
||||
#[inline]
|
||||
fn from(s: ot::BaseSenderSetup) -> Self {
|
||||
fn from(s: kos15::BaseSenderSetup) -> Self {
|
||||
Self {
|
||||
setup: SenderSetup::from(s.setup),
|
||||
cointoss_commit: s.cointoss_commit.to_vec(),
|
||||
@@ -242,7 +244,7 @@ impl From<ot::BaseSenderSetup> for BaseSenderSetup {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<BaseSenderSetup> for ot::BaseSenderSetup {
|
||||
impl TryFrom<BaseSenderSetup> for kos15::BaseSenderSetup {
|
||||
type Error = Error;
|
||||
|
||||
#[inline]
|
||||
@@ -257,9 +259,9 @@ impl TryFrom<BaseSenderSetup> for ot::BaseSenderSetup {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ot::BaseReceiverSetup> for BaseReceiverSetup {
|
||||
impl From<kos15::BaseReceiverSetup> for BaseReceiverSetup {
|
||||
#[inline]
|
||||
fn from(s: ot::BaseReceiverSetup) -> Self {
|
||||
fn from(s: kos15::BaseReceiverSetup) -> Self {
|
||||
Self {
|
||||
setup: ReceiverSetup::from(s.setup),
|
||||
cointoss_share: s.cointoss_share.to_vec(),
|
||||
@@ -267,7 +269,7 @@ impl From<ot::BaseReceiverSetup> for BaseReceiverSetup {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<BaseReceiverSetup> for ot::BaseReceiverSetup {
|
||||
impl TryFrom<BaseReceiverSetup> for kos15::BaseReceiverSetup {
|
||||
type Error = Error;
|
||||
|
||||
#[inline]
|
||||
@@ -282,9 +284,9 @@ impl TryFrom<BaseReceiverSetup> for ot::BaseReceiverSetup {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ot::BaseSenderPayload> for BaseSenderPayload {
|
||||
impl From<kos15::BaseSenderPayload> for BaseSenderPayload {
|
||||
#[inline]
|
||||
fn from(s: ot::BaseSenderPayload) -> Self {
|
||||
fn from(s: kos15::BaseSenderPayload) -> Self {
|
||||
Self {
|
||||
payload: SenderPayload::from(s.payload),
|
||||
cointoss_share: s.cointoss_share.to_vec(),
|
||||
@@ -292,7 +294,7 @@ impl From<ot::BaseSenderPayload> for BaseSenderPayload {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<BaseSenderPayload> for ot::BaseSenderPayload {
|
||||
impl TryFrom<BaseSenderPayload> for kos15::BaseSenderPayload {
|
||||
type Error = Error;
|
||||
|
||||
#[inline]
|
||||
@@ -354,7 +356,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::SenderSetup = proto_base_core_data
|
||||
let sender_setup: crate::ot::base::dh_ot::SenderSetup = proto_base_core_data
|
||||
.sender_setup
|
||||
.clone()
|
||||
.try_into()
|
||||
@@ -362,7 +364,7 @@ pub mod tests {
|
||||
|
||||
assert_eq!(sender_setup, ot_core_data.sender_setup);
|
||||
|
||||
let receiver_setup: crate::ot::base::ReceiverSetup = proto_base_core_data
|
||||
let receiver_setup: crate::ot::base::dh_ot::ReceiverChoices = proto_base_core_data
|
||||
.receiver_setup
|
||||
.clone()
|
||||
.try_into()
|
||||
@@ -370,7 +372,7 @@ pub mod tests {
|
||||
|
||||
assert_eq!(receiver_setup, ot_core_data.receiver_setup);
|
||||
|
||||
let sender_payload: crate::ot::base::SenderPayload = proto_base_core_data
|
||||
let sender_payload: crate::ot::base::dh_ot::SenderPayload = proto_base_core_data
|
||||
.sender_payload
|
||||
.clone()
|
||||
.try_into()
|
||||
@@ -381,7 +383,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::BaseSenderSetup = proto_ext_core_data
|
||||
let base_sender_setup: crate::ot::extension::kos15::BaseSenderSetup = proto_ext_core_data
|
||||
.base_sender_setup
|
||||
.clone()
|
||||
.try_into()
|
||||
@@ -389,19 +391,21 @@ pub mod tests {
|
||||
|
||||
assert_eq!(base_sender_setup, ot_ext_core_data.base_sender_setup);
|
||||
|
||||
let base_receiver_setup: crate::ot::extension::BaseReceiverSetup = proto_ext_core_data
|
||||
.base_receiver_setup
|
||||
.clone()
|
||||
.try_into()
|
||||
.unwrap();
|
||||
let base_receiver_setup: crate::ot::extension::kos15::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::BaseSenderPayload = proto_ext_core_data
|
||||
.base_sender_payload
|
||||
.clone()
|
||||
.try_into()
|
||||
.unwrap();
|
||||
let base_sender_payload: crate::ot::extension::kos15::BaseSenderPayload =
|
||||
proto_ext_core_data
|
||||
.base_sender_payload
|
||||
.clone()
|
||||
.try_into()
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(base_sender_payload, ot_ext_core_data.base_sender_payload);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user