fp2 works

This commit is contained in:
Dmitry Vagner 2023-03-28 11:12:59 -07:00
parent 3b95e01390
commit 823b06acab
4 changed files with 135 additions and 52 deletions

View File

@ -53,7 +53,7 @@ global test_sub_fp381:
%jump(0xdeadbeef)
%macro add_fp381_2
global add_fp381_2:
// stack: x: 2, x_: 2, y: 2, y_: 2
%stack (x: 2, x_: 2, y: 2, y_: 2) -> (y_, x_, y, x)
// stack: y_: 2, x_: 2, y: 2, x: 2
@ -63,28 +63,52 @@ global test_sub_fp381:
// stack: x: 2, y: 2, z_: 2
%add_fp381
// stack: z: 2, z_: 2
%endmacro
%jump(0xdeadbeef)
%macro mul_fp381_2
// stack: x: 2, x_: 2, y: 2, y_: 2
%stack (x: 2, x_: 2, y: 2, y_: 2) -> (y_, x_, y, x)
// stack: y_: 2, x_: 2, y: 2, x: 2
%add_fp381
// stack: z_: 2, y: 2, x: 2
%stack (z_: 2, y: 2, x: 2) -> (x, y, z_)
// stack: x: 2, y: 2, z_: 2
%add_fp381
// stack: z: 2, z_: 2
%endmacro
global mul_fp381_2:
// stack: a, b, c, d
DUP4
DUP4
// stack: b, a, b, c, d
DUP8
DUP8
// stack: c, b, a, b, c, d
DUP12
DUP12
// stack: d, c, b, a, b, c, d
DUP8
DUP8
// stack: a, d, c, b, a, b, c, d
%macro sub_fp381_2
// stack: x: 2, x_: 2, y: 2, y_: 2
%stack (x: 2, x_: 2, y: 2, y_: 2) -> (y_, x_, y, x)
// stack: y_: 2, x_: 2, y: 2, x: 2
// stack: a, d, c, b, a, b, c, d
%mul_fp381
// stack: ad, c, b, a, b, c, d
%stack (ad: 2, c: 2, b: 2) -> (b, c, ad)
// stack: b, c, ad, a, b, c, d
%mul_fp381
// stack: bc, ad, a, b, c, d
%add_fp381
// stack: z_im, a, b, c, d
%stack (z_im: 2, a: 2, b: 2, c: 2, d: 2) -> (b, d, c, a, z_im)
// stack: b, d, c, a, z_im
%mul_fp381
// stack: bd, c, a, z_im
%stack (bd: 2, c: 2, a: 2) -> (a, c, bd)
// stack: a, c, bd, z_im
%mul_fp381
// stack: ac, bd, z_im
%sub_fp381
// stack: z_re, z_im
%jump(0xdeadbeef)
global sub_fp381_2:
// stack: x: 2, x_: 2, y: 2, y_: 2
%stack (x: 2, x_: 2, y: 2, y_: 2) -> (x_, y_, y, x)
// stack: x_: 2, y_: 2, y: 2, x: 2
%sub_fp381
// stack: z_: 2, y: 2, x: 2
%stack (z_: 2, y: 2, x: 2) -> (x, y, z_)
// stack: x: 2, y: 2, z_: 2
%add_fp381
%sub_fp381
// stack: z: 2, z_: 2
%endmacro
%jump(0xdeadbeef)

View File

