Skip to content

Commit

Permalink
update transparent ptx and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
XuyangSong committed Aug 23, 2024
1 parent c89faee commit 5acbb08
Show file tree
Hide file tree
Showing 9 changed files with 108 additions and 161 deletions.
4 changes: 2 additions & 2 deletions taiga_halo2/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ subtle = { version = "2.3", default-features = false }
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"
bincode = "1.3.3"
byteorder = "1.4"
num-bigint = "0.4"

Expand Down Expand Up @@ -47,7 +47,7 @@ name = "tx_examples"
required-features = ["examples"]

[features]
default = []
default = ["serde"]
nif = ["dep:rustler", "borsh", "pasta_curves/repr-erlang"]
serde = ["dep:serde", "pasta_curves/serde"]
borsh = ["dep:borsh"]
Expand Down
48 changes: 10 additions & 38 deletions taiga_halo2/src/circuit/resource_logic_bytecode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,9 @@ use crate::{
ResourceLogicVerifyingInfo, ResourceLogicVerifyingInfoTrait, VampIRResourceLogicCircuit,
},
constant::{
RESOURCE_LOGIC_CIRCUIT_NULLIFIER_ONE_PUBLIC_INPUT_IDX,
RESOURCE_LOGIC_CIRCUIT_NULLIFIER_TWO_PUBLIC_INPUT_IDX,
RESOURCE_LOGIC_CIRCUIT_OUTPUT_CM_ONE_PUBLIC_INPUT_IDX,
RESOURCE_LOGIC_CIRCUIT_OUTPUT_CM_TWO_PUBLIC_INPUT_IDX,
RESOURCE_LOGIC_CIRCUIT_RESOURCE_MERKLE_ROOT_IDX,
RESOURCE_LOGIC_CIRCUIT_SELF_RESOURCE_ID_IDX,
},
nullifier::Nullifier,
resource::ResourceCommitment,
};

