diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index c4ecfe8..93ba2a4 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -51,6 +51,30 @@ jobs: command: fmt args: --all -- --check + no-std: + name: no_std compatibility check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + override: true + - uses: Swatinem/rust-cache@v1 + - uses: actions-rs/cargo@v1 + with: + command: check + args: --no-default-features --features r1cs + - uses: actions-rs/cargo@v1 + with: + command: build + args: --no-default-features --features r1cs + - uses: actions-rs/cargo@v1 + with: + command: test + args: --no-default-features --features r1cs + # clippy: # name: Clippy # runs-on: ubuntu-latest diff --git a/CHANGELOG.md b/CHANGELOG.md index 35d4488..e75f768 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,3 +27,7 @@ # 0.6.0 * Fix: Resolve incorrect `SubAssign` and `AddAssign` implementations in R1CS. + +# 0.7.0 + +* Fix: Add `no_std` compatibility. diff --git a/Cargo.toml b/Cargo.toml index f19a8c3..32c131d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "decaf377" -version = "0.6.0" +version = "0.7.0" authors = ["Henry de Valence ", "redshiftzero "] description = "A prime-order group designed for use in SNARKs over BLS12-377" edition = "2018" @@ -9,13 +9,12 @@ license = "MIT OR Apache-2.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -thiserror = "1" -hex = "0.4" -num-bigint = "0.4" -once_cell = "1.8" -tracing = "0.1" -tracing-subscriber = "0.2" -anyhow = "1.0" +hex = {version ="=0.4.2", default-features=false} +num-bigint = {version= "0.4.4", default-features=false} +once_cell = {version= "1.8", default-features=false} +tracing = {version = "0.1", default-features=false} +tracing-subscriber = {version = "0.3", default-features=false } +anyhow = {version ="1.0", default-features=false} ark-relations = "0.4" ark-r1cs-std = { version = "0.4", optional=true, default-features=false } ark-std = { version = "0.4", default-features=false } @@ -26,14 +25,15 @@ ark-bls12-377 = "0.4" ark-ed-on-bls12-377 = { version = "0.4", features = ["r1cs"] } ark-groth16 = { version = "0.4", default-features=false, optional=true } ark-snark = { version = "0.4", optional=true } -zeroize = "1.4" +zeroize = {version ="1.7", default-features=false} +hashbrown = "0.14.3" # This matches what ark-std (a library for no_std compatibility) does, having # a default feature of std - without the ark-std std feature, decaf377 doesn't # compile [features] default = ["std"] -std = ["ark-std/std"] +std = ["ark-std/std", "tracing/std", "anyhow/std", "tracing-subscriber/std", "zeroize/std", "once_cell/std", "num-bigint/std", "hex/std" ] parallel = ["ark-ff/parallel", "ark-ec/parallel", "ark-groth16/parallel", "ark-std/parallel", "ark-r1cs-std/parallel"] r1cs = ["ark-r1cs-std", "ark-groth16", "ark-snark"] diff --git a/src/element.rs b/src/element.rs index 901c8ee..c15f0b0 100644 --- a/src/element.rs +++ b/src/element.rs @@ -5,6 +5,7 @@ use ark_ec::{ use ark_ed_on_bls12_377::EdwardsConfig; use ark_ff::MontFp; use ark_serialize::Valid; +use ark_std::vec::Vec; use crate::{ constants::{GENERATOR_X, GENERATOR_Y}, diff --git a/src/element/affine.rs b/src/element/affine.rs index a24af34..bfb8cb9 100644 --- a/src/element/affine.rs +++ b/src/element/affine.rs @@ -1,4 +1,4 @@ -use std::hash::Hash; +use core::hash::Hash; use crate::element::EdwardsAffine; use ark_std::fmt::{Display, Formatter, Result as FmtResult}; @@ -14,7 +14,7 @@ pub struct AffineElement { } impl Hash for AffineElement { - fn hash(&self, state: &mut H) { + fn hash(&self, state: &mut H) { self.inner.hash(state); } } @@ -46,8 +46,8 @@ impl PartialEq for AffineElement { impl Eq for AffineElement {} -impl std::fmt::Debug for AffineElement { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl core::fmt::Debug for AffineElement { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { let element: Element = self.into(); f.write_fmt(format_args!( "decaf377::AffineElement({})", diff --git a/src/element/projective.rs b/src/element/projective.rs index fff6285..cfdcef6 100644 --- a/src/element/projective.rs +++ b/src/element/projective.rs @@ -1,5 +1,5 @@ -use std::borrow::Borrow; -use std::hash::Hash; +use core::borrow::Borrow; +use core::hash::Hash; use ark_ff::Zero; use ark_std::fmt::{Display, Formatter, Result as FmtResult}; @@ -14,13 +14,13 @@ pub struct Element { } impl Hash for Element { - fn hash(&self, state: &mut H) { + fn hash(&self, state: &mut H) { self.inner.hash(state); } } -impl std::fmt::Debug for Element { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl core::fmt::Debug for Element { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { // This prints the hex of the encoding of self, rather than the // coordinates, because that's what's most useful to downstream // consumers of the library. diff --git a/src/encoding.rs b/src/encoding.rs index 91dd627..1e42db9 100644 --- a/src/encoding.rs +++ b/src/encoding.rs @@ -1,6 +1,6 @@ #![allow(non_snake_case)] -use std::convert::{TryFrom, TryInto}; +use core::convert::{TryFrom, TryInto}; use ark_ec::twisted_edwards::TECurveConfig; use ark_ff::{Field, One}; @@ -14,8 +14,8 @@ use crate::{ #[derive(Copy, Clone, Default, Eq, Ord, PartialOrd, PartialEq)] pub struct Encoding(pub [u8; 32]); -impl std::fmt::Debug for Encoding { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl core::fmt::Debug for Encoding { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { f.write_fmt(format_args!( "decaf377::Encoding({})", hex::encode(&self.0[..]) diff --git a/src/error.rs b/src/error.rs index 04223bb..a8261c7 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,9 +1,20 @@ -use thiserror::Error; +use ark_std::error::Error; -#[derive(Error, Debug)] +#[derive(Debug)] pub enum EncodingError { - #[error("Invalid Decaf377 encoding")] InvalidEncoding, - #[error("Invalid length bytes in encoded point")] InvalidSliceLength, } + +impl core::fmt::Display for EncodingError { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + let msg = match self { + Self::InvalidEncoding => "Invalid Decaf377 encoding", + Self::InvalidSliceLength => "Invalid length bytes in encoded point", + }; + + msg.fmt(f) + } +} + +impl Error for EncodingError {} diff --git a/src/invsqrt.rs b/src/invsqrt.rs index e203574..6b1667f 100644 --- a/src/invsqrt.rs +++ b/src/invsqrt.rs @@ -1,8 +1,10 @@ -use std::collections::HashMap; -use std::convert::TryInto; +use core::convert::TryInto; +use hashbrown::HashMap; use ark_ed_on_bls12_377::Fq; use ark_ff::{BigInteger256, BigInteger64, Field, Zero}; +use ark_std::boxed::Box; +use ark_std::vec::Vec; 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}; diff --git a/src/lib.rs b/src/lib.rs index c1817c4..d286b95 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,4 @@ +#![no_std] //! `decaf377` [instantiates Decaf over the BLS12-377 scalar //! field](https://penumbra.zone/crypto/primitives/decaf377.html). diff --git a/src/r1cs.rs b/src/r1cs.rs index 6558132..76fa76f 100644 --- a/src/r1cs.rs +++ b/src/r1cs.rs @@ -6,6 +6,7 @@ pub mod ops; pub use ark_ed_on_bls12_377::constraints::FqVar; use ark_ff::ToConstraintField; +use ark_std::vec::Vec; pub use element::ElementVar; use crate::{Element, Fq}; diff --git a/src/r1cs/element.rs b/src/r1cs/element.rs index 65c58a1..464c995 100644 --- a/src/r1cs/element.rs +++ b/src/r1cs/element.rs @@ -1,10 +1,11 @@ #![allow(non_snake_case)] -use std::borrow::Borrow; +use core::borrow::Borrow; use ark_ec::AffineRepr; use ark_ed_on_bls12_377::constraints::FqVar; use ark_r1cs_std::{alloc::AllocVar, eq::EqGadget, prelude::*, R1CSVar}; use ark_relations::r1cs::{ConstraintSystemRef, SynthesisError}; +use ark_std::vec::Vec; use crate::r1cs::lazy::LazyElementVar; use crate::{element::EdwardsAffine, r1cs::inner::ElementVar as InnerElementVar}; @@ -125,7 +126,7 @@ impl CondSelectGadget for ElementVar { // This lets us use `new_constant`, `new_input` (public), or `new_witness` to add // decaf elements to an R1CS constraint system. impl AllocVar for ElementVar { - fn new_variable>( + fn new_variable>( cs: impl Into>, f: impl FnOnce() -> Result, mode: AllocationMode, diff --git a/src/r1cs/inner.rs b/src/r1cs/inner.rs index 89aeab5..29112f7 100644 --- a/src/r1cs/inner.rs +++ b/src/r1cs/inner.rs @@ -1,6 +1,6 @@ #![allow(non_snake_case)] -use std::borrow::Borrow; -use std::ops::{Add, AddAssign, Sub, SubAssign}; +use core::borrow::Borrow; +use core::ops::{Add, AddAssign, Sub, SubAssign}; use ark_ec::{twisted_edwards::TECurveConfig, AffineRepr}; use ark_ed_on_bls12_377::constraints::FqVar; @@ -9,6 +9,7 @@ use ark_r1cs_std::{ }; use ark_relations::ns; use ark_relations::r1cs::{ConstraintSystemRef, SynthesisError}; +use ark_std::vec::Vec; use crate::element::EdwardsAffine; use crate::Decaf377EdwardsConfig; @@ -230,7 +231,7 @@ impl CondSelectGadget for ElementVar { // This lets us use `new_constant`, `new_input` (public), or `new_witness` to add // decaf elements to an R1CS constraint system. impl AllocVar for ElementVar { - fn new_variable>( + fn new_variable>( cs: impl Into>, f: impl FnOnce() -> Result, mode: AllocationMode, diff --git a/src/r1cs/lazy.rs b/src/r1cs/lazy.rs index 7f2ea91..6a400d3 100644 --- a/src/r1cs/lazy.rs +++ b/src/r1cs/lazy.rs @@ -1,4 +1,4 @@ -use std::cell::RefCell; +use core::cell::RefCell; use ark_relations::r1cs::SynthesisError; diff --git a/src/r1cs/ops.rs b/src/r1cs/ops.rs index 54a5691..b1ce49d 100644 --- a/src/r1cs/ops.rs +++ b/src/r1cs/ops.rs @@ -1,4 +1,4 @@ -use std::ops::{Add, AddAssign, Sub, SubAssign}; +use core::ops::{Add, AddAssign, Sub, SubAssign}; use crate::{r1cs::element::ElementVar, Element}; diff --git a/src/serialize.rs b/src/serialize.rs index ab18e12..e20139a 100644 --- a/src/serialize.rs +++ b/src/serialize.rs @@ -1,4 +1,4 @@ -use std::convert::TryInto; +use core::convert::TryInto; use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; use ark_std::io::{Read, Write}; diff --git a/tests/encoding.rs b/tests/encoding.rs index 93e76a5..f7cf359 100644 --- a/tests/encoding.rs +++ b/tests/encoding.rs @@ -1,4 +1,4 @@ -use std::convert::TryFrom; +use core::convert::TryFrom; use proptest::prelude::*;