286 lines
8.6 KiB
Rust
Raw Normal View History

2023-01-21 13:24:45 +07:00
use std::mem::transmute;
2023-01-20 14:30:12 +07:00
use std::ops::Range;
2022-12-15 14:08:23 -08:00
2022-10-12 10:06:34 -04:00
use anyhow::Result;
use ethereum_types::U256;
2023-01-25 16:10:53 +07:00
use crate::bn254_arithmetic::{gen_fp12, Fp, Fp12, Fp2};
use crate::bn254_pairing::{gen_fp12_sparse, tate, Curve, TwistedCurve};
2022-11-04 13:55:13 +01:00
use crate::cpu::kernel::aggregator::KERNEL;
2023-01-20 14:30:12 +07:00
use crate::cpu::kernel::interpreter::Interpreter;
2023-01-20 13:59:39 +07:00
use crate::memory::segments::Segment;
use crate::witness::memory::MemoryAddress;
2023-01-20 14:30:12 +07:00
struct InterpreterSetup {
2023-01-24 00:01:47 +07:00
label: String,
2023-01-20 13:59:39 +07:00
stack: Vec<U256>,
memory: Vec<(usize, Vec<U256>)>,
2022-12-22 17:39:18 -08:00
}
2023-01-21 13:19:07 +07:00
fn run_setup_interpreter(setup: InterpreterSetup) -> Result<Interpreter<'static>> {
2023-01-24 00:01:47 +07:00
let label = KERNEL.global_labels[&setup.label];
2023-01-20 14:30:12 +07:00
let mut stack = setup.stack;
2023-01-20 13:59:39 +07:00
stack.reverse();
let mut interpreter = Interpreter::new_with_kernel(label, stack);
2023-01-20 14:30:12 +07:00
for (pointer, data) in setup.memory {
2023-01-20 13:59:39 +07:00
for (i, term) in data.iter().enumerate() {
interpreter.generation_state.memory.set(
MemoryAddress::new(0, Segment::KernelGeneral, pointer + i),
*term,
)
}
}
interpreter.run()?;
2023-01-21 13:19:07 +07:00
Ok(interpreter)
}
2023-01-20 14:30:12 +07:00
2023-01-21 13:19:07 +07:00
fn extract_kernel_output(range: Range<usize>, interpreter: Interpreter<'static>) -> Vec<U256> {
2023-01-20 14:30:12 +07:00
let mut output: Vec<U256> = vec![];
2023-01-21 13:19:07 +07:00
for i in range {
let term = interpreter.generation_state.memory.get(MemoryAddress::new(
0,
Segment::KernelGeneral,
i,
));
output.push(term);
2023-01-20 14:30:12 +07:00
}
2023-01-21 13:19:07 +07:00
output
2023-01-20 13:59:39 +07:00
}
2023-01-21 13:24:45 +07:00
fn fp12_on_stack(f: Fp12) -> Vec<U256> {
let f: [U256; 12] = unsafe { transmute(f) };
f.into_iter().collect()
}
2023-01-21 13:19:07 +07:00
fn setup_mul_test(
in0: usize,
in1: usize,
out: usize,
f: Fp12,
g: Fp12,
label: &str,
) -> InterpreterSetup {
2023-01-20 14:30:12 +07:00
InterpreterSetup {
2023-01-24 00:01:47 +07:00
label: label.to_string(),
2023-01-21 13:19:07 +07:00
stack: vec![
U256::from(in0),
U256::from(in1),
U256::from(out),
U256::from(0xdeadbeefu32),
],
2023-01-21 13:24:45 +07:00
memory: vec![(in0, fp12_on_stack(f)), (in1, fp12_on_stack(g))],
2023-01-20 14:30:12 +07:00
}
2022-11-14 15:58:37 -08:00
}
2022-12-14 20:16:50 -08:00
#[test]
2022-12-15 13:18:00 -08:00
fn test_mul_fp12() -> Result<()> {
2023-01-21 13:19:07 +07:00
let in0: usize = 64;
let in1: usize = 76;
let out: usize = 88;
2022-12-15 17:00:38 -08:00
let f: Fp12 = gen_fp12();
let g: Fp12 = gen_fp12();
let h: Fp12 = gen_fp12_sparse();
2022-11-15 13:34:47 -08:00
2023-01-21 13:19:07 +07:00
let setup_normal: InterpreterSetup = setup_mul_test(in0, in1, out, f, g, "mul_fp12");
let setup_sparse: InterpreterSetup = setup_mul_test(in0, in1, out, f, h, "mul_fp12_sparse");
let setup_square: InterpreterSetup = setup_mul_test(in0, in1, out, f, f, "square_fp12_test");
let intrptr_normal: Interpreter = run_setup_interpreter(setup_normal).unwrap();
let intrptr_sparse: Interpreter = run_setup_interpreter(setup_sparse).unwrap();
let intrptr_square: Interpreter = run_setup_interpreter(setup_square).unwrap();
2022-11-15 13:34:47 -08:00
2023-01-21 13:19:07 +07:00
let out_normal: Vec<U256> = extract_kernel_output(out..out + 12, intrptr_normal);
let out_sparse: Vec<U256> = extract_kernel_output(out..out + 12, intrptr_sparse);
let out_square: Vec<U256> = extract_kernel_output(out..out + 12, intrptr_square);
2022-11-15 13:34:47 -08:00
2023-01-21 13:24:45 +07:00
let exp_normal: Vec<U256> = fp12_on_stack(f * g);
let exp_sparse: Vec<U256> = fp12_on_stack(f * h);
let exp_square: Vec<U256> = fp12_on_stack(f * f);
2022-11-15 13:34:47 -08:00
2022-12-15 13:18:00 -08:00
assert_eq!(out_normal, exp_normal);
assert_eq!(out_sparse, exp_sparse);
assert_eq!(out_square, exp_square);
2022-11-15 13:34:47 -08:00
Ok(())
2022-11-15 13:40:14 -08:00
}
2022-12-15 17:00:38 -08:00
2023-01-21 13:19:07 +07:00
fn setup_frob_test(ptr: usize, f: Fp12, label: &str) -> InterpreterSetup {
2023-01-20 14:52:44 +07:00
InterpreterSetup {
2023-01-24 00:01:47 +07:00
label: label.to_string(),
2023-01-21 13:19:07 +07:00
stack: vec![U256::from(ptr)],
2023-01-21 13:24:45 +07:00
memory: vec![(ptr, fp12_on_stack(f))],
2023-01-20 14:52:44 +07:00
}
}
#[test]
fn test_frob_fp12() -> Result<()> {
2023-01-21 13:19:07 +07:00
let ptr: usize = 100;
2023-01-20 14:52:44 +07:00
let f: Fp12 = gen_fp12();
2023-01-21 13:19:07 +07:00
let setup_frob_1 = setup_frob_test(ptr, f, "test_frob_fp12_1");
let setup_frob_2 = setup_frob_test(ptr, f, "test_frob_fp12_2");
let setup_frob_3 = setup_frob_test(ptr, f, "test_frob_fp12_3");
let setup_frob_6 = setup_frob_test(ptr, f, "test_frob_fp12_6");
2023-01-20 14:52:44 +07:00
2023-01-21 13:19:07 +07:00
let intrptr_frob_1: Interpreter = run_setup_interpreter(setup_frob_1).unwrap();
let intrptr_frob_2: Interpreter = run_setup_interpreter(setup_frob_2).unwrap();
let intrptr_frob_3: Interpreter = run_setup_interpreter(setup_frob_3).unwrap();
let intrptr_frob_6: Interpreter = run_setup_interpreter(setup_frob_6).unwrap();
let out_frob_1: Vec<U256> = extract_kernel_output(ptr..ptr + 12, intrptr_frob_1);
let out_frob_2: Vec<U256> = extract_kernel_output(ptr..ptr + 12, intrptr_frob_2);
let out_frob_3: Vec<U256> = extract_kernel_output(ptr..ptr + 12, intrptr_frob_3);
let out_frob_6: Vec<U256> = extract_kernel_output(ptr..ptr + 12, intrptr_frob_6);
2023-01-20 14:52:44 +07:00
2023-01-24 00:01:47 +07:00
let exp_frob_1: Vec<U256> = fp12_on_stack(f.frob(1));
let exp_frob_2: Vec<U256> = fp12_on_stack(f.frob(2));
let exp_frob_3: Vec<U256> = fp12_on_stack(f.frob(3));
let exp_frob_6: Vec<U256> = fp12_on_stack(f.frob(6));
2023-01-20 14:52:44 +07:00
assert_eq!(out_frob_1, exp_frob_1);
assert_eq!(out_frob_2, exp_frob_2);
assert_eq!(out_frob_3, exp_frob_3);
assert_eq!(out_frob_6, exp_frob_6);
Ok(())
}
2022-12-19 14:39:23 -08:00
2023-01-20 14:58:34 +07:00
#[test]
2023-01-25 16:26:41 +07:00
fn test_inv_fp254_12() -> Result<()> {
2023-01-21 13:19:07 +07:00
let ptr: usize = 100;
let inv: usize = 112;
2023-01-20 14:58:34 +07:00
let f: Fp12 = gen_fp12();
2022-12-20 11:57:45 -08:00
2023-01-21 13:19:07 +07:00
let setup = InterpreterSetup {
2023-01-25 16:26:41 +07:00
label: "inv_fp254_12".to_string(),
2023-01-21 13:19:07 +07:00
stack: vec![U256::from(ptr), U256::from(inv), U256::from(0xdeadbeefu32)],
2023-01-21 13:24:45 +07:00
memory: vec![(ptr, fp12_on_stack(f))],
2023-01-21 13:19:07 +07:00
};
let interpreter: Interpreter = run_setup_interpreter(setup).unwrap();
let output: Vec<U256> = extract_kernel_output(inv..inv + 12, interpreter);
2023-01-23 14:59:08 +07:00
let expected: Vec<U256> = fp12_on_stack(f.inv());
2022-12-20 11:57:45 -08:00
2023-01-20 14:58:34 +07:00
assert_eq!(output, expected);
Ok(())
}
2022-12-20 11:57:45 -08:00
2023-01-17 23:58:36 +07:00
// #[test]
2023-01-23 14:59:08 +07:00
// fn test_invariance_inducing_power() -> Result<()> {
2023-01-17 23:58:36 +07:00
// let ptr = U256::from(300);
// let out = U256::from(400);
2022-12-20 17:23:05 -08:00
2023-01-17 23:58:36 +07:00
// let f: Fp12 = gen_fp12();
2022-12-20 17:23:05 -08:00
2023-01-17 23:58:36 +07:00
// let mut stack = vec![ptr];
2023-01-21 13:24:45 +07:00
// stack.extend(fp12_on_stack(f));
2023-01-17 23:58:36 +07:00
// stack.extend(vec![
// ptr,
// out,
// get_address_from_label("return_fp12_on_stack"),
// out,
// ]);
2022-12-21 14:52:54 -08:00
2023-01-21 13:19:07 +07:00
// let output: Vec<U256> = run_setup_interpreter("test_pow", stack);
2023-01-23 14:59:08 +07:00
// let expected: Vec<U256> = fp12_on_stack(invariance_inducing_power(f));
2022-12-21 14:52:54 -08:00
2023-01-17 23:58:36 +07:00
// assert_eq!(output, expected);
2022-12-21 14:52:54 -08:00
2023-01-17 23:58:36 +07:00
// Ok(())
// }
2022-12-21 14:52:54 -08:00
2023-01-17 23:58:36 +07:00
// #[test]
// fn test_miller() -> Result<()> {
// let p: Curve = curve_generator();
// let q: TwistedCurve = twisted_curve_generator();
2022-12-27 14:55:47 -08:00
2023-01-17 23:58:36 +07:00
// let stack = make_tate_stack(p, q);
2023-01-21 13:19:07 +07:00
// let output = run_setup_interpreter("test_miller", stack);
2023-01-21 13:24:45 +07:00
// let expected = fp12_on_stack(miller_loop(p, q));
2022-12-27 18:38:20 -08:00
2023-01-17 23:58:36 +07:00
// assert_eq!(output, expected);
2022-12-27 18:38:20 -08:00
2023-01-17 23:58:36 +07:00
// Ok(())
// }
2022-12-27 18:38:20 -08:00
2023-01-25 16:10:53 +07:00
// The curve is cyclic with generator (1, 2)
pub const CURVE_GENERATOR: Curve = {
Curve {
x: Fp { val: U256::one() },
y: Fp {
val: U256([2, 0, 0, 0]),
},
}
};
// The twisted curve is cyclic with generator (x, y) as follows
pub const TWISTED_GENERATOR: TwistedCurve = {
TwistedCurve {
x: Fp2 {
re: Fp {
val: U256([
0x46debd5cd992f6ed,
0x674322d4f75edadd,
0x426a00665e5c4479,
0x1800deef121f1e76,
]),
},
im: Fp {
val: U256([
0x97e485b7aef312c2,
0xf1aa493335a9e712,
0x7260bfb731fb5d25,
0x198e9393920d483a,
]),
},
},
y: Fp2 {
re: Fp {
val: U256([
0x4ce6cc0166fa7daa,
0xe3d1e7690c43d37b,
0x4aab71808dcb408f,
0x12c85ea5db8c6deb,
]),
},
im: Fp {
val: U256([
0x55acdadcd122975b,
0xbc4b313370b38ef3,
0xec9e99ad690c3395,
0x090689d0585ff075,
]),
},
},
}
};
2023-01-24 09:42:42 +07:00
#[test]
fn test_tate() -> Result<()> {
let ptr: usize = 300;
let out: usize = 400;
2023-01-24 09:43:47 +07:00
let inputs: Vec<U256> = vec![
CURVE_GENERATOR.x.val,
CURVE_GENERATOR.y.val,
TWISTED_GENERATOR.x.re.val,
TWISTED_GENERATOR.x.im.val,
TWISTED_GENERATOR.y.re.val,
TWISTED_GENERATOR.y.im.val,
];
2023-01-24 09:42:42 +07:00
let setup = InterpreterSetup {
label: "tate".to_string(),
stack: vec![U256::from(ptr), U256::from(out), U256::from(0xdeadbeefu32)],
2023-01-24 09:43:47 +07:00
memory: vec![(ptr, inputs)],
2023-01-24 09:42:42 +07:00
};
let interpreter = run_setup_interpreter(setup).unwrap();
let output: Vec<U256> = extract_kernel_output(out..out + 12, interpreter);
2023-01-24 17:08:29 +07:00
// let output: Vec<U256> = interpreter.stack().to_vec();
2023-01-24 09:42:42 +07:00
let expected = fp12_on_stack(tate(CURVE_GENERATOR, TWISTED_GENERATOR));
2023-01-17 23:58:36 +07:00
2023-01-24 09:42:42 +07:00
assert_eq!(output, expected);
2022-12-27 18:38:20 -08:00
2023-01-24 09:42:42 +07:00
Ok(())
}