@ -4,12 +4,12 @@ use rand::Rng;
use crate::cpu::kernel::interpreter::{
run_interpreter_with_memory, InterpreterMemoryInitialization,
};
use crate::extension_tower::{Stack, BLS381};
use crate::extension_tower::{Fp2, Stack, BLS381};
use crate::memory::segments::Segment::KernelGeneral;
fn run_and_return_bls(label: String, x: BLS381, y: BLS381) -> BLS381 {
let mut stack = x.on_stack();
stack.extend(y.on_stack());
let mut stack = x.to_stack();
stack.extend(y.to_stack());
let setup = InterpreterMemoryInitialization {
label,
stack,
@ -18,7 +18,7 @@ fn run_and_return_bls(label: String, x: BLS381, y: BLS381) -> BLS381 {
};
let interpreter = run_interpreter_with_memory(setup).unwrap();
let output = interpreter.stack();
BLS381::from_limbs(output[0], output[1])
BLS381::from_stack(output)
}
#[test]
@ -37,3 +37,34 @@ fn test_bls_ops() -> Result<()> {
Ok(())
}
fn run_and_return_bls_fp2(label: String, x: Fp2<BLS381>, y: Fp2<BLS381>) -> Fp2<BLS381> {
let mut stack = x.to_stack();
stack.extend(y.to_stack());
let setup = InterpreterMemoryInitialization {
label,
stack,
segment: KernelGeneral,
memory: vec![],
};
let interpreter = run_interpreter_with_memory(setup).unwrap();
let output = interpreter.stack();
Fp2::from_stack(output)
}
#[test]
fn test_bls_fp2() -> Result<()> {
let mut rng = rand::thread_rng();
let x: Fp2<BLS381> = rng.gen::<Fp2<BLS381>>();
let y: Fp2<BLS381> = rng.gen::<Fp2<BLS381>>();
let output_add = run_and_return_bls_fp2("add_fp381_2".to_string(), x, y);
let output_mul = run_and_return_bls_fp2("mul_fp381_2".to_string(), x, y);
let output_sub = run_and_return_bls_fp2("sub_fp381_2".to_string(), x, y);
assert_eq!(output_add, x + y);
assert_eq!(output_mul, x * y);
assert_eq!(output_sub, x - y);
Ok(())
}

View File

@ -25,9 +25,9 @@ fn setup_mul_fp6_test(
g: Fp6<BN254>,
label: &str,
) -> InterpreterMemoryInitialization {
let mut stack = f.on_stack();
let mut stack = f.to_stack();
if label == "mul_fp254_6" {
stack.extend(g.on_stack());
stack.extend(g.to_stack());
}
stack.push(U256::from(0xdeadbeefu32));
InterpreterMemoryInitialization {
@ -53,8 +53,8 @@ fn test_mul_fp6() -> Result<()> {
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();
let exp_normal: Vec<U256> = (f * g).to_stack();
let exp_square: Vec<U256> = (f * f).to_stack();
assert_eq!(out_normal, exp_normal);
assert_eq!(out_square, exp_square);
@ -84,7 +84,7 @@ fn setup_mul_fp12_test(
label: label.to_string(),
stack,
segment: BnPairing,
memory: vec![(in0, f.on_stack()), (in1, g.on_stack())],
memory: vec![(in0, f.to_stack()), (in1, g.to_stack())],
}
}
@ -112,9 +112,9 @@ fn test_mul_fp12() -> Result<()> {
let out_sparse: Vec<U256> = intrptr_sparse.extract_kernel_memory(BnPairing, out..out + 12);
let out_square: Vec<U256> = intrptr_square.extract_kernel_memory(BnPairing, out..out + 12);
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();
let exp_normal: Vec<U256> = (f * g).to_stack();
let exp_sparse: Vec<U256> = (f * h).to_stack();
let exp_square: Vec<U256> = (f * f).to_stack();
assert_eq!(out_normal, exp_normal);
assert_eq!(out_sparse, exp_sparse);
@ -126,7 +126,7 @@ fn test_mul_fp12() -> Result<()> {
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(),
stack: f.to_stack(),
segment: BnPairing,
memory: vec![],
}
@ -140,7 +140,7 @@ fn test_frob_fp6() -> Result<()> {
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();
let exp_frob: Vec<U256> = f.frob(n).to_stack();
assert_eq!(out_frob, exp_frob);
}
Ok(())
@ -151,7 +151,7 @@ fn setup_frob_fp12_test(ptr: usize, f: Fp12<BN254>, n: usize) -> InterpreterMemo
label: String::from("test_frob_fp254_12_") + &(n.to_string()),
stack: vec![U256::from(ptr)],
segment: BnPairing,
memory: vec![(ptr, f.on_stack())],
memory: vec![(ptr, f.to_stack())],
}
}
@ -164,7 +164,7 @@ fn test_frob_fp12() -> Result<()> {
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();
let exp_frob: Vec<U256> = f.frob(n).to_stack();
assert_eq!(out_frob, exp_frob);
}
Ok(())
@ -181,11 +181,11 @@ fn test_inv_fp12() -> Result<()> {
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())],
memory: vec![(ptr, f.to_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();
let expected: Vec<U256> = f.inv().to_stack();
assert_eq!(output, expected);
@ -202,12 +202,12 @@ fn test_invariant_exponent() -> Result<()> {
label: "bn254_invariant_exponent".to_string(),
stack: vec![U256::from(ptr), U256::from(0xdeadbeefu32)],
segment: BnPairing,
memory: vec![(ptr, f.on_stack())],
memory: vec![(ptr, f.to_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();
let expected: Vec<U256> = invariant_exponent(f).to_stack();
assert_eq!(output, expected);
@ -287,7 +287,7 @@ fn test_miller() -> Result<()> {
};
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();
let expected = miller_loop(CURVE_GENERATOR, TWISTED_GENERATOR).to_stack();
assert_eq!(output, expected);
@ -315,7 +315,7 @@ fn test_tate() -> Result<()> {
};
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();
let expected = tate(CURVE_GENERATOR, TWISTED_GENERATOR).to_stack();
assert_eq!(output, expected);

View File

@ -144,13 +144,6 @@ impl BLS381 {
pub fn hi(self) -> U256 {
U256(self.val.0[4..].try_into().unwrap())
}
pub fn from_limbs(hi: U256, lo: U256) -> BLS381 {
let mut val = [0u64; 8];
val[..4].copy_from_slice(&lo.0);
val[4..].copy_from_slice(&hi.0);
BLS381 { val: U512(val) }
}
}
impl Distribution<BLS381> for Standard {
@ -1208,25 +1201,60 @@ where
}
pub trait Stack {
fn on_stack(self) -> Vec<U256>;
fn to_stack(self) -> Vec<U256>;
fn from_stack(stack: &[U256]) -> Self;
}
impl Stack for BLS381 {
fn on_stack(self) -> Vec<U256> {
fn to_stack(self) -> Vec<U256> {
vec![self.lo(), self.hi()]
}
fn from_stack(stack: &[U256]) -> BLS381 {
let mut val = [0u64; 8];
val[..4].copy_from_slice(&stack[1].0);
val[4..].copy_from_slice(&stack[0].0);
BLS381 { val: U512(val) }
}
}
impl Stack for Fp2<BLS381> {
fn to_stack(self) -> Vec<U256> {
let mut res = self.re.to_stack();
res.extend(self.im.to_stack());
res
}
fn from_stack(stack: &[U256]) -> Fp2<BLS381> {
let re = BLS381::from_stack(&stack[2..4]);
let im = BLS381::from_stack(&stack[0..2]);
Fp2 { re, im }
}
}
impl Stack for Fp6<BN254> {
fn on_stack(self) -> Vec<U256> {
fn to_stack(self) -> Vec<U256> {
let f: [U256; 6] = unsafe { transmute(self) };
f.into_iter().collect()
}
fn from_stack(stack: &[U256]) -> Self {
let mut f = [U256::zero(); 6];
f.copy_from_slice(stack);
unsafe { transmute(f) }
}
}
impl Stack for Fp12<BN254> {
fn on_stack(self) -> Vec<U256> {
fn to_stack(self) -> Vec<U256> {
let f: [U256; 12] = unsafe { transmute(self) };
f.into_iter().collect()
}
fn from_stack(stack: &[U256]) -> Self {
let mut f = [U256::zero(); 12];
f.copy_from_slice(stack);
unsafe { transmute(f) }
}
}