parasol_cpu 0.10.0

This crate contains the Parasol CPU, which runs programs over a mix of encrypted and plaintext data.
Documentation
use std::sync::Arc;

use rand::{RngCore, rng};

use crate::{
    ArgsBuilder, Memory,
    proc::IsaOp,
    register_names::*,
    test_utils::{MaybeEncryptedUInt, make_computer_128},
};

use parasol_runtime::test_utils::get_secret_keys_128;

fn can_xor(val1: u32, val2: u32, encrypted_val1: bool, encrypted_val2: bool) {
    let (mut proc, enc) = make_computer_128();
    let sk = get_secret_keys_128();

    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::Xor(T0, T0, T1),
        IsaOp::Store(RP, T0, 32, 0),
        IsaOp::Ret(),
    ]);

    let args = ArgsBuilder::new()
        .arg(MaybeEncryptedUInt::<32>::new(
            val1 as u128,
            &enc,
            &sk,
            encrypted_val1,
        ))
        .arg(MaybeEncryptedUInt::<32>::new(
            val2 as u128,
            &enc,
            &sk,
            encrypted_val2,
        ))
        .return_value::<MaybeEncryptedUInt<32>>();

    let ans = proc.run_program(program, &memory, args).unwrap();
    let ans = ans.get(&enc, &sk);

    assert_eq!(expected, ans);
}

#[test]
fn can_xor_plaintext_inputs() {
    for _ in 0..10 {
        let val1 = rng().next_u32();
        let val2 = rng().next_u32();
        can_xor(val1, val2, false, false);
    }
}

#[test]
fn can_xor_ciphertext_left() {
    for _ in 0..5 {
        let val1 = rng().next_u32();
        let val2 = rng().next_u32();
        can_xor(val1, val2, true, false);
    }
}

#[test]
fn can_xor_ciphertext_right() {
    for _ in 0..5 {
        let val1 = rng().next_u32();
        let val2 = rng().next_u32();
        can_xor(val1, val2, false, true);
    }
}

#[test]
fn can_xor_ciphertext_both() {
    for _ in 0..5 {
        let val1 = rng().next_u32();
        let val2 = rng().next_u32();
        can_xor(val1, val2, true, true);
    }
}