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
31 changes: 0 additions & 31 deletions arm/src/encryption.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,7 @@ use k256::{
ProjectivePoint, Scalar,
};
use rand::rngs::OsRng;
#[cfg(feature = "nif")]
use rustler::{Decoder, Encoder, Env, Error, NifResult, OwnedBinary, Term};
use serde::{Deserialize, Serialize};
#[cfg(feature = "nif")]
use std::io::Write;

#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct SecretKey(Scalar);
Expand All @@ -30,33 +26,6 @@ impl SecretKey {
}
}

#[cfg(feature = "nif")]
fn do_encode<'a>(secret_key: &SecretKey, env: Env<'a>) -> Result<Term<'a>, Error> {
let bytes = bincode::serialize(&secret_key.0).unwrap();

let mut erl_bin = OwnedBinary::new(bytes.len()).ok_or(Error::BadArg)?;
let _ = erl_bin.as_mut_slice().write_all(&bytes);

Ok(erl_bin.release(env).to_term(env))
}

#[cfg(feature = "nif")]
impl Encoder for SecretKey {
fn encode<'a>(&self, env: Env<'a>) -> Term<'a> {
let result = do_encode(self, env).expect("failed to encode SecretKey");
result
}
}

#[cfg(feature = "nif")]
impl<'a> Decoder<'a> for SecretKey {
fn decode(term: Term<'a>) -> NifResult<Self> {
let binary = term.decode_as_binary()?.as_slice();
let scalar: Scalar = bincode::deserialize(binary).expect("failed to decode SecretKey");
Ok(SecretKey(scalar))
}
}

#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct Ciphertext(Vec<u8>);

Expand Down
4 changes: 3 additions & 1 deletion arm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ pub mod nullifier_key;
pub mod proving_system;
pub mod resource;
pub mod resource_logic;
mod rustler_util;
#[cfg(feature = "nif")]
pub mod rustler_util;
#[cfg(feature = "transaction")]
pub mod test_logic;
Comment on lines +26 to 27
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test_logic is a circuit implementation, and the transaction feature does not apply to it.

#[cfg(feature = "transaction")]
pub mod transaction;
Expand Down
2 changes: 1 addition & 1 deletion arm/src/logic_instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize};

