use std::mem;
use std::ops::Index;
use aead::rand_core::SeedableRng;
use crypto_bigint::{Encoding, U64};
use rand::Rng;
use rand_chacha::ChaCha20Rng;
use serde::{Deserialize, Serialize};
mod constants;
use crate::constants::{FIELD_SIZE, FIELD_SIZE_BYTES, FRACTION_LENGTH, N};
pub type FieldElement = U64;
pub type Binary = bool;
pub trait ExtractBit: Index<usize, Output = u8> {
fn extract_bit(&self, idx: usize) -> bool {
let byte_idx = idx >> 3;
let bit_idx = idx & 0x7;
let byte = self[byte_idx];
((byte >> bit_idx) & 1) != 0
}
}
impl ExtractBit for Vec<u8> {}
impl<const T: usize> ExtractBit for [u8; T] {}
#[derive(Copy, Clone, Default, Debug)]
pub struct BinaryArithmetic {
pub value: [u8; FIELD_SIZE_BYTES],
}
impl BinaryArithmetic {
pub const ZERO: BinaryArithmetic = BinaryArithmetic {
value: [0u8; FIELD_SIZE_BYTES],
};
pub fn get_external_size(&self) -> usize {
FIELD_SIZE_BYTES
}
pub fn from_binary_string(b: &BinaryString) -> Self {
let len = b.value.len();
assert!(len <= FIELD_SIZE_BYTES);
let mut value = b.value.clone();
if len != FIELD_SIZE_BYTES {
let zero_pad = FIELD_SIZE_BYTES - len;
value.extend(std::iter::repeat(0u8).take(zero_pad));
}
BinaryArithmetic {
value: value.try_into().unwrap(),
}
}
pub fn to_binary_string(&self, len: usize) -> BinaryString {
let in_bytes = len.div_ceil(8);
let value = &self.value[0..in_bytes];
BinaryString {
length: len as u64,
value: value.to_vec(),
}
}
pub fn xor(&self, other: &Self) -> Self {
let mut value = self.value;
#[allow(clippy::needless_range_loop)]
for i in 0..FIELD_SIZE_BYTES {
value[i] ^= other.value[i];
}
BinaryArithmetic { value }
}
}
#[derive(Copy, Clone, Default, Debug)]
pub struct BinaryArithmeticShare {
pub value1: [u8; FIELD_SIZE_BYTES],
pub value2: [u8; FIELD_SIZE_BYTES],
}
impl BinaryArithmeticShare {
pub const ZERO: BinaryArithmeticShare = BinaryArithmeticShare {
value1: [0u8; FIELD_SIZE_BYTES],
value2: [0u8; FIELD_SIZE_BYTES],
};
pub fn new(
value1: [u8; FIELD_SIZE_BYTES],
value2: [u8; FIELD_SIZE_BYTES],
) -> BinaryArithmeticShare {
BinaryArithmeticShare { value1, value2 }
}
pub fn from_constant(c: &FieldElement, party_index: usize) -> Self {
let v = c
.wrapping_mul(&FieldElement::from(1u64 << FRACTION_LENGTH))
.to_le_bytes();
match party_index {
0 => BinaryArithmeticShare {
value1: v,
value2: v,
},
1 => BinaryArithmeticShare {
value1: v,
value2: [0u8; FIELD_SIZE_BYTES],
},
_ => BinaryArithmeticShare::ZERO,
}
}
pub fn reconstruct(&self, other: &BinaryArithmetic) -> BinaryArithmetic {
let mut value = self.value2;
#[allow(clippy::needless_range_loop)]
for i in 0..FIELD_SIZE_BYTES {
value[i] ^= other.value[i];
}
BinaryArithmetic { value }
}
pub fn from_own_and_other(
own: &BinaryArithmetic,
other: &BinaryArithmetic,
) -> BinaryArithmeticShare {
let mut value1 = own.value;
#[allow(clippy::needless_range_loop)]
for i in 0..FIELD_SIZE_BYTES {
value1[i] ^= other.value[i];
}
BinaryArithmeticShare {
value1,
value2: own.value,
}
}
pub fn from_binary_share(
from_share: &BinaryShare,
) -> BinaryArithmeticShare {
let mut share = BinaryArithmeticShare::default();
let byte_idx = FRACTION_LENGTH >> 3;
let bit_idx = FRACTION_LENGTH & 0x7;
if from_share.value1 {
share.value1[byte_idx] |= 1 << bit_idx;
}
if from_share.value2 {
share.value2[byte_idx] |= 1 << bit_idx;
}
share
}
pub fn to_binary_string_share(&self) -> BinaryStringShare {
BinaryStringShare {
length: FIELD_SIZE as u64,
value1: self.value1.to_vec(),
value2: self.value2.to_vec(),
}
}
pub fn from_binary_string_share(
from_share: &BinaryStringShare,
) -> BinaryArithmeticShare {
assert_eq!(from_share.length, FIELD_SIZE as u64);
BinaryArithmeticShare {
value1: from_share.value1.clone().try_into().unwrap(),
value2: from_share.value2.clone().try_into().unwrap(),
}
}
pub fn from_choice(c: &BinaryShare) -> Self {
let v1 = c.value1;
let v2 = c.value2;
let value1 = match v1 {
true => [255u8; FIELD_SIZE_BYTES],
false => [0u8; FIELD_SIZE_BYTES],
};
let value2 = match v2 {
true => [255u8; FIELD_SIZE_BYTES],
false => [0u8; FIELD_SIZE_BYTES],
};
BinaryArithmeticShare { value1, value2 }
}
pub fn xor(&self, other: &Self) -> BinaryArithmeticShare {
let mut value1 = self.value1;
let mut value2 = self.value2;
for i in 0..FIELD_SIZE_BYTES {
value1[i] ^= other.value1[i];
value2[i] ^= other.value2[i];
}
BinaryArithmeticShare { value1, value2 }
}
pub fn not(&self) -> Self {
let mut value2 = self.value2;
#[allow(clippy::needless_range_loop)]
for i in 0..FIELD_SIZE_BYTES {
value2[i] ^= 0xFF;
}
BinaryArithmeticShare {
value1: self.value1,
value2,
}
}
pub fn and_bitwise(
&self,
other: &Self,
randomness: &mut CommonRandomness,
) -> BinaryArithmetic {
let mut alpha_bytes = [0u8; FIELD_SIZE_BYTES];
#[allow(clippy::needless_range_loop)]
for i in 0..FIELD_SIZE_BYTES {
let mut alpha_byte = 0u8;
for j in 0..8 {
let alpha = randomness.random_zero_bool() as u8;
alpha_byte |= alpha << j;
}
alpha_bytes[i] = alpha_byte
}
let mut res = [0u8; FIELD_SIZE_BYTES];
for i in 0..FIELD_SIZE_BYTES {
res[i] = (self.value1[i] & other.value1[i])
^ (self.value2[i] & other.value2[i])
^ alpha_bytes[i];
}
BinaryArithmetic { value: res }
}
pub fn get_binary_share(&self, index: usize) -> BinaryShare {
let bit1 = self.value1.extract_bit(index);
let bit2 = self.value2.extract_bit(index);
BinaryShare {
value1: bit1,
value2: bit2,
}
}
pub fn set_binary_share(&mut self, index: usize, share: BinaryShare) {
let byte_idx = index >> 3;
let bit_idx = index & 0x7;
assert!(
byte_idx < self.value1.len(),
"No value assigned to the index yet!! {} {}",
byte_idx,
self.value1.len()
);
let mask = !(1 << bit_idx);
self.value1[byte_idx] &= mask;
self.value1[byte_idx] |= (share.value1 as u8) << bit_idx;
self.value2[byte_idx] &= mask;
self.value2[byte_idx] |= (share.value2 as u8) << bit_idx;
}
pub fn left_shift(&self, shift: usize) -> BinaryArithmeticShare {
let v1 = FieldElement::from_le_slice(&self.value1).shl(shift);
let v2 = FieldElement::from_le_slice(&self.value2).shl(shift);
BinaryArithmeticShare {
value1: v1.to_le_bytes(),
value2: v2.to_le_bytes(),
}
}
}
#[derive(Clone, Default, Debug, Serialize, Deserialize, PartialEq)]
pub struct BinaryString {
pub length: u64,
pub value: Vec<u8>,
}
impl BinaryString {
pub fn new() -> Self {
BinaryString {
length: 0,
value: Vec::new(),
}
}
pub fn new_with_zeros(size_in_bits: usize) -> Self {
let size_in_bytes = (size_in_bits + 7) / 8;
BinaryString {
length: size_in_bits as u64,
value: vec![0u8; size_in_bytes],
}
}
pub fn length_in_bytes(&self) -> usize {
if (self.length % 8) == 0 {
(self.length / 8) as usize
} else {
(self.length / 8) as usize + 1
}
}
pub fn get_external_size(&self) -> usize {
mem::size_of::<u64>() + self.length_in_bytes()
}
pub fn with_capacity(size: usize) -> Self {
let num_bytes = (size + 7) / 8;
BinaryString {
length: 0_u64,
value: Vec::with_capacity(num_bytes),
}
}
pub fn get(&self, index: usize) -> bool {
self.value.extract_bit(index)
}
pub fn set(&mut self, index: usize, value: bool) {
let byte_idx = index >> 3;
let bit_idx = index & 0x7;
assert!(
byte_idx < self.value.len(),
"No value assigned to the index yet!! {} {}",
byte_idx,
self.value.len()
);
self.value[byte_idx] &= !(1 << bit_idx);
self.value[byte_idx] |= (value as u8) << bit_idx;
}
pub fn push(&mut self, value: bool) {
let index = self.length as usize;
if index >= self.value.len() * 8 {
self.value.push(0);
}
let byte_idx = index >> 3;
let bit_idx = index & 0x7;
self.value[byte_idx] |= (value as u8) << bit_idx;
self.length += 1;
}
pub fn reverse(&mut self) {
let mut newout = Self::with_capacity(self.length as usize);
for i in (0..self.length as usize).rev() {
newout.push(self.get(i));
}
self.value = newout.value;
}
pub fn extend(&mut self, val: &Self) {
for i in 0..(val.length as usize) {
self.push(val.get(i));
}
}
pub fn xor(&self, other: &Self) -> BinaryString {
assert_eq!(
self.length, other.length,
"BinaryString instances must have the same length"
);
let mut value = Vec::new();
for i in 0..self.value.len() {
value.push(self.value[i] ^ other.value[i]);
}
BinaryString {
length: self.length,
value,
}
}
pub fn and(&self, other: &Self) -> BinaryString {
assert_eq!(
self.length, other.length,
"BinaryString instances must have the same length"
);
let mut value = Vec::new();
for i in 0..self.value.len() {
value.push(self.value[i] & other.value[i]);
}
BinaryString {
length: self.length,
value,
}
}
pub fn _slice(&self, start: usize, end: usize) -> BinaryString {
assert!(start <= end, "Start index cannot be greater than end index");
assert!(
end <= self.length as usize,
"End index exceeds BinaryStringShare length"
);
let mut result = BinaryString::with_capacity(end - start);
for i in start..end {
result.push(self.get(i));
}
result
}
pub fn split(&self, index: usize) -> (Self, Self) {
assert_eq!(self.length % 8, 0);
assert_eq!(index % 8, 0);
assert!(
index <= self.length as usize,
"End index exceeds BinaryString length"
);
let index_in_bytes = index / 8;
let r1 = BinaryString {
length: index as u64,
value: self.value[0..index_in_bytes].to_vec(),
};
let r2 = BinaryString {
length: self.length - index as u64,
value: self.value[index_in_bytes..].to_vec(),
};
(r1, r2)
}
pub fn append_bytes_with_padding(&mut self, other: &[u8]) {
self.length = (self.length + 7) / 8 * 8;
self.length += other.len() as u64;
self.value.extend_from_slice(other);
}
}
#[derive(Clone, Debug, Copy, Serialize, Deserialize)]
pub struct BinaryShare {
pub value1: Binary,
pub value2: Binary,
}
impl BinaryShare {
pub const ZERO: BinaryShare = BinaryShare {
value1: false,
value2: false,
};
pub fn from_constant(value: Binary, party_index: usize) -> Self {
match party_index {
0 => BinaryShare {
value1: value,
value2: value,
},
1 => BinaryShare {
value1: value,
value2: false,
},
_ => BinaryShare::ZERO,
}
}
pub fn not(&self) -> BinaryShare {
BinaryShare {
value1: self.value1,
value2: self.value2 ^ true,
}
}
pub fn xor(&self, other: &BinaryShare) -> BinaryShare {
BinaryShare {
value1: self.value1 ^ other.value1,
value2: self.value2 ^ other.value2,
}
}
pub fn and_bitwise(
&self,
other: &BinaryShare,
randomness: &mut CommonRandomness,
) -> Binary {
let alpha = randomness.random_zero_bool();
(self.value1 & other.value1) ^ (self.value2 & other.value2) ^ alpha
}
}
#[derive(Clone, Default, Debug, Serialize, Deserialize)]
pub struct BinaryStringShare {
pub length: u64,
pub value1: Vec<u8>,
pub value2: Vec<u8>,
}
impl BinaryStringShare {
pub fn new() -> Self {
BinaryStringShare {
length: 0,
value1: Vec::new(),
value2: Vec::new(),
}
}
pub fn zero(length: usize) -> Self {
let num_bytes = (length + 7) / 8;
BinaryStringShare {
length: length as u64,
value1: vec![0u8; num_bytes],
value2: vec![0u8; num_bytes],
}
}
pub fn from_constant(c: &BinaryString, party_index: usize) -> Self {
match party_index {
0 => BinaryStringShare {
length: c.length,
value1: c.value.clone(),
value2: c.value.clone(),
},
1 => BinaryStringShare {
length: c.length,
value1: c.value.clone(),
value2: vec![0u8; c.value.len()],
},
_ => BinaryStringShare {
length: c.length,
value1: vec![0u8; c.value.len()],
value2: vec![0u8; c.value.len()],
},
}
}
pub fn from_choice(c: &BinaryShare, size: usize) -> Self {
let v1 = c.value1;
let v2 = c.value2;
let mut res = BinaryStringShare::with_capacity(size);
for _ in 0..size {
res.push(v1, v2)
}
res
}
pub fn length_in_bytes(&self) -> usize {
if (self.length % 8) == 0 {
(self.length / 8) as usize
} else {
(self.length / 8) as usize + 1
}
}
pub fn get_external_size(&self) -> usize {
mem::size_of::<u64>() + self.length_in_bytes() * 2
}
pub fn with_capacity(size: usize) -> Self {
let num_bytes = (size + 7) / 8;
BinaryStringShare {
length: 0_u64,
value1: Vec::with_capacity(num_bytes),
value2: Vec::with_capacity(num_bytes),
}
}
pub fn get(&self, index: usize) -> (bool, bool) {
let bit1 = self.value1.extract_bit(index);
let bit2 = self.value2.extract_bit(index);
(bit1, bit2)
}
pub fn get_binary_share(&self, index: usize) -> BinaryShare {
let bit1 = self.value1.extract_bit(index);
let bit2 = self.value2.extract_bit(index);
BinaryShare {
value1: bit1,
value2: bit2,
}
}
pub fn set(&mut self, index: usize, value1: bool, value2: bool) {
let byte_idx = index >> 3;
let bit_idx = index & 0x7;
assert!(
byte_idx < self.value1.len(),
"No value assigned to the index yet!! {} {}",
byte_idx,
self.value1.len()
);
let mask = !(1 << bit_idx);
self.value1[byte_idx] &= mask;
self.value1[byte_idx] |= (value1 as u8) << bit_idx;
self.value2[byte_idx] &= mask;
self.value2[byte_idx] |= (value2 as u8) << bit_idx;
}
pub fn set_binary_share(&mut self, index: usize, share: &BinaryShare) {
let byte_idx = index >> 3;
let bit_idx = index & 0x7;
assert!(
byte_idx < self.value1.len(),
"No value assigned to the index yet!! {} {}",
byte_idx,
self.value1.len()
);
let mask = !(1 << bit_idx);
self.value1[byte_idx] &= mask;
self.value1[byte_idx] |= (share.value1 as u8) << bit_idx;
self.value2[byte_idx] &= mask;
self.value2[byte_idx] |= (share.value2 as u8) << bit_idx;
}
pub fn push(&mut self, value1: bool, value2: bool) {
let index = self.length as usize;
if index >= self.value1.len() * 8 {
self.value1.push(0);
self.value2.push(0);
}
let byte_idx = index >> 3;
let bit_idx = index & 0x7;
self.value1[byte_idx] |= (value1 as u8) << bit_idx;
self.value2[byte_idx] |= (value2 as u8) << bit_idx;
self.length += 1;
}
pub fn push_binary_share(&mut self, share: BinaryShare) {
let index = self.length as usize;
if index >= self.value1.len() * 8 {
self.value1.push(0);
self.value2.push(0);
}
let byte_idx = index >> 3;
let bit_idx = index & 0x7;
self.value1[byte_idx] |= (share.value1 as u8) << bit_idx;
self.value2[byte_idx] |= (share.value2 as u8) << bit_idx;
self.length += 1;
}
pub fn reverse(&mut self) {
let mut newout = Self::with_capacity(self.length as usize);
for i in (0..self.length as usize).rev() {
newout.push_binary_share(self.get_binary_share(i));
}
self.value1 = newout.value1;
self.value2 = newout.value2;
}
pub fn extend(&mut self, val: &Self) {
for i in 0..(val.length as usize) {
let tup = val.get(i);
self.push(tup.0, tup.1);
}
}
pub fn not(&self) -> Self {
let mut value2 = self.value2.clone();
#[allow(clippy::needless_range_loop)]
for i in 0..self.value2.len() {
value2[i] ^= 0xFF;
}
Self {
length: self.length,
value1: self.value1.clone(),
value2,
}
}
pub fn xor(&self, other: &Self) -> BinaryStringShare {
assert_eq!(
self.length, other.length,
"BinaryStringShare instances must have the same length"
);
let mut value1 = Vec::new();
let mut value2 = Vec::new();
for i in 0..self.value1.len() {
value1.push(self.value1[i] ^ other.value1[i]);
value2.push(self.value2[i] ^ other.value2[i]);
}
BinaryStringShare {
length: self.length,
value1,
value2,
}
}
pub fn xor_scalar(&self, scalar: &BinaryString) -> BinaryStringShare {
assert_eq!(
self.length, scalar.length,
"BinaryStringShare and BinaryString instances must have the same length"
);
let mut value2 = Vec::new();
for i in 0..self.value2.len() {
value2.push(self.value2[i] ^ scalar.value[i]);
}
BinaryStringShare {
length: self.length,
value1: self.value1.clone(),
value2,
}
}
pub fn and_scalar(&self, scalar: &BinaryString) -> BinaryStringShare {
assert_eq!(
self.length, scalar.length,
"BinaryStringShare and BinaryString instances must have the same length"
);
let mut value1 = Vec::new();
let mut value2 = Vec::new();
for i in 0..self.value2.len() {
value1.push(self.value1[i] & scalar.value[i]);
value2.push(self.value2[i] & scalar.value[i]);
}
BinaryStringShare {
length: self.length,
value1,
value2,
}
}
pub fn and_bitwise(
&self,
other: &Self,
randomness: &mut CommonRandomness,
) -> BinaryString {
assert_eq!(self.length, other.length);
let n = self.length as usize;
let mut value = Vec::new();
for _ in 0..self.length_in_bytes() {
value.push(randomness.random_zero_byte());
}
let alpha = BinaryString {
length: n as u64,
value,
};
let mut res = BinaryString::new_with_zeros(n);
for i in 0..self.length_in_bytes() {
res.value[i] = (self.value1[i] & other.value1[i])
^ (self.value2[i] & other.value2[i])
^ alpha.value[i];
}
res
}
pub fn _slice(&self, start: usize, end: usize) -> BinaryStringShare {
assert!(start <= end, "Start index cannot be greater than end index");
assert!(
end <= self.length as usize,
"End index exceeds BinaryStringShare length"
);
let mut result = BinaryStringShare::with_capacity(end - start);
for i in start..end {
let (bit1, bit2) = self.get(i);
result.push(bit1, bit2);
}
result
}
pub fn append(&mut self, other: &Self) {
assert_eq!(self.length % 8, 0);
assert_eq!(other.length % 8, 0);
self.length += other.length;
self.value1.extend_from_slice(&other.value1);
self.value2.extend_from_slice(&other.value2);
}
pub fn split(&self, index: usize) -> (Self, Self) {
assert_eq!(self.length % 8, 0);
assert_eq!(index % 8, 0);
assert!(
index <= self.length as usize,
"End index exceeds BinaryStringShare length"
);
let index_in_bytes = index / 8;
let r1 = BinaryStringShare {
length: index as u64,
value1: self.value1[0..index_in_bytes].to_vec(),
value2: self.value2[0..index_in_bytes].to_vec(),
};
let r2 = BinaryStringShare {
length: self.length - index as u64,
value1: self.value1[index_in_bytes..].to_vec(),
value2: self.value2[index_in_bytes..].to_vec(),
};
(r1, r2)
}
pub fn append_with_padding(&mut self, other: &Self) {
self.length = (self.length + 7) / 8 * 8;
self.length += (other.value1.len() * 8) as u64;
self.value1.extend_from_slice(&other.value1);
self.value2.extend_from_slice(&other.value2);
}
pub fn append_arith_with_padding(
&mut self,
other: &BinaryArithmeticShare,
) {
self.length = (self.length + 7) / 8 * 8;
self.length += (other.value1.len() * 8) as u64;
self.value1.extend_from_slice(&other.value1);
self.value2.extend_from_slice(&other.value2);
}
}
#[derive(Clone, Debug)]
pub struct CommonRandomness {
f1: ChaCha20Rng,
f2: ChaCha20Rng,
}
impl CommonRandomness {
pub fn new(key_prev: [u8; 32], key_next: [u8; 32]) -> Self {
CommonRandomness {
f1: ChaCha20Rng::from_seed(key_prev),
f2: ChaCha20Rng::from_seed(key_next),
}
}
pub fn random_zero_bool(&mut self) -> bool {
let rb: bool = self.f2.r#gen();
let ra: bool = self.f1.r#gen();
rb ^ ra
}
pub fn random_bit(&mut self) -> [bool; 2] {
let rb: bool = self.f2.r#gen();
let ra: bool = self.f1.r#gen();
[ra ^ rb, rb]
}
pub fn random_zero_byte(&mut self) -> u8 {
let rb: u8 = self.f2.r#gen();
let ra: u8 = self.f1.r#gen();
rb ^ ra
}
pub fn random_byte_share(&mut self) -> [u8; 2] {
let rb: u8 = self.f2.r#gen();
let ra: u8 = self.f1.r#gen();
[ra ^ rb, rb]
}
pub fn random_8_bytes(&mut self) -> ([u8; 8], [u8; 8]) {
let ra: [u8; 8] = self.f1.r#gen();
let rb: [u8; 8] = self.f2.r#gen();
(ra, rb)
}
pub fn random_32_bytes(&mut self) -> ([u8; 32], [u8; 32]) {
let ra: [u8; 32] = self.f1.r#gen();
let rb: [u8; 32] = self.f2.r#gen();
(ra, rb)
}
pub fn random_binary_string_share(
&mut self,
l: usize,
) -> BinaryStringShare {
let size_in_bytes = (l + 7) / 8;
let mut value1 = Vec::with_capacity(size_in_bytes);
let mut value2 = Vec::with_capacity(size_in_bytes);
for _ in 0..size_in_bytes {
let [v1, v2] = self.random_byte_share();
value1.push(v1);
value2.push(v2);
}
BinaryStringShare {
length: l as u64,
value1,
value2,
}
}
}
#[derive(Clone, Debug, Default)]
pub struct MultTripleStorage {
pub a: BinaryStringShare,
pub b: BinaryStringShare,
pub c: BinaryStringShare,
}
impl MultTripleStorage {
pub fn new() -> Self {
MultTripleStorage {
a: BinaryStringShare::new(),
b: BinaryStringShare::new(),
c: BinaryStringShare::new(),
}
}
pub fn push(&mut self, a: BinaryShare, b: BinaryShare) {
self.a.push_binary_share(a);
self.b.push_binary_share(b);
}
pub fn insert_c(&mut self, c: BinaryShare) {
self.c.push_binary_share(c);
}
pub fn push_a_b_binary_string_share(
&mut self,
a: &BinaryStringShare,
b: &BinaryStringShare,
) {
self.a.append_with_padding(a);
self.b.append_with_padding(b);
}
pub fn insert_c_binary_string_share(&mut self, c: &BinaryStringShare) {
self.c.append_with_padding(c);
}
pub fn push_a_b_binary_arith_shares(
&mut self,
a: &BinaryArithmeticShare,
b: &BinaryArithmeticShare,
) {
self.a.append_arith_with_padding(a);
self.b.append_arith_with_padding(b);
}
pub fn insert_c_binary_arith_share(&mut self, c: &BinaryArithmeticShare) {
self.c.append_arith_with_padding(c);
}
pub fn len(&self) -> usize {
self.a.length as usize
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
}
#[derive(Clone, Debug)]
pub struct ServerState {
pub common_randomness: CommonRandomness,
pub and_triples: MultTripleStorage,
pub unverified_list: BinaryString,
pub ver: (BinaryStringShare, BinaryStringShare, BinaryStringShare),
pub rep: (BinaryStringShare, BinaryStringShare, BinaryStringShare),
}
impl ServerState {
pub fn new(common_randomness: CommonRandomness) -> Self {
ServerState {
common_randomness,
and_triples: MultTripleStorage::new(),
unverified_list: BinaryString::new(),
ver: (
BinaryStringShare::with_capacity(N),
BinaryStringShare::with_capacity(N),
BinaryStringShare::with_capacity(N),
),
rep: (
BinaryStringShare::with_capacity(N),
BinaryStringShare::with_capacity(N),
BinaryStringShare::with_capacity(N),
),
}
}
}
pub fn binary_string_to_u8_vec(input: BinaryString) -> Vec<u8> {
let mut vec_u8 = Vec::new();
let mut byte = 0u8;
for i in 0..(input.length as usize) {
if input.get(i) {
byte |= 1 << (7 - (i % 8));
}
if i % 8 == 7 {
vec_u8.push(byte);
byte = 0;
}
}
if input.length % 8 != 0 {
vec_u8.push(byte);
}
vec_u8
}