Skip to content

Commit

Permalink
Update Legendre impl
Browse files Browse the repository at this point in the history
Complete Pluto Eris docs
  • Loading branch information
davidnevadoc committed Nov 29, 2023
1 parent 18e648c commit 9bfa6c4
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 38 deletions.
26 changes: 6 additions & 20 deletions src/pluto_eris/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const NEG_SIX_U_PLUS_2_NAF: [i8; 114] = [
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1,
];

/// Value of (57/(u + 3))^((p - 1)/2) where u^2 + 5 = 0 in Fp2
/// Value of (57/(u + 3))^((p - 1)/2) where u^2 + 5 = 0 in Fp2.
const XI_TO_P_MINUS_1_OVER_2: Fp2 = Fp2 {
c0: Fp::from_raw([
0x54cf5ad1c0926216,
Expand Down Expand Up @@ -212,19 +212,21 @@ impl Group for Gt {
}
}

/// Points of G2 in Jacobian coordinates.
/// These are points lie in the twisted curve E'(Fp2).
#[derive(Clone, Debug)]
pub struct G2Prepared {
pub(crate) coeffs: Vec<(Fp2, Fp2, Fp2)>,
pub(crate) infinity: bool,
}

impl G2Prepared {
/// Returns true if `self` is the infinity point
/// Returns true if `self` is the infinity point.
pub fn is_zero(&self) -> bool {
self.infinity
}

/// Prepares a G2 point in affine coordinates
/// Prepares a G2 point in affine coordinates.
pub fn from_affine(q: G2Affine) -> Self {
if bool::from(q.is_identity()) {
return G2Prepared {
Expand Down Expand Up @@ -661,13 +663,7 @@ impl MultiMillerLoop for Pluto {
}
}

// pub fn pairing(g1: &G1Affine, g2: &G2Affine) -> Gt {
// let g2 = G2Prepared::from_affine(*g2);
// let terms: &[(&G1Affine, &G2Prepared)] = &[(g1, &g2)];
// let u = multi_miller_loop(terms);
// u.final_exponentiation()
// }

/// Pluto pairing-friendly curve. See: https://github.com/daira/pluto-eris
#[derive(Clone, Debug)]
pub struct Pluto;

Expand All @@ -684,19 +680,9 @@ impl Engine for Pluto {
let terms: &[(&G1Affine, &G2Prepared)] = &[(p, &q)];
let u = Self::multi_miller_loop(terms);
u.final_exponentiation()
// pairing(p, q)
}
}

// impl MultiMillerLoop for Pluto {
// type G2Prepared = G2Prepared;
// type Result = Gt;

// fn multi_miller_loop(terms: &[(&Self::G1Affine, &Self::G2Prepared)]) -> Self::Result {
// multi_miller_loop(terms)
// }
// }

#[cfg(test)]
use rand::SeedableRng;
#[cfg(test)]
Expand Down
6 changes: 3 additions & 3 deletions src/pluto_eris/fields/fp.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use crate::arithmetic::{adc, mac, sbb};
use crate::ff::{FromUniformBytes, PrimeField, WithSmallOrderMulGroup};
use crate::{
field_arithmetic_7_limbs, field_bits_7_limbs, field_common_7_limbs, impl_from_u64_7_limbs,
prime_field_legendre,
extend_field_legendre, field_arithmetic_7_limbs, field_bits_7_limbs, field_common_7_limbs,
impl_from_u64_7_limbs,
};
use crate::{
impl_add_binop_specify_output, impl_binops_additive, impl_binops_additive_specify_output,
Expand Down Expand Up @@ -202,7 +202,7 @@ field_bits_7_limbs!(Fp, MODULUS);
#[cfg(not(target_pointer_width = "64"))]
field_bits_7_limbs!(Fp, MODULUS, MODULUS_LIMBS_32);

prime_field_legendre!(Fp);
extend_field_legendre!(Fp);

impl Fp {
pub const fn size() -> usize {
Expand Down
23 changes: 11 additions & 12 deletions src/pluto_eris/fields/fp2.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::fp::{Fp, MODULUS_STR};
use crate::ff::{Field, FromUniformBytes, PrimeField, WithSmallOrderMulGroup};
use crate::legendre::Legendre;
use crate::ff_ext::Legendre;
use core::convert::TryInto;
use core::ops::{Add, Mul, Neg, Sub};
use rand::RngCore;
Expand Down Expand Up @@ -315,23 +315,22 @@ impl Fp2 {
tmp
})
}
}

impl Legendre for Fp2 {
type BasePrimeField = Fp;
fn legendre_exp() -> &'static [u64] {
Self::BasePrimeField::legendre_exp()
}

/// Norm of Fp2 as extension field in u over Fp
fn norm(&self) -> Self::BasePrimeField {
fn norm(&self) -> Fp {
// norm = self * self.cojungate()
let t0 = self.c0.square();
let t1 = self.c1.square() * U_SQUARE;
t1 - t0
}
}

impl Legendre for Fp2 {
fn legendre(&self) -> i64 {
self.norm().legendre()
}
}

impl Field for Fp2 {
const ZERO: Self = Self::zero();
const ONE: Self = Self::one();
Expand Down Expand Up @@ -699,7 +698,7 @@ pub fn test_sqrt() {
const N_ITER: usize = 1000;
for _ in 0..N_ITER {
let a = Fp2::random(&mut rng);
if a.legendre() == -Fp::ONE {
if a.legendre() == -1 {
assert!(bool::from(a.sqrt().is_none()));
}
}
Expand All @@ -708,7 +707,7 @@ pub fn test_sqrt() {
let a = Fp2::random(&mut rng);
let mut b = a;
b.square_assign();
assert_eq!(b.legendre(), Fp::ONE);
assert_eq!(b.legendre(), 1);

let b = b.sqrt().unwrap();
let mut negb = b;
Expand All @@ -721,7 +720,7 @@ pub fn test_sqrt() {
for _ in 0..N_ITER {
let mut b = c;
b.square_assign();
assert_eq!(b.legendre(), Fp::ONE);
assert_eq!(b.legendre(), 1);

b = b.sqrt().unwrap();

Expand Down
6 changes: 3 additions & 3 deletions src/pluto_eris/fields/fq.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use crate::arithmetic::{adc, mac, sbb};
use crate::ff::{FromUniformBytes, PrimeField, WithSmallOrderMulGroup};
use crate::{
field_arithmetic_7_limbs, field_bits_7_limbs, field_common_7_limbs, impl_from_u64_7_limbs,
prime_field_legendre,
extend_field_legendre, field_arithmetic_7_limbs, field_bits_7_limbs, field_common_7_limbs,
impl_from_u64_7_limbs,
};
use crate::{
impl_add_binop_specify_output, impl_binops_additive, impl_binops_additive_specify_output,
Expand Down Expand Up @@ -192,7 +192,7 @@ field_bits_7_limbs!(Fq, MODULUS);
#[cfg(not(target_pointer_width = "64"))]
field_bits_7_limbs!(Fq, MODULUS, MODULUS_LIMBS_32);

prime_field_legendre!(Fq);
extend_field_legendre!(Fq);

impl Fq {
/// Return field element size in bytes.
Expand Down
10 changes: 10 additions & 0 deletions src/pluto_eris/fields/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,16 @@ macro_rules! field_common_7_limbs {
$r
}

// Returns the Jacobi symbol, where the numerator and denominator
// are the element and the characteristic of the field, respectively.
// The Jacobi symbol is applicable to odd moduli
// while the Legendre symbol is applicable to prime moduli.
// They are equivalent for prime moduli.
#[inline(always)]
pub fn jacobi(&self) -> i64 {
$crate::ff_ext::jacobi::jacobi::<8>(&self.0, &$modulus.0)
}

fn from_u512(limbs: [u64; 8]) -> $field {
// We reduce an arbitrary 512-bit number by decomposing it into two 256-bit digits
// with the higher bits multiplied by 2^256. Thus, we perform two reductions
Expand Down
7 changes: 7 additions & 0 deletions src/pluto_eris/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
//! # `Pluto\Eris half-pairing ccyle`
//!
//! Implementation of the Pluto / Eris half-pairing cycle of prime order elliptic curves.
//!
//! Supporting evidence: https://github.com/daira/pluto-eris
//! Field constant derivation: https://github.com/davidnevadoc/ec-constants/tree/main/pluto_eris
//! Pairing constants derivation: https://github.com/John-Gong-Math/pluto_eris/blob/main/pluto_pairing.ipynb
mod curve;
mod engine;
mod fields;
Expand Down

0 comments on commit 9bfa6c4

Please sign in to comment.