mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-03 14:23:07 +00:00
abstraction
This commit is contained in:
parent
537debdc2e
commit
6599c90a6e
@ -5,32 +5,32 @@ use rand::Rng;
|
||||
|
||||
use crate::extension_tower::{FieldExt, Fp12, Fp2, Fp6, BN254};
|
||||
|
||||
// The curve consists of pairs (x, y): (BN254, BN254) | y^2 = x^3 + 2
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub struct Curve {
|
||||
pub x: BN254,
|
||||
pub y: BN254,
|
||||
pub struct Curve<T>
|
||||
where
|
||||
T: FieldExt,
|
||||
{
|
||||
pub x: T,
|
||||
pub y: T,
|
||||
}
|
||||
|
||||
// The curve is cyclic with generator (1, 2)
|
||||
pub const CURVE_GENERATOR: Curve = {
|
||||
Curve {
|
||||
x: BN254 { val: U256::one() },
|
||||
y: BN254 {
|
||||
val: U256([2, 0, 0, 0]),
|
||||
},
|
||||
impl<T: FieldExt> Curve<T> {
|
||||
pub fn unit() -> Self {
|
||||
Curve {
|
||||
x: T::UNIT,
|
||||
y: T::UNIT,
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Standard addition formula for elliptic curves, restricted to the cases
|
||||
/// where neither inputs nor output would ever be the identity O. source:
|
||||
/// https://en.wikipedia.org/wiki/Elliptic_curve#Algebraic_interpretation
|
||||
impl Add for Curve {
|
||||
impl<T: FieldExt> Add for Curve<T> {
|
||||
type Output = Self;
|
||||
|
||||
fn add(self, other: Self) -> Self {
|
||||
let m = if self == other {
|
||||
BN254::new(3) * self.x * self.x / (BN254::new(2) * self.y)
|
||||
T::new(3) * self.x * self.x / (T::new(2) * self.y)
|
||||
} else {
|
||||
(other.y - self.y) / (other.x - self.x)
|
||||
};
|
||||
@ -42,8 +42,8 @@ impl Add for Curve {
|
||||
}
|
||||
}
|
||||
|
||||
impl Neg for Curve {
|
||||
type Output = Curve;
|
||||
impl<T: FieldExt> Neg for Curve<T> {
|
||||
type Output = Curve<T>;
|
||||
|
||||
fn neg(self) -> Self {
|
||||
Curve {
|
||||
@ -53,37 +53,48 @@ impl Neg for Curve {
|
||||
}
|
||||
}
|
||||
|
||||
impl Mul<i32> for Curve {
|
||||
type Output = Curve;
|
||||
|
||||
fn mul(self, other: i32) -> Self {
|
||||
let mut result: Curve = self;
|
||||
if other.is_negative() {
|
||||
result = -result;
|
||||
}
|
||||
let mut multiplier = result;
|
||||
let mut exp = other.abs() as usize;
|
||||
while exp > 0 {
|
||||
if exp % 2 == 1 {
|
||||
result = result + multiplier;
|
||||
}
|
||||
exp >>= 1;
|
||||
multiplier = multiplier + multiplier;
|
||||
}
|
||||
result
|
||||
}
|
||||
pub trait CurveGroup {
|
||||
const GENERATOR: Self;
|
||||
}
|
||||
|
||||
// The twisted curve consists of pairs (x, y): (Fp2, Fp2) | y^2 = x^3 + 3/(9 + i)
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub struct TwistedCurve {
|
||||
pub x: Fp2<BN254>,
|
||||
pub y: Fp2<BN254>,
|
||||
/// The BN curve consists of pairs
|
||||
/// (x, y): (BN254, BN254) | y^2 = x^3 + 2
|
||||
// with generator given by (1, 2)
|
||||
impl CurveGroup for Curve<BN254> {
|
||||
const GENERATOR: Curve<BN254> = Curve {
|
||||
x: BN254 { val: U256::one() },
|
||||
y: BN254 {
|
||||
val: U256([2, 0, 0, 0]),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// The twisted curve is cyclic with generator (x, y) as follows
|
||||
pub const TWISTED_GENERATOR: TwistedCurve = {
|
||||
TwistedCurve {
|
||||
// impl<T: FieldExt: Add> Mul<i32> for Curve {
|
||||
// type Output = Curve;
|
||||
|
||||
// fn mul(self, other: i32) -> Self {
|
||||
// let mut result: Curve = self;
|
||||
// if other.is_negative() {
|
||||
// result = -result;
|
||||
// }
|
||||
// let mut multiplier = result;
|
||||
// let mut exp = other.unsigned_abs() as usize;
|
||||
// while exp > 0 {
|
||||
// if exp % 2 == 1 {
|
||||
// result = result + multiplier;
|
||||
// }
|
||||
// exp >>= 1;
|
||||
// multiplier = multiplier + multiplier;
|
||||
// }
|
||||
// result
|
||||
// }
|
||||
// }
|
||||
|
||||
/// The twisted curve consists of pairs
|
||||
/// (x, y): (Fp2<BN254>, Fp2<BN254>) | y^2 = x^3 + 3/(9 + i)
|
||||
/// with generator given as follows
|
||||
impl CurveGroup for Curve<Fp2<BN254>> {
|
||||
const GENERATOR: Curve<Fp2<BN254>> = Curve {
|
||||
x: Fp2 {
|
||||
re: BN254 {
|
||||
val: U256([
|
||||
@ -120,11 +131,11 @@ pub const TWISTED_GENERATOR: TwistedCurve = {
|
||||
]),
|
||||
},
|
||||
},
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
// The tate pairing takes a point each from the curve and its twist and outputs an Fp12 element
|
||||
pub fn tate(p: Curve, q: TwistedCurve) -> Fp12<BN254> {
|
||||
pub fn tate(p: Curve<BN254>, q: Curve<Fp2<BN254>>) -> Fp12<BN254> {
|
||||
let miller_output = miller_loop(p, q);
|
||||
final_exponent(miller_output)
|
||||
}
|
||||
@ -132,7 +143,7 @@ pub fn tate(p: Curve, q: TwistedCurve) -> Fp12<BN254> {
|
||||
/// Standard code for miller loop, can be found on page 99 at this url:
|
||||
/// https://static1.squarespace.com/static/5fdbb09f31d71c1227082339/t/5ff394720493bd28278889c6/1609798774687/PairingsForBeginners.pdf#page=107
|
||||
/// where EXP is a hardcoding of the array of Booleans that the loop traverses
|
||||
pub fn miller_loop(p: Curve, q: TwistedCurve) -> Fp12<BN254> {
|
||||
pub fn miller_loop(p: Curve<BN254>, q: Curve<Fp2<BN254>>) -> Fp12<BN254> {
|
||||
let mut r = p;
|
||||
let mut acc: Fp12<BN254> = Fp12::<BN254>::UNIT;
|
||||
let mut line: Fp12<BN254>;
|
||||
@ -151,14 +162,14 @@ pub fn miller_loop(p: Curve, q: TwistedCurve) -> Fp12<BN254> {
|
||||
}
|
||||
|
||||
/// The sloped line function for doubling a point
|
||||
pub fn tangent(p: Curve, q: TwistedCurve) -> Fp12<BN254> {
|
||||
pub fn tangent(p: Curve<BN254>, q: Curve<Fp2<BN254>>) -> Fp12<BN254> {
|
||||
let cx = -BN254::new(3) * p.x * p.x;
|
||||
let cy = BN254::new(2) * p.y;
|
||||
sparse_embed(p.y * p.y - BN254::new(9), q.x * cx, q.y * cy)
|
||||
}
|
||||
|
||||
/// The sloped line function for adding two points
|
||||
pub fn cord(p1: Curve, p2: Curve, q: TwistedCurve) -> Fp12<BN254> {
|
||||
pub fn cord(p1: Curve<BN254>, p2: Curve<BN254>, q: Curve<Fp2<BN254>>) -> Fp12<BN254> {
|
||||
let cx = p2.y - p1.y;
|
||||
let cy = p1.x - p2.x;
|
||||
sparse_embed(p1.y * p2.x - p2.y * p1.x, q.x * cx, q.y * cy)
|
||||
|
||||
@ -4,14 +4,12 @@ use anyhow::Result;
|
||||
use ethereum_types::U256;
|
||||
use rand::Rng;
|
||||
|
||||
use crate::bn254_pairing::{
|
||||
final_exponent, gen_fp12_sparse, miller_loop, CURVE_GENERATOR, TWISTED_GENERATOR,
|
||||
};
|
||||
use crate::bn254_pairing::{final_exponent, gen_fp12_sparse, miller_loop, Curve, CurveGroup};
|
||||
use crate::cpu::kernel::interpreter::{
|
||||
run_interpreter_with_memory, Interpreter, InterpreterMemoryInitialization,
|
||||
};
|
||||
use crate::cpu::kernel::tests::u256ify;
|
||||
use crate::extension_tower::{FieldExt, Fp12, Fp6, Stack, BN254};
|
||||
use crate::extension_tower::{FieldExt, Fp12, Fp2, Fp6, Stack, BN254};
|
||||
use crate::memory::segments::Segment::BnPairing;
|
||||
|
||||
fn extract_stack(interpreter: Interpreter<'static>) -> Vec<U256> {
|
||||
@ -204,8 +202,8 @@ fn test_bn_final_exponent() -> Result<()> {
|
||||
}
|
||||
|
||||
fn pairing_input() -> Vec<U256> {
|
||||
let curve_gen: [U256; 2] = unsafe { transmute(CURVE_GENERATOR) };
|
||||
let twisted_gen: [U256; 4] = unsafe { transmute(TWISTED_GENERATOR) };
|
||||
let curve_gen: [U256; 2] = unsafe { transmute(Curve::<BN254>::GENERATOR) };
|
||||
let twisted_gen: [U256; 4] = unsafe { transmute(Curve::<Fp2<BN254>>::GENERATOR) };
|
||||
let mut input = curve_gen.to_vec();
|
||||
input.extend_from_slice(&twisted_gen);
|
||||
input
|
||||
@ -225,7 +223,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 = miller_loop(CURVE_GENERATOR, TWISTED_GENERATOR).on_stack();
|
||||
let expected = miller_loop(Curve::<BN254>::GENERATOR, Curve::<Fp2<BN254>>::GENERATOR).on_stack();
|
||||
|
||||
assert_eq!(output, expected);
|
||||
|
||||
|
||||
@ -7,6 +7,7 @@ use rand::Rng;
|
||||
|
||||
pub trait FieldExt:
|
||||
Copy
|
||||
+ std::cmp::PartialEq
|
||||
+ std::ops::Add<Output = Self>
|
||||
+ std::ops::Neg<Output = Self>
|
||||
+ std::ops::Sub<Output = Self>
|
||||
@ -15,6 +16,7 @@ pub trait FieldExt:
|
||||
{
|
||||
const ZERO: Self;
|
||||
const UNIT: Self;
|
||||
fn new(val: usize) -> Self;
|
||||
fn inv(self) -> Self;
|
||||
}
|
||||
|
||||
@ -30,14 +32,6 @@ pub struct BN254 {
|
||||
pub val: U256,
|
||||
}
|
||||
|
||||
impl BN254 {
|
||||
pub fn new(val: usize) -> BN254 {
|
||||
BN254 {
|
||||
val: U256::from(val),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Distribution<BN254> for Standard {
|
||||
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> BN254 {
|
||||
let xs = rng.gen::<[u64; 4]>();
|
||||
@ -91,6 +85,11 @@ impl Mul for BN254 {
|
||||
impl FieldExt for BN254 {
|
||||
const ZERO: Self = BN254 { val: U256::zero() };
|
||||
const UNIT: Self = BN254 { val: U256::one() };
|
||||
fn new(val: usize) -> BN254 {
|
||||
BN254 {
|
||||
val: U256::from(val),
|
||||
}
|
||||
}
|
||||
fn inv(self) -> BN254 {
|
||||
let exp = BN_BASE - 2;
|
||||
let mut current = self;
|
||||
@ -131,12 +130,6 @@ pub struct BLS381 {
|
||||
}
|
||||
|
||||
impl BLS381 {
|
||||
pub fn new(val: usize) -> BLS381 {
|
||||
BLS381 {
|
||||
val: U512::from(val),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn lo(self) -> U256 {
|
||||
U256(self.val.0[..4].try_into().unwrap())
|
||||
}
|
||||
@ -234,6 +227,11 @@ impl Mul for BLS381 {
|
||||
impl FieldExt for BLS381 {
|
||||
const ZERO: Self = BLS381 { val: U512::zero() };
|
||||
const UNIT: Self = BLS381 { val: U512::one() };
|
||||
fn new(val: usize) -> BLS381 {
|
||||
BLS381 {
|
||||
val: U512::from(val),
|
||||
}
|
||||
}
|
||||
fn inv(self) -> BLS381 {
|
||||
let exp = BLS_BASE - 2;
|
||||
let mut current = self;
|
||||
@ -365,6 +363,14 @@ impl<T: FieldExt> FieldExt for Fp2<T> {
|
||||
re: T::UNIT,
|
||||
im: T::ZERO,
|
||||
};
|
||||
|
||||
fn new(val: usize) -> Fp2<T> {
|
||||
Fp2 {
|
||||
re: T::new(val),
|
||||
im: T::ZERO,
|
||||
}
|
||||
}
|
||||
|
||||
/// The inverse of z is given by z'/||z||^2 since ||z||^2 = zz'
|
||||
fn inv(self) -> Fp2<T> {
|
||||
let norm_sq = self.norm_sq();
|
||||
@ -974,6 +980,14 @@ where
|
||||
t1: Fp2::<T>::ZERO,
|
||||
t2: Fp2::<T>::ZERO,
|
||||
};
|
||||
|
||||
fn new(val: usize) -> Fp6<T> {
|
||||
Fp6 {
|
||||
t0: Fp2::<T>::new(val),
|
||||
t1: Fp2::<T>::ZERO,
|
||||
t2: Fp2::<T>::ZERO,
|
||||
}
|
||||
}
|
||||
|
||||
/// Let x_n = x^(p^n) and note that
|
||||
/// x_0 = x^(p^0) = x^1 = x
|
||||
@ -1040,6 +1054,13 @@ where
|
||||
z1: Fp6::<T>::ZERO,
|
||||
};
|
||||
|
||||
fn new(val: usize) -> Fp12<T> {
|
||||
Fp12 {
|
||||
z0: Fp6::<T>::new(val),
|
||||
z1: Fp6::<T>::ZERO,
|
||||
}
|
||||
}
|
||||
|
||||
/// By Galois Theory, given x: Fp12, the product
|
||||
/// phi = Prod_{i=0}^11 x_i
|
||||
/// lands in BN254, and hence the inverse of x is given by
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user