Skip to content

Commit

Permalink
Merge branch 'vasily/serde'
Browse files Browse the repository at this point in the history
  • Loading branch information
mariari committed Aug 30, 2023
2 parents cba8398 + c497f01 commit cc04b0c
Show file tree
Hide file tree
Showing 12 changed files with 301 additions and 62 deletions.
15 changes: 10 additions & 5 deletions taiga_halo2/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,16 @@ dyn-clone = "1.0"
reddsa = {git = "https://github.com/heliaxdev/reddsa.git", branch = "taiga"}
vamp-ir = { git = "https://github.com/anoma/vamp-ir.git", rev = "6d401f8a479951727586ef0c44c42edab3139090"}
bincode = "2.0.0-rc.3"
borsh = { version = "0.10", features = ["const-generics"] }
byteorder = "1.4"
num-bigint = "0.4"

serde = { version = "1.0", features = ["derive"], optional = true }
borsh = { version = "0.10", features = ["const-generics"], optional = true }

[dev-dependencies]
criterion = "0.5"
proptest = "1.2"

[features]
default = []
nif = ["rustler", "pasta_curves/repr-erlang"]
serde_json = "1.0"

[[bench]]
name = "action_proof"
Expand All @@ -44,3 +43,9 @@ harness = false

[[example]]
name = "tx_examples"

[features]
default = ["borsh", "serde"]
nif = ["rustler", "pasta_curves/repr-erlang"]
serde = ["dep:serde", "pasta_curves/serde"]
borsh = ["dep:borsh"]
16 changes: 12 additions & 4 deletions taiga_halo2/src/action.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,22 @@ use crate::{
nullifier::Nullifier,
value_commitment::ValueCommitment,
};
use borsh::{BorshDeserialize, BorshSerialize};
use ff::PrimeField;
use halo2_proofs::arithmetic::Field;
use pasta_curves::pallas;
use rand::RngCore;
#[cfg(feature = "nif")]
use rustler::NifStruct;
use std::io;
#[cfg(feature = "serde")]
use serde;

#[cfg(feature = "borsh")]
use borsh::{BorshDeserialize, BorshSerialize};

/// The action result used in transaction.
#[derive(Copy, Debug, Clone)]
#[cfg_attr(feature = "nif", derive(NifStruct))]
#[cfg_attr(feature = "nif", module = "Taiga.Action.Instance")]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct ActionInstance {
/// The root of the note commitment Merkle tree.
pub anchor: pallas::Base,
Expand Down Expand Up @@ -50,8 +53,10 @@ impl ActionInstance {
}
}

