Skip to content

Commit

Permalink
implement processed scalar mul only for the correct MODULAR_BITS and 1
Browse files Browse the repository at this point in the history
  • Loading branch information
tsunrise committed Mar 18, 2022
1 parent 9339611 commit 8636b0b
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 22 deletions.
17 changes: 17 additions & 0 deletions manta-crypto/src/ecc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,9 @@ pub trait ScalarMul<COM = ()> {
/// Elliptic Curve Pre-processed Scalar Multiplication Operation
pub trait PreprocessedScalarMul<COM, const N: usize>: ScalarMul<COM> + Sized {
/// Performs the scalar multiplication against a pre-computed table.
///
/// The pre-computed table is a list of power-of-two multiples of `scalar`, such that
/// `table[i] = scalar * 2^i`.
#[must_use]
fn preprocessed_scalar_mul(
table: &[Self; N],
Expand All @@ -145,6 +148,20 @@ pub trait PreprocessedScalarMul<COM, const N: usize>: ScalarMul<COM> + Sized {
) -> Self::Output;
}

impl<G, COM> PreprocessedScalarMul<COM, 1> for G
where
G: ScalarMul<COM>,
{
#[inline]
fn preprocessed_scalar_mul(
table: &[Self; 1],
scalar: &Self::Scalar,
compiler: &mut COM,
) -> Self::Output {
table[0].scalar_mul(scalar, compiler)
}
}

/// Elliptic Curve Group
pub trait Group<COM = ()>: PointAdd<COM> + PointDouble<COM> + ScalarMul<COM> {}

Expand Down
58 changes: 36 additions & 22 deletions manta-pay/src/crypto/ecc/arkworks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

use crate::crypto::constraint::arkworks::{self, empty, full, Boolean, Fp, FpVar, R1CS};
use alloc::vec::Vec;
use ark_bls12_381::Bls12_381;
use ark_ff::{BigInteger, Field, FpParameters, PrimeField};
use ark_r1cs_std::ToBitsGadget;
use ark_relations::ns;
Expand All @@ -35,6 +36,7 @@ use manta_util::codec;
use manta_util::serde::{Deserialize, Serialize, Serializer};

pub use ark_ec::{AffineCurve, ProjectiveCurve};
use ark_ed_on_bls12_381::EdwardsProjective;
pub use ark_r1cs_std::groups::CurveVar;

/// Constraint Field Type
Expand Down Expand Up @@ -406,31 +408,43 @@ where
}
}

impl<C, CV, const N: usize> ecc::PreprocessedScalarMul<Compiler<C>, N> for GroupVar<C, CV> where
C: ProjectiveCurve,
CV: CurveVar<C, ConstraintField<C>> {
/// Performs the scalar multiplication against a pre-computed table.
///
/// The pre-computed table is a list of power-of-two multiples of `scalar`, such that
/// `table[i] = scalar * 2^i`.
fn preprocessed_scalar_mul(table: &[Self; N], scalar: &Self::Scalar, compiler: &mut Compiler<C>) -> Self::Output {
// Computes the standard little-endian double-and-add algorithm
// (Algorithm 3.26, Guide to Elliptic Curve Cryptography)
// adapted from https://github.com/arkworks-rs/r1cs-std/blob/50ab8ee5ba8c09637044718eceac38e98e0ea67c/src/groups/mod.rs#L110-L139

let _ = compiler;
let mut result: CV = CV::zero();
let scalar_bits = scalar.0.to_bits_le().expect("Bit decomposition is not allowed to fail.");
debug_assert_eq!(scalar_bits.len(), N, "Scalar is expected to have N bits.");
for (bit, base) in scalar_bits.into_iter().zip(table.iter()){
// compute `self + 2^i * scalar`
let scalar_plus_base = result.clone() + base.0.clone();
result = bit.select(&scalar_plus_base, &result).expect("Conditional select is not allowed to fail. ");
macro_rules! impl_processed_scalar_mul {
($curve: ty, $N: expr) => {
impl<CV> ecc::PreprocessedScalarMul<Compiler<$curve>, $N> for GroupVar<$curve, CV>
where
CV: CurveVar<$curve, ConstraintField<EdwardsProjective>>,
{
fn preprocessed_scalar_mul(
table: &[Self; $N],
scalar: &Self::Scalar,
compiler: &mut Compiler<EdwardsProjective>,
) -> Self::Output {
// Computes the standard little-endian double-and-add algorithm
// (Algorithm 3.26, Guide to Elliptic Curve Cryptography)
// adapted from https://github.com/arkworks-rs/r1cs-std/blob/50ab8ee5ba8c09637044718eceac38e98e0ea67c/src/groups/mod.rs#L110-L139

let _ = compiler;
let mut result: CV = CV::zero();
let scalar_bits = scalar
.0
.to_bits_le()
.expect("Bit decomposition is not allowed to fail.");
debug_assert_eq!(scalar_bits.len(), $N, "Scalar is expected to have N bits.");
for (bit, base) in scalar_bits.into_iter().zip(table.iter()) {
// compute `self + 2^i * scalar`
let scalar_plus_base = result.clone() + base.0.clone();
result = bit
.select(&scalar_plus_base, &result)
.expect("Conditional select is not allowed to fail. ");
}
Self(result, PhantomData)
}
}
Self(result, PhantomData)
}
};
}

impl_processed_scalar_mul!(EdwardsProjective, 252);

impl<C, CV> Equal<Compiler<C>> for GroupVar<C, CV>
where
C: ProjectiveCurve,
Expand Down

0 comments on commit 8636b0b

Please sign in to comment.