Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions arm/src/logic_instance.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
use risc0_zkvm::Digest;
#[cfg(feature = "nif")]
use rustler::NifStruct;
use serde::{Deserialize, Serialize};

#[derive(Clone, Debug, Default, Serialize, Deserialize)]
#[cfg_attr(feature = "nif", derive(NifStruct))]
#[cfg_attr(feature = "nif", module = "Anoma.Arm.LogicInstance")]
pub struct LogicInstance {
pub tag: Digest,
pub is_consumed: bool,
Expand Down
124 changes: 95 additions & 29 deletions arm/src/rustler_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::action_tree::MerkleTree;
use crate::compliance::{ComplianceInstance, ComplianceWitness};
use crate::compliance_unit::ComplianceUnit;
use crate::delta_proof::{DeltaProof, DeltaWitness};
use crate::logic_instance::{AppData, ExpirableBlob};
use crate::logic_instance::{AppData, ExpirableBlob, LogicInstance};
use crate::logic_proof::{LogicVerifier, LogicVerifierInputs};
use crate::merkle_path::MerklePath;
use crate::nullifier_key::{NullifierKey, NullifierKeyCommitment};
Expand All @@ -18,6 +18,7 @@ use crate::utils::{bytes_to_words, words_to_bytes};
use bincode;
use k256::ecdsa::{RecoveryId, Signature, SigningKey};
use k256::AffinePoint;
use risc0_zkvm::Digest;
use rustler::types::map::map_new;
use rustler::{atoms, Binary, Decoder, Encoder, NifResult};
use rustler::{Env, Error, OwnedBinary, Term};
Expand All @@ -40,6 +41,9 @@ atoms! {
at_discovery_payload = "discovery_payload",
at_external_payload = "external_payload",
at_application_payload = "application_payload",
at_logic_instance = "Anoma.Arm.LogicInstance",
at_is_consumed = "is_consumed",
at_root = "root",
at_logic_verifier_inputs = "Elixir.Anoma.Arm.LogicVerifierInputs",
at_tag = "tag",
at_verifying_key = "verifying_key",
Expand Down Expand Up @@ -131,6 +135,19 @@ impl<'a> RustlerDecoder<'a> for Vec<u32> {
}
}

impl RustlerEncoder for Digest {
fn rustler_encode<'a>(&self, env: Env<'a>) -> Result<Term<'a>, Error> {
self.as_words().to_vec().rustler_encode(env)
}
}

impl<'a> RustlerDecoder<'a> for Digest {
fn rustler_decode(term: Term<'a>) -> NifResult<Self> {
let binary: Vec<u32> = term.decode()?;
binary.try_into().map_err(|_| Error::BadArg)
}
}

impl RustlerEncoder for AffinePoint {
fn rustler_encode<'a>(&self, env: Env<'a>) -> Result<Term<'a>, Error> {
bincode::serialize(self)
Expand Down Expand Up @@ -361,9 +378,9 @@ impl RustlerEncoder for LogicVerifierInputs {
impl<'a> RustlerDecoder<'a> for LogicVerifierInputs {
fn rustler_decode(term: Term<'a>) -> NifResult<Self> {
let tag_term = term.map_get(at_tag().encode(term.get_env()))?;
let tag: Vec<u32> = RustlerDecoder::rustler_decode(tag_term)?;
let tag = RustlerDecoder::rustler_decode(tag_term)?;
let verifying_key_term = term.map_get(at_verifying_key().encode(term.get_env()))?;
let verifying_key: Vec<u32> = RustlerDecoder::rustler_decode(verifying_key_term)?;
let verifying_key = RustlerDecoder::rustler_decode(verifying_key_term)?;
let app_data_term = term.map_get(at_app_data_key().encode(term.get_env()))?;
let app_data: AppData = app_data_term.decode()?;
let proof_term = term.map_get(at_proof().encode(term.get_env()))?;
Expand All @@ -378,6 +395,45 @@ impl<'a> RustlerDecoder<'a> for LogicVerifierInputs {
}
}

impl RustlerEncoder for LogicInstance {
fn rustler_encode<'a>(&self, env: Env<'a>) -> NifResult<Term<'a>> {
map_new(env)
.map_put(at_struct().encode(env), at_logic_instance().encode(env))?
.map_put(at_tag().encode(env), self.tag.rustler_encode(env)?)?
.map_put(at_is_consumed().encode(env), self.is_consumed.encode(env))?
.map_put(at_root().encode(env), self.root.rustler_encode(env)?)?
.map_put(
at_app_data().encode(env),
self.app_data.rustler_encode(env)?,
)
}
}

impl<'a> RustlerDecoder<'a> for LogicInstance {
fn rustler_decode(term: Term<'a>) -> NifResult<Self> {
let env = term.get_env();

let tag_term = term.map_get(at_tag().encode(env))?;
let tag = RustlerDecoder::rustler_decode(tag_term)?;

let is_consumed_term = term.map_get(at_is_consumed().encode(env))?;
let is_consumed: bool = is_consumed_term.decode()?;

let root_term = term.map_get(at_root().encode(env))?;
let root = RustlerDecoder::rustler_decode(root_term)?;

let app_data_term = term.map_get(at_app_data().encode(env))?;
let app_data = RustlerDecoder::rustler_decode(app_data_term)?;

Ok(LogicInstance {
tag,
is_consumed,
root,
app_data,
})
}
}