#[derive(Clone, Debug, Default, Serialize, Deserialize)]
#[cfg_attr(feature = "nif", derive(NifStruct))]
#[cfg_attr(feature = "nif", module = "Anoma.Arm.LogicInstance")]
#[cfg_attr(feature = "nif", module = "AnomaSDK.Arm.LogicInstance")]
pub struct LogicInstance {
pub tag: Vec<u32>,
pub is_consumed: bool,
Expand Down
2 changes: 1 addition & 1 deletion arm/src/resource_logic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ pub trait LogicCircuit: Default + Clone + Serialize + for<'de> Deserialize<'de>

#[derive(Clone, Default, Serialize, Deserialize)]
#[cfg_attr(feature = "nif", derive(NifStruct))]
#[cfg_attr(feature = "nif", module = "Anoma.Arm.TrivialLogicWitness")]
#[cfg_attr(feature = "nif", module = "AnomaSDK.Arm.TrivialLogicWitness")]
pub struct TrivialLogicWitness {
pub resource: Resource,
pub receive_existence_path: MerklePath,
Expand Down
122 changes: 97 additions & 25 deletions arm/src/rustler_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +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::encryption::{Ciphertext, SecretKey};
use crate::logic_instance::{AppData, ExpirableBlob};
use crate::logic_proof::{LogicVerifier, LogicVerifierInputs};
use crate::merkle_path::MerklePath;
Expand All @@ -17,13 +18,15 @@ use crate::transaction::{Delta, Transaction};
use crate::utils::{bytes_to_words, words_to_bytes};
use bincode;
use k256::ecdsa::{RecoveryId, Signature, SigningKey};
use k256::AffinePoint;
use k256::elliptic_curve::PrimeField;
use k256::{AffinePoint, Scalar};
use rustler::types::map::map_new;
use rustler::{atoms, Binary, Decoder, Encoder, NifResult};
use rustler::{Env, Error, OwnedBinary, Term};
use std::io::Write;

atoms! {
at_nil = "nil",
at_true = "true",
at_false = "false",
at_value = "value",
Expand All @@ -33,38 +36,38 @@ atoms! {
at_struct = "__struct__",
at_deletion_criteria = "deletion_criteria",
at_blob = "blob",
at_compliance_unit = "Elixir.Anoma.Arm.ComplianceUnit",
at_expirable_blob = "Elixir.Anoma.Arm.ExpirableBlob",
at_app_data = "Elixir.Anoma.Arm.AppData",
at_compliance_unit = "Elixir.AnomaSDK.Arm.ComplianceUnit",
at_expirable_blob = "Elixir.AnomaSDK.Arm.ExpirableBlob",
at_app_data = "Elixir.AnomaSDK.Arm.AppData",
at_resource_payload = "resource_payload",
at_discovery_payload = "discovery_payload",
at_external_payload = "external_payload",
at_application_payload = "application_payload",
at_logic_verifier_inputs = "Elixir.Anoma.Arm.LogicVerifierInputs",
at_logic_verifier_inputs = "Elixir.AnomaSDK.Arm.LogicVerifierInputs",
at_tag = "tag",
at_verifying_key = "verifying_key",
at_app_data_key = "app_data",
at_action = "Elixir.Anoma.Arm.Action",
at_action = "Elixir.AnomaSDK.Arm.Action",
at_compliance_units = "compliance_units",
at_logic_verifier_inputs_key = "logic_verifier_inputs",
at_merkle_tree = "Elixir.Anoma.Arm.MerkleTree",
at_merkle_tree = "Elixir.AnomaSDK.Arm.MerkleTree",
at_leaves = "leaves",
at_compliance_instance = "Elixir.Anoma.Arm.ComplianceInstance",
at_compliance_instance = "Elixir.AnomaSDK.Arm.ComplianceInstance",
at_consumed_nullifier = "consumed_nullifier",
at_consumed_logic_ref = "consumed_logic_ref",
at_consumed_commitment_tree_root = "consumed_commitment_tree_root",
at_created_commitment = "created_commitment",
at_created_logic_ref = "created_logic_ref",
at_delta_x = "delta_x",
at_delta_y = "delta_y",
at_compliance_witness = "Elixir.Anoma.Arm.ComplianceWitness",
at_compliance_witness = "Elixir.AnomaSDK.Arm.ComplianceWitness",
at_consumed_resource = "consumed_resource",
at_merkle_path = "merkle_path",
at_ephemeral_root = "ephemeral_root",
at_nf_key = "nf_key",
at_created_resource = "created_resource",
at_rcv = "rcv",
at_resource = "Elixir.Anoma.Arm.Resource",
at_resource = "Elixir.AnomaSDK.Arm.Resource",
at_logic_ref = "logic_ref",
at_label_ref = "label_ref",
at_quantity = "quantity",
Expand All @@ -73,13 +76,13 @@ atoms! {
at_nonce = "nonce",
at_nk_commitment = "nk_commitment",
at_rand_seed = "rand_seed",
at_delta_proof = "Elixir.Anoma.Arm.DeltaProof",
at_delta_proof = "Elixir.AnomaSDK.Arm.DeltaProof",
at_signature = "signature",
at_recid = "recid",
at_delta_witness = "Elixir.Anoma.Arm.DeltaWitness",
at_delta_witness = "Elixir.AnomaSDK.Arm.DeltaWitness",
at_signing_key = "signing_key",
at_logic_verifier = "Elixir.Anoma.Arm.LogicVerifier",
at_transaction = "Elixir.Anoma.Arm.Transaction",
at_logic_verifier = "Elixir.AnomaSDK.Arm.LogicVerifier",
at_transaction = "Elixir.AnomaSDK.Arm.Transaction",
at_actions = "actions",
at_delta_proof_field = "delta_proof",
at_expected_balance = "expected_balance",
Expand Down Expand Up @@ -177,6 +180,72 @@ impl<'a> RustlerDecoder<'a> for RecoveryId {
}
}

//--------------------------------------------------------------------------------------------------
// CipherText

impl RustlerEncoder for Ciphertext {
fn rustler_encode<'a>(&self, env: Env<'a>) -> Result<Term<'a>, Error> {
let bytes = self.as_words();
Ok(bytes.rustler_encode(env)?)
}
}

impl<'a> RustlerDecoder<'a> for Ciphertext {
fn rustler_decode(term: Term<'a>) -> NifResult<Self> {
let words: Vec<u32> = RustlerDecoder::rustler_decode(term)?;
let cipher_text: Ciphertext = Ciphertext::from_words(words.as_slice());
Ok(cipher_text)
}
}

impl Encoder for Ciphertext {
fn encode<'a>(&self, env: Env<'a>) -> Term<'a> {
self.rustler_encode(env)
.expect("failed to encode SecretKey")
}
}

