Skip to content

Commit b393c69

Browse files
Merge pull request #944 from ProvableHQ/feat/record-scanning-and-arithmetic
[Feature] Add arithmetic types, plaintext, and conversion of plaintext & records to JS objects
2 parents ce996ac + add561f commit b393c69

34 files changed

+4600
-2097
lines changed

.circleci/config.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ jobs:
150150
- run:
151151
working_directory: wasm
152152
command: |
153-
cargo fmt -- --check
153+
cargo fmt --all -- --check
154154
155155
156156
workflows:

wasm/src/account/address.rs

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
use crate::account::{PrivateKey, Signature, ViewKey};
1818

19-
use crate::types::native::AddressNative;
19+
use crate::{account::compute_key::ComputeKey, types::native::AddressNative};
2020
use core::{convert::TryFrom, fmt, ops::Deref, str::FromStr};
2121
use wasm_bindgen::prelude::*;
2222

@@ -43,6 +43,13 @@ impl Address {
4343
Self(AddressNative::try_from(**view_key).unwrap())
4444
}
4545

46+
/// Derive an Aleo address from a compute key.
47+
///
48+
/// @param {ComputeKey} compute_key The compute key to derive the address from
49+
pub fn from_compute_key(compute_key: &ComputeKey) -> Self {
50+
compute_key.address()
51+
}
52+
4653
/// Create an aleo address object from a string representation of an address
4754
///
4855
/// @param {string} address String representation of an addressm
@@ -69,11 +76,17 @@ impl Address {
6976
}
7077
}
7178

72-
impl FromStr for Address {
73-
type Err = anyhow::Error;
79+
impl Deref for Address {
80+
type Target = AddressNative;
7481

75-
fn from_str(address: &str) -> Result<Self, Self::Err> {
76-
Ok(Self(AddressNative::from_str(address)?))
82+
fn deref(&self) -> &Self::Target {
83+
&self.0
84+
}
85+
}
86+
87+
impl fmt::Display for Address {
88+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
89+
write!(f, "{}", self.0)
7790
}
7891
}
7992

@@ -83,17 +96,29 @@ impl From<AddressNative> for Address {
8396
}
8497
}
8598

