primitives/correlated_randomness/dabits/
sharing.rs1use itertools::izip;
2use num_traits::identities::{One, Zero};
3
4use crate::{
5 algebra::field::{binary::Gf2_128, Bit, FieldExtension, SubfieldElement},
6 correlated_randomness::dabits::{DaBit, DaBits, OpenDaBit, OpenDaBits},
7 errors::PrimitiveError,
8 sharing::{Reconstructible, VerifiableWith},
9 types::{HeapArray, PeerIndex, Positive},
10};
11impl<F: FieldExtension> Reconstructible for DaBit<F> {
16 type Value = (Bit, SubfieldElement<F>);
17 type Opening = OpenDaBit<F>;
18
19 fn open_to(&self, peer_index: PeerIndex) -> Result<Self::Opening, PrimitiveError> {
21 let opened_bit = self.bit.open_to(peer_index)?;
22
23 Ok(OpenDaBit {
24 opened_bit,
25 opened_field: self.field.open_to(peer_index)?,
26 })
27 }
28
29 fn open_to_all_others(&self) -> impl ExactSizeIterator<Item = Self::Opening> {
31 (0..self.field.get_macs().len())
32 .map(|peer_index| self.open_to(peer_index).expect("Opening should not fail"))
33 }
34
35 fn reconstruct(&self, openings: Vec<Self::Opening>) -> Result<Self::Value, PrimitiveError> {
37 let (bit_openings, field_openings): (Vec<_>, Vec<_>) = openings
38 .iter()
39 .map(|dabit_opening| (dabit_opening.bit(), dabit_opening.field()))
40 .unzip();
41
42 if field_openings.len() != self.field.get_macs().len() {
43 return Err(PrimitiveError::InvalidSize(
44 self.field.get_macs().len(),
45 field_openings.len(),
46 ));
47 }
48
49 let field = self.field.reconstruct(field_openings)?;
50 let bit = self.bit.reconstruct(bit_openings)?;
51
52 Ok((bit, field))
53 }
54}
55
56impl<F: FieldExtension> VerifiableWith for DaBit<F> {
57 type VerificationData = ();
58
59 fn verify_with(&self, openings: Vec<Self::Opening>, _data: ()) -> Result<(), PrimitiveError> {
61 let (bit, field) = self.reconstruct(openings)?;
62
63 if field == SubfieldElement::<F>::one() {
65 if bit != SubfieldElement::<Gf2_128>::one() {
66 return Err(PrimitiveError::WrongCorrelation(
67 "daBit bit does not match the field element.".to_string(),
68 ));
69 }
70 } else if field == SubfieldElement::<F>::zero() {
71 if bit != SubfieldElement::<Gf2_128>::zero() {
72 return Err(PrimitiveError::WrongCorrelation(
73 "daBit bit does not match the field element.".to_string(),
74 ));
75 }
76 } else {
77 return Err(PrimitiveError::WrongCorrelation(
78 "daBit field element is not 0 or 1.".to_string(),
79 ));
80 }
81 Ok(())
82 }
83}
84
85impl<F: FieldExtension, N: Positive> Reconstructible for DaBits<F, N> {
86 type Opening = OpenDaBits<F, N>;
87 type Value = HeapArray<(Bit, SubfieldElement<F>), N>;
88
89 fn open_to(&self, peer_index: PeerIndex) -> Result<Self::Opening, PrimitiveError> {
91 Ok(OpenDaBits {
92 opened_bits: self.bits.open_to(peer_index)?,
93 opened_field_shares: self.field_shares.open_to(peer_index)?,
94 })
95 }
96
97 fn open_to_all_others(&self) -> impl ExactSizeIterator<Item = Self::Opening> {
100 izip!(
101 self.bits.open_to_all_others(),
102 self.field_shares.open_to_all_others()
103 )
104 .map(|(opened_bits, opened_field_shares)| OpenDaBits {
105 opened_bits,
106 opened_field_shares,
107 })
108 }
109
110 fn reconstruct(&self, openings: Vec<Self::Opening>) -> Result<Self::Value, PrimitiveError> {
112 let (bit_openings, field_openings): (Vec<_>, Vec<_>) = openings
113 .into_iter()
114 .map(|dabit_opening| (dabit_opening.opened_bits, dabit_opening.opened_field_shares))
115 .unzip();
116 let bits = self.bits.reconstruct(bit_openings)?;
117 let field_shares = self.field_shares.reconstruct(field_openings)?;
118
119 Ok(HeapArray::from_iter(izip!(
120 bits.into_iter(),
121 field_shares.into_iter()
122 )))
123 }
124}
125
126impl<F: FieldExtension, N: Positive> VerifiableWith for DaBits<F, N> {
127 type VerificationData = ();
128
129 fn verify_with(&self, openings: Vec<Self::Opening>, _data: ()) -> Result<(), PrimitiveError> {
131 let openings = self.reconstruct(openings)?;
132
133 for (bit, field) in openings {
134 if field == SubfieldElement::<F>::one() {
136 if bit != SubfieldElement::<Gf2_128>::one() {
137 return Err(PrimitiveError::WrongCorrelation(
138 "daBit bit does not match the field element.".to_string(),
139 ));
140 }
141 } else if field == SubfieldElement::<F>::zero() {
142 if bit != SubfieldElement::<Gf2_128>::zero() {
143 return Err(PrimitiveError::WrongCorrelation(
144 "daBit bit does not match the field element.".to_string(),
145 ));
146 }
147 } else {
148 return Err(PrimitiveError::WrongCorrelation(
149 "daBit field element is not 0 or 1.".to_string(),
150 ));
151 }
152 }
153
154 Ok(())
155 }
156}