Utility function for preparing secret-shared data. TODO: in the future, we need to make secret-sharing more generic. # Arguments `prng` - PRNG object (for randomness). `data` - array to secret-share. `scalar_type` - scalar type to use. # Returns Vector of shares.
(
prng: &mut PRNG,
data: &[T],
scalar_type: ScalarType,
)
| 148 | /// |
| 149 | /// Vector of shares. |
| 150 | pub fn share_vector<T: TryInto<u128> + Not<Output = T> + TryInto<u8> + Copy>( |
| 151 | prng: &mut PRNG, |
| 152 | data: &[T], |
| 153 | scalar_type: ScalarType, |
| 154 | ) -> Result<Vec<Value>> { |
| 155 | let n = data.len(); |
| 156 | let n_bytes = n * scalar_size_in_bytes(scalar_type) as usize; |
| 157 | |
| 158 | // first share (r0) is pseudo-random |
| 159 | let r0_bytes = prng.get_random_bytes(n_bytes)?; |
| 160 | let r0 = Value::from_bytes(r0_bytes) |
| 161 | .to_flattened_array_u128(array_type(vec![n as u64], scalar_type))?; |
| 162 | // second share (r1) is pseudo-random |
| 163 | let r1_bytes = prng.get_random_bytes(n_bytes)?; |
| 164 | let r1 = Value::from_bytes(r1_bytes) |
| 165 | .to_flattened_array_u128(array_type(vec![n as u64], scalar_type))?; |
| 166 | // third share (r2) is r2 = data - (r0 + r1) |
| 167 | let r0r1 = add_vectors_u128(&r0, &r1, scalar_type.get_modulus())?; |
| 168 | let data_u128 = Value::from_flattened_array(data, scalar_type)? |
| 169 | .to_flattened_array_u128(array_type(vec![n as u64], scalar_type))?; |
| 170 | let r2 = subtract_vectors_u128(&data_u128, &r0r1, scalar_type.get_modulus())?; |
| 171 | |
| 172 | let shares = vec![ |
| 173 | Value::from_flattened_array(&r0, scalar_type)?, |
| 174 | Value::from_flattened_array(&r1, scalar_type)?, |
| 175 | Value::from_flattened_array(&r2, scalar_type)?, |
| 176 | ]; |
| 177 | |
| 178 | let mut garbage = vec![]; |
| 179 | for _ in 0..3 { |
| 180 | garbage.push(Value::from_flattened_array( |
| 181 | &prng.get_random_bytes(n_bytes)?, |
| 182 | UINT8, |
| 183 | )?); |
| 184 | } |
| 185 | |
| 186 | // convert the shares to a value |
| 187 | Ok(vec![ |
| 188 | Value::from_vector(vec![ |
| 189 | shares[0].clone(), |
| 190 | shares[1].clone(), |
| 191 | garbage[2].clone(), |
| 192 | ]), |
| 193 | Value::from_vector(vec![ |
| 194 | garbage[0].clone(), |
| 195 | shares[1].clone(), |
| 196 | shares[2].clone(), |
| 197 | ]), |
| 198 | Value::from_vector(vec![ |
| 199 | shares[0].clone(), |
| 200 | garbage[1].clone(), |
| 201 | shares[2].clone(), |
| 202 | ]), |
| 203 | ]) |
| 204 | } |
| 205 | |
| 206 | /// Selects elements of node 0 if bits of node b are zero and elements of node 1 otherwise. |
| 207 | /// |