Skip to content

Commit

Permalink
adding mul fns to XXModelParameters
Browse files Browse the repository at this point in the history
  • Loading branch information
zhenfeizhang committed Mar 8, 2022
1 parent e5fa00f commit 84da5a7
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 45 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
- [\#364](https://github.com/arkworks-rs/algebra/pull/364) (`ark-ec`) Add `ChunkedPippenger` to variable-base MSM.
- [\#371](https://github.com/arkworks-rs/algebra/pull/371) (`ark-serialize`) Add serialization impls for arrays
- [\#386](https://github.com/arkworks-rs/algebra/pull/386) (`ark-ff-macros`, `ark-ff`) Add a macro to derive `MontConfig`.
- [\#396](https://github.com/arkworks-rs/algebra/pull/396) (`ark-ec`) Add a default `mul` function to `TE/SWModelParameter` trait definition.

### Improvements

Expand Down
18 changes: 4 additions & 14 deletions ec/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,18 +220,7 @@ pub trait ProjectiveCurve:
fn add_assign_mixed(&mut self, other: &Self::Affine);

/// Performs scalar multiplication of this element.
fn mul<S: AsRef<[u64]>>(mut self, other: S) -> Self {
let mut res = Self::zero();
for b in ark_ff::BitIteratorBE::without_leading_zeros(other) {
res.double_in_place();
if b {
res += self;
}
}

self = res;
self
}
fn mul<S: AsRef<[u64]>>(self, other: S) -> Self;
}

/// Affine representation of an elliptic curve point guaranteed to be
Expand Down Expand Up @@ -262,8 +251,8 @@ pub trait AffineCurve:
{
type Parameters: ModelParameters<ScalarField = Self::ScalarField, BaseField = Self::BaseField>;

/// The group defined by this curve has order `h * r` where `r` is a large prime.
/// `Self::ScalarField` is the prime field defined by `r`
/// The group defined by this curve has order `h * r` where `r` is a large
/// prime. `Self::ScalarField` is the prime field defined by `r`
type ScalarField: PrimeField + SquareRootField + Into<<Self::ScalarField as PrimeField>::BigInt>;

/// The finite field over which this curve is defined.
Expand Down Expand Up @@ -334,6 +323,7 @@ pub trait AffineCurve:
fn mul_by_cofactor_inv(&self) -> Self {
self.mul(Self::Parameters::COFACTOR_INV).into()
}

}

impl<C: ProjectiveCurve> crate::group::Group for C {
Expand Down
86 changes: 73 additions & 13 deletions ec/src/models/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::AffineCurve;
use crate::{AffineCurve, ProjectiveCurve};
use ark_ff::{fields::BitIteratorBE, Field, PrimeField, SquareRootField, Zero};

pub mod bls12;
Expand All @@ -12,9 +12,9 @@ pub mod twisted_edwards_extended;
/// Elliptic curves can be represented via different "models" with varying
/// efficiency properties.
/// `ModelParameters` bundles together the types that are common
/// to all models of the given curve, namely the `BaseField` over which the curve
/// is defined, and the `ScalarField` defined by the appropriate prime-order
/// subgroup of the curve.
/// to all models of the given curve, namely the `BaseField` over which the
/// curve is defined, and the `ScalarField` defined by the appropriate
/// prime-order subgroup of the curve.
pub trait ModelParameters: Send + Sync + Sized + 'static {
/// Base field that the curve is defined over.
type BaseField: Field + SquareRootField;
Expand All @@ -27,7 +27,8 @@ pub trait ModelParameters: Send + Sync + Sized + 'static {
}

/// Constants and convenience functions that collectively define the [Short Weierstrass model](https://www.hyperelliptic.org/EFD/g1p/auto-shortw.html)
/// of the curve. In this model, the curve equation is `y² = x³ + a * x + b`, for constants `a` and `b`.
/// of the curve. In this model, the curve equation is `y² = x³ + a * x + b`,
/// for constants `a` and `b`.
pub trait SWModelParameters: ModelParameters {
/// Coefficient `a` of the curve equation.
const COEFF_A: Self::BaseField;
Expand All @@ -51,7 +52,8 @@ pub trait SWModelParameters: ModelParameters {
/// Helper method for computing `elem + Self::COEFF_B`.
///
/// The default implementation should be overridden only if
/// the sum can be computed faster than standard field addition (eg: via doubling).
/// the sum can be computed faster than standard field addition (eg: via
/// doubling).
#[inline(always)]
fn add_b(elem: &Self::BaseField) -> Self::BaseField {
if !Self::COEFF_B.is_zero() {
Expand All @@ -64,21 +66,50 @@ pub trait SWModelParameters: ModelParameters {

/// Check if the provided curve point is in the prime-order subgroup.
///
/// The default implementation multiplies `item` by the order `r` of the prime-order
/// subgroup, and checks if the result is one.
/// The default implementation multiplies `item` by the order `r` of the
/// prime-order subgroup, and checks if the result is one.
/// Implementors can choose to override this default impl
/// if the given curve has faster methods
/// for performing this check (for example, via leveraging curve isomorphisms).
/// for performing this check (for example, via leveraging curve
/// isomorphisms).
fn is_in_correct_subgroup_assuming_on_curve(
item: &short_weierstrass_jacobian::GroupAffine<Self>,
) -> bool {
item.mul_bits(BitIteratorBE::new(Self::ScalarField::characteristic()))
.is_zero()
}

/// Default implementation of group multiplication for projective
/// coordinates
fn mul_projective(
base: &short_weierstrass_jacobian::GroupProjective<Self>,
scalar: &[u64],
) -> short_weierstrass_jacobian::GroupProjective<Self> {
let mut res = short_weierstrass_jacobian::GroupProjective::<Self>::zero();
for b in ark_ff::BitIteratorBE::without_leading_zeros(scalar) {
res.double_in_place();
if b {
res += base;
}
}

res
}

/// Default implementation of group multiplication for affine
/// coordinates
fn mul_affine(
base: &short_weierstrass_jacobian::GroupAffine<Self>,
scalar: &[u64],
) -> short_weierstrass_jacobian::GroupProjective<Self> {
Self::mul_projective(&base.into_projective(), scalar)
}

}

/// Constants and convenience functions that collectively define the [Twisted Edwards model](https://www.hyperelliptic.org/EFD/g1p/auto-twisted.html)
/// of the curve. In this model, the curve equation is `a * x² + y² = 1 + d * x² * y²`, for constants `a` and `d`.
/// of the curve. In this model, the curve equation is `a * x² + y² = 1 + d * x²
/// * y²`, for constants `a` and `d`.
pub trait TEModelParameters: ModelParameters {
/// Coefficient `a` of the curve equation.
const COEFF_A: Self::BaseField;
Expand All @@ -87,7 +118,8 @@ pub trait TEModelParameters: ModelParameters {
/// Coefficients of the base point of the curve
const AFFINE_GENERATOR_COEFFS: (Self::BaseField, Self::BaseField);

/// Model parameters for the Montgomery curve that is birationally equivalent to this curve.
/// Model parameters for the Montgomery curve that is birationally
/// equivalent to this curve.
type MontgomeryModelParameters: MontgomeryModelParameters<BaseField = Self::BaseField>;

/// Helper method for computing `elem * Self::COEFF_A`.
Expand All @@ -110,16 +142,44 @@ pub trait TEModelParameters: ModelParameters {
item.mul_bits(BitIteratorBE::new(Self::ScalarField::characteristic()))
.is_zero()
}

/// Default implementation of group multiplication for projective
/// coordinates
fn mul_projective(
base: &twisted_edwards_extended::GroupProjective<Self>,
scalar: &[u64],
) -> twisted_edwards_extended::GroupProjective<Self> {
let mut res = twisted_edwards_extended::GroupProjective::<Self>::zero();
for b in ark_ff::BitIteratorBE::without_leading_zeros(scalar) {
res.double_in_place();
if b {
res += base;
}
}

res
}

/// Default implementation of group multiplication for affine
/// coordinates
fn mul_affine(
base: &twisted_edwards_extended::GroupAffine<Self>,
scalar: &[u64],
) -> twisted_edwards_extended::GroupProjective<Self> {
Self::mul_projective(&base.into_projective(), scalar)
}
}

/// Constants and convenience functions that collectively define the [Montgomery model](https://www.hyperelliptic.org/EFD/g1p/auto-montgom.html)
/// of the curve. In this model, the curve equation is `b * y² = x³ + a * x² + x`, for constants `a` and `b`.
/// of the curve. In this model, the curve equation is `b * y² = x³ + a * x² +
/// x`, for constants `a` and `b`.
pub trait MontgomeryModelParameters: ModelParameters {
/// Coefficient `a` of the curve equation.
const COEFF_A: Self::BaseField;
/// Coefficient `b` of the curve equation.
const COEFF_B: Self::BaseField;

/// Model parameters for the Twisted Edwards curve that is birationally equivalent to this curve.
/// Model parameters for the Twisted Edwards curve that is birationally
/// equivalent to this curve.
type TEModelParameters: TEModelParameters<BaseField = Self::BaseField>;
}
5 changes: 5 additions & 0 deletions ec/src/models/short_weierstrass_jacobian.rs
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,11 @@ impl<P: Parameters> ProjectiveCurve for GroupProjective<P> {
self.z -= &hh;
}
}

#[inline]
fn mul<S: AsRef<[u64]>>(self, other: S) -> Self{
P::mul_projective(&self, other.as_ref())
}
}

impl<P: Parameters> Neg for GroupProjective<P> {
Expand Down
50 changes: 32 additions & 18 deletions ec/src/models/twisted_edwards_extended.rs
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,11 @@ impl<P: Parameters> ProjectiveCurve for GroupProjective<P> {
// Z3 = F*G
self.z = f * &g;
}

#[inline]
fn mul<S: AsRef<[u64]>>(self, other: S) -> Self{
P::mul_projective(&self, other.as_ref())
}
}

impl<P: Parameters> Neg for GroupProjective<P> {
Expand Down Expand Up @@ -831,8 +836,9 @@ impl<P: Parameters> GroupAffine<P> {
/// If and only if `greatest` is set will the lexicographically
/// largest y-coordinate be selected.
///
/// This method is implemented for backwards compatibility with the old serialization format
/// and will be deprecated and then removed in a future version.
/// This method is implemented for backwards compatibility with the old
/// serialization format and will be deprecated and then removed in a
/// future version.
#[allow(dead_code)]
pub fn get_point_from_x_old(x: P::BaseField, greatest: bool) -> Option<Self> {
let x2 = x.square();
Expand All @@ -846,8 +852,9 @@ impl<P: Parameters> GroupAffine<P> {
Self::new(x, y)
})
}
/// This method is implemented for backwards compatibility with the old serialization format
/// and will be deprecated and then removed in a future version.
/// This method is implemented for backwards compatibility with the old
/// serialization format and will be deprecated and then removed in a
/// future version.
pub fn serialize_old<W: Write>(&self, writer: W) -> Result<(), SerializationError> {
if self.is_zero() {
let flags = EdwardsFlags::default();
Expand All @@ -863,8 +870,9 @@ impl<P: Parameters> GroupAffine<P> {

#[allow(unused_qualifications)]
#[inline]
/// This method is implemented for backwards compatibility with the old serialization format
/// and will be deprecated and then removed in a future version.
/// This method is implemented for backwards compatibility with the old
/// serialization format and will be deprecated and then removed in a
/// future version.
pub fn serialize_uncompressed_old<W: Write>(
&self,
mut writer: W,
Expand All @@ -875,8 +883,9 @@ impl<P: Parameters> GroupAffine<P> {
}

#[allow(unused_qualifications)]
/// This method is implemented for backwards compatibility with the old serialization format
/// and will be deprecated and then removed in a future version.
/// This method is implemented for backwards compatibility with the old
/// serialization format and will be deprecated and then removed in a
/// future version.
pub fn deserialize_uncompressed_old<R: Read>(reader: R) -> Result<Self, SerializationError> {
let p = Self::deserialize_unchecked(reader)?;

Expand All @@ -885,8 +894,9 @@ impl<P: Parameters> GroupAffine<P> {
}
Ok(p)
}
/// This method is implemented for backwards compatibility with the old serialization format
/// and will be deprecated and then removed in a future version.
/// This method is implemented for backwards compatibility with the old
/// serialization format and will be deprecated and then removed in a
/// future version.
pub fn deserialize_old<R: Read>(mut reader: R) -> Result<Self, SerializationError> {
let (x, flags): (P::BaseField, EdwardsFlags) =
CanonicalDeserializeWithFlags::deserialize_with_flags(&mut reader)?;
Expand All @@ -903,17 +913,19 @@ impl<P: Parameters> GroupAffine<P> {
}
}
impl<P: Parameters> GroupProjective<P> {
/// This method is implemented for backwards compatibility with the old serialization format
/// and will be deprecated and then removed in a future version.
/// This method is implemented for backwards compatibility with the old
/// serialization format and will be deprecated and then removed in a
/// future version.
pub fn serialize_old<W: Write>(&self, writer: W) -> Result<(), SerializationError> {
let aff = GroupAffine::<P>::from(self.clone());
aff.serialize_old(writer)
}

#[allow(unused_qualifications)]
#[inline]
/// This method is implemented for backwards compatibility with the old serialization format
/// and will be deprecated and then removed in a future version.
/// This method is implemented for backwards compatibility with the old
/// serialization format and will be deprecated and then removed in a
/// future version.
pub fn serialize_uncompressed_old<W: Write>(
&self,
writer: W,
Expand All @@ -923,14 +935,16 @@ impl<P: Parameters> GroupProjective<P> {
}

#[allow(unused_qualifications)]
/// This method is implemented for backwards compatibility with the old serialization format
/// and will be deprecated and then removed in a future version.
/// This method is implemented for backwards compatibility with the old
/// serialization format and will be deprecated and then removed in a
/// future version.
pub fn deserialize_uncompressed_old<R: Read>(reader: R) -> Result<Self, SerializationError> {
let aff = GroupAffine::<P>::deserialize_uncompressed(reader)?;
Ok(aff.into())
}
/// This method is implemented for backwards compatibility with the old serialization format
/// and will be deprecated and then removed in a future version.
/// This method is implemented for backwards compatibility with the old
/// serialization format and will be deprecated and then removed in a
/// future version.
pub fn deserialize_old<R: Read>(reader: R) -> Result<Self, SerializationError> {
let aff = GroupAffine::<P>::deserialize_old(reader)?;
Ok(aff.into())
Expand Down

0 comments on commit 84da5a7

Please sign in to comment.