mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-04-05 03:03:45 +00:00
Merge pull request #941 from mir-protocol/bls-fp2
BLS Fp2 Operations and More Systematic Test API
This commit is contained in:
commit
c36ed15e2d
@ -12,20 +12,6 @@
|
||||
// stack: z0, z1
|
||||
%endmacro
|
||||
|
||||
%macro mul_fp381
|
||||
// stack: x0, x1, y0, y1
|
||||
PROVER_INPUT(sf::bls381_base::mul_hi)
|
||||
// stack: z1, x0, x1, y0, y1
|
||||
SWAP4
|
||||
// stack: y1, x0, x1, y0, z1
|
||||
PROVER_INPUT(sf::bls381_base::mul_lo)
|
||||
// stack: z0, y1, x0, x1, y0, z1
|
||||
SWAP4
|
||||
// stack: y0, y1, x0, x1, z0, z1
|
||||
%pop4
|
||||
// stack: z0, z1
|
||||
%endmacro
|
||||
|
||||
%macro sub_fp381
|
||||
// stack: x0, x1, y0, y1
|
||||
PROVER_INPUT(sf::bls381_base::sub_hi)
|
||||
@ -40,14 +26,76 @@
|
||||
// stack: z0, z1
|
||||
%endmacro
|
||||
|
||||
global test_add_fp381:
|
||||
%macro mul_fp381
|
||||
// stack: x0, x1, y0, y1
|
||||
PROVER_INPUT(sf::bls381_base::mul_hi)
|
||||
// stack: z1, x0, x1, y0, y1
|
||||
SWAP4
|
||||
// stack: y1, x0, x1, y0, z1
|
||||
PROVER_INPUT(sf::bls381_base::mul_lo)
|
||||
// stack: z0, y1, x0, x1, y0, z1
|
||||
SWAP4
|
||||
// stack: y0, y1, x0, x1, z0, z1
|
||||
%pop4
|
||||
// stack: z0, z1
|
||||
%endmacro
|
||||
|
||||
%macro add_fp381_2
|
||||
// stack: x_re, x_im, y_re, y_im
|
||||
%stack (x_re: 2, x_im: 2, y_re: 2, y_im: 2) -> (y_im, x_im, y_re, x_re)
|
||||
// stack: y_im, x_im, y_re, x_re
|
||||
%add_fp381
|
||||
%jump(0xdeadbeef)
|
||||
// stack: z_im, y_re, x_re
|
||||
%stack (z_im: 2, y_re: 2, x_re: 2) -> (x_re, y_re, z_im)
|
||||
// stack: x_re, y_re, z_im
|
||||
%add_fp381
|
||||
// stack: z_re, z_im
|
||||
%endmacro
|
||||
|
||||
global test_mul_fp381:
|
||||
%mul_fp381
|
||||
%jump(0xdeadbeef)
|
||||
|
||||
global test_sub_fp381:
|
||||
%macro sub_fp381_2
|
||||
// stack: x_re, x_im, y_re, y_im
|
||||
%stack (x_re: 2, x_im: 2, y_re: 2, y_im: 2) -> (x_im, y_im, y_re, x_re)
|
||||
// stack: x_im, y_im, y_re, x_re
|
||||
%sub_fp381
|
||||
%jump(0xdeadbeef)
|
||||
// stack: z_im, y_re, x_re
|
||||
%stack (z_im: 2, y_re: 2, x_re: 2) -> (x_re, y_re, z_im)
|
||||
// stack: x_re, y_re, z_im
|
||||
%sub_fp381
|
||||
// stack: z_re, z_im
|
||||
%endmacro
|
||||
|
||||
// note that {x,y}_{re,im} all take up two stack terms
|
||||
global mul_fp381_2:
|
||||
// stack: x_re, x_im, y_re, y_im, jumpdest
|
||||
DUP4
|
||||
DUP4
|
||||
// stack: x_im, x_re, x_im, y_re, y_im, jumpdest
|
||||
DUP8
|
||||
DUP8
|
||||
// stack: y_re, x_im, x_re, x_im, y_re, y_im, jumpdest
|
||||
DUP12
|
||||
DUP12
|
||||
// stack: y_im, y_re, x_im, x_re, x_im, y_re, y_im, jumpdest
|
||||
DUP8
|
||||
DUP8
|
||||
// stack: x_re , y_im, y_re, x_im, x_re, x_im, y_re, y_im, jumpdest
|
||||
%mul_fp381
|
||||
// stack: x_re * y_im, y_re, x_im, x_re, x_im, y_re, y_im, jumpdest
|
||||
%stack (v: 2, y_re: 2, x_im: 2) -> (x_im, y_re, v)
|
||||
// stack: x_im , y_re, x_re*y_im, x_re, x_im, y_re, y_im, jumpdest
|
||||
%mul_fp381
|
||||
// stack: x_im * y_re, x_re*y_im, x_re, x_im, y_re, y_im, jumpdest
|
||||
%add_fp381
|
||||
// stack: z_im, x_re, x_im, y_re, y_im, jumpdest
|
||||
%stack (z_im: 2, x_re: 2, x_im: 2, y_re: 2, y_im: 2) -> (x_im, y_im, y_re, x_re, z_im)
|
||||
// stack: x_im , y_im, y_re, x_re, z_im, jumpdest
|
||||
%mul_fp381
|
||||
// stack: x_im * y_im, y_re, x_re, z_im, jumpdest
|
||||
%stack (v: 2, y_re: 2, x_re: 2) -> (x_re, y_re, v)
|
||||
// stack: x_re , y_re, x_im*y_im, z_im, jumpdest
|
||||
%mul_fp381
|
||||
// stack: x_re * y_re, x_im*y_im, z_im, jumpdest
|
||||
%sub_fp381
|
||||
// stack: z_re, z_im, jumpdest
|
||||
%stack (z_re: 2, z_im: 2, jumpdest) -> (jumpdest, z_re, z_im)
|
||||
JUMP
|
||||
|
||||
@ -1,42 +1,32 @@
|
||||
use anyhow::Result;
|
||||
use ethereum_types::U512;
|
||||
use ethereum_types::U256;
|
||||
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());
|
||||
#[test]
|
||||
fn test_bls_fp2_mul() -> Result<()> {
|
||||
let mut rng = rand::thread_rng();
|
||||
let x: Fp2<BLS381> = rng.gen::<Fp2<BLS381>>();
|
||||
let y: Fp2<BLS381> = rng.gen::<Fp2<BLS381>>();
|
||||
|
||||
let mut stack = x.to_stack().to_vec();
|
||||
stack.extend(y.to_stack().to_vec());
|
||||
stack.push(U256::from(0xdeadbeefu32));
|
||||
let setup = InterpreterMemoryInitialization {
|
||||
label,
|
||||
label: "mul_fp381_2".to_string(),
|
||||
stack,
|
||||
segment: KernelGeneral,
|
||||
memory: vec![],
|
||||
};
|
||||
let interpreter = run_interpreter_with_memory(setup).unwrap();
|
||||
let output = interpreter.stack();
|
||||
BLS381 {
|
||||
val: U512::from(output[1]) + (U512::from(output[0]) << 256),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bls_ops() -> Result<()> {
|
||||
let mut rng = rand::thread_rng();
|
||||
let x: BLS381 = rng.gen::<BLS381>();
|
||||
let y: BLS381 = rng.gen::<BLS381>();
|
||||
|
||||
let output_add = run_and_return_bls("test_add_fp381".to_string(), x, y);
|
||||
let output_mul = run_and_return_bls("test_mul_fp381".to_string(), x, y);
|
||||
let output_sub = run_and_return_bls("test_sub_fp381".to_string(), x, y);
|
||||
|
||||
assert_eq!(output_add, x + y);
|
||||
assert_eq!(output_mul, x * y);
|
||||
assert_eq!(output_sub, x - y);
|
||||
let stack: Vec<U256> = interpreter.stack().iter().rev().cloned().collect();
|
||||
let output = Fp2::<BLS381>::from_stack(&stack);
|
||||
|
||||
assert_eq!(output, x * y);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -11,22 +11,12 @@ use crate::curve_pairings::{
|
||||
use crate::extension_tower::{FieldExt, Fp12, Fp2, Fp6, Stack, BN254};
|
||||
use crate::memory::segments::Segment::BnPairing;
|
||||
|
||||
fn extract_stack(interpreter: Interpreter<'static>) -> Vec<U256> {
|
||||
interpreter
|
||||
.stack()
|
||||
.iter()
|
||||
.rev()
|
||||
.cloned()
|
||||
.collect::<Vec<U256>>()
|
||||
}
|
||||
|
||||
fn run_bn_mul_fp6(f: Fp6<BN254>, g: Fp6<BN254>, label: &str) -> Vec<U256> {
|
||||
let mut stack = f.on_stack();
|
||||
fn run_bn_mul_fp6(f: Fp6<BN254>, g: Fp6<BN254>, label: &str) -> Fp6<BN254> {
|
||||
let mut stack = f.to_stack();
|
||||
if label == "mul_fp254_6" {
|
||||
stack.extend(g.on_stack());
|
||||
stack.extend(g.to_stack().to_vec());
|
||||
}
|
||||
stack.push(U256::from(0xdeadbeefu32));
|
||||
|
||||
let setup = InterpreterMemoryInitialization {
|
||||
label: label.to_string(),
|
||||
stack,
|
||||
@ -34,7 +24,8 @@ fn run_bn_mul_fp6(f: Fp6<BN254>, g: Fp6<BN254>, label: &str) -> Vec<U256> {
|
||||
memory: vec![],
|
||||
};
|
||||
let interpreter = run_interpreter_with_memory(setup).unwrap();
|
||||
extract_stack(interpreter)
|
||||
let output: Vec<U256> = interpreter.stack().iter().rev().cloned().collect();
|
||||
Fp6::<BN254>::from_stack(&output)
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -43,19 +34,16 @@ fn test_bn_mul_fp6() -> Result<()> {
|
||||
let f: Fp6<BN254> = rng.gen::<Fp6<BN254>>();
|
||||
let g: Fp6<BN254> = rng.gen::<Fp6<BN254>>();
|
||||
|
||||
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");
|
||||
let output_normal: Fp6<BN254> = run_bn_mul_fp6(f, g, "mul_fp254_6");
|
||||
let output_square: Fp6<BN254> = run_bn_mul_fp6(f, f, "square_fp254_6");
|
||||
|
||||
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);
|
||||
assert_eq!(output_normal, f * g);
|
||||
assert_eq!(output_square, f * f);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn run_bn_mul_fp12(f: Fp12<BN254>, g: Fp12<BN254>, label: &str) -> Vec<U256> {
|
||||
fn run_bn_mul_fp12(f: Fp12<BN254>, g: Fp12<BN254>, label: &str) -> Fp12<BN254> {
|
||||
let in0: usize = 100;
|
||||
let in1: usize = 112;
|
||||
let out: usize = 124;
|
||||
@ -69,15 +57,15 @@ fn run_bn_mul_fp12(f: Fp12<BN254>, g: Fp12<BN254>, label: &str) -> Vec<U256> {
|
||||
if label == "square_fp254_12" {
|
||||
stack.remove(0);
|
||||
}
|
||||
|
||||
let setup = InterpreterMemoryInitialization {
|
||||
label: label.to_string(),
|
||||
stack,
|
||||
segment: BnPairing,
|
||||
memory: vec![(in0, f.on_stack()), (in1, g.on_stack())],
|
||||
memory: vec![(in0, f.to_stack().to_vec()), (in1, g.to_stack().to_vec())],
|
||||
};
|
||||
let interpreter = run_interpreter_with_memory(setup).unwrap();
|
||||
interpreter.extract_kernel_memory(BnPairing, out..out + 12)
|
||||
let output = interpreter.extract_kernel_memory(BnPairing, out..out + 12);
|
||||
Fp12::<BN254>::from_stack(&output)
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -87,30 +75,27 @@ fn test_bn_mul_fp12() -> Result<()> {
|
||||
let g: Fp12<BN254> = rng.gen::<Fp12<BN254>>();
|
||||
let h: Fp12<BN254> = gen_bn_fp12_sparse(&mut rng);
|
||||
|
||||
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");
|
||||
let output_normal = run_bn_mul_fp12(f, g, "mul_fp254_12");
|
||||
let output_sparse = run_bn_mul_fp12(f, h, "mul_fp254_12_sparse");
|
||||
let output_square = run_bn_mul_fp12(f, f, "square_fp254_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();
|
||||
|
||||
assert_eq!(out_normal, exp_normal);
|
||||
assert_eq!(out_sparse, exp_sparse);
|
||||
assert_eq!(out_square, exp_square);
|
||||
assert_eq!(output_normal, f * g);
|
||||
assert_eq!(output_sparse, f * h);
|
||||
assert_eq!(output_square, f * f);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn run_bn_frob_fp6(f: Fp6<BN254>, n: usize) -> Vec<U256> {
|
||||
fn run_bn_frob_fp6(n: usize, f: Fp6<BN254>) -> Fp6<BN254> {
|
||||
let setup = InterpreterMemoryInitialization {
|
||||
label: format!("test_frob_fp254_6_{}", n),
|
||||
stack: f.on_stack(),
|
||||
stack: f.to_stack().to_vec(),
|
||||
segment: BnPairing,
|
||||
memory: vec![],
|
||||
};
|
||||
let interpreter = run_interpreter_with_memory(setup).unwrap();
|
||||
extract_stack(interpreter)
|
||||
let interpreter: Interpreter = run_interpreter_with_memory(setup).unwrap();
|
||||
let output: Vec<U256> = interpreter.stack().iter().rev().cloned().collect();
|
||||
Fp6::<BN254>::from_stack(&output)
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -118,34 +103,33 @@ fn test_bn_frob_fp6() -> Result<()> {
|
||||
let mut rng = rand::thread_rng();
|
||||
let f: Fp6<BN254> = rng.gen::<Fp6<BN254>>();
|
||||
for n in 1..4 {
|
||||
let output: Vec<U256> = run_bn_frob_fp6(f, n);
|
||||
let expected: Vec<U256> = f.frob(n).on_stack();
|
||||
assert_eq!(output, expected);
|
||||
let output = run_bn_frob_fp6(n, f);
|
||||
assert_eq!(output, f.frob(n));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn run_bn_frob_fp12(f: Fp12<BN254>, n: usize) -> Vec<U256> {
|
||||
fn run_bn_frob_fp12(f: Fp12<BN254>, n: usize) -> Fp12<BN254> {
|
||||
let ptr: usize = 100;
|
||||
let setup = InterpreterMemoryInitialization {
|
||||
label: format!("test_frob_fp254_12_{}", n),
|
||||
stack: vec![U256::from(ptr)],
|
||||
segment: BnPairing,
|
||||
memory: vec![(ptr, f.on_stack())],
|
||||
memory: vec![(ptr, f.to_stack().to_vec())],
|
||||
};
|
||||
let interpreter = run_interpreter_with_memory(setup).unwrap();
|
||||
interpreter.extract_kernel_memory(BnPairing, ptr..ptr + 12)
|
||||
let interpeter: Interpreter = run_interpreter_with_memory(setup).unwrap();
|
||||
let output: Vec<U256> = interpeter.extract_kernel_memory(BnPairing, ptr..ptr + 12);
|
||||
Fp12::<BN254>::from_stack(&output)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bn_frob_fp12() -> Result<()> {
|
||||
fn test_frob_fp12() -> Result<()> {
|
||||
let mut rng = rand::thread_rng();
|
||||
let f: Fp12<BN254> = rng.gen::<Fp12<BN254>>();
|
||||
|
||||
for n in [1, 2, 3, 6] {
|
||||
let output = run_bn_frob_fp12(f, n);
|
||||
let expected: Vec<U256> = f.frob(n).on_stack();
|
||||
assert_eq!(output, expected);
|
||||
assert_eq!(output, f.frob(n));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@ -161,13 +145,13 @@ fn test_bn_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().to_vec())],
|
||||
};
|
||||
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 output = Fp12::<BN254>::from_stack(&output);
|
||||
|
||||
assert_eq!(output, expected);
|
||||
assert_eq!(output, f.inv());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -188,12 +172,12 @@ fn test_bn_final_exponent() -> Result<()> {
|
||||
U256::from(0xdeadbeefu32),
|
||||
],
|
||||
segment: BnPairing,
|
||||
memory: vec![(ptr, f.on_stack())],
|
||||
memory: vec![(ptr, f.to_stack().to_vec())],
|
||||
};
|
||||
|
||||
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> = bn_final_exponent(f).on_stack();
|
||||
let expected: Vec<U256> = bn_final_exponent(f).to_stack();
|
||||
|
||||
assert_eq!(output, expected);
|
||||
|
||||
@ -209,8 +193,8 @@ fn test_bn_miller() -> Result<()> {
|
||||
let p: Curve<BN254> = rng.gen::<Curve<BN254>>();
|
||||
let q: Curve<Fp2<BN254>> = rng.gen::<Curve<Fp2<BN254>>>();
|
||||
|
||||
let mut input = p.on_stack();
|
||||
input.extend(q.on_stack());
|
||||
let mut input = p.to_stack();
|
||||
input.extend(q.to_stack());
|
||||
|
||||
let setup = InterpreterMemoryInitialization {
|
||||
label: "bn254_miller".to_string(),
|
||||
@ -220,7 +204,7 @@ fn test_bn_miller() -> Result<()> {
|
||||
};
|
||||
let interpreter = run_interpreter_with_memory(setup).unwrap();
|
||||
let output: Vec<U256> = interpreter.extract_kernel_memory(BnPairing, out..out + 12);
|
||||
let expected = bn_miller_loop(p, q).on_stack();
|
||||
let expected = bn_miller_loop(p, q).to_stack();
|
||||
|
||||
assert_eq!(output, expected);
|
||||
|
||||
@ -243,13 +227,13 @@ fn test_bn_pairing() -> Result<()> {
|
||||
|
||||
let p: Curve<BN254> = Curve::<BN254>::int(m);
|
||||
let q: Curve<Fp2<BN254>> = Curve::<Fp2<BN254>>::int(n);
|
||||
input.extend(p.on_stack());
|
||||
input.extend(q.on_stack());
|
||||
input.extend(p.to_stack());
|
||||
input.extend(q.to_stack());
|
||||
}
|
||||
let p: Curve<BN254> = Curve::<BN254>::int(acc);
|
||||
let q: Curve<Fp2<BN254>> = Curve::<Fp2<BN254>>::GENERATOR;
|
||||
input.extend(p.on_stack());
|
||||
input.extend(q.on_stack());
|
||||
input.extend(p.to_stack());
|
||||
input.extend(q.to_stack());
|
||||
|
||||
let setup = InterpreterMemoryInitialization {
|
||||
label: "bn254_pairing".to_string(),
|
||||
|
||||
@ -25,12 +25,21 @@ impl<T: FieldExt> Curve<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: FieldExt + Stack> Curve<T> {
|
||||
pub fn on_stack(self) -> Vec<U256> {
|
||||
let mut stack = self.x.on_stack();
|
||||
stack.extend(self.y.on_stack());
|
||||
impl<T: FieldExt + Stack> Stack for Curve<T> {
|
||||
const SIZE: usize = 2 * T::SIZE;
|
||||
|
||||
fn to_stack(&self) -> Vec<U256> {
|
||||
let mut stack = self.x.to_stack();
|
||||
stack.extend(self.y.to_stack());
|
||||
stack
|
||||
}
|
||||
|
||||
fn from_stack(stack: &[U256]) -> Self {
|
||||
Curve {
|
||||
x: T::from_stack(&stack[0..T::SIZE]),
|
||||
y: T::from_stack(&stack[T::SIZE..2 * T::SIZE]),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Curve<T>
|
||||
|
||||
@ -1223,43 +1223,79 @@ where
|
||||
}
|
||||
|
||||
pub trait Stack {
|
||||
fn on_stack(self) -> Vec<U256>;
|
||||
const SIZE: usize;
|
||||
|
||||
fn to_stack(&self) -> Vec<U256>;
|
||||
|
||||
fn from_stack(stack: &[U256]) -> Self;
|
||||
}
|
||||
|
||||
impl Stack for BN254 {
|
||||
fn on_stack(self) -> Vec<U256> {
|
||||
const SIZE: usize = 1;
|
||||
|
||||
fn to_stack(&self) -> Vec<U256> {
|
||||
vec![self.val]
|
||||
}
|
||||
|
||||
fn from_stack(stack: &[U256]) -> BN254 {
|
||||
BN254 { val: stack[0] }
|
||||
}
|
||||
}
|
||||
|
||||
impl Stack for BLS381 {
|
||||
fn on_stack(self) -> Vec<U256> {
|
||||
const SIZE: usize = 2;
|
||||
|
||||
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[0].0);
|
||||
val[4..].copy_from_slice(&stack[1].0);
|
||||
BLS381 { val: U512(val) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Stack for Fp2<T>
|
||||
where
|
||||
T: FieldExt + Stack,
|
||||
{
|
||||
fn on_stack(self) -> Vec<U256> {
|
||||
let mut stack = self.re.on_stack();
|
||||
stack.extend(self.im.on_stack());
|
||||
impl<T: FieldExt + Stack> Stack for Fp2<T> {
|
||||
const SIZE: usize = 2 * T::SIZE;
|
||||
|
||||
fn to_stack(&self) -> Vec<U256> {
|
||||
let mut stack = self.re.to_stack();
|
||||
stack.extend(self.im.to_stack());
|
||||
stack
|
||||
}
|
||||
|
||||
fn from_stack(stack: &[U256]) -> Fp2<T> {
|
||||
let field_size = T::SIZE;
|
||||
let re = T::from_stack(&stack[0..field_size]);
|
||||
let im = T::from_stack(&stack[field_size..2 * field_size]);
|
||||
Fp2 { re, im }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Stack for Fp6<T>
|
||||
where
|
||||
T: FieldExt,
|
||||
Fp2<T>: Adj + Stack,
|
||||
Fp2<T>: Adj,
|
||||
Fp2<T>: Stack,
|
||||
{
|
||||
fn on_stack(self) -> Vec<U256> {
|
||||
let mut stack = self.t0.on_stack();
|
||||
stack.extend(self.t1.on_stack());
|
||||
stack.extend(self.t2.on_stack());
|
||||
const SIZE: usize = 3 * Fp2::<T>::SIZE;
|
||||
|
||||
fn to_stack(&self) -> Vec<U256> {
|
||||
let mut stack = self.t0.to_stack();
|
||||
stack.extend(self.t1.to_stack());
|
||||
stack.extend(self.t2.to_stack());
|
||||
stack
|
||||
}
|
||||
|
||||
fn from_stack(stack: &[U256]) -> Self {
|
||||
let field_size = Fp2::<T>::SIZE;
|
||||
let t0 = Fp2::<T>::from_stack(&stack[0..field_size]);
|
||||
let t1 = Fp2::<T>::from_stack(&stack[field_size..2 * field_size]);
|
||||
let t2 = Fp2::<T>::from_stack(&stack[2 * field_size..3 * field_size]);
|
||||
Fp6 { t0, t1, t2 }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Stack for Fp12<T>
|
||||
@ -1268,9 +1304,18 @@ where
|
||||
Fp2<T>: Adj,
|
||||
Fp6<T>: Stack,
|
||||
{
|
||||
fn on_stack(self) -> Vec<U256> {
|
||||
let mut stack = self.z0.on_stack();
|
||||
stack.extend(self.z1.on_stack());
|
||||
const SIZE: usize = 2 * Fp6::<T>::SIZE;
|
||||
|
||||
fn to_stack(&self) -> Vec<U256> {
|
||||
let mut stack = self.z0.to_stack();
|
||||
stack.extend(self.z1.to_stack());
|
||||
stack
|
||||
}
|
||||
|
||||
fn from_stack(stack: &[U256]) -> Self {
|
||||
let field_size = Fp6::<T>::SIZE;
|
||||
let z0 = Fp6::<T>::from_stack(&stack[0..field_size]);
|
||||
let z1 = Fp6::<T>::from_stack(&stack[field_size..2 * field_size]);
|
||||
Fp12 { z0, z1 }
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user