2022-12-15 14:08:23 -08:00
|
|
|
use std::str::FromStr;
|
|
|
|
|
|
2022-10-12 10:06:34 -04:00
|
|
|
use anyhow::Result;
|
|
|
|
|
use ethereum_types::U256;
|
|
|
|
|
|
2022-12-21 14:52:54 -08:00
|
|
|
use crate::bn254::{
|
2022-12-27 18:38:20 -08:00
|
|
|
curve_generator, fp12_to_vec, frob_fp12, gen_fp12, gen_fp12_sparse, miller_loop, mul_fp12,
|
|
|
|
|
power, tate, twisted_curve_generator, Curve, Fp12, TwistedCurve,
|
2022-12-21 14:52:54 -08:00
|
|
|
};
|
2022-11-04 13:55:13 +01:00
|
|
|
use crate::cpu::kernel::aggregator::KERNEL;
|
2022-12-21 14:52:54 -08:00
|
|
|
use crate::cpu::kernel::interpreter::run_interpreter;
|
2022-10-12 10:06:34 -04:00
|
|
|
|
2023-01-13 09:06:23 +04:00
|
|
|
fn get_address_from_label(lbl: &str) -> U256 {
|
2022-12-22 17:39:18 -08:00
|
|
|
U256::from(KERNEL.global_labels[lbl])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn make_stack(vecs: Vec<Vec<U256>>) -> Vec<U256> {
|
|
|
|
|
let mut stack = vec![];
|
|
|
|
|
for vec in vecs {
|
|
|
|
|
stack.extend(vec)
|
|
|
|
|
}
|
|
|
|
|
stack
|
|
|
|
|
}
|
|
|
|
|
|
2022-12-22 17:07:24 -08:00
|
|
|
fn get_output(lbl: &str, stack: Vec<U256>) -> Vec<U256> {
|
|
|
|
|
let label = KERNEL.global_labels[lbl];
|
|
|
|
|
let mut input = stack;
|
|
|
|
|
input.reverse();
|
|
|
|
|
let mut output = run_interpreter(label, input).unwrap().stack().to_vec();
|
|
|
|
|
output.reverse();
|
|
|
|
|
output
|
2022-12-16 17:35:52 -08:00
|
|
|
}
|
|
|
|
|
|
2022-12-22 17:39:18 -08:00
|
|
|
fn make_mul_stack(f: Fp12, g: Fp12, mul_label: &str) -> Vec<U256> {
|
|
|
|
|
let in0 = U256::from(64);
|
|
|
|
|
let in1 = U256::from(76);
|
|
|
|
|
let out = U256::from(88);
|
|
|
|
|
|
|
|
|
|
make_stack(vec![
|
|
|
|
|
vec![in0],
|
|
|
|
|
fp12_to_vec(f),
|
|
|
|
|
vec![in1],
|
|
|
|
|
fp12_to_vec(g),
|
|
|
|
|
vec![
|
2023-01-13 09:06:23 +04:00
|
|
|
get_address_from_label(mul_label),
|
2022-12-22 17:39:18 -08:00
|
|
|
in0,
|
|
|
|
|
in1,
|
|
|
|
|
out,
|
2023-01-13 09:06:23 +04:00
|
|
|
get_address_from_label("return_fp12_on_stack"),
|
2022-12-22 17:39:18 -08:00
|
|
|
out,
|
|
|
|
|
],
|
|
|
|
|
])
|
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<()> {
|
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
|
|
|
|
2022-12-22 17:39:18 -08:00
|
|
|
let normal: Vec<U256> = make_mul_stack(f, g, "mul_fp12");
|
|
|
|
|
let sparse: Vec<U256> = make_mul_stack(f, h, "mul_fp12_sparse");
|
|
|
|
|
let square: Vec<U256> = make_mul_stack(f, f, "square_fp12_test");
|
2022-11-15 13:34:47 -08:00
|
|
|
|
2022-12-22 17:07:24 -08:00
|
|
|
let out_normal: Vec<U256> = get_output("test_mul_fp12", normal);
|
|
|
|
|
let out_sparse: Vec<U256> = get_output("test_mul_fp12", sparse);
|
|
|
|
|
let out_square: Vec<U256> = get_output("test_mul_fp12", square);
|
2022-11-15 13:34:47 -08:00
|
|
|
|
2022-12-22 17:07:24 -08:00
|
|
|
let exp_normal: Vec<U256> = fp12_to_vec(mul_fp12(f, g));
|
|
|
|
|
let exp_sparse: Vec<U256> = fp12_to_vec(mul_fp12(f, h));
|
|
|
|
|
let exp_square: Vec<U256> = fp12_to_vec(mul_fp12(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
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_frob_fp12() -> Result<()> {
|
2022-12-21 14:52:54 -08:00
|
|
|
let ptr = U256::from(100);
|
2022-12-22 17:39:18 -08:00
|
|
|
|
2022-12-15 17:00:38 -08:00
|
|
|
let f: Fp12 = gen_fp12();
|
|
|
|
|
|
2022-12-22 17:39:18 -08:00
|
|
|
let stack = make_stack(vec![vec![ptr], fp12_to_vec(f), vec![ptr]]);
|
2022-12-15 17:00:38 -08:00
|
|
|
|
2022-12-22 17:07:24 -08:00
|
|
|
let out_frob1: Vec<U256> = get_output("test_frob_fp12_1", stack.clone());
|
|
|
|
|
let out_frob2: Vec<U256> = get_output("test_frob_fp12_2", stack.clone());
|
|
|
|
|
let out_frob3: Vec<U256> = get_output("test_frob_fp12_3", stack.clone());
|
|
|
|
|
let out_frob6: Vec<U256> = get_output("test_frob_fp12_6", stack);
|
2022-12-15 17:00:38 -08:00
|
|
|
|
2022-12-22 17:07:24 -08:00
|
|
|
let exp_frob1: Vec<U256> = fp12_to_vec(frob_fp12(1, f));
|
|
|
|
|
let exp_frob2: Vec<U256> = fp12_to_vec(frob_fp12(2, f));
|
|
|
|
|
let exp_frob3: Vec<U256> = fp12_to_vec(frob_fp12(3, f));
|
|
|
|
|
let exp_frob6: Vec<U256> = fp12_to_vec(frob_fp12(6, f));
|
2022-12-15 17:00:38 -08:00
|
|
|
|
|
|
|
|
assert_eq!(out_frob1, exp_frob1);
|
|
|
|
|
assert_eq!(out_frob2, exp_frob2);
|
|
|
|
|
assert_eq!(out_frob3, exp_frob3);
|
|
|
|
|
assert_eq!(out_frob6, exp_frob6);
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
2022-12-19 14:39:23 -08:00
|
|
|
|
2022-12-21 14:52:54 -08:00
|
|
|
#[test]
|
|
|
|
|
fn test_inv_fp12() -> Result<()> {
|
2022-12-20 12:21:27 -08:00
|
|
|
let ptr = U256::from(200);
|
|
|
|
|
let inv = U256::from(300);
|
2022-12-20 11:57:45 -08:00
|
|
|
|
|
|
|
|
let f: Fp12 = gen_fp12();
|
|
|
|
|
|
2022-12-27 18:38:20 -08:00
|
|
|
let stack = make_stack(vec![
|
|
|
|
|
vec![ptr],
|
|
|
|
|
fp12_to_vec(f),
|
|
|
|
|
vec![ptr, inv, U256::from_str("0xdeadbeef").unwrap()],
|
|
|
|
|
]);
|
2022-12-20 11:57:45 -08:00
|
|
|
|
2022-12-22 17:07:24 -08:00
|
|
|
let output: Vec<U256> = get_output("test_inv_fp12", stack);
|
2022-12-20 11:57:45 -08:00
|
|
|
|
|
|
|
|
assert_eq!(output, vec![]);
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
2022-12-20 12:47:36 -08:00
|
|
|
#[test]
|
2022-12-27 16:00:16 -08:00
|
|
|
fn test_power() -> Result<()> {
|
2022-12-20 17:23:05 -08:00
|
|
|
let ptr = U256::from(300);
|
|
|
|
|
let out = U256::from(400);
|
|
|
|
|
|
2022-12-21 14:52:54 -08:00
|
|
|
let f: Fp12 = gen_fp12();
|
2022-12-20 17:23:05 -08:00
|
|
|
|
2022-12-22 17:39:18 -08:00
|
|
|
let stack = make_stack(vec![
|
|
|
|
|
vec![ptr],
|
|
|
|
|
fp12_to_vec(f),
|
2023-01-13 09:06:51 +04:00
|
|
|
vec![
|
|
|
|
|
ptr,
|
|
|
|
|
out,
|
|
|
|
|
get_address_from_label("return_fp12_on_stack"),
|
|
|
|
|
out,
|
|
|
|
|
],
|
2022-12-22 17:39:18 -08:00
|
|
|
]);
|
2022-12-21 14:52:54 -08:00
|
|
|
|
2022-12-22 17:07:24 -08:00
|
|
|
let output: Vec<U256> = get_output("test_pow", stack);
|
|
|
|
|
let expected: Vec<U256> = fp12_to_vec(power(f));
|
2022-12-21 14:52:54 -08:00
|
|
|
|
2022-12-22 15:10:29 -08:00
|
|
|
assert_eq!(output, expected);
|
2022-12-21 14:52:54 -08:00
|
|
|
|
2022-12-22 15:10:29 -08:00
|
|
|
Ok(())
|
|
|
|
|
}
|
2022-12-21 14:52:54 -08:00
|
|
|
|
2022-12-27 18:38:20 -08:00
|
|
|
fn make_tate_stack(p: Curve, q: TwistedCurve) -> Vec<U256> {
|
2022-12-27 14:55:47 -08:00
|
|
|
let ptr = U256::from(300);
|
|
|
|
|
let out = U256::from(400);
|
|
|
|
|
|
|
|
|
|
let p_: Vec<U256> = p.into_iter().collect();
|
|
|
|
|
let q_: Vec<U256> = q.into_iter().flatten().collect();
|
|
|
|
|
|
2022-12-29 14:03:52 -08:00
|
|
|
make_stack(vec![
|
|
|
|
|
vec![ptr],
|
|
|
|
|
p_,
|
|
|
|
|
q_,
|
2023-01-13 09:06:51 +04:00
|
|
|
vec![
|
|
|
|
|
ptr,
|
|
|
|
|
out,
|
|
|
|
|
get_address_from_label("return_fp12_on_stack"),
|
|
|
|
|
out,
|
|
|
|
|
],
|
2022-12-29 14:03:52 -08:00
|
|
|
])
|
2022-12-27 18:38:20 -08:00
|
|
|
}
|
2022-12-27 14:55:47 -08:00
|
|
|
|
2022-12-27 18:38:20 -08:00
|
|
|
#[test]
|
|
|
|
|
fn test_miller() -> Result<()> {
|
|
|
|
|
let p: Curve = curve_generator();
|
|
|
|
|
let q: TwistedCurve = twisted_curve_generator();
|
|
|
|
|
|
|
|
|
|
let stack = make_tate_stack(p, q);
|
|
|
|
|
let output = get_output("test_miller", stack);
|
2022-12-27 14:55:47 -08:00
|
|
|
let expected = fp12_to_vec(miller_loop(p, q));
|
|
|
|
|
|
|
|
|
|
assert_eq!(output, expected);
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
2022-12-27 18:38:20 -08:00
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_tate() -> Result<()> {
|
|
|
|
|
let p: Curve = curve_generator();
|
|
|
|
|
let q: TwistedCurve = twisted_curve_generator();
|
|
|
|
|
|
|
|
|
|
let stack = make_tate_stack(p, q);
|
|
|
|
|
let output = get_output("test_tate", stack);
|
|
|
|
|
let expected = fp12_to_vec(tate(p, q));
|
|
|
|
|
|
|
|
|
|
assert_eq!(output, expected);
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|