Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🎨 Improve mpc-boolean-field structure. #49

Merged
merged 1 commit into from
May 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions mpc-algebra/src/mpc_primitives.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use rand::Rng;

use crate::boolean_field::BooleanWire;

pub trait UniformBitRand: Sized {
type BaseField;

Expand All @@ -16,7 +18,7 @@ pub trait BitwiseLessThan {

pub trait LessThan {
type Output;

fn is_smaller_or_equal_than_mod_minus_one_div_two(&self) -> Self::Output;
fn is_smaller_than(&self, other: &Self) -> Self::Output;
}
Expand All @@ -30,12 +32,12 @@ pub trait LogicalOperations {
}

pub trait EqualityZero {
type Output;
type Output: BooleanWire<Base = Self>;
fn is_zero_shared(&self) -> Self::Output;
}

pub trait BitDecomposition {
type BooleanField;
type BooleanField: BooleanWire<Base = Self>;

fn bit_decomposition(&self) -> Vec<Self::BooleanField>;
}
Expand Down
4 changes: 2 additions & 2 deletions mpc-algebra/src/r1cs_helper/mpc_fp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ use ark_ff::{Field, PrimeField, SquareRootField};
use ark_r1cs_std::{
alloc::{AllocVar, AllocationMode},
fields::FieldOpsBounds,
impl_ops,
R1CSVar,
impl_ops, R1CSVar,
};
use ark_r1cs_std::{impl_bounded_ops, Assignment};
use ark_relations::{
Expand All @@ -17,6 +16,7 @@ use ark_std::{One, Zero};
use ark_ff::FpParameters;

use crate::{
boolean_field::BooleanWire,
mpc_eq::MpcEqGadget,
mpc_select::{MpcCondSelectGadget, MpcTwoBitLookupGadget},
BitDecomposition, EqualityZero, FieldShare, MpcBoolean, MpcField, MpcToBitsGadget, Reveal,
Expand Down
112 changes: 72 additions & 40 deletions mpc-algebra/src/wire/boolean_field.rs
Original file line number Diff line number Diff line change
@@ -1,44 +1,58 @@
use crate::{BitAdd, BitwiseLessThan, FieldShare, MpcField, Reveal, UniformBitRand};
use ark_ff::{
BigInteger, Field, FpParameters, One, PrimeField, SquareRootField, UniformRand, Zero,
};
use core::panic;
use std::ops::{BitAnd, BitOr, BitXor, Not};
use ark_ff::{BigInteger, Field, FpParameters, One, PrimeField, SquareRootField, UniformRand, Zero};
use mpc_trait::MpcWire;
use rand::Rng;
use crate::{BitAdd, BitwiseLessThan, FieldShare, MpcField, Reveal, UniformBitRand};
use std::ops::{BitAnd, BitOr, BitXor, Not};

#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub struct MpcBooleanField<F: Field, S: FieldShare<F>>(MpcField<F,S>);
pub struct MpcBooleanField<F: Field, S: FieldShare<F>>(MpcField<F, S>);

pub trait BooleanWire: Not + From<bool> {
type Base;

fn pub_true() -> Self;
fn pub_false() -> Self;
fn field(&self) -> Self::Base;
fn and(self, other: Self) -> Self;
fn or(self, other: Self) -> Self;
fn xor(self, other: Self) -> Self;
}

impl<F: Field, S: FieldShare<F>> BooleanWire for MpcBooleanField<F, S> {
type Base = MpcField<F, S>;

impl<F: Field, S: FieldShare<F>> MpcBooleanField<F, S> {
pub fn pub_true() -> Self {
fn pub_true() -> Self {
Self(MpcField::one())
}

pub fn pub_false() -> Self {
fn pub_false() -> Self {
Self(MpcField::zero())
}

pub fn field(&self) -> MpcField<F, S> {
fn field(&self) -> MpcField<F, S> {
self.0
}

pub fn and(self, other: Self) -> Self {
fn and(self, other: Self) -> Self {
Self(self.0 * other.0)
}

pub fn or(self, other: Self) -> Self {
fn or(self, other: Self) -> Self {
Self(self.0 + other.0 - (self.0 * other.0))
}

pub fn xor(self, other: Self) -> Self {
Self(self.0 + other.0 - (self.0 * other.0 * MpcField::from_public(F::from(2u8))))
fn xor(self, other: Self) -> Self {
Self(self.0 + other.0 - (self.0 * other.0 * MpcField::from(2u8)))
}
}

impl<F: Field, S: FieldShare<F>> Not for MpcBooleanField<F, S> {
type Output = Self;

fn not(self) -> Self::Output {
Self (MpcField::one() - self.0)
Self(MpcField::one() - self.0)
}
}

Expand Down Expand Up @@ -109,8 +123,8 @@ impl<F: PrimeField, S: FieldShare<F>> BitwiseLessThan for Vec<MpcBooleanField<F,

// d_i = OR_{j=i}^{modulus_size-1} c_j
let mut d = vec![rev_c[0]];
for i in 0..modulus_size -1 {
d.push(d[i]|rev_c[i+1]);
for i in 0..modulus_size - 1 {
d.push(d[i] | rev_c[i + 1]);
}
d.reverse();

Expand All @@ -122,9 +136,14 @@ impl<F: PrimeField, S: FieldShare<F>> BitwiseLessThan for Vec<MpcBooleanField<F,
d[i].field() - d[i + 1].field()
}
})
.collect::<Vec<MpcField<F,S>>>();

Self::Output::from(e.iter().zip(other.iter()).map(|(&e, &b)| e * b.field()).sum::<MpcField<F,S>>())
.collect::<Vec<MpcField<F, S>>>();

Self::Output::from(
e.iter()
.zip(other.iter())
.map(|(&e, &b)| e * b.field())
.sum::<MpcField<F, S>>(),
)
}
}

Expand All @@ -144,7 +163,10 @@ impl<F: PrimeField + SquareRootField, S: FieldShare<F>> UniformBitRand for MpcBo
}
}

Self((r / Self::BaseField::from_public(root_r2) + Self::BaseField::one()) / Self::BaseField::from_public(F::from(2u8)))
Self(
(r / Self::BaseField::from_public(root_r2) + Self::BaseField::one())
/ Self::BaseField::from_public(F::from(2u8)),
)
}

fn rand_number_bitwise<R: Rng + ?Sized>(rng: &mut R) -> (Vec<Self>, Self::BaseField) {
Expand All @@ -163,29 +185,39 @@ impl<F: PrimeField + SquareRootField, S: FieldShare<F>> UniformBitRand for MpcBo
.map(|_| Self::bit_rand(rng))
.collect::<Vec<_>>();

if bits.clone().is_smaller_than_le(&modulus_bits).field().reveal().is_one() {
if bits
.clone()
.is_smaller_than_le(&modulus_bits)
.field()
.reveal()
.is_one()
{
break bits;
}
};

// bits to field elemetn (little endian)
let num = valid_bits.iter().map(|b|b.field()).rev().fold(Self::BaseField::zero(), |acc, x| {
acc * Self::BaseField::from_public(F::from(2u8)) + x
});
let num = valid_bits
.iter()
.map(|b| b.field())
.rev()
.fold(Self::BaseField::zero(), |acc, x| {
acc * Self::BaseField::from_public(F::from(2u8)) + x
});

(valid_bits, num)
}
}

impl <F: Field, S: FieldShare<F>> MpcWire for MpcBooleanField<F, S> {
impl<F: Field, S: FieldShare<F>> MpcWire for MpcBooleanField<F, S> {
fn is_shared(&self) -> bool {
self.field().is_shared()
}

fn publicize(&mut self) {
self.field().publicize();
}

fn publicize_cow<'b>(&'b self) -> std::borrow::Cow<'b, Self> {
if self.is_shared() {
let mut s = self.clone();
Expand All @@ -197,7 +229,6 @@ impl <F: Field, S: FieldShare<F>> MpcWire for MpcBooleanField<F, S> {
}
}


impl<F: Field, S: FieldShare<F>> BitAdd for Vec<MpcBooleanField<F, S>> {
type Output = Self;

Expand All @@ -215,7 +246,8 @@ impl<F: Field, S: FieldShare<F>> BitAdd for Vec<MpcBooleanField<F, S>> {

let p_vec = (0..l)
.map(|i| {
self[i].field() + other[i].field() - MpcField::<F, S>::from_public(F::from(2u64)) * s_vec[i].field()
self[i].field() + other[i].field()
- MpcField::<F, S>::from_public(F::from(2u64)) * s_vec[i].field()
})
.collect::<Vec<_>>();

Expand All @@ -225,8 +257,8 @@ impl<F: Field, S: FieldShare<F>> BitAdd for Vec<MpcBooleanField<F, S>> {
Some(*is_s)
})
.collect::<Vec<_>>();
ret.into_iter().map(MpcBooleanField::<F,S>::from).collect()

ret.into_iter().map(MpcBooleanField::<F, S>::from).collect()
}
false => {
panic!("public is not expected here");
Expand All @@ -247,12 +279,14 @@ impl<F: Field, S: FieldShare<F>> BitAdd for Vec<MpcBooleanField<F, S>> {
.map(|i| {
if i == 0 {
(self[0].field() + other[0].field()
- MpcField::<F, S>::from_public(F::from(2u64)) * c_vec[0].field()).into()
- MpcField::<F, S>::from_public(F::from(2u64)) * c_vec[0].field())
.into()
} else if i == l {
c_vec[l - 1]
} else {
(self[i].field() + other[i].field() + c_vec[i - 1].field()
- MpcField::<F, S>::from_public(F::from(2u64)) * c_vec[i].field()).into()
- MpcField::<F, S>::from_public(F::from(2u64)) * c_vec[i].field())
.into()
}
})
.collect()
Expand All @@ -264,7 +298,6 @@ impl<F: Field, S: FieldShare<F>> BitAdd for Vec<MpcBooleanField<F, S>> {
}
}


impl<F: Field, S: FieldShare<F>> Reveal for MpcBooleanField<F, S> {
type Base = F;
#[inline]
Expand All @@ -280,7 +313,6 @@ impl<F: Field, S: FieldShare<F>> Reveal for MpcBooleanField<F, S> {
} else {
panic!("not boolean")
}

}
#[inline]
fn from_add_shared(b: Self::Base) -> Self {
Expand All @@ -289,8 +321,8 @@ impl<F: Field, S: FieldShare<F>> Reveal for MpcBooleanField<F, S> {
#[inline]
fn unwrap_as_public(self) -> Self::Base {
match self.field() {
MpcField::<F,S>::Shared(s) => s.unwrap_as_public(),
MpcField::<F,S>::Public(s) => s,
MpcField::<F, S>::Shared(s) => s.unwrap_as_public(),
MpcField::<F, S>::Public(s) => s,
}
}
#[inline]
Expand All @@ -302,9 +334,9 @@ impl<F: Field, S: FieldShare<F>> Reveal for MpcBooleanField<F, S> {
todo!()
}
fn init_protocol() {
MpcField::<F,S>::init_protocol()
MpcField::<F, S>::init_protocol()
}
fn deinit_protocol() {
MpcField::<F,S>::deinit_protocol()
MpcField::<F, S>::deinit_protocol()
}
}
}
2 changes: 1 addition & 1 deletion mpc-algebra/src/wire/field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use ark_serialize::{
CanonicalSerializeWithFlags,
};

use crate::boolean_field::MpcBooleanField;
use crate::boolean_field::{BooleanWire, MpcBooleanField};
// use crate::channel::MpcSerNet;
use crate::share::field::FieldShare;
use crate::{
Expand Down
Loading