mirror of
https://github.com/tlsnotary/tlsn.git
synced 2026-01-09 14:48:13 -05:00
base ot
This commit is contained in:
@@ -8,6 +8,7 @@ edition = "2018"
|
||||
[dependencies]
|
||||
aes = { version="0.7.5", features=[]}
|
||||
cipher = "0.3"
|
||||
sha2 = "0.10.1"
|
||||
rand = "0.7"
|
||||
rand_core = "0.5"
|
||||
rand_chacha = "0.2"
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
use aes::cipher::{generic_array::GenericArray, NewBlockCipher};
|
||||
use aes::Aes128;
|
||||
use criterion::{black_box, criterion_group, criterion_main, Criterion};
|
||||
use pop_mpc::block::Block;
|
||||
use pop_mpc::circuit::Circuit;
|
||||
use pop_mpc::garble::{
|
||||
evaluator::HalfGateEvaluator, generator::half_gate::*, generator::GarbledCircuitGenerator,
|
||||
};
|
||||
use aes::cipher::{
|
||||
generic_array::GenericArray, NewBlockCipher,
|
||||
};
|
||||
use aes::Aes128;
|
||||
use rand::SeedableRng;
|
||||
use rand_chacha::ChaCha12Rng;
|
||||
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
use cipher::{
|
||||
consts::{U16, U32},
|
||||
generic_array::GenericArray,
|
||||
BlockCipher, BlockEncrypt,
|
||||
};
|
||||
use core::ops::{BitAnd, BitXor, BitXorAssign};
|
||||
use curve25519_dalek::ristretto::RistrettoPoint;
|
||||
use rand::{CryptoRng, Rng, SeedableRng};
|
||||
use sha2::{Digest, Sha256};
|
||||
use std::convert::{From, TryInto};
|
||||
use cipher::{BlockCipher, BlockEncrypt, consts::U16, generic_array::GenericArray};
|
||||
|
||||
#[repr(transparent)]
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
@@ -24,7 +30,11 @@ impl Block {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn hash_tweak<C: BlockCipher<BlockSize = U16> + BlockEncrypt>(&self, c: &mut C, tweak: usize) -> Self {
|
||||
pub fn hash_tweak<C: BlockCipher<BlockSize = U16> + BlockEncrypt>(
|
||||
&self,
|
||||
c: &mut C,
|
||||
tweak: usize,
|
||||
) -> Self {
|
||||
let gid: [u8; 16] = (tweak as u128).to_be_bytes();
|
||||
let label: [u8; 16] = self.to_be_bytes();
|
||||
|
||||
@@ -46,6 +56,17 @@ impl Block {
|
||||
Self::new(h)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn hash_point(point: &RistrettoPoint, tweak: usize) -> 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)
|
||||
|
||||
@@ -3,8 +3,8 @@ use crate::block::{Block, SELECT_MASK};
|
||||
use crate::circuit::Circuit;
|
||||
use crate::errors::EvaluatorError;
|
||||
use crate::garble::circuit::GarbledCircuit;
|
||||
use cipher::{BlockCipher, BlockEncrypt, consts::U16, generic_array::GenericArray};
|
||||
use crate::gate::Gate;
|
||||
use cipher::{consts::U16, generic_array::GenericArray, BlockCipher, BlockEncrypt};
|
||||
|
||||
pub struct HalfGateEvaluator;
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ use crate::block::Block;
|
||||
use crate::circuit::Circuit;
|
||||
use crate::errors::EvaluatorError;
|
||||
use crate::garble::circuit::GarbledCircuit;
|
||||
use cipher::{BlockCipher, BlockEncrypt, consts::U16, generic_array::GenericArray};
|
||||
use cipher::{consts::U16, generic_array::GenericArray, BlockCipher, BlockEncrypt};
|
||||
|
||||
pub trait GarbledCircuitEvaluator {
|
||||
fn eval<C: BlockCipher<BlockSize = U16> + BlockEncrypt>(
|
||||
|
||||
@@ -3,8 +3,8 @@ use crate::block::{Block, SELECT_MASK};
|
||||
use crate::circuit::Circuit;
|
||||
use crate::errors::GeneratorError;
|
||||
use crate::garble::circuit::GarbledCircuit;
|
||||
use cipher::{BlockCipher, BlockEncrypt, consts::U16, generic_array::GenericArray};
|
||||
use crate::gate::Gate;
|
||||
use cipher::{consts::U16, generic_array::GenericArray, BlockCipher, BlockEncrypt};
|
||||
use rand::{CryptoRng, Rng, SeedableRng};
|
||||
|
||||
pub struct HalfGateGenerator;
|
||||
@@ -124,9 +124,7 @@ impl GarbledCircuitGenerator for HalfGateGenerator {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use aes::cipher::{
|
||||
generic_array::GenericArray, NewBlockCipher,
|
||||
};
|
||||
use aes::cipher::{generic_array::GenericArray, NewBlockCipher};
|
||||
use aes::Aes128;
|
||||
use rand_chacha::ChaCha12Rng;
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ pub use half_gate::*;
|
||||
use crate::circuit::Circuit;
|
||||
use crate::errors::GeneratorError;
|
||||
use crate::garble::circuit::GarbledCircuit;
|
||||
use cipher::{BlockCipher, BlockEncrypt, consts::U16, generic_array::GenericArray};
|
||||
use cipher::{consts::U16, generic_array::GenericArray, BlockCipher, BlockEncrypt};
|
||||
use rand::{CryptoRng, Rng};
|
||||
|
||||
pub trait GarbledCircuitGenerator {
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
pub mod circuit;
|
||||
pub mod evaluator;
|
||||
pub mod generator;
|
||||
pub mod generator;
|
||||
|
||||
@@ -8,3 +8,4 @@ pub mod element;
|
||||
pub mod errors;
|
||||
pub mod garble;
|
||||
mod gate;
|
||||
pub mod ot;
|
||||
|
||||
@@ -21,12 +21,10 @@ pub struct BaseOTSender {
|
||||
}
|
||||
|
||||
pub struct OTSetupSender {
|
||||
s: RistrettoPoint
|
||||
pub s: RistrettoPoint,
|
||||
}
|
||||
|
||||
pub struct OTSend {
|
||||
|
||||
}
|
||||
pub struct OTSend {}
|
||||
|
||||
pub struct BaseOTReceiver {
|
||||
s: RistrettoBasepointTable,
|
||||
@@ -54,19 +52,109 @@ impl OTSender {
|
||||
}
|
||||
|
||||
pub fn setup(&self) -> OTSetupSender {
|
||||
OTSetupSender {
|
||||
s: self.base.s
|
||||
OTSetupSender { s: self.base.s }
|
||||
}
|
||||
|
||||
pub fn encode_base_labels(
|
||||
&mut self,
|
||||
inputs: &[[Block; 2]],
|
||||
points: &[RistrettoPoint],
|
||||
) -> Vec<[Block; 2]> {
|
||||
let ys = self.base.y * self.base.s;
|
||||
let ks: Vec<[Block; 2]> = inputs
|
||||
.iter()
|
||||
.zip(points)
|
||||
.enumerate()
|
||||
.map(|(i, (input, point))| {
|
||||
let tweak = (self.base.counter as usize) + i;
|
||||
let yr = self.base.y * point;
|
||||
let k0 = Block::hash_point(&yr, tweak);
|
||||
let k1 = Block::hash_point(&(yr - ys), tweak);
|
||||
let c0 = k0 ^ input[0];
|
||||
let c1 = k1 ^ input[1];
|
||||
[c0, c1]
|
||||
})
|
||||
.collect();
|
||||
self.base.counter += inputs.len() as u128;
|
||||
|
||||
ks
|
||||
}
|
||||
}
|
||||
|
||||
impl OTReceiver {
|
||||
pub fn new(s_setup: &OTSetupSender) -> Self {
|
||||
Self {
|
||||
base: BaseOTReceiver {
|
||||
s: RistrettoBasepointTable::create(&s_setup.s),
|
||||
counter: 0,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// pub fn send(&self, inputs: &[[Block; 2]], points: &[Block]) -> OTSend {
|
||||
// let ys= self.base.y * self.base.s;
|
||||
// let ks = inputs.iter().zip(points).map(|input, point| {
|
||||
// let yr = self.base.y * point;
|
||||
// }).collect::<[Block; 2]>();
|
||||
pub fn setup<R: Rng + CryptoRng>(
|
||||
&mut self,
|
||||
rng: &mut R,
|
||||
choice: &[bool],
|
||||
) -> Vec<(RistrettoPoint, Block)> {
|
||||
let zero = &Scalar::zero() * &self.base.s;
|
||||
let one = &Scalar::one() * &self.base.s;
|
||||
let ks: Vec<(RistrettoPoint, Block)> = choice
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, b)| {
|
||||
let tweak = (self.base.counter as usize) + i;
|
||||
let x = Scalar::random(rng);
|
||||
let c = if *b { one } else { zero };
|
||||
let r = c + &x * &RISTRETTO_BASEPOINT_TABLE;
|
||||
let k = Block::hash_point(&(&x * &self.base.s), tweak);
|
||||
(r, k)
|
||||
})
|
||||
.collect();
|
||||
self.base.counter += choice.len() as u128;
|
||||
ks
|
||||
}
|
||||
|
||||
// OTSend {}
|
||||
// }
|
||||
pub fn decode_base_labels(
|
||||
&self,
|
||||
choice: &[bool],
|
||||
hs: &[Block],
|
||||
encoded_labels: &[[Block; 2]],
|
||||
) -> Vec<Block> {
|
||||
choice
|
||||
.iter()
|
||||
.zip(hs.iter())
|
||||
.zip(encoded_labels.iter())
|
||||
.map(|((c, h), labels)| *h ^ if *c { labels[1] } else { labels[0] })
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl OTReceiver {}
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use rand::SeedableRng;
|
||||
|
||||
#[test]
|
||||
fn test_base_ot() {
|
||||
let mut s_rng = ChaCha12Rng::from_entropy();
|
||||
let mut r_rng = ChaCha12Rng::from_entropy();
|
||||
let mut sender = OTSender::new(&mut s_rng);
|
||||
|
||||
let s_setup = sender.setup();
|
||||
let s_inputs = [
|
||||
[Block::new(0), Block::new(1)],
|
||||
[Block::new(2), Block::new(3)],
|
||||
];
|
||||
|
||||
let mut receiver = OTReceiver::new(&s_setup);
|
||||
let choice = [false, true];
|
||||
|
||||
let r_setup = receiver.setup(&mut r_rng, &choice);
|
||||
let (r_points, r_hs): (Vec<RistrettoPoint>, Vec<Block>) = r_setup.into_iter().unzip();
|
||||
|
||||
let encoded_labels = sender.encode_base_labels(&s_inputs, &r_points.as_slice());
|
||||
|
||||
let received = receiver.decode_base_labels(&choice, &r_hs, &encoded_labels);
|
||||
assert_eq!(received, [Block::new(0), Block::new(3)]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
use aes::cipher::{generic_array::GenericArray, NewBlockCipher};
|
||||
use aes::Aes128;
|
||||
use pop_mpc::{
|
||||
block::Block,
|
||||
circuit::Circuit,
|
||||
garble::{evaluator::*, generator::*},
|
||||
};
|
||||
use aes::cipher::{
|
||||
generic_array::GenericArray, NewBlockCipher,
|
||||
};
|
||||
use aes::Aes128;
|
||||
use rand::SeedableRng;
|
||||
use rand_chacha::ChaCha12Rng;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user