Skip to content

Commit f70e92c

Browse files
[Feature] Re-add Aleo private key encryption to SDK + add private key encryption demo to aleo.tools (ProvableHQ#479)
* Add message signing and record encryption/decryption to Aleo.tools * Add message signing and record encryption/decryption using a sample record to Aleo.tools * Add Alert UI elements for verification + clear state when signing message * Ensure sign & verify state clear on key change * Small formatting nit * Second small formatting nit * Add back private key encryption and re-organize rust SDK dependencies * Add private key encrpytion to aleo.tools * Remove the wasm compilation target of death from SnarkVM_console * Add minor state management updates * update UI with advanced tab for account encrypt + decrypt * improve formatting and fix broken copy buttons --------- Signed-off-by: Mike Turner <[email protected]> Co-authored-by: collin <[email protected]>
1 parent 73afaf7 commit f70e92c

28 files changed

+520
-285
lines changed

Cargo.lock

Lines changed: 4 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rust/Cargo.toml

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,15 +46,25 @@ default-features = false
4646

4747
[dependencies.ureq]
4848
version = "2.6.2"
49+
features = [ "json" ]
4950
optional = true
5051

5152
[dependencies.serde_json]
5253
version = "1.0.91"
5354

54-
[dependencies.snarkvm]
55-
workspace = true
55+
[dependencies.snarkvm-console]
5656
features = [ "parallel" ]
5757
optional = true
58+
version = "0.9.13"
59+
60+
[dependencies.snarkvm-synthesizer]
61+
features = [ "parallel" ]
62+
optional = true
63+
version = "0.9.13"
64+
65+
[dependencies.snarkvm-utilities]
66+
features = [ "parallel" ]
67+
version = "0.9.13"
5868

5969
[dev-dependencies.bencher]
6070
version = "0.1.5"
@@ -63,6 +73,7 @@ version = "0.1.5"
6373
version = "0.3.1"
6474

6575
[features]
66-
default = [ "blocking", "snarkvm" ]
76+
default = [ "blocking", "snarkvm-synthesizer", "snarkvm-console" ]
6777
async = [ "reqwest" ]
6878
blocking = [ "ureq" ]
79+
wasm = [ "snarkvm-console" ]

rust/benches/account.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
#[macro_use]
1818
extern crate bencher;
19-
use snarkvm::console::{
19+
use snarkvm_console::{
2020
account::{Address, PrivateKey},
2121
network::Testnet3,
2222
};

rust/benches/private_key_encryption.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
extern crate bencher;
1919

2020
use aleo_rust::Encryptor;
21-
use snarkvm::console::{account::PrivateKey, network::Testnet3};
21+
use snarkvm_console::{account::PrivateKey, network::Testnet3};
2222

2323
use bencher::Bencher;
2424
use rand::SeedableRng;

rust/src/account/encryptor.rs

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,13 @@
1414
// You should have received a copy of the GNU General Public License
1515
// along with the Aleo library. If not, see <https://www.gnu.org/licenses/>.
1616

17-
use snarkvm::{
18-
console::{
19-
account::PrivateKey,
20-
network::Network,
21-
program::{Ciphertext, Identifier, Literal, Plaintext},
22-
types::Field,
23-
},
24-
prelude::Uniform,
17+
use snarkvm_console::{
18+
account::PrivateKey,
19+
network::Network,
20+
program::{Ciphertext, Identifier, Literal, Plaintext},
21+
types::Field,
2522
};
23+
use snarkvm_utilities::Uniform;
2624

2725
use anyhow::{anyhow, Result};
2826
use once_cell::sync::OnceCell;
@@ -97,7 +95,8 @@ impl<N: Network> Encryptor<N> {
9795
mod tests {
9896
use super::*;
9997

100-
use snarkvm::prelude::{TestRng, Testnet3 as CurrentNetwork};
98+
use snarkvm_console::network::Testnet3 as CurrentNetwork;
99+
use snarkvm_utilities::TestRng;
101100

102101
#[test]
103102
fn test_encryptor_encrypt_and_decrypt() {

rust/src/api/asynchronous.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,11 @@
1717
use crate::AleoAPIClient;
1818

1919
use anyhow::{anyhow, bail, Result};
20-
use snarkvm::{
21-
console::{
22-
program::{Network, ProgramID},
23-
types::Field,
24-
},
25-
synthesizer::{Block, Program, Transaction},
20+
use snarkvm_console::{
21+
program::{Network, ProgramID},
22+
types::Field,
2623
};
24+
use snarkvm_synthesizer::{Block, Program, Transaction};
2725
use std::convert::TryInto;
2826

2927
impl<N: Network> AleoAPIClient<N> {

rust/src/api/blocking.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,12 @@
1717
use crate::AleoAPIClient;
1818

1919
use anyhow::{anyhow, bail, Result};
20-
use snarkvm::{
21-
console::{
22-
account::ViewKey,
23-
program::{Ciphertext, Network, ProgramID, Record},
24-
types::Field,
25-
},
26-
synthesizer::{Block, Program, Transaction},
20+
use snarkvm_console::{
21+
account::ViewKey,
22+
program::{Ciphertext, Network, ProgramID, Record},
23+
types::Field,
2724
};
25+
use snarkvm_synthesizer::{Block, Program, Transaction};
2826
use std::{convert::TryInto, ops::Range};
2927

3028
#[cfg(not(feature = "async"))]
@@ -174,7 +172,7 @@ mod tests {
174172
use super::*;
175173

176174
use crate::testnet3;
177-
use snarkvm::console::{account::PrivateKey, network::Testnet3};
175+
use snarkvm_console::{account::PrivateKey, network::Testnet3};
178176
use std::{convert::TryFrom, str::FromStr};
179177

180178
type N = Testnet3;

rust/src/api/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ pub mod asynchronous;
2424
#[cfg(feature = "async")]
2525
pub use asynchronous::*;
2626

27-
use snarkvm::{console::program::Network, prelude::Testnet3};
27+
use snarkvm_console::{network::Testnet3, program::Network};
2828
use std::marker::PhantomData;
2929

3030
pub struct AleoAPIClient<N: Network> {

sdk/src/account.ts

Lines changed: 32 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
PrivateKey,
44
Signature,
55
ViewKey,
6+
PrivateKeyCiphertext,
67
RecordCiphertext,
78
} from "@aleohq/wasm";
89

@@ -56,25 +57,25 @@ export class Account {
5657
this.adr = Address.from_private_key(this.pk);
5758
}
5859

59-
// /**
60-
// * Attempts to create an account from a private key ciphertext
61-
// * @param {PrivateKeyCiphertext | string} ciphertext
62-
// * @param {string} password
63-
// * @returns {PrivateKey | Error}
64-
// *
65-
// * @example
66-
// * let ciphertext = PrivateKey.newEncrypted("password");
67-
// * let account = Account.fromCiphertext(ciphertext, "password");
68-
// */
69-
// public static fromCiphertext(ciphertext: PrivateKeyCiphertext | string, password: string) {
70-
// try {
71-
// ciphertext = (typeof ciphertext === "string") ? PrivateKeyCiphertext.fromString(ciphertext) : ciphertext;
72-
// const pk = PrivateKey.fromPrivateKeyCiphertext(ciphertext, password);
73-
// return new Account({ privateKey: pk.to_string() });
74-
// } catch(e) {
75-
// throw new Error("Wrong password or invalid ciphertext");
76-
// }
77-
// }
60+
/**
61+
* Attempts to create an account from a private key ciphertext
62+
* @param {PrivateKeyCiphertext | string} ciphertext
63+
* @param {string} password
64+
* @returns {PrivateKey | Error}
65+
*
66+
* @example
67+
* let ciphertext = PrivateKey.newEncrypted("password");
68+
* let account = Account.fromCiphertext(ciphertext, "password");
69+
*/
70+
public static fromCiphertext(ciphertext: PrivateKeyCiphertext | string, password: string) {
71+
try {
72+
ciphertext = (typeof ciphertext === "string") ? PrivateKeyCiphertext.fromString(ciphertext) : ciphertext;
73+
const pk = PrivateKey.fromPrivateKeyCiphertext(ciphertext, password);
74+
return new Account({ privateKey: pk.to_string() });
75+
} catch(e) {
76+
throw new Error("Wrong password or invalid ciphertext");
77+
}
78+
}
7879

7980
private privateKeyFromParams(params: AccountParam) {
8081
if (params.seed) {
@@ -102,18 +103,18 @@ export class Account {
102103
return this.address().to_string()
103104
}
104105

105-
// /**
106-
// * Encrypt the account's private key with a password
107-
// * @param {string} ciphertext
108-
// * @returns {PrivateKeyCiphertext}
109-
// *
110-
// * @example
111-
// * let account = new Account();
112-
// * let ciphertext = account.encryptAccount("password");
113-
// */
114-
// encryptAccount(password: string) {
115-
// return this.pk.toCiphertext(password);
116-
// }
106+
/**
107+
* Encrypt the account's private key with a password
108+
* @param {string} ciphertext
109+
* @returns {PrivateKeyCiphertext}
110+
*
111+
* @example
112+
* let account = new Account();
113+
* let ciphertext = account.encryptAccount("password");
114+
*/
115+
encryptAccount(password: string) {
116+
return this.pk.toCiphertext(password);
117+
}
117118

118119
/**
119120
* Decrypts a Record in ciphertext form into plaintext

sdk/tests/account.test.ts

Lines changed: 35 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -60,41 +60,41 @@ describe('Account', () => {
6060
expect(account.address().to_string()).toEqual(addressString);
6161
expect(account.toString()).toEqual(addressString);
6262
});
63-
//
64-
// test('can encrypt an account and decrypt to the same account', () => {
65-
// const newAccount = new Account();
66-
// const privateKeyCiphertext = newAccount.encryptAccount("mypassword");
67-
// const privateKeyCiphertextString = privateKeyCiphertext.toString();
68-
//
69-
// // Generate account from valid private key string
70-
// const accountFromString = Account.fromCiphertext(privateKeyCiphertextString, "mypassword");
71-
// const accountFromObject = Account.fromCiphertext(privateKeyCiphertext, "mypassword");
72-
//
73-
// for (const account of [accountFromString, accountFromObject]) {
74-
// // Test that expected output is generated
75-
// expect(account.privateKey().to_string()).toEqual(newAccount.privateKey().to_string());
76-
// expect(account.viewKey().to_string()).toEqual(newAccount.viewKey().to_string());
77-
// expect(account.address().to_string()).toEqual(newAccount.toString());
78-
// expect(account.toString()).toEqual(newAccount.toString());
79-
// }
80-
// });
81-
//
82-
// test('fails to create an account from a bad password', () => {
83-
// const newAccount = new Account();
84-
// const privateKeyCiphertext = newAccount.encryptAccount("mypassword");
85-
// const privateKeyCiphertextString = privateKeyCiphertext.toString();
86-
//
87-
// try {
88-
// Account.fromCiphertext(privateKeyCiphertextString, "badpassword");
89-
// Account.fromCiphertext(privateKeyCiphertext, "badpassword");
90-
//
91-
// // Should not get here
92-
// expect(true).toBe(false);
93-
// } catch (err) {
94-
// // The account should fail to decrypt
95-
// expect(true).toBe(true);
96-
// }
97-
// });
63+
64+
test('can encrypt an account and decrypt to the same account', () => {
65+
const newAccount = new Account();
66+
const privateKeyCiphertext = newAccount.encryptAccount("mypassword");
67+
const privateKeyCiphertextString = privateKeyCiphertext.toString();
68+
69+
// Generate account from valid private key string
70+
const accountFromString = Account.fromCiphertext(privateKeyCiphertextString, "mypassword");
71+
const accountFromObject = Account.fromCiphertext(privateKeyCiphertext, "mypassword");
72+
73+
for (const account of [accountFromString, accountFromObject]) {
74+
// Test that expected output is generated
75+
expect(account.privateKey().to_string()).toEqual(newAccount.privateKey().to_string());
76+
expect(account.viewKey().to_string()).toEqual(newAccount.viewKey().to_string());
77+
expect(account.address().to_string()).toEqual(newAccount.toString());
78+
expect(account.toString()).toEqual(newAccount.toString());
79+
}
80+
});
81+
82+
test('fails to create an account from a bad password', () => {
83+
const newAccount = new Account();
84+
const privateKeyCiphertext = newAccount.encryptAccount("mypassword");
85+
const privateKeyCiphertextString = privateKeyCiphertext.toString();
86+
87+
try {
88+
Account.fromCiphertext(privateKeyCiphertextString, "badpassword");
89+
Account.fromCiphertext(privateKeyCiphertext, "badpassword");
90+
91+
// Should not get here
92+
expect(true).toBe(false);
93+
} catch (err) {
94+
// The account should fail to decrypt
95+
expect(true).toBe(true);
96+
}
97+
});
9898
});
9999

100100
describe('View Key Record Decryption', () => {

0 commit comments

Comments
 (0)