325 lines
10 KiB
Rust
Raw Normal View History

2022-10-12 10:06:34 -04:00
use anyhow::Result;
use ethereum_types::U256;
2023-02-01 19:15:56 -08:00
use rand::Rng;
2022-10-12 10:06:34 -04:00
2023-02-16 19:45:33 -08:00
use crate::cpu::kernel::interpreter::{
run_interpreter_with_memory, Interpreter, InterpreterMemoryInitialization,
};
2023-03-21 13:51:11 -07:00
// use crate::bn254_arithmetic::{Fp, Fp12, Fp2, Fp6};
// use crate::bn254_pairing::{
// gen_fp12_sparse, invariant_exponent, miller_loop, tate, Curve, TwistedCurve,
// };
2023-03-21 13:55:51 -07:00
use crate::extension_tower::{Fp12, Fp6, Stack, BN254};
2023-02-16 19:45:33 -08:00
use crate::memory::segments::Segment::BnPairing;
2023-01-20 13:59:39 +07:00
2023-02-07 18:53:58 -08:00
fn extract_stack(interpreter: Interpreter<'static>) -> Vec<U256> {
2023-02-16 19:45:33 -08:00
interpreter
.stack()
.iter()
.rev()
.cloned()
.collect::<Vec<U256>>()
2023-02-07 18:53:58 -08:00
}
2023-03-21 13:55:51 -07:00
fn setup_mul_fp6_test(
f: Fp6<BN254>,
g: Fp6<BN254>,
label: &str,
) -> InterpreterMemoryInitialization {
let mut stack = f.on_stack();
if label == "mul_fp254_6" {
stack.extend(g.on_stack());
}
stack.push(U256::from(0xdeadbeefu32));
InterpreterMemoryInitialization {
label: label.to_string(),
stack,
segment: BnPairing,
memory: vec![],
}
}
2023-02-07 18:53:58 -08:00
2023-03-21 13:55:51 -07:00
#[test]
fn test_mul_fp6() -> Result<()> {
let mut rng = rand::thread_rng();
let f: Fp6<BN254> = rng.gen::<Fp6<BN254>>();
let g: Fp6<BN254> = rng.gen::<Fp6<BN254>>();
2023-02-07 18:53:58 -08:00
2023-03-21 13:55:51 -07:00
let setup_normal: InterpreterMemoryInitialization = setup_mul_fp6_test(f, g, "mul_fp254_6");
let setup_square: InterpreterMemoryInitialization = setup_mul_fp6_test(f, f, "square_fp254_6");
2023-02-07 18:53:58 -08:00
2023-03-21 13:55:51 -07:00
let intrptr_normal: Interpreter = run_interpreter_with_memory(setup_normal).unwrap();
let intrptr_square: Interpreter = run_interpreter_with_memory(setup_square).unwrap();
2023-02-07 18:53:58 -08:00
2023-03-21 13:55:51 -07:00
let out_normal: Vec<U256> = extract_stack(intrptr_normal);
let out_square: Vec<U256> = extract_stack(intrptr_square);
2023-02-07 18:53:58 -08:00
2023-03-21 13:55:51 -07:00
let exp_normal: Vec<U256> = (f * g).on_stack();
let exp_square: Vec<U256> = (f * f).on_stack();
2023-02-07 18:53:58 -08:00
2023-03-21 13:55:51 -07:00
assert_eq!(out_normal, exp_normal);
assert_eq!(out_square, exp_square);
2023-02-07 18:53:58 -08:00
2023-03-21 13:55:51 -07:00
Ok(())
}
2023-02-07 18:53:58 -08:00
2023-02-16 19:45:33 -08:00
fn setup_mul_fp12_test(
out: usize,
2023-03-21 13:51:11 -07:00
f: Fp12<BN254>,
g: Fp12<BN254>,
2023-02-16 19:45:33 -08:00
label: &str,
) -> InterpreterMemoryInitialization {
2023-02-13 14:04:43 -08:00
let in0: usize = 200;
let in1: usize = 212;
2023-02-07 18:53:58 -08:00
let mut stack = vec![
U256::from(in0),
U256::from(in1),
U256::from(out),
U256::from(0xdeadbeefu32),
];
if label == "square_fp254_12" {
stack.remove(0);
}
2023-02-16 19:45:33 -08:00
InterpreterMemoryInitialization {
2023-01-24 00:01:47 +07:00
label: label.to_string(),
2023-02-07 18:53:58 -08:00
stack,
2023-02-16 19:45:33 -08:00
segment: BnPairing,
2023-02-07 09:18:49 -08:00
memory: vec![(in0, f.on_stack()), (in1, g.on_stack())],
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]
2023-02-07 14:54:07 -08:00
fn test_mul_fp12() -> Result<()> {
2023-02-13 14:04:43 -08:00
let out: usize = 224;
2023-01-21 13:19:07 +07:00
2023-02-01 19:15:56 -08:00
let mut rng = rand::thread_rng();
2023-03-21 13:51:11 -07:00
let f: Fp12<BN254> = rng.gen::<Fp12<BN254>>();
let g: Fp12<BN254> = rng.gen::<Fp12<BN254>>();
// let h: Fp12<BN254> = gen_fp12_sparse(&mut rng);
2022-11-15 13:34:47 -08:00
2023-02-16 19:45:33 -08:00
let setup_normal: InterpreterMemoryInitialization =
setup_mul_fp12_test(out, f, g, "mul_fp254_12");
2023-03-21 13:51:11 -07:00
// let setup_sparse: InterpreterMemoryInitialization =
// setup_mul_fp12_test(out, f, h, "mul_fp254_12_sparse");
2023-02-16 19:45:33 -08:00
let setup_square: InterpreterMemoryInitialization =
setup_mul_fp12_test(out, f, f, "square_fp254_12");
2023-01-21 13:19:07 +07:00
2023-02-16 19:45:33 -08:00
let intrptr_normal: Interpreter = run_interpreter_with_memory(setup_normal).unwrap();
2023-03-21 13:51:11 -07:00
// let intrptr_sparse: Interpreter = run_interpreter_with_memory(setup_sparse).unwrap();
2023-02-16 19:45:33 -08:00
let intrptr_square: Interpreter = run_interpreter_with_memory(setup_square).unwrap();
2022-11-15 13:34:47 -08:00
2023-02-16 20:00:39 -08:00
let out_normal: Vec<U256> = intrptr_normal.extract_kernel_memory(BnPairing, out..out + 12);
2023-03-21 13:51:11 -07:00
// let out_sparse: Vec<U256> = intrptr_sparse.extract_kernel_memory(BnPairing, out..out + 12);
2023-02-16 20:00:39 -08:00
let out_square: Vec<U256> = intrptr_square.extract_kernel_memory(BnPairing, out..out + 12);
2022-11-15 13:34:47 -08:00
2023-02-07 09:18:49 -08:00
let exp_normal: Vec<U256> = (f * g).on_stack();
2023-03-21 13:51:11 -07:00
// let exp_sparse: Vec<U256> = (f * h).on_stack();
2023-02-07 09:18:49 -08:00
let exp_square: Vec<U256> = (f * f).on_stack();
2022-11-15 13:34:47 -08:00
2022-12-15 13:18:00 -08:00
assert_eq!(out_normal, exp_normal);
2023-03-21 13:51:11 -07:00
// assert_eq!(out_sparse, exp_sparse);
2022-12-15 13:18:00 -08:00
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-03-21 13:55:51 -07:00
fn setup_frob_fp6_test(f: Fp6<BN254>, n: usize) -> InterpreterMemoryInitialization {
InterpreterMemoryInitialization {
label: String::from("test_frob_fp254_6_") + &(n.to_string()),
stack: f.on_stack(),
segment: BnPairing,
memory: vec![],
}
}
#[test]
fn test_frob_fp6() -> Result<()> {
let mut rng = rand::thread_rng();
let f: Fp6<BN254> = rng.gen::<Fp6<BN254>>();
for n in 1..4 {
let setup_frob = setup_frob_fp6_test(f, n);
let intrptr_frob: Interpreter = run_interpreter_with_memory(setup_frob).unwrap();
let out_frob: Vec<U256> = extract_stack(intrptr_frob);
let exp_frob: Vec<U256> = f.frob(n).on_stack();
assert_eq!(out_frob, exp_frob);
}
Ok(())
}
2023-03-21 13:51:11 -07:00
fn setup_frob_fp12_test(ptr: usize, f: Fp12<BN254>, n: usize) -> InterpreterMemoryInitialization {
2023-02-16 19:45:33 -08:00
InterpreterMemoryInitialization {
2023-02-25 10:55:18 -08:00
label: String::from("test_frob_fp254_12_") + &(n.to_string()),
2023-01-21 13:19:07 +07:00
stack: vec![U256::from(ptr)],
2023-02-16 19:45:33 -08:00
segment: BnPairing,
2023-02-07 09:18:49 -08:00
memory: vec![(ptr, f.on_stack())],
2023-01-20 14:52:44 +07:00
}
}
#[test]
2023-02-07 14:54:07 -08:00
fn test_frob_fp12() -> Result<()> {
2023-02-13 14:04:43 -08:00
let ptr: usize = 200;
2023-02-01 19:15:56 -08:00
let mut rng = rand::thread_rng();
2023-03-21 13:51:11 -07:00
let f: Fp12<BN254> = rng.gen::<Fp12<BN254>>();
2023-02-25 10:55:18 -08:00
for n in [1, 2, 3, 6] {
let setup_frob = setup_frob_fp12_test(ptr, f, n);
let intrptr_frob: Interpreter = run_interpreter_with_memory(setup_frob).unwrap();
let out_frob: Vec<U256> = intrptr_frob.extract_kernel_memory(BnPairing, ptr..ptr + 12);
let exp_frob: Vec<U256> = f.frob(n).on_stack();
assert_eq!(out_frob, exp_frob);
}
2023-01-20 14:52:44 +07:00
Ok(())
}
2022-12-19 14:39:23 -08:00
2023-03-21 13:51:11 -07:00
// #[test]
// fn test_inv_fp12() -> Result<()> {
// let ptr: usize = 200;
// let inv: usize = 212;
// let mut rng = rand::thread_rng();
// let f: Fp12 = rng.gen::<Fp12>();
// let setup = InterpreterMemoryInitialization {
// label: "inv_fp254_12".to_string(),
// stack: vec![U256::from(ptr), U256::from(inv), U256::from(0xdeadbeefu32)],
// segment: BnPairing,
// memory: vec![(ptr, f.on_stack())],
// };
// let interpreter: Interpreter = run_interpreter_with_memory(setup).unwrap();
// let output: Vec<U256> = interpreter.extract_kernel_memory(BnPairing, inv..inv + 12);
// let expected: Vec<U256> = f.inv().on_stack();
// assert_eq!(output, expected);
// Ok(())
// }
// #[test]
// fn test_invariant_exponent() -> Result<()> {
// let ptr: usize = 200;
// let mut rng = rand::thread_rng();
// let f: Fp12 = rng.gen::<Fp12>();
// let setup = InterpreterMemoryInitialization {
// label: "bn254_invariant_exponent".to_string(),
// stack: vec![U256::from(ptr), U256::from(0xdeadbeefu32)],
// segment: BnPairing,
// memory: vec![(ptr, f.on_stack())],
// };
// let interpreter: Interpreter = run_interpreter_with_memory(setup).unwrap();
// let output: Vec<U256> = interpreter.extract_kernel_memory(BnPairing, ptr..ptr + 12);
// let expected: Vec<U256> = invariant_exponent(f).on_stack();
// assert_eq!(output, expected);
// Ok(())
// }
// // 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,
// ]),
// },
// },
// }
// };
// #[test]
// fn test_miller() -> Result<()> {
// let ptr: usize = 200;
// let out: usize = 206;
// 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,
// ];
// let setup = InterpreterMemoryInitialization {
// label: "bn254_miller".to_string(),
// stack: vec![U256::from(ptr), U256::from(out), U256::from(0xdeadbeefu32)],
// segment: BnPairing,
// memory: vec![(ptr, inputs)],
// };
// let interpreter = run_interpreter_with_memory(setup).unwrap();
// let output: Vec<U256> = interpreter.extract_kernel_memory(BnPairing, out..out + 12);
// let expected = miller_loop(CURVE_GENERATOR, TWISTED_GENERATOR).on_stack();
// assert_eq!(output, expected);
// Ok(())
// }
// #[test]
// fn test_tate() -> Result<()> {
// let ptr: usize = 200;
// let out: usize = 206;
// 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,
// ];
// let setup = InterpreterMemoryInitialization {
// label: "bn254_tate".to_string(),
// stack: vec![U256::from(ptr), U256::from(out), U256::from(0xdeadbeefu32)],
// segment: BnPairing,
// memory: vec![(ptr, inputs)],
// };
// let interpreter = run_interpreter_with_memory(setup).unwrap();
// let output: Vec<U256> = interpreter.extract_kernel_memory(BnPairing, out..out + 12);
// let expected = tate(CURVE_GENERATOR, TWISTED_GENERATOR).on_stack();
// assert_eq!(output, expected);
// Ok(())
// }