From 316b996dbfa32dd4c4092bc5b7cce2675ba9db4f Mon Sep 17 00:00:00 2001 From: Todd Norton Date: Thu, 8 Sep 2022 19:30:35 +0200 Subject: [PATCH 01/10] wip: remove all scale dep --- manta-pay/Cargo.toml | 10 +-- .../src/crypto/constraint/arkworks/groth16.rs | 68 +--------------- .../src/crypto/constraint/arkworks/mod.rs | 65 --------------- manta-pay/src/crypto/ecc/arkworks.rs | 67 ---------------- manta-pay/src/signer/mod.rs | 57 ------------- manta-pay/src/test/transfer.rs | 79 ------------------- manta-pay/src/util/mod.rs | 4 - manta-pay/src/util/scale.rs | 60 -------------- 8 files changed, 3 insertions(+), 407 deletions(-) delete mode 100644 manta-pay/src/util/scale.rs diff --git a/manta-pay/Cargo.toml b/manta-pay/Cargo.toml index 96fdcdcf4..2dc910b01 100644 --- a/manta-pay/Cargo.toml +++ b/manta-pay/Cargo.toml @@ -54,12 +54,6 @@ groth16 = ["ark-groth16", "ark-snark", "arkworks"] # Enable HTTP Signer Client http = ["manta-util/reqwest", "serde"] -# SCALE Codec and Type Info -scale = ["scale-codec", "scale-info"] - -# SCALE Codec and Type Info with the Standard Library Enabled -scale-std = ["scale", "scale-codec/std", "scale-info/std", "std"] - # Serde serde = ["manta-accounting/serde", "manta-crypto/serde"] @@ -119,8 +113,6 @@ manta-util = { path = "../manta-util", default-features = false } parking_lot = { version = "0.12.1", optional = true, default-features = false } rand_chacha = { version = "0.3.1", default-features = false } rayon = { version = "1.5.1", optional = true, default-features = false } -scale-codec = { package = "parity-scale-codec", version = "3.1.2", optional = true, default-features = false, features = ["derive", "max-encoded-len"] } -scale-info = { version = "2.1.2", optional = true, default-features = false, features = ["derive"] } serde_json = { version = "1.0.85", optional = true, default-features = false, features = ["alloc"] } tempfile = { version = "3.3.0", optional = true, default-features = false } tide = { version = "0.16.0", optional = true, default-features = false, features = ["h1-server"] } @@ -130,4 +122,4 @@ ws_stream_wasm = { version = "0.7.3", optional = true, default-features = false [dev-dependencies] manta-crypto = { path = "../manta-crypto", default-features = false, features = ["getrandom"] } -manta-pay = { path = ".", default-features = false, features = ["download", "groth16", "scale", "scale-std", "std", "test"] } +manta-pay = { path = ".", default-features = false, features = ["download", "groth16", "std", "test"] } diff --git a/manta-pay/src/crypto/constraint/arkworks/groth16.rs b/manta-pay/src/crypto/constraint/arkworks/groth16.rs index ae6473911..709519d0d 100644 --- a/manta-pay/src/crypto/constraint/arkworks/groth16.rs +++ b/manta-pay/src/crypto/constraint/arkworks/groth16.rs @@ -35,8 +35,8 @@ use manta_crypto::{ }; use manta_util::codec::{self, DecodeError}; -#[cfg(feature = "scale")] -use crate::crypto::ecc::arkworks::Group; +// #[cfg(feature = "scale")] +// use crate::crypto::ecc::arkworks::Group; #[cfg(feature = "serde")] use manta_util::serde::{Deserialize, Serialize, Serializer}; @@ -74,70 +74,6 @@ pub struct Proof( where E: PairingEngine; -#[cfg(feature = "scale")] -#[cfg_attr(doc_cfg, doc(cfg(feature = "scale")))] -impl scale_codec::Decode for Proof -where - E: PairingEngine, -{ - #[inline] - fn decode(input: &mut I) -> Result - where - I: scale_codec::Input, - { - Ok(Self( - CanonicalDeserialize::deserialize(arkworks::codec::ScaleCodecReader(input)) - .map_err(|_| "Deserialization Error")?, - )) - } -} - -#[cfg(feature = "scale")] -#[cfg_attr(doc_cfg, doc(cfg(feature = "scale")))] -impl scale_codec::Encode for Proof -where - E: PairingEngine, -{ - #[inline] - fn using_encoded(&self, f: Encoder) -> R - where - Encoder: FnOnce(&[u8]) -> R, - { - f(&proof_as_bytes::(&self.0)) - } -} - -#[cfg(feature = "scale")] -#[cfg_attr(doc_cfg, doc(cfg(feature = "scale")))] -impl scale_codec::EncodeLike for Proof where E: PairingEngine {} - -#[cfg(feature = "scale")] -#[cfg_attr(doc_cfg, doc(cfg(feature = "scale")))] -impl scale_codec::MaxEncodedLen for Proof -where - E: PairingEngine, -{ - #[inline] - fn max_encoded_len() -> usize { - 2 * Group::::max_encoded_len() - + Group::::max_encoded_len() - } -} - -#[cfg(feature = "scale")] -#[cfg_attr(doc_cfg, doc(cfg(feature = "scale")))] -impl scale_info::TypeInfo for Proof -where - E: PairingEngine, -{ - type Identity = [u8]; - - #[inline] - fn type_info() -> scale_info::Type { - Self::Identity::type_info() - } -} - impl codec::Encode for Proof where E: PairingEngine, diff --git a/manta-pay/src/crypto/constraint/arkworks/mod.rs b/manta-pay/src/crypto/constraint/arkworks/mod.rs index 9d0b60c96..2220b1c14 100644 --- a/manta-pay/src/crypto/constraint/arkworks/mod.rs +++ b/manta-pay/src/crypto/constraint/arkworks/mod.rs @@ -163,71 +163,6 @@ where } } -#[cfg(feature = "scale")] -#[cfg_attr(doc_cfg, doc(cfg(feature = "scale")))] -impl scale_codec::Decode for Fp -where - F: Field, -{ - #[inline] - fn decode(input: &mut I) -> Result - where - I: scale_codec::Input, - { - Ok(Self( - F::deserialize(codec::ScaleCodecReader(input)).map_err(|_| "Deserialization Error")?, - )) - } -} - -#[cfg(feature = "scale")] -#[cfg_attr(doc_cfg, doc(cfg(feature = "scale")))] -impl scale_codec::Encode for Fp -where - F: Field, -{ - #[inline] - fn using_encoded(&self, f: Encoder) -> R - where - Encoder: FnOnce(&[u8]) -> R, - { - f(&field_element_as_bytes::(&self.0)) - } -} - -#[cfg(feature = "scale")] -#[cfg_attr(doc_cfg, doc(cfg(feature = "scale")))] -impl scale_codec::EncodeLike for Fp where F: Field {} - -#[cfg(feature = "scale")] -#[cfg_attr(doc_cfg, doc(cfg(feature = "scale")))] -impl scale_codec::MaxEncodedLen for Fp -where - F: Field, -{ - #[inline] - fn max_encoded_len() -> usize { - byte_count( - <::Params as FpParameters>::MODULUS_BITS - * (F::extension_degree() as u32), - ) as usize - } -} - -#[cfg(feature = "scale")] -#[cfg_attr(doc_cfg, doc(cfg(feature = "scale")))] -impl scale_info::TypeInfo for Fp -where - F: Field, -{ - type Identity = [u8]; - - #[inline] - fn type_info() -> scale_info::Type { - Self::Identity::type_info() - } -} - impl eclair::cmp::PartialEq for Fp where F: Field, diff --git a/manta-pay/src/crypto/ecc/arkworks.rs b/manta-pay/src/crypto/ecc/arkworks.rs index 80ccfaee3..6ea8b8759 100644 --- a/manta-pay/src/crypto/ecc/arkworks.rs +++ b/manta-pay/src/crypto/ecc/arkworks.rs @@ -141,73 +141,6 @@ where } } -#[cfg(feature = "scale")] -#[cfg_attr(doc_cfg, doc(cfg(feature = "scale")))] -impl scale_codec::Decode for Group -where - C: ProjectiveCurve, -{ - #[inline] - fn decode(input: &mut I) -> Result - where - I: scale_codec::Input, - { - Ok(Self( - CanonicalDeserialize::deserialize(arkworks::codec::ScaleCodecReader(input)) - .map_err(|_| "Deserialization Error")?, - )) - } -} - -#[cfg(feature = "scale")] -#[cfg_attr(doc_cfg, doc(cfg(feature = "scale")))] -impl scale_codec::Encode for Group -where - C: ProjectiveCurve, -{ - #[inline] - fn using_encoded(&self, f: Encoder) -> R - where - Encoder: FnOnce(&[u8]) -> R, - { - f(&affine_point_as_bytes::(&self.0)) - } -} - -#[cfg(feature = "scale")] -#[cfg_attr(doc_cfg, doc(cfg(feature = "scale")))] -impl scale_codec::EncodeLike for Group where C: ProjectiveCurve {} - -#[cfg(feature = "scale")] -#[cfg_attr(doc_cfg, doc(cfg(feature = "scale")))] -impl scale_codec::MaxEncodedLen for Group -where - C: ProjectiveCurve, -{ - #[inline] - fn max_encoded_len() -> usize { - // NOTE: In affine form, we have two base field elements to represent the point. The - // encoding uses a compressed representation, so we only need to include half as many - // bytes. We add space for an extra byte flag in case we need to keep track of - // "infinity". - Fp::::max_encoded_len() + 1 - } -} - -#[cfg(feature = "scale")] -#[cfg_attr(doc_cfg, doc(cfg(feature = "scale")))] -impl scale_info::TypeInfo for Group -where - C: ProjectiveCurve, -{ - type Identity = [u8]; - - #[inline] - fn type_info() -> scale_info::Type { - Self::Identity::type_info() - } -} - impl AsBytes for Group where C: ProjectiveCurve, diff --git a/manta-pay/src/signer/mod.rs b/manta-pay/src/signer/mod.rs index 9feb02c3e..f9b0735f8 100644 --- a/manta-pay/src/signer/mod.rs +++ b/manta-pay/src/signer/mod.rs @@ -104,64 +104,7 @@ impl From for Checkpoint { impl ledger::Checkpoint for Checkpoint {} -#[cfg(feature = "scale")] -#[cfg_attr(doc_cfg, doc(cfg(feature = "scale")))] -impl scale_codec::Decode for Checkpoint { - #[inline] - fn decode(input: &mut I) -> Result - where - I: scale_codec::Input, - { - RawCheckpoint::decode(input).map(Into::into) - } -} - -#[cfg(feature = "scale")] -#[cfg_attr(doc_cfg, doc(cfg(feature = "scale")))] -impl scale_codec::Encode for Checkpoint { - #[inline] - fn using_encoded(&self, f: Encoder) -> R - where - Encoder: FnOnce(&[u8]) -> R, - { - RawCheckpoint::from(*self).using_encoded(f) - } -} - -#[cfg(feature = "scale")] -#[cfg_attr(doc_cfg, doc(cfg(feature = "scale")))] -impl scale_codec::EncodeLike for Checkpoint {} - -#[cfg(feature = "scale")] -#[cfg_attr(doc_cfg, doc(cfg(feature = "scale")))] -impl scale_codec::MaxEncodedLen for Checkpoint { - #[inline] - fn max_encoded_len() -> usize { - RawCheckpoint::max_encoded_len() - } -} - -#[cfg(feature = "scale")] -#[cfg_attr(doc_cfg, doc(cfg(feature = "scale")))] -impl scale_info::TypeInfo for Checkpoint { - type Identity = RawCheckpoint; - - #[inline] - fn type_info() -> scale_info::Type { - Self::Identity::type_info() - } -} - /// Raw Checkpoint for Encoding and Decoding -#[cfg_attr( - feature = "scale", - derive( - scale_codec::Decode, - scale_codec::Encode, - scale_codec::MaxEncodedLen, - scale_info::TypeInfo - ) -)] #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] pub struct RawCheckpoint { /// Receiver Index diff --git a/manta-pay/src/test/transfer.rs b/manta-pay/src/test/transfer.rs index 8aeaa896e..b93fb2790 100644 --- a/manta-pay/src/test/transfer.rs +++ b/manta-pay/src/test/transfer.rs @@ -19,7 +19,6 @@ use crate::{ config::{FullParameters, Mint, PrivateTransfer, Proof, ProofSystem, Reclaim}, test::payment::UtxoAccumulator, - util::scale::{assert_valid_codec, assert_valid_io_codec}, }; use ark_std::rand::RngCore; use core::fmt::Debug; @@ -250,81 +249,3 @@ fn reclaim_proof_validity() { .expect("Random Reclaim should have produced a proof."); validity_check_with_fuzzing(&verifying_context, &post, &mut rng); } - -/// Asserts that `proof` can be SCALE encoded and decoded with at least [`Vec`], [`Cursor`], and -/// [`File`](std::fs::File). -#[inline] -fn assert_valid_proof_codec(proof: &Proof) { - assert_valid_codec(proof, &mut Vec::new(), move |v| v.as_slice()); - assert_valid_io_codec(proof, &mut Cursor::new(vec![0; 8192])); - assert_valid_io_codec( - proof, - &mut tempfile::tempfile().expect("Unable to construct temporary file."), - ); -} - -/// Tests the SCALE encoding and decoding of a [`Mint`] proof. -#[test] -fn mint_proof_scale_codec() { - let mut rng = OsRng; - let parameters = rng.gen(); - let mut utxo_accumulator = UtxoAccumulator::new(rng.gen()); - let (proving_context, verifying_context) = Mint::generate_context( - &(), - FullParameters::new(¶meters, utxo_accumulator.model()), - &mut rng, - ) - .expect("Unable to create proving and verifying contexts."); - let post = Mint::sample_post( - &proving_context, - ¶meters, - &mut utxo_accumulator, - &mut rng, - ) - .expect("Random Mint should have produced a proof."); - assert_valid_proof_codec(post.assert_valid_proof(&verifying_context)); -} - -/// Tests the SCALE encoding and decoding of a [`PrivateTransfer`] proof. -#[test] -fn private_transfer_proof_scale_codec() { - let mut rng = OsRng; - let parameters = rng.gen(); - let mut utxo_accumulator = UtxoAccumulator::new(rng.gen()); - let (proving_context, verifying_context) = PrivateTransfer::generate_context( - &(), - FullParameters::new(¶meters, utxo_accumulator.model()), - &mut rng, - ) - .expect("Unable to create proving and verifying contexts."); - let post = PrivateTransfer::sample_post( - &proving_context, - ¶meters, - &mut utxo_accumulator, - &mut rng, - ) - .expect("Random PrivateTransfer should have produced a proof."); - assert_valid_proof_codec(post.assert_valid_proof(&verifying_context)); -} - -/// Tests the SCALE encoding and decoding of a [`Reclaim`] proof. -#[test] -fn reclaim_proof_scale_codec() { - let mut rng = OsRng; - let parameters = rng.gen(); - let mut utxo_accumulator = UtxoAccumulator::new(rng.gen()); - let (proving_context, verifying_context) = Reclaim::generate_context( - &(), - FullParameters::new(¶meters, utxo_accumulator.model()), - &mut rng, - ) - .expect("Unable to create proving and verifying contexts."); - let post = Reclaim::sample_post( - &proving_context, - ¶meters, - &mut utxo_accumulator, - &mut rng, - ) - .expect("Random Reclaim should have produced a proof."); - assert_valid_proof_codec(post.assert_valid_proof(&verifying_context)); -} diff --git a/manta-pay/src/util/mod.rs b/manta-pay/src/util/mod.rs index fe69b8ddc..5254637eb 100644 --- a/manta-pay/src/util/mod.rs +++ b/manta-pay/src/util/mod.rs @@ -15,7 +15,3 @@ // along with manta-rs. If not, see . //! Manta Pay Utilities - -#[cfg(feature = "scale")] -#[cfg_attr(doc_cfg, doc(cfg(feature = "scale")))] -pub mod scale; diff --git a/manta-pay/src/util/scale.rs b/manta-pay/src/util/scale.rs deleted file mode 100644 index 251c1c1de..000000000 --- a/manta-pay/src/util/scale.rs +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright 2019-2022 Manta Network. -// This file is part of manta-rs. -// -// manta-rs is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// manta-rs is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with manta-rs. If not, see . - -//! SCALE Utilities - -use core::fmt::Debug; -use scale_codec::{Decode, Encode, Input, Output}; - -#[cfg(feature = "scale-std")] -use { - scale_codec::IoReader, - std::io::{Read, Seek, Write}, -}; - -/// Asserts that the SCALE encoding and decoding of `value` is equal to `value`, using `buffer` as -/// the [`Output`] type and `f(buffer)` as the [`Input`]. -#[inline] -pub fn assert_valid_codec<'o, T, O, I, F>(value: &T, buffer: &'o mut O, f: F) -where - T: Debug + Decode + Encode + PartialEq, - O: Output, - I: 'o + Input, - F: FnOnce(&'o mut O) -> I, -{ - value.encode_to(buffer); - assert_eq!( - value, - &T::decode(&mut f(buffer)).expect("Unable to decode the value from the input."), - "The value and its decoded-encoded form were unequal." - ); -} - -/// Asserts that the SCALE encoding and decoding of `value` is equal to `value`, using `buffer` as -/// the [`Output`] and [`Input`] with [`std`]. -#[cfg(feature = "scale-std")] -#[cfg_attr(doc_cfg, doc(cfg(feature = "scale-std")))] -#[inline] -pub fn assert_valid_io_codec(value: &T, buffer: &mut O) -where - T: Debug + Decode + Encode + PartialEq, - O: Read + Seek + Write, -{ - assert_valid_codec(value, buffer, move |b| { - b.rewind().expect("Unable to rewind buffer."); - IoReader(b) - }) -} From 3bb5ec5838f0eaa8c288c7e3f48e43ad4ea0fe85 Mon Sep 17 00:00:00 2001 From: Todd Norton Date: Thu, 8 Sep 2022 23:17:07 +0200 Subject: [PATCH 02/10] migrate Fp --- manta-crypto/Cargo.toml | 2 + manta-crypto/src/arkworks/codec.rs | 171 ++++++++++++ manta-crypto/src/arkworks/ff.rs | 247 +++++++++++++++++- manta-crypto/src/arkworks/mod.rs | 1 + .../src/crypto/constraint/arkworks/mod.rs | 227 +--------------- 5 files changed, 421 insertions(+), 227 deletions(-) create mode 100644 manta-crypto/src/arkworks/codec.rs diff --git a/manta-crypto/Cargo.toml b/manta-crypto/Cargo.toml index 612a3bcad..5b0d6ff80 100644 --- a/manta-crypto/Cargo.toml +++ b/manta-crypto/Cargo.toml @@ -32,6 +32,7 @@ arkworks = [ "ark-r1cs-std", "ark-relations", "ark-serialize", + "ark-std", ] # Dalek Cryptography Backend @@ -61,6 +62,7 @@ ark-ff = { version = "0.3.0", optional = true, default-features = false } ark-r1cs-std = { version = "0.3.1", optional = true, default-features = false } ark-relations = { version = "0.3.0", optional = true, default-features = false } ark-serialize = { version = "0.3.0", optional = true, default-features = false, features = ["derive"] } +ark-std = { version = "0.3.0", optional = true, default-features = false } derivative = { version = "2.2.0", default-features = false, features = ["use_core"] } ed25519-dalek = { version = "1.0.1", optional = true, default-features = false, features = ["u64_backend"] } manta-util = { path = "../manta-util", default-features = false, features = ["alloc"] } diff --git a/manta-crypto/src/arkworks/codec.rs b/manta-crypto/src/arkworks/codec.rs new file mode 100644 index 000000000..a4088b216 --- /dev/null +++ b/manta-crypto/src/arkworks/codec.rs @@ -0,0 +1,171 @@ +// Copyright 2019-2022 Manta Network. +// This file is part of manta-rs. +// +// manta-rs is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// manta-rs is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with manta-rs. If not, see . + +//! Codec Utilities + +use ark_std::io::{self, Error, ErrorKind}; +use manta_util::codec::{Read, ReadExactError, Write}; + +pub use crate::arkworks::serialize::{ + CanonicalDeserialize, CanonicalSerialize, SerializationError, +}; + +/// Serialization Hook +pub trait HasSerialization<'s>: 's { + /// Serialize Type + type Serialize: CanonicalSerialize + From<&'s Self>; +} + +/// Deserialization Hook +pub trait HasDeserialization: Sized { + /// Deserialize Type + type Deserialize: CanonicalDeserialize + Into; +} + +/// Arkworks Reader +pub struct ArkReader +where + R: Read, +{ + /// Reader State + state: Result, +} + +impl ArkReader +where + R: Read, +{ + /// Builds a new [`ArkReader`] from `reader`. + #[inline] + pub fn new(reader: R) -> Self { + Self { state: Ok(reader) } + } + + /// Updates the internal reader state by performing the `f` computation. + #[inline] + fn update(&mut self, f: F) -> Option + where + F: FnOnce(&mut R) -> Result, + { + if let Ok(reader) = self.state.as_mut() { + match f(reader) { + Ok(value) => return Some(value), + Err(err) => self.state = Err(err), + } + } + None + } + + /// Returns the reader state back or an error if it occured during any [`Read`](io::Read) + /// methods. + #[inline] + pub fn finish(self) -> Result { + self.state + } +} + +impl io::Read for ArkReader +where + R: Read, +{ + #[inline] + fn read(&mut self, buf: &mut [u8]) -> Result { + self.update(|reader| reader.read(buf)) + .ok_or_else(|| Error::new(ErrorKind::Other, "Reading Error")) + } + + #[inline] + fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), Error> { + match self.update(|reader| match reader.read_exact(buf) { + Ok(value) => Ok(Ok(value)), + Err(ReadExactError::Read(err)) => Err(err), + Err(ReadExactError::UnexpectedEnd(err)) => Ok(Err(err)), + }) { + Some(Ok(_)) => Ok(()), + Some(Err(_)) => Err(Error::new( + ErrorKind::UnexpectedEof, + "Unexpected end of buffer.", + )), + _ => Err(Error::new(ErrorKind::Other, "Reading Error")), + } + } +} + +/// Arkworks Writer +pub struct ArkWriter +where + W: Write, +{ + /// Writer State + state: Result, +} + +impl ArkWriter +where + W: Write, +{ + /// Builds a new [`ArkWriter`] from `writer`. + #[inline] + pub fn new(writer: W) -> Self { + Self { state: Ok(writer) } + } + + /// Updates the internal writer state by performing the `f` computation. + #[inline] + fn update(&mut self, f: F) -> Option + where + F: FnOnce(&mut W) -> Result, + { + if let Ok(writer) = self.state.as_mut() { + match f(writer) { + Ok(value) => return Some(value), + Err(err) => self.state = Err(err), + } + } + None + } + + /// Returns the writer state back or an error if it occured during any [`Write`](io::Write) + /// methods. + #[inline] + pub fn finish(self) -> Result { + self.state + } +} + +impl io::Write for ArkWriter +where + W: Write, +{ + #[inline] + fn write(&mut self, mut buf: &[u8]) -> Result { + self.update(|writer| writer.write(&mut buf)) + .ok_or_else(|| Error::new(ErrorKind::Other, "Writing Error")) + } + + #[inline] + fn flush(&mut self) -> Result<(), Error> { + // NOTE: We can't necessarily do better than this for now, unfortunately. + Ok(()) + } + + #[inline] + fn write_all(&mut self, mut buf: &[u8]) -> Result<(), Error> { + self.update(|writer| writer.write(&mut buf)) + .map(|_| ()) + .ok_or_else(|| Error::new(ErrorKind::Other, "Writing Error")) + } +} diff --git a/manta-crypto/src/arkworks/ff.rs b/manta-crypto/src/arkworks/ff.rs index e9096bbd3..b8fdf1ddf 100644 --- a/manta-crypto/src/arkworks/ff.rs +++ b/manta-crypto/src/arkworks/ff.rs @@ -16,11 +16,256 @@ //! Arkworks Finite Field Backend -use manta_util::{byte_count, into_array_unchecked}; +use crate::{ + algebra, + arkworks::codec, + constraint::{Input, ProofSystem}, + eclair::{ + self, + bool::{Bool, ConditionalSelect}, + }, + rand::{RngCore, Sample}, +}; +use alloc::vec::Vec; +use core::iter::{self, Extend}; +use manta_util::{ + byte_count, + codec::{Decode, DecodeError, Encode, Read, Write}, + into_array_unchecked, SizeLimit, +}; + +#[cfg(feature = "serde")] +use manta_util::serde::{Deserialize, Serialize, Serializer}; #[doc(inline)] pub use ark_ff::*; +/// Field Element +#[cfg_attr( + feature = "serde", + derive(Deserialize, Serialize), + serde( + bound(deserialize = "", serialize = ""), + crate = "manta_util::serde", + deny_unknown_fields, + try_from = "Vec" + ) +)] +#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct Fp( + /// Field Element + #[cfg_attr( + feature = "serde", + serde(serialize_with = "serialize_field_element::") + )] + pub F, +) +where + F: Field; + +impl From for Fp +where + F: Field, +{ + #[inline] + fn from(value: u128) -> Self { + Self(value.into()) + } +} + +impl ToConstraintField for Fp +where + F: PrimeField, +{ + #[inline] + fn to_field_elements(&self) -> Option> { + self.0.to_field_elements() + } +} + +impl Input

