mirror of
https://github.com/powdr-labs/powdr.git
synced 2026-04-20 03:03:25 -04:00
309 lines
8.8 KiB
Rust
309 lines
8.8 KiB
Rust
use compiler::test_util::{gen_estark_proof, gen_halo2_proof, verify_test_file};
|
|
use number::{FieldElement, GoldilocksField};
|
|
use test_log::test;
|
|
|
|
fn verify_asm<T: FieldElement>(file_name: &str, inputs: Vec<T>) {
|
|
verify_test_file(file_name, inputs, vec![]);
|
|
}
|
|
|
|
fn slice_to_vec<T: FieldElement>(arr: &[i32]) -> Vec<T> {
|
|
arr.iter().cloned().map(|x| x.into()).collect()
|
|
}
|
|
|
|
#[test]
|
|
fn simple_sum_asm() {
|
|
let f = "asm/simple_sum.asm";
|
|
let i = [16, 4, 1, 2, 8, 5];
|
|
verify_asm::<GoldilocksField>(f, slice_to_vec(&i));
|
|
gen_halo2_proof(f, slice_to_vec(&i));
|
|
gen_estark_proof(f, slice_to_vec(&i));
|
|
}
|
|
|
|
#[test]
|
|
fn secondary_block_machine_add2() {
|
|
let f = "asm/secondary_block_machine_add2.asm";
|
|
verify_asm::<GoldilocksField>(f, vec![]);
|
|
gen_halo2_proof(f, vec![]);
|
|
gen_estark_proof(f, vec![]);
|
|
}
|
|
|
|
#[test]
|
|
fn mem_write_once() {
|
|
let f = "asm/mem_write_once.asm";
|
|
verify_asm::<GoldilocksField>(f, vec![]);
|
|
gen_halo2_proof(f, vec![]);
|
|
gen_estark_proof(f, vec![]);
|
|
}
|
|
|
|
#[test]
|
|
fn mem_write_once_external_write() {
|
|
let f = "asm/mem_write_once_external_write.asm";
|
|
let mut mem = vec![GoldilocksField::from(0); 256];
|
|
mem[17] = GoldilocksField::from(42);
|
|
mem[62] = GoldilocksField::from(123);
|
|
mem[255] = GoldilocksField::from(-1);
|
|
verify_test_file::<GoldilocksField>(f, vec![], vec![("main.v".to_string(), mem)]);
|
|
}
|
|
|
|
#[test]
|
|
fn block_machine_cache_miss() {
|
|
let f = "asm/block_machine_cache_miss.asm";
|
|
verify_asm::<GoldilocksField>(f, vec![]);
|
|
gen_halo2_proof(f, vec![]);
|
|
gen_estark_proof(f, vec![]);
|
|
}
|
|
|
|
#[test]
|
|
fn palindrome() {
|
|
let f = "asm/palindrome.asm";
|
|
let i = [7, 1, 7, 3, 9, 3, 7, 1];
|
|
verify_asm::<GoldilocksField>(f, slice_to_vec(&i));
|
|
gen_halo2_proof(f, slice_to_vec(&i));
|
|
// currently starky leads to
|
|
// thread 'functional_instructions' has overflowed its stack
|
|
// leave it out until that's fixed
|
|
//gen_estark_proof(f, slice_to_vec(&i));
|
|
}
|
|
|
|
#[test]
|
|
fn single_function_vm() {
|
|
let f = "asm/single_function_vm.asm";
|
|
let i = [];
|
|
verify_asm::<GoldilocksField>(f, slice_to_vec(&i));
|
|
gen_halo2_proof(f, slice_to_vec(&i));
|
|
gen_estark_proof(f, slice_to_vec(&i));
|
|
}
|
|
|
|
#[test]
|
|
fn empty() {
|
|
let f = "asm/empty.asm";
|
|
let i = [];
|
|
verify_asm::<GoldilocksField>(f, slice_to_vec(&i));
|
|
gen_halo2_proof(f, slice_to_vec(&i));
|
|
gen_estark_proof(f, slice_to_vec(&i));
|
|
}
|
|
|
|
#[test]
|
|
fn single_operation() {
|
|
let f = "asm/single_operation.asm";
|
|
let i = [];
|
|
verify_asm::<GoldilocksField>(f, slice_to_vec(&i));
|
|
gen_halo2_proof(f, slice_to_vec(&i));
|
|
gen_estark_proof(f, slice_to_vec(&i));
|
|
}
|
|
|
|
#[test]
|
|
fn empty_vm() {
|
|
let f = "asm/empty_vm.asm";
|
|
let i = [];
|
|
verify_asm::<GoldilocksField>(f, slice_to_vec(&i));
|
|
gen_halo2_proof(f, slice_to_vec(&i));
|
|
gen_estark_proof(f, slice_to_vec(&i));
|
|
}
|
|
|
|
#[test]
|
|
fn vm_to_block_unique_interface() {
|
|
let f = "asm/vm_to_block_unique_interface.asm";
|
|
let i = [];
|
|
verify_asm::<GoldilocksField>(f, slice_to_vec(&i));
|
|
gen_halo2_proof(f, slice_to_vec(&i));
|
|
// currently starky leads to
|
|
// thread 'functional_instructions' has overflowed its stack
|
|
// leave it out until that's fixed
|
|
//gen_estark_proof(f, slice_to_vec(&i));
|
|
}
|
|
|
|
#[test]
|
|
fn vm_to_block_to_block() {
|
|
let f = "asm/vm_to_block_to_block.asm";
|
|
let i = [];
|
|
verify_asm::<GoldilocksField>(f, slice_to_vec(&i));
|
|
gen_halo2_proof(f, slice_to_vec(&i));
|
|
}
|
|
|
|
#[test]
|
|
fn block_to_block() {
|
|
let f = "asm/block_to_block.asm";
|
|
let i = [];
|
|
verify_asm::<GoldilocksField>(f, slice_to_vec(&i));
|
|
gen_halo2_proof(f, slice_to_vec(&i));
|
|
gen_estark_proof(f, slice_to_vec(&i));
|
|
}
|
|
|
|
#[test]
|
|
fn vm_to_block_multiple_interfaces() {
|
|
let f = "asm/vm_to_block_multiple_interfaces.asm";
|
|
let i = [];
|
|
verify_asm::<GoldilocksField>(f, slice_to_vec(&i));
|
|
gen_halo2_proof(f, slice_to_vec(&i));
|
|
gen_estark_proof(f, slice_to_vec(&i));
|
|
}
|
|
|
|
#[test]
|
|
fn vm_to_vm() {
|
|
let f = "asm/vm_to_vm.asm";
|
|
let i = [];
|
|
verify_asm::<GoldilocksField>(f, slice_to_vec(&i));
|
|
gen_halo2_proof(f, slice_to_vec(&i));
|
|
gen_estark_proof(f, slice_to_vec(&i));
|
|
}
|
|
|
|
#[test]
|
|
fn vm_to_vm_dynamic_trace_length() {
|
|
let f = "asm/vm_to_vm_dynamic_trace_length.asm";
|
|
let i = [];
|
|
verify_asm::<GoldilocksField>(f, slice_to_vec(&i));
|
|
gen_halo2_proof(f, slice_to_vec(&i));
|
|
gen_estark_proof(f, slice_to_vec(&i));
|
|
}
|
|
|
|
#[test]
|
|
fn vm_to_vm_to_block() {
|
|
let f = "asm/vm_to_vm_to_block.asm";
|
|
let i = [];
|
|
verify_asm::<GoldilocksField>(f, slice_to_vec(&i));
|
|
gen_halo2_proof(f, slice_to_vec(&i));
|
|
gen_estark_proof(f, slice_to_vec(&i));
|
|
}
|
|
|
|
#[test]
|
|
fn vm_to_block_array() {
|
|
let f = "asm/vm_to_block_array.asm";
|
|
let i = [];
|
|
verify_asm::<GoldilocksField>(f, slice_to_vec(&i));
|
|
gen_halo2_proof(f, slice_to_vec(&i));
|
|
gen_estark_proof(f, slice_to_vec(&i));
|
|
}
|
|
|
|
#[test]
|
|
fn vm_to_vm_to_vm() {
|
|
let f = "asm/vm_to_vm_to_vm.asm";
|
|
let i = [];
|
|
verify_asm::<GoldilocksField>(f, slice_to_vec(&i));
|
|
gen_halo2_proof(f, slice_to_vec(&i));
|
|
gen_estark_proof(f, slice_to_vec(&i));
|
|
}
|
|
|
|
#[test]
|
|
fn test_mem_read_write() {
|
|
let f = "asm/mem_read_write.asm";
|
|
verify_asm::<GoldilocksField>(f, Default::default());
|
|
gen_halo2_proof(f, Default::default());
|
|
gen_estark_proof(f, Default::default());
|
|
}
|
|
|
|
#[test]
|
|
fn test_multi_assign() {
|
|
let f = "asm/multi_assign.asm";
|
|
let i = [7];
|
|
verify_asm::<GoldilocksField>(f, slice_to_vec(&i));
|
|
gen_halo2_proof(f, slice_to_vec(&i));
|
|
gen_estark_proof(f, slice_to_vec(&i));
|
|
}
|
|
|
|
#[test]
|
|
fn test_multi_return() {
|
|
let f = "asm/multi_return.asm";
|
|
let i = [];
|
|
verify_asm::<GoldilocksField>(f, slice_to_vec(&i));
|
|
gen_halo2_proof(f, slice_to_vec(&i));
|
|
gen_estark_proof(f, Default::default());
|
|
}
|
|
|
|
#[test]
|
|
#[should_panic = "called `Result::unwrap()` on an `Err` value: [\"Assignment register `Z` is incompatible with `square_and_double(3)`. Try using `<==` with no explicit assignment registers.\", \"Assignment register `Y` is incompatible with `square_and_double(3)`. Try using `<==` with no explicit assignment registers.\"]"]
|
|
fn test_multi_return_wrong_assignment_registers() {
|
|
let f = "asm/multi_return_wrong_assignment_registers.asm";
|
|
let i = [];
|
|
verify_asm::<GoldilocksField>(f, slice_to_vec(&i));
|
|
}
|
|
|
|
#[test]
|
|
#[should_panic = "Result::unwrap()` on an `Err` value: [\"Mismatched number of registers for assignment A, B <=Y= square_and_double(3);\"]"]
|
|
fn test_multi_return_wrong_assignment_register_length() {
|
|
let f = "asm/multi_return_wrong_assignment_register_length.asm";
|
|
let i = [];
|
|
verify_asm::<GoldilocksField>(f, slice_to_vec(&i));
|
|
}
|
|
|
|
#[test]
|
|
fn test_bit_access() {
|
|
let f = "asm/bit_access.asm";
|
|
let i = [20];
|
|
verify_asm::<GoldilocksField>(f, slice_to_vec(&i));
|
|
gen_halo2_proof(f, slice_to_vec(&i));
|
|
// currently starky leads to
|
|
// thread 'functional_instructions' has overflowed its stack
|
|
// leave it out until that's fixed
|
|
//gen_estark_proof(f, slice_to_vec(&i));
|
|
}
|
|
|
|
#[test]
|
|
fn test_sqrt() {
|
|
let f = "asm/sqrt.asm";
|
|
verify_asm::<GoldilocksField>(f, Default::default());
|
|
gen_halo2_proof(f, Default::default());
|
|
gen_estark_proof(f, Default::default());
|
|
}
|
|
|
|
#[test]
|
|
fn functional_instructions() {
|
|
let f = "asm/functional_instructions.asm";
|
|
let i = [20];
|
|
verify_asm::<GoldilocksField>(f, slice_to_vec(&i));
|
|
gen_halo2_proof(f, slice_to_vec(&i));
|
|
// currently starky leads to
|
|
// thread 'functional_instructions' has overflowed its stack
|
|
// leave it out until that's fixed
|
|
//gen_estark_proof(f, slice_to_vec(&i));
|
|
}
|
|
|
|
#[test]
|
|
fn full_pil_constant() {
|
|
let f = "asm/full_pil_constant.asm";
|
|
verify_asm::<GoldilocksField>(f, Default::default());
|
|
gen_halo2_proof(f, Default::default());
|
|
gen_estark_proof(f, Default::default());
|
|
}
|
|
|
|
#[test]
|
|
fn intermediate() {
|
|
let f = "asm/intermediate.asm";
|
|
verify_asm::<GoldilocksField>(f, Default::default());
|
|
gen_halo2_proof(f, Default::default());
|
|
gen_estark_proof(f, Default::default());
|
|
}
|
|
|
|
#[test]
|
|
fn intermediate_nested() {
|
|
let f = "asm/intermediate_nested.asm";
|
|
verify_asm::<GoldilocksField>(f, Default::default());
|
|
gen_halo2_proof(f, Default::default());
|
|
gen_estark_proof(f, Default::default());
|
|
}
|
|
|
|
mod book {
|
|
use super::*;
|
|
use number::GoldilocksField;
|
|
use test_log::test;
|
|
|
|
fn run_book_test(file: &str) {
|
|
// passing 0 to all tests currently works as they either take no prover input or 0 works
|
|
let i = [0];
|
|
|
|
verify_asm::<GoldilocksField>(&format!("{file}"), slice_to_vec(&i));
|
|
gen_halo2_proof(file, slice_to_vec(&i));
|
|
gen_estark_proof(file, slice_to_vec(&i));
|
|
}
|
|
|
|
include!(concat!(env!("OUT_DIR"), "/asm_book_tests.rs"));
|
|
}
|
|
|
|
#[test]
|
|
#[should_panic = "Witness generation failed."]
|
|
fn hello_world_asm_fail() {
|
|
let f = "asm/book/hello_world.asm";
|
|
let i = [1];
|
|
verify_asm::<GoldilocksField>(f, slice_to_vec(&i));
|
|
}
|