266 lines
8.2 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-04-26 09:57:36 -07:00
use crate::cpu::kernel::tests::u256ify;
2023-04-27 17:15:25 -07:00
use crate::curve_pairings::{final_exponent, gen_fp12_sparse, miller_loop, Curve};
2023-04-26 17:21:52 -07:00
use crate::extension_tower::{FieldExt, Fp12, Fp2, 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-04-19 14:51:25 -07:00
fn run_bn_mul_fp6(f: Fp6<BN254>, g: Fp6<BN254>, label: &str) -> Vec<U256> {
2023-03-21 13:55:51 -07:00
let mut stack = f.on_stack();
if label == "mul_fp254_6" {
stack.extend(g.on_stack());
}
stack.push(U256::from(0xdeadbeefu32));
2023-04-19 13:12:47 -07:00
let setup = InterpreterMemoryInitialization {
2023-03-21 13:55:51 -07:00
label: label.to_string(),
stack,
segment: BnPairing,
memory: vec![],
2023-04-19 13:12:47 -07:00
};
let interpreter = run_interpreter_with_memory(setup).unwrap();
extract_stack(interpreter)
2023-03-21 13:55:51 -07:00
}
2023-02-07 18:53:58 -08:00
2023-03-21 13:55:51 -07:00
#[test]
2023-04-19 14:51:25 -07:00
fn test_bn_mul_fp6() -> Result<()> {
2023-03-21 13:55:51 -07:00
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-04-19 14:51:25 -07:00
let out_normal: Vec<U256> = run_bn_mul_fp6(f, g, "mul_fp254_6");
let out_square: Vec<U256> = run_bn_mul_fp6(f, f, "square_fp254_6");
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-04-19 14:51:25 -07:00
fn run_bn_mul_fp12(f: Fp12<BN254>, g: Fp12<BN254>, label: &str) -> Vec<U256> {
2023-04-20 20:54:13 -07:00
let in0: usize = 100;
let in1: usize = 112;
let out: usize = 124;
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-04-19 13:12:47 -07:00
let setup = 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-04-19 13:12:47 -07:00
};
let interpreter = run_interpreter_with_memory(setup).unwrap();
interpreter.extract_kernel_memory(BnPairing, out..out + 12)
2022-11-14 15:58:37 -08:00
}
2022-12-14 20:16:50 -08:00
#[test]
2023-04-19 14:51:25 -07:00
fn test_bn_mul_fp12() -> Result<()> {
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>>();
2023-03-21 19:19:02 -07:00
let h: Fp12<BN254> = gen_fp12_sparse(&mut rng);
2022-11-15 13:34:47 -08:00
2023-04-19 14:51:25 -07:00
let out_normal: Vec<U256> = run_bn_mul_fp12(f, g, "mul_fp254_12");
let out_sparse: Vec<U256> = run_bn_mul_fp12(f, h, "mul_fp254_12_sparse");
let out_square: Vec<U256> = run_bn_mul_fp12(f, f, "square_fp254_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 19:19:02 -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 19:19:02 -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-04-19 14:51:25 -07:00
fn run_bn_frob_fp6(f: Fp6<BN254>, n: usize) -> Vec<U256> {
2023-04-19 13:19:06 -07:00
let setup = InterpreterMemoryInitialization {
label: format!("test_frob_fp254_6_{}", n),
2023-03-21 13:55:51 -07:00
stack: f.on_stack(),
segment: BnPairing,
memory: vec![],
2023-04-19 13:19:06 -07:00
};
let interpreter = run_interpreter_with_memory(setup).unwrap();
extract_stack(interpreter)
2023-03-21 13:55:51 -07:00
}
#[test]
2023-04-19 14:51:25 -07:00
fn test_bn_frob_fp6() -> Result<()> {
2023-03-21 13:55:51 -07:00
let mut rng = rand::thread_rng();
let f: Fp6<BN254> = rng.gen::<Fp6<BN254>>();
for n in 1..4 {
2023-04-19 14:51:25 -07:00
let output: Vec<U256> = run_bn_frob_fp6(f, n);
2023-04-19 13:19:06 -07:00
let expected: Vec<U256> = f.frob(n).on_stack();
assert_eq!(output, expected);
2023-03-21 13:55:51 -07:00
}
Ok(())
}
2023-03-21 13:51:11 -07:00
2023-04-19 14:51:25 -07:00
fn run_bn_frob_fp12(f: Fp12<BN254>, n: usize) -> Vec<U256> {
2023-04-20 20:54:13 -07:00
let ptr: usize = 100;
2023-04-19 13:19:06 -07:00
let setup = InterpreterMemoryInitialization {
label: format!("test_frob_fp254_12_{}", n),
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-04-19 13:19:06 -07:00
};
let interpreter = run_interpreter_with_memory(setup).unwrap();
interpreter.extract_kernel_memory(BnPairing, ptr..ptr + 12)
2023-01-20 14:52:44 +07:00
}
#[test]
2023-04-19 14:51:25 -07:00
fn test_bn_frob_fp12() -> Result<()> {
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-04-19 13:19:06 -07:00
2023-02-25 10:55:18 -08:00
for n in [1, 2, 3, 6] {
2023-04-19 14:51:25 -07:00
let output = run_bn_frob_fp12(f, n);
2023-04-19 13:19:06 -07:00
let expected: Vec<U256> = f.frob(n).on_stack();
assert_eq!(output, expected);
2023-02-25 10:55:18 -08:00
}
2023-01-20 14:52:44 +07:00
Ok(())
}
2022-12-19 14:39:23 -08:00
2023-03-21 19:19:02 -07:00
#[test]
2023-04-19 14:51:25 -07:00
fn test_bn_inv_fp12() -> Result<()> {
2023-04-20 20:54:13 -07:00
let ptr: usize = 100;
let inv: usize = 112;
2023-03-21 19:19:02 -07:00
let mut rng = rand::thread_rng();
let f: Fp12<BN254> = rng.gen::<Fp12<BN254>>();
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]
2023-04-19 14:51:25 -07:00
fn test_bn_final_exponent() -> Result<()> {
2023-04-20 20:54:13 -07:00
let ptr: usize = 100;
2023-04-19 13:30:03 -07:00
2023-03-21 19:19:02 -07:00
let mut rng = rand::thread_rng();
let f: Fp12<BN254> = rng.gen::<Fp12<BN254>>();
let setup = InterpreterMemoryInitialization {
2023-04-19 13:12:47 -07:00
label: "bn254_final_exponent".to_string(),
2023-04-19 14:45:11 -07:00
stack: vec![
U256::zero(),
U256::zero(),
U256::from(ptr),
U256::from(0xdeadbeefu32),
],
2023-03-21 19:19:02 -07:00
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);
2023-04-19 13:12:47 -07:00
let expected: Vec<U256> = final_exponent(f).on_stack();
2023-03-21 19:19:02 -07:00
assert_eq!(output, expected);
Ok(())
}
2023-04-24 09:37:42 -07:00
#[test]
fn test_bn_miller() -> Result<()> {
let ptr: usize = 100;
let out: usize = 106;
2023-04-27 16:20:55 -07:00
let mut rng = rand::thread_rng();
let p: Curve<BN254> = rng.gen::<Curve<BN254>>();
let q: Curve<Fp2<BN254>> = rng.gen::<Curve<Fp2<BN254>>>();
2023-04-27 17:15:25 -07:00
let mut input = p.on_stack();
input.extend(q.on_stack());
2023-03-21 19:19:02 -07:00
let setup = InterpreterMemoryInitialization {
label: "bn254_miller".to_string(),
stack: vec![U256::from(ptr), U256::from(out), U256::from(0xdeadbeefu32)],
segment: BnPairing,
2023-04-24 09:33:05 -07:00
memory: vec![(ptr, input)],
2023-03-21 19:19:02 -07:00
};
let interpreter = run_interpreter_with_memory(setup).unwrap();
let output: Vec<U256> = interpreter.extract_kernel_memory(BnPairing, out..out + 12);
2023-04-27 16:20:55 -07:00
let expected = miller_loop(p, q).on_stack();
2023-03-21 19:19:02 -07:00
assert_eq!(output, expected);
Ok(())
}
#[test]
2023-04-19 14:51:25 -07:00
fn test_bn_pairing() -> Result<()> {
2023-04-20 20:54:13 -07:00
let out: usize = 100;
let ptr: usize = 112;
2023-04-26 14:16:35 -07:00
2023-04-26 09:57:36 -07:00
let inputs: Vec<U256> = u256ify(vec![
"0x1c76476f4def4bb94541d57ebba1193381ffa7aa76ada664dd31c16024c43f59",
"0x3034dd2920f673e204fee2811c678745fc819b55d3e9d294e45c9b03a76aef41",
2023-04-26 14:16:23 -07:00
"0x04bf11ca01483bfa8b34b43561848d28905960114c8ac04049af4b6315a41678",
2023-04-26 09:57:36 -07:00
"0x209dd15ebff5d46c4bd888e51a93cf99a7329636c63514396b4a452003a35bf7",
"0x120a2a4cf30c1bf9845f20c6fe39e07ea2cce61f0c9bb048165fe5e4de877550",
"0x2bb8324af6cfc93537a2ad1a445cfd0ca2a71acd7ac41fadbf933c2a51be344d",
"0x111e129f1cf1097710d41c4ac70fcdfa5ba2023c6ff1cbeac322de49d1b6df7c",
"0x2032c61a830e3c17286de9462bf242fca2883585b93870a73853face6a6bf411",
"0x1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed",
"0x198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2",
"0x12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa",
2023-04-26 15:29:53 -07:00
"0x090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b",
2023-04-26 09:57:36 -07:00
])
.unwrap();
2023-04-26 14:16:23 -07:00
let setup = InterpreterMemoryInitialization {
2023-04-26 09:57:36 -07:00
label: "bn254_pairing".to_string(),
stack: vec![
2023-04-26 15:29:53 -07:00
U256::from(2),
2023-04-26 09:57:36 -07:00
U256::from(ptr),
U256::from(out),
U256::from(0xdeadbeefu32),
],
segment: BnPairing,
2023-04-26 14:16:23 -07:00
memory: vec![(ptr, inputs)],
2023-04-26 09:57:36 -07:00
};
2023-04-26 14:16:23 -07:00
let interpreter = run_interpreter_with_memory(setup).unwrap();
2023-04-26 15:35:19 -07:00
assert_eq!(interpreter.stack()[0], U256::one());
2023-03-21 19:19:02 -07:00
Ok(())
}