use std::sync::Arc;
use rand::{RngCore, rng};
use crate::{ArgsBuilder, Memory, proc::IsaOp, register_names::*, test_utils::make_computer_128};
use parasol_runtime::{fluent::UInt8, test_utils::get_secret_keys_128};
#[test]
fn can_or_plaintext_inputs() {
let (mut proc, _enc) = make_computer_128();
let val1 = 14u32;
let val2 = 7u32;
let expected = val1 | val2;
let memory = Arc::new(Memory::new_default_stack());
let program = memory.allocate_program(&[
IsaOp::Load(T0, SP, 32, 0),
IsaOp::Load(T1, SP, 32, 4),
IsaOp::Or(T0, T0, T1),
IsaOp::Store(RP, T0, 32, 0),
IsaOp::Ret(),
]);
let args = ArgsBuilder::new().arg(val1).arg(val2).return_value::<u32>();
let ans = proc.run_program(program, &memory, args).unwrap();
assert_eq!(expected, ans);
}
#[test]
fn can_or_ciphertext_inputs() {
let (mut proc, enc) = make_computer_128();
let sk = get_secret_keys_128();
let mut test = |val1: u8, val2: u8| {
let expected = val1 | val2;
let memory = Arc::new(Memory::new_default_stack());
let program = memory.allocate_program(&[
IsaOp::Load(T0, SP, 8, 0),
IsaOp::Load(T1, SP, 8, 1),
IsaOp::Or(T0, T0, T1),
IsaOp::Store(RP, T0, 8, 0),
IsaOp::Ret(),
]);
let args = ArgsBuilder::new()
.arg(UInt8::encrypt_secret(val1 as u128, &enc, &sk))
.arg(UInt8::encrypt_secret(val2 as u128, &enc, &sk))
.return_value::<UInt8>();
let answer = proc.run_program(program, &memory, args).unwrap();
let answer = answer.decrypt(&enc, &sk) as u8;
assert_eq!(expected, answer);
};
for _ in 0..=10 {
let val1 = (rng().next_u64() % 16) as u8;
let val2 = (rng().next_u64() % 16) as u8;
test(val1, val2);
}
}