(
op: Operation,
mpc_graph: Graph,
inputs: Vec<Value>,
expected: Vec<u128>,
output_parties: Vec<IOStatus>,
t: Type,
)
| 514 | } |
| 515 | |
| 516 | fn check_output( |
| 517 | op: Operation, |
| 518 | mpc_graph: Graph, |
| 519 | inputs: Vec<Value>, |
| 520 | expected: Vec<u128>, |
| 521 | output_parties: Vec<IOStatus>, |
| 522 | t: Type, |
| 523 | ) -> Result<()> { |
| 524 | let output = random_evaluate(mpc_graph.clone(), inputs)?; |
| 525 | let st = t.get_scalar_type(); |
| 526 | |
| 527 | let out = if output_parties.is_empty() { |
| 528 | output.access_vector(|v| { |
| 529 | let mut res = vec![0; expected.len()]; |
| 530 | for val in v { |
| 531 | let arr = match t.clone() { |
| 532 | Type::Scalar(_) => { |
| 533 | vec![val.to_u128(st)?] |
| 534 | } |
| 535 | Type::Array(_, _) => val.to_flattened_array_u128(t.clone())?, |
| 536 | _ => { |
| 537 | panic!("Shouldn't be here"); |
| 538 | } |
| 539 | }; |
| 540 | for i in 0..expected.len() { |
| 541 | if op == Operation::A2B { |
| 542 | res[i] ^= arr[i]; |
| 543 | } else { |
| 544 | res[i] = res[i].wrapping_add(arr[i]); |
| 545 | } |
| 546 | } |
| 547 | } |
| 548 | Ok(res) |
| 549 | })? |
| 550 | } else { |
| 551 | assert!(output.check_type(t.clone())?); |
| 552 | match t.clone() { |
| 553 | Type::Scalar(_) => vec![output.to_u128(st)?], |
| 554 | Type::Array(_, _) => output.to_flattened_array_u128(t.clone())?, |
| 555 | _ => { |
| 556 | panic!("Shouldn't be here"); |
| 557 | } |
| 558 | } |
| 559 | }; |
| 560 | let (expected, out) = if let Some(m) = st.get_modulus() { |
| 561 | ( |
| 562 | expected.iter().map(|x| (x % m)).collect(), |
| 563 | out.iter().map(|x| (x % m)).collect(), |
| 564 | ) |
| 565 | } else { |
| 566 | (expected, out) |
| 567 | }; |
| 568 | assert_eq!(out, expected); |
| 569 | Ok(()) |
| 570 | } |
| 571 | |
| 572 | fn conversion_test(op: Operation, st: ScalarType) -> Result<()> { |
| 573 | let helper = |input: Vec<u128>, |
no test coverage detected