Skip to content

Commit

Permalink
add partial_fulfillment_vp (de)serialization and add partial_fulfillm…
Browse files Browse the repository at this point in the history
…ent_vp to vp_bytecode
  • Loading branch information
XuyangSong committed Dec 5, 2023
1 parent 8836296 commit 9642c29
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 20 deletions.
14 changes: 13 additions & 1 deletion taiga_halo2/src/circuit/vp_bytecode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
use crate::circuit::vp_examples::TrivialValidityPredicateCircuit;
#[cfg(feature = "examples")]
use crate::circuit::vp_examples::{
partial_fulfillment_intent::PartialFulfillmentIntentValidityPredicateCircuit,
receiver_vp::ReceiverValidityPredicateCircuit,
signature_verification::SignatureVerificationValidityPredicateCircuit,
token::TokenValidityPredicateCircuit,
Expand Down Expand Up @@ -40,7 +41,8 @@ pub enum ValidityPredicateRepresentation {
Token,
SignatureVerification,
Receiver,
// TODO: add other vp types here if needed
PartialFulfillmentIntent,
// Add other native vp types here if needed
}

#[derive(Clone, Debug)]
Expand Down Expand Up @@ -98,6 +100,11 @@ impl ValidityPredicateByteCode {
let vp = ReceiverValidityPredicateCircuit::from_bytes(&self.inputs);
Ok(vp.get_verifying_info())
}
#[cfg(feature = "examples")]
ValidityPredicateRepresentation::PartialFulfillmentIntent => {
let vp = PartialFulfillmentIntentValidityPredicateCircuit::from_bytes(&self.inputs);
Ok(vp.get_verifying_info())
}
#[allow(unreachable_patterns)]
_ => Err(TransactionError::InvalidValidityPredicateRepresentation),
}
Expand Down Expand Up @@ -143,6 +150,11 @@ impl ValidityPredicateByteCode {
let vp = ReceiverValidityPredicateCircuit::from_bytes(&self.inputs);
vp.verify_transparently()?
}
#[cfg(feature = "examples")]
ValidityPredicateRepresentation::PartialFulfillmentIntent => {
let vp = PartialFulfillmentIntentValidityPredicateCircuit::from_bytes(&self.inputs);
vp.verify_transparently()?
}
#[allow(unreachable_patterns)]
_ => return Err(TransactionError::InvalidValidityPredicateRepresentation),
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use crate::{
sub::{SubChip, SubInstructions},
target_resource_variable::{get_is_input_resource_flag, get_owned_resource_variable},
},
vp_bytecode::{ValidityPredicateByteCode, ValidityPredicateRepresentation},
vp_circuit::{
BasicValidityPredicateVariables, VPVerifyingInfo, ValidityPredicateCircuit,
ValidityPredicateConfig, ValidityPredicatePublicInputs, ValidityPredicateVerifyingInfo,
Expand All @@ -23,12 +24,13 @@ use crate::{
vp_commitment::ValidityPredicateCommitment,
vp_vk::ValidityPredicateVerifyingKey,
};
use borsh::{BorshDeserialize, BorshSerialize};
use halo2_proofs::{
circuit::{floor_planner, Layouter},
plonk::{keygen_pk, keygen_vk, Circuit, ConstraintSystem, Error},
};
use lazy_static::lazy_static;
use pasta_curves::pallas;
use pasta_curves::{group::ff::PrimeField, pallas};
use rand::rngs::OsRng;
use rand::RngCore;

Expand All @@ -54,6 +56,23 @@ pub struct PartialFulfillmentIntentValidityPredicateCircuit {
pub swap: Swap,
}

impl PartialFulfillmentIntentValidityPredicateCircuit {
pub fn to_bytecode(&self) -> ValidityPredicateByteCode {
ValidityPredicateByteCode::new(
ValidityPredicateRepresentation::PartialFulfillmentIntent,
self.to_bytes(),
)
}

pub fn to_bytes(&self) -> Vec<u8> {
borsh::to_vec(&self).unwrap()
}

pub fn from_bytes(bytes: &Vec<u8>) -> Self {
BorshDeserialize::deserialize(&mut bytes.as_ref()).unwrap()
}
}

impl ValidityPredicateCircuit for PartialFulfillmentIntentValidityPredicateCircuit {
// Add custom constraints
fn custom_constraints(
Expand Down Expand Up @@ -178,6 +197,49 @@ impl ValidityPredicateCircuit for PartialFulfillmentIntentValidityPredicateCircu
vp_circuit_impl!(PartialFulfillmentIntentValidityPredicateCircuit);
vp_verifying_info_impl!(PartialFulfillmentIntentValidityPredicateCircuit);

impl BorshSerialize for PartialFulfillmentIntentValidityPredicateCircuit {
fn serialize<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
writer.write_all(&self.owned_resource_id.to_repr())?;
for input in self.input_resources.iter() {
input.serialize(writer)?;
}

for output in self.output_resources.iter() {
output.serialize(writer)?;
}

self.swap.serialize(writer)?;

Ok(())
}
}

impl BorshDeserialize for PartialFulfillmentIntentValidityPredicateCircuit {
fn deserialize_reader<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self> {
let owned_resource_id_bytes = <[u8; 32]>::deserialize_reader(reader)?;
let owned_resource_id = Option::from(pallas::Base::from_repr(owned_resource_id_bytes))
.ok_or_else(|| {
std::io::Error::new(
std::io::ErrorKind::InvalidData,
"owned_resource_id not in field",
)
})?;
let input_resources: Vec<_> = (0..NUM_RESOURCE)
.map(|_| Resource::deserialize_reader(reader))
.collect::<Result<_, _>>()?;
let output_resources: Vec<_> = (0..NUM_RESOURCE)
.map(|_| Resource::deserialize_reader(reader))
.collect::<Result<_, _>>()?;
let swap = Swap::deserialize_reader(reader)?;
Ok(Self {
owned_resource_id,
input_resources: input_resources.try_into().unwrap(),
output_resources: output_resources.try_into().unwrap(),
swap,
})
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down Expand Up @@ -278,6 +340,13 @@ mod tests {
output_resources,
swap,
};

// Test serialization
let circuit = {
let circuit_bytes = circuit.to_bytes();
PartialFulfillmentIntentValidityPredicateCircuit::from_bytes(&circuit_bytes)
};

let public_inputs = circuit.get_public_inputs(&mut rng);

let prover = MockProver::<pallas::Base>::run(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use crate::{
resource::Resource,
utils::poseidon_hash_n,
};
use borsh::{BorshDeserialize, BorshSerialize};
use halo2_proofs::arithmetic::Field;
use halo2_proofs::{
circuit::{Layouter, Value},
Expand All @@ -16,7 +17,7 @@ use halo2_proofs::{
use pasta_curves::pallas;
use rand::RngCore;

#[derive(Clone, Debug, Default)]
#[derive(Clone, Debug, Default, BorshSerialize, BorshDeserialize)]
pub struct Swap {
pub sell: TokenResource,
pub buy: Token,
Expand Down
47 changes: 30 additions & 17 deletions taiga_halo2/src/circuit/vp_examples/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ impl TokenName {
}
}

#[derive(Clone, Debug, Default)]
#[derive(Clone, Debug, Default, BorshSerialize, BorshDeserialize)]
pub struct Token {
name: TokenName,
quantity: u64,
Expand Down Expand Up @@ -147,7 +147,7 @@ impl Token {
}
}

#[derive(Clone, Debug, Default)]
#[derive(Clone, Debug, Default, BorshDeserialize, BorshSerialize)]
pub struct TokenResource {
pub token_name: TokenName,
pub resource: Resource,
Expand Down Expand Up @@ -537,9 +537,7 @@ impl BorshSerialize for TokenValidityPredicateCircuit {
}

self.token_name.serialize(writer)?;

writer.write_all(&self.auth.pk.to_bytes())?;
writer.write_all(&self.auth.vk.to_repr())?;
self.auth.serialize(writer)?;
writer.write_all(&self.receiver_vp_vk.to_repr())?;
self.rseed.serialize(writer)?;

Expand All @@ -564,18 +562,7 @@ impl BorshDeserialize for TokenValidityPredicateCircuit {
.map(|_| Resource::deserialize_reader(reader))
.collect::<Result<_, _>>()?;
let token_name = TokenName::deserialize_reader(reader)?;
let pk_bytes = <[u8; 32]>::deserialize_reader(reader)?;
let pk = Option::from(pallas::Point::from_bytes(&pk_bytes)).ok_or_else(|| {
std::io::Error::new(
std::io::ErrorKind::InvalidData,
"owned_resource_id not in point",
)
})?;
let vk_bytes = <[u8; 32]>::deserialize_reader(reader)?;
let vk = Option::from(pallas::Base::from_repr(vk_bytes)).ok_or_else(|| {
std::io::Error::new(std::io::ErrorKind::InvalidData, "vk not in field")
})?;
let auth = TokenAuthorization { pk, vk };
let auth = TokenAuthorization::deserialize_reader(reader)?;
let receiver_vp_vk_bytes = <[u8; 32]>::deserialize_reader(reader)?;
let receiver_vp_vk = Option::from(pallas::Base::from_repr(receiver_vp_vk_bytes))
.ok_or_else(|| {
Expand All @@ -597,6 +584,32 @@ impl BorshDeserialize for TokenValidityPredicateCircuit {
}
}

impl BorshSerialize for TokenAuthorization {
fn serialize<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
writer.write_all(&self.pk.to_bytes())?;
writer.write_all(&self.vk.to_repr())?;
Ok(())
}
}

impl BorshDeserialize for TokenAuthorization {
fn deserialize_reader<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self> {
let pk_bytes = <[u8; 32]>::deserialize_reader(reader)?;
let pk = Option::from(pallas::Point::from_bytes(&pk_bytes)).ok_or_else(|| {
std::io::Error::new(
std::io::ErrorKind::InvalidData,
"owned_resource_id not in point",
)
})?;
let vk_bytes = <[u8; 32]>::deserialize_reader(reader)?;
let vk = Option::from(pallas::Base::from_repr(vk_bytes)).ok_or_else(|| {
std::io::Error::new(std::io::ErrorKind::InvalidData, "vk not in field")
})?;

Ok(Self { pk, vk })
}
}

impl TokenAuthorization {
pub fn new(pk: pallas::Point, vk: pallas::Base) -> Self {
Self { pk, vk }
Expand Down

0 comments on commit 9642c29

Please sign in to comment.