Skip to content

Commit

Permalink
initial visibility restriction (#22)
Browse files Browse the repository at this point in the history
* initial visibility restriction

* finalized visibility restriction

* fmt

* satisfy ci
  • Loading branch information
trbritt authored Aug 19, 2024
1 parent f1579d2 commit 57ed4c5
Show file tree
Hide file tree
Showing 16 changed files with 91 additions and 96 deletions.
8 changes: 5 additions & 3 deletions src/fields/extensions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ use std::ops::{Add, AddAssign, Neg, Sub, SubAssign};
// since the underlying Mul, Add, etc., are not, and const traits are in the works
// https://github.com/rust-lang/rust/issues/67792
#[derive(Copy, Clone, Debug)]
pub struct FieldExtension<const D: usize, const N: usize, F: FieldExtensionTrait<D, N>>(pub [F; N]);
pub struct FieldExtension<const D: usize, const N: usize, F: FieldExtensionTrait<D, N>>(
pub(crate) [F; N],
);

impl<const D: usize, const N: usize, F: FieldExtensionTrait<D, N>> From<u64>
for FieldExtension<D, N, F>
Expand All @@ -32,13 +34,13 @@ impl<const D: usize, const N: usize, F: FieldExtensionTrait<D, N>> FieldExtensio
/// This is a const constructor that takes a slice of field elements and returns a field extension
/// The usage of the generics means that it is possible to instantiate any representation of
/// an extension need.
pub const fn new(c: &[F; N]) -> Self {
pub(crate) const fn new(c: &[F; N]) -> Self {
Self(*c)
}
/// There is eventually a need to be able to perform multiplication across different field
/// extensions, and more or less this corresponds to a basic scaling, see
/// <https://eprint.iacr.org/2010/354.pdf>
pub fn scale(&self, factor: F) -> Self {
pub(crate) fn scale(&self, factor: F) -> Self {
let mut i = 0;
let mut retval = [F::zero(); N];
while i < N {
Expand Down
6 changes: 5 additions & 1 deletion src/fields/fp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ use num_traits::{Euclid, Inv, One, Pow, Zero};
use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Rem, Sub, SubAssign};
use subtle::CtOption;

pub const BN254_FP_MODULUS: Fp = Fp::new(U256::from_words([
pub(crate) const BN254_FP_MODULUS: Fp = Fp::new(U256::from_words([
0x3C208C16D87CFD47,
0x97816A916871CA8D,
0xB85045B68181585D,
Expand All @@ -59,6 +59,7 @@ pub const BN254_FP_MODULUS: Fp = Fp::new(U256::from_words([
/// used to generate the quotient field F(x)/f(x)), D, and (ii) the number of elements
/// required for a unique representation of an element in the extension, N. An extension can have
/// many different representations, so it is key to allow this flexibility.
///
pub trait FieldExtensionTrait<const D: usize, const N: usize>:
Sized
+ Copy
Expand Down Expand Up @@ -90,6 +91,9 @@ pub trait FieldExtensionTrait<const D: usize, const N: usize>:

fn curve_constant() -> Self;
}
/// Visibility settings in rust on macro exports make this seem as not use, even though its
/// public and is indeed used ...
#[allow(dead_code)]
pub trait FinitePrimeField<const DLIMBS: usize, UintType, const D: usize, const N: usize>:
FieldExtensionTrait<D, N> + Rem<Output = Self> + Euclid + Pow<U256> + From<u64>
where
Expand Down
23 changes: 6 additions & 17 deletions src/fields/fp12.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ const FP12_QUADRATIC_NON_RESIDUE: Fp12 = Fp12::new(&[
]),
]);

pub type Fp12 = FieldExtension<12, 2, Fp6>;
pub(crate) type Fp12 = FieldExtension<12, 2, Fp6>;

impl FieldExtensionTrait<12, 2> for Fp12 {
fn quadratic_non_residue() -> Self {
Expand Down Expand Up @@ -259,21 +259,10 @@ impl ConditionallySelectable for Fp12 {
}
/// Below are additional functions needed on Fp12 for the pairing operations
impl Fp12 {
pub fn unitary_inverse(&self) -> Self {
pub(crate) fn unitary_inverse(&self) -> Self {
Self::new(&[self.0[0], -self.0[1]])
}
pub fn pow(&self, arg: &[u64; 4]) -> Self {
let mut res = Self::one();
for e in arg.iter().rev() {
for i in (0..64).rev() {
res = res.square();
if ((*e >> i) & 1) == 1 {
res *= *self;
}
}
}
res
}

/// Due to the efficiency considerations of storing only the nonzero entries in the sparse
/// Fp12, there is a need to implement sparse multiplication on Fp12, which is what the
/// madness below is. It is an amalgamation of Algs 21-25 of <https://eprint.iacr.org/2010/354.pdf>
Expand All @@ -298,7 +287,7 @@ impl Fp12 {
/// The function below is called by `zcash`, `bn`, and `arkworks` as `mul_by_024`, referring to
/// the indices of the non-zero elements in the 6x Fp2 representation above for the
/// multiplication.
pub fn sparse_mul(&self, ell_0: Fp2, ell_vw: Fp2, ell_vv: Fp2) -> Fp12 {
pub(crate) fn sparse_mul(&self, ell_0: Fp2, ell_vw: Fp2, ell_vv: Fp2) -> Fp12 {
let z0 = self.0[0].0[0];
let z1 = self.0[0].0[1];
let z2 = self.0[0].0[2];
Expand Down Expand Up @@ -362,15 +351,15 @@ impl Fp12 {

Fp12::new(&[Fp6::new(&[z0, z1, z2]), Fp6::new(&[z3, z4, z5])])
}
pub fn frobenius(&self, exponent: usize) -> Self {
pub(crate) fn frobenius(&self, exponent: usize) -> Self {
Self::new(&[
self.0[0].frobenius(exponent),
self.0[1]
.frobenius(exponent)
.scale(FROBENIUS_COEFF_FP12_C1[exponent % 12]),
])
}
pub fn square(&self) -> Self {
pub(crate) fn square(&self) -> Self {
// For F_{p^{12}} = F_{p^6}(w)/(w^2-\gamma), and A=a_0 + a_1*w \in F_{p^{12}},
// we determine C=c_0+c_1*w = A^2\in F_{p^{12}}
// Alg 22 from <https://eprint.iacr.org/2010/354.pdf>
Expand Down
4 changes: 2 additions & 2 deletions src/fields/fp2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use std::ops::{Div, DivAssign, Mul, MulAssign};
use subtle::{Choice, ConstantTimeEq, CtOption};

const FP2_QUADRATIC_NON_RESIDUE: Fp2 = Fp2::new(&[Fp::NINE, Fp::ONE]);
pub const TWO_INV: Fp = Fp::new(U256::from_words([
pub(crate) const TWO_INV: Fp = Fp::new(U256::from_words([
11389680472494603940,
14681934109093717318,
15863968012492123182,
Expand Down Expand Up @@ -65,7 +65,7 @@ impl Fp2 {
res
}

pub fn residue_mul(&self) -> Self {
pub(crate) fn residue_mul(&self) -> Self {
self * &FP2_QUADRATIC_NON_RESIDUE
}
pub fn frobenius(&self, exponent: usize) -> Self {
Expand Down
14 changes: 5 additions & 9 deletions src/fields/fp6.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::fields::fp2::Fp2;
use crypto_bigint::{rand_core::CryptoRngCore, subtle::ConditionallySelectable, U256};
use num_traits::{Inv, One, Zero};
use std::ops::{Div, DivAssign, Mul, MulAssign};
use subtle::{Choice, CtOption};
use subtle::Choice;

// the following values are a bit difficult to compute. The reason
// is that they involve operations up to p^11, which occupy a U4096
Expand Down Expand Up @@ -171,29 +171,25 @@ const FP6_QUADRATIC_NON_RESIDUE: Fp6 = Fp6::new(&[
Fp2::new(&[Fp::ZERO, Fp::ZERO]),
]);

pub type Fp6 = FieldExtension<6, 3, Fp2>;
pub(crate) type Fp6 = FieldExtension<6, 3, Fp2>;

impl Fp6 {
pub fn residue_mul(&self) -> Self {
pub(crate) fn residue_mul(&self) -> Self {
Self([self.0[2].residue_mul(), self.0[0], self.0[1]])
}
pub fn frobenius(&self, exponent: usize) -> Self {
pub(crate) fn frobenius(&self, exponent: usize) -> Self {
Self::new(&[
self.0[0].frobenius(exponent),
self.0[1].frobenius(exponent) * FROBENIUS_COEFF_FP6_C1[exponent % 6],
self.0[2].frobenius(exponent) * FROBENIUS_COEFF_FP6_C2[exponent % 6],
])
}

pub fn sqrt(&self) -> CtOption<Self> {
unimplemented!()
}

// this is simply the same as the multiplication below
// however, there are some simple algebraic reductions
// you can do with squaring. this just implements that,
// but functionally it is the same as the `Mul` trait below
pub fn square(&self) -> Self {
pub(crate) fn square(&self) -> Self {
let t0 = self.0[0].square();
let cross = self.0[0] * self.0[1];
let t1 = cross + cross;
Expand Down
10 changes: 5 additions & 5 deletions src/fields/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
mod extensions;
pub mod fp;
pub mod fp12;
pub mod fp2;
pub mod fp6;
pub mod utils;
pub(crate) mod fp;
pub(crate) mod fp12;
pub(crate) mod fp2;
pub(crate) mod fp6;
pub(crate) mod utils;
4 changes: 2 additions & 2 deletions src/fields/utils.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
use crypto_bigint::{Encoding, U256, U512};

pub fn to_larger_uint<const N: usize, const M: usize>(smaller_bytes: &[u8; N]) -> [u8; M] {
pub(crate) fn to_larger_uint<const N: usize, const M: usize>(smaller_bytes: &[u8; N]) -> [u8; M] {
assert!(M > N, "Target size must be larger than source size");
let mut larger_bytes = [0u8; M];
larger_bytes[M - N..].copy_from_slice(smaller_bytes);
larger_bytes
}

// Specific conversion functions
pub fn u256_to_u512(u256: &U256) -> U512 {
pub(crate) fn u256_to_u512(u256: &U256) -> U512 {
U512::from_be_bytes(to_larger_uint::<32, 64>(&u256.to_be_bytes()))
}
4 changes: 2 additions & 2 deletions src/groups/g1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ use crypto_bigint::rand_core::CryptoRngCore;
use num_traits::Zero;
use subtle::{Choice, ConstantTimeEq};

pub type G1Affine = GroupAffine<1, 1, Fp>;
pub(crate) type G1Affine = GroupAffine<1, 1, Fp>;

pub type G1Projective = GroupProjective<1, 1, Fp>;
pub(crate) type G1Projective = GroupProjective<1, 1, Fp>;

impl GroupTrait<1, 1, Fp> for G1Affine {
fn generator() -> Self {
Expand Down
28 changes: 14 additions & 14 deletions src/groups/g2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
//! representations. The internal translation does not induce that much overhead really, but it
//! is something to keep in mind.
//!
//! All public facing methods here implement the subgroup check to ensure that the user cannot
//! All pub(crate) lic facing methods here implement the subgroup check to ensure that the user cannot
//! input a value in $E^\prime(F_{p^2})$ that is not in the r-torsion.
use crate::fields::fp::{FieldExtensionTrait, Fp, Fr};
Expand Down Expand Up @@ -56,7 +56,7 @@ const G2_Y: Fp2 = Fp2::new(&[
])),
]);
// the first constant of the endomorphism, $\xi^((p-1)/3)$, see below
pub const EPS_EXP0: Fp2 = Fp2::new(&[
pub(crate) const EPS_EXP0: Fp2 = Fp2::new(&[
Fp::new(U256::from_words([
11088870908804158781,
13226160682434769676,
Expand All @@ -71,7 +71,7 @@ pub const EPS_EXP0: Fp2 = Fp2::new(&[
])),
]);
// the second constant of the endomorphism, $\xi^((p-1)/2)$, see below
pub const EPS_EXP1: Fp2 = Fp2::new(&[
pub(crate) const EPS_EXP1: Fp2 = Fp2::new(&[
Fp::new(U256::from_words([
15876315988453495642,
15828711151707445656,
Expand All @@ -86,17 +86,10 @@ pub const EPS_EXP1: Fp2 = Fp2::new(&[
])),
]);

// the cofactor of $\mathbb{G}_2$
const C2: Fp = Fp::new(U256::from_words([
17887900258952609094,
8020209761171036667,
0,
0,
]));
// the parameter that generates this member of the BN family
pub const BLS_X: Fp = Fp::new(U256::from_words([4965661367192848881, 0, 0, 0]));
pub(crate) const BLS_X: Fp = Fp::new(U256::from_words([4965661367192848881, 0, 0, 0]));

pub type G2Affine = GroupAffine<2, 2, Fp2>;
pub(crate) type G2Affine = GroupAffine<2, 2, Fp2>;

pub type G2Projective = GroupProjective<2, 2, Fp2>;

Expand Down Expand Up @@ -193,6 +186,13 @@ impl GroupTrait<2, 2, Fp2> for G2Projective {
/// through the `new` constructor to ensure that the random value does indeed pass the curve
/// and subgroup checks
fn rand<R: CryptoRngCore>(rng: &mut R) -> Self {
// the cofactor of $\mathbb{G}_2$
const C2: Fp = Fp::new(U256::from_words([
17887900258952609094,
8020209761171036667,
0,
0,
]));
let rando = Fp::new(Fr::rand(rng).value());
let mut tmp = Self::generator() * rando;

Expand Down Expand Up @@ -232,7 +232,7 @@ impl G2Affine {
/// This method is used internally for rapid, low overhead, conversion of types when there
/// are formulae that don't have clean versions in projective coordinates. The 'unchecked'
/// refers to the fact that these points are not subjected to a subgroup verification, and
/// therefore this method is not exposed publicly.
/// therefore this method is not exposed pub(crate) licly.
///
/// DON'T USE THIS METHOD UNLESS YOU KNOW WHAT YOU'RE DOING
fn new_unchecked(v: [Fp2; 2]) -> Result<Self, GroupError> {
Expand All @@ -256,7 +256,7 @@ impl G2Affine {
}
}
impl G2Projective {
/// The public entrypoint to making a value in $\mathbb{G}_2$. This takes the (x,y,z) values
/// The pub(crate) lic entrypoint to making a value in $\mathbb{G}_2$. This takes the (x,y,z) values
/// from the user, and passes them through a subgroup and curve check to ensure validity.
/// Values returned from this function are guaranteed to be on the curve and in the r-torsion.
pub fn new(v: [Fp2; 3]) -> Result<Self, GroupError> {
Expand Down
23 changes: 12 additions & 11 deletions src/groups/group.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ pub trait GroupTrait<const D: usize, const N: usize, F: FieldExtensionTrait<D, N
/// It is an endomorphism of the algebraic closure of the base field, but NOT of the curve
/// Therefore, these points must bypass curve membership and torsion checks, and therefore
/// directly be instantiated as a struct
#[allow(dead_code)]
fn frobenius(&self, exponent: usize) -> Self;
}

Expand All @@ -68,9 +69,9 @@ pub struct GroupAffine<const D: usize, const N: usize, F: FieldExtensionTrait<D,
/// has no unique representation in this form. Generation of the point at infinity is accomplished
/// either by calling the `zero` method, or by applying binary operations to 'normal' points to
/// reach the point at infinity with arithmetic.
pub x: F,
pub y: F,
pub infinity: Choice,
pub(crate) x: F,
pub(crate) y: F,
pub(crate) infinity: Choice,
}
/// this is the beginning of Rust lifetime magic. The issue is that when we implement
/// the arithmetic, we need to explicitly state the lifetime of each operand
Expand Down Expand Up @@ -141,15 +142,15 @@ impl<const D: usize, const N: usize, F: FieldExtensionTrait<D, N>> PartialEq
}
}
impl<const D: usize, const N: usize, F: FieldExtensionTrait<D, N>> GroupAffine<D, N, F> {
pub fn zero() -> Self {
pub(crate) fn zero() -> Self {
Self {
x: F::zero(),
y: F::one(),
infinity: Choice::from(1u8),
}
}

pub fn is_zero(&self) -> bool {
pub(crate) fn is_zero(&self) -> bool {
bool::from(self.infinity)
}
}
Expand All @@ -165,24 +166,24 @@ pub struct GroupProjective<const D: usize, const N: usize, F: FieldExtensionTrai
/// projective coords, or (iii) have mixed representations. For security, due to the uniqueness of
/// the representation of the point at infinity, we therefore opt to have
/// all arithmetic done in projective coordinates.
pub x: F,
pub y: F,
pub z: F,
pub(crate) x: F,
pub(crate) y: F,
pub(crate) z: F,
}
impl<const D: usize, const N: usize, F: FieldExtensionTrait<D, N>> GroupProjective<D, N, F> {
/// This is the point at infinity! This object really is the additive identity of the group,
/// when the group law is addition, which it is here. It satisfies the properties that
/// $zero+a=a$ for some $a$ in the group, as well as $a+(-a)=zero$, which means that the
/// convention zero makes the most sense to me here.
pub fn zero() -> Self {
pub(crate) fn zero() -> Self {
Self {
x: F::zero(),
y: F::one(),
z: F::zero(),
}
}

pub fn is_zero(&self) -> bool {
pub(crate) fn is_zero(&self) -> bool {
self.z.is_zero()
}

Expand All @@ -192,7 +193,7 @@ impl<const D: usize, const N: usize, F: FieldExtensionTrait<D, N>> GroupProjecti
/// Complexity:
/// `6M`(ultiplications) + `2S`(quarings)
/// + `1m`(ultiplication by scalar) + `9A`(dditions)
pub fn double(&self) -> Self {
pub(crate) fn double(&self) -> Self {
let t0 = self.y * self.y;
let z3 = t0 + t0;
let z3 = z3 + z3;
Expand Down
6 changes: 3 additions & 3 deletions src/groups/gt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ const GT: Fp12 = Fp12::new(&[
]);

#[derive(Copy, Clone, Debug)]
pub struct Gt(pub Fp12);
pub(crate) struct Gt(pub(crate) Fp12);

impl<'a> Neg for &'a Gt {
type Output = Gt;
Expand Down Expand Up @@ -226,12 +226,12 @@ impl GroupTrait<12, 2, Fp12> for Gt {
}
impl Gt {
/// Returns the group identity, which is $1$.
pub fn identity() -> Gt {
pub(crate) fn identity() -> Gt {
Gt(Fp12::one())
}

/// Doubles this group element.
pub fn double(&self) -> Gt {
pub(crate) fn double(&self) -> Gt {
Gt(self.0.square())
}
}
Loading

0 comments on commit 57ed4c5

Please sign in to comment.