Implemented remaining protocol steps

This commit is contained in:
th4s
2023-12-11 10:53:48 +01:00
parent 88e679c2f2
commit 9f696713a2
4 changed files with 138 additions and 58 deletions

View File

@@ -1,62 +1,10 @@
//! This crate is a testing ground for the E2F protocol (page 33) from <https://eprint.iacr.org/2023/964>
use mpz_share_conversion_core::fields::{p256::P256, UniformRand};
use rand::thread_rng;
mod ole;
mod prover;
mod verifier;
pub use prover::Prover;
pub use verifier::Verifier;
pub struct Ole {
input_sender: Vec<P256>,
input_receiver: Vec<P256>,
output: Vec<P256>,
}
impl Ole {
pub fn input(&mut self, role: Role, input: Vec<P256>) {
if role == Role::Sender {
self.input_sender = input;
} else {
self.input_receiver = input;
}
}
pub fn output(&mut self, role: Role) -> Vec<P256> {
assert!(self.input_sender.len() == self.input_receiver.len());
if !self.output.is_empty() {
return std::mem::take(&mut self.output);
}
let mut rng = thread_rng();
let mut output = vec![];
let mut output_cached = vec![];
for (s, r) in self.input_sender.iter().zip(self.input_receiver.iter()) {
let s_out = P256::rand(&mut rng);
let r_out = *s * *r + -s_out;
if role == Role::Sender {
output.push(s_out);
output_cached.push(r_out);
} else {
output.push(r_out);
output_cached.push(s_out);
}
}
self.input_sender.clear();
self.input_receiver.clear();
self.output = output_cached;
output
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Role {
Sender,
Receiver,
}
// In step 6 abort if w == 0

54
src/ole.rs Normal file
View File

@@ -0,0 +1,54 @@
use mpz_share_conversion_core::fields::{p256::P256, UniformRand};
use rand::thread_rng;
pub struct Ole {
input_sender: Vec<P256>,
input_receiver: Vec<P256>,
output: Vec<P256>,
}
impl Ole {
pub fn input(&mut self, role: Role, input: Vec<P256>) {
if role == Role::Sender {
self.input_sender = input;
} else {
self.input_receiver = input;
}
}
pub fn output(&mut self, role: Role) -> Vec<P256> {
assert!(self.input_sender.len() == self.input_receiver.len());
if !self.output.is_empty() {
return std::mem::take(&mut self.output);
}
let mut rng = thread_rng();
let mut output = vec![];
let mut output_cached = vec![];
for (s, r) in self.input_sender.iter().zip(self.input_receiver.iter()) {
let s_out = P256::rand(&mut rng);
let r_out = *s * *r + -s_out;
if role == Role::Sender {
output.push(s_out);
output_cached.push(r_out);
} else {
output.push(r_out);
output_cached.push(s_out);
}
}
self.input_sender.clear();
self.input_receiver.clear();
self.output = output_cached;
output
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Role {
Sender,
Receiver,
}

View File

@@ -1,7 +1,7 @@
//! The prover implementation
use crate::{Ole, Role};
use mpz_share_conversion_core::fields::{p256::P256, UniformRand};
use crate::ole::{Ole, Role};
use mpz_share_conversion_core::fields::{p256::P256, Field, UniformRand};
use rand::thread_rng;
#[derive(Debug, Default)]
@@ -29,6 +29,12 @@ pub struct Prover {
// Handshake 5
ec_point: Option<(P256, P256)>,
omega_share: Option<P256>,
// Handshake 6
eta_share: Option<P256>,
// Handshake 7
z1: Option<P256>,
}
impl Prover {
@@ -94,4 +100,37 @@ impl Prover {
pub fn handshake5_set_omega(&mut self, varepsilon1: P256) {
self.omega_share = Some(varepsilon1 * self.a1.unwrap() + self.c1.unwrap());
}
pub fn handshake6_omega_share_open(&self) -> P256 {
self.omega_share.unwrap()
}
pub fn handshake6_varepsilon2_share_open(&self) -> P256 {
-self.ec_point.unwrap().1 + -self.b1_prime.unwrap()
}
pub fn handshake6_set_eta(&mut self, omega: P256, varepsilon2: P256) {
let omega_inv = omega.inverse();
let a1 = self.a1.unwrap();
let c1_prime = self.c1_prime.unwrap();
self.eta_share = Some(omega_inv * (varepsilon2 * a1 + c1_prime));
}
pub fn handshake7_varepsilon3_share_open(&self) -> P256 {
self.eta_share.unwrap() + -self.r1.unwrap()
}
pub fn handshake7_set_z1(&mut self, varepsilon3: P256) {
let two = P256::new(2).unwrap();
let r1 = self.r1.unwrap();
let r_squared_share = self.r_squared_share.unwrap();
let x1 = self.ec_point.unwrap().0;
self.z1 = Some(varepsilon3 * varepsilon3 + two * varepsilon3 * r1 + r_squared_share + -x1);
}
pub fn handshake8_z1_share_open(&self) -> P256 {
self.z1.unwrap()
}
}

View File

@@ -1,7 +1,7 @@
//! The verifier implementation
use crate::{Ole, Role};
use mpz_share_conversion_core::fields::{p256::P256, UniformRand};
use crate::ole::{Ole, Role};
use mpz_share_conversion_core::fields::{p256::P256, Field, UniformRand};
use rand::thread_rng;
#[derive(Debug, Default)]
@@ -29,6 +29,12 @@ pub struct Verifier {
// Handshake 5
ec_point: Option<(P256, P256)>,
omega_share: Option<P256>,
// Handshake 6
eta_share: Option<P256>,
// Handshake 7
z2: Option<P256>,
}
impl Verifier {
@@ -94,4 +100,37 @@ impl Verifier {
pub fn handshake5_set_omega(&mut self, varepsilon1: P256) {
self.omega_share = Some(varepsilon1 * self.a2.unwrap() + self.c2.unwrap());
}
pub fn handshake6_omega_share_open(&self) -> P256 {
self.omega_share.unwrap()
}
pub fn handshake6_varepsilon2_share_open(&self) -> P256 {
self.ec_point.unwrap().1 + -self.b2_prime.unwrap()
}
pub fn handshake6_set_eta(&mut self, omega: P256, varepsilon2: P256) {
let omega_inv = omega.inverse();
let a2 = self.a2.unwrap();
let c2_prime = self.c2_prime.unwrap();
self.eta_share = Some(omega_inv * (varepsilon2 * a2 + c2_prime));
}
pub fn handshake7_varepsilon3_share_open(&self) -> P256 {
self.eta_share.unwrap() + -self.r2.unwrap()
}
pub fn handshake7_set_z1(&mut self, varepsilon3: P256) {
let two = P256::new(2).unwrap();
let r2 = self.r2.unwrap();
let r_squared_share = self.r_squared_share.unwrap();
let x2 = self.ec_point.unwrap().0;
self.z2 = Some(varepsilon3 * varepsilon3 + two * varepsilon3 * r2 + r_squared_share + -x2);
}
pub fn handshake8_z2_open(&self) -> P256 {
self.z2.unwrap()
}
}