Skip to content

Commit bf7a5a3

Browse files
authored
Merge pull request #24 from anoma/xuyang/fix_delta_format
fix delta format
2 parents 7a25e29 + a82d8b0 commit bf7a5a3

File tree

11 files changed

+366
-23
lines changed

11 files changed

+366
-23
lines changed

native/aarm/Cargo.toml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
[package]
2+
name = "aarm"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7+
8+
[dependencies]
9+
# If you want to try (experimental) std support, add `features = [ "std" ]` to risc0-zkvm
10+
risc0-zkvm = { version = "1.1.2" }
11+
serde = { version = "1.0.197", default-features = false }
12+
compliance_circuit = { path = "../examples/compliance_circuit/methods", package = 'methods'}
13+
aarm_core = { path = "../aarm_core" }
14+
15+
[dev-dependencies]
16+
bincode = "1.3"
17+
serde_bytes = "0.11"

native/aarm/src/action.rs

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
use compliance_circuit::COMPLIANCE_GUEST_ID;
2+
use risc0_zkvm::Receipt;
3+
use serde::{Deserialize, Serialize};
4+
5+
#[derive(Clone, Debug, Deserialize, Serialize)]
6+
pub struct Action {
7+
pub compliance_units: Vec<Receipt>,
8+
pub logic_proofs: Vec<Receipt>,
9+
}
10+
11+
impl Action {
12+
pub fn new(compliance_units: Vec<Receipt>, logic_proofs: Vec<Receipt>) -> Self {
13+
Action {
14+
compliance_units,
15+
logic_proofs,
16+
}
17+
}
18+
19+
pub fn get_compliance_units(&self) -> &Vec<Receipt> {
20+
&self.compliance_units
21+
}
22+
23+
pub fn get_logic_proofs(&self) -> &Vec<Receipt> {
24+
&self.logic_proofs
25+
}
26+
27+
pub fn verify(&self) -> bool {
28+
for receipt in &self.compliance_units {
29+
if receipt.verify(COMPLIANCE_GUEST_ID).is_err() {
30+
return false;
31+
}
32+
}
33+
34+
// TODO: Verify real logic proofs
35+
for receipt in &self.logic_proofs {
36+
if receipt.verify(COMPLIANCE_GUEST_ID).is_err() {
37+
return false;
38+
}
39+
}
40+
41+
// TODO: Verify other checks
42+
// Actually, the verification should occur on validators/EVM adapter.
43+
44+
true
45+
}
46+
}
47+
48+
#[test]
49+
fn test_action() {
50+
use aarm_core::{compliance::ComplianceWitness, constants::TREE_DEPTH, utils::GenericEnv};
51+
use bincode;
52+
use compliance_circuit::COMPLIANCE_GUEST_ELF;
53+
use risc0_zkvm::{default_prover, ExecutorEnv};
54+
use serde_bytes::ByteBuf;
55+
56+
let compliance_witness: ComplianceWitness<TREE_DEPTH> =
57+
ComplianceWitness::<TREE_DEPTH>::default();
58+
let generic_env = GenericEnv {
59+
data: ByteBuf::from(bincode::serialize(&compliance_witness).unwrap()),
60+
};
61+
62+
let env = ExecutorEnv::builder()
63+
.write(&generic_env)
64+
.unwrap()
65+
.build()
66+
.unwrap();
67+
68+
let prover = default_prover();
69+
70+
let receipt = prover.prove(env, COMPLIANCE_GUEST_ELF).unwrap().receipt;
71+
72+
let compliance_units = vec![receipt.clone()];
73+
let logic_proofs = vec![receipt];
74+
75+
let action = Action::new(compliance_units, logic_proofs);
76+
77+
assert!(action.verify());
78+
}

native/aarm/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
pub mod action;
2+
pub mod transaction;

native/aarm/src/transaction.rs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
use crate::action::Action;
2+
use aarm_core::delta_proof::{DeltaInstance, DeltaProof, DeltaWitness};
3+
use serde::{Deserialize, Serialize};
4+
5+
#[derive(Clone, Debug, Deserialize, Serialize)]
6+
pub struct Transaction {
7+
pub action: Vec<Action>,
8+
pub delta_proof: Delta,
9+
}
10+
11+
#[derive(Clone, Debug, Deserialize, Serialize)]
12+
pub enum Delta {
13+
Witness(DeltaWitness),
14+
Proof(DeltaProof),
15+
}
16+
17+
impl Transaction {
18+
pub fn new(action: Vec<Action>, delta: Delta) -> Self {
19+
Transaction {
20+
action,
21+
delta_proof: delta,
22+
}
23+
}
24+
25+
pub fn generate_delta_proof(&mut self) {
26+
match self.delta_proof {
27+
Delta::Witness(ref witness) => {
28+
let msg = self.get_delta_msg();
29+
let proof = DeltaProof::prove(&msg, witness);
30+
self.delta_proof = Delta::Proof(proof);
31+
}
32+
Delta::Proof(_) => {}
33+
}
34+
}
35+
36+
pub fn verify(&self) -> bool {
37+
match &self.delta_proof {
38+
Delta::Proof(ref proof) => {
39+
let msg = self.get_delta_msg();
40+
let instance = self.get_delta_instance();
41+
if DeltaProof::verify(&msg, proof, instance).is_err() {
42+
return false;
43+
}
44+
for action in &self.action {
45+
if !action.verify() {
46+
return false;
47+
}
48+
}
49+
true
50+
}
51+
Delta::Witness(_) => false,
52+
}
53+
}
54+
55+
pub fn get_delta_instance(&self) -> DeltaInstance {
56+
unimplemented!()
57+
}
58+
59+
pub fn get_delta_msg(&self) -> Vec<u8> {
60+
unimplemented!()
61+
}
62+
}