86-
impl fmt::Display for Address {
87-
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
88-
write!(f, "{}", self.0)
99+
impl From<Address> for AddressNative {
100+
fn from(value: Address) -> Self {
101+
value.0
89102
}
90103
}
91104

92-
impl Deref for Address {
93-
type Target = AddressNative;
105+
impl From<&AddressNative> for Address {
106+
fn from(value: &AddressNative) -> Self {
107+
Self(value.clone())
108+
}
109+
}
94110

95-
fn deref(&self) -> &Self::Target {
96-
&self.0
111+
impl From<&Address> for AddressNative {
112+
fn from(value: &Address) -> Self {
113+
value.0
114+
}
115+
}
116+
117+
impl FromStr for Address {
118+
type Err = anyhow::Error;
119+
120+
fn from_str(address: &str) -> Result<Self, Self::Err> {
121+
Ok(Self(AddressNative::from_str(address)?))
97122
}
98123
}
99124

wasm/src/account/compute_key.rs

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
// Copyright (C) 2019-2023 Aleo Systems Inc.
2+
// This file is part of the Aleo SDK library.
3+
4+
// The Aleo SDK library is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
9+
// The Aleo SDK library is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU General Public License for more details.
13+
14+
// You should have received a copy of the GNU General Public License
15+
// along with the Aleo SDK library. If not, see <https://www.gnu.org/licenses/>.
16+
17+
use super::PrivateKey;
18+
use crate::{
19+
types::{native::ComputeKeyNative, Group, Scalar},
20+
Address,
21+
};
22+
23+
use core::{convert::TryFrom, ops::Deref};
24+
use wasm_bindgen::prelude::*;
25+
26+
#[wasm_bindgen]
27+
#[derive(Clone, Debug, PartialEq, Eq)]
28+
pub struct ComputeKey(ComputeKeyNative);
29+
30+
#[wasm_bindgen]
31+
impl ComputeKey {
32+
/// Create a new compute key from a private key.
33+
///
34+
/// @param {PrivateKey} private_key Private key
35+
///
36+
/// @returns {ComputeKey} Compute key
37+
pub fn from_private_key(private_key: &PrivateKey) -> Self {
38+
Self(ComputeKeyNative::try_from(**private_key).unwrap())
39+
}
40+
41+
/// Get the address from the compute key.
42+
///
43+
/// @returns {Address}
44+
pub fn address(&self) -> Address {
45+
Address::from(self.0.to_address())
46+
}
47+
48+
/// Get the sk_prf of the compute key.
49+
///
50+
/// @returns {Scalar} sk_prf
51+
pub fn sk_prf(&self) -> Scalar {
52+
Scalar::from(self.0.sk_prf())
53+
}
54+
55+
/// Get the pr_tag of the compute key.
56+
///
57+
/// @returns {Group} pr_tag
58+
pub fn pk_sig(&self) -> Group {
59+
Group::from(self.0.pk_sig())
60+
}
61+
62+
/// Get the pr_sig of the compute key.
63+
///
64+
/// @returns {Group} pr_sig
65+
pub fn pr_sig(&self) -> Group {
66+
Group::from(self.0.pr_sig())
67+
}
68+
}
69+
70+
impl Deref for ComputeKey {
71+
type Target = ComputeKeyNative;
72+
73+
fn deref(&self) -> &Self::Target {
74+
&self.0
75+
}
76+
}
77+
78+
impl From<ComputeKeyNative> for ComputeKey {
79+
fn from(compute_key: ComputeKeyNative) -> Self {
80+
Self(compute_key)
81+
}
82+
}
83+
84+
impl From<ComputeKey> for ComputeKeyNative {
85+
fn from(compute_key: ComputeKey) -> Self {
86+
compute_key.0
87+
}
88+
}
89+
90+
impl From<&ComputeKey> for ComputeKeyNative {
91+
fn from(compute_key: &ComputeKey) -> Self {
92+
compute_key.0.clone()
93+
}
94+
}
95+
96+
impl From<&ComputeKeyNative> for ComputeKey {
97+
fn from(compute_key: &ComputeKeyNative) -> Self {
98+
Self(compute_key.clone())
99+
}
100+
}
101+
102+
#[cfg(test)]
103+
mod tests {
104+
use super::*;
105+
use crate::{
106+
types::native::{AddressNative, CurrentNetwork},
107+
PrivateKey,
108+
};
109+
110+
use snarkvm_console::network::Network;
111+
112+
#[test]
113+
fn test_compute_key_conversions() {
114+
// Create a new private key.
115+
let private_key = PrivateKey::new();
116+
let address = Address::from_private_key(&private_key);
117+
118+
// Get the compute key from the private key.
119+
let compute_key = ComputeKey::from_private_key(&private_key);
120+
121+
// Assert the address derivation can be computed from the compute key components.
122+
// Compute pk_prf := G^sk_prf.
123+
let pk_prf = Group::from(CurrentNetwork::g_scalar_multiply(&*compute_key.sk_prf()));
124+
// Compute the address := pk_sig + pr_sig + pk_prf.
125+
let group = compute_key.pk_sig().add(&compute_key.pr_sig()).add(&pk_prf);
126+
let address_native = AddressNative::new(*group);
127+
let derived_address = Address::from(address_native);
128+
129+
// Assert an address can be derived from the compute key via it's official function.
130+
let compute_key_address = Address::from_compute_key(&compute_key);
131+
132+
// Check the address matches all possible derivations from the compute key.
133+
assert_eq!(address, compute_key.address());
134+
assert_eq!(address, derived_address);
135+
assert_eq!(address, compute_key_address);
136+
}
137+
}

wasm/src/account/graph_key.rs

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
// Copyright (C) 2019-2023 Aleo Systems Inc.
2+
// This file is part of the Aleo SDK library.
3+
4+
// The Aleo SDK library is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
9+
// The Aleo SDK library is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU General Public License for more details.
13+
14+
// You should have received a copy of the GNU General Public License
15+
// along with the Aleo SDK library. If not, see <https://www.gnu.org/licenses/>.
16+
17+
use super::ViewKey;
18+
use crate::types::{native::GraphKeyNative, Field};
19+
20+
use core::{convert::TryFrom, fmt, ops::Deref, str::FromStr};
21+
use wasm_bindgen::prelude::*;
22+
23+
#[wasm_bindgen]
24+
#[derive(Clone, Debug, PartialEq, Eq)]
25+
pub struct GraphKey(GraphKeyNative);
26+
27+
#[wasm_bindgen]
28+
impl GraphKey {
29+
/// Create a new graph key from a view key.
30+
///
31+
/// @param {ViewKey} view_key View key
32+
/// @returns {GraphKey} Graph key
33+
pub fn from_view_key(view_key: &ViewKey) -> Self {
34+
Self::from(GraphKeyNative::try_from(**view_key).unwrap())
35+
}
36+
37+
/// Create a new graph key from a string representation of a graph key
38+
///
39+
/// @param {string} graph_key String representation of a graph key
40+
/// @returns {GraphKey} Graph key
41+
pub fn from_string(graph_key: &str) -> Self {
42+
Self::from_str(graph_key).unwrap()
43+
}
44+
45+
/// Get a string representation of a graph key
46+
///
47+
/// @returns {string} String representation of a graph key
48+
#[allow(clippy::inherent_to_string_shadow_display)]
49+
pub fn to_string(&self) -> String {
50+
self.0.to_string()
51+
}
52+
53+
/// Get the sk_tag of the graph key. Used to determine ownership of records.
54+
pub fn sk_tag(&self) -> Field {
55+
Field::from(self.0.sk_tag())
56+
}
57+
}
58+
59+
impl Deref for GraphKey {
60+
type Target = GraphKeyNative;
61+
62+
fn deref(&self) -> &Self::Target {
63+
&self.0
64+
}
65+
}
66+
67+
impl fmt::Display for GraphKey {
68+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
69+
write!(f, "{}", self.0)
70+
}
71+
}
72+
73+
impl FromStr for GraphKey {
74+
type Err = anyhow::Error;
75+
76+
fn from_str(graph_key: &str) -> Result<Self, Self::Err> {
77+
Ok(Self(GraphKeyNative::from_str(graph_key)?))
78+
}
79+
}
80+
81+
impl From<GraphKeyNative> for GraphKey {
82+
fn from(value: GraphKeyNative) -> Self {
83+
Self(value)
84+
}
85+
}
86+
87+
impl From<GraphKey> for GraphKeyNative {
88+
fn from(value: GraphKey) -> Self {
89+
value.0
90+
}
91+
}
92+
93+
impl From<&GraphKey> for GraphKeyNative {
94+
fn from(value: &GraphKey) -> Self {
95+
value.0.clone()
96+
}
97+
}
98+
99+
impl From<&GraphKeyNative> for GraphKey {
100+
fn from(value: &GraphKeyNative) -> Self {
101+
Self(value.clone())
102+
}
103+
}
104+
105+
#[cfg(test)]
106+
mod tests {
107+
use super::*;
108+
use crate::PrivateKey;
109+
110+
use wasm_bindgen_test::*;
111+
112+
#[wasm_bindgen_test]
113+
fn test_graph_conversions() {
114+
// Derive a new account.
115+
let private_key = PrivateKey::new();
116+
let view_key = ViewKey::from_private_key(&private_key);
117+
118+
// Test conversion from view key to graph key.
119+
let graph_key = GraphKey::from_view_key(&view_key);
120+
121+
// Test to and from string.
122+
let graph_key_string = graph_key.to_string();
123+
let graph_key_from_string = GraphKey::from_string(&graph_key_string);
124+
assert_eq!(graph_key, graph_key_from_string);
125+
126+
// Test conversion of sk_tag to string and back.
127+
let sk_tag = graph_key.sk_tag();
128+
let sk_tag_string = sk_tag.to_string();
129+
let sk_tag_from_string = Field::from_string(&sk_tag_string).unwrap();
130+
assert_eq!(sk_tag, sk_tag_from_string);
131+
}
132+
}

wasm/src/account/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,15 @@
1717
pub mod address;
1818
pub use address::*;
1919

20+
pub mod compute_key;
21+
pub use compute_key::*;
22+
2023
pub mod encryptor;
2124
pub use encryptor::*;
2225

26+
pub mod graph_key;
27+
pub use graph_key::*;
28+
2329
pub mod private_key;
2430
pub use private_key::*;
2531

0 commit comments

Comments
 (0)