(&self, context: Context, argument_types: Vec<Type>)
| 36 | #[typetag::serde] |
| 37 | impl CustomOperationBody for ObliviousTransfer { |
| 38 | fn instantiate(&self, context: Context, argument_types: Vec<Type>) -> Result<Graph> { |
| 39 | if argument_types.len() != 4 { |
| 40 | return Err(runtime_error!( |
| 41 | "Oblivious transport should have 4 input types" |
| 42 | )); |
| 43 | } |
| 44 | if argument_types[0] != argument_types[1] { |
| 45 | return Err(runtime_error!("First two input types should be equal")); |
| 46 | } |
| 47 | let bit_type = argument_types[2].clone(); |
| 48 | if bit_type.get_scalar_type() != BIT { |
| 49 | return Err(runtime_error!( |
| 50 | "Bit type should be a binary array or scalar" |
| 51 | )); |
| 52 | } |
| 53 | let key_type = argument_types[3].clone(); |
| 54 | if key_type != array_type(vec![KEY_LENGTH], BIT) { |
| 55 | return Err(runtime_error!( |
| 56 | "Key type should be a binary array of length {}", |
| 57 | KEY_LENGTH |
| 58 | )); |
| 59 | } |
| 60 | if self.sender_id >= PARTIES as u64 { |
| 61 | return Err(runtime_error!("Sender ID is incorrect")); |
| 62 | } |
| 63 | if self.receiver_id >= PARTIES as u64 { |
| 64 | return Err(runtime_error!("Receiver ID is incorrect")); |
| 65 | } |
| 66 | if self.sender_id == self.receiver_id { |
| 67 | return Err(runtime_error!( |
| 68 | "Receiver ID should be different from the sender id" |
| 69 | )); |
| 70 | } |
| 71 | |
| 72 | let g = context.create_graph()?; |
| 73 | |
| 74 | // Input values known to the sender |
| 75 | let input_type = argument_types[0].clone(); |
| 76 | let i0 = g.input(input_type.clone())?; |
| 77 | let i1 = g.input(input_type.clone())?; |
| 78 | |
| 79 | // Selection bit known to the receiver and helper |
| 80 | let b = g.input(bit_type)?; |
| 81 | |
| 82 | // PRF key known to the sender and helper. |
| 83 | // It can be the corresponding PRF key for multiplication. |
| 84 | let prf_key = g.input(key_type)?; |
| 85 | |
| 86 | // The sender and helper generate two random masks for the input values |
| 87 | let r0 = g.prf(prf_key.clone(), 0, input_type.clone())?; |
| 88 | let r1 = g.prf(prf_key, 0, input_type.clone())?; |
| 89 | |
| 90 | // The sender masks the input values and send them to the receiver |
| 91 | let masked_i0 = i0 |
| 92 | .add(r0.clone())? |
| 93 | .nop()? |
| 94 | .add_annotation(NodeAnnotation::Send(self.sender_id, self.receiver_id))?; |
| 95 | let masked_i1 = i1 |
nothing calls this directly
no test coverage detected