native/aarm_core/src/authorization.rs

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
use k256::ecdsa::{
2+
signature::{Signer, Verifier},
3+
Error, Signature, SigningKey, VerifyingKey,
4+
};
5+
use k256::{elliptic_curve::rand_core::OsRng, EncodedPoint};
6+
use serde::{Deserialize, Serialize};
7+
8+
#[derive(Clone)]
9+
pub struct AuthorizationSigningKey(SigningKey);
10+
11+
#[derive(Clone, Debug, Serialize, Deserialize)]
12+
pub struct AuthorizationVerifyingKey(EncodedPoint);
13+
14+
#[derive(Clone, Serialize, Deserialize)]
15+
pub struct AuthorizationSignature(Signature);
16+
17+
impl AuthorizationSigningKey {
18+
pub fn new() -> Self {
19+
let signing_key = SigningKey::random(&mut OsRng);
20+
AuthorizationSigningKey(signing_key)
21+
}
22+
23+
pub fn sign(&self, message: &[u8]) -> AuthorizationSignature {
24+
AuthorizationSignature(self.0.sign(message))
25+
}
26+
27+
pub fn to_bytes(&self) -> [u8; 32] {
28+
self.0.to_bytes().into()
29+
}
30+
31+
pub fn from_bytes(bytes: &[u8]) -> Self {
32+
AuthorizationSigningKey(SigningKey::from_bytes(bytes.into()).unwrap())
33+
}
34+
}
35+
36+
impl Default for AuthorizationSigningKey {
37+
fn default() -> Self {
38+
Self::new()
39+
}
40+
}
41+
42+
impl Serialize for AuthorizationSigningKey {
43+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
44+
where
45+
S: serde::Serializer,
46+
{
47+
serializer.serialize_bytes(&self.to_bytes())
48+
}
49+
}
50+
51+
impl<'de> Deserialize<'de> for AuthorizationSigningKey {
52+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
53+
where
54+
D: serde::Deserializer<'de>,
55+
{
56+
let bytes = <[u8; 32]>::deserialize(deserializer)?;
57+
Ok(AuthorizationSigningKey::from_bytes(&bytes))
58+
}
59+
}
60+
61+
impl AuthorizationVerifyingKey {
62+
pub fn from_signing_key(signing_key: &AuthorizationSigningKey) -> Self {
63+
let verifying_key = signing_key.0.verifying_key();
64+
AuthorizationVerifyingKey(verifying_key.to_encoded_point(false))
65+
}
66+
67+
pub fn verify(&self, message: &[u8], signature: &AuthorizationSignature) -> Result<(), Error> {
68+
VerifyingKey::from_encoded_point(&self.0)
69+
.unwrap()
70+
.verify(message, signature.inner())
71+
}
72+
}
73+
74+
impl AuthorizationSignature {
75+
pub fn inner(&self) -> &Signature {
76+
&self.0
77+
}
78+
}
79+
80+
#[test]
81+
fn test_authorization() {
82+
let signing_key = AuthorizationSigningKey::new();
83+
let verifying_key = AuthorizationVerifyingKey::from_signing_key(&signing_key);
84+
85+
let message = b"Hello, world!";
86+
let signature = signing_key.sign(message);
87+
88+
assert!(verifying_key.verify(message, &signature).is_ok());
89+
}

native/aarm_core/src/compliance.rs

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
use crate::{
2-
constants::{DEFAULT_BYTES, TRIVIAL_RESOURCE_LOGIC_VK},
3-
merkle_path::MerklePath,
4-
nullifier_key::NullifierKey,
2+
constants::TRIVIAL_RESOURCE_LOGIC_VK, merkle_path::MerklePath, nullifier_key::NullifierKey,
53
resource::Resource,
64
};
75
use k256::{
8-
elliptic_curve::{group::GroupEncoding, Field},
9-
ProjectivePoint, Scalar,
6+
elliptic_curve::{
7+
sec1::{FromEncodedPoint, ToEncodedPoint},
8+
Field,
9+
},
10+
EncodedPoint, ProjectivePoint, Scalar,
1011
};
1112
use rand::Rng;
1213
use risc0_zkvm::sha::{Digest, Impl, Sha256};
@@ -17,7 +18,7 @@ pub struct ComplianceInstance {
1718
pub nullifier: Digest,
1819
pub commitment: Digest,
1920
pub merkle_root: Digest,
20-
pub delta: [u8; DEFAULT_BYTES],
21+
pub delta: EncodedPoint,
2122
pub consumed_logic_ref: Digest,
2223
pub created_logic_ref: Digest,
2324
}
@@ -117,17 +118,26 @@ impl<const COMMITMENT_TREE_DEPTH: usize> ComplianceCircuit<COMMITMENT_TREE_DEPTH
117118
MerklePath::from_path(self.compliance_witness.merkle_path).root(cm)
118119
}
119120

