sl_compute_common/
lib.rs

1// Copyright (c) Silence Laboratories Pte. Ltd. All Rights Reserved.
2// This software is licensed under the Silence Laboratories License Agreement.
3
4use std::mem;
5use std::ops::Index;
6
7use aead::rand_core::SeedableRng;
8use crypto_bigint::{Encoding, U64};
9use rand::Rng;
10use rand_chacha::ChaCha20Rng;
11use serde::{Deserialize, Serialize};
12
13mod constants;
14
15use crate::constants::{FIELD_SIZE, FIELD_SIZE_BYTES, FRACTION_LENGTH, N};
16
17pub type FieldElement = U64;
18pub type Binary = bool;
19
20pub trait ExtractBit: Index<usize, Output = u8> {
21    fn extract_bit(&self, idx: usize) -> bool {
22        let byte_idx = idx >> 3;
23        let bit_idx = idx & 0x7;
24        let byte = self[byte_idx];
25
26        ((byte >> bit_idx) & 1) != 0
27    }
28}
29
30impl ExtractBit for Vec<u8> {}
31impl<const T: usize> ExtractBit for [u8; T] {}
32
33#[derive(Copy, Clone, Default, Debug)]
34pub struct BinaryArithmetic {
35    pub value: [u8; FIELD_SIZE_BYTES],
36}
37
38impl BinaryArithmetic {
39    /// ZERO BinaryArithmetic
40    pub const ZERO: BinaryArithmetic = BinaryArithmetic {
41        value: [0u8; FIELD_SIZE_BYTES],
42    };
43
44    pub fn get_external_size(&self) -> usize {
45        FIELD_SIZE_BYTES
46    }
47
48    pub fn from_binary_string(b: &BinaryString) -> Self {
49        let len = b.value.len();
50        assert!(len <= FIELD_SIZE_BYTES);
51
52        let mut value = b.value.clone();
53
54        if len != FIELD_SIZE_BYTES {
55            let zero_pad = FIELD_SIZE_BYTES - len;
56            value.extend(std::iter::repeat(0u8).take(zero_pad));
57        }
58        BinaryArithmetic {
59            value: value.try_into().unwrap(),
60        }
61    }
62
63    pub fn to_binary_string(&self, len: usize) -> BinaryString {
64        let in_bytes = len.div_ceil(8);
65
66        let value = &self.value[0..in_bytes];
67
68        BinaryString {
69            length: len as u64,
70            value: value.to_vec(),
71        }
72    }
73
74    pub fn xor(&self, other: &Self) -> Self {
75        let mut value = self.value;
76        #[allow(clippy::needless_range_loop)]
77        for i in 0..FIELD_SIZE_BYTES {
78            value[i] ^= other.value[i];
79        }
80        BinaryArithmetic { value }
81    }
82}
83
84#[derive(Copy, Clone, Default, Debug)]
85pub struct BinaryArithmeticShare {
86    pub value1: [u8; FIELD_SIZE_BYTES],
87    pub value2: [u8; FIELD_SIZE_BYTES],
88}
89
90impl BinaryArithmeticShare {
91    /// ZERO BinaryArithmeticShare
92    pub const ZERO: BinaryArithmeticShare = BinaryArithmeticShare {
93        value1: [0u8; FIELD_SIZE_BYTES],
94        value2: [0u8; FIELD_SIZE_BYTES],
95    };
96
97    pub fn new(
98        value1: [u8; FIELD_SIZE_BYTES],
99        value2: [u8; FIELD_SIZE_BYTES],
100    ) -> BinaryArithmeticShare {
101        BinaryArithmeticShare { value1, value2 }
102    }
103
104    /// Returns party share for constant value
105    pub fn from_constant(c: &FieldElement, party_index: usize) -> Self {
106        let v = c
107            .wrapping_mul(&FieldElement::from(1u64 << FRACTION_LENGTH))
108            .to_le_bytes();
109        match party_index {
110            0 => BinaryArithmeticShare {
111                value1: v,
112                value2: v,
113            },
114            1 => BinaryArithmeticShare {
115                value1: v,
116                value2: [0u8; FIELD_SIZE_BYTES],
117            },
118            _ => BinaryArithmeticShare::ZERO,
119        }
120    }
121
122    /// Reconstruct value with value1 from previous party
123    pub fn reconstruct(&self, other: &BinaryArithmetic) -> BinaryArithmetic {
124        let mut value = self.value2;
125        #[allow(clippy::needless_range_loop)]
126        for i in 0..FIELD_SIZE_BYTES {
127            value[i] ^= other.value[i];
128        }
129        BinaryArithmetic { value }
130    }
131
132    pub fn from_own_and_other(
133        own: &BinaryArithmetic,
134        other: &BinaryArithmetic,
135    ) -> BinaryArithmeticShare {
136        let mut value1 = own.value;
137        #[allow(clippy::needless_range_loop)]
138        for i in 0..FIELD_SIZE_BYTES {
139            value1[i] ^= other.value[i];
140        }
141        BinaryArithmeticShare {
142            value1,
143            value2: own.value,
144        }
145    }
146
147    /// Create BinaryArithmeticShare from BinaryShare
148    pub fn from_binary_share(
149        from_share: &BinaryShare,
150    ) -> BinaryArithmeticShare {
151        let mut share = BinaryArithmeticShare::default();
152        let byte_idx = FRACTION_LENGTH >> 3;
153        let bit_idx = FRACTION_LENGTH & 0x7;
154        if from_share.value1 {
155            share.value1[byte_idx] |= 1 << bit_idx;
156        }
157        if from_share.value2 {
158            share.value2[byte_idx] |= 1 << bit_idx;
159        }
160        share
161    }
162
163    pub fn to_binary_string_share(&self) -> BinaryStringShare {
164        BinaryStringShare {
165            length: FIELD_SIZE as u64,
166            value1: self.value1.to_vec(),
167            value2: self.value2.to_vec(),
168        }
169    }
170
171    pub fn from_binary_string_share(
172        from_share: &BinaryStringShare,
173    ) -> BinaryArithmeticShare {
174        assert_eq!(from_share.length, FIELD_SIZE as u64);
175        BinaryArithmeticShare {
176            value1: from_share.value1.clone().try_into().unwrap(),
177            value2: from_share.value2.clone().try_into().unwrap(),
178        }
179    }
180
181    pub fn from_choice(c: &BinaryShare) -> Self {
182        let v1 = c.value1;
183        let v2 = c.value2;
184
185        let value1 = match v1 {
186            true => [255u8; FIELD_SIZE_BYTES],
187            false => [0u8; FIELD_SIZE_BYTES],
188        };
189
190        let value2 = match v2 {
191            true => [255u8; FIELD_SIZE_BYTES],
192            false => [0u8; FIELD_SIZE_BYTES],
193        };
194
195        BinaryArithmeticShare { value1, value2 }
196    }
197
198    pub fn xor(&self, other: &Self) -> BinaryArithmeticShare {
199        let mut value1 = self.value1;
200        let mut value2 = self.value2;
201        for i in 0..FIELD_SIZE_BYTES {
202            value1[i] ^= other.value1[i];
203            value2[i] ^= other.value2[i];
204        }
205        BinaryArithmeticShare { value1, value2 }
206    }
207
208    pub fn not(&self) -> Self {
209        let mut value2 = self.value2;
210        #[allow(clippy::needless_range_loop)]
211        for i in 0..FIELD_SIZE_BYTES {
212            value2[i] ^= 0xFF;
213        }
214        BinaryArithmeticShare {
215            value1: self.value1,
216            value2,
217        }
218    }
219
220    pub fn and_bitwise(
221        &self,
222        other: &Self,
223        randomness: &mut CommonRandomness,
224    ) -> BinaryArithmetic {
225        let mut alpha_bytes = [0u8; FIELD_SIZE_BYTES];
226        #[allow(clippy::needless_range_loop)]
227        for i in 0..FIELD_SIZE_BYTES {
228            let mut alpha_byte = 0u8;
229            for j in 0..8 {
230                let alpha = randomness.random_zero_bool() as u8;
231                alpha_byte |= alpha << j;
232            }
233            alpha_bytes[i] = alpha_byte
234        }
235        let mut res = [0u8; FIELD_SIZE_BYTES];
236        for i in 0..FIELD_SIZE_BYTES {
237            res[i] = (self.value1[i] & other.value1[i])
238                ^ (self.value2[i] & other.value2[i])
239                ^ alpha_bytes[i];
240        }
241
242        BinaryArithmetic { value: res }
243    }
244
245    pub fn get_binary_share(&self, index: usize) -> BinaryShare {
246        let bit1 = self.value1.extract_bit(index);
247        let bit2 = self.value2.extract_bit(index);
248        BinaryShare {
249            value1: bit1,
250            value2: bit2,
251        }
252    }
253
254    pub fn set_binary_share(&mut self, index: usize, share: BinaryShare) {
255        let byte_idx = index >> 3;
256        let bit_idx = index & 0x7;
257
258        assert!(
259            byte_idx < self.value1.len(),
260            "No value assigned to the index yet!! {} {}",
261            byte_idx,
262            self.value1.len()
263        );
264
265        let mask = !(1 << bit_idx);
266
267        self.value1[byte_idx] &= mask;
268        self.value1[byte_idx] |= (share.value1 as u8) << bit_idx;
269
270        self.value2[byte_idx] &= mask;
271        self.value2[byte_idx] |= (share.value2 as u8) << bit_idx;
272    }
273
274    pub fn left_shift(&self, shift: usize) -> BinaryArithmeticShare {
275        let v1 = FieldElement::from_le_slice(&self.value1).shl(shift);
276        let v2 = FieldElement::from_le_slice(&self.value2).shl(shift);
277
278        BinaryArithmeticShare {
279            value1: v1.to_le_bytes(),
280            value2: v2.to_le_bytes(),
281        }
282    }
283}
284#[derive(Clone, Default, Debug, Serialize, Deserialize, PartialEq)]
285pub struct BinaryString {
286    pub length: u64,
287    pub value: Vec<u8>,
288}
289
290impl BinaryString {
291    pub fn new() -> Self {
292        BinaryString {
293            length: 0,
294            value: Vec::new(),
295        }
296    }
297
298    pub fn new_with_zeros(size_in_bits: usize) -> Self {
299        let size_in_bytes = (size_in_bits + 7) / 8;
300        BinaryString {
301            length: size_in_bits as u64,
302            value: vec![0u8; size_in_bytes],
303        }
304    }
305
306    pub fn length_in_bytes(&self) -> usize {
307        if (self.length % 8) == 0 {
308            (self.length / 8) as usize
309        } else {
310            (self.length / 8) as usize + 1
311        }
312    }
313
314    pub fn get_external_size(&self) -> usize {
315        mem::size_of::<u64>() + self.length_in_bytes()
316    }
317
318    pub fn with_capacity(size: usize) -> Self {
319        let num_bytes = (size + 7) / 8;
320        BinaryString {
321            length: 0_u64,
322            value: Vec::with_capacity(num_bytes),
323        }
324    }
325
326    pub fn get(&self, index: usize) -> bool {
327        self.value.extract_bit(index)
328    }
329
330    pub fn set(&mut self, index: usize, value: bool) {
331        let byte_idx = index >> 3;
332        let bit_idx = index & 0x7;
333
334        assert!(
335            byte_idx < self.value.len(),
336            "No value assigned to the index yet!! {} {}",
337            byte_idx,
338            self.value.len()
339        );
340
341        self.value[byte_idx] &= !(1 << bit_idx);
342        self.value[byte_idx] |= (value as u8) << bit_idx;
343    }
344
345    pub fn push(&mut self, value: bool) {
346        let index = self.length as usize;
347
348        if index >= self.value.len() * 8 {
349            self.value.push(0);
350        }
351
352        let byte_idx = index >> 3;
353        let bit_idx = index & 0x7;
354        self.value[byte_idx] |= (value as u8) << bit_idx;
355
356        self.length += 1;
357    }
358
359    pub fn reverse(&mut self) {
360        let mut newout = Self::with_capacity(self.length as usize);
361
362        for i in (0..self.length as usize).rev() {
363            newout.push(self.get(i));
364        }
365
366        self.value = newout.value;
367    }
368
369    pub fn extend(&mut self, val: &Self) {
370        for i in 0..(val.length as usize) {
371            self.push(val.get(i));
372        }
373    }
374
375    pub fn xor(&self, other: &Self) -> BinaryString {
376        assert_eq!(
377            self.length, other.length,
378            "BinaryString instances must have the same length"
379        );
380        let mut value = Vec::new();
381        for i in 0..self.value.len() {
382            value.push(self.value[i] ^ other.value[i]);
383        }
384        BinaryString {
385            length: self.length,
386            value,
387        }
388    }
389
390    pub fn and(&self, other: &Self) -> BinaryString {
391        assert_eq!(
392            self.length, other.length,
393            "BinaryString instances must have the same length"
394        );
395        let mut value = Vec::new();
396        for i in 0..self.value.len() {
397            value.push(self.value[i] & other.value[i]);
398        }
399        BinaryString {
400            length: self.length,
401            value,
402        }
403    }
404
405    pub fn _slice(&self, start: usize, end: usize) -> BinaryString {
406        assert!(start <= end, "Start index cannot be greater than end index");
407        assert!(
408            end <= self.length as usize,
409            "End index exceeds BinaryStringShare length"
410        );
411
412        let mut result = BinaryString::with_capacity(end - start);
413
414        for i in start..end {
415            result.push(self.get(i));
416        }
417
418        result
419    }
420
421    pub fn split(&self, index: usize) -> (Self, Self) {
422        assert_eq!(self.length % 8, 0);
423        assert_eq!(index % 8, 0);
424        assert!(
425            index <= self.length as usize,
426            "End index exceeds BinaryString length"
427        );
428
429        let index_in_bytes = index / 8;
430        let r1 = BinaryString {
431            length: index as u64,
432            value: self.value[0..index_in_bytes].to_vec(),
433        };
434
435        let r2 = BinaryString {
436            length: self.length - index as u64,
437            value: self.value[index_in_bytes..].to_vec(),
438        };
439
440        (r1, r2)
441    }
442
443    /// Use only for unverified_list
444    pub fn append_bytes_with_padding(&mut self, other: &[u8]) {
445        // pad length
446        self.length = (self.length + 7) / 8 * 8;
447        self.length += other.len() as u64;
448        self.value.extend_from_slice(other);
449    }
450}
451#[derive(Clone, Debug, Copy, Serialize, Deserialize)]
452pub struct BinaryShare {
453    pub value1: Binary,
454    pub value2: Binary,
455}
456
457impl BinaryShare {
458    /// ZERO BinaryShare
459    pub const ZERO: BinaryShare = BinaryShare {
460        value1: false,
461        value2: false,
462    };
463
464    pub fn from_constant(value: Binary, party_index: usize) -> Self {
465        match party_index {
466            0 => BinaryShare {
467                value1: value,
468                value2: value,
469            },
470            1 => BinaryShare {
471                value1: value,
472                value2: false,
473            },
474            _ => BinaryShare::ZERO,
475        }
476    }
477
478    pub fn not(&self) -> BinaryShare {
479        BinaryShare {
480            value1: self.value1,
481            value2: self.value2 ^ true,
482        }
483    }
484
485    pub fn xor(&self, other: &BinaryShare) -> BinaryShare {
486        BinaryShare {
487            value1: self.value1 ^ other.value1,
488            value2: self.value2 ^ other.value2,
489        }
490    }
491
492    pub fn and_bitwise(
493        &self,
494        other: &BinaryShare,
495        randomness: &mut CommonRandomness,
496    ) -> Binary {
497        let alpha = randomness.random_zero_bool();
498        (self.value1 & other.value1) ^ (self.value2 & other.value2) ^ alpha
499    }
500}
501
502#[derive(Clone, Default, Debug, Serialize, Deserialize)]
503pub struct BinaryStringShare {
504    pub length: u64,
505    pub value1: Vec<u8>,
506    pub value2: Vec<u8>,
507}
508
509impl BinaryStringShare {
510    pub fn new() -> Self {
511        BinaryStringShare {
512            length: 0,
513            value1: Vec::new(),
514            value2: Vec::new(),
515        }
516    }
517
518    pub fn zero(length: usize) -> Self {
519        let num_bytes = (length + 7) / 8;
520        BinaryStringShare {
521            length: length as u64,
522            value1: vec![0u8; num_bytes],
523            value2: vec![0u8; num_bytes],
524        }
525    }
526
527    pub fn from_constant(c: &BinaryString, party_index: usize) -> Self {
528        match party_index {
529            0 => BinaryStringShare {
530                length: c.length,
531                value1: c.value.clone(),
532                value2: c.value.clone(),
533            },
534            1 => BinaryStringShare {
535                length: c.length,
536                value1: c.value.clone(),
537                value2: vec![0u8; c.value.len()],
538            },
539            _ => BinaryStringShare {
540                length: c.length,
541                value1: vec![0u8; c.value.len()],
542                value2: vec![0u8; c.value.len()],
543            },
544        }
545    }
546
547    pub fn from_choice(c: &BinaryShare, size: usize) -> Self {
548        let v1 = c.value1;
549        let v2 = c.value2;
550        let mut res = BinaryStringShare::with_capacity(size);
551        for _ in 0..size {
552            res.push(v1, v2)
553        }
554        res
555    }
556
557    pub fn length_in_bytes(&self) -> usize {
558        if (self.length % 8) == 0 {
559            (self.length / 8) as usize
560        } else {
561            (self.length / 8) as usize + 1
562        }
563    }
564
565    pub fn get_external_size(&self) -> usize {
566        mem::size_of::<u64>() + self.length_in_bytes() * 2
567    }
568
569    pub fn with_capacity(size: usize) -> Self {
570        let num_bytes = (size + 7) / 8;
571        BinaryStringShare {
572            length: 0_u64,
573            value1: Vec::with_capacity(num_bytes),
574            value2: Vec::with_capacity(num_bytes),
575        }
576    }
577
578    pub fn get(&self, index: usize) -> (bool, bool) {
579        let bit1 = self.value1.extract_bit(index);
580        let bit2 = self.value2.extract_bit(index);
581        (bit1, bit2)
582    }
583
584    pub fn get_binary_share(&self, index: usize) -> BinaryShare {
585        let bit1 = self.value1.extract_bit(index);
586        let bit2 = self.value2.extract_bit(index);
587        BinaryShare {
588            value1: bit1,
589            value2: bit2,
590        }
591    }
592
593    pub fn set(&mut self, index: usize, value1: bool, value2: bool) {
594        let byte_idx = index >> 3;
595        let bit_idx = index & 0x7;
596
597        assert!(
598            byte_idx < self.value1.len(),
599            "No value assigned to the index yet!! {} {}",
600            byte_idx,
601            self.value1.len()
602        );
603
604        let mask = !(1 << bit_idx);
605
606        self.value1[byte_idx] &= mask;
607        self.value1[byte_idx] |= (value1 as u8) << bit_idx;
608
609        self.value2[byte_idx] &= mask;
610        self.value2[byte_idx] |= (value2 as u8) << bit_idx;
611    }
612
613    pub fn set_binary_share(&mut self, index: usize, share: &BinaryShare) {
614        let byte_idx = index >> 3;
615        let bit_idx = index & 0x7;
616
617        assert!(
618            byte_idx < self.value1.len(),
619            "No value assigned to the index yet!! {} {}",
620            byte_idx,
621            self.value1.len()
622        );
623
624        let mask = !(1 << bit_idx);
625
626        self.value1[byte_idx] &= mask;
627        self.value1[byte_idx] |= (share.value1 as u8) << bit_idx;
628
629        self.value2[byte_idx] &= mask;
630        self.value2[byte_idx] |= (share.value2 as u8) << bit_idx;
631    }
632
633    pub fn push(&mut self, value1: bool, value2: bool) {
634        let index = self.length as usize;
635
636        if index >= self.value1.len() * 8 {
637            self.value1.push(0);
638            self.value2.push(0);
639        }
640
641        let byte_idx = index >> 3;
642        let bit_idx = index & 0x7;
643        self.value1[byte_idx] |= (value1 as u8) << bit_idx;
644        self.value2[byte_idx] |= (value2 as u8) << bit_idx;
645
646        self.length += 1;
647    }
648
649    pub fn push_binary_share(&mut self, share: BinaryShare) {
650        let index = self.length as usize;
651
652        if index >= self.value1.len() * 8 {
653            self.value1.push(0);
654            self.value2.push(0);
655        }
656
657        let byte_idx = index >> 3;
658        let bit_idx = index & 0x7;
659        self.value1[byte_idx] |= (share.value1 as u8) << bit_idx;
660        self.value2[byte_idx] |= (share.value2 as u8) << bit_idx;
661
662        self.length += 1;
663    }
664
665    pub fn reverse(&mut self) {
666        let mut newout = Self::with_capacity(self.length as usize);
667
668        for i in (0..self.length as usize).rev() {
669            newout.push_binary_share(self.get_binary_share(i));
670        }
671
672        self.value1 = newout.value1;
673        self.value2 = newout.value2;
674    }
675
676    pub fn extend(&mut self, val: &Self) {
677        for i in 0..(val.length as usize) {
678            let tup = val.get(i);
679            self.push(tup.0, tup.1);
680        }
681    }
682
683    pub fn not(&self) -> Self {
684        let mut value2 = self.value2.clone();
685        #[allow(clippy::needless_range_loop)]
686        for i in 0..self.value2.len() {
687            value2[i] ^= 0xFF;
688        }
689        Self {
690            length: self.length,
691            value1: self.value1.clone(),
692            value2,
693        }
694    }
695
696    pub fn xor(&self, other: &Self) -> BinaryStringShare {
697        assert_eq!(
698            self.length, other.length,
699            "BinaryStringShare instances must have the same length"
700        );
701        let mut value1 = Vec::new();
702        let mut value2 = Vec::new();
703
704        for i in 0..self.value1.len() {
705            value1.push(self.value1[i] ^ other.value1[i]);
706            value2.push(self.value2[i] ^ other.value2[i]);
707        }
708        BinaryStringShare {
709            length: self.length,
710            value1,
711            value2,
712        }
713    }
714
715    pub fn xor_scalar(&self, scalar: &BinaryString) -> BinaryStringShare {
716        assert_eq!(
717            self.length, scalar.length,
718            "BinaryStringShare and BinaryString instances must have the same length"
719        );
720        let mut value2 = Vec::new();
721
722        for i in 0..self.value2.len() {
723            value2.push(self.value2[i] ^ scalar.value[i]);
724        }
725        BinaryStringShare {
726            length: self.length,
727            value1: self.value1.clone(),
728            value2,
729        }
730    }
731
732    pub fn and_scalar(&self, scalar: &BinaryString) -> BinaryStringShare {
733        assert_eq!(
734            self.length, scalar.length,
735            "BinaryStringShare and BinaryString instances must have the same length"
736        );
737        let mut value1 = Vec::new();
738        let mut value2 = Vec::new();
739
740        for i in 0..self.value2.len() {
741            value1.push(self.value1[i] & scalar.value[i]);
742            value2.push(self.value2[i] & scalar.value[i]);
743        }
744        BinaryStringShare {
745            length: self.length,
746            value1,
747            value2,
748        }
749    }
750
751    pub fn and_bitwise(
752        &self,
753        other: &Self,
754        randomness: &mut CommonRandomness,
755    ) -> BinaryString {
756        assert_eq!(self.length, other.length);
757        let n = self.length as usize;
758
759        let mut value = Vec::new();
760        for _ in 0..self.length_in_bytes() {
761            value.push(randomness.random_zero_byte());
762        }
763        let alpha = BinaryString {
764            length: n as u64,
765            value,
766        };
767
768        let mut res = BinaryString::new_with_zeros(n);
769        for i in 0..self.length_in_bytes() {
770            res.value[i] = (self.value1[i] & other.value1[i])
771                ^ (self.value2[i] & other.value2[i])
772                ^ alpha.value[i];
773        }
774        res
775    }
776
777    pub fn _slice(&self, start: usize, end: usize) -> BinaryStringShare {
778        assert!(start <= end, "Start index cannot be greater than end index");
779        assert!(
780            end <= self.length as usize,
781            "End index exceeds BinaryStringShare length"
782        );
783
784        let mut result = BinaryStringShare::with_capacity(end - start);
785
786        for i in start..end {
787            let (bit1, bit2) = self.get(i);
788            result.push(bit1, bit2);
789        }
790
791        result
792    }
793
794    pub fn append(&mut self, other: &Self) {
795        assert_eq!(self.length % 8, 0);
796        assert_eq!(other.length % 8, 0);
797        self.length += other.length;
798        self.value1.extend_from_slice(&other.value1);
799        self.value2.extend_from_slice(&other.value2);
800    }
801
802    pub fn split(&self, index: usize) -> (Self, Self) {
803        assert_eq!(self.length % 8, 0);
804        assert_eq!(index % 8, 0);
805        assert!(
806            index <= self.length as usize,
807            "End index exceeds BinaryStringShare length"
808        );
809
810        let index_in_bytes = index / 8;
811        let r1 = BinaryStringShare {
812            length: index as u64,
813            value1: self.value1[0..index_in_bytes].to_vec(),
814            value2: self.value2[0..index_in_bytes].to_vec(),
815        };
816
817        let r2 = BinaryStringShare {
818            length: self.length - index as u64,
819            value1: self.value1[index_in_bytes..].to_vec(),
820            value2: self.value2[index_in_bytes..].to_vec(),
821        };
822
823        (r1, r2)
824    }
825
826    /// Use only for verify mult triples
827    pub fn append_with_padding(&mut self, other: &Self) {
828        // pad length
829        self.length = (self.length + 7) / 8 * 8;
830        self.length += (other.value1.len() * 8) as u64;
831        self.value1.extend_from_slice(&other.value1);
832        self.value2.extend_from_slice(&other.value2);
833    }
834
835    /// Use only for verify mult triples
836    pub fn append_arith_with_padding(
837        &mut self,
838        other: &BinaryArithmeticShare,
839    ) {
840        // pad length
841        self.length = (self.length + 7) / 8 * 8;
842        self.length += (other.value1.len() * 8) as u64;
843        self.value1.extend_from_slice(&other.value1);
844        self.value2.extend_from_slice(&other.value2);
845    }
846}
847
848#[derive(Clone, Debug)]
849pub struct CommonRandomness {
850    f1: ChaCha20Rng,
851    f2: ChaCha20Rng,
852}
853
854impl CommonRandomness {
855    /// New CommonRandomness
856    pub fn new(key_prev: [u8; 32], key_next: [u8; 32]) -> Self {
857        CommonRandomness {
858            f1: ChaCha20Rng::from_seed(key_prev),
859            f2: ChaCha20Rng::from_seed(key_next),
860        }
861    }
862
863    /// Implementation of the Protocol 2.3.2. RandomZero()
864    pub fn random_zero_bool(&mut self) -> bool {
865        let rb: bool = self.f2.r#gen();
866        let ra: bool = self.f1.r#gen();
867        rb ^ ra
868    }
869
870    /// Implementation of the Protocol 2.3.3. RandomBit()
871    pub fn random_bit(&mut self) -> [bool; 2] {
872        let rb: bool = self.f2.r#gen();
873        let ra: bool = self.f1.r#gen();
874        [ra ^ rb, rb]
875    }
876
877    /// RandomZeroByte()
878    pub fn random_zero_byte(&mut self) -> u8 {
879        let rb: u8 = self.f2.r#gen();
880        let ra: u8 = self.f1.r#gen();
881        rb ^ ra
882    }
883
884    /// RandomByte()
885    pub fn random_byte_share(&mut self) -> [u8; 2] {
886        let rb: u8 = self.f2.r#gen();
887        let ra: u8 = self.f1.r#gen();
888        [ra ^ rb, rb]
889    }
890
891    /// Returns (random_prev: [u8; 8], random_next: [u8; 8])
892    pub fn random_8_bytes(&mut self) -> ([u8; 8], [u8; 8]) {
893        let ra: [u8; 8] = self.f1.r#gen();
894        let rb: [u8; 8] = self.f2.r#gen();
895        (ra, rb)
896    }
897
898    /// Returns (random_prev: [u8; 32], random_next: [u8; 32])
899    pub fn random_32_bytes(&mut self) -> ([u8; 32], [u8; 32]) {
900        let ra: [u8; 32] = self.f1.r#gen();
901        let rb: [u8; 32] = self.f2.r#gen();
902        (ra, rb)
903    }
904
905    pub fn random_binary_string_share(
906        &mut self,
907        l: usize,
908    ) -> BinaryStringShare {
909        let size_in_bytes = (l + 7) / 8;
910        let mut value1 = Vec::with_capacity(size_in_bytes);
911        let mut value2 = Vec::with_capacity(size_in_bytes);
912        for _ in 0..size_in_bytes {
913            let [v1, v2] = self.random_byte_share();
914            value1.push(v1);
915            value2.push(v2);
916        }
917        BinaryStringShare {
918            length: l as u64,
919            value1,
920            value2,
921        }
922    }
923}
924
925#[derive(Clone, Debug, Default)]
926pub struct MultTripleStorage {
927    pub a: BinaryStringShare,
928    pub b: BinaryStringShare,
929    pub c: BinaryStringShare,
930}
931
932impl MultTripleStorage {
933    pub fn new() -> Self {
934        MultTripleStorage {
935            a: BinaryStringShare::new(),
936            b: BinaryStringShare::new(),
937            c: BinaryStringShare::new(),
938        }
939    }
940
941    pub fn push(&mut self, a: BinaryShare, b: BinaryShare) {
942        self.a.push_binary_share(a);
943        self.b.push_binary_share(b);
944    }
945
946    pub fn insert_c(&mut self, c: BinaryShare) {
947        self.c.push_binary_share(c);
948    }
949
950    pub fn push_a_b_binary_string_share(
951        &mut self,
952        a: &BinaryStringShare,
953        b: &BinaryStringShare,
954    ) {
955        self.a.append_with_padding(a);
956        self.b.append_with_padding(b);
957    }
958
959    pub fn insert_c_binary_string_share(&mut self, c: &BinaryStringShare) {
960        self.c.append_with_padding(c);
961    }
962
963    pub fn push_a_b_binary_arith_shares(
964        &mut self,
965        a: &BinaryArithmeticShare,
966        b: &BinaryArithmeticShare,
967    ) {
968        self.a.append_arith_with_padding(a);
969        self.b.append_arith_with_padding(b);
970    }
971
972    pub fn insert_c_binary_arith_share(&mut self, c: &BinaryArithmeticShare) {
973        self.c.append_arith_with_padding(c);
974    }
975
976    pub fn len(&self) -> usize {
977        self.a.length as usize
978    }
979
980    pub fn is_empty(&self) -> bool {
981        self.len() == 0
982    }
983}
984
985#[derive(Clone, Debug)]
986pub struct ServerState {
987    pub common_randomness: CommonRandomness,
988    pub and_triples: MultTripleStorage,
989    pub unverified_list: BinaryString,
990    pub ver: (BinaryStringShare, BinaryStringShare, BinaryStringShare),
991    pub rep: (BinaryStringShare, BinaryStringShare, BinaryStringShare),
992}
993
994impl ServerState {
995    pub fn new(common_randomness: CommonRandomness) -> Self {
996        ServerState {
997            common_randomness,
998            and_triples: MultTripleStorage::new(),
999            unverified_list: BinaryString::new(),
1000            ver: (
1001                BinaryStringShare::with_capacity(N),
1002                BinaryStringShare::with_capacity(N),
1003                BinaryStringShare::with_capacity(N),
1004            ),
1005            rep: (
1006                BinaryStringShare::with_capacity(N),
1007                BinaryStringShare::with_capacity(N),
1008                BinaryStringShare::with_capacity(N),
1009            ),
1010        }
1011    }
1012}
1013
1014pub fn binary_string_to_u8_vec(input: BinaryString) -> Vec<u8> {
1015    let mut vec_u8 = Vec::new();
1016    let mut byte = 0u8;
1017
1018    for i in 0..(input.length as usize) {
1019        if input.get(i) {
1020            byte |= 1 << (7 - (i % 8));
1021        }
1022        if i % 8 == 7 {
1023            vec_u8.push(byte);
1024            byte = 0;
1025        }
1026    }
1027    if input.length % 8 != 0 {
1028        vec_u8.push(byte);
1029    }
1030
1031    vec_u8
1032}