#[cfg(feature = "borsh")]
Expand Down Expand Up @@ -131,8 +126,7 @@ impl ResourceLogicByteCode {
// Verify resource_logic circuit transparently and return self resource id for further checking
pub fn verify_transparently(
&self,
compliance_nfs: &[Nullifier],
compliance_cms: &[ResourceCommitment],
compliance_resource_merkle_root: &pallas::Base,
) -> Result<pallas::Base, TransactionError> {
// check resource logic transparently
let public_inputs = match &self.circuit {
Expand Down Expand Up @@ -189,33 +183,12 @@ impl ResourceLogicByteCode {
_ => return Err(TransactionError::InvalidResourceLogicRepresentation),
};

// check nullifiers
// Check the resource_logic actually uses the input resources from compliance circuits.
let resource_logic_nfs = [
public_inputs.get_from_index(RESOURCE_LOGIC_CIRCUIT_NULLIFIER_ONE_PUBLIC_INPUT_IDX),
public_inputs.get_from_index(RESOURCE_LOGIC_CIRCUIT_NULLIFIER_TWO_PUBLIC_INPUT_IDX),
];
// check resource merkle root
let logic_resource_merkle_root =
public_inputs.get_from_index(RESOURCE_LOGIC_CIRCUIT_RESOURCE_MERKLE_ROOT_IDX);

if !((compliance_nfs[0].inner() == resource_logic_nfs[0]
&& compliance_nfs[1].inner() == resource_logic_nfs[1])
|| (compliance_nfs[0].inner() == resource_logic_nfs[1]
&& compliance_nfs[1].inner() == resource_logic_nfs[0]))
{
return Err(TransactionError::InconsistentNullifier);
}

// check resource_commitments
// Check the resource_logic actually uses the output resources from compliance circuits.
let resource_logic_cms = [
public_inputs.get_from_index(RESOURCE_LOGIC_CIRCUIT_OUTPUT_CM_ONE_PUBLIC_INPUT_IDX),
public_inputs.get_from_index(RESOURCE_LOGIC_CIRCUIT_OUTPUT_CM_TWO_PUBLIC_INPUT_IDX),
];
if !((compliance_cms[0].inner() == resource_logic_cms[0]
&& compliance_cms[1].inner() == resource_logic_cms[1])
|| (compliance_cms[0].inner() == resource_logic_cms[1]
&& compliance_cms[1].inner() == resource_logic_cms[0]))
{
return Err(TransactionError::InconsistentOutputResourceCommitment);
if logic_resource_merkle_root != *compliance_resource_merkle_root {
return Err(TransactionError::InconsistentResourceMerkleRoot);
}

Ok(public_inputs.get_from_index(RESOURCE_LOGIC_CIRCUIT_SELF_RESOURCE_ID_IDX))
Expand Down Expand Up @@ -251,14 +224,13 @@ impl ApplicationByteCode {
// Verify resource_logic circuits transparently and return owned resource PubID for further checking
pub fn verify_transparently(
&self,
compliance_nfs: &[Nullifier],
compliance_cms: &[ResourceCommitment],
compliance_root: &pallas::Base,
) -> Result<pallas::Base, TransactionError> {
let self_resource_id = self
.app_resource_logic_bytecode
.verify_transparently(compliance_nfs, compliance_cms)?;
.verify_transparently(compliance_root)?;
for dynamic_resource_logic in self.dynamic_resource_logic_bytecode.iter() {
let id = dynamic_resource_logic.verify_transparently(compliance_nfs, compliance_cms)?;
let id = dynamic_resource_logic.verify_transparently(compliance_root)?;
// check: the app_resource_logic and dynamic_resource_logics belong to the resource
if id != self_resource_id {
return Err(TransactionError::InconsistentSelfResourceID);
Expand Down
43 changes: 3 additions & 40 deletions taiga_halo2/src/circuit/resource_logic_examples.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ lazy_static! {

// TrivialResourceLogicCircuit with empty custom constraints.
#[derive(Clone, Debug, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct TrivialResourceLogicCircuit {
self_resource: ResourceExistenceWitness,
}
Expand All @@ -85,50 +86,12 @@ impl TrivialResourceLogicCircuit {
ResourceLogicByteCode::new(ResourceLogicRepresentation::Trivial, self.to_bytes())
}

// Only for test
#[cfg(feature = "borsh")]
pub fn to_bytes(&self) -> Vec<u8> {
borsh::to_vec(&self).unwrap()
bincode::serialize(&self).unwrap()
}

// Only for test
#[cfg(feature = "borsh")]
pub fn from_bytes(bytes: &Vec<u8>) -> Self {
BorshDeserialize::deserialize(&mut bytes.as_ref()).unwrap()
}
}

#[cfg(feature = "borsh")]
impl BorshSerialize for TrivialResourceLogicCircuit {
fn serialize<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
use ff::PrimeField;
writer.write_all(&self.self_resource_id.to_repr())?;
for input in self.input_resources.iter() {
input.serialize(writer)?;
}

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

#[cfg(feature = "borsh")]
impl BorshDeserialize for TrivialResourceLogicCircuit {
fn deserialize_reader<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self> {
let self_resource_id = crate::utils::read_base_field(reader)?;
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<_, _>>()?;
Ok(Self {
self_resource_id,
input_resources: input_resources.try_into().unwrap(),
output_resources: output_resources.try_into().unwrap(),
})
bincode::deserialize(bytes).unwrap()
}
}

Expand Down
7 changes: 1 addition & 6 deletions taiga_halo2/src/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,7 @@ pub const RESOURCE_LOGIC_CIRCUIT_CUSTOM_PUBLIC_INPUT_NUM: usize = 2;
pub const RESOURCE_LOGIC_CIRCUIT_RESOURCE_ENCRYPTION_PUBLIC_INPUT_NUM: usize =
RESOURCE_ENCRYPTION_CIPHERTEXT_NUM + 2; // ciphertext(12) + public_key(2)

// TODO: Get rid of the outdated indexs
pub const RESOURCE_LOGIC_CIRCUIT_NULLIFIER_ONE_PUBLIC_INPUT_IDX: usize = 0;
pub const RESOURCE_LOGIC_CIRCUIT_OUTPUT_CM_ONE_PUBLIC_INPUT_IDX: usize = 1;
pub const RESOURCE_LOGIC_CIRCUIT_NULLIFIER_TWO_PUBLIC_INPUT_IDX: usize = 2;
pub const RESOURCE_LOGIC_CIRCUIT_OUTPUT_CM_TWO_PUBLIC_INPUT_IDX: usize = 3;

// resource logic public input index
pub const RESOURCE_LOGIC_CIRCUIT_RESOURCE_MERKLE_ROOT_IDX: usize = 0;
pub const RESOURCE_LOGIC_CIRCUIT_SELF_RESOURCE_ID_IDX: usize = 1;
pub const RESOURCE_LOGIC_CIRCUIT_FIRST_DYNAMIC_RESOURCE_LOGIC_CM_1: usize = 2;
Expand Down
15 changes: 13 additions & 2 deletions taiga_halo2/src/executable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use pasta_curves::pallas;

use crate::{
delta_commitment::DeltaCommitment, error::TransactionError, merkle_tree::Anchor,
nullifier::Nullifier, resource::ResourceCommitment,
nullifier::Nullifier, resource::ResourceCommitment, resource_tree::ResourceMerkleTreeLeaves,
};

// Executable is an unified interface for partial transaction, which is the atomic executable uinit.
Expand All @@ -12,5 +12,16 @@ pub trait Executable {
fn get_output_cms(&self) -> Vec<ResourceCommitment>;
fn get_delta_commitments(&self) -> Vec<DeltaCommitment>;
fn get_anchors(&self) -> Vec<Anchor>;
fn get_resource_merkle_root(&self) -> pallas::Base;
fn get_resource_merkle_root(&self) -> pallas::Base {
let mut leaves = vec![];
self.get_nullifiers()
.iter()
.zip(self.get_output_cms())
.for_each(|(nf, cm)| {
leaves.push(nf.inner());
leaves.push(cm.inner());
});
let tree = ResourceMerkleTreeLeaves::new(leaves);
tree.root()
}
}
1 change: 1 addition & 0 deletions taiga_halo2/src/resource_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use crate::{
use pasta_curves::pallas;

#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct ResourceExistenceWitness {
resource: Resource,
merkle_path: [(pallas::Base, LR); TAIGA_RESOURCE_TREE_DEPTH],
Expand Down
14 changes: 0 additions & 14 deletions taiga_halo2/src/shielded_ptx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ use crate::merkle_tree::Anchor;
use crate::nullifier::Nullifier;
use crate::proof::Proof;
use crate::resource::{ResourceCommitment, ResourceLogics};
use crate::resource_tree::ResourceMerkleTreeLeaves;
use halo2_proofs::plonk::Error;
use pasta_curves::pallas;
use rand::RngCore;
Expand Down Expand Up @@ -303,19 +302,6 @@ impl Executable for ShieldedPartialTransaction {
.map(|compliance| compliance.compliance_instance.anchor)
.collect()
}

fn get_resource_merkle_root(&self) -> pallas::Base {
let mut leaves = vec![];
self.get_nullifiers()
.iter()
.zip(self.get_output_cms())
.for_each(|(nf, cm)| {
leaves.push(nf.inner());
leaves.push(cm.inner());
});
let tree = ResourceMerkleTreeLeaves::new(leaves);
tree.root()
}
}

#[cfg(feature = "borsh")]
Expand Down
64 changes: 37 additions & 27 deletions taiga_halo2/src/taiga_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ pub fn verify_shielded_partial_transaction(ptx_bytes: Vec<u8>) -> Result<(), Tra
pub mod tests {
use crate::{
nullifier::tests::random_nullifier_key_commitment, resource::tests::random_resource,
taiga_api::*,
resource_tree::ResourceMerkleTreeLeaves, taiga_api::*,
};
use rand::rngs::OsRng;

Expand Down Expand Up @@ -264,7 +264,6 @@ pub mod tests {

// construct resources
let input_resource_1 = random_resource(&mut rng);
let input_resource_1_nf = input_resource_1.get_nf().unwrap();
let mut output_resource_1 = random_resource(&mut rng);
let merkle_path_1 = MerklePath::random(&mut rng, TAIGA_COMMITMENT_TREE_DEPTH);
let compliance_1 = ComplianceInfo::new(
Expand All @@ -276,7 +275,6 @@ pub mod tests {
);

let input_resource_2 = random_resource(&mut rng);
let input_resource_2_nf = input_resource_2.get_nf().unwrap();
let mut output_resource_2 = random_resource(&mut rng);
let merkle_path_2 = MerklePath::random(&mut rng, TAIGA_COMMITMENT_TREE_DEPTH);
let compliance_2 = ComplianceInfo::new(
Expand All @@ -287,45 +285,57 @@ pub mod tests {
&mut rng,
);

// Collect resource merkle leaves
let input_resource_nf_1 = input_resource_1.get_nf().unwrap().inner();
let output_resource_cm_1 = output_resource_1.commitment().inner();
let input_resource_nf_2 = input_resource_2.get_nf().unwrap().inner();
let output_resource_cm_2 = output_resource_2.commitment().inner();
let resource_merkle_tree = ResourceMerkleTreeLeaves::new(vec![
input_resource_nf_1,
output_resource_cm_1,
input_resource_nf_2,
output_resource_cm_2,
]);

// construct applications
let input_resource_1_app = {
let app_resource_logic = TrivialResourceLogicCircuit::new(
input_resource_1_nf.inner(),
[input_resource_1, input_resource_2],
[output_resource_1, output_resource_2],
);
let input_resource_path_1 = resource_merkle_tree
.generate_path(input_resource_nf_1)
.unwrap();
let input_resource_application_logic_1 =
TrivialResourceLogicCircuit::new(input_resource_1, input_resource_path_1);

ApplicationByteCode::new(app_resource_logic.to_bytecode(), vec![])
ApplicationByteCode::new(input_resource_application_logic_1.to_bytecode(), vec![])
};

let input_resource_2_app = {
let app_resource_logic = TrivialResourceLogicCircuit::new(
input_resource_2_nf.inner(),
[input_resource_1, input_resource_2],
[output_resource_1, output_resource_2],
);
let input_resource_path_2 = resource_merkle_tree
.generate_path(input_resource_nf_2)
.unwrap();
let input_resource_application_logic_2 =
TrivialResourceLogicCircuit::new(input_resource_2, input_resource_path_2);

ApplicationByteCode::new(app_resource_logic.to_bytecode(), vec![])
ApplicationByteCode::new(input_resource_application_logic_2.to_bytecode(), vec![])
};

let output_resource_1_app = {
let app_resource_logic = TrivialResourceLogicCircuit::new(
output_resource_1.commitment().inner(),
[input_resource_1, input_resource_2],
[output_resource_1, output_resource_2],
);
let output_resource_path_1 = resource_merkle_tree
.generate_path(output_resource_cm_1)
.unwrap();
let output_resource_application_logic_1 =
TrivialResourceLogicCircuit::new(output_resource_1, output_resource_path_1);

ApplicationByteCode::new(app_resource_logic.to_bytecode(), vec![])
ApplicationByteCode::new(output_resource_application_logic_1.to_bytecode(), vec![])
};

let output_resource_2_app = {
let app_resource_logic = TrivialResourceLogicCircuit::new(
output_resource_2.commitment().inner(),
[input_resource_1, input_resource_2],
[output_resource_1, output_resource_2],
);
let output_resource_path_2 = resource_merkle_tree
.generate_path(output_resource_cm_2)
.unwrap();
let output_resource_application_logic_2 =
TrivialResourceLogicCircuit::new(output_resource_2, output_resource_path_2);

ApplicationByteCode::new(app_resource_logic.to_bytecode(), vec![])
ApplicationByteCode::new(output_resource_application_logic_2.to_bytecode(), vec![])
};

// construct ptx
Expand Down
Loading

0 comments on commit 5acbb08

Please sign in to comment.