120-
pub fn delta_commitment(&self) -> [u8; DEFAULT_BYTES] {
121+
pub fn delta_commitment(&self) -> EncodedPoint {
121122
// Compute delta and make delta commitment public
122123
let delta = self.compliance_witness.consumed_resource.kind()
123124
* self.compliance_witness.consumed_resource.quantity_scalar()
124125
- self.compliance_witness.created_resource.kind()
125126
* self.compliance_witness.created_resource.quantity_scalar()
126127
+ ProjectivePoint::GENERATOR * self.compliance_witness.rcv;
127128

128-
let delta_bytes: [u8; DEFAULT_BYTES] = delta.to_affine().to_bytes()[..DEFAULT_BYTES]
129-
.try_into()
130-
.expect("Slice length mismatch");
131-
delta_bytes
129+
delta.to_encoded_point(false)
130+
}
131+
}
132+
133+
impl ComplianceInstance {
134+
pub fn delta_coordinates(&self) -> ([u8; 32], [u8; 32]) {
135+
let x = (*self.delta.x().unwrap()).into();
136+
let y = (*self.delta.y().unwrap()).into();
137+
(x, y)
138+
}
139+
140+
pub fn delta_projective(&self) -> ProjectivePoint {
141+
ProjectivePoint::from_encoded_point(&self.delta).unwrap()
132142
}
133143
}

native/aarm_core/src/delta_proof.rs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
use k256::ecdsa::{Error, RecoveryId, Signature, SigningKey, VerifyingKey};
22
use k256::{elliptic_curve::ScalarPrimitive, ProjectivePoint, PublicKey, Scalar, SecretKey};
3+
use serde::{Deserialize, Serialize};
34
use sha3::{Digest, Keccak256};
45

6+
#[derive(Clone, Debug)]
57
pub struct DeltaProof {
68
pub signature: Signature,
79
pub recid: RecoveryId,
810
}
911

12+
#[derive(Clone, Debug)]
1013
pub struct DeltaWitness {
1114
pub signing_key: SigningKey,
1215
}
@@ -79,6 +82,13 @@ impl DeltaWitness {
7982
pub fn to_bytes(&self) -> [u8; 32] {
8083
self.signing_key.to_bytes().into()
8184
}
85+
86+
pub fn compose(&mut self, other: &DeltaWitness) {
87+
let sum = self.signing_key.as_nonzero_scalar().as_ref()
88+
+ other.signing_key.as_nonzero_scalar().as_ref();
89+
let sk: SecretKey = SecretKey::new(sum.into());
90+
self.signing_key = SigningKey::from(sk);
91+
}
8292
}
8393

8494
impl DeltaInstance {
@@ -92,6 +102,49 @@ impl DeltaInstance {
92102
}
93103
}
94104

105+
impl Serialize for DeltaProof {
106+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
107+
where
108+
S: serde::Serializer,
109+
{
110+
serializer.serialize_bytes(&self.to_bytes())
111+
}
112+
}
113+
114+
impl<'de> Deserialize<'de> for DeltaProof {
115+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
116+
where
117+
D: serde::Deserializer<'de>,
118+
{
119+
let bytes: Vec<u8> = serde_bytes::deserialize(deserializer)?;
120+
if bytes.len() != 65 {
121+
return Err(serde::de::Error::custom(
122+
"Invalid byte length for DeltaProof",
123+
));
124+
}
125+
Ok(DeltaProof::from_bytes(&bytes))
126+
}
127+
}
128+
129+
impl Serialize for DeltaWitness {
130+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
131+
where
132+
S: serde::Serializer,
133+
{
134+
serializer.serialize_bytes(&self.to_bytes())
135+
}
136+
}
137+
138+
impl<'de> Deserialize<'de> for DeltaWitness {
139+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
140+
where
141+
D: serde::Deserializer<'de>,
142+
{
143+
let bytes = <[u8; 32]>::deserialize(deserializer)?;
144+
Ok(DeltaWitness::from_bytes(&bytes))
145+
}
146+
}
147+
95148
#[test]
96149
fn test_delta_proof() {
97150
use k256::elliptic_curve::rand_core::OsRng;

0 commit comments

Comments
 (0)