Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

arkworks-independent sqrts, point encoding/decoding #80

Merged
merged 13 commits into from
Jan 30, 2024
13 changes: 2 additions & 11 deletions src/elligator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ use crate::element::{Decaf377EdwardsConfig, EdwardsProjective};

use crate::{
constants::{ONE, TWO, ZETA},
Element, Fq, OnCurve, Sign, SqrtRatioZeta,
sign::Sign,
Element, Fq, OnCurve,
};

impl Element {
Expand Down Expand Up @@ -68,20 +69,10 @@ impl Element {
&R_1 + &R_2
}

#[deprecated(note = "please use `hash_to_curve` instead")]
pub fn map_to_group_uniform(r_1: &Fq, r_2: &Fq) -> Element {
Element::hash_to_curve(r_1, r_2)
}

/// Maps a field element to a decaf377 `Element` suitable for CDH challenges.
pub fn encode_to_curve(r: &Fq) -> Element {
Element::elligator_map(r)
}

#[deprecated(note = "please use `encode_to_curve` instead")]
pub fn map_to_group_cdh(r: &Fq) -> Element {
Element::encode_to_curve(r)
}
}

#[cfg(test)]
Expand Down
14 changes: 2 additions & 12 deletions src/encoding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ use ark_ec::twisted_edwards::TECurveConfig;
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize, Read, Write};

use crate::{
constants::TWO, element::Decaf377EdwardsConfig, EdwardsProjective, Element, EncodingError, Fq,
OnCurve, Sign, SqrtRatioZeta,
constants::TWO, element::Decaf377EdwardsConfig, sign::Sign, EdwardsProjective, Element,
EncodingError, Fq, OnCurve,
};

#[derive(Copy, Clone, Default, Eq, Ord, PartialOrd, PartialEq)]
Expand Down Expand Up @@ -87,11 +87,6 @@ impl Element {
Element { inner: -self.inner }
}

#[deprecated(note = "please use `vartime_compress_to_field` instead")]
pub fn compress_to_field(&self) -> Fq {
self.vartime_compress_to_field()
}

