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-02-01 19:15:56 -08:00
|
|
|
use rand::Rng;
|
2022-10-12 10:06:34 -04:00
|
|
|
|
2023-02-07 18:53:58 -08:00
|
|
|
use crate::bn254_arithmetic::{Fp, Fp12, Fp2, Fp6};
|
2023-02-07 14:54:07 -08:00
|
|
|
use crate::bn254_pairing::{
|
|
|
|
|
gen_fp12_sparse, invariant_exponent, miller_loop, 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-02-07 14:54:07 -08:00
|
|
|
impl InterpreterSetup {
|
|
|
|
|
fn run(self) -> Result<Interpreter<'static>> {
|
|
|
|
|
let label = KERNEL.global_labels[&self.label];
|
|
|
|
|
let mut stack = self.stack;
|
|
|
|
|
stack.reverse();
|
|
|
|
|
let mut interpreter = Interpreter::new_with_kernel(label, stack);
|
|
|
|
|
for (pointer, data) in self.memory {
|
|
|
|
|
for (i, term) in data.iter().enumerate() {
|
|
|
|
|
interpreter.generation_state.memory.set(
|
2023-02-13 12:32:40 -08:00
|
|
|
MemoryAddress::new(0, Segment::BnPairing, pointer + i),
|
2023-02-07 14:54:07 -08:00
|
|
|
*term,
|
|
|
|
|
)
|
|
|
|
|
}
|
2023-01-20 13:59:39 +07:00
|
|
|
}
|
2023-02-07 14:54:07 -08:00
|
|
|
interpreter.run()?;
|
|
|
|
|
Ok(interpreter)
|
2023-01-20 13:59:39 +07:00
|
|
|
}
|
2023-01-21 13:19:07 +07:00
|
|
|
}
|
2023-01-20 14:30:12 +07:00
|
|
|
|
2023-02-07 14:54:07 -08:00
|
|
|
fn extract_kernel_memory(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 {
|
2023-02-13 13:21:47 -08:00
|
|
|
let term =
|
|
|
|
|
interpreter
|
|
|
|
|
.generation_state
|
|
|
|
|
.memory
|
|
|
|
|
.get(MemoryAddress::new(0, Segment::BnPairing, i));
|
2023-01-21 13:19:07 +07:00
|
|
|
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-02-07 18:53:58 -08:00
|
|
|
fn extract_stack(interpreter: Interpreter<'static>) -> Vec<U256> {
|
|
|
|
|
let stack = interpreter.stack();
|
|
|
|
|
stack.iter().rev().cloned().collect::<Vec<U256>>()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn setup_mul_fp6_test(f: Fp6, g: Fp6, label: &str) -> InterpreterSetup {
|
|
|
|
|
let mut stack = f.on_stack();
|
|
|
|
|
if label == "mul_fp254_6" {
|
|
|
|
|
stack.extend(g.on_stack());
|
|
|
|
|
}
|
|
|
|
|
stack.push(U256::from(0xdeadbeefu32));
|
|
|
|
|
InterpreterSetup {
|
|
|
|
|
label: label.to_string(),
|
|
|
|
|
stack,
|
|
|
|
|
memory: vec![],
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_mul_fp6() -> Result<()> {
|
|
|
|
|
let mut rng = rand::thread_rng();
|
|
|
|
|
let f: Fp6 = rng.gen::<Fp6>();
|
|
|
|
|
let g: Fp6 = rng.gen::<Fp6>();
|
|
|
|
|
|
|
|
|
|
let setup_normal: InterpreterSetup = setup_mul_fp6_test(f, g, "mul_fp254_6");
|
|
|
|
|
let setup_square: InterpreterSetup = setup_mul_fp6_test(f, f, "square_fp254_6");
|
|
|
|
|
|
|
|
|
|
let intrptr_normal: Interpreter = setup_normal.run().unwrap();
|
|
|
|
|
let intrptr_square: Interpreter = setup_square.run().unwrap();
|
|
|
|
|
|
|
|
|
|
let out_normal: Vec<U256> = extract_stack(intrptr_normal);
|
|
|
|
|
let out_square: Vec<U256> = extract_stack(intrptr_square);
|
|
|
|
|
|
|
|
|
|
let exp_normal: Vec<U256> = (f * g).on_stack();
|
|
|
|
|
let exp_square: Vec<U256> = (f * f).on_stack();
|
|
|
|
|
|
|
|
|
|
assert_eq!(out_normal, exp_normal);
|
|
|
|
|
assert_eq!(out_square, exp_square);
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn setup_mul_fp12_test(out: usize, f: Fp12, g: Fp12, label: &str) -> InterpreterSetup {
|
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-01-20 14:30:12 +07:00
|
|
|
InterpreterSetup {
|
2023-01-24 00:01:47 +07:00
|
|
|
label: label.to_string(),
|
2023-02-07 18:53:58 -08:00
|
|
|
stack,
|
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();
|
|
|
|
|
let f: Fp12 = rng.gen::<Fp12>();
|
|
|
|
|
let g: Fp12 = rng.gen::<Fp12>();
|
|
|
|
|
let h: Fp12 = gen_fp12_sparse(&mut rng);
|
2022-11-15 13:34:47 -08:00
|
|
|
|
2023-02-07 18:53:58 -08:00
|
|
|
let setup_normal: InterpreterSetup = setup_mul_fp12_test(out, f, g, "mul_fp254_12");
|
|
|
|
|
let setup_sparse: InterpreterSetup = setup_mul_fp12_test(out, f, h, "mul_fp254_12_sparse");
|
|
|
|
|
let setup_square: InterpreterSetup = setup_mul_fp12_test(out, f, f, "square_fp254_12");
|
2023-01-21 13:19:07 +07:00
|
|
|
|
2023-02-07 14:54:07 -08:00
|
|
|
let intrptr_normal: Interpreter = setup_normal.run().unwrap();
|
|
|
|
|
let intrptr_sparse: Interpreter = setup_sparse.run().unwrap();
|
|
|
|
|
let intrptr_square: Interpreter = setup_square.run().unwrap();
|
2022-11-15 13:34:47 -08:00
|
|
|
|
2023-02-07 14:54:07 -08:00
|
|
|
let out_normal: Vec<U256> = extract_kernel_memory(out..out + 12, intrptr_normal);
|
|
|
|
|
let out_sparse: Vec<U256> = extract_kernel_memory(out..out + 12, intrptr_sparse);
|
|
|
|
|
let out_square: Vec<U256> = extract_kernel_memory(out..out + 12, intrptr_square);
|
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();
|
|
|
|
|
let exp_sparse: Vec<U256> = (f * h).on_stack();
|
|
|
|
|
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);
|
|
|
|
|
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-02-07 18:53:58 -08:00
|
|
|
fn setup_frob_fp6_test(f: Fp6, label: &str) -> InterpreterSetup {
|
|
|
|
|
InterpreterSetup {
|
|
|
|
|
label: label.to_string(),
|
|
|
|
|
stack: f.on_stack(),
|
|
|
|
|
memory: vec![],
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_frob_fp6() -> Result<()> {
|
|
|
|
|
let mut rng = rand::thread_rng();
|
|
|
|
|
let f: Fp6 = rng.gen::<Fp6>();
|
|
|
|
|
|
|
|
|
|
let setup_frob_1 = setup_frob_fp6_test(f, "test_frob_fp254_6_1");
|
|
|
|
|
let setup_frob_2 = setup_frob_fp6_test(f, "test_frob_fp254_6_2");
|
|
|
|
|
let setup_frob_3 = setup_frob_fp6_test(f, "test_frob_fp254_6_3");
|
|
|
|
|
|
|
|
|
|
let intrptr_frob_1: Interpreter = setup_frob_1.run().unwrap();
|
|
|
|
|
let intrptr_frob_2: Interpreter = setup_frob_2.run().unwrap();
|
|
|
|
|
let intrptr_frob_3: Interpreter = setup_frob_3.run().unwrap();
|
|
|
|
|
|
|
|
|
|
let out_frob_1: Vec<U256> = extract_stack(intrptr_frob_1);
|
|
|
|
|
let out_frob_2: Vec<U256> = extract_stack(intrptr_frob_2);
|
|
|
|
|
let out_frob_3: Vec<U256> = extract_stack(intrptr_frob_3);
|
|
|
|
|
|
|
|
|
|
let exp_frob_1: Vec<U256> = f.frob(1).on_stack();
|
|
|
|
|
let exp_frob_2: Vec<U256> = f.frob(2).on_stack();
|
|
|
|
|
let exp_frob_3: Vec<U256> = f.frob(3).on_stack();
|
|
|
|
|
|
|
|
|
|
assert_eq!(out_frob_1, exp_frob_1);
|
|
|
|
|
assert_eq!(out_frob_2, exp_frob_2);
|
|
|
|
|
assert_eq!(out_frob_3, exp_frob_3);
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn setup_frob_fp12_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-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();
|
|
|
|
|
let f: Fp12 = rng.gen::<Fp12>();
|
2023-01-20 14:52:44 +07:00
|
|
|
|
2023-02-07 18:53:58 -08:00
|
|
|
let setup_frob_1 = setup_frob_fp12_test(ptr, f, "test_frob_fp254_12_1");
|
|
|
|
|
let setup_frob_2 = setup_frob_fp12_test(ptr, f, "test_frob_fp254_12_2");
|
|
|
|
|
let setup_frob_3 = setup_frob_fp12_test(ptr, f, "test_frob_fp254_12_3");
|
|
|
|
|
let setup_frob_6 = setup_frob_fp12_test(ptr, f, "test_frob_fp254_12_6");
|
2023-01-20 14:52:44 +07:00
|
|
|
|
2023-02-07 14:54:07 -08:00
|
|
|
let intrptr_frob_1: Interpreter = setup_frob_1.run().unwrap();
|
|
|
|
|
let intrptr_frob_2: Interpreter = setup_frob_2.run().unwrap();
|
|
|
|
|
let intrptr_frob_3: Interpreter = setup_frob_3.run().unwrap();
|
|
|
|
|
let intrptr_frob_6: Interpreter = setup_frob_6.run().unwrap();
|
2023-01-21 13:19:07 +07:00
|
|
|
|
2023-02-07 14:54:07 -08:00
|
|
|
let out_frob_1: Vec<U256> = extract_kernel_memory(ptr..ptr + 12, intrptr_frob_1);
|
|
|
|
|
let out_frob_2: Vec<U256> = extract_kernel_memory(ptr..ptr + 12, intrptr_frob_2);
|
|
|
|
|
let out_frob_3: Vec<U256> = extract_kernel_memory(ptr..ptr + 12, intrptr_frob_3);
|
|
|
|
|
let out_frob_6: Vec<U256> = extract_kernel_memory(ptr..ptr + 12, intrptr_frob_6);
|
2023-01-20 14:52:44 +07:00
|
|
|
|
2023-02-07 09:18:49 -08:00
|
|
|
let exp_frob_1: Vec<U256> = f.frob(1).on_stack();
|
|
|
|
|
let exp_frob_2: Vec<U256> = f.frob(2).on_stack();
|
|
|
|
|
let exp_frob_3: Vec<U256> = f.frob(3).on_stack();
|
|
|
|
|
let exp_frob_6: Vec<U256> = f.frob(6).on_stack();
|
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-02-07 14:54:07 -08:00
|
|
|
fn test_inv_fp12() -> Result<()> {
|
2023-02-13 14:04:43 -08:00
|
|
|
let ptr: usize = 200;
|
|
|
|
|
let inv: usize = 212;
|
2023-02-01 19:15:56 -08:00
|
|
|
let mut rng = rand::thread_rng();
|
|
|
|
|
let f: Fp12 = rng.gen::<Fp12>();
|
2023-02-01 19:19:36 -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-02-07 09:18:49 -08:00
|
|
|
memory: vec![(ptr, f.on_stack())],
|
2023-01-21 13:19:07 +07:00
|
|
|
};
|
2023-02-07 14:54:07 -08:00
|
|
|
let interpreter: Interpreter = setup.run().unwrap();
|
|
|
|
|
let output: Vec<U256> = extract_kernel_memory(inv..inv + 12, interpreter);
|
2023-02-07 09:18:49 -08:00
|
|
|
let expected: Vec<U256> = f.inv().on_stack();
|
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-02-07 14:54:07 -08:00
|
|
|
#[test]
|
|
|
|
|
fn test_invariant_exponent() -> Result<()> {
|
2023-02-13 14:04:43 -08:00
|
|
|
let ptr: usize = 200;
|
2022-12-20 17:23:05 -08:00
|
|
|
|
2023-02-07 14:54:07 -08:00
|
|
|
let mut rng = rand::thread_rng();
|
|
|
|
|
let f: Fp12 = rng.gen::<Fp12>();
|
2022-12-20 17:23:05 -08:00
|
|
|
|
2023-02-07 14:54:07 -08:00
|
|
|
let setup = InterpreterSetup {
|
|
|
|
|
label: "bn254_invariant_exponent".to_string(),
|
|
|
|
|
stack: vec![U256::from(ptr), U256::from(0xdeadbeefu32)],
|
|
|
|
|
memory: vec![(ptr, f.on_stack())],
|
|
|
|
|
};
|
2022-12-21 14:52:54 -08:00
|
|
|
|
2023-02-07 14:54:07 -08:00
|
|
|
let interpreter: Interpreter = setup.run().unwrap();
|
|
|
|
|
let output: Vec<U256> = extract_kernel_memory(ptr..ptr + 12, interpreter);
|
|
|
|
|
let expected: Vec<U256> = invariant_exponent(f).on_stack();
|
2022-12-21 14:52:54 -08:00
|
|
|
|
2023-02-07 14:54:07 -08:00
|
|
|
assert_eq!(output, expected);
|
2022-12-21 14:52:54 -08:00
|
|
|
|
2023-02-07 14:54:07 -08:00
|
|
|
Ok(())
|
|
|
|
|
}
|
2022-12-21 14:52:54 -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-02-07 09:18:49 -08:00
|
|
|
#[test]
|
|
|
|
|
fn test_miller() -> Result<()> {
|
|
|
|
|
let ptr: usize = 300;
|
|
|
|
|
let out: usize = 400;
|
|
|
|
|
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 = InterpreterSetup {
|
|
|
|
|
label: "bn254_miller".to_string(),
|
|
|
|
|
stack: vec![U256::from(ptr), U256::from(out), U256::from(0xdeadbeefu32)],
|
|
|
|
|
memory: vec![(ptr, inputs)],
|
|
|
|
|
};
|
2023-02-07 14:54:07 -08:00
|
|
|
let interpreter = setup.run().unwrap();
|
|
|
|
|
let output: Vec<U256> = extract_kernel_memory(out..out + 12, interpreter);
|
2023-02-07 09:18:49 -08:00
|
|
|
let expected = miller_loop(CURVE_GENERATOR, TWISTED_GENERATOR).on_stack();
|
|
|
|
|
|
|
|
|
|
assert_eq!(output, expected);
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-24 09:42:42 +07:00
|
|
|
#[test]
|
|
|
|
|
fn test_tate() -> Result<()> {
|
2023-02-13 14:04:43 -08:00
|
|
|
let ptr: usize = 200;
|
|
|
|
|
let out: usize = 206;
|
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 {
|
2023-02-05 17:40:04 -08:00
|
|
|
label: "bn254_tate".to_string(),
|
2023-01-24 09:42:42 +07:00
|
|
|
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
|
|
|
};
|
2023-02-07 14:54:07 -08:00
|
|
|
let interpreter = setup.run().unwrap();
|
|
|
|
|
let output: Vec<U256> = extract_kernel_memory(out..out + 12, interpreter);
|
2023-02-07 09:18:49 -08:00
|
|
|
let expected = tate(CURVE_GENERATOR, TWISTED_GENERATOR).on_stack();
|
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(())
|
|
|
|
|
}
|