for Fp +where + F: Field, + P: ProofSystem + ?Sized, + P::Input: Extend, +{ + #[inline] + fn extend(&self, input: &mut P::Input) { + input.extend(iter::once(self.0)) + } +} + +impl Decode for Fp +where + F: Field, +{ + type Error = codec::SerializationError; + + #[inline] + fn decode(reader: R) -> Result> + where + R: Read, + { + let mut reader = codec::ArkReader::new(reader); + match F::deserialize(&mut reader) { + Ok(value) => reader + .finish() + .map(move |_| Self(value)) + .map_err(DecodeError::Read), + Err(err) => Err(DecodeError::Decode(err)), + } + } +} + +impl Encode for Fp +where + F: Field, +{ + #[inline] + fn encode(&self, writer: W) -> Result<(), W::Error> + where + W: Write, + { + let mut writer = codec::ArkWriter::new(writer); + let _ = self.0.serialize(&mut writer); + writer.finish().map(move |_| ()) + } +} + +impl eclair::cmp::PartialEq for Fp +where + F: Field, +{ + #[inline] + fn eq(&self, rhs: &Self, _: &mut ()) -> bool { + PartialEq::eq(self, rhs) + } +} + +impl eclair::num::Zero for Fp +where + F: Field, +{ + type Verification = bool; + + #[inline] + fn zero(_: &mut ()) -> Self { + Self(F::zero()) + } + + #[inline] + fn is_zero(&self, _: &mut ()) -> Self::Verification { + self.0.is_zero() + } +} + +impl eclair::num::One for Fp +where + F: Field, +{ + type Verification = bool; + + #[inline] + fn one(_: &mut ()) -> Self { + Self(F::one()) + } + + #[inline] + fn is_one(&self, _: &mut ()) -> Self::Verification { + self.0.is_one() + } +} + +impl ConditionalSelect for Fp +where + F: Field, +{ + #[inline] + fn select(bit: &Bool, true_value: &Self, false_value: &Self, _: &mut ()) -> Self { + if *bit { + *true_value + } else { + *false_value + } + } +} + +impl Sample for Fp +where + F: Field, +{ + #[inline] + fn sample(_: (), rng: &mut R) -> Self + where + R: RngCore + ?Sized, + { + Self(F::rand(rng)) + } +} + +impl algebra::Group for Fp +where + F: Field, +{ + #[inline] + fn add(&self, rhs: &Self, _: &mut ()) -> Self { + Self(self.0 + rhs.0) + } +} + +impl algebra::Ring for Fp +where + F: Field, +{ + #[inline] + fn mul(&self, rhs: &Self, _: &mut ()) -> Self { + Self(self.0 * rhs.0) + } +} + +impl SizeLimit for Fp +where + F: PrimeField, +{ + const SIZE: usize = byte_count(::MODULUS_BITS) as usize; +} + +impl TryFrom> for Fp +where + F: Field, +{ + type Error = codec::SerializationError; + + #[inline] + fn try_from(bytes: Vec) -> Result { + F::deserialize(&mut bytes.as_slice()).map(Self) + } +} + +/// Converts `element` into its canonical byte-representation. +#[inline] +pub fn field_element_as_bytes(element: &F) -> Vec +where + F: Field, +{ + let mut buffer = Vec::new(); + element + .serialize(&mut buffer) + .expect("Serialization is not allowed to fail."); + buffer +} + +/// Uses `serializer` to serialize `element`. +#[cfg(feature = "serde")] +#[inline] +fn serialize_field_element(element: &F, serializer: S) -> Result +where + F: Field, + S: Serializer, +{ + serializer.serialize_bytes(&field_element_as_bytes(element)) +} + /// Implements a fallible conversion from `F` to `$type`. macro_rules! field_try_into { ($($name:ident => $type:tt),* $(,)?) => { diff --git a/manta-crypto/src/arkworks/mod.rs b/manta-crypto/src/arkworks/mod.rs index c959806b7..85960828f 100644 --- a/manta-crypto/src/arkworks/mod.rs +++ b/manta-crypto/src/arkworks/mod.rs @@ -22,6 +22,7 @@ pub use ark_relations as relations; pub use ark_serialize as serialize; pub mod algebra; +pub mod codec; pub mod constraint; pub mod ff; pub mod pairing; diff --git a/manta-pay/src/crypto/constraint/arkworks/mod.rs b/manta-pay/src/crypto/constraint/arkworks/mod.rs index 2220b1c14..70a9f9ee8 100644 --- a/manta-pay/src/crypto/constraint/arkworks/mod.rs +++ b/manta-pay/src/crypto/constraint/arkworks/mod.rs @@ -71,232 +71,6 @@ pub mod pairing; #[cfg_attr(doc_cfg, doc(cfg(feature = "groth16")))] pub mod groth16; -/// Field Element -#[cfg_attr( - feature = "serde", - derive(Deserialize, Serialize), - serde( - bound(deserialize = "", serialize = ""), - crate = "manta_util::serde", - deny_unknown_fields, - try_from = "Vec" - ) -)] -#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] -pub struct Fp( - /// Field Element - #[cfg_attr( - feature = "serde", - serde(serialize_with = "serialize_field_element::") - )] - pub F, -) -where - F: Field; - -impl From for Fp -where - F: Field, -{ - #[inline] - fn from(value: u128) -> Self { - Self(value.into()) - } -} - -impl ToConstraintField for Fp -where - F: PrimeField, -{ - #[inline] - fn to_field_elements(&self) -> Option> { - self.0.to_field_elements() - } -} - -impl Input

for Fp -where - F: Field, - P: ProofSystem + ?Sized, - P::Input: Extend, -{ - #[inline] - fn extend(&self, input: &mut P::Input) { - input.extend(iter::once(self.0)) - } -} - -impl Decode for Fp -where - F: Field, -{ - type Error = codec::SerializationError; - - #[inline] - fn decode(reader: R) -> Result> - where - R: Read, - { - let mut reader = codec::ArkReader::new(reader); - match F::deserialize(&mut reader) { - Ok(value) => reader - .finish() - .map(move |_| Self(value)) - .map_err(DecodeError::Read), - Err(err) => Err(DecodeError::Decode(err)), - } - } -} - -impl Encode for Fp -where - F: Field, -{ - #[inline] - fn encode(&self, writer: W) -> Result<(), W::Error> - where - W: Write, - { - let mut writer = codec::ArkWriter::new(writer); - let _ = self.0.serialize(&mut writer); - writer.finish().map(move |_| ()) - } -} - -impl eclair::cmp::PartialEq for Fp -where - F: Field, -{ - #[inline] - fn eq(&self, rhs: &Self, _: &mut ()) -> bool { - PartialEq::eq(self, rhs) - } -} - -impl eclair::num::Zero for Fp -where - F: Field, -{ - type Verification = bool; - - #[inline] - fn zero(_: &mut ()) -> Self { - Self(F::zero()) - } - - #[inline] - fn is_zero(&self, _: &mut ()) -> Self::Verification { - self.0.is_zero() - } -} - -impl eclair::num::One for Fp -where - F: Field, -{ - type Verification = bool; - - #[inline] - fn one(_: &mut ()) -> Self { - Self(F::one()) - } - - #[inline] - fn is_one(&self, _: &mut ()) -> Self::Verification { - self.0.is_one() - } -} - -impl ConditionalSelect for Fp -where - F: Field, -{ - #[inline] - fn select(bit: &Bool, true_value: &Self, false_value: &Self, _: &mut ()) -> Self { - if *bit { - *true_value - } else { - *false_value - } - } -} - -impl Sample for Fp -where - F: Field, -{ - #[inline] - fn sample(_: (), rng: &mut R) -> Self - where - R: RngCore + ?Sized, - { - Self(F::rand(rng)) - } -} - -impl algebra::Group for Fp -where - F: Field, -{ - #[inline] - fn add(&self, rhs: &Self, _: &mut ()) -> Self { - Self(self.0 + rhs.0) - } -} - -impl algebra::Ring for Fp -where - F: Field, -{ - #[inline] - fn mul(&self, rhs: &Self, _: &mut ()) -> Self { - Self(self.0 * rhs.0) - } -} - -impl SizeLimit for Fp -where - F: PrimeField, -{ - const SIZE: usize = byte_count(::MODULUS_BITS) as usize; -} - -impl TryFrom> for Fp -where - F: Field, -{ - type Error = codec::SerializationError; - - #[inline] - fn try_from(bytes: Vec) -> Result { - F::deserialize(&mut bytes.as_slice()).map(Self) - } -} - -/// Converts `element` into its canonical byte-representation. -#[inline] -pub fn field_element_as_bytes(element: &F) -> Vec -where - F: Field, -{ - let mut buffer = Vec::new(); - element - .serialize(&mut buffer) - .expect("Serialization is not allowed to fail."); - buffer -} - -/// Uses `serializer` to serialize `element`. -#[cfg(feature = "serde")] -#[inline] -fn serialize_field_element(element: &F, serializer: S) -> Result -where - F: Field, - S: Serializer, -{ - serializer.serialize_bytes(&field_element_as_bytes(element)) -} - /// Synthesis Result pub type SynthesisResult = Result; @@ -692,6 +466,7 @@ where /// Testing Suite #[cfg(test)] mod tests { + // move to constraint with R1CS use super::*; use ark_bls12_381::Fr; use core::iter::repeat_with; From bb0a7e652dcd53669eba744a6ac357309af122df Mon Sep 17 00:00:00 2001 From: Todd Norton Date: Fri, 9 Sep 2022 00:17:54 +0200 Subject: [PATCH 03/10] move r1cs to manta-crypto --- manta-crypto/src/arkworks/constraint.rs | 123 +++++++++++++++++- manta-pay/src/config.rs | 4 +- .../src/crypto/constraint/arkworks/mod.rs | 2 +- manta-pay/src/crypto/ecc/arkworks.rs | 4 +- manta-pay/src/crypto/poseidon/arkworks.rs | 4 +- manta-pay/src/crypto/poseidon/compat.rs | 4 +- manta-pay/src/signer/base.rs | 6 +- 7 files changed, 131 insertions(+), 16 deletions(-) diff --git a/manta-crypto/src/arkworks/constraint.rs b/manta-crypto/src/arkworks/constraint.rs index 986892a0a..a1a3ba4b5 100644 --- a/manta-crypto/src/arkworks/constraint.rs +++ b/manta-crypto/src/arkworks/constraint.rs @@ -18,8 +18,10 @@ use crate::{ arkworks::{ - ff::{FpParameters, PrimeField}, - r1cs_std::{alloc::AllocVar, eq::EqGadget, select::CondSelectGadget, ToBitsGadget}, + ff::{Fp, FpParameters, PrimeField}, + r1cs_std::{ + alloc::AllocVar, eq::EqGadget, fields::FieldVar, select::CondSelectGadget, ToBitsGadget, + }, relations::{ ns, r1cs::{ @@ -36,9 +38,9 @@ use crate::{ Constant, Variable, }, bool::{Assert, ConditionalSwap}, - num::AssertWithinBitRange, - ops::Add, - Has, + num::{AssertWithinBitRange, Zero}, + ops::{Add, BitAnd, BitOr}, + Has, NonNative, }, }; @@ -114,6 +116,8 @@ where } } +impl NonNative for R1CS where F: PrimeField {} + impl Has for R1CS where F: PrimeField, @@ -267,6 +271,96 @@ where } } +impl BitAnd> for Boolean +where + F: PrimeField, +{ + type Output = Self; + + #[inline] + fn bitand(self, rhs: Self, compiler: &mut R1CS) -> Self::Output { + let _ = compiler; + self.and(&rhs).expect("Bitwise AND is not allowed to fail.") + } +} + +impl BitOr> for Boolean +where + F: PrimeField, +{ + type Output = Self; + + #[inline] + fn bitor(self, rhs: Self, compiler: &mut R1CS) -> Self::Output { + let _ = compiler; + self.or(&rhs).expect("Bitwise OR is not allowed to fail.") + } +} + +impl Constant> for FpVar +where + F: PrimeField, +{ + type Type = Fp; + + #[inline] + fn new_constant(this: &Self::Type, compiler: &mut R1CS) -> Self { + AllocVar::new_constant(ns!(compiler.0, "field constant"), this.0) + .expect("Variable allocation is not allowed to fail.") + } +} + +impl Constant> for Fp +where + F: PrimeField, +{ + type Type = Self; + + #[inline] + fn new_constant(this: &Self::Type, compiler: &mut R1CS) -> Self { + let _ = compiler; + *this + } +} + +impl Variable> for FpVar +where + F: PrimeField, +{ + type Type = Fp; + + #[inline] + fn new_known(this: &Self::Type, compiler: &mut R1CS) -> Self { + Self::new_input(ns!(compiler.0, "field public input"), full(this.0)) + .expect("Variable allocation is not allowed to fail.") + } + + #[inline] + fn new_unknown(compiler: &mut R1CS) -> Self { + Self::new_input(ns!(compiler.0, "field public input"), empty::) + .expect("Variable allocation is not allowed to fail.") + } +} + +impl Variable> for FpVar +where + F: PrimeField, +{ + type Type = Fp; + + #[inline] + fn new_known(this: &Self::Type, compiler: &mut R1CS) -> Self { + Self::new_witness(ns!(compiler.0, "field secret witness"), full(this.0)) + .expect("Variable allocation is not allowed to fail.") + } + + #[inline] + fn new_unknown(compiler: &mut R1CS) -> Self { + Self::new_witness(ns!(compiler.0, "field secret witness"), empty::) + .expect("Variable allocation is not allowed to fail.") + } +} + impl eclair::cmp::PartialEq> for FpVar where F: PrimeField, @@ -315,3 +409,22 @@ where self + rhs } } + +impl Zero> for FpVar +where + F: PrimeField, +{ + type Verification = Boolean; + + #[inline] + fn zero(compiler: &mut R1CS) -> Self { + let _ = compiler; + FieldVar::zero() + } + + #[inline] + fn is_zero(&self, compiler: &mut R1CS) -> Self::Verification { + let _ = compiler; + FieldVar::is_zero(self).expect("Comparison with zero is not allowed to fail.") + } +} diff --git a/manta-pay/src/config.rs b/manta-pay/src/config.rs index 633314283..d85f6b6c6 100644 --- a/manta-pay/src/config.rs +++ b/manta-pay/src/config.rs @@ -17,7 +17,7 @@ //! Manta-Pay Configuration use crate::crypto::{ - constraint::arkworks::{field_element_as_bytes, groth16, Boolean, Fp, FpVar, R1CS}, + constraint::arkworks::{groth16, Boolean, FpVar, R1CS}, ecc, encryption::aes::{self, FixedNonceAesGcm}, key::Blake2sKdf, @@ -38,7 +38,7 @@ use manta_crypto::{ accumulator, algebra::DiffieHellman, arkworks::{ - ff::ToConstraintField, + ff::{field_element_as_bytes, Fp, ToConstraintField}, serialize::{CanonicalDeserialize, CanonicalSerialize, SerializationError}, }, constraint::Input, diff --git a/manta-pay/src/crypto/constraint/arkworks/mod.rs b/manta-pay/src/crypto/constraint/arkworks/mod.rs index 70a9f9ee8..432602085 100644 --- a/manta-pay/src/crypto/constraint/arkworks/mod.rs +++ b/manta-pay/src/crypto/constraint/arkworks/mod.rs @@ -21,7 +21,7 @@ use core::iter::{self, Extend}; use manta_crypto::{ algebra, arkworks::{ - ff::{Field, FpParameters, PrimeField, ToConstraintField}, + ff::{Field, Fp, FpParameters, PrimeField, ToConstraintField}, r1cs_std::{ alloc::AllocVar, eq::EqGadget, fields::FieldVar, select::CondSelectGadget, ToBitsGadget, }, diff --git a/manta-pay/src/crypto/ecc/arkworks.rs b/manta-pay/src/crypto/ecc/arkworks.rs index 6ea8b8759..e928c2252 100644 --- a/manta-pay/src/crypto/ecc/arkworks.rs +++ b/manta-pay/src/crypto/ecc/arkworks.rs @@ -17,7 +17,7 @@ //! Arkworks Elliptic Curve Primitives use crate::crypto::constraint::arkworks::{ - self, conditionally_select, empty, full, Boolean, Fp, FpVar, R1CS, + self, conditionally_select, empty, full, Boolean, FpVar, R1CS, }; use alloc::vec::Vec; use core::{borrow::Borrow, marker::PhantomData}; @@ -27,7 +27,7 @@ use manta_crypto::{ arkworks::{ algebra::{affine_point_as_bytes, modulus_is_smaller}, ec::{AffineCurve, ProjectiveCurve}, - ff::{BigInteger, Field, PrimeField, Zero as _}, + ff::{BigInteger, Field, Fp, PrimeField, Zero as _}, r1cs_std::{groups::CurveVar, ToBitsGadget}, relations::ns, serialize::{CanonicalDeserialize, CanonicalSerialize, SerializationError}, diff --git a/manta-pay/src/crypto/poseidon/arkworks.rs b/manta-pay/src/crypto/poseidon/arkworks.rs index f390dc48f..b94e849a9 100644 --- a/manta-pay/src/crypto/poseidon/arkworks.rs +++ b/manta-pay/src/crypto/poseidon/arkworks.rs @@ -17,7 +17,7 @@ //! Poseidon Arkworks Backend use crate::crypto::{ - constraint::arkworks::{Fp, FpVar, R1CS}, + constraint::arkworks::{FpVar, R1CS}, poseidon::{ self, encryption::BlockElement, hash::DomainTag, Constants, Field, FieldGeneration, ParameterFieldType, @@ -25,7 +25,7 @@ use crate::crypto::{ }; use manta_crypto::{ arkworks::{ - ff::{BigInteger, Field as _, FpParameters, PrimeField}, + ff::{BigInteger, Field as _, Fp, FpParameters, PrimeField}, r1cs_std::fields::FieldVar, }, eclair::alloc::Constant, diff --git a/manta-pay/src/crypto/poseidon/compat.rs b/manta-pay/src/crypto/poseidon/compat.rs index 43198050c..ad5c3dd2c 100644 --- a/manta-pay/src/crypto/poseidon/compat.rs +++ b/manta-pay/src/crypto/poseidon/compat.rs @@ -327,10 +327,10 @@ pub type Output = #[cfg(feature = "arkworks")] #[cfg_attr(doc_cfg, doc(cfg(feature = "arkworks")))] pub mod arkworks { - use crate::crypto::constraint::arkworks::{Fp, FpVar, R1CS}; + use crate::crypto::constraint::arkworks::{FpVar, R1CS}; use manta_crypto::{ arkworks::{ - ff::{Field, PrimeField}, + ff::{Field, Fp, PrimeField}, r1cs_std::fields::FieldVar, }, eclair::alloc::{Allocate, Constant}, diff --git a/manta-pay/src/signer/base.rs b/manta-pay/src/signer/base.rs index cbbdd12ea..baf6e93c9 100644 --- a/manta-pay/src/signer/base.rs +++ b/manta-pay/src/signer/base.rs @@ -18,7 +18,6 @@ use crate::{ config::{Bls12_381_Edwards, Config, MerkleTreeConfiguration, SecretKey}, - crypto::constraint::arkworks::Fp, key::{CoinType, KeySecret, Testnet, TestnetKeySecret}, signer::Checkpoint, }; @@ -33,7 +32,10 @@ use manta_accounting::{ }, }; use manta_crypto::{ - arkworks::{ec::ProjectiveCurve, ff::PrimeField}, + arkworks::{ + ec::ProjectiveCurve, + ff::{Fp, PrimeField}, + }, key::kdf::KeyDerivationFunction, merkle_tree, merkle_tree::forest::Configuration, From 7fc06f164405056175f73b3c5feb1f8bbf9e5de7 Mon Sep 17 00:00:00 2001 From: Todd Norton Date: Fri, 9 Sep 2022 00:36:36 +0200 Subject: [PATCH 04/10] remove unused imports --- .../src/crypto/constraint/arkworks/mod.rs | 21 +++---------------- 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/manta-pay/src/crypto/constraint/arkworks/mod.rs b/manta-pay/src/crypto/constraint/arkworks/mod.rs index 432602085..7d7107d47 100644 --- a/manta-pay/src/crypto/constraint/arkworks/mod.rs +++ b/manta-pay/src/crypto/constraint/arkworks/mod.rs @@ -16,12 +16,9 @@ //! Arkworks Constraint System and Proof System Implementations -use alloc::vec::Vec; -use core::iter::{self, Extend}; use manta_crypto::{ - algebra, arkworks::{ - ff::{Field, Fp, FpParameters, PrimeField, ToConstraintField}, + ff::{Fp, FpParameters, PrimeField}, r1cs_std::{ alloc::AllocVar, eq::EqGadget, fields::FieldVar, select::CondSelectGadget, ToBitsGadget, }, @@ -33,32 +30,20 @@ use manta_crypto::{ }, }, }, - constraint::{ - measure::{Count, Measure}, - Input, ProofSystem, - }, + constraint::measure::{Count, Measure}, eclair::{ self, alloc::{ mode::{self, Public, Secret}, Constant, Variable, }, - bool::{Assert, Bool, ConditionalSelect, ConditionalSwap}, + bool::{Assert, ConditionalSelect, ConditionalSwap}, num::{AssertWithinBitRange, Zero}, ops::{Add, BitAnd, BitOr}, Has, NonNative, }, - rand::{RngCore, Sample}, -}; -use manta_util::{ - byte_count, - codec::{Decode, DecodeError, Encode, Read, Write}, - SizeLimit, }; -#[cfg(feature = "serde")] -use manta_util::serde::{Deserialize, Serialize, Serializer}; - pub use manta_crypto::arkworks::{ r1cs_std::{bits::boolean::Boolean, fields::fp::FpVar}, relations::r1cs::SynthesisError, From 382b4618797924f298274fa71fbcd124e31df5fc Mon Sep 17 00:00:00 2001 From: Todd Norton Date: Fri, 9 Sep 2022 01:07:09 +0200 Subject: [PATCH 05/10] fix dep.s for tests --- manta-pay/src/crypto/constraint/arkworks/mod.rs | 2 +- manta-pay/src/crypto/poseidon/matrix.rs | 2 +- manta-pay/src/crypto/poseidon/mds.rs | 4 ++-- manta-pay/src/crypto/poseidon/round_constants.rs | 3 +-- manta-pay/src/test/transfer.rs | 3 +-- manta-trusted-setup/src/groth16/test/mod.rs | 5 +++-- 6 files changed, 9 insertions(+), 10 deletions(-) diff --git a/manta-pay/src/crypto/constraint/arkworks/mod.rs b/manta-pay/src/crypto/constraint/arkworks/mod.rs index 7d7107d47..0115a7898 100644 --- a/manta-pay/src/crypto/constraint/arkworks/mod.rs +++ b/manta-pay/src/crypto/constraint/arkworks/mod.rs @@ -458,7 +458,7 @@ mod tests { use manta_crypto::{ arkworks::ff::BigInteger, eclair::alloc::Allocate, - rand::{OsRng, Rand}, + rand::{OsRng, Rand, RngCore}, }; /// Checks if `assert_within_range` passes when `should_pass` is `true` and fails when diff --git a/manta-pay/src/crypto/poseidon/matrix.rs b/manta-pay/src/crypto/poseidon/matrix.rs index 5ed358ef8..f70e805f5 100644 --- a/manta-pay/src/crypto/poseidon/matrix.rs +++ b/manta-pay/src/crypto/poseidon/matrix.rs @@ -627,8 +627,8 @@ where #[cfg(test)] mod test { use super::*; - use crate::crypto::constraint::arkworks::Fp; use ark_bls12_381::Fr; + use manta_crypto::arkworks::ff::Fp; /// Checks if generating minor matrix is correct. #[test] diff --git a/manta-pay/src/crypto/poseidon/mds.rs b/manta-pay/src/crypto/poseidon/mds.rs index 9cfff4bda..2c36d6898 100644 --- a/manta-pay/src/crypto/poseidon/mds.rs +++ b/manta-pay/src/crypto/poseidon/mds.rs @@ -264,10 +264,10 @@ where #[cfg(test)] mod test { use super::*; - use crate::crypto::{constraint::arkworks::Fp, poseidon::matrix::Matrix}; + use crate::crypto::poseidon::matrix::Matrix; use ark_bls12_381::Fr; use manta_crypto::{ - arkworks::ff::{field_new, UniformRand}, + arkworks::ff::{field_new, Fp, UniformRand}, rand::OsRng, }; diff --git a/manta-pay/src/crypto/poseidon/round_constants.rs b/manta-pay/src/crypto/poseidon/round_constants.rs index 007a0b0ea..1e35ced83 100644 --- a/manta-pay/src/crypto/poseidon/round_constants.rs +++ b/manta-pay/src/crypto/poseidon/round_constants.rs @@ -78,9 +78,8 @@ where #[cfg(test)] mod test { use super::*; - use crate::crypto::constraint::arkworks::Fp; use ark_bls12_381::Fr; - use manta_crypto::arkworks::ff::field_new; + use manta_crypto::arkworks::ff::{field_new, Fp}; /// Checks if [`GrainLFSR`] matches hardcoded sage outputs. #[test] diff --git a/manta-pay/src/test/transfer.rs b/manta-pay/src/test/transfer.rs index b93fb2790..0d30c9ee7 100644 --- a/manta-pay/src/test/transfer.rs +++ b/manta-pay/src/test/transfer.rs @@ -17,7 +17,7 @@ //! Manta Pay Transfer Testing use crate::{ - config::{FullParameters, Mint, PrivateTransfer, Proof, ProofSystem, Reclaim}, + config::{FullParameters, Mint, PrivateTransfer, ProofSystem, Reclaim}, test::payment::UtxoAccumulator, }; use ark_std::rand::RngCore; @@ -30,7 +30,6 @@ use manta_crypto::{ constraint::{self, measure::Measure, test::verify_fuzz_public_input, ProofSystem as _}, rand::{fuzz::Fuzz, OsRng, Rand, Sample}, }; -use std::io::Cursor; /// Tests the generation of proving/verifying contexts for [`Mint`]. #[test] diff --git a/manta-trusted-setup/src/groth16/test/mod.rs b/manta-trusted-setup/src/groth16/test/mod.rs index 44a4b4b6c..a3cf38069 100644 --- a/manta-trusted-setup/src/groth16/test/mod.rs +++ b/manta-trusted-setup/src/groth16/test/mod.rs @@ -31,8 +31,9 @@ use ark_snark::SNARK; use blake2::Digest; use manta_crypto::{ arkworks::{ + constraint::R1CS, ec::{AffineCurve, PairingEngine}, - ff::{field_new, UniformRand}, + ff::{field_new, Fp, UniformRand}, pairing::{test::assert_valid_pairing_ratio, Pairing}, r1cs_std::eq::EqGadget, ratio::test::assert_valid_ratio_proof, @@ -44,7 +45,7 @@ use manta_crypto::{ }, rand::{CryptoRng, OsRng, RngCore, Sample}, }; -use manta_pay::crypto::constraint::arkworks::{Fp, FpVar, R1CS}; +use manta_pay::crypto::constraint::arkworks::FpVar; use manta_util::into_array_unchecked; /// Test MPC From 8e4b4e53c7b50f2d42d06fa22f2621b7d5b5305a Mon Sep 17 00:00:00 2001 From: Todd Norton Date: Fri, 9 Sep 2022 01:15:16 +0200 Subject: [PATCH 06/10] fix: changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a9d30ddc6..4cdade55b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ## [Unreleased] ### Added +- [\#248](https://github.com/Manta-Network/manta-rs/pull/248) Move Fp and R1CS to manta-crypto - [\#237](https://github.com/Manta-Network/manta-rs/pull/237) Public input fuzzing tests for transfer protocol - [\#215](https://github.com/Manta-Network/manta-rs/pull/215) Add windowed multiplication algorithm for groups - [\#213](https://github.com/Manta-Network/manta-rs/pull/197) Add Ceremony Utilities From d1a1a40cc4a20905e34dbe34a0e47093996910e2 Mon Sep 17 00:00:00 2001 From: Todd Norton Date: Mon, 12 Sep 2022 15:33:01 +0200 Subject: [PATCH 07/10] wip: move R1CS --- manta-pay/src/crypto/poseidon/arkworks.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manta-pay/src/crypto/poseidon/arkworks.rs b/manta-pay/src/crypto/poseidon/arkworks.rs index b94e849a9..3a75d60f2 100644 --- a/manta-pay/src/crypto/poseidon/arkworks.rs +++ b/manta-pay/src/crypto/poseidon/arkworks.rs @@ -17,7 +17,6 @@ //! Poseidon Arkworks Backend use crate::crypto::{ - constraint::arkworks::{FpVar, R1CS}, poseidon::{ self, encryption::BlockElement, hash::DomainTag, Constants, Field, FieldGeneration, ParameterFieldType, @@ -25,6 +24,7 @@ use crate::crypto::{ }; use manta_crypto::{ arkworks::{ + constraint::{FpVar, R1CS}, ff::{BigInteger, Field as _, Fp, FpParameters, PrimeField}, r1cs_std::fields::FieldVar, }, From 4ef56d64af8ec55a744f787f13e5e8bd952a55f1 Mon Sep 17 00:00:00 2001 From: Todd Norton Date: Mon, 12 Sep 2022 15:34:38 +0200 Subject: [PATCH 08/10] fmt --- manta-pay/src/crypto/poseidon/arkworks.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/manta-pay/src/crypto/poseidon/arkworks.rs b/manta-pay/src/crypto/poseidon/arkworks.rs index 3a75d60f2..0befd58de 100644 --- a/manta-pay/src/crypto/poseidon/arkworks.rs +++ b/manta-pay/src/crypto/poseidon/arkworks.rs @@ -16,11 +16,9 @@ //! Poseidon Arkworks Backend -use crate::crypto::{ - poseidon::{ - self, encryption::BlockElement, hash::DomainTag, Constants, Field, FieldGeneration, - ParameterFieldType, - }, +use crate::crypto::poseidon::{ + self, encryption::BlockElement, hash::DomainTag, Constants, Field, FieldGeneration, + ParameterFieldType, }; use manta_crypto::{ arkworks::{ From f6fe9cadd8c3ea2898f89669773f70d2a29edd77 Mon Sep 17 00:00:00 2001 From: Todd Norton Date: Mon, 12 Sep 2022 20:40:30 +0200 Subject: [PATCH 09/10] feat: finish moving FpVar out of manta-pay --- manta-pay/src/config.rs | 3 ++- manta-pay/src/crypto/constraint/arkworks/groth16.rs | 2 +- manta-pay/src/crypto/constraint/arkworks/mod.rs | 4 ++-- manta-pay/src/crypto/ecc/arkworks.rs | 8 +++++++- manta-pay/src/crypto/poseidon/compat.rs | 3 ++- manta-trusted-setup/src/groth16/test/mod.rs | 3 +-- 6 files changed, 15 insertions(+), 8 deletions(-) diff --git a/manta-pay/src/config.rs b/manta-pay/src/config.rs index 2008ede5a..60e454f96 100644 --- a/manta-pay/src/config.rs +++ b/manta-pay/src/config.rs @@ -17,7 +17,7 @@ //! Manta-Pay Configuration use crate::crypto::{ - constraint::arkworks::{groth16, Boolean, FpVar, R1CS}, + constraint::arkworks::{groth16, Boolean, R1CS}, // TODO: Move R1CS with Groth16 ecc, encryption::aes::{self, FixedNonceAesGcm}, key::Blake2sKdf, @@ -37,6 +37,7 @@ use manta_crypto::{ algebra::DiffieHellman, arkworks::{ bls12_381::{self, Bls12_381}, + constraint::FpVar, ed_on_bls12_381::{self, constraints::EdwardsVar as Bls12_381_EdwardsVar}, ff::{field_element_as_bytes, Fp, ToConstraintField}, serialize::{CanonicalDeserialize, CanonicalSerialize, SerializationError}, diff --git a/manta-pay/src/crypto/constraint/arkworks/groth16.rs b/manta-pay/src/crypto/constraint/arkworks/groth16.rs index 709519d0d..bed7c0878 100644 --- a/manta-pay/src/crypto/constraint/arkworks/groth16.rs +++ b/manta-pay/src/crypto/constraint/arkworks/groth16.rs @@ -19,7 +19,7 @@ use crate::crypto::constraint::arkworks::{ self, codec::{HasDeserialization, HasSerialization, SerializationError}, - R1CS, + R1CS, // TODO: Move with Groth16 }; use alloc::vec::Vec; use ark_groth16::{Groth16 as ArkGroth16, PreparedVerifyingKey, ProvingKey}; diff --git a/manta-pay/src/crypto/constraint/arkworks/mod.rs b/manta-pay/src/crypto/constraint/arkworks/mod.rs index ad7da27ec..225dc7e7d 100644 --- a/manta-pay/src/crypto/constraint/arkworks/mod.rs +++ b/manta-pay/src/crypto/constraint/arkworks/mod.rs @@ -18,6 +18,7 @@ use manta_crypto::{ arkworks::{ + constraint::FpVar, ff::{Fp, FpParameters, PrimeField}, r1cs_std::{ alloc::AllocVar, eq::EqGadget, fields::FieldVar, select::CondSelectGadget, ToBitsGadget, @@ -45,8 +46,7 @@ use manta_crypto::{ }; pub use manta_crypto::arkworks::{ - r1cs_std::{bits::boolean::Boolean, fields::fp::FpVar}, - relations::r1cs::SynthesisError, + r1cs_std::bits::boolean::Boolean, relations::r1cs::SynthesisError, }; pub mod codec; diff --git a/manta-pay/src/crypto/ecc/arkworks.rs b/manta-pay/src/crypto/ecc/arkworks.rs index e928c2252..3bb365e33 100644 --- a/manta-pay/src/crypto/ecc/arkworks.rs +++ b/manta-pay/src/crypto/ecc/arkworks.rs @@ -17,7 +17,12 @@ //! Arkworks Elliptic Curve Primitives use crate::crypto::constraint::arkworks::{ - self, conditionally_select, empty, full, Boolean, FpVar, R1CS, + self, + conditionally_select, + empty, + full, + Boolean, + R1CS, // TODO: Move R1CS with Groth16 }; use alloc::vec::Vec; use core::{borrow::Borrow, marker::PhantomData}; @@ -26,6 +31,7 @@ use manta_crypto::{ algebra::FixedBaseScalarMul, arkworks::{ algebra::{affine_point_as_bytes, modulus_is_smaller}, + constraint::FpVar, ec::{AffineCurve, ProjectiveCurve}, ff::{BigInteger, Field, Fp, PrimeField, Zero as _}, r1cs_std::{groups::CurveVar, ToBitsGadget}, diff --git a/manta-pay/src/crypto/poseidon/compat.rs b/manta-pay/src/crypto/poseidon/compat.rs index ad5c3dd2c..3a65d5c16 100644 --- a/manta-pay/src/crypto/poseidon/compat.rs +++ b/manta-pay/src/crypto/poseidon/compat.rs @@ -327,9 +327,10 @@ pub type Output = #[cfg(feature = "arkworks")] #[cfg_attr(doc_cfg, doc(cfg(feature = "arkworks")))] pub mod arkworks { - use crate::crypto::constraint::arkworks::{FpVar, R1CS}; + use crate::crypto::constraint::arkworks::R1CS; use manta_crypto::{ arkworks::{ + constraint::FpVar, ff::{Field, Fp, PrimeField}, r1cs_std::fields::FieldVar, }, diff --git a/manta-trusted-setup/src/groth16/test/mod.rs b/manta-trusted-setup/src/groth16/test/mod.rs index b22af78a5..e74c8ec10 100644 --- a/manta-trusted-setup/src/groth16/test/mod.rs +++ b/manta-trusted-setup/src/groth16/test/mod.rs @@ -31,7 +31,7 @@ use blake2::Digest; use manta_crypto::{ arkworks::{ bn254::{Bn254, Fr, G1Affine, G2Affine}, - constraint::R1CS, + constraint::{FpVar, R1CS}, ec::{AffineCurve, PairingEngine}, ff::{field_new, Fp, UniformRand}, pairing::Pairing, @@ -45,7 +45,6 @@ use manta_crypto::{ }, rand::{CryptoRng, OsRng, RngCore, Sample}, }; -use manta_pay::crypto::constraint::arkworks::FpVar; use manta_util::into_array_unchecked; /// Test MPC From a982d322c56f3008054e661949589da0cc9b97b6 Mon Sep 17 00:00:00 2001 From: Todd Norton Date: Mon, 12 Sep 2022 21:07:15 +0200 Subject: [PATCH 10/10] remove comments --- manta-pay/src/crypto/constraint/arkworks/groth16.rs | 3 --- manta-pay/src/crypto/constraint/arkworks/mod.rs | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/manta-pay/src/crypto/constraint/arkworks/groth16.rs b/manta-pay/src/crypto/constraint/arkworks/groth16.rs index bed7c0878..5740b718e 100644 --- a/manta-pay/src/crypto/constraint/arkworks/groth16.rs +++ b/manta-pay/src/crypto/constraint/arkworks/groth16.rs @@ -35,9 +35,6 @@ use manta_crypto::{ }; use manta_util::codec::{self, DecodeError}; -// #[cfg(feature = "scale")] -// use crate::crypto::ecc::arkworks::Group; - #[cfg(feature = "serde")] use manta_util::serde::{Deserialize, Serialize, Serializer}; diff --git a/manta-pay/src/crypto/constraint/arkworks/mod.rs b/manta-pay/src/crypto/constraint/arkworks/mod.rs index 225dc7e7d..afbda99aa 100644 --- a/manta-pay/src/crypto/constraint/arkworks/mod.rs +++ b/manta-pay/src/crypto/constraint/arkworks/mod.rs @@ -451,7 +451,7 @@ where /// Testing Suite #[cfg(test)] mod tests { - // move to constraint with R1CS + // TODO: move to constraint with R1CS use super::*; use core::iter::repeat_with; use manta_crypto::{