diff --git a/CHANGELOG.md b/CHANGELOG.md index b6dd5f731..e0fa57d5c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ - Derive `Debug`, `Snafu` on `enum TaggedBlobError` - Updated `tagged-base64` reference url to reflect the Espresso Systems name change - Add `HashToGroup` support for both SW and TE curves +- `#[tagged_blob(...)]` macro now supports `const` variables in addition to string literals ### Bugfixes diff --git a/plonk/Cargo.toml b/plonk/Cargo.toml index 9ee5f2799..7372e8f98 100644 --- a/plonk/Cargo.toml +++ b/plonk/Cargo.toml @@ -30,6 +30,7 @@ derivative = { version = "2", features = ["use_core"] } num-bigint = { version = "0.4", default-features = false} rand_chacha = { version = "0.3.1" } sha3 = "^0.10" +espresso-systems-common = { git = "https://github.com/espressosystems/espresso-systems-common", tag = "0.1.1" } [dependencies.ark-poly-commit] diff --git a/plonk/src/proof_system/structs.rs b/plonk/src/proof_system/structs.rs index 3748cba4e..4849d8558 100644 --- a/plonk/src/proof_system/structs.rs +++ b/plonk/src/proof_system/structs.rs @@ -37,6 +37,7 @@ use ark_std::{ vec, vec::Vec, }; +use espresso_systems_common::jellyfish as tag; use jf_rescue::RescueParameter; use jf_utils::{field_switching, fq_to_fr, fr_to_fq, tagged_blob}; @@ -57,7 +58,7 @@ pub(crate) type CommitKey<'a, E> = Powers<'a, E>; pub type OpenKey = VerifierKey; /// A Plonk SNARK proof. -#[tagged_blob("PROOF")] +#[tagged_blob(tag::PROOF)] #[derive(Debug, Clone, PartialEq, Eq, CanonicalSerialize, CanonicalDeserialize, Derivative)] #[derivative(Hash(bound = "E:PairingEngine"))] pub struct Proof { @@ -232,7 +233,7 @@ pub struct PlookupProof { } /// An aggregated SNARK proof that batchly proving multiple instances. -#[tagged_blob("BATCHPROOF")] +#[tagged_blob(tag::BATCHPROOF)] #[derive(Debug, Clone, PartialEq, Eq, CanonicalSerialize, CanonicalDeserialize, Derivative)] #[derivative(Hash(bound = "E:PairingEngine"))] pub struct BatchProof { diff --git a/primitives/Cargo.toml b/primitives/Cargo.toml index 899769aaf..ad58361ca 100644 --- a/primitives/Cargo.toml +++ b/primitives/Cargo.toml @@ -37,6 +37,7 @@ derivative = { version = "2", features = ["use_core"] } rand_chacha = { version = "0.3.1", default-features = false } sha2 = { version = "0.10.1", default-features = false } digest = { version = "0.10.1", default-features = false } +espresso-systems-common = { git = "https://github.com/espressosystems/espresso-systems-common", tag = "0.1.1" } [dev-dependencies] rand_chacha = "^0.3" diff --git a/primitives/src/merkle_tree.rs b/primitives/src/merkle_tree.rs index fe83dd53f..a1211ed12 100644 --- a/primitives/src/merkle_tree.rs +++ b/primitives/src/merkle_tree.rs @@ -29,6 +29,7 @@ use ark_std::{ vec::Vec, }; use core::{convert::TryFrom, fmt::Debug}; +use espresso_systems_common::jellyfish as tag; use jf_rescue::{Permutation, RescueParameter}; use jf_utils::tagged_blob; use serde::{Deserialize, Serialize}; @@ -189,7 +190,7 @@ impl MerklePath { } /// Represents the value for a node in the merkle tree. -#[tagged_blob("NODE")] +#[tagged_blob(tag::NODE)] #[derive( Clone, Debug, PartialEq, Eq, Hash, Default, CanonicalSerialize, CanonicalDeserialize, Copy, )] @@ -817,7 +818,7 @@ where } /// Data struct for a merkle leaf. -#[tagged_blob("LEAF")] +#[tagged_blob(tag::LEAF)] #[derive( Clone, Debug, PartialEq, Eq, Hash, Default, CanonicalSerialize, CanonicalDeserialize, Copy, )] diff --git a/primitives/src/signatures/bls.rs b/primitives/src/signatures/bls.rs index 5fda9b4f8..986a17de6 100644 --- a/primitives/src/signatures/bls.rs +++ b/primitives/src/signatures/bls.rs @@ -19,6 +19,7 @@ use ark_std::{ One, UniformRand, }; use core::marker::PhantomData; +use espresso_systems_common::jellyfish as tag; use jf_utils::{multi_pairing, tagged_blob}; /// BLS signature scheme. @@ -28,14 +29,14 @@ pub struct BLSSignatureScheme { } /// BLS public verification key -#[tagged_blob("BLSVERKEY")] +#[tagged_blob(tag::BLSVERKEY)] #[derive(CanonicalSerialize, CanonicalDeserialize, Derivative)] #[derivative(Clone(bound = "P: Bls12Parameters"))] #[derivative(Default(bound = "P: Bls12Parameters"))] pub struct BLSVerKey(pub(crate) GroupAffine); /// Signing key for BLS signature. -#[tagged_blob("BLSSIGNINGKEY")] +#[tagged_blob(tag::BLSSIGNINGKEY)] #[derive(CanonicalSerialize, CanonicalDeserialize, Derivative)] #[derivative(Clone(bound = "P: Bls12Parameters"))] #[derivative(Default(bound = "P: Bls12Parameters"))] @@ -44,7 +45,7 @@ pub struct BLSSignKey( ); /// Signing key for BLS signature. -#[tagged_blob("BLSSIG")] +#[tagged_blob(tag::BLSSIG)] #[derive(CanonicalSerialize, CanonicalDeserialize, Derivative)] #[derivative(Clone(bound = "P: Bls12Parameters"))] #[derivative(Default(bound = "P: Bls12Parameters"))] diff --git a/primitives/src/signatures/schnorr.rs b/primitives/src/signatures/schnorr.rs index 0d8db3294..bb543925e 100644 --- a/primitives/src/signatures/schnorr.rs +++ b/primitives/src/signatures/schnorr.rs @@ -23,6 +23,7 @@ use ark_std::{ string::ToString, vec, }; +use espresso_systems_common::jellyfish as tag; use jf_rescue::{Permutation, RescueParameter}; use jf_utils::{fq_to_fr, fq_to_fr_with_mask, fr_to_fq, tagged_blob}; use zeroize::Zeroize; @@ -120,7 +121,7 @@ impl SignKey { /// Signature public verification key // derive zeroize here so that keypair can be zeroized -#[tagged_blob("SCHNORRVERKEY")] +#[tagged_blob(tag::SCHNORRVERKEY)] #[derive(Clone, CanonicalSerialize, CanonicalDeserialize, Derivative)] #[derivative(Debug(bound = "P: Parameters"))] #[derivative(Default(bound = "P: Parameters"))] @@ -186,7 +187,7 @@ impl VerKey