impl Encoder for LogicVerifierInputs {
fn encode<'a>(&self, env: Env<'a>) -> Term<'a> {
let encoded = self.rustler_encode(env);
Expand Down Expand Up @@ -450,7 +506,7 @@ impl RustlerEncoder for MerkleTree {
let encoded_vec: Term = self
.leaves
.iter()
.map(|leaf: &Vec<u32>| {
.map(|leaf| {
leaf.rustler_encode(env)
.expect("could not encode MerkleTree leaf")
})
Expand All @@ -471,7 +527,7 @@ impl<'a> RustlerDecoder<'a> for MerkleTree {
let leaves_terms =
Vec::<Term>::decode(leaves_term).expect("failed to decode MerkleTree leaves");

let leaves: Vec<Vec<u32>> = leaves_terms
let leaves: Vec<Digest> = leaves_terms
.iter()
.map(|term| RustlerDecoder::rustler_decode(*term).expect("failed to decode leaf"))
.collect();
Expand Down Expand Up @@ -518,11 +574,11 @@ impl<'a> RustlerDecoder<'a> for MerklePath {
fn rustler_decode(term: Term<'a>) -> NifResult<Self> {
let path_terms = Vec::<Term>::decode(term).expect("failed to decode MerklePath list");

let path: Vec<(Vec<u32>, bool)> = path_terms
let path: Vec<(Digest, bool)> = path_terms
.iter()
.map(|term| {
let tuple: (Term, Term) = term.decode().expect("failed to decode MerklePath tuple");
let hash: Vec<u32> = RustlerDecoder::rustler_decode(tuple.0)
let hash: Digest = RustlerDecoder::rustler_decode(tuple.0)
.expect("failed to decode MerklePath hash");
let is_right: bool = tuple
.1
Expand Down Expand Up @@ -579,9 +635,14 @@ impl RustlerEncoder for ComplianceInstance {
at_created_logic_ref().encode(env),
self.created_logic_ref.rustler_encode(env)?,
)?
.map_put(at_delta_x().encode(env), self.delta_x.rustler_encode(env)?)?
.map_put(at_delta_y().encode(env), self.delta_y.rustler_encode(env)?)?;

.map_put(
at_delta_x().encode(env),
self.delta_x.to_vec().rustler_encode(env)?,
)?
.map_put(
at_delta_y().encode(env),
self.delta_y.to_vec().rustler_encode(env)?,
)?;
Ok(map)
}
}
Expand All @@ -590,38 +651,37 @@ impl<'a> RustlerDecoder<'a> for ComplianceInstance {
fn rustler_decode(term: Term<'a>) -> NifResult<Self> {
let consumed_nullifier_term =
term.map_get(at_consumed_nullifier().encode(term.get_env()))?;
let consumed_nullifier: Vec<u32> = RustlerDecoder::rustler_decode(consumed_nullifier_term)?;
let consumed_nullifier = RustlerDecoder::rustler_decode(consumed_nullifier_term)?;

let consumed_logic_ref_term =
term.map_get(at_consumed_logic_ref().encode(term.get_env()))?;
let consumed_logic_ref: Vec<u32> = RustlerDecoder::rustler_decode(consumed_logic_ref_term)?;
let consumed_logic_ref = RustlerDecoder::rustler_decode(consumed_logic_ref_term)?;

let consumed_commitment_tree_root_term =
term.map_get(at_consumed_commitment_tree_root().encode(term.get_env()))?;
let consumed_commitment_tree_root: Vec<u32> =
let consumed_commitment_tree_root =
RustlerDecoder::rustler_decode(consumed_commitment_tree_root_term)?;

let created_commitment_term =
term.map_get(at_created_commitment().encode(term.get_env()))?;
let created_commitment: Vec<u32> = RustlerDecoder::rustler_decode(created_commitment_term)?;
let created_commitment = RustlerDecoder::rustler_decode(created_commitment_term)?;

let created_logic_ref_term = term.map_get(at_created_logic_ref().encode(term.get_env()))?;
let created_logic_ref: Vec<u32> = RustlerDecoder::rustler_decode(created_logic_ref_term)?;
let created_logic_ref = RustlerDecoder::rustler_decode(created_logic_ref_term)?;

let delta_x_term = term.map_get(at_delta_x().encode(term.get_env()))?;
let delta_x: Vec<u32> = RustlerDecoder::rustler_decode(delta_x_term)?;

let delta_y_term = term.map_get(at_delta_y().encode(term.get_env()))?;
let delta_y: Vec<u32> = RustlerDecoder::rustler_decode(delta_y_term)?;

Ok(ComplianceInstance {
consumed_nullifier,
consumed_logic_ref,
consumed_commitment_tree_root,
created_commitment,
created_logic_ref,
delta_x,
delta_y,
delta_x: <[u32; 8]>::try_from(delta_x).map_err(|_e| Error::BadArg)?,
delta_y: <[u32; 8]>::try_from(delta_y).map_err(|_e| Error::BadArg)?,
})
}
}
Expand Down Expand Up @@ -678,7 +738,7 @@ impl<'a> RustlerDecoder<'a> for ComplianceWitness {
let merkle_path: MerklePath = RustlerDecoder::rustler_decode(merkle_path_term)?;

let ephemeral_root_term = term.map_get(at_ephemeral_root().encode(term.get_env()))?;
let ephemeral_root: Vec<u32> = RustlerDecoder::rustler_decode(ephemeral_root_term)?;
let ephemeral_root = RustlerDecoder::rustler_decode(ephemeral_root_term)?;

let nf_key_term = term.map_get(at_nf_key().encode(term.get_env()))?;
let nf_key: NullifierKey = nf_key_term.decode()?;
Expand Down Expand Up @@ -718,15 +778,16 @@ impl<'a> Decoder<'a> for ComplianceWitness {

impl RustlerEncoder for NullifierKeyCommitment {
fn rustler_encode<'a>(&self, env: Env<'a>) -> Result<Term<'a>, Error> {
let inner_bytes = self.inner().to_vec();
let inner_bytes = self.inner().as_words().to_vec();
inner_bytes.rustler_encode(env)
}
}

impl<'a> RustlerDecoder<'a> for NullifierKeyCommitment {
fn rustler_decode(term: Term<'a>) -> NifResult<Self> {
let bytes: Vec<u8> = RustlerDecoder::rustler_decode(term)?;
Ok(NullifierKeyCommitment::from_bytes(&bytes))
Ok(NullifierKeyCommitment::from_bytes(&bytes)
.map_err(|e| Error::Term(Box::new(e.to_string())))?)
}
}

Expand Down Expand Up @@ -794,14 +855,17 @@ impl RustlerEncoder for Resource {
self.value_ref.rustler_encode(env)?,
)?
.map_put(at_is_ephemeral().encode(env), self.is_ephemeral.encode(env))?
.map_put(at_nonce().encode(env), self.nonce.rustler_encode(env)?)?
.map_put(
at_nonce().encode(env),
self.nonce.to_vec().rustler_encode(env)?,
)?
.map_put(
at_nk_commitment().encode(env),
self.nk_commitment.rustler_encode(env)?,
)?
.map_put(
at_rand_seed().encode(env),
self.rand_seed.rustler_encode(env)?,
self.rand_seed.to_vec().rustler_encode(env)?,
)?;

Ok(map)
Expand All @@ -811,16 +875,16 @@ impl RustlerEncoder for Resource {
impl<'a> RustlerDecoder<'a> for Resource {
fn rustler_decode(term: Term<'a>) -> NifResult<Self> {
let logic_ref_term = term.map_get(at_logic_ref().encode(term.get_env()))?;
let logic_ref: Vec<u8> = RustlerDecoder::rustler_decode(logic_ref_term)?;
let logic_ref = RustlerDecoder::rustler_decode(logic_ref_term)?;

let label_ref_term = term.map_get(at_label_ref().encode(term.get_env()))?;
let label_ref: Vec<u8> = RustlerDecoder::rustler_decode(label_ref_term)?;
let label_ref = RustlerDecoder::rustler_decode(label_ref_term)?;

let quantity_term = term.map_get(at_quantity().encode(term.get_env()))?;
let quantity: u128 = quantity_term.decode()?;

let value_ref_term = term.map_get(at_value_ref().encode(term.get_env()))?;
let value_ref: Vec<u8> = RustlerDecoder::rustler_decode(value_ref_term)?;
let value_ref = RustlerDecoder::rustler_decode(value_ref_term)?;

let is_ephemeral_term = term.map_get(at_is_ephemeral().encode(term.get_env()))?;
let is_ephemeral: bool = is_ephemeral_term.decode()?;
Expand All @@ -841,9 +905,11 @@ impl<'a> RustlerDecoder<'a> for Resource {
quantity,
value_ref,
is_ephemeral,
nonce,
nonce: <[u8; 32]>::try_from(nonce)
.map_err(|_e| Error::Term(Box::new("invalid_nonce")))?,
nk_commitment,
rand_seed,
rand_seed: <[u8; 32]>::try_from(rand_seed)
.map_err(|_e| Error::Term(Box::new("invalid_nonce")))?,
})
}
}
Expand Down Expand Up @@ -971,7 +1037,7 @@ impl<'a> RustlerDecoder<'a> for LogicVerifier {
let instance: Vec<u8> = RustlerDecoder::rustler_decode(instance_term)?;

let verifying_key_term = term.map_get(at_verifying_key().encode(term.get_env()))?;
let verifying_key: Vec<u32> = RustlerDecoder::rustler_decode(verifying_key_term)?;
let verifying_key = RustlerDecoder::rustler_decode(verifying_key_term)?;

Ok(LogicVerifier {
proof,
Expand Down