pub fn vartime_compress_to_field(&self) -> Fq {
// This isn't a constant, only because traits don't have const methods
// yet and subtraction is only implemented as part of the Sub trait.
Expand All @@ -118,11 +113,6 @@ impl Element {
s
}

#[deprecated(note = "please use `vartime_compress` instead")]
pub fn compress(&self) -> Encoding {
self.vartime_compress()
}

pub fn vartime_compress(&self) -> Encoding {
let s = self.vartime_compress_to_field();

Expand Down
10 changes: 8 additions & 2 deletions src/fields/fq/u32/wrapper.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use subtle::ConditionallySelectable;
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq};

use super::fiat;

Expand Down Expand Up @@ -210,11 +210,17 @@ impl Fq {
}

impl ConditionallySelectable for Fq {
fn conditional_select(a: &Self, b: &Self, choice: subtle::Choice) -> Self {
fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
let mut out = [0u32; 8];
for i in 0..8 {
out[i] = u32::conditional_select(&a.0 .0[i], &b.0 .0[i], choice);
}
Self(fiat::FqMontgomeryDomainFieldElement(out))
}
}

impl ConstantTimeEq for Fq {
fn ct_eq(&self, other: &Fq) -> Choice {
self.0 .0.ct_eq(&other.0 .0)
}
}
1 change: 1 addition & 0 deletions src/fields/fq/u64/arkworks_constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ pub const TRACE_MINUS_ONE_DIV_TWO_LIMBS: [u64; 4] = [
4779,
];

// c1
pub const TWO_ADICITY: u32 = 0x2f;

pub const QUADRATIC_NON_RESIDUE_TO_TRACE: Fq = Fq::from_montgomery_limbs([
Expand Down
8 changes: 7 additions & 1 deletion src/fields/fq/u64/wrapper.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use subtle::ConditionallySelectable;
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq};

use super::fiat;

Expand Down Expand Up @@ -198,3 +198,9 @@ impl ConditionallySelectable for Fq {
Self(fiat::FqMontgomeryDomainFieldElement(out))
}
}

impl ConstantTimeEq for Fq {
fn ct_eq(&self, other: &Fq) -> Choice {
self.0 .0.ct_eq(&other.0 .0)
}
}
20 changes: 8 additions & 12 deletions src/invsqrt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,6 @@ use once_cell::sync::Lazy;

use crate::constants::{G, M_MINUS_ONE_DIV_TWO, N, ONE, SQRT_W, ZETA_TO_ONE_MINUS_M_DIV_TWO};

pub trait SqrtRatioZeta: Sized {
/// Computes the square root of a ratio of field elements, returning:
///
/// - `(true, sqrt(num/den))` if `num` and `den` are both nonzero and `num/den` is square;
/// - `(true, 0)` if `num` is zero;
/// - `(false, 0)` if `den` is zero;
/// - `(false, sqrt(zeta*num/den))` if `num` and `den` are both nonzero and `num/den` is nonsquare;
fn sqrt_ratio_zeta(num: &Self, den: &Self) -> (bool, Self);
}

struct SquareRootTables {
pub s_lookup: HashMap<Fq, u64>,
pub nonsquare_lookup: [Fq; 2],
Expand Down Expand Up @@ -73,8 +63,14 @@ impl SquareRootTables {

static SQRT_LOOKUP_TABLES: Lazy<SquareRootTables> = Lazy::new(|| SquareRootTables::new());

impl SqrtRatioZeta for Fq {
fn sqrt_ratio_zeta(num: &Self, den: &Self) -> (bool, Self) {
impl Fq {
/// Computes the square root of a ratio of field elements, returning:
///
/// - `(true, sqrt(num/den))` if `num` and `den` are both nonzero and `num/den` is square;
/// - `(true, 0)` if `num` is zero;
/// - `(false, 0)` if `den` is zero;
/// - `(false, sqrt(zeta*num/den))` if `num` and `den` are both nonzero and `num/den` is nonsquare;
pub fn sqrt_ratio_zeta(num: &Self, den: &Self) -> (bool, Self) {
// This square root method is based on:
// * [Sarkar2020](https://eprint.iacr.org/2020/1407)
// * [Zcash Pasta](https://github.com/zcash/pasta_curves)
Expand Down
10 changes: 5 additions & 5 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@
pub mod smol_curve;
pub use fields::{fp::Fp, fq::Fq, fr::Fr};

mod sign;

mod on_curve;
use on_curve::OnCurve;

Check warning on line 14 in src/lib.rs

View workflow job for this annotation

GitHub Actions / build without alloc

unused import: `on_curve::OnCurve`

Check warning on line 14 in src/lib.rs

View workflow job for this annotation

GitHub Actions / no_std compatibility check

unused import: `on_curve::OnCurve`

Check warning on line 14 in src/lib.rs

View workflow job for this annotation

GitHub Actions / no_std compatibility check

unused import: `on_curve::OnCurve`

Check warning on line 14 in src/lib.rs

View workflow job for this annotation

GitHub Actions / no_std compatibility check

unused import: `on_curve::OnCurve`

cfg_if! {
if #[cfg(feature = "arkworks")] {
pub mod bls12_377;
Expand All @@ -18,11 +23,9 @@
mod error;
mod field_ext;
mod invsqrt;
mod on_curve;
mod ops;
pub mod rand;
pub mod serialize;
mod sign;

pub use constants::ZETA;
pub use element::{AffineElement, Element};
Expand All @@ -36,9 +39,6 @@

pub use bls12_377::Bls12_377;

pub use invsqrt::SqrtRatioZeta;
use on_curve::OnCurve;
use sign::Sign;

/// Return the conventional generator for `decaf377`.
pub fn basepoint() -> Element {
Expand Down
20 changes: 13 additions & 7 deletions src/on_curve.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
use ark_ec::{
models::{twisted_edwards::Projective, twisted_edwards::TECurveConfig},
Group,
};
use ark_ff::{BigInteger, Field, PrimeField, Zero};
use ark_serialize::CanonicalSerialize;
use cfg_if::cfg_if;

use crate::constants;
cfg_if! {
if #[cfg(feature = "arkworks")] {
use ark_ec::{
models::{twisted_edwards::Projective, twisted_edwards::TECurveConfig},
Group,
};
use ark_ff::{BigInteger, Field, PrimeField, Zero};
use ark_serialize::CanonicalSerialize;
use crate::constants;
}
}

pub trait OnCurve {
fn is_on_curve(&self) -> bool;
}

#[cfg(feature = "arkworks")]
impl<P: TECurveConfig> OnCurve for Projective<P> {
#[allow(non_snake_case)]
fn is_on_curve(&self) -> bool {
Expand Down
2 changes: 1 addition & 1 deletion src/r1cs/fqvar_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use ark_r1cs_std::select::CondSelectGadget;
use ark_r1cs_std::{R1CSVar, ToBitsGadget};
use ark_relations::r1cs::SynthesisError;

use crate::{constants::ZETA, r1cs::FqVar, Fq, SqrtRatioZeta};
use crate::{constants::ZETA, r1cs::FqVar, Fq};

pub trait FqVarExtension: Sized {
fn isqrt(&self) -> Result<(Boolean<Fq>, FqVar), SynthesisError>;
Expand Down
6 changes: 1 addition & 5 deletions src/sign.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,6 @@ pub trait Sign: core::ops::Neg<Output = Self> + Sized {

impl Sign for Fq {
fn is_nonnegative(&self) -> bool {
use ark_serialize::CanonicalSerialize;
let mut bytes = [0u8; 32];
self.serialize_compressed(&mut bytes[..])
.expect("serialization into array should be infallible");
bytes[0] & 1 == 0
(self.to_le_limbs()[0] & 1) == 0
}
}
39 changes: 39 additions & 0 deletions src/smol_curve/constants.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
use crate::Fq;

pub const ZETA: Fq = Fq::from_montgomery_limbs_64([
5947794125541564500,
11292571455564096885,
11814268415718120036,
155746270000486182,
]);

pub const ZETA_TO_TRACE: Fq = Fq::from_montgomery_limbs_64([

Check warning on line 10 in src/smol_curve/constants.rs

View workflow job for this annotation

GitHub Actions / Check

constant `ZETA_TO_TRACE` is never used

Check warning on line 10 in src/smol_curve/constants.rs

View workflow job for this annotation

GitHub Actions / build without alloc

constant `ZETA_TO_TRACE` is never used

Check warning on line 10 in src/smol_curve/constants.rs

View workflow job for this annotation

GitHub Actions / no_std compatibility check

constant `ZETA_TO_TRACE` is never used

Check warning on line 10 in src/smol_curve/constants.rs

View workflow job for this annotation

GitHub Actions / no_std compatibility check

constant `ZETA_TO_TRACE` is never used

Check warning on line 10 in src/smol_curve/constants.rs

View workflow job for this annotation

GitHub Actions / no_std compatibility check

constant `ZETA_TO_TRACE` is never used

Check warning on line 10 in src/smol_curve/constants.rs

View workflow job for this annotation

GitHub Actions / Test Suite (r1cs)

constant `ZETA_TO_TRACE` is never used

Check warning on line 10 in src/smol_curve/constants.rs

View workflow job for this annotation

GitHub Actions / Test Suite (r1cs,u32_backend)

constant `ZETA_TO_TRACE` is never used
6282505393754313363,
14378628227555923904,
9804873068900332207,
302335131180501866,
]);

/// COEFF_A = -1
pub const COEFF_A: Fq = Fq::from_montgomery_limbs_64([
10157024534604021774,
16668528035959406606,
5322190058819395602,
387181115924875961,
]);

/// COEFF_D = 3021
pub const COEFF_D: Fq = Fq::from_montgomery_limbs_64([
15008245758212136496,
17341409599856531410,
648869460136961410,
719771289660577536,
]);

/// -2 COEFF_D / COEFF_A = 6042
pub const COEFF_K: Fq = Fq::from_montgomery_limbs_64([
10844245690243005535,
9774967673803681700,
12776203677742963460,
94262208632981673,
]);
Loading
Loading