Skip to content

Commit

Permalink
add sig_verification_vp (de)serialization and add sig_verification_vp…
Browse files Browse the repository at this point in the history
… to vp_bytecode
  • Loading branch information
XuyangSong committed Dec 5, 2023
1 parent f3ad0cb commit f3d3b30
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 4 deletions.
18 changes: 16 additions & 2 deletions taiga_halo2/src/circuit/vp_bytecode.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
#[cfg(feature = "examples")]
use crate::circuit::vp_examples::token::TokenValidityPredicateCircuit;
#[cfg(feature = "borsh")]
use crate::circuit::vp_examples::TrivialValidityPredicateCircuit;
#[cfg(feature = "examples")]
use crate::circuit::vp_examples::{
signature_verification::SignatureVerificationValidityPredicateCircuit,
token::TokenValidityPredicateCircuit,
};
use crate::error::TransactionError;
use crate::shielded_ptx::ResourceVPVerifyingInfoSet;
use crate::{
Expand Down Expand Up @@ -34,6 +37,7 @@ pub enum ValidityPredicateRepresentation {
// TODO: figure out if we can have a unified circuit presentation. In theory, it's possible to separate the circuit system and proving system.
Trivial,
Token,
SignatureVerification,
// TODO: add other vp types here if needed
}

Expand Down Expand Up @@ -82,6 +86,11 @@ impl ValidityPredicateByteCode {
let vp = TokenValidityPredicateCircuit::from_bytes(&self.inputs);
Ok(vp.get_verifying_info())
}
#[cfg(feature = "examples")]
ValidityPredicateRepresentation::SignatureVerification => {
let vp = SignatureVerificationValidityPredicateCircuit::from_bytes(&self.inputs);
Ok(vp.get_verifying_info())
}
#[allow(unreachable_patterns)]
_ => Err(TransactionError::InvalidValidityPredicateRepresentation),
}
Expand Down Expand Up @@ -117,6 +126,11 @@ impl ValidityPredicateByteCode {
let vp = TokenValidityPredicateCircuit::from_bytes(&self.inputs);
vp.verify_transparently()?
}
#[cfg(feature = "examples")]
ValidityPredicateRepresentation::SignatureVerification => {
let vp = SignatureVerificationValidityPredicateCircuit::from_bytes(&self.inputs);
vp.verify_transparently()?
}
#[allow(unreachable_patterns)]
_ => return Err(TransactionError::InvalidValidityPredicateRepresentation),
};
Expand Down
113 changes: 112 additions & 1 deletion taiga_halo2/src/circuit/vp_examples/signature_verification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::{
assign_free_advice, poseidon_hash::poseidon_hash_gadget,
target_resource_variable::get_owned_resource_variable,
},
vp_bytecode::{ValidityPredicateByteCode, ValidityPredicateRepresentation},
vp_circuit::{
BasicValidityPredicateVariables, VPVerifyingInfo, ValidityPredicateCircuit,
ValidityPredicateConfig, ValidityPredicatePublicInputs, ValidityPredicateVerifyingInfo,
Expand All @@ -18,6 +19,7 @@ use crate::{
vp_commitment::ValidityPredicateCommitment,
vp_vk::ValidityPredicateVerifyingKey,
};
use borsh::{BorshDeserialize, BorshSerialize};
use halo2_gadgets::ecc::{chip::EccChip, FixedPoint, NonIdentityPoint, ScalarFixed, ScalarVar};
use halo2_proofs::{
arithmetic::Field,
Expand All @@ -27,7 +29,7 @@ use halo2_proofs::{
use lazy_static::lazy_static;
use pasta_curves::{
arithmetic::CurveAffine,
group::{Curve, Group},
group::{ff::PrimeField, Curve, Group, GroupEncoding},
pallas,
};
use rand::rngs::OsRng;
Expand Down Expand Up @@ -149,6 +151,21 @@ impl SignatureVerificationValidityPredicateCircuit {
receiver_vp_vk,
}
}

pub fn to_bytecode(&self) -> ValidityPredicateByteCode {
ValidityPredicateByteCode::new(
ValidityPredicateRepresentation::SignatureVerification,
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 SignatureVerificationValidityPredicateCircuit {
Expand Down Expand Up @@ -288,6 +305,93 @@ impl ValidityPredicateCircuit for SignatureVerificationValidityPredicateCircuit
vp_circuit_impl!(SignatureVerificationValidityPredicateCircuit);
vp_verifying_info_impl!(SignatureVerificationValidityPredicateCircuit);

impl BorshSerialize for SignatureVerificationValidityPredicateCircuit {
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)?;
}

writer.write_all(&self.vp_vk.to_repr())?;
self.signature.serialize(writer)?;
writer.write_all(&self.receiver_vp_vk.to_repr())?;

Ok(())
}
}

impl BorshDeserialize for SignatureVerificationValidityPredicateCircuit {
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 vp_vk_bytes = <[u8; 32]>::deserialize_reader(reader)?;
let vp_vk = Option::from(pallas::Base::from_repr(vp_vk_bytes)).ok_or_else(|| {
std::io::Error::new(std::io::ErrorKind::InvalidData, "vp_vk not in field")
})?;
let signature = SchnorrSignature::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(|| {
std::io::Error::new(
std::io::ErrorKind::InvalidData,
"receiver_vp_vk not in field",
)
})?;
Ok(Self {
owned_resource_id,
input_resources: input_resources.try_into().unwrap(),
output_resources: output_resources.try_into().unwrap(),
vp_vk,
signature,
receiver_vp_vk,
})
}
}

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

Ok(())
}
}

impl BorshDeserialize for SchnorrSignature {
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, "pk not in point")
})?;
let r_bytes = <[u8; 32]>::deserialize_reader(reader)?;
let r = Option::from(pallas::Point::from_bytes(&r_bytes)).ok_or_else(|| {
std::io::Error::new(std::io::ErrorKind::InvalidData, "r not in point")
})?;
let s_bytes = <[u8; 32]>::deserialize_reader(reader)?;
let s = Option::from(pallas::Scalar::from_repr(s_bytes)).ok_or_else(|| {
std::io::Error::new(std::io::ErrorKind::InvalidData, "s not in field")
})?;
Ok(Self { pk, r, s })
}
}

#[test]
fn test_halo2_sig_verification_vp_circuit() {
use crate::circuit::vp_examples::{
Expand Down Expand Up @@ -317,6 +421,13 @@ fn test_halo2_sig_verification_vp_circuit() {
*COMPRESSED_RECEIVER_VK,
)
};

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

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

let prover = MockProver::<pallas::Base>::run(
Expand Down
2 changes: 1 addition & 1 deletion taiga_halo2/src/circuit/vp_examples/token.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use crate::circuit::vp_bytecode::{ValidityPredicateByteCode, ValidityPredicateRepresentation};
use crate::{
circuit::{
blake2s::{vp_commitment_gadget, Blake2sChip},
Expand All @@ -7,6 +6,7 @@ use crate::{
poseidon_hash::poseidon_hash_gadget,
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 Down

0 comments on commit f3d3b30

Please sign in to comment.