{ /// Signature secret key pair used to sign messages // make sure sk can be zeroized -#[tagged_blob("SIGNKEYPAIR")] +#[tagged_blob(tag::SIGNKEYPAIR)] #[derive(Clone, Default, CanonicalSerialize, CanonicalDeserialize, PartialEq, Derivative)] #[derivative(Debug(bound = "P: Parameters"))] pub struct KeyPair

@@ -202,7 +203,7 @@ where // ===================================================== /// The signature of Schnorr signature scheme -#[tagged_blob("SIG")] +#[tagged_blob(tag::SIG)] #[derive(Clone, Eq, CanonicalSerialize, CanonicalDeserialize, Derivative)] #[derivative(Debug(bound = "P: Parameters"))] #[derivative(Default(bound = "P: Parameters"))] diff --git a/utilities/Cargo.toml b/utilities/Cargo.toml index 959786df6..5f254c106 100644 --- a/utilities/Cargo.toml +++ b/utilities/Cargo.toml @@ -30,6 +30,8 @@ ark-ed-on-bls12-381-bandersnatch = { git = "https://github.com/arkworks-rs/curve ark-bn254 = { version = "0.3.0", default-features = false, features = ["curve"] } ark-bls12-377 = { git = "https://github.com/arkworks-rs/curves", rev = "677b4ae751a274037880ede86e9b6f30f62635af" } ark-bls12-381 = { version = "0.3.0", default-features = false, features = ["curve"] } +ark-serialize = { version = "0.3.0", default-features = false, features = ["derive"] } +serde_json = "1.0" [features] std = [] diff --git a/utilities/src/lib.rs b/utilities/src/lib.rs index 47888e263..b23ef47c9 100644 --- a/utilities/src/lib.rs +++ b/utilities/src/lib.rs @@ -4,7 +4,7 @@ // You should have received a copy of the MIT License // along with the Jellyfish library. If not, see . -#![no_std] +#![cfg_attr(not(test), no_std)] mod conversion; mod macros; diff --git a/utilities/src/serialize.rs b/utilities/src/serialize.rs index 442f27740..d10638fe6 100644 --- a/utilities/src/serialize.rs +++ b/utilities/src/serialize.rs @@ -205,6 +205,39 @@ pub mod tagged_blob { let bytes = deserialize_with_tag(T::tag().as_str(), deserializer)?; Ok((bytes, Default::default())) } + + #[cfg(test)] + mod test { + use crate as jf_utils; + use ark_serialize::*; + use jf_utils::tagged_blob; + use std::vec::Vec; + + #[tagged_blob("A")] + #[derive(Debug, Clone, PartialEq, Eq, CanonicalDeserialize, CanonicalSerialize)] + pub struct A(Vec); + + #[test] + fn test_tagged_blob_static_str() { + let a = A(Vec::new()); + let str = serde_json::to_string(&a).unwrap(); + assert_eq!(str, r#""A~AAAAAAAAAABr""#); + } + + mod tags { + pub const B: &str = "B"; + } + #[tagged_blob(tags::B)] + #[derive(Debug, Clone, PartialEq, Eq, CanonicalDeserialize, CanonicalSerialize)] + pub struct B(Vec); + + #[test] + fn test_tagged_blob_const_str() { + let b = B(Vec::new()); + let str = serde_json::to_string(&b).unwrap(); + assert_eq!(str, r#""B~AAAAAAAAAADg""#); + } + } } /// Serializers for finite field elements. diff --git a/utilities_derive/src/lib.rs b/utilities_derive/src/lib.rs index 38a2e27b7..585bf4f76 100644 --- a/utilities_derive/src/lib.rs +++ b/utilities_derive/src/lib.rs @@ -11,7 +11,7 @@ extern crate proc_macro; use ark_std::format; use proc_macro::TokenStream; use quote::quote; -use syn::{parse_macro_input, AttributeArgs, Item, NestedMeta}; +use syn::{parse_macro_input, AttributeArgs, Item, Meta, NestedMeta}; /// Derive serdes for a type which serializes as a binary blob. /// @@ -89,9 +89,10 @@ pub fn tagged_blob(args: TokenStream, input: TokenStream) -> TokenStream { _ => panic!("expected struct or enum"), }; let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); - let tag = match args.as_slice() { + let tag: &dyn quote::ToTokens = match args.as_slice() { [NestedMeta::Lit(tag)] => tag, - _ => panic!("tagged_blob takes one argument, the tag, as a string literal"), + [NestedMeta::Meta(Meta::Path(path))] => path, + x => panic!("tagged_blob takes one argument, the tag, as a string literal or expression, found {:?}", x), }; let serde_str = format!("jf_utils::TaggedBlob<{}>", quote!(#name #ty_generics)); let output = quote! {