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

Add missing methods as need for integrating the latest version of this crate #91

Merged
merged 5 commits into from
Apr 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ authors = [
"redshiftzero <jen@penumbralabs.xyz>",
]
description = "A prime-order group designed for use in SNARKs over BLS12-377"
edition = "2018"
edition = "2021"
license = "MIT OR Apache-2.0"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand All @@ -16,6 +16,7 @@ license = "MIT OR Apache-2.0"
cfg-if = "1.0"
hex = { version = "=0.4.3", default-features = false }
subtle = { version = "2.5", default-features = false }
rand_core = { version = "0.6", default-features = false }
zeroize = { version = "1.7", default-features = false }
# no-std
num-bigint = { version = "0.4.4", optional = true, default-features = false }
Expand All @@ -38,14 +39,15 @@ once_cell = { version = "1.8", optional = true, default-features = false }
# compile
[features]
default = ["arkworks"]
alloc = ["once_cell/alloc", "zeroize/alloc"]
alloc = ["once_cell/alloc", "zeroize/alloc", "rand_core/alloc"]
std = [
"alloc",
"zeroize/std",
"once_cell/std",
"num-bigint/std",
"hex/std",
"subtle/std",
"rand_core/std"
]
parallel = [
"ark-ff/parallel",
Expand Down
35 changes: 19 additions & 16 deletions src/ark_curve/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,22 +58,25 @@ pub static G: Lazy<Fq> = Lazy::new(|| ZETA.pow(*M));
pub static SQRT_W: u32 = 8;

// Canonical basepoint projective coordinates
pub static B_X: Lazy<Fq> = Lazy::new(|| {
from_ark_fq(ark_ff::MontFp!(
"4959445789346820725352484487855828915252512307947624787834978378872129235627"
))
});
pub static B_Y: Lazy<Fq> = Lazy::new(|| {
from_ark_fq(ark_ff::MontFp!(
"6060471950081851567114691557659790004756535011754163002297540472747064943288"
))
});
pub static B_T: Lazy<Fq> = Lazy::new(|| {
from_ark_fq(ark_ff::MontFp!(
"7709528722369014828560854854815397945854484030754980890329689855465844419067"
))
});
pub static B_Z: Lazy<Fq> = Lazy::new(|| from_ark_fq(ark_ff::MontFp!("1")));
pub const B_X: Fq = Fq::from_montgomery_limbs([
5825153684096051627,
16988948339439369204,
186539475124256708,
1230075515893193738,
]);
pub const B_Y: Fq = Fq::from_montgomery_limbs([
9786171649960077610,
13527783345193426398,
10983305067350511165,
1251302644532346138,
]);
pub const B_T: Fq = Fq::from_montgomery_limbs([
7466800842436274004,
14314110021432015475,
14108125795146788134,
1305086759679105397,
]);
pub const B_Z: Fq = Fq::ONE;

// Canonical basepoint affine coordinates
pub const GENERATOR_X: Fq = Fq::from_montgomery_limbs([
Expand Down
4 changes: 2 additions & 2 deletions src/ark_curve/element.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ impl Group for Element {
}

fn generator() -> Self {
crate::basepoint()
Self::GENERATOR
}

fn mul_bigint(&self, other: impl AsRef<[u64]>) -> Self {
Expand Down Expand Up @@ -111,7 +111,7 @@ impl AffineRepr for AffinePoint {
}

fn generator() -> Self {
crate::basepoint().into()
Element::GENERATOR.into()
}

fn from_random_bytes(bytes: &[u8]) -> Option<Self> {
Expand Down
13 changes: 13 additions & 0 deletions src/ark_curve/element/projective.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,24 @@ use zeroize::Zeroize;

use crate::{ark_curve::EdwardsProjective, Fq, Fr};

use super::super::constants::{B_T, B_X, B_Y, B_Z};

#[derive(Copy, Clone)]
pub struct Element {
pub(crate) inner: EdwardsProjective,
}

impl Element {
/// Return the conventional generator for `decaf377`.
pub const GENERATOR: Self = Self {
inner: EdwardsProjective::new_unchecked(B_X, B_Y, B_T, B_Z),
};

pub const IDENTITY: Self = Self {
inner: EdwardsProjective::new_unchecked(Fq::ZERO, Fq::ONE, Fq::ZERO, Fq::ONE),
};
}

impl Hash for Element {
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
self.inner.hash(state);
Expand Down
12 changes: 0 additions & 12 deletions src/ark_curve/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,3 @@ mod on_curve;
pub mod r1cs;

pub use bls12_377::Bls12_377;

/// Return the conventional generator for `decaf377`.
pub fn basepoint() -> Element {
Element {
inner: EdwardsProjective::new(
*constants::B_X,
*constants::B_Y,
*constants::B_T,
*constants::B_Z,
),
}
}
16 changes: 12 additions & 4 deletions src/fields/fp.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
// Fiat-crypto generates some unused type aliases, but we don't want to edit the generated code at all.
#![allow(dead_code)]

use cfg_if::cfg_if;
use rand_core::CryptoRngCore;

use crate::EncodingError;

Expand Down Expand Up @@ -115,7 +113,6 @@ impl Fp {
}) // let acc =
}

///
/// Convert bytes into an Fp element, returning None if these bytes are not already reduced.
///
/// This means that values that cannot be produced by encoding a field element will return
Expand All @@ -132,6 +129,17 @@ impl Fp {
pub fn to_bytes(&self) -> [u8; N_8] {
self.to_bytes_le()
}

/// Sample a random field element uniformly.
pub fn rand<R: CryptoRngCore>(rng: &mut R) -> Self {
// Sample wide, reduce
let bytes = {
let mut out = [0u8; N_8 + 16];
rng.fill_bytes(&mut out);
out
};
Self::from_le_bytes_mod_order(&bytes)
}
}

#[cfg(test)]
Expand Down
2 changes: 1 addition & 1 deletion src/fields/fp/u32/wrapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use super::{
const N: usize = N_32;

#[derive(Copy, Clone)]
pub struct Fp(pub fiat::FpMontgomeryDomainFieldElement);
pub struct Fp(fiat::FpMontgomeryDomainFieldElement);

impl PartialEq for Fp {
fn eq(&self, other: &Self) -> bool {
Expand Down
2 changes: 1 addition & 1 deletion src/fields/fp/u64/wrapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use super::{
const N: usize = N_64;

#[derive(Copy, Clone)]
pub struct Fp(pub fiat::FpMontgomeryDomainFieldElement);
pub struct Fp(fiat::FpMontgomeryDomainFieldElement);

impl PartialEq for Fp {
fn eq(&self, other: &Self) -> bool {
Expand Down
15 changes: 12 additions & 3 deletions src/fields/fq.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
// Fiat-crypto generates some unused type aliases, but we don't want to edit the generated code at all.
#![allow(dead_code)]

use cfg_if::cfg_if;
use rand_core::CryptoRngCore;

use crate::EncodingError;

Expand Down Expand Up @@ -116,6 +114,17 @@ impl Fq {
pub fn to_bytes(&self) -> [u8; N_8] {
self.to_bytes_le()
}

/// Sample a random field element uniformly.
pub fn rand<R: CryptoRngCore>(rng: &mut R) -> Self {
// Sample wide, reduce
let bytes = {
let mut out = [0u8; N_8 + 16];
rng.fill_bytes(&mut out);
out
};
Self::from_le_bytes_mod_order(&bytes)
}
}

#[cfg(test)]
Expand Down
2 changes: 1 addition & 1 deletion src/fields/fq/u32/wrapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use super::{
const N: usize = N_32;

#[derive(Copy, Clone)]
pub struct Fq(pub fiat::FqMontgomeryDomainFieldElement);
pub struct Fq(fiat::FqMontgomeryDomainFieldElement);

impl PartialEq for Fq {
fn eq(&self, other: &Self) -> bool {
Expand Down
2 changes: 1 addition & 1 deletion src/fields/fq/u64/wrapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use super::{
const N: usize = N_64;

#[derive(Copy, Clone)]
pub struct Fq(pub fiat::FqMontgomeryDomainFieldElement);
pub struct Fq(fiat::FqMontgomeryDomainFieldElement);

impl PartialEq for Fq {
fn eq(&self, other: &Self) -> bool {
Expand Down
15 changes: 12 additions & 3 deletions src/fields/fr.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
// Fiat-crypto generates some unused type aliases, but we don't want to edit the generated code at all.
#![allow(dead_code)]

use cfg_if::cfg_if;
use rand_core::CryptoRngCore;

use crate::EncodingError;

Expand Down Expand Up @@ -108,6 +106,17 @@ impl Fr {
pub fn to_bytes(&self) -> [u8; N_8] {
self.to_bytes_le()
}

/// Sample a random field element uniformly.
pub fn rand<R: CryptoRngCore>(rng: &mut R) -> Self {
// Sample wide, reduce
let bytes = {
let mut out = [0u8; N_8 + 16];
rng.fill_bytes(&mut out);
out
};
Self::from_le_bytes_mod_order(&bytes)
}
}

#[cfg(test)]
Expand Down
2 changes: 1 addition & 1 deletion src/fields/fr/u32/wrapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use super::{
const N: usize = N_32;

#[derive(Copy, Clone)]
pub struct Fr(pub fiat::FrMontgomeryDomainFieldElement);
pub struct Fr(fiat::FrMontgomeryDomainFieldElement);

impl PartialEq for Fr {
fn eq(&self, other: &Self) -> bool {
Expand Down
2 changes: 1 addition & 1 deletion src/fields/fr/u64/wrapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use super::{
const N: usize = N_64;

#[derive(Copy, Clone)]
pub struct Fr(pub fiat::FrMontgomeryDomainFieldElement);
pub struct Fr(fiat::FrMontgomeryDomainFieldElement);

impl PartialEq for Fr {
fn eq(&self, other: &Self) -> bool {
Expand Down
2 changes: 0 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ cfg_if! {

pub use ark_curve::{Element, Encoding, ZETA};

pub use ark_curve::basepoint;

pub use ark_curve::bls12_377::Bls12_377;

#[cfg(feature = "r1cs")]
Expand Down
86 changes: 86 additions & 0 deletions src/min_curve/element.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,13 @@ impl Element {
Element { x, y, z, t }
}
}
///
/// Convenience method to make identity checks more readable.
pub fn is_identity(&self) -> bool {
// Section 4.5 of Decaf paper states for cofactor 4 curves we can
// just check X = 0 to check equality with identity
self.x == Fq::ZERO
}

pub fn double(self) -> Self {
// https://eprint.iacr.org/2008/522 Section 3.3
Expand Down Expand Up @@ -383,6 +390,85 @@ mod test {
}
}

impl From<&Element> for Encoding {
fn from(point: &Element) -> Self {
point.vartime_compress()
}
}

impl From<Element> for Encoding {
fn from(point: Element) -> Self {
point.vartime_compress()
}
}

impl TryFrom<&[u8]> for Encoding {
type Error = EncodingError;

fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
if bytes.len() == 32 {
let mut arr = [0u8; 32];
arr.copy_from_slice(&bytes[0..32]);
Ok(Encoding(arr))
} else {
Err(EncodingError::InvalidSliceLength)
}
}
}

impl From<[u8; 32]> for Encoding {
fn from(bytes: [u8; 32]) -> Encoding {
Encoding(bytes)
}
}

impl From<Encoding> for [u8; 32] {
fn from(enc: Encoding) -> [u8; 32] {
enc.0
}
}

impl TryFrom<&Encoding> for Element {
type Error = EncodingError;
fn try_from(bytes: &Encoding) -> Result<Self, Self::Error> {
bytes.vartime_decompress()
}
}

impl TryFrom<Encoding> for Element {
type Error = EncodingError;
fn try_from(bytes: Encoding) -> Result<Self, Self::Error> {
bytes.vartime_decompress()
}
}

impl TryFrom<&[u8]> for Element {
type Error = EncodingError;

fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
let b: [u8; 32] = bytes
.try_into()
.map_err(|_| EncodingError::InvalidSliceLength)?;

Encoding(b).try_into()
}
}

impl TryFrom<[u8; 32]> for Element {
type Error = EncodingError;

fn try_from(bytes: [u8; 32]) -> Result<Self, Self::Error> {
let encoding = Encoding(bytes);
encoding.try_into()
}
}

impl From<Element> for [u8; 32] {
fn from(enc: Element) -> [u8; 32] {
enc.vartime_compress().0
}
}

#[cfg(all(test, feature = "arkworks"))]
mod proptests {
use super::*;
Expand Down
Loading
Loading