#[cfg(feature = "borsh")]
impl BorshSerialize for ActionInstance {
fn serialize<W: std::io::Write>(&self, writer: &mut W) -> borsh::maybestd::io::Result<()> {
use ff::PrimeField;
writer.write_all(&self.anchor.to_repr())?;
writer.write_all(&self.nf.to_bytes())?;
writer.write_all(&self.cm_x.to_repr())?;
Expand All @@ -60,8 +65,11 @@ impl BorshSerialize for ActionInstance {
}
}

#[cfg(feature = "borsh")]
impl BorshDeserialize for ActionInstance {
fn deserialize_reader<R: io::Read>(reader: &mut R) -> io::Result<Self> {
fn deserialize_reader<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self> {
use ff::PrimeField;
use std::io;
let anchor_bytes = <[u8; 32]>::deserialize_reader(reader)?;
let anchor = Option::from(pallas::Base::from_repr(anchor_bytes))
.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "anchor not in field"))?;
Expand Down
22 changes: 17 additions & 5 deletions taiga_halo2/src/binding_signature.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
use crate::constant::NOTE_COMMITMENT_R_GENERATOR;
use borsh::{BorshDeserialize, BorshSerialize};
use pasta_curves::group::cofactor::CofactorCurveAffine;
use pasta_curves::group::{ff::PrimeField, GroupEncoding};
use pasta_curves::pallas;
use rand::{CryptoRng, RngCore};
use reddsa::{private, Error, SigType, Signature, SigningKey, VerificationKey};
use std::io;

#[cfg(feature = "serde")]
use serde;

#[cfg(feature = "borsh")]
use borsh::{BorshDeserialize, BorshSerialize};

#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum TaigaBinding {}
Expand All @@ -29,12 +33,15 @@ impl private::Sealed<TaigaBinding> for TaigaBinding {
impl SigType for TaigaBinding {}

#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct BindingSignature(Signature<TaigaBinding>);

#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct BindingSigningKey(SigningKey<TaigaBinding>);

#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct BindingVerificationKey(VerificationKey<TaigaBinding>);

impl BindingSignature {
Expand All @@ -48,14 +55,16 @@ impl BindingSignature {
}
}

#[cfg(feature = "borsh")]
impl BorshSerialize for BindingSignature {
fn serialize<W: std::io::Write>(&self, writer: &mut W) -> borsh::maybestd::io::Result<()> {
fn serialize<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
writer.write_all(&self.to_bytes())
}
}

#[cfg(feature = "borsh")]
impl BorshDeserialize for BindingSignature {
fn deserialize_reader<R: io::Read>(reader: &mut R) -> io::Result<Self> {
fn deserialize_reader<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self> {
let mut sig_bytes = [0u8; 64];
reader.read_exact(&mut sig_bytes)?;
Ok(Self::from_bytes(sig_bytes))
Expand All @@ -81,14 +90,17 @@ impl BindingSigningKey {
}
}

#[cfg(feature = "borsh")]
impl BorshSerialize for BindingSigningKey {
fn serialize<W: std::io::Write>(&self, writer: &mut W) -> borsh::maybestd::io::Result<()> {
writer.write_all(&self.to_bytes())
}
}

#[cfg(feature = "borsh")]
impl BorshDeserialize for BindingSigningKey {
fn deserialize_reader<R: io::Read>(reader: &mut R) -> io::Result<Self> {
fn deserialize_reader<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self> {
use std::io;
let mut key_bytes = [0u8; 32];
reader.read_exact(&mut key_bytes)?;
Self::from_bytes(key_bytes).map_err(|_| {
Expand Down
90 changes: 86 additions & 4 deletions taiga_halo2/src/circuit/vp_circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,8 @@ use crate::{
utils::mod_r_p,
vp_vk::ValidityPredicateVerifyingKey,
};
use borsh::{BorshDeserialize, BorshSerialize};
use dyn_clone::{clone_trait_object, DynClone};
use ff::PrimeField;
//use ff::PrimeField;
use group::cofactor::CofactorCurveAffine;
use halo2_gadgets::{ecc::chip::EccChip, sinsemilla::chip::SinsemillaChip};
use halo2_proofs::{
Expand All @@ -47,14 +46,20 @@ use pasta_curves::{pallas, vesta, EqAffine, Fp};
use rand::{rngs::OsRng, RngCore};
use std::collections::HashMap;
use std::fs;
use std::io;
//use std::io;
use std::path::PathBuf;
use std::rc::Rc;
use vamp_ir::ast::Module;
use vamp_ir::halo2::synth::{make_constant, Halo2Module, PrimeFieldOps};
use vamp_ir::transform::compile;
use vamp_ir::util::{read_inputs_from_file, Config};

#[cfg(feature = "serde")]
use serde;

#[cfg(feature = "borsh")]
use borsh::{BorshDeserialize, BorshSerialize};

#[cfg(feature = "nif")]
use rustler::types::atom;
#[cfg(feature = "nif")]
Expand All @@ -63,7 +68,15 @@ use rustler::{Decoder, Encoder, Env, NifResult, Term};
pub type ValidityPredicate = dyn ValidityPredicateVerifyingInfo;

#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct VPVerifyingInfo {
#[cfg_attr(
feature = "serde",
serde(
serialize_with = "serde_serialize_verifying_key",
deserialize_with = "serde_deserialize_verifying_key"
)
)]
pub vk: VerifyingKey<vesta::Affine>,
pub proof: Proof,
pub public_inputs: ValidityPredicatePublicInputs,
Expand Down Expand Up @@ -111,6 +124,7 @@ impl<'a> Decoder<'a> for VPVerifyingInfo {
}

#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct ValidityPredicatePublicInputs([pallas::Base; VP_CIRCUIT_PUBLIC_INPUT_NUM]);

#[cfg(feature = "nif")]
Expand Down Expand Up @@ -160,8 +174,10 @@ impl VPVerifyingInfo {
}
}

#[cfg(feature = "borsh")]
impl BorshSerialize for VPVerifyingInfo {
fn serialize<W: std::io::Write>(&self, writer: &mut W) -> borsh::maybestd::io::Result<()> {
use ff::PrimeField;
// Write vk
self.vk.write(writer)?;
// Write proof
Expand All @@ -174,8 +190,11 @@ impl BorshSerialize for VPVerifyingInfo {
}
}

#[cfg(feature = "borsh")]
impl BorshDeserialize for VPVerifyingInfo {
fn deserialize_reader<R: io::Read>(reader: &mut R) -> io::Result<Self> {
fn deserialize_reader<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self> {
use ff::PrimeField;
use std::io;
// Read vk
use crate::circuit::vp_examples::TrivialValidityPredicateCircuit;
let params = SETUP_PARAMS_MAP.get(&VP_CIRCUIT_PARAMS_SIZE).unwrap();
Expand All @@ -199,6 +218,34 @@ impl BorshDeserialize for VPVerifyingInfo {
}
}

#[cfg(feature = "serde")]
fn serde_serialize_verifying_key<S>(
x: &VerifyingKey<vesta::Affine>,
s: S,
) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let mut buf = Vec::new();
x.write(&mut buf).unwrap();
s.serialize_bytes(&buf)
}

#[cfg(feature = "serde")]
fn serde_deserialize_verifying_key<'de, D>(d: D) -> Result<VerifyingKey<vesta::Affine>, D::Error>
where
D: serde::Deserializer<'de>,
{
use serde::de::Error;
let buf: Vec<u8> = serde::Deserialize::deserialize(d)?;

use crate::circuit::vp_examples::TrivialValidityPredicateCircuit;
let params = SETUP_PARAMS_MAP.get(&VP_CIRCUIT_PARAMS_SIZE).unwrap();
let vk = VerifyingKey::read::<_, TrivialValidityPredicateCircuit>(&mut buf.as_slice(), params)
.map_err(|e| Error::custom(format!("Error reading VerifyingKey: {}", e)))?;
Ok(vk)
}

impl ValidityPredicatePublicInputs {
pub fn inner(&self) -> &[pallas::Base; VP_CIRCUIT_PUBLIC_INPUT_NUM] {
&self.0
Expand Down Expand Up @@ -1039,4 +1086,39 @@ mod tests {
)
.is_err());
}

#[cfg(feature = "serde")]
#[test]
fn test_vk_serialize() {
use crate::circuit::{
vp_circuit::{serde_deserialize_verifying_key, serde_serialize_verifying_key},
vp_examples::TrivialValidityPredicateCircuit,
};
use halo2_proofs::plonk::VerifyingKey;
use pasta_curves::vesta;
use serde_json;

#[derive(serde::Serialize, serde::Deserialize)]
struct TestStruct {
#[serde(
serialize_with = "serde_serialize_verifying_key",
deserialize_with = "serde_deserialize_verifying_key"
)]
vk: VerifyingKey<vesta::Affine>,
}

let t = TrivialValidityPredicateCircuit::default().get_vp_vk();

let a = TestStruct {
vk: t.get_vk().unwrap(),
};

let ser = serde_json::to_string(&a).unwrap();
let deser: TestStruct = serde_json::from_str(&ser).unwrap();

let a_bytes = a.vk.to_bytes();
let deser_bytes = deser.vk.to_bytes();

assert_eq!(a_bytes, deser_bytes);
}
}
22 changes: 18 additions & 4 deletions taiga_halo2/src/merkle_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,25 @@ use std::hash::{Hash, Hasher};

use crate::utils::poseidon_hash;
use crate::{constant::TAIGA_COMMITMENT_TREE_DEPTH, note::Note};
use borsh::{BorshDeserialize, BorshSerialize};
use ff::PrimeField;
use halo2_proofs::arithmetic::Field;
use pasta_curves::pallas;
use rand::{Rng, RngCore};

use crate::merkle_tree::LR::{L, R};
use rand::distributions::{Distribution, Standard};

#[derive(Clone, Debug, PartialEq, Eq, Copy, Hash, Default, BorshSerialize, BorshDeserialize)]
#[cfg(feature = "borsh")]
use ff::PrimeField;

#[cfg(feature = "serde")]
use serde;

#[cfg(feature = "borsh")]
use borsh::{BorshDeserialize, BorshSerialize};

#[derive(Clone, Debug, PartialEq, Eq, Copy, Hash, Default)]
#[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum LR {
R,
#[default]
Expand Down Expand Up @@ -44,7 +53,9 @@ impl Distribution<LR> for Standard {

/// A path from a position in a particular commitment tree to the root of that tree.
/// In Orchard merkle tree, they are using MerkleCRH(layer, left, right), where MerkleCRH is a sinsemilla. We are using poseidon_hash(left, right).
#[derive(Clone, Debug, PartialEq, Eq, Hash, BorshSerialize, BorshDeserialize)]
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct MerklePath {
merkle_path: Vec<(Node, LR)>,
}
Expand Down Expand Up @@ -92,6 +103,7 @@ impl Default for MerklePath {

/// A node within the Sapling commitment tree.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Node(pallas::Base);

impl Node {
Expand All @@ -116,13 +128,15 @@ impl Node {
}
}

#[cfg(feature = "borsh")]
impl BorshSerialize for Node {
fn serialize<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
writer.write_all(&self.0.to_repr())?;
Ok(())
}
}

#[cfg(feature = "borsh")]
impl BorshDeserialize for Node {
fn deserialize_reader<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self> {
let mut repr = [0u8; 32];
Expand Down
Loading

0 comments on commit cc04b0c

Please sign in to comment.