impl<'a> Decoder<'a> for Ciphertext {
fn decode(term: Term<'a>) -> NifResult<Self> {
Ciphertext::rustler_decode(term)
}
}

//--------------------------------------------------------------------------------------------------
// SecretKey

impl RustlerEncoder for SecretKey {
fn rustler_encode<'a>(&self, env: Env<'a>) -> Result<Term<'a>, Error> {
let bytes = self.inner().to_bytes().as_slice().to_vec();
Ok(bytes.rustler_encode(env)?)
}
}

impl<'a> RustlerDecoder<'a> for SecretKey {
fn rustler_decode(term: Term<'a>) -> NifResult<Self> {
let secret_key_vec: Vec<u8> = RustlerDecoder::rustler_decode(term)?;
let secret_key_slice: [u8; 32] = secret_key_vec.try_into().unwrap();
let sk = SecretKey::new(Scalar::from_repr(secret_key_slice.into()).unwrap());
Ok(sk)
}
}

impl Encoder for SecretKey {
fn encode<'a>(&self, env: Env<'a>) -> Term<'a> {
self.rustler_encode(env)
.expect("failed to encode SecretKey")
}
}

impl<'a> Decoder<'a> for SecretKey {
fn decode(term: Term<'a>) -> NifResult<Self> {
SecretKey::rustler_decode(term)
}
}

//--------------------------------------------------------------------------------------------------
// SigningKey

impl RustlerEncoder for SigningKey {
fn rustler_encode<'a>(&self, env: Env<'a>) -> Result<Term<'a>, Error> {
let bytes = self.to_bytes();
Expand Down Expand Up @@ -999,20 +1068,20 @@ impl<'a> Decoder<'a> for LogicVerifier {

impl RustlerEncoder for Transaction {
fn rustler_encode<'a>(&self, env: Env<'a>) -> Result<Term<'a>, Error> {
let balance_term: Term;
match &self.expected_balance {
None => balance_term = at_nil().encode(env),
Some(vec) => balance_term = RustlerEncoder::rustler_encode(vec, env)?,
};

let map = map_new(env)
.map_put(at_struct().encode(env), at_transaction().encode(env))?
.map_put(at_actions().encode(env), self.actions.encode(env))?
.map_put(
at_delta_proof_field().encode(env),
self.delta_proof.encode(env),
)?
.map_put(
at_expected_balance().encode(env),
match &self.expected_balance {
Some(balance) => balance.rustler_encode(env)?,
None => ().encode(env),
},
)?;
.map_put(at_expected_balance().encode(env), balance_term)?;

Ok(map)
}
Expand All @@ -1027,10 +1096,13 @@ impl<'a> RustlerDecoder<'a> for Transaction {
let delta_proof: Delta = delta_proof_term.decode()?;

let expected_balance_term = term.map_get(at_expected_balance().encode(term.get_env()))?;
let expected_balance: Option<Vec<u8>> = match expected_balance_term.decode::<()>() {
Ok(_) => None,
Err(_) => Some(RustlerDecoder::rustler_decode(expected_balance_term)?),
};
let mut expected_balance: Option<Vec<u8>> = None;

if expected_balance_term.is_binary() {
let expected_balance_vec: Vec<u8> =
RustlerDecoder::rustler_decode(expected_balance_term)?;
expected_balance = Some(expected_balance_vec);
}

Ok(Transaction {
actions,
Expand Down
2 changes: 1 addition & 1 deletion arm/src/test_logic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use rustler::NifStruct;

#[derive(Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "nif", derive(NifStruct))]
#[cfg_attr(feature = "nif", module = "Anoma.Arm.TestLogicWitness")]
#[cfg_attr(feature = "nif", module = "AnomaSDK.Arm.TestLogicWitness")]
pub struct TestLogicWitness {
pub resource: Resource,
pub receive_existence_path: MerklePath,
Expand Down