mirror of
https://github.com/logos-blockchain/lssa.git
synced 2026-02-17 11:53:14 +00:00
Merge pull request #246 from logos-blockchain/marvin/private_keys
private key protocol fixes
This commit is contained in:
commit
8cf73c00a9
@ -92,7 +92,7 @@ wallet account new private
|
||||
# Output:
|
||||
Generated new account with account_id Private/HMRHZdPw4pbyPVZHNGrV6K5AA95wACFsHTRST84fr3CF
|
||||
With npk 6a2dfe433cf28e525aa0196d719be3c16146f7ee358ca39595323f94fde38f93
|
||||
With ipk 03d59abf4bee974cc12ddb44641c19f0b5441fef39191f047c988c29a77252a577
|
||||
With vpk 03d59abf4bee974cc12ddb44641c19f0b5441fef39191f047c988c29a77252a577
|
||||
```
|
||||
|
||||
2. Create the token (Token B):
|
||||
|
||||
@ -154,11 +154,11 @@ wallet account new private
|
||||
# Output:
|
||||
Generated new account with account_id Private/HacPU3hakLYzWtSqUPw6TUr8fqoMieVWovsUR6sJf7cL
|
||||
With npk e6366f79d026c8bd64ae6b3d601f0506832ec682ab54897f205fffe64ec0d951
|
||||
With ipk 02ddc96d0eb56e00ce14994cfdaec5ae1f76244180a919545983156e3519940a17
|
||||
With vpk 02ddc96d0eb56e00ce14994cfdaec5ae1f76244180a919545983156e3519940a17
|
||||
```
|
||||
|
||||
> [!Tip]
|
||||
> Focus on the account ID for now. The `npk` and `ipk` values are stored locally and used to build privacy-preserving transactions. The private account ID is derived from `npk`.
|
||||
> Focus on the account ID for now. The `npk` and `vpk` values are stored locally and used to build privacy-preserving transactions. The private account ID is derived from `npk`.
|
||||
|
||||
Just like public accounts, new private accounts start out uninitialized:
|
||||
|
||||
@ -228,17 +228,17 @@ wallet account new private
|
||||
# Output:
|
||||
Generated new account with account_id Private/AukXPRBmrYVqoqEW2HTs7N3hvTn3qdNFDcxDHVr5hMm5
|
||||
With npk 0c95ebc4b3830f53da77bb0b80a276a776cdcf6410932acc718dcdb3f788a00e
|
||||
With ipk 039fd12a3674a880d3e917804129141e4170d419d1f9e28a3dcf979c1f2369cb72
|
||||
With vpk 039fd12a3674a880d3e917804129141e4170d419d1f9e28a3dcf979c1f2369cb72
|
||||
```
|
||||
|
||||
> [!Tip]
|
||||
> Ignore the private account ID here and use the `npk` and `ipk` values to send to a foreign private account.
|
||||
> Ignore the private account ID here and use the `npk` and `vpk` values to send to a foreign private account.
|
||||
|
||||
```bash
|
||||
wallet auth-transfer send \
|
||||
--from Public/Ev1JprP9BmhbFVQyBcbznU8bAXcwrzwRoPTetXdQPAWS \
|
||||
--to-npk 0c95ebc4b3830f53da77bb0b80a276a776cdcf6410932acc718dcdb3f788a00e \
|
||||
--to-ipk 039fd12a3674a880d3e917804129141e4170d419d1f9e28a3dcf979c1f2369cb72 \
|
||||
--to-vpk 039fd12a3674a880d3e917804129141e4170d419d1f9e28a3dcf979c1f2369cb72 \
|
||||
--amount 3
|
||||
```
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -97,7 +97,7 @@ _wallet_auth_transfer() {
|
||||
'--from[Source account ID]:from_account:_wallet_account_ids' \
|
||||
'--to[Destination account ID (for owned accounts)]:to_account:_wallet_account_ids' \
|
||||
'--to-npk[Destination nullifier public key (for foreign private accounts)]:npk:' \
|
||||
'--to-ipk[Destination viewing public key (for foreign private accounts)]:ipk:' \
|
||||
'--to-vpk[Destination viewing public key (for foreign private accounts)]:vpk:' \
|
||||
'--amount[Amount of native tokens to send]:amount:'
|
||||
;;
|
||||
esac
|
||||
@ -164,7 +164,7 @@ _wallet_account() {
|
||||
get)
|
||||
_arguments \
|
||||
'(-r --raw)'{-r,--raw}'[Get raw account data]' \
|
||||
'(-k --keys)'{-k,--keys}'[Display keys (pk for public accounts, npk/ipk for private accounts)]' \
|
||||
'(-k --keys)'{-k,--keys}'[Display keys (pk for public accounts, npk/vpk for private accounts)]' \
|
||||
'(-a --account-id)'{-a,--account-id}'[Account ID to query]:account_id:_wallet_account_ids'
|
||||
;;
|
||||
list|ls)
|
||||
@ -255,7 +255,7 @@ _wallet_token() {
|
||||
'--from[Source holding account ID]:from_account:_wallet_account_ids' \
|
||||
'--to[Destination holding account ID (for owned accounts)]:to_account:_wallet_account_ids' \
|
||||
'--to-npk[Destination nullifier public key (for foreign private accounts)]:npk:' \
|
||||
'--to-ipk[Destination viewing public key (for foreign private accounts)]:ipk:' \
|
||||
'--to-vpk[Destination viewing public key (for foreign private accounts)]:vpk:' \
|
||||
'--amount[Amount of tokens to send]:amount:'
|
||||
;;
|
||||
burn)
|
||||
@ -269,7 +269,7 @@ _wallet_token() {
|
||||
'--definition[Definition account ID]:definition_account:_wallet_account_ids' \
|
||||
'--holder[Holder account ID (for owned accounts)]:holder_account:_wallet_account_ids' \
|
||||
'--holder-npk[Holder nullifier public key (for foreign private accounts)]:npk:' \
|
||||
'--holder-ipk[Holder viewing public key (for foreign private accounts)]:ipk:' \
|
||||
'--holder-vpk[Holder viewing public key (for foreign private accounts)]:vpk:' \
|
||||
'--amount[Amount of tokens to mint]:amount:'
|
||||
;;
|
||||
esac
|
||||
|
||||
@ -29,40 +29,7 @@
|
||||
],
|
||||
"initial_commitments": [
|
||||
{
|
||||
"npk": [
|
||||
63,
|
||||
202,
|
||||
178,
|
||||
231,
|
||||
183,
|
||||
82,
|
||||
237,
|
||||
212,
|
||||
216,
|
||||
221,
|
||||
215,
|
||||
255,
|
||||
153,
|
||||
101,
|
||||
177,
|
||||
161,
|
||||
254,
|
||||
210,
|
||||
128,
|
||||
122,
|
||||
54,
|
||||
190,
|
||||
230,
|
||||
151,
|
||||
183,
|
||||
64,
|
||||
225,
|
||||
229,
|
||||
113,
|
||||
1,
|
||||
228,
|
||||
97
|
||||
],
|
||||
"npk": [13, 25, 40, 5, 198, 248, 210, 248, 237, 121, 124, 145, 186, 142, 253, 216, 236, 69, 193, 32, 166, 167, 49, 133, 172, 111, 159, 46, 84, 17, 157, 23],
|
||||
"account": {
|
||||
"program_owner": [
|
||||
0,
|
||||
@ -80,40 +47,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"npk": [
|
||||
192,
|
||||
251,
|
||||
166,
|
||||
243,
|
||||
167,
|
||||
236,
|
||||
84,
|
||||
249,
|
||||
35,
|
||||
136,
|
||||
130,
|
||||
172,
|
||||
219,
|
||||
225,
|
||||
161,
|
||||
139,
|
||||
229,
|
||||
89,
|
||||
243,
|
||||
125,
|
||||
194,
|
||||
213,
|
||||
209,
|
||||
30,
|
||||
23,
|
||||
174,
|
||||
100,
|
||||
244,
|
||||
124,
|
||||
74,
|
||||
140,
|
||||
47
|
||||
],
|
||||
"npk": [32, 67, 72, 164, 106, 53, 66, 239, 141, 15, 52, 230, 136, 177, 2, 236, 207, 243, 134, 135, 210, 143, 87, 232, 215, 128, 194, 120, 113, 224, 4, 165],
|
||||
"account": {
|
||||
"program_owner": [
|
||||
0,
|
||||
|
||||
@ -102,7 +102,7 @@ async fn amm_public() -> Result<()> {
|
||||
from: format_public_account_id(supply_account_id_1),
|
||||
to: Some(format_public_account_id(recipient_account_id_1)),
|
||||
to_npk: None,
|
||||
to_ipk: None,
|
||||
to_vpk: None,
|
||||
amount: 7,
|
||||
};
|
||||
|
||||
@ -126,7 +126,7 @@ async fn amm_public() -> Result<()> {
|
||||
from: format_public_account_id(supply_account_id_2),
|
||||
to: Some(format_public_account_id(recipient_account_id_2)),
|
||||
to_npk: None,
|
||||
to_ipk: None,
|
||||
to_vpk: None,
|
||||
amount: 7,
|
||||
};
|
||||
|
||||
|
||||
@ -26,7 +26,7 @@ async fn private_transfer_to_owned_account() -> Result<()> {
|
||||
from: format_private_account_id(from),
|
||||
to: Some(format_private_account_id(to)),
|
||||
to_npk: None,
|
||||
to_ipk: None,
|
||||
to_vpk: None,
|
||||
amount: 100,
|
||||
});
|
||||
|
||||
@ -59,13 +59,13 @@ async fn private_transfer_to_foreign_account() -> Result<()> {
|
||||
let from: AccountId = ctx.existing_private_accounts()[0];
|
||||
let to_npk = NullifierPublicKey([42; 32]);
|
||||
let to_npk_string = hex::encode(to_npk.0);
|
||||
let to_ipk = Secp256k1Point::from_scalar(to_npk.0);
|
||||
let to_vpk = Secp256k1Point::from_scalar(to_npk.0);
|
||||
|
||||
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
|
||||
from: format_private_account_id(from),
|
||||
to: None,
|
||||
to_npk: Some(to_npk_string),
|
||||
to_ipk: Some(hex::encode(to_ipk.0)),
|
||||
to_vpk: Some(hex::encode(to_vpk.0)),
|
||||
amount: 100,
|
||||
});
|
||||
|
||||
@ -113,7 +113,7 @@ async fn deshielded_transfer_to_public_account() -> Result<()> {
|
||||
from: format_private_account_id(from),
|
||||
to: Some(format_public_account_id(to)),
|
||||
to_npk: None,
|
||||
to_ipk: None,
|
||||
to_vpk: None,
|
||||
amount: 100,
|
||||
});
|
||||
|
||||
@ -168,12 +168,12 @@ async fn private_transfer_to_owned_account_using_claiming_path() -> Result<()> {
|
||||
.cloned()
|
||||
.context("Failed to get private account")?;
|
||||
|
||||
// Send to this account using claiming path (using npk and ipk instead of account ID)
|
||||
// Send to this account using claiming path (using npk and vpk instead of account ID)
|
||||
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
|
||||
from: format_private_account_id(from),
|
||||
to: None,
|
||||
to_npk: Some(hex::encode(to_keys.nullifer_public_key.0)),
|
||||
to_ipk: Some(hex::encode(to_keys.incoming_viewing_public_key.0)),
|
||||
to_vpk: Some(hex::encode(to_keys.viewing_public_key.0)),
|
||||
amount: 100,
|
||||
});
|
||||
|
||||
@ -221,7 +221,7 @@ async fn shielded_transfer_to_owned_private_account() -> Result<()> {
|
||||
from: format_public_account_id(from),
|
||||
to: Some(format_private_account_id(to)),
|
||||
to_npk: None,
|
||||
to_ipk: None,
|
||||
to_vpk: None,
|
||||
amount: 100,
|
||||
});
|
||||
|
||||
@ -256,14 +256,14 @@ async fn shielded_transfer_to_foreign_account() -> Result<()> {
|
||||
|
||||
let to_npk = NullifierPublicKey([42; 32]);
|
||||
let to_npk_string = hex::encode(to_npk.0);
|
||||
let to_ipk = Secp256k1Point::from_scalar(to_npk.0);
|
||||
let to_vpk = Secp256k1Point::from_scalar(to_npk.0);
|
||||
let from: AccountId = ctx.existing_public_accounts()[0];
|
||||
|
||||
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
|
||||
from: format_public_account_id(from),
|
||||
to: None,
|
||||
to_npk: Some(to_npk_string),
|
||||
to_ipk: Some(hex::encode(to_ipk.0)),
|
||||
to_vpk: Some(hex::encode(to_vpk.0)),
|
||||
amount: 100,
|
||||
});
|
||||
|
||||
@ -325,12 +325,12 @@ async fn private_transfer_to_owned_account_continuous_run_path() -> Result<()> {
|
||||
.cloned()
|
||||
.context("Failed to get private account")?;
|
||||
|
||||
// Send transfer using nullifier and incoming viewing public keys
|
||||
// Send transfer using nullifier and viewing public keys
|
||||
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
|
||||
from: format_private_account_id(from),
|
||||
to: None,
|
||||
to_npk: Some(hex::encode(to_keys.nullifer_public_key.0)),
|
||||
to_ipk: Some(hex::encode(to_keys.incoming_viewing_public_key.0)),
|
||||
to_vpk: Some(hex::encode(to_keys.viewing_public_key.0)),
|
||||
amount: 100,
|
||||
});
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ async fn successful_transfer_to_existing_account() -> Result<()> {
|
||||
from: format_public_account_id(ctx.existing_public_accounts()[0]),
|
||||
to: Some(format_public_account_id(ctx.existing_public_accounts()[1])),
|
||||
to_npk: None,
|
||||
to_ipk: None,
|
||||
to_vpk: None,
|
||||
amount: 100,
|
||||
});
|
||||
|
||||
@ -72,7 +72,7 @@ pub async fn successful_transfer_to_new_account() -> Result<()> {
|
||||
from: format_public_account_id(ctx.existing_public_accounts()[0]),
|
||||
to: Some(format_public_account_id(new_persistent_account_id)),
|
||||
to_npk: None,
|
||||
to_ipk: None,
|
||||
to_vpk: None,
|
||||
amount: 100,
|
||||
});
|
||||
|
||||
@ -108,7 +108,7 @@ async fn failed_transfer_with_insufficient_balance() -> Result<()> {
|
||||
from: format_public_account_id(ctx.existing_public_accounts()[0]),
|
||||
to: Some(format_public_account_id(ctx.existing_public_accounts()[1])),
|
||||
to_npk: None,
|
||||
to_ipk: None,
|
||||
to_vpk: None,
|
||||
amount: 1000000,
|
||||
});
|
||||
|
||||
@ -146,7 +146,7 @@ async fn two_consecutive_successful_transfers() -> Result<()> {
|
||||
from: format_public_account_id(ctx.existing_public_accounts()[0]),
|
||||
to: Some(format_public_account_id(ctx.existing_public_accounts()[1])),
|
||||
to_npk: None,
|
||||
to_ipk: None,
|
||||
to_vpk: None,
|
||||
amount: 100,
|
||||
});
|
||||
|
||||
@ -178,7 +178,7 @@ async fn two_consecutive_successful_transfers() -> Result<()> {
|
||||
from: format_public_account_id(ctx.existing_public_accounts()[0]),
|
||||
to: Some(format_public_account_id(ctx.existing_public_accounts()[1])),
|
||||
to_npk: None,
|
||||
to_ipk: None,
|
||||
to_vpk: None,
|
||||
amount: 100,
|
||||
});
|
||||
|
||||
|
||||
@ -50,7 +50,7 @@ async fn restore_keys_from_seed() -> Result<()> {
|
||||
from: format_private_account_id(from),
|
||||
to: Some(format_private_account_id(to_account_id1)),
|
||||
to_npk: None,
|
||||
to_ipk: None,
|
||||
to_vpk: None,
|
||||
amount: 100,
|
||||
});
|
||||
wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
|
||||
@ -60,7 +60,7 @@ async fn restore_keys_from_seed() -> Result<()> {
|
||||
from: format_private_account_id(from),
|
||||
to: Some(format_private_account_id(to_account_id2)),
|
||||
to_npk: None,
|
||||
to_ipk: None,
|
||||
to_vpk: None,
|
||||
amount: 101,
|
||||
});
|
||||
wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
|
||||
@ -96,7 +96,7 @@ async fn restore_keys_from_seed() -> Result<()> {
|
||||
from: format_public_account_id(from),
|
||||
to: Some(format_public_account_id(to_account_id3)),
|
||||
to_npk: None,
|
||||
to_ipk: None,
|
||||
to_vpk: None,
|
||||
amount: 102,
|
||||
});
|
||||
wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
|
||||
@ -106,7 +106,7 @@ async fn restore_keys_from_seed() -> Result<()> {
|
||||
from: format_public_account_id(from),
|
||||
to: Some(format_public_account_id(to_account_id4)),
|
||||
to_npk: None,
|
||||
to_ipk: None,
|
||||
to_vpk: None,
|
||||
amount: 103,
|
||||
});
|
||||
wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
|
||||
@ -169,7 +169,7 @@ async fn restore_keys_from_seed() -> Result<()> {
|
||||
from: format_private_account_id(to_account_id1),
|
||||
to: Some(format_private_account_id(to_account_id2)),
|
||||
to_npk: None,
|
||||
to_ipk: None,
|
||||
to_vpk: None,
|
||||
amount: 10,
|
||||
});
|
||||
wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
|
||||
@ -178,7 +178,7 @@ async fn restore_keys_from_seed() -> Result<()> {
|
||||
from: format_public_account_id(to_account_id3),
|
||||
to: Some(format_public_account_id(to_account_id4)),
|
||||
to_npk: None,
|
||||
to_ipk: None,
|
||||
to_vpk: None,
|
||||
amount: 11,
|
||||
});
|
||||
wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
|
||||
|
||||
@ -115,7 +115,7 @@ async fn create_and_transfer_public_token() -> Result<()> {
|
||||
from: format_public_account_id(supply_account_id),
|
||||
to: Some(format_public_account_id(recipient_account_id)),
|
||||
to_npk: None,
|
||||
to_ipk: None,
|
||||
to_vpk: None,
|
||||
amount: transfer_amount,
|
||||
};
|
||||
|
||||
@ -208,7 +208,7 @@ async fn create_and_transfer_public_token() -> Result<()> {
|
||||
definition: format_public_account_id(definition_account_id),
|
||||
holder: Some(format_public_account_id(recipient_account_id)),
|
||||
holder_npk: None,
|
||||
holder_ipk: None,
|
||||
holder_vpk: None,
|
||||
amount: mint_amount,
|
||||
};
|
||||
|
||||
@ -343,7 +343,7 @@ async fn create_and_transfer_token_with_private_supply() -> Result<()> {
|
||||
from: format_private_account_id(supply_account_id),
|
||||
to: Some(format_private_account_id(recipient_account_id)),
|
||||
to_npk: None,
|
||||
to_ipk: None,
|
||||
to_vpk: None,
|
||||
amount: transfer_amount,
|
||||
};
|
||||
|
||||
@ -525,7 +525,7 @@ async fn create_token_with_private_definition() -> Result<()> {
|
||||
definition: format_private_account_id(definition_account_id),
|
||||
holder: Some(format_public_account_id(recipient_account_id_public)),
|
||||
holder_npk: None,
|
||||
holder_ipk: None,
|
||||
holder_vpk: None,
|
||||
amount: mint_amount_public,
|
||||
};
|
||||
|
||||
@ -572,7 +572,7 @@ async fn create_token_with_private_definition() -> Result<()> {
|
||||
definition: format_private_account_id(definition_account_id),
|
||||
holder: Some(format_private_account_id(recipient_account_id_private)),
|
||||
holder_npk: None,
|
||||
holder_ipk: None,
|
||||
holder_vpk: None,
|
||||
amount: mint_amount_private,
|
||||
};
|
||||
|
||||
@ -701,7 +701,7 @@ async fn create_token_with_private_definition_and_supply() -> Result<()> {
|
||||
from: format_private_account_id(supply_account_id),
|
||||
to: Some(format_private_account_id(recipient_account_id)),
|
||||
to_npk: None,
|
||||
to_ipk: None,
|
||||
to_vpk: None,
|
||||
amount: transfer_amount,
|
||||
};
|
||||
|
||||
@ -819,7 +819,7 @@ async fn shielded_token_transfer() -> Result<()> {
|
||||
from: format_public_account_id(supply_account_id),
|
||||
to: Some(format_private_account_id(recipient_account_id)),
|
||||
to_npk: None,
|
||||
to_ipk: None,
|
||||
to_vpk: None,
|
||||
amount: transfer_amount,
|
||||
};
|
||||
|
||||
@ -933,7 +933,7 @@ async fn deshielded_token_transfer() -> Result<()> {
|
||||
from: format_private_account_id(supply_account_id),
|
||||
to: Some(format_public_account_id(recipient_account_id)),
|
||||
to_npk: None,
|
||||
to_ipk: None,
|
||||
to_vpk: None,
|
||||
amount: transfer_amount,
|
||||
};
|
||||
|
||||
@ -1056,7 +1056,7 @@ async fn token_claiming_path_with_private_accounts() -> Result<()> {
|
||||
definition: format_private_account_id(definition_account_id),
|
||||
holder: None,
|
||||
holder_npk: Some(hex::encode(holder_keys.nullifer_public_key.0)),
|
||||
holder_ipk: Some(hex::encode(holder_keys.incoming_viewing_public_key.0)),
|
||||
holder_vpk: Some(hex::encode(holder_keys.viewing_public_key.0)),
|
||||
amount: mint_amount,
|
||||
};
|
||||
|
||||
|
||||
@ -16,7 +16,7 @@ use nssa::{
|
||||
use nssa_core::{
|
||||
MembershipProof, NullifierPublicKey,
|
||||
account::{AccountWithMetadata, data::Data},
|
||||
encryption::IncomingViewingPublicKey,
|
||||
encryption::ViewingPublicKey,
|
||||
};
|
||||
use tokio::test;
|
||||
|
||||
@ -192,8 +192,8 @@ impl TpsTestManager {
|
||||
fn build_privacy_transaction() -> PrivacyPreservingTransaction {
|
||||
let program = Program::authenticated_transfer_program();
|
||||
let sender_nsk = [1; 32];
|
||||
let sender_isk = [99; 32];
|
||||
let sender_ipk = IncomingViewingPublicKey::from_scalar(sender_isk);
|
||||
let sender_vsk = [99; 32];
|
||||
let sender_vpk = ViewingPublicKey::from_scalar(sender_vsk);
|
||||
let sender_npk = NullifierPublicKey::from(&sender_nsk);
|
||||
let sender_pre = AccountWithMetadata::new(
|
||||
Account {
|
||||
@ -206,18 +206,18 @@ fn build_privacy_transaction() -> PrivacyPreservingTransaction {
|
||||
AccountId::from(&sender_npk),
|
||||
);
|
||||
let recipient_nsk = [2; 32];
|
||||
let recipient_isk = [99; 32];
|
||||
let recipient_ipk = IncomingViewingPublicKey::from_scalar(recipient_isk);
|
||||
let recipient_vsk = [99; 32];
|
||||
let recipient_vpk = ViewingPublicKey::from_scalar(recipient_vsk);
|
||||
let recipient_npk = NullifierPublicKey::from(&recipient_nsk);
|
||||
let recipient_pre =
|
||||
AccountWithMetadata::new(Account::default(), false, AccountId::from(&recipient_npk));
|
||||
|
||||
let eph_holder_from = EphemeralKeyHolder::new(&sender_npk);
|
||||
let sender_ss = eph_holder_from.calculate_shared_secret_sender(&sender_ipk);
|
||||
let sender_ss = eph_holder_from.calculate_shared_secret_sender(&sender_vpk);
|
||||
let sender_epk = eph_holder_from.generate_ephemeral_public_key();
|
||||
|
||||
let eph_holder_to = EphemeralKeyHolder::new(&recipient_npk);
|
||||
let recipient_ss = eph_holder_to.calculate_shared_secret_sender(&recipient_ipk);
|
||||
let recipient_ss = eph_holder_to.calculate_shared_secret_sender(&recipient_vpk);
|
||||
let recipient_epk = eph_holder_from.generate_ephemeral_public_key();
|
||||
|
||||
let balance_to_move: u128 = 1;
|
||||
@ -246,8 +246,8 @@ fn build_privacy_transaction() -> PrivacyPreservingTransaction {
|
||||
vec![],
|
||||
vec![],
|
||||
vec![
|
||||
(sender_npk, sender_ipk, sender_epk),
|
||||
(recipient_npk, recipient_ipk, recipient_epk),
|
||||
(sender_npk, sender_vpk, sender_epk),
|
||||
(recipient_npk, recipient_vpk, recipient_epk),
|
||||
],
|
||||
output,
|
||||
)
|
||||
|
||||
@ -600,10 +600,10 @@ fn test_wallet_ffi_get_private_account_keys() -> Result<()> {
|
||||
.0;
|
||||
|
||||
let expected_npk = &key_chain.nullifer_public_key;
|
||||
let expected_ivk = &key_chain.incoming_viewing_public_key;
|
||||
let expected_vpk = &key_chain.viewing_public_key;
|
||||
|
||||
assert_eq!(&keys.npk(), expected_npk);
|
||||
assert_eq!(&keys.ivk().unwrap(), expected_ivk);
|
||||
assert_eq!(&keys.vpk().unwrap(), expected_vpk);
|
||||
|
||||
unsafe {
|
||||
wallet_ffi_free_private_account_keys((&mut keys) as *mut FfiPrivateAccountKeys);
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
use nssa_core::{
|
||||
NullifierPublicKey, SharedSecretKey,
|
||||
encryption::{EphemeralPublicKey, EphemeralSecretKey, IncomingViewingPublicKey},
|
||||
encryption::{EphemeralPublicKey, EphemeralSecretKey, ViewingPublicKey},
|
||||
};
|
||||
use rand::{RngCore, rngs::OsRng};
|
||||
use sha2::Digest;
|
||||
@ -13,12 +13,12 @@ pub struct EphemeralKeyHolder {
|
||||
}
|
||||
|
||||
pub fn produce_one_sided_shared_secret_receiver(
|
||||
ipk: &IncomingViewingPublicKey,
|
||||
vpk: &ViewingPublicKey,
|
||||
) -> (SharedSecretKey, EphemeralPublicKey) {
|
||||
let mut esk = [0; 32];
|
||||
OsRng.fill_bytes(&mut esk);
|
||||
(
|
||||
SharedSecretKey::new(&esk, ipk),
|
||||
SharedSecretKey::new(&esk, vpk),
|
||||
EphemeralPublicKey::from_scalar(esk),
|
||||
)
|
||||
}
|
||||
@ -42,11 +42,8 @@ impl EphemeralKeyHolder {
|
||||
|
||||
pub fn calculate_shared_secret_sender(
|
||||
&self,
|
||||
receiver_incoming_viewing_public_key: &IncomingViewingPublicKey,
|
||||
receiver_viewing_public_key: &ViewingPublicKey,
|
||||
) -> SharedSecretKey {
|
||||
SharedSecretKey::new(
|
||||
&self.ephemeral_secret_key,
|
||||
receiver_incoming_viewing_public_key,
|
||||
)
|
||||
SharedSecretKey::new(&self.ephemeral_secret_key, receiver_viewing_public_key)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
use k256::{Scalar, elliptic_curve::PrimeField};
|
||||
use nssa_core::encryption::IncomingViewingPublicKey;
|
||||
use nssa_core::{NullifierPublicKey, encryption::ViewingPublicKey};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::key_management::{
|
||||
@ -18,7 +18,7 @@ pub struct ChildKeysPrivate {
|
||||
|
||||
impl KeyNode for ChildKeysPrivate {
|
||||
fn root(seed: [u8; 64]) -> Self {
|
||||
let hash_value = hmac_sha512::HMAC::mac(seed, "NSSA_master_priv");
|
||||
let hash_value = hmac_sha512::HMAC::mac(seed, b"LEE_master_priv");
|
||||
|
||||
let ssk = SecretSpendingKey(
|
||||
*hash_value
|
||||
@ -29,23 +29,21 @@ impl KeyNode for ChildKeysPrivate {
|
||||
.last_chunk::<32>()
|
||||
.expect("hash_value is 64 bytes, must be safe to get last 32");
|
||||
|
||||
let nsk = ssk.generate_nullifier_secret_key();
|
||||
let isk = ssk.generate_incoming_viewing_secret_key();
|
||||
let ovk = ssk.generate_outgoing_viewing_secret_key();
|
||||
let nsk = ssk.generate_nullifier_secret_key(None);
|
||||
let vsk = ssk.generate_viewing_secret_key(None);
|
||||
|
||||
let npk = (&nsk).into();
|
||||
let ipk = IncomingViewingPublicKey::from_scalar(isk);
|
||||
let npk = NullifierPublicKey::from(&nsk);
|
||||
let vpk = ViewingPublicKey::from_scalar(vsk);
|
||||
|
||||
Self {
|
||||
value: (
|
||||
KeyChain {
|
||||
secret_spending_key: ssk,
|
||||
nullifer_public_key: npk,
|
||||
incoming_viewing_public_key: ipk,
|
||||
viewing_public_key: vpk,
|
||||
private_key_holder: PrivateKeyHolder {
|
||||
nullifier_secret_key: nsk,
|
||||
incoming_viewing_secret_key: isk,
|
||||
outgoing_viewing_secret_key: ovk,
|
||||
viewing_secret_key: vsk,
|
||||
},
|
||||
},
|
||||
nssa::Account::default(),
|
||||
@ -56,27 +54,14 @@ impl KeyNode for ChildKeysPrivate {
|
||||
}
|
||||
|
||||
fn nth_child(&self, cci: u32) -> Self {
|
||||
let parent_pt = Scalar::from_repr(
|
||||
self.value
|
||||
.0
|
||||
.private_key_holder
|
||||
.outgoing_viewing_secret_key
|
||||
.into(),
|
||||
)
|
||||
.expect("Key generated as scalar, must be valid representation")
|
||||
+ Scalar::from_repr(self.value.0.private_key_holder.nullifier_secret_key.into())
|
||||
let parent_pt =
|
||||
Scalar::from_repr(self.value.0.private_key_holder.nullifier_secret_key.into())
|
||||
.expect("Key generated as scalar, must be valid representation")
|
||||
* Scalar::from_repr(
|
||||
self.value
|
||||
.0
|
||||
.private_key_holder
|
||||
.incoming_viewing_secret_key
|
||||
.into(),
|
||||
)
|
||||
.expect("Key generated as scalar, must be valid representation");
|
||||
* Scalar::from_repr(self.value.0.private_key_holder.viewing_secret_key.into())
|
||||
.expect("Key generated as scalar, must be valid representation");
|
||||
let mut input = vec![];
|
||||
|
||||
input.extend_from_slice(b"NSSA_seed_priv");
|
||||
input.extend_from_slice(b"LEE_seed_priv");
|
||||
input.extend_from_slice(&parent_pt.to_bytes());
|
||||
input.extend_from_slice(&cci.to_le_bytes());
|
||||
|
||||
@ -91,23 +76,21 @@ impl KeyNode for ChildKeysPrivate {
|
||||
.last_chunk::<32>()
|
||||
.expect("hash_value is 64 bytes, must be safe to get last 32");
|
||||
|
||||
let nsk = ssk.generate_nullifier_secret_key();
|
||||
let isk = ssk.generate_incoming_viewing_secret_key();
|
||||
let ovk = ssk.generate_outgoing_viewing_secret_key();
|
||||
let nsk = ssk.generate_nullifier_secret_key(Some(cci));
|
||||
let vsk = ssk.generate_viewing_secret_key(Some(cci));
|
||||
|
||||
let npk = (&nsk).into();
|
||||
let ipk = IncomingViewingPublicKey::from_scalar(isk);
|
||||
let npk = NullifierPublicKey::from(&nsk);
|
||||
let vpk = ViewingPublicKey::from_scalar(vsk);
|
||||
|
||||
Self {
|
||||
value: (
|
||||
KeyChain {
|
||||
secret_spending_key: ssk,
|
||||
nullifer_public_key: npk,
|
||||
incoming_viewing_public_key: ipk,
|
||||
viewing_public_key: vpk,
|
||||
private_key_holder: PrivateKeyHolder {
|
||||
nullifier_secret_key: nsk,
|
||||
incoming_viewing_secret_key: isk,
|
||||
outgoing_viewing_secret_key: ovk,
|
||||
viewing_secret_key: vsk,
|
||||
},
|
||||
},
|
||||
nssa::Account::default(),
|
||||
@ -144,120 +127,98 @@ impl<'a> From<&'a mut ChildKeysPrivate> for &'a mut (KeyChain, nssa::Account) {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use nssa_core::{NullifierPublicKey, NullifierSecretKey};
|
||||
|
||||
use super::*;
|
||||
use crate::key_management::{self, secret_holders::ViewingSecretKey};
|
||||
|
||||
#[test]
|
||||
fn test_keys_deterministic_generation() {
|
||||
let root_keys = ChildKeysPrivate::root([42; 64]);
|
||||
let child_keys = root_keys.nth_child(5);
|
||||
fn test_master_key_generation() {
|
||||
let seed: [u8; 64] = [
|
||||
252, 56, 204, 83, 232, 123, 209, 188, 187, 167, 39, 213, 71, 39, 58, 65, 125, 134, 255,
|
||||
49, 43, 108, 92, 53, 173, 164, 94, 142, 150, 74, 21, 163, 43, 144, 226, 87, 199, 18,
|
||||
129, 223, 176, 198, 5, 150, 157, 70, 210, 254, 14, 105, 89, 191, 246, 27, 52, 170, 56,
|
||||
114, 39, 38, 118, 197, 205, 225,
|
||||
];
|
||||
|
||||
assert_eq!(root_keys.cci, None);
|
||||
assert_eq!(child_keys.cci, Some(5));
|
||||
let keys = ChildKeysPrivate::root(seed);
|
||||
|
||||
assert_eq!(
|
||||
root_keys.value.0.secret_spending_key.0,
|
||||
[
|
||||
249, 83, 253, 32, 174, 204, 185, 44, 253, 167, 61, 92, 128, 5, 152, 4, 220, 21, 88,
|
||||
84, 167, 180, 154, 249, 44, 77, 33, 136, 59, 131, 203, 152
|
||||
]
|
||||
);
|
||||
assert_eq!(
|
||||
child_keys.value.0.secret_spending_key.0,
|
||||
[
|
||||
16, 242, 229, 242, 252, 158, 153, 210, 234, 120, 70, 85, 83, 196, 5, 53, 28, 26,
|
||||
187, 230, 22, 193, 146, 232, 237, 3, 166, 184, 122, 1, 233, 93
|
||||
]
|
||||
);
|
||||
let expected_ssk: SecretSpendingKey = key_management::secret_holders::SecretSpendingKey([
|
||||
246, 79, 26, 124, 135, 95, 52, 51, 201, 27, 48, 194, 2, 144, 51, 219, 245, 128, 139,
|
||||
222, 42, 195, 105, 33, 115, 97, 186, 0, 97, 14, 218, 191,
|
||||
]);
|
||||
|
||||
assert_eq!(
|
||||
root_keys.value.0.private_key_holder.nullifier_secret_key,
|
||||
[
|
||||
38, 195, 52, 182, 16, 66, 167, 156, 9, 14, 65, 100, 17, 93, 166, 71, 27, 148, 93,
|
||||
85, 116, 109, 130, 8, 195, 222, 159, 214, 141, 41, 124, 57
|
||||
]
|
||||
);
|
||||
assert_eq!(
|
||||
child_keys.value.0.private_key_holder.nullifier_secret_key,
|
||||
[
|
||||
215, 46, 2, 151, 174, 60, 86, 154, 5, 3, 175, 245, 12, 176, 220, 58, 250, 118, 236,
|
||||
49, 254, 221, 229, 58, 40, 1, 170, 145, 175, 108, 23, 170
|
||||
]
|
||||
);
|
||||
let expected_ccc = [
|
||||
56, 114, 70, 249, 67, 169, 206, 9, 192, 11, 180, 168, 149, 129, 42, 95, 43, 157, 130,
|
||||
111, 13, 5, 195, 75, 20, 255, 162, 85, 40, 251, 8, 168,
|
||||
];
|
||||
|
||||
assert_eq!(
|
||||
root_keys
|
||||
.value
|
||||
.0
|
||||
.private_key_holder
|
||||
.incoming_viewing_secret_key,
|
||||
[
|
||||
153, 161, 15, 34, 96, 184, 165, 165, 27, 244, 155, 40, 70, 5, 241, 133, 78, 40, 61,
|
||||
118, 48, 148, 226, 5, 97, 18, 201, 128, 82, 248, 163, 72
|
||||
]
|
||||
);
|
||||
assert_eq!(
|
||||
child_keys
|
||||
.value
|
||||
.0
|
||||
.private_key_holder
|
||||
.incoming_viewing_secret_key,
|
||||
[
|
||||
192, 155, 55, 43, 164, 115, 71, 145, 227, 225, 21, 57, 55, 12, 226, 44, 10, 103,
|
||||
39, 73, 230, 173, 60, 69, 69, 122, 110, 241, 164, 3, 192, 57
|
||||
]
|
||||
);
|
||||
let expected_nsk: NullifierSecretKey = [
|
||||
154, 102, 103, 5, 34, 235, 227, 13, 22, 182, 226, 11, 7, 67, 110, 162, 99, 193, 174,
|
||||
34, 234, 19, 222, 2, 22, 12, 163, 252, 88, 11, 0, 163,
|
||||
];
|
||||
|
||||
assert_eq!(
|
||||
root_keys
|
||||
.value
|
||||
.0
|
||||
.private_key_holder
|
||||
.outgoing_viewing_secret_key,
|
||||
[
|
||||
205, 87, 71, 129, 90, 242, 217, 200, 140, 252, 124, 46, 207, 7, 33, 156, 83, 166,
|
||||
150, 81, 98, 131, 182, 156, 110, 92, 78, 140, 125, 218, 152, 154
|
||||
]
|
||||
);
|
||||
assert_eq!(
|
||||
child_keys
|
||||
.value
|
||||
.0
|
||||
.private_key_holder
|
||||
.outgoing_viewing_secret_key,
|
||||
[
|
||||
131, 202, 219, 172, 219, 29, 48, 120, 226, 209, 209, 10, 216, 173, 48, 167, 233,
|
||||
17, 35, 155, 30, 217, 176, 120, 72, 146, 250, 226, 165, 178, 255, 90
|
||||
]
|
||||
);
|
||||
let expected_npk: NullifierPublicKey = nssa_core::NullifierPublicKey([
|
||||
7, 123, 125, 191, 233, 183, 201, 4, 20, 214, 155, 210, 45, 234, 27, 240, 194, 111, 97,
|
||||
247, 155, 113, 122, 246, 192, 0, 70, 61, 76, 71, 70, 2,
|
||||
]);
|
||||
let expected_vsk: ViewingSecretKey = [
|
||||
155, 90, 54, 75, 228, 130, 68, 201, 129, 251, 180, 195, 250, 64, 34, 230, 241, 204,
|
||||
216, 50, 149, 156, 10, 67, 208, 74, 9, 10, 47, 59, 50, 202,
|
||||
];
|
||||
|
||||
assert_eq!(
|
||||
root_keys.value.0.nullifer_public_key.0,
|
||||
[
|
||||
65, 176, 149, 243, 192, 45, 216, 177, 169, 56, 229, 7, 28, 66, 204, 87, 109, 83,
|
||||
152, 64, 14, 188, 179, 210, 147, 60, 22, 251, 203, 70, 89, 215
|
||||
]
|
||||
);
|
||||
assert_eq!(
|
||||
child_keys.value.0.nullifer_public_key.0,
|
||||
[
|
||||
69, 104, 130, 115, 48, 134, 19, 188, 67, 148, 163, 54, 155, 237, 57, 27, 136, 228,
|
||||
111, 233, 205, 158, 149, 31, 84, 11, 241, 176, 243, 12, 138, 249
|
||||
]
|
||||
);
|
||||
let expected_vpk_as_bytes: [u8; 33] = [
|
||||
2, 191, 99, 102, 114, 40, 131, 109, 166, 8, 222, 186, 107, 29, 156, 106, 206, 96, 127,
|
||||
80, 170, 66, 217, 79, 38, 80, 11, 74, 147, 123, 221, 159, 166,
|
||||
];
|
||||
|
||||
assert_eq!(
|
||||
root_keys.value.0.incoming_viewing_public_key.0,
|
||||
&[
|
||||
3, 174, 56, 136, 244, 179, 18, 122, 38, 220, 36, 50, 200, 41, 104, 167, 70, 18, 60,
|
||||
202, 93, 193, 29, 16, 125, 252, 96, 51, 199, 152, 47, 233, 178
|
||||
]
|
||||
);
|
||||
assert_eq!(
|
||||
child_keys.value.0.incoming_viewing_public_key.0,
|
||||
&[
|
||||
3, 18, 202, 246, 79, 141, 169, 51, 55, 202, 120, 169, 244, 201, 156, 162, 216, 115,
|
||||
126, 53, 46, 94, 235, 125, 114, 178, 215, 81, 171, 93, 93, 88, 117
|
||||
]
|
||||
);
|
||||
assert!(expected_ssk == keys.value.0.secret_spending_key);
|
||||
assert!(expected_ccc == keys.ccc);
|
||||
assert!(expected_nsk == keys.value.0.private_key_holder.nullifier_secret_key);
|
||||
assert!(expected_npk == keys.value.0.nullifer_public_key);
|
||||
assert!(expected_vsk == keys.value.0.private_key_holder.viewing_secret_key);
|
||||
assert!(expected_vpk_as_bytes == keys.value.0.viewing_public_key.to_bytes());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_child_keys_generation() {
|
||||
let seed: [u8; 64] = [
|
||||
252, 56, 204, 83, 232, 123, 209, 188, 187, 167, 39, 213, 71, 39, 58, 65, 125, 134, 255,
|
||||
49, 43, 108, 92, 53, 173, 164, 94, 142, 150, 74, 21, 163, 43, 144, 226, 87, 199, 18,
|
||||
129, 223, 176, 198, 5, 150, 157, 70, 210, 254, 14, 105, 89, 191, 246, 27, 52, 170, 56,
|
||||
114, 39, 38, 118, 197, 205, 225,
|
||||
];
|
||||
|
||||
let root_node = ChildKeysPrivate::root(seed);
|
||||
let child_node = ChildKeysPrivate::nth_child(&root_node, 42u32);
|
||||
|
||||
let expected_ccc: [u8; 32] = [
|
||||
145, 59, 225, 32, 54, 168, 14, 45, 60, 253, 57, 202, 31, 86, 142, 234, 51, 57, 154, 88,
|
||||
132, 200, 92, 191, 220, 144, 42, 184, 108, 35, 226, 146,
|
||||
];
|
||||
|
||||
let expected_nsk: NullifierSecretKey = [
|
||||
19, 100, 119, 73, 191, 225, 234, 219, 129, 88, 40, 229, 63, 225, 189, 136, 69, 172,
|
||||
221, 186, 147, 83, 150, 207, 70, 17, 228, 70, 113, 87, 227, 31,
|
||||
];
|
||||
let expected_npk: NullifierPublicKey = nssa_core::NullifierPublicKey([
|
||||
133, 235, 223, 151, 12, 69, 26, 222, 60, 125, 235, 125, 167, 212, 201, 168, 101, 242,
|
||||
111, 239, 1, 228, 12, 252, 146, 53, 75, 17, 187, 255, 122, 181,
|
||||
]);
|
||||
|
||||
let expected_vsk: ViewingSecretKey = [
|
||||
218, 219, 193, 132, 160, 6, 178, 194, 139, 248, 199, 81, 17, 133, 37, 201, 58, 104, 49,
|
||||
222, 187, 46, 156, 93, 14, 118, 209, 243, 38, 101, 77, 45,
|
||||
];
|
||||
let expected_vpk_as_bytes: [u8; 33] = [
|
||||
3, 164, 65, 167, 88, 167, 179, 51, 159, 27, 241, 174, 77, 174, 142, 106, 128, 96, 69,
|
||||
74, 117, 231, 42, 193, 235, 153, 206, 116, 102, 7, 101, 192, 45,
|
||||
];
|
||||
|
||||
assert!(expected_ccc == child_node.ccc);
|
||||
assert!(expected_nsk == child_node.value.0.private_key_holder.nullifier_secret_key);
|
||||
assert!(expected_npk == child_node.value.0.nullifer_public_key);
|
||||
assert!(expected_vsk == child_node.value.0.private_key_holder.viewing_secret_key);
|
||||
assert!(expected_vpk_as_bytes == child_node.value.0.viewing_public_key.to_bytes());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
use nssa_core::{
|
||||
NullifierPublicKey, SharedSecretKey,
|
||||
encryption::{EphemeralPublicKey, IncomingViewingPublicKey},
|
||||
encryption::{EphemeralPublicKey, ViewingPublicKey},
|
||||
};
|
||||
use secret_holders::{PrivateKeyHolder, SecretSpendingKey, SeedHolder};
|
||||
use serde::{Deserialize, Serialize};
|
||||
@ -17,7 +17,7 @@ pub struct KeyChain {
|
||||
pub secret_spending_key: SecretSpendingKey,
|
||||
pub private_key_holder: PrivateKeyHolder,
|
||||
pub nullifer_public_key: NullifierPublicKey,
|
||||
pub incoming_viewing_public_key: IncomingViewingPublicKey,
|
||||
pub viewing_public_key: ViewingPublicKey,
|
||||
}
|
||||
|
||||
impl KeyChain {
|
||||
@ -27,16 +27,16 @@ impl KeyChain {
|
||||
let seed_holder = SeedHolder::new_os_random();
|
||||
let secret_spending_key = seed_holder.produce_top_secret_key_holder();
|
||||
|
||||
let private_key_holder = secret_spending_key.produce_private_key_holder();
|
||||
let private_key_holder = secret_spending_key.produce_private_key_holder(None);
|
||||
|
||||
let nullifer_public_key = private_key_holder.generate_nullifier_public_key();
|
||||
let incoming_viewing_public_key = private_key_holder.generate_incoming_viewing_public_key();
|
||||
let viewing_public_key = private_key_holder.generate_viewing_public_key();
|
||||
|
||||
Self {
|
||||
secret_spending_key,
|
||||
private_key_holder,
|
||||
nullifer_public_key,
|
||||
incoming_viewing_public_key,
|
||||
viewing_public_key,
|
||||
}
|
||||
}
|
||||
|
||||
@ -46,16 +46,16 @@ impl KeyChain {
|
||||
let seed_holder = SeedHolder::new_mnemonic(passphrase);
|
||||
let secret_spending_key = seed_holder.produce_top_secret_key_holder();
|
||||
|
||||
let private_key_holder = secret_spending_key.produce_private_key_holder();
|
||||
let private_key_holder = secret_spending_key.produce_private_key_holder(None);
|
||||
|
||||
let nullifer_public_key = private_key_holder.generate_nullifier_public_key();
|
||||
let incoming_viewing_public_key = private_key_holder.generate_incoming_viewing_public_key();
|
||||
let viewing_public_key = private_key_holder.generate_viewing_public_key();
|
||||
|
||||
Self {
|
||||
secret_spending_key,
|
||||
private_key_holder,
|
||||
nullifer_public_key,
|
||||
incoming_viewing_public_key,
|
||||
viewing_public_key,
|
||||
}
|
||||
}
|
||||
|
||||
@ -64,9 +64,7 @@ impl KeyChain {
|
||||
ephemeral_public_key_sender: EphemeralPublicKey,
|
||||
) -> SharedSecretKey {
|
||||
SharedSecretKey::new(
|
||||
&self
|
||||
.secret_spending_key
|
||||
.generate_incoming_viewing_secret_key(),
|
||||
&self.secret_spending_key.generate_viewing_secret_key(None),
|
||||
&ephemeral_public_key_sender,
|
||||
)
|
||||
}
|
||||
@ -112,10 +110,10 @@ mod tests {
|
||||
let seed_holder = SeedHolder::new_os_random();
|
||||
let top_secret_key_holder = seed_holder.produce_top_secret_key_holder();
|
||||
|
||||
let utxo_secret_key_holder = top_secret_key_holder.produce_private_key_holder();
|
||||
let utxo_secret_key_holder = top_secret_key_holder.produce_private_key_holder(None);
|
||||
|
||||
let nullifer_public_key = utxo_secret_key_holder.generate_nullifier_public_key();
|
||||
let viewing_public_key = utxo_secret_key_holder.generate_incoming_viewing_public_key();
|
||||
let viewing_public_key = utxo_secret_key_holder.generate_viewing_public_key();
|
||||
|
||||
let pub_account_signing_key = nssa::PrivateKey::new_os_random();
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@ use bip39::Mnemonic;
|
||||
use common::HashType;
|
||||
use nssa_core::{
|
||||
NullifierPublicKey, NullifierSecretKey,
|
||||
encryption::{IncomingViewingPublicKey, Scalar},
|
||||
encryption::{Scalar, ViewingPublicKey},
|
||||
};
|
||||
use rand::{RngCore, rngs::OsRng};
|
||||
use serde::{Deserialize, Serialize};
|
||||
@ -18,20 +18,18 @@ pub struct SeedHolder {
|
||||
pub(crate) seed: Vec<u8>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
|
||||
/// Secret spending key object. Can produce `PrivateKeyHolder` objects.
|
||||
pub struct SecretSpendingKey(pub(crate) [u8; 32]);
|
||||
|
||||
pub type IncomingViewingSecretKey = Scalar;
|
||||
pub type OutgoingViewingSecretKey = Scalar;
|
||||
pub type ViewingSecretKey = Scalar;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
/// Private key holder. Produces public keys. Can produce account_id. Can produce shared secret for
|
||||
/// recepient.
|
||||
pub struct PrivateKeyHolder {
|
||||
pub nullifier_secret_key: NullifierSecretKey,
|
||||
pub(crate) incoming_viewing_secret_key: IncomingViewingSecretKey,
|
||||
pub outgoing_viewing_secret_key: OutgoingViewingSecretKey,
|
||||
pub(crate) viewing_secret_key: ViewingSecretKey,
|
||||
}
|
||||
|
||||
impl SeedHolder {
|
||||
@ -75,44 +73,49 @@ impl SeedHolder {
|
||||
}
|
||||
|
||||
impl SecretSpendingKey {
|
||||
pub fn generate_nullifier_secret_key(&self) -> NullifierSecretKey {
|
||||
let mut hasher = sha2::Sha256::new();
|
||||
pub fn generate_nullifier_secret_key(&self, index: Option<u32>) -> NullifierSecretKey {
|
||||
let index = match index {
|
||||
None => 0u32,
|
||||
_ => index.expect("Expect a valid u32"),
|
||||
};
|
||||
|
||||
hasher.update("NSSA_keys");
|
||||
const PREFIX: &[u8; 8] = b"LEE/keys";
|
||||
const SUFFIX_1: &[u8; 1] = &[1];
|
||||
const SUFFIX_2: &[u8; 19] = &[0; 19];
|
||||
|
||||
let mut hasher = sha2::Sha256::new();
|
||||
hasher.update(PREFIX);
|
||||
hasher.update(self.0);
|
||||
hasher.update([1u8]);
|
||||
hasher.update([0u8; 22]);
|
||||
hasher.update(SUFFIX_1);
|
||||
hasher.update(index.to_le_bytes());
|
||||
hasher.update(SUFFIX_2);
|
||||
|
||||
<NullifierSecretKey>::from(hasher.finalize_fixed())
|
||||
}
|
||||
|
||||
pub fn generate_incoming_viewing_secret_key(&self) -> IncomingViewingSecretKey {
|
||||
let mut hasher = sha2::Sha256::new();
|
||||
pub fn generate_viewing_secret_key(&self, index: Option<u32>) -> ViewingSecretKey {
|
||||
let index = match index {
|
||||
None => 0u32,
|
||||
_ => index.expect("Expect a valid u32"),
|
||||
};
|
||||
const PREFIX: &[u8; 8] = b"LEE/keys";
|
||||
const SUFFIX_1: &[u8; 1] = &[2];
|
||||
const SUFFIX_2: &[u8; 19] = &[0; 19];
|
||||
|
||||
hasher.update("NSSA_keys");
|
||||
let mut hasher = sha2::Sha256::new();
|
||||
hasher.update(PREFIX);
|
||||
hasher.update(self.0);
|
||||
hasher.update([2u8]);
|
||||
hasher.update([0u8; 22]);
|
||||
hasher.update(SUFFIX_1);
|
||||
hasher.update(index.to_le_bytes());
|
||||
hasher.update(SUFFIX_2);
|
||||
|
||||
hasher.finalize_fixed().into()
|
||||
}
|
||||
|
||||
pub fn generate_outgoing_viewing_secret_key(&self) -> OutgoingViewingSecretKey {
|
||||
let mut hasher = sha2::Sha256::new();
|
||||
|
||||
hasher.update("NSSA_keys");
|
||||
hasher.update(self.0);
|
||||
hasher.update([3u8]);
|
||||
hasher.update([0u8; 22]);
|
||||
|
||||
hasher.finalize_fixed().into()
|
||||
}
|
||||
|
||||
pub fn produce_private_key_holder(&self) -> PrivateKeyHolder {
|
||||
pub fn produce_private_key_holder(&self, index: Option<u32>) -> PrivateKeyHolder {
|
||||
PrivateKeyHolder {
|
||||
nullifier_secret_key: self.generate_nullifier_secret_key(),
|
||||
incoming_viewing_secret_key: self.generate_incoming_viewing_secret_key(),
|
||||
outgoing_viewing_secret_key: self.generate_outgoing_viewing_secret_key(),
|
||||
nullifier_secret_key: self.generate_nullifier_secret_key(index),
|
||||
viewing_secret_key: self.generate_viewing_secret_key(index),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -122,8 +125,8 @@ impl PrivateKeyHolder {
|
||||
(&self.nullifier_secret_key).into()
|
||||
}
|
||||
|
||||
pub fn generate_incoming_viewing_public_key(&self) -> IncomingViewingPublicKey {
|
||||
IncomingViewingPublicKey::from_scalar(self.incoming_viewing_secret_key)
|
||||
pub fn generate_viewing_public_key(&self) -> ViewingPublicKey {
|
||||
ViewingPublicKey::from_scalar(self.viewing_secret_key)
|
||||
}
|
||||
}
|
||||
|
||||
@ -131,6 +134,7 @@ impl PrivateKeyHolder {
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
// TODO? are these necessary?
|
||||
#[test]
|
||||
fn seed_generation_test() {
|
||||
let seed_holder = SeedHolder::new_os_random();
|
||||
@ -155,18 +159,7 @@ mod tests {
|
||||
|
||||
let top_secret_key_holder = seed_holder.produce_top_secret_key_holder();
|
||||
|
||||
let _ = top_secret_key_holder.generate_incoming_viewing_secret_key();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ovs_generation_test() {
|
||||
let seed_holder = SeedHolder::new_os_random();
|
||||
|
||||
assert_eq!(seed_holder.seed.len(), 64);
|
||||
|
||||
let top_secret_key_holder = seed_holder.produce_top_secret_key_holder();
|
||||
|
||||
let _ = top_secret_key_holder.generate_outgoing_viewing_secret_key();
|
||||
let _ = top_secret_key_holder.generate_viewing_secret_key(None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@ -159,6 +159,7 @@ mod tests {
|
||||
assert_eq!(new_acc_with_metadata.account_id, fingerprint);
|
||||
}
|
||||
|
||||
#[cfg(feature = "host")]
|
||||
#[test]
|
||||
fn parse_valid_account_id() {
|
||||
let base58_str = "11111111111111111111111111111111";
|
||||
@ -166,6 +167,7 @@ mod tests {
|
||||
assert_eq!(account_id.value, [0u8; 32]);
|
||||
}
|
||||
|
||||
#[cfg(feature = "host")]
|
||||
#[test]
|
||||
fn parse_invalid_base58() {
|
||||
let base58_str = "00".repeat(32); // invalid base58 chars
|
||||
@ -173,6 +175,7 @@ mod tests {
|
||||
assert!(matches!(result, AccountIdError::InvalidBase58(_)));
|
||||
}
|
||||
|
||||
#[cfg(feature = "host")]
|
||||
#[test]
|
||||
fn parse_wrong_length_short() {
|
||||
let base58_str = "11".repeat(31); // 62 chars = 31 bytes
|
||||
@ -180,6 +183,7 @@ mod tests {
|
||||
assert!(matches!(result, AccountIdError::InvalidLength(_)));
|
||||
}
|
||||
|
||||
#[cfg(feature = "host")]
|
||||
#[test]
|
||||
fn parse_wrong_length_long() {
|
||||
let base58_str = "11".repeat(33); // 66 chars = 33 bytes
|
||||
|
||||
@ -10,7 +10,7 @@ use serde::{Deserialize, Serialize};
|
||||
pub mod shared_key_derivation;
|
||||
|
||||
#[cfg(feature = "host")]
|
||||
pub use shared_key_derivation::{EphemeralPublicKey, EphemeralSecretKey, IncomingViewingPublicKey};
|
||||
pub use shared_key_derivation::{EphemeralPublicKey, EphemeralSecretKey, ViewingPublicKey};
|
||||
|
||||
use crate::{Commitment, account::Account};
|
||||
|
||||
|
||||
@ -28,7 +28,7 @@ impl Secp256k1Point {
|
||||
|
||||
pub type EphemeralSecretKey = Scalar;
|
||||
pub type EphemeralPublicKey = Secp256k1Point;
|
||||
pub type IncomingViewingPublicKey = Secp256k1Point;
|
||||
pub type ViewingPublicKey = Secp256k1Point;
|
||||
impl From<&EphemeralSecretKey> for EphemeralPublicKey {
|
||||
fn from(value: &EphemeralSecretKey) -> Self {
|
||||
Secp256k1Point::from_scalar(*value)
|
||||
|
||||
@ -10,7 +10,8 @@ pub struct NullifierPublicKey(pub [u8; 32]);
|
||||
|
||||
impl From<&NullifierPublicKey> for AccountId {
|
||||
fn from(value: &NullifierPublicKey) -> Self {
|
||||
const PRIVATE_ACCOUNT_ID_PREFIX: &[u8; 32] = b"/NSSA/v0.2/AccountId/Private/\x00\x00\x00";
|
||||
const PRIVATE_ACCOUNT_ID_PREFIX: &[u8; 32] =
|
||||
b"/LEE/v0.3/AccountId/Private/\x00\x00\x00\x00";
|
||||
|
||||
let mut bytes = [0; 64];
|
||||
bytes[0..32].copy_from_slice(PRIVATE_ACCOUNT_ID_PREFIX);
|
||||
@ -28,9 +29,9 @@ impl AsRef<[u8]> for NullifierPublicKey {
|
||||
impl From<&NullifierSecretKey> for NullifierPublicKey {
|
||||
fn from(value: &NullifierSecretKey) -> Self {
|
||||
let mut bytes = Vec::new();
|
||||
const PREFIX: &[u8; 9] = b"NSSA_keys";
|
||||
const PREFIX: &[u8; 8] = b"LEE/keys";
|
||||
const SUFFIX_1: &[u8; 1] = &[7];
|
||||
const SUFFIX_2: &[u8; 22] = &[0; 22];
|
||||
const SUFFIX_2: &[u8; 23] = &[0; 23];
|
||||
bytes.extend_from_slice(PREFIX);
|
||||
bytes.extend_from_slice(value);
|
||||
bytes.extend_from_slice(SUFFIX_1);
|
||||
@ -102,8 +103,8 @@ mod tests {
|
||||
196, 134, 22, 224, 211, 237, 120, 136, 225, 188, 220, 249, 28,
|
||||
];
|
||||
let expected_npk = NullifierPublicKey([
|
||||
202, 120, 42, 189, 194, 218, 78, 244, 31, 6, 108, 169, 29, 61, 22, 221, 69, 138, 197,
|
||||
161, 241, 39, 142, 242, 242, 50, 188, 201, 99, 28, 176, 238,
|
||||
78, 20, 20, 5, 177, 198, 233, 100, 175, 134, 174, 200, 24, 205, 68, 215, 130, 74, 35,
|
||||
54, 154, 184, 219, 42, 168, 106, 126, 147, 133, 244, 18, 218,
|
||||
]);
|
||||
let npk = NullifierPublicKey::from(&nsk);
|
||||
assert_eq!(npk, expected_npk);
|
||||
@ -117,8 +118,8 @@ mod tests {
|
||||
];
|
||||
let npk = NullifierPublicKey::from(&nsk);
|
||||
let expected_account_id = AccountId::new([
|
||||
18, 153, 225, 78, 35, 214, 212, 205, 152, 83, 18, 246, 69, 41, 20, 217, 85, 1, 108, 7,
|
||||
87, 133, 181, 53, 247, 221, 174, 12, 112, 194, 34, 121,
|
||||
139, 72, 194, 222, 215, 187, 147, 56, 55, 35, 222, 205, 156, 12, 204, 227, 166, 44, 30,
|
||||
81, 186, 14, 167, 234, 28, 236, 32, 213, 125, 251, 193, 233,
|
||||
]);
|
||||
|
||||
let account_id = AccountId::from(&npk);
|
||||
|
||||
@ -223,7 +223,7 @@ mod tests {
|
||||
let expected_sender_pre = sender.clone();
|
||||
|
||||
let esk = [3; 32];
|
||||
let shared_secret = SharedSecretKey::new(&esk, &recipient_keys.ivk());
|
||||
let shared_secret = SharedSecretKey::new(&esk, &recipient_keys.vpk());
|
||||
|
||||
let (output, proof) = execute_and_prove(
|
||||
vec![sender, recipient],
|
||||
@ -316,10 +316,10 @@ mod tests {
|
||||
];
|
||||
|
||||
let esk_1 = [3; 32];
|
||||
let shared_secret_1 = SharedSecretKey::new(&esk_1, &sender_keys.ivk());
|
||||
let shared_secret_1 = SharedSecretKey::new(&esk_1, &sender_keys.vpk());
|
||||
|
||||
let esk_2 = [5; 32];
|
||||
let shared_secret_2 = SharedSecretKey::new(&esk_2, &recipient_keys.ivk());
|
||||
let shared_secret_2 = SharedSecretKey::new(&esk_2, &recipient_keys.vpk());
|
||||
|
||||
let (output, proof) = execute_and_prove(
|
||||
vec![sender_pre.clone(), recipient],
|
||||
|
||||
@ -2,7 +2,7 @@ use borsh::{BorshDeserialize, BorshSerialize};
|
||||
use nssa_core::{
|
||||
Commitment, CommitmentSetDigest, Nullifier, NullifierPublicKey, PrivacyPreservingCircuitOutput,
|
||||
account::{Account, Nonce},
|
||||
encryption::{Ciphertext, EphemeralPublicKey, IncomingViewingPublicKey},
|
||||
encryption::{Ciphertext, EphemeralPublicKey, ViewingPublicKey},
|
||||
};
|
||||
use sha2::{Digest, Sha256};
|
||||
|
||||
@ -21,10 +21,10 @@ impl EncryptedAccountData {
|
||||
fn new(
|
||||
ciphertext: Ciphertext,
|
||||
npk: NullifierPublicKey,
|
||||
ivk: IncomingViewingPublicKey,
|
||||
vpk: ViewingPublicKey,
|
||||
epk: EphemeralPublicKey,
|
||||
) -> Self {
|
||||
let view_tag = Self::compute_view_tag(npk, ivk);
|
||||
let view_tag = Self::compute_view_tag(npk, vpk);
|
||||
Self {
|
||||
ciphertext,
|
||||
epk,
|
||||
@ -32,12 +32,12 @@ impl EncryptedAccountData {
|
||||
}
|
||||
}
|
||||
|
||||
/// Computes the tag as the first byte of SHA256("/NSSA/v0.2/ViewTag/" || Npk || Ivk)
|
||||
pub fn compute_view_tag(npk: NullifierPublicKey, ivk: IncomingViewingPublicKey) -> ViewTag {
|
||||
/// Computes the tag as the first byte of SHA256("/NSSA/v0.2/ViewTag/" || Npk || vpk)
|
||||
pub fn compute_view_tag(npk: NullifierPublicKey, vpk: ViewingPublicKey) -> ViewTag {
|
||||
let mut hasher = Sha256::new();
|
||||
hasher.update(b"/NSSA/v0.2/ViewTag/");
|
||||
hasher.update(npk.to_byte_array());
|
||||
hasher.update(ivk.to_bytes());
|
||||
hasher.update(vpk.to_bytes());
|
||||
let digest: [u8; 32] = hasher.finalize().into();
|
||||
digest[0]
|
||||
}
|
||||
@ -57,11 +57,7 @@ impl Message {
|
||||
pub fn try_from_circuit_output(
|
||||
public_account_ids: Vec<AccountId>,
|
||||
nonces: Vec<Nonce>,
|
||||
public_keys: Vec<(
|
||||
NullifierPublicKey,
|
||||
IncomingViewingPublicKey,
|
||||
EphemeralPublicKey,
|
||||
)>,
|
||||
public_keys: Vec<(NullifierPublicKey, ViewingPublicKey, EphemeralPublicKey)>,
|
||||
output: PrivacyPreservingCircuitOutput,
|
||||
) -> Result<Self, NssaError> {
|
||||
if public_keys.len() != output.ciphertexts.len() {
|
||||
@ -74,8 +70,8 @@ impl Message {
|
||||
.ciphertexts
|
||||
.into_iter()
|
||||
.zip(public_keys)
|
||||
.map(|(ciphertext, (npk, ivk, epk))| {
|
||||
EncryptedAccountData::new(ciphertext, npk, ivk, epk)
|
||||
.map(|(ciphertext, (npk, vpk, epk))| {
|
||||
EncryptedAccountData::new(ciphertext, npk, vpk, epk)
|
||||
})
|
||||
.collect();
|
||||
Ok(Self {
|
||||
@ -94,7 +90,7 @@ pub mod tests {
|
||||
use nssa_core::{
|
||||
Commitment, EncryptionScheme, Nullifier, NullifierPublicKey, SharedSecretKey,
|
||||
account::Account,
|
||||
encryption::{EphemeralPublicKey, IncomingViewingPublicKey},
|
||||
encryption::{EphemeralPublicKey, ViewingPublicKey},
|
||||
};
|
||||
use sha2::{Digest, Sha256};
|
||||
|
||||
@ -142,21 +138,21 @@ pub mod tests {
|
||||
#[test]
|
||||
fn test_encrypted_account_data_constructor() {
|
||||
let npk = NullifierPublicKey::from(&[1; 32]);
|
||||
let ivk = IncomingViewingPublicKey::from_scalar([2; 32]);
|
||||
let vpk = ViewingPublicKey::from_scalar([2; 32]);
|
||||
let account = Account::default();
|
||||
let commitment = Commitment::new(&npk, &account);
|
||||
let esk = [3; 32];
|
||||
let shared_secret = SharedSecretKey::new(&esk, &ivk);
|
||||
let shared_secret = SharedSecretKey::new(&esk, &vpk);
|
||||
let epk = EphemeralPublicKey::from_scalar(esk);
|
||||
let ciphertext = EncryptionScheme::encrypt(&account, &shared_secret, &commitment, 2);
|
||||
let encrypted_account_data =
|
||||
EncryptedAccountData::new(ciphertext.clone(), npk.clone(), ivk.clone(), epk.clone());
|
||||
EncryptedAccountData::new(ciphertext.clone(), npk.clone(), vpk.clone(), epk.clone());
|
||||
|
||||
let expected_view_tag = {
|
||||
let mut hasher = Sha256::new();
|
||||
hasher.update(b"/NSSA/v0.2/ViewTag/");
|
||||
hasher.update(npk.to_byte_array());
|
||||
hasher.update(ivk.to_bytes());
|
||||
hasher.update(vpk.to_bytes());
|
||||
let digest: [u8; 32] = hasher.finalize().into();
|
||||
digest[0]
|
||||
};
|
||||
@ -165,7 +161,7 @@ pub mod tests {
|
||||
assert_eq!(encrypted_account_data.epk, epk);
|
||||
assert_eq!(
|
||||
encrypted_account_data.view_tag,
|
||||
EncryptedAccountData::compute_view_tag(npk, ivk)
|
||||
EncryptedAccountData::compute_view_tag(npk, vpk)
|
||||
);
|
||||
assert_eq!(encrypted_account_data.view_tag, expected_view_tag);
|
||||
}
|
||||
|
||||
@ -315,7 +315,7 @@ pub mod tests {
|
||||
use nssa_core::{
|
||||
Commitment, Nullifier, NullifierPublicKey, NullifierSecretKey, SharedSecretKey,
|
||||
account::{Account, AccountId, AccountWithMetadata, Nonce, data::Data},
|
||||
encryption::{EphemeralPublicKey, IncomingViewingPublicKey, Scalar},
|
||||
encryption::{EphemeralPublicKey, Scalar, ViewingPublicKey},
|
||||
program::{PdaSeed, ProgramId},
|
||||
};
|
||||
use token_core::{TokenDefinition, TokenHolding};
|
||||
@ -864,7 +864,7 @@ pub mod tests {
|
||||
|
||||
pub struct TestPrivateKeys {
|
||||
pub nsk: NullifierSecretKey,
|
||||
pub isk: Scalar,
|
||||
pub vsk: Scalar,
|
||||
}
|
||||
|
||||
impl TestPrivateKeys {
|
||||
@ -872,22 +872,22 @@ pub mod tests {
|
||||
NullifierPublicKey::from(&self.nsk)
|
||||
}
|
||||
|
||||
pub fn ivk(&self) -> IncomingViewingPublicKey {
|
||||
IncomingViewingPublicKey::from_scalar(self.isk)
|
||||
pub fn vpk(&self) -> ViewingPublicKey {
|
||||
ViewingPublicKey::from_scalar(self.vsk)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn test_private_account_keys_1() -> TestPrivateKeys {
|
||||
TestPrivateKeys {
|
||||
nsk: [13; 32],
|
||||
isk: [31; 32],
|
||||
vsk: [31; 32],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn test_private_account_keys_2() -> TestPrivateKeys {
|
||||
TestPrivateKeys {
|
||||
nsk: [38; 32],
|
||||
isk: [83; 32],
|
||||
vsk: [83; 32],
|
||||
}
|
||||
}
|
||||
|
||||
@ -908,7 +908,7 @@ pub mod tests {
|
||||
let recipient = AccountWithMetadata::new(Account::default(), false, &recipient_keys.npk());
|
||||
|
||||
let esk = [3; 32];
|
||||
let shared_secret = SharedSecretKey::new(&esk, &recipient_keys.ivk());
|
||||
let shared_secret = SharedSecretKey::new(&esk, &recipient_keys.vpk());
|
||||
let epk = EphemeralPublicKey::from_scalar(esk);
|
||||
|
||||
let (output, proof) = circuit::execute_and_prove(
|
||||
@ -926,7 +926,7 @@ pub mod tests {
|
||||
let message = Message::try_from_circuit_output(
|
||||
vec![sender_keys.account_id()],
|
||||
vec![sender_nonce],
|
||||
vec![(recipient_keys.npk(), recipient_keys.ivk(), epk)],
|
||||
vec![(recipient_keys.npk(), recipient_keys.vpk(), epk)],
|
||||
output,
|
||||
)
|
||||
.unwrap();
|
||||
@ -951,11 +951,11 @@ pub mod tests {
|
||||
AccountWithMetadata::new(Account::default(), false, &recipient_keys.npk());
|
||||
|
||||
let esk_1 = [3; 32];
|
||||
let shared_secret_1 = SharedSecretKey::new(&esk_1, &sender_keys.ivk());
|
||||
let shared_secret_1 = SharedSecretKey::new(&esk_1, &sender_keys.vpk());
|
||||
let epk_1 = EphemeralPublicKey::from_scalar(esk_1);
|
||||
|
||||
let esk_2 = [3; 32];
|
||||
let shared_secret_2 = SharedSecretKey::new(&esk_2, &recipient_keys.ivk());
|
||||
let shared_secret_2 = SharedSecretKey::new(&esk_2, &recipient_keys.vpk());
|
||||
let epk_2 = EphemeralPublicKey::from_scalar(esk_2);
|
||||
|
||||
let (output, proof) = circuit::execute_and_prove(
|
||||
@ -977,8 +977,8 @@ pub mod tests {
|
||||
vec![],
|
||||
vec![],
|
||||
vec![
|
||||
(sender_keys.npk(), sender_keys.ivk(), epk_1),
|
||||
(recipient_keys.npk(), recipient_keys.ivk(), epk_2),
|
||||
(sender_keys.npk(), sender_keys.vpk(), epk_1),
|
||||
(recipient_keys.npk(), recipient_keys.vpk(), epk_2),
|
||||
],
|
||||
output,
|
||||
)
|
||||
@ -1008,7 +1008,7 @@ pub mod tests {
|
||||
);
|
||||
|
||||
let esk = [3; 32];
|
||||
let shared_secret = SharedSecretKey::new(&esk, &sender_keys.ivk());
|
||||
let shared_secret = SharedSecretKey::new(&esk, &sender_keys.vpk());
|
||||
let epk = EphemeralPublicKey::from_scalar(esk);
|
||||
|
||||
let (output, proof) = circuit::execute_and_prove(
|
||||
@ -1026,7 +1026,7 @@ pub mod tests {
|
||||
let message = Message::try_from_circuit_output(
|
||||
vec![*recipient_account_id],
|
||||
vec![],
|
||||
vec![(sender_keys.npk(), sender_keys.ivk(), epk)],
|
||||
vec![(sender_keys.npk(), sender_keys.vpk(), epk)],
|
||||
output,
|
||||
)
|
||||
.unwrap();
|
||||
@ -1538,11 +1538,11 @@ pub mod tests {
|
||||
vec![
|
||||
(
|
||||
sender_keys.npk(),
|
||||
SharedSecretKey::new(&[55; 32], &sender_keys.ivk()),
|
||||
SharedSecretKey::new(&[55; 32], &sender_keys.vpk()),
|
||||
),
|
||||
(
|
||||
recipient_keys.npk(),
|
||||
SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()),
|
||||
SharedSecretKey::new(&[56; 32], &recipient_keys.vpk()),
|
||||
),
|
||||
],
|
||||
vec![sender_keys.nsk],
|
||||
@ -1572,7 +1572,7 @@ pub mod tests {
|
||||
// Setting only one key for an execution with two private accounts.
|
||||
let private_account_keys = [(
|
||||
sender_keys.npk(),
|
||||
SharedSecretKey::new(&[55; 32], &sender_keys.ivk()),
|
||||
SharedSecretKey::new(&[55; 32], &sender_keys.vpk()),
|
||||
)];
|
||||
let result = execute_and_prove(
|
||||
vec![private_account_1, private_account_2],
|
||||
@ -1615,11 +1615,11 @@ pub mod tests {
|
||||
vec![
|
||||
(
|
||||
sender_keys.npk(),
|
||||
SharedSecretKey::new(&[55; 32], &sender_keys.ivk()),
|
||||
SharedSecretKey::new(&[55; 32], &sender_keys.vpk()),
|
||||
),
|
||||
(
|
||||
recipient_keys.npk(),
|
||||
SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()),
|
||||
SharedSecretKey::new(&[56; 32], &recipient_keys.vpk()),
|
||||
),
|
||||
],
|
||||
vec![sender_keys.nsk],
|
||||
@ -1657,11 +1657,11 @@ pub mod tests {
|
||||
vec![
|
||||
(
|
||||
sender_keys.npk(),
|
||||
SharedSecretKey::new(&[55; 32], &sender_keys.ivk()),
|
||||
SharedSecretKey::new(&[55; 32], &sender_keys.vpk()),
|
||||
),
|
||||
(
|
||||
recipient_keys.npk(),
|
||||
SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()),
|
||||
SharedSecretKey::new(&[56; 32], &recipient_keys.vpk()),
|
||||
),
|
||||
],
|
||||
private_account_nsks.to_vec(),
|
||||
@ -1693,12 +1693,12 @@ pub mod tests {
|
||||
// First private account is the sender
|
||||
(
|
||||
sender_keys.npk(),
|
||||
SharedSecretKey::new(&[55; 32], &sender_keys.ivk()),
|
||||
SharedSecretKey::new(&[55; 32], &sender_keys.vpk()),
|
||||
),
|
||||
// Second private account is the recipient
|
||||
(
|
||||
recipient_keys.npk(),
|
||||
SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()),
|
||||
SharedSecretKey::new(&[56; 32], &recipient_keys.vpk()),
|
||||
),
|
||||
];
|
||||
|
||||
@ -1753,11 +1753,11 @@ pub mod tests {
|
||||
vec![
|
||||
(
|
||||
sender_keys.npk(),
|
||||
SharedSecretKey::new(&[55; 32], &sender_keys.ivk()),
|
||||
SharedSecretKey::new(&[55; 32], &sender_keys.vpk()),
|
||||
),
|
||||
(
|
||||
recipient_keys.npk(),
|
||||
SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()),
|
||||
SharedSecretKey::new(&[56; 32], &recipient_keys.vpk()),
|
||||
),
|
||||
],
|
||||
vec![sender_keys.nsk],
|
||||
@ -1801,11 +1801,11 @@ pub mod tests {
|
||||
vec![
|
||||
(
|
||||
sender_keys.npk(),
|
||||
SharedSecretKey::new(&[55; 32], &sender_keys.ivk()),
|
||||
SharedSecretKey::new(&[55; 32], &sender_keys.vpk()),
|
||||
),
|
||||
(
|
||||
recipient_keys.npk(),
|
||||
SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()),
|
||||
SharedSecretKey::new(&[56; 32], &recipient_keys.vpk()),
|
||||
),
|
||||
],
|
||||
vec![sender_keys.nsk],
|
||||
@ -1848,11 +1848,11 @@ pub mod tests {
|
||||
vec![
|
||||
(
|
||||
sender_keys.npk(),
|
||||
SharedSecretKey::new(&[55; 32], &sender_keys.ivk()),
|
||||
SharedSecretKey::new(&[55; 32], &sender_keys.vpk()),
|
||||
),
|
||||
(
|
||||
recipient_keys.npk(),
|
||||
SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()),
|
||||
SharedSecretKey::new(&[56; 32], &recipient_keys.vpk()),
|
||||
),
|
||||
],
|
||||
vec![sender_keys.nsk],
|
||||
@ -1895,11 +1895,11 @@ pub mod tests {
|
||||
vec![
|
||||
(
|
||||
sender_keys.npk(),
|
||||
SharedSecretKey::new(&[55; 32], &sender_keys.ivk()),
|
||||
SharedSecretKey::new(&[55; 32], &sender_keys.vpk()),
|
||||
),
|
||||
(
|
||||
recipient_keys.npk(),
|
||||
SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()),
|
||||
SharedSecretKey::new(&[56; 32], &recipient_keys.vpk()),
|
||||
),
|
||||
],
|
||||
vec![sender_keys.nsk],
|
||||
@ -1940,11 +1940,11 @@ pub mod tests {
|
||||
vec![
|
||||
(
|
||||
sender_keys.npk(),
|
||||
SharedSecretKey::new(&[55; 32], &sender_keys.ivk()),
|
||||
SharedSecretKey::new(&[55; 32], &sender_keys.vpk()),
|
||||
),
|
||||
(
|
||||
recipient_keys.npk(),
|
||||
SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()),
|
||||
SharedSecretKey::new(&[56; 32], &recipient_keys.vpk()),
|
||||
),
|
||||
],
|
||||
vec![sender_keys.nsk],
|
||||
@ -2013,11 +2013,11 @@ pub mod tests {
|
||||
vec![
|
||||
(
|
||||
sender_keys.npk(),
|
||||
SharedSecretKey::new(&[55; 32], &sender_keys.ivk()),
|
||||
SharedSecretKey::new(&[55; 32], &sender_keys.vpk()),
|
||||
),
|
||||
(
|
||||
recipient_keys.npk(),
|
||||
SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()),
|
||||
SharedSecretKey::new(&[56; 32], &recipient_keys.vpk()),
|
||||
),
|
||||
],
|
||||
vec![sender_keys.nsk],
|
||||
@ -2050,15 +2050,15 @@ pub mod tests {
|
||||
let private_account_keys = [
|
||||
(
|
||||
sender_keys.npk(),
|
||||
SharedSecretKey::new(&[55; 32], &sender_keys.ivk()),
|
||||
SharedSecretKey::new(&[55; 32], &sender_keys.vpk()),
|
||||
),
|
||||
(
|
||||
recipient_keys.npk(),
|
||||
SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()),
|
||||
SharedSecretKey::new(&[56; 32], &recipient_keys.vpk()),
|
||||
),
|
||||
(
|
||||
sender_keys.npk(),
|
||||
SharedSecretKey::new(&[57; 32], &sender_keys.ivk()),
|
||||
SharedSecretKey::new(&[57; 32], &sender_keys.vpk()),
|
||||
),
|
||||
];
|
||||
let result = execute_and_prove(
|
||||
@ -2105,11 +2105,11 @@ pub mod tests {
|
||||
vec![
|
||||
(
|
||||
sender_keys.npk(),
|
||||
SharedSecretKey::new(&[55; 32], &sender_keys.ivk()),
|
||||
SharedSecretKey::new(&[55; 32], &sender_keys.vpk()),
|
||||
),
|
||||
(
|
||||
recipient_keys.npk(),
|
||||
SharedSecretKey::new(&[56; 32], &recipient_keys.ivk()),
|
||||
SharedSecretKey::new(&[56; 32], &recipient_keys.vpk()),
|
||||
),
|
||||
],
|
||||
private_account_nsks.to_vec(),
|
||||
@ -2192,7 +2192,7 @@ pub mod tests {
|
||||
let visibility_mask = [1, 1];
|
||||
let private_account_nsks = [sender_keys.nsk, sender_keys.nsk];
|
||||
let private_account_membership_proofs = [Some((1, vec![])), Some((1, vec![]))];
|
||||
let shared_secret = SharedSecretKey::new(&[55; 32], &sender_keys.ivk());
|
||||
let shared_secret = SharedSecretKey::new(&[55; 32], &sender_keys.vpk());
|
||||
let result = execute_and_prove(
|
||||
vec![private_account_1.clone(), private_account_1],
|
||||
Program::serialize_instruction(100u128).unwrap(),
|
||||
@ -3809,11 +3809,11 @@ pub mod tests {
|
||||
);
|
||||
|
||||
let from_esk = [3; 32];
|
||||
let from_ss = SharedSecretKey::new(&from_esk, &from_keys.ivk());
|
||||
let from_ss = SharedSecretKey::new(&from_esk, &from_keys.vpk());
|
||||
let from_epk = EphemeralPublicKey::from_scalar(from_esk);
|
||||
|
||||
let to_esk = [3; 32];
|
||||
let to_ss = SharedSecretKey::new(&to_esk, &to_keys.ivk());
|
||||
let to_ss = SharedSecretKey::new(&to_esk, &to_keys.vpk());
|
||||
let to_epk = EphemeralPublicKey::from_scalar(to_esk);
|
||||
|
||||
let mut dependencies = HashMap::new();
|
||||
@ -3858,8 +3858,8 @@ pub mod tests {
|
||||
vec![],
|
||||
vec![],
|
||||
vec![
|
||||
(to_keys.npk(), to_keys.ivk(), to_epk),
|
||||
(from_keys.npk(), from_keys.ivk(), from_epk),
|
||||
(to_keys.npk(), to_keys.vpk(), to_epk),
|
||||
(from_keys.npk(), from_keys.vpk(), from_epk),
|
||||
],
|
||||
output,
|
||||
)
|
||||
@ -4069,7 +4069,7 @@ pub mod tests {
|
||||
|
||||
// Set up parameters for the new account
|
||||
let esk = [3; 32];
|
||||
let shared_secret = SharedSecretKey::new(&esk, &private_keys.ivk());
|
||||
let shared_secret = SharedSecretKey::new(&esk, &private_keys.vpk());
|
||||
let epk = EphemeralPublicKey::from_scalar(esk);
|
||||
|
||||
// Balance to initialize the account with (0 for a new account)
|
||||
@ -4094,7 +4094,7 @@ pub mod tests {
|
||||
let message = Message::try_from_circuit_output(
|
||||
vec![],
|
||||
vec![],
|
||||
vec![(private_keys.npk(), private_keys.ivk(), epk)],
|
||||
vec![(private_keys.npk(), private_keys.vpk(), epk)],
|
||||
output,
|
||||
)
|
||||
.unwrap();
|
||||
@ -4124,7 +4124,7 @@ pub mod tests {
|
||||
|
||||
// Set up parameters for claiming the new account
|
||||
let esk = [3; 32];
|
||||
let shared_secret = SharedSecretKey::new(&esk, &private_keys.ivk());
|
||||
let shared_secret = SharedSecretKey::new(&esk, &private_keys.vpk());
|
||||
let epk = EphemeralPublicKey::from_scalar(esk);
|
||||
|
||||
let balance: u128 = 0;
|
||||
@ -4146,7 +4146,7 @@ pub mod tests {
|
||||
let message = Message::try_from_circuit_output(
|
||||
vec![],
|
||||
vec![],
|
||||
vec![(private_keys.npk(), private_keys.ivk(), epk)],
|
||||
vec![(private_keys.npk(), private_keys.vpk(), epk)],
|
||||
output,
|
||||
)
|
||||
.unwrap();
|
||||
@ -4174,7 +4174,7 @@ pub mod tests {
|
||||
|
||||
let noop_program = Program::noop();
|
||||
let esk2 = [4; 32];
|
||||
let shared_secret2 = SharedSecretKey::new(&esk2, &private_keys.ivk());
|
||||
let shared_secret2 = SharedSecretKey::new(&esk2, &private_keys.vpk());
|
||||
|
||||
let nonce2 = 0xdeadbeef2;
|
||||
|
||||
@ -4256,7 +4256,7 @@ pub mod tests {
|
||||
vec![2],
|
||||
vec![(
|
||||
sender_keys.npk(),
|
||||
SharedSecretKey::new(&[3; 32], &sender_keys.ivk()),
|
||||
SharedSecretKey::new(&[3; 32], &sender_keys.vpk()),
|
||||
)],
|
||||
vec![sender_keys.nsk],
|
||||
vec![Some((0, vec![]))],
|
||||
@ -4284,7 +4284,7 @@ pub mod tests {
|
||||
vec![2],
|
||||
vec![(
|
||||
sender_keys.npk(),
|
||||
SharedSecretKey::new(&[3; 32], &sender_keys.ivk()),
|
||||
SharedSecretKey::new(&[3; 32], &sender_keys.vpk()),
|
||||
)],
|
||||
vec![sender_keys.nsk],
|
||||
vec![Some((0, vec![]))],
|
||||
@ -4327,7 +4327,7 @@ pub mod tests {
|
||||
let instruction = (balance_to_transfer, auth_transfers.id());
|
||||
|
||||
let recipient_esk = [3; 32];
|
||||
let recipient = SharedSecretKey::new(&recipient_esk, &recipient_keys.ivk());
|
||||
let recipient = SharedSecretKey::new(&recipient_esk, &recipient_keys.vpk());
|
||||
|
||||
let mut dependencies = HashMap::new();
|
||||
dependencies.insert(auth_transfers.id(), auth_transfers);
|
||||
|
||||
@ -73,7 +73,7 @@ pub unsafe extern "C" fn wallet_ffi_get_public_account_key(
|
||||
|
||||
/// Get keys for a private account.
|
||||
///
|
||||
/// Returns the nullifier public key (NPK) and incoming viewing public key (IPK)
|
||||
/// Returns the nullifier public key (NPK) and viewing public key (VPK)
|
||||
/// for the specified private account. These keys are safe to share publicly.
|
||||
///
|
||||
/// # Parameters
|
||||
@ -130,17 +130,17 @@ pub unsafe extern "C" fn wallet_ffi_get_private_account_keys(
|
||||
// NPK is a 32-byte array
|
||||
let npk_bytes = key_chain.nullifer_public_key.0;
|
||||
|
||||
// IPK is a compressed secp256k1 point (33 bytes)
|
||||
let ipk_bytes = key_chain.incoming_viewing_public_key.to_bytes();
|
||||
let ipk_len = ipk_bytes.len();
|
||||
let ipk_vec = ipk_bytes.to_vec();
|
||||
let ipk_boxed = ipk_vec.into_boxed_slice();
|
||||
let ipk_ptr = Box::into_raw(ipk_boxed) as *const u8;
|
||||
// VPK is a compressed secp256k1 point (33 bytes)
|
||||
let vpk_bytes = key_chain.viewing_public_key.to_bytes();
|
||||
let vpk_len = vpk_bytes.len();
|
||||
let vpk_vec = vpk_bytes.to_vec();
|
||||
let vpk_boxed = vpk_vec.into_boxed_slice();
|
||||
let vpk_ptr = Box::into_raw(vpk_boxed) as *const u8;
|
||||
|
||||
unsafe {
|
||||
(*out_keys).nullifier_public_key.data = npk_bytes;
|
||||
(*out_keys).incoming_viewing_public_key = ipk_ptr;
|
||||
(*out_keys).incoming_viewing_public_key_len = ipk_len;
|
||||
(*out_keys).viewing_public_key = vpk_ptr;
|
||||
(*out_keys).viewing_public_key_len = vpk_len;
|
||||
}
|
||||
|
||||
WalletFfiError::Success
|
||||
@ -159,10 +159,10 @@ pub unsafe extern "C" fn wallet_ffi_free_private_account_keys(keys: *mut FfiPriv
|
||||
|
||||
unsafe {
|
||||
let keys = &*keys;
|
||||
if !keys.incoming_viewing_public_key.is_null() && keys.incoming_viewing_public_key_len > 0 {
|
||||
if !keys.viewing_public_key.is_null() && keys.viewing_public_key_len > 0 {
|
||||
let slice = std::slice::from_raw_parts_mut(
|
||||
keys.incoming_viewing_public_key as *mut u8,
|
||||
keys.incoming_viewing_public_key_len,
|
||||
keys.viewing_public_key as *mut u8,
|
||||
keys.viewing_public_key_len,
|
||||
);
|
||||
drop(Box::from_raw(slice as *mut [u8]));
|
||||
}
|
||||
|
||||
@ -150,8 +150,8 @@ pub unsafe extern "C" fn wallet_ffi_transfer_shielded(
|
||||
|
||||
let from_id = AccountId::new(unsafe { (*from).data });
|
||||
let to_npk = (*to_keys).npk();
|
||||
let to_ipk = match (*to_keys).ivk() {
|
||||
Ok(ipk) => ipk,
|
||||
let to_vpk = match (*to_keys).vpk() {
|
||||
Ok(vpk) => vpk,
|
||||
Err(e) => {
|
||||
print_error("Invalid viewing key");
|
||||
return e;
|
||||
@ -162,7 +162,7 @@ pub unsafe extern "C" fn wallet_ffi_transfer_shielded(
|
||||
let transfer = NativeTokenTransfer(&wallet);
|
||||
|
||||
match block_on(
|
||||
transfer.send_shielded_transfer_to_outer_account(from_id, to_npk, to_ipk, amount),
|
||||
transfer.send_shielded_transfer_to_outer_account(from_id, to_npk, to_vpk, amount),
|
||||
) {
|
||||
Ok(Ok((response, _shared_key))) => {
|
||||
let tx_hash = CString::new(response.tx_hash)
|
||||
@ -323,8 +323,8 @@ pub unsafe extern "C" fn wallet_ffi_transfer_private(
|
||||
|
||||
let from_id = AccountId::new(unsafe { (*from).data });
|
||||
let to_npk = (*to_keys).npk();
|
||||
let to_ipk = match (*to_keys).ivk() {
|
||||
Ok(ipk) => ipk,
|
||||
let to_vpk = match (*to_keys).vpk() {
|
||||
Ok(vpk) => vpk,
|
||||
Err(e) => {
|
||||
print_error("Invalid viewing key");
|
||||
return e;
|
||||
@ -334,7 +334,7 @@ pub unsafe extern "C" fn wallet_ffi_transfer_private(
|
||||
|
||||
let transfer = NativeTokenTransfer(&wallet);
|
||||
|
||||
match block_on(transfer.send_private_transfer_to_outer_account(from_id, to_npk, to_ipk, amount))
|
||||
match block_on(transfer.send_private_transfer_to_outer_account(from_id, to_npk, to_vpk, amount))
|
||||
{
|
||||
Ok(Ok((response, _shared_key))) => {
|
||||
let tx_hash = CString::new(response.tx_hash)
|
||||
|
||||
@ -72,18 +72,18 @@ impl Default for FfiAccount {
|
||||
pub struct FfiPrivateAccountKeys {
|
||||
/// Nullifier public key (32 bytes)
|
||||
pub nullifier_public_key: FfiBytes32,
|
||||
/// Incoming viewing public key (compressed secp256k1 point)
|
||||
pub incoming_viewing_public_key: *const u8,
|
||||
/// Length of incoming viewing public key (typically 33 bytes)
|
||||
pub incoming_viewing_public_key_len: usize,
|
||||
/// viewing public key (compressed secp256k1 point)
|
||||
pub viewing_public_key: *const u8,
|
||||
/// Length of viewing public key (typically 33 bytes)
|
||||
pub viewing_public_key_len: usize,
|
||||
}
|
||||
|
||||
impl Default for FfiPrivateAccountKeys {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
nullifier_public_key: FfiBytes32::default(),
|
||||
incoming_viewing_public_key: std::ptr::null(),
|
||||
incoming_viewing_public_key_len: 0,
|
||||
viewing_public_key: std::ptr::null(),
|
||||
viewing_public_key_len: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -157,13 +157,10 @@ impl FfiPrivateAccountKeys {
|
||||
nssa_core::NullifierPublicKey(self.nullifier_public_key.data)
|
||||
}
|
||||
|
||||
pub fn ivk(&self) -> Result<nssa_core::encryption::IncomingViewingPublicKey, WalletFfiError> {
|
||||
if self.incoming_viewing_public_key_len == 33 {
|
||||
pub fn vpk(&self) -> Result<nssa_core::encryption::ViewingPublicKey, WalletFfiError> {
|
||||
if self.viewing_public_key_len == 33 {
|
||||
let slice = unsafe {
|
||||
slice::from_raw_parts(
|
||||
self.incoming_viewing_public_key,
|
||||
self.incoming_viewing_public_key_len,
|
||||
)
|
||||
slice::from_raw_parts(self.viewing_public_key, self.viewing_public_key_len)
|
||||
};
|
||||
Ok(Secp256k1Point(slice.to_vec()))
|
||||
} else {
|
||||
|
||||
679
wallet-ffi/wallet_ffi.h
Normal file
679
wallet-ffi/wallet_ffi.h
Normal file
@ -0,0 +1,679 @@
|
||||
/**
|
||||
* NSSA Wallet FFI Bindings
|
||||
*
|
||||
* Thread Safety: All functions are thread-safe. The wallet handle can be
|
||||
* shared across threads, but operations are serialized internally.
|
||||
*
|
||||
* Memory Management:
|
||||
* - Functions returning pointers allocate memory that must be freed
|
||||
* - Use the corresponding wallet_ffi_free_* function to free memory
|
||||
* - Never free memory returned by FFI using standard C free()
|
||||
*
|
||||
* Error Handling:
|
||||
* - Functions return WalletFfiError codes
|
||||
* - On error, call wallet_ffi_get_last_error() for detailed message
|
||||
* - The error string must be freed with wallet_ffi_free_error_string()
|
||||
*
|
||||
* Initialization:
|
||||
* 1. Call wallet_ffi_init_runtime() before any other function
|
||||
* 2. Create wallet with wallet_ffi_create_new() or wallet_ffi_open()
|
||||
* 3. Destroy wallet with wallet_ffi_destroy() when done
|
||||
*/
|
||||
|
||||
|
||||
#ifndef WALLET_FFI_H
|
||||
#define WALLET_FFI_H
|
||||
|
||||
/* Generated with cbindgen:0.29.2 */
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/**
|
||||
* Error codes returned by FFI functions.
|
||||
*/
|
||||
typedef enum WalletFfiError {
|
||||
/**
|
||||
* Operation completed successfully
|
||||
*/
|
||||
SUCCESS = 0,
|
||||
/**
|
||||
* A null pointer was passed where a valid pointer was expected
|
||||
*/
|
||||
NULL_POINTER = 1,
|
||||
/**
|
||||
* Invalid UTF-8 string
|
||||
*/
|
||||
INVALID_UTF8 = 2,
|
||||
/**
|
||||
* Wallet handle is not initialized
|
||||
*/
|
||||
WALLET_NOT_INITIALIZED = 3,
|
||||
/**
|
||||
* Configuration error
|
||||
*/
|
||||
CONFIG_ERROR = 4,
|
||||
/**
|
||||
* Storage/persistence error
|
||||
*/
|
||||
STORAGE_ERROR = 5,
|
||||
/**
|
||||
* Network/RPC error
|
||||
*/
|
||||
NETWORK_ERROR = 6,
|
||||
/**
|
||||
* Account not found
|
||||
*/
|
||||
ACCOUNT_NOT_FOUND = 7,
|
||||
/**
|
||||
* Key not found for account
|
||||
*/
|
||||
KEY_NOT_FOUND = 8,
|
||||
/**
|
||||
* Insufficient funds for operation
|
||||
*/
|
||||
INSUFFICIENT_FUNDS = 9,
|
||||
/**
|
||||
* Invalid account ID format
|
||||
*/
|
||||
INVALID_ACCOUNT_ID = 10,
|
||||
/**
|
||||
* Tokio runtime error
|
||||
*/
|
||||
RUNTIME_ERROR = 11,
|
||||
/**
|
||||
* Password required but not provided
|
||||
*/
|
||||
PASSWORD_REQUIRED = 12,
|
||||
/**
|
||||
* Block synchronization error
|
||||
*/
|
||||
SYNC_ERROR = 13,
|
||||
/**
|
||||
* Serialization/deserialization error
|
||||
*/
|
||||
SERIALIZATION_ERROR = 14,
|
||||
/**
|
||||
* Invalid conversion from FFI types to NSSA types
|
||||
*/
|
||||
INVALID_TYPE_CONVERSION = 15,
|
||||
/**
|
||||
* Invalid Key value
|
||||
*/
|
||||
INVALID_KEY_VALUE = 16,
|
||||
/**
|
||||
* Internal error (catch-all)
|
||||
*/
|
||||
INTERNAL_ERROR = 99,
|
||||
} WalletFfiError;
|
||||
|
||||
/**
|
||||
* Opaque pointer to the Wallet instance.
|
||||
*
|
||||
* This type is never instantiated directly - it's used as an opaque handle
|
||||
* to hide the internal wallet structure from C code.
|
||||
*/
|
||||
typedef struct WalletHandle {
|
||||
uint8_t _private[0];
|
||||
} WalletHandle;
|
||||
|
||||
/**
|
||||
* 32-byte array type for AccountId, keys, hashes, etc.
|
||||
*/
|
||||
typedef struct FfiBytes32 {
|
||||
uint8_t data[32];
|
||||
} FfiBytes32;
|
||||
|
||||
/**
|
||||
* Single entry in the account list.
|
||||
*/
|
||||
typedef struct FfiAccountListEntry {
|
||||
struct FfiBytes32 account_id;
|
||||
bool is_public;
|
||||
} FfiAccountListEntry;
|
||||
|
||||
/**
|
||||
* List of accounts returned by wallet_ffi_list_accounts.
|
||||
*/
|
||||
typedef struct FfiAccountList {
|
||||
struct FfiAccountListEntry *entries;
|
||||
uintptr_t count;
|
||||
} FfiAccountList;
|
||||
|
||||
/**
|
||||
* Program ID - 8 u32 values (32 bytes total).
|
||||
*/
|
||||
typedef struct FfiProgramId {
|
||||
uint32_t data[8];
|
||||
} FfiProgramId;
|
||||
|
||||
/**
|
||||
* U128 - 16 bytes little endian
|
||||
*/
|
||||
typedef struct FfiU128 {
|
||||
uint8_t data[16];
|
||||
} FfiU128;
|
||||
|
||||
/**
|
||||
* Account data structure - C-compatible version of nssa Account.
|
||||
*
|
||||
* Note: `balance` and `nonce` are u128 values represented as little-endian
|
||||
* byte arrays since C doesn't have native u128 support.
|
||||
*/
|
||||
typedef struct FfiAccount {
|
||||
struct FfiProgramId program_owner;
|
||||
/**
|
||||
* Balance as little-endian [u8; 16]
|
||||
*/
|
||||
struct FfiU128 balance;
|
||||
/**
|
||||
* Pointer to account data bytes
|
||||
*/
|
||||
const uint8_t *data;
|
||||
/**
|
||||
* Length of account data
|
||||
*/
|
||||
uintptr_t data_len;
|
||||
/**
|
||||
* Nonce as little-endian [u8; 16]
|
||||
*/
|
||||
struct FfiU128 nonce;
|
||||
} FfiAccount;
|
||||
|
||||
/**
|
||||
* Public key info for a public account.
|
||||
*/
|
||||
typedef struct FfiPublicAccountKey {
|
||||
struct FfiBytes32 public_key;
|
||||
} FfiPublicAccountKey;
|
||||
|
||||
/**
|
||||
* Public keys for a private account (safe to expose).
|
||||
*/
|
||||
typedef struct FfiPrivateAccountKeys {
|
||||
/**
|
||||
* Nullifier public key (32 bytes)
|
||||
*/
|
||||
struct FfiBytes32 nullifier_public_key;
|
||||
/**
|
||||
* viewing public key (compressed secp256k1 point)
|
||||
*/
|
||||
const uint8_t *viewing_public_key;
|
||||
/**
|
||||
* Length of viewing public key (typically 33 bytes)
|
||||
*/
|
||||
uintptr_t viewing_public_key_len;
|
||||
} FfiPrivateAccountKeys;
|
||||
|
||||
/**
|
||||
* Result of a transfer operation.
|
||||
*/
|
||||
typedef struct FfiTransferResult {
|
||||
/**
|
||||
* Transaction hash (null-terminated string, or null on failure)
|
||||
*/
|
||||
char *tx_hash;
|
||||
/**
|
||||
* Whether the transfer succeeded
|
||||
*/
|
||||
bool success;
|
||||
} FfiTransferResult;
|
||||
|
||||
/**
|
||||
* Create a new public account.
|
||||
*
|
||||
* Public accounts use standard transaction signing and are suitable for
|
||||
* non-private operations.
|
||||
*
|
||||
* # Parameters
|
||||
* - `handle`: Valid wallet handle
|
||||
* - `out_account_id`: Output pointer for the new account ID (32 bytes)
|
||||
*
|
||||
* # Returns
|
||||
* - `Success` on successful creation
|
||||
* - Error code on failure
|
||||
*
|
||||
* # Safety
|
||||
* - `handle` must be a valid wallet handle from `wallet_ffi_create_new` or `wallet_ffi_open`
|
||||
* - `out_account_id` must be a valid pointer to a `FfiBytes32` struct
|
||||
*/
|
||||
enum WalletFfiError wallet_ffi_create_account_public(struct WalletHandle *handle,
|
||||
struct FfiBytes32 *out_account_id);
|
||||
|
||||
/**
|
||||
* Create a new private account.
|
||||
*
|
||||
* Private accounts use privacy-preserving transactions with nullifiers
|
||||
* and commitments.
|
||||
*
|
||||
* # Parameters
|
||||
* - `handle`: Valid wallet handle
|
||||
* - `out_account_id`: Output pointer for the new account ID (32 bytes)
|
||||
*
|
||||
* # Returns
|
||||
* - `Success` on successful creation
|
||||
* - Error code on failure
|
||||
*
|
||||
* # Safety
|
||||
* - `handle` must be a valid wallet handle from `wallet_ffi_create_new` or `wallet_ffi_open`
|
||||
* - `out_account_id` must be a valid pointer to a `FfiBytes32` struct
|
||||
*/
|
||||
enum WalletFfiError wallet_ffi_create_account_private(struct WalletHandle *handle,
|
||||
struct FfiBytes32 *out_account_id);
|
||||
|
||||
/**
|
||||
* List all accounts in the wallet.
|
||||
*
|
||||
* Returns both public and private accounts managed by this wallet.
|
||||
*
|
||||
* # Parameters
|
||||
* - `handle`: Valid wallet handle
|
||||
* - `out_list`: Output pointer for the account list
|
||||
*
|
||||
* # Returns
|
||||
* - `Success` on successful listing
|
||||
* - Error code on failure
|
||||
*
|
||||
* # Memory
|
||||
* The returned list must be freed with `wallet_ffi_free_account_list()`.
|
||||
*
|
||||
* # Safety
|
||||
* - `handle` must be a valid wallet handle from `wallet_ffi_create_new` or `wallet_ffi_open`
|
||||
* - `out_list` must be a valid pointer to a `FfiAccountList` struct
|
||||
*/
|
||||
enum WalletFfiError wallet_ffi_list_accounts(struct WalletHandle *handle,
|
||||
struct FfiAccountList *out_list);
|
||||
|
||||
/**
|
||||
* Free an account list returned by `wallet_ffi_list_accounts`.
|
||||
*
|
||||
* # Safety
|
||||
* The list must be either null or a valid list returned by `wallet_ffi_list_accounts`.
|
||||
*/
|
||||
void wallet_ffi_free_account_list(struct FfiAccountList *list);
|
||||
|
||||
/**
|
||||
* Get account balance.
|
||||
*
|
||||
* For public accounts, this fetches the balance from the network.
|
||||
* For private accounts, this returns the locally cached balance.
|
||||
*
|
||||
* # Parameters
|
||||
* - `handle`: Valid wallet handle
|
||||
* - `account_id`: The account ID (32 bytes)
|
||||
* - `is_public`: Whether this is a public account
|
||||
* - `out_balance`: Output for balance as little-endian [u8; 16]
|
||||
*
|
||||
* # Returns
|
||||
* - `Success` on successful query
|
||||
* - Error code on failure
|
||||
*
|
||||
* # Safety
|
||||
* - `handle` must be a valid wallet handle from `wallet_ffi_create_new` or `wallet_ffi_open`
|
||||
* - `account_id` must be a valid pointer to a `FfiBytes32` struct
|
||||
* - `out_balance` must be a valid pointer to a `[u8; 16]` array
|
||||
*/
|
||||
enum WalletFfiError wallet_ffi_get_balance(struct WalletHandle *handle,
|
||||
const struct FfiBytes32 *account_id,
|
||||
bool is_public,
|
||||
uint8_t (*out_balance)[16]);
|
||||
|
||||
/**
|
||||
* Get full public account data from the network.
|
||||
*
|
||||
* # Parameters
|
||||
* - `handle`: Valid wallet handle
|
||||
* - `account_id`: The account ID (32 bytes)
|
||||
* - `out_account`: Output pointer for account data
|
||||
*
|
||||
* # Returns
|
||||
* - `Success` on successful query
|
||||
* - Error code on failure
|
||||
*
|
||||
* # Memory
|
||||
* The account data must be freed with `wallet_ffi_free_account_data()`.
|
||||
*
|
||||
* # Safety
|
||||
* - `handle` must be a valid wallet handle from `wallet_ffi_create_new` or `wallet_ffi_open`
|
||||
* - `account_id` must be a valid pointer to a `FfiBytes32` struct
|
||||
* - `out_account` must be a valid pointer to a `FfiAccount` struct
|
||||
*/
|
||||
enum WalletFfiError wallet_ffi_get_account_public(struct WalletHandle *handle,
|
||||
const struct FfiBytes32 *account_id,
|
||||
struct FfiAccount *out_account);
|
||||
|
||||
/**
|
||||
* Free account data returned by `wallet_ffi_get_account_public`.
|
||||
*
|
||||
* # Safety
|
||||
* The account must be either null or a valid account returned by
|
||||
* `wallet_ffi_get_account_public`.
|
||||
*/
|
||||
void wallet_ffi_free_account_data(struct FfiAccount *account);
|
||||
|
||||
/**
|
||||
* Get the public key for a public account.
|
||||
*
|
||||
* This returns the public key derived from the account's signing key.
|
||||
*
|
||||
* # Parameters
|
||||
* - `handle`: Valid wallet handle
|
||||
* - `account_id`: The account ID (32 bytes)
|
||||
* - `out_public_key`: Output pointer for the public key
|
||||
*
|
||||
* # Returns
|
||||
* - `Success` on successful retrieval
|
||||
* - `KeyNotFound` if the account's key is not in this wallet
|
||||
* - Error code on other failures
|
||||
*
|
||||
* # Safety
|
||||
* - `handle` must be a valid wallet handle from `wallet_ffi_create_new` or `wallet_ffi_open`
|
||||
* - `account_id` must be a valid pointer to a `FfiBytes32` struct
|
||||
* - `out_public_key` must be a valid pointer to a `FfiPublicAccountKey` struct
|
||||
*/
|
||||
enum WalletFfiError wallet_ffi_get_public_account_key(struct WalletHandle *handle,
|
||||
const struct FfiBytes32 *account_id,
|
||||
struct FfiPublicAccountKey *out_public_key);
|
||||
|
||||
/**
|
||||
* Get keys for a private account.
|
||||
*
|
||||
* Returns the nullifier public key (NPK) and viewing public key (VPK)
|
||||
* for the specified private account. These keys are safe to share publicly.
|
||||
*
|
||||
* # Parameters
|
||||
* - `handle`: Valid wallet handle
|
||||
* - `account_id`: The account ID (32 bytes)
|
||||
* - `out_keys`: Output pointer for the key data
|
||||
*
|
||||
* # Returns
|
||||
* - `Success` on successful retrieval
|
||||
* - `AccountNotFound` if the private account is not in this wallet
|
||||
* - Error code on other failures
|
||||
*
|
||||
* # Memory
|
||||
* The keys structure must be freed with `wallet_ffi_free_private_account_keys()`.
|
||||
*
|
||||
* # Safety
|
||||
* - `handle` must be a valid wallet handle from `wallet_ffi_create_new` or `wallet_ffi_open`
|
||||
* - `account_id` must be a valid pointer to a `FfiBytes32` struct
|
||||
* - `out_keys` must be a valid pointer to a `FfiPrivateAccountKeys` struct
|
||||
*/
|
||||
enum WalletFfiError wallet_ffi_get_private_account_keys(struct WalletHandle *handle,
|
||||
const struct FfiBytes32 *account_id,
|
||||
struct FfiPrivateAccountKeys *out_keys);
|
||||
|
||||
/**
|
||||
* Free private account keys returned by `wallet_ffi_get_private_account_keys`.
|
||||
*
|
||||
* # Safety
|
||||
* The keys must be either null or valid keys returned by
|
||||
* `wallet_ffi_get_private_account_keys`.
|
||||
*/
|
||||
void wallet_ffi_free_private_account_keys(struct FfiPrivateAccountKeys *keys);
|
||||
|
||||
/**
|
||||
* Convert an account ID to a Base58 string.
|
||||
*
|
||||
* # Parameters
|
||||
* - `account_id`: The account ID (32 bytes)
|
||||
*
|
||||
* # Returns
|
||||
* - Pointer to null-terminated Base58 string on success
|
||||
* - Null pointer on error
|
||||
*
|
||||
* # Memory
|
||||
* The returned string must be freed with `wallet_ffi_free_string()`.
|
||||
*
|
||||
* # Safety
|
||||
* - `account_id` must be a valid pointer to a `FfiBytes32` struct
|
||||
*/
|
||||
char *wallet_ffi_account_id_to_base58(const struct FfiBytes32 *account_id);
|
||||
|
||||
/**
|
||||
* Parse a Base58 string into an account ID.
|
||||
*
|
||||
* # Parameters
|
||||
* - `base58_str`: Null-terminated Base58 string
|
||||
* - `out_account_id`: Output pointer for the account ID (32 bytes)
|
||||
*
|
||||
* # Returns
|
||||
* - `Success` on successful parsing
|
||||
* - `InvalidAccountId` if the string is not valid Base58
|
||||
* - Error code on other failures
|
||||
*
|
||||
* # Safety
|
||||
* - `base58_str` must be a valid pointer to a null-terminated C string
|
||||
* - `out_account_id` must be a valid pointer to a `FfiBytes32` struct
|
||||
*/
|
||||
enum WalletFfiError wallet_ffi_account_id_from_base58(const char *base58_str,
|
||||
struct FfiBytes32 *out_account_id);
|
||||
|
||||
/**
|
||||
* Synchronize private accounts to a specific block.
|
||||
*
|
||||
* This scans the blockchain from the last synced block to the specified block,
|
||||
* updating private account balances based on any relevant transactions.
|
||||
*
|
||||
* # Parameters
|
||||
* - `handle`: Valid wallet handle
|
||||
* - `block_id`: Target block number to sync to
|
||||
*
|
||||
* # Returns
|
||||
* - `Success` if synchronization completed
|
||||
* - `SyncError` if synchronization failed
|
||||
* - Error code on other failures
|
||||
*
|
||||
* # Note
|
||||
* This operation can take a while for large block ranges. The wallet
|
||||
* internally uses a progress bar which may output to stdout.
|
||||
*
|
||||
* # Safety
|
||||
* - `handle` must be a valid wallet handle from `wallet_ffi_create_new` or `wallet_ffi_open`
|
||||
*/
|
||||
enum WalletFfiError wallet_ffi_sync_to_block(struct WalletHandle *handle, uint64_t block_id);
|
||||
|
||||
/**
|
||||
* Get the last synced block number.
|
||||
*
|
||||
* # Parameters
|
||||
* - `handle`: Valid wallet handle
|
||||
* - `out_block_id`: Output pointer for the block number
|
||||
*
|
||||
* # Returns
|
||||
* - `Success` on success
|
||||
* - Error code on failure
|
||||
*
|
||||
* # Safety
|
||||
* - `handle` must be a valid wallet handle from `wallet_ffi_create_new` or `wallet_ffi_open`
|
||||
* - `out_block_id` must be a valid pointer to a `u64`
|
||||
*/
|
||||
enum WalletFfiError wallet_ffi_get_last_synced_block(struct WalletHandle *handle,
|
||||
uint64_t *out_block_id);
|
||||
|
||||
/**
|
||||
* Get the current block height from the sequencer.
|
||||
*
|
||||
* # Parameters
|
||||
* - `handle`: Valid wallet handle
|
||||
* - `out_block_height`: Output pointer for the current block height
|
||||
*
|
||||
* # Returns
|
||||
* - `Success` on success
|
||||
* - `NetworkError` if the sequencer is unreachable
|
||||
* - Error code on other failures
|
||||
*
|
||||
* # Safety
|
||||
* - `handle` must be a valid wallet handle from `wallet_ffi_create_new` or `wallet_ffi_open`
|
||||
* - `out_block_height` must be a valid pointer to a `u64`
|
||||
*/
|
||||
enum WalletFfiError wallet_ffi_get_current_block_height(struct WalletHandle *handle,
|
||||
uint64_t *out_block_height);
|
||||
|
||||
/**
|
||||
* Send a public token transfer.
|
||||
*
|
||||
* Transfers tokens from one public account to another on the network.
|
||||
*
|
||||
* # Parameters
|
||||
* - `handle`: Valid wallet handle
|
||||
* - `from`: Source account ID (must be owned by this wallet)
|
||||
* - `to`: Destination account ID
|
||||
* - `amount`: Amount to transfer as little-endian [u8; 16]
|
||||
* - `out_result`: Output pointer for transfer result
|
||||
*
|
||||
* # Returns
|
||||
* - `Success` if the transfer was submitted successfully
|
||||
* - `InsufficientFunds` if the source account doesn't have enough balance
|
||||
* - `KeyNotFound` if the source account's signing key is not in this wallet
|
||||
* - Error code on other failures
|
||||
*
|
||||
* # Memory
|
||||
* The result must be freed with `wallet_ffi_free_transfer_result()`.
|
||||
*
|
||||
* # Safety
|
||||
* - `handle` must be a valid wallet handle from `wallet_ffi_create_new` or `wallet_ffi_open`
|
||||
* - `from` must be a valid pointer to a `FfiBytes32` struct
|
||||
* - `to` must be a valid pointer to a `FfiBytes32` struct
|
||||
* - `amount` must be a valid pointer to a `[u8; 16]` array
|
||||
* - `out_result` must be a valid pointer to a `FfiTransferResult` struct
|
||||
*/
|
||||
enum WalletFfiError wallet_ffi_transfer_public(struct WalletHandle *handle,
|
||||
const struct FfiBytes32 *from,
|
||||
const struct FfiBytes32 *to,
|
||||
const uint8_t (*amount)[16],
|
||||
struct FfiTransferResult *out_result);
|
||||
|
||||
/**
|
||||
* Register a public account on the network.
|
||||
*
|
||||
* This initializes a public account on the blockchain. The account must be
|
||||
* owned by this wallet.
|
||||
*
|
||||
* # Parameters
|
||||
* - `handle`: Valid wallet handle
|
||||
* - `account_id`: Account ID to register
|
||||
* - `out_result`: Output pointer for registration result
|
||||
*
|
||||
* # Returns
|
||||
* - `Success` if the registration was submitted successfully
|
||||
* - Error code on failure
|
||||
*
|
||||
* # Memory
|
||||
* The result must be freed with `wallet_ffi_free_transfer_result()`.
|
||||
*
|
||||
* # Safety
|
||||
* - `handle` must be a valid wallet handle from `wallet_ffi_create_new` or `wallet_ffi_open`
|
||||
* - `account_id` must be a valid pointer to a `FfiBytes32` struct
|
||||
* - `out_result` must be a valid pointer to a `FfiTransferResult` struct
|
||||
*/
|
||||
enum WalletFfiError wallet_ffi_register_public_account(struct WalletHandle *handle,
|
||||
const struct FfiBytes32 *account_id,
|
||||
struct FfiTransferResult *out_result);
|
||||
|
||||
/**
|
||||
* Free a transfer result returned by `wallet_ffi_transfer_public` or
|
||||
* `wallet_ffi_register_public_account`.
|
||||
*
|
||||
* # Safety
|
||||
* The result must be either null or a valid result from a transfer function.
|
||||
*/
|
||||
void wallet_ffi_free_transfer_result(struct FfiTransferResult *result);
|
||||
|
||||
/**
|
||||
* Create a new wallet with fresh storage.
|
||||
*
|
||||
* This initializes a new wallet with a new seed derived from the password.
|
||||
* Use this for first-time wallet creation.
|
||||
*
|
||||
* # Parameters
|
||||
* - `config_path`: Path to the wallet configuration file (JSON)
|
||||
* - `storage_path`: Path where wallet data will be stored
|
||||
* - `password`: Password for encrypting the wallet seed
|
||||
*
|
||||
* # Returns
|
||||
* - Opaque wallet handle on success
|
||||
* - Null pointer on error (call `wallet_ffi_get_last_error()` for details)
|
||||
*
|
||||
* # Safety
|
||||
* All string parameters must be valid null-terminated UTF-8 strings.
|
||||
*/
|
||||
struct WalletHandle *wallet_ffi_create_new(const char *config_path,
|
||||
const char *storage_path,
|
||||
const char *password);
|
||||
|
||||
/**
|
||||
* Open an existing wallet from storage.
|
||||
*
|
||||
* This loads a wallet that was previously created with `wallet_ffi_create_new()`.
|
||||
*
|
||||
* # Parameters
|
||||
* - `config_path`: Path to the wallet configuration file (JSON)
|
||||
* - `storage_path`: Path where wallet data is stored
|
||||
*
|
||||
* # Returns
|
||||
* - Opaque wallet handle on success
|
||||
* - Null pointer on error (call `wallet_ffi_get_last_error()` for details)
|
||||
*
|
||||
* # Safety
|
||||
* All string parameters must be valid null-terminated UTF-8 strings.
|
||||
*/
|
||||
struct WalletHandle *wallet_ffi_open(const char *config_path, const char *storage_path);
|
||||
|
||||
/**
|
||||
* Destroy a wallet handle and free its resources.
|
||||
*
|
||||
* After calling this function, the handle is invalid and must not be used.
|
||||
*
|
||||
* # Safety
|
||||
* - The handle must be either null or a valid handle from `wallet_ffi_create_new()` or
|
||||
* `wallet_ffi_open()`.
|
||||
* - The handle must not be used after this call.
|
||||
*/
|
||||
void wallet_ffi_destroy(struct WalletHandle *handle);
|
||||
|
||||
/**
|
||||
* Save wallet state to persistent storage.
|
||||
*
|
||||
* This should be called periodically or after important operations to ensure
|
||||
* wallet data is persisted to disk.
|
||||
*
|
||||
* # Parameters
|
||||
* - `handle`: Valid wallet handle
|
||||
*
|
||||
* # Returns
|
||||
* - `Success` on successful save
|
||||
* - Error code on failure
|
||||
*
|
||||
* # Safety
|
||||
* - `handle` must be a valid wallet handle from `wallet_ffi_create_new` or `wallet_ffi_open`
|
||||
*/
|
||||
enum WalletFfiError wallet_ffi_save(struct WalletHandle *handle);
|
||||
|
||||
/**
|
||||
* Get the sequencer address from the wallet configuration.
|
||||
*
|
||||
* # Parameters
|
||||
* - `handle`: Valid wallet handle
|
||||
*
|
||||
* # Returns
|
||||
* - Pointer to null-terminated string on success (caller must free with
|
||||
* `wallet_ffi_free_string()`)
|
||||
* - Null pointer on error
|
||||
*
|
||||
* # Safety
|
||||
* - `handle` must be a valid wallet handle from `wallet_ffi_create_new` or `wallet_ffi_open`
|
||||
*/
|
||||
char *wallet_ffi_get_sequencer_addr(struct WalletHandle *handle);
|
||||
|
||||
/**
|
||||
* Free a string returned by wallet FFI functions.
|
||||
*
|
||||
* # Safety
|
||||
* The pointer must be either null or a valid string returned by an FFI function.
|
||||
*/
|
||||
void wallet_ffi_free_string(char *ptr);
|
||||
|
||||
#endif /* WALLET_FFI_H */
|
||||
@ -84,9 +84,9 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
{
|
||||
"Private": {
|
||||
"account_id": "3oCG8gqdKLMegw4rRfyaMQvuPHpcASt7xwttsmnZLSkw",
|
||||
"account_id": "2ECgkFTaXzwjJBXR7ZKmXYQtpHbvTTHK9Auma4NL9AUo",
|
||||
"account": {
|
||||
"program_owner": [
|
||||
0,
|
||||
@ -103,219 +103,19 @@
|
||||
"nonce": 0
|
||||
},
|
||||
"key_chain": {
|
||||
"secret_spending_key": [
|
||||
251,
|
||||
82,
|
||||
235,
|
||||
1,
|
||||
146,
|
||||
96,
|
||||
30,
|
||||
81,
|
||||
162,
|
||||
234,
|
||||
33,
|
||||
15,
|
||||
123,
|
||||
129,
|
||||
116,
|
||||
0,
|
||||
84,
|
||||
136,
|
||||
176,
|
||||
70,
|
||||
190,
|
||||
224,
|
||||
161,
|
||||
54,
|
||||
134,
|
||||
142,
|
||||
154,
|
||||
1,
|
||||
18,
|
||||
251,
|
||||
242,
|
||||
189
|
||||
],
|
||||
"secret_spending_key": [112, 17, 152, 192, 217, 201, 142, 92, 111, 68, 85, 222, 107, 73, 78, 196, 118, 226, 37, 17, 185, 177, 149, 182, 9, 85, 187, 152, 163, 144, 68, 121],
|
||||
"private_key_holder": {
|
||||
"nullifier_secret_key": [
|
||||
29,
|
||||
250,
|
||||
10,
|
||||
187,
|
||||
35,
|
||||
123,
|
||||
180,
|
||||
250,
|
||||
246,
|
||||
97,
|
||||
216,
|
||||
153,
|
||||
44,
|
||||
156,
|
||||
16,
|
||||
93,
|
||||
241,
|
||||
26,
|
||||
174,
|
||||
219,
|
||||
72,
|
||||
84,
|
||||
34,
|
||||
247,
|
||||
112,
|
||||
101,
|
||||
217,
|
||||
243,
|
||||
189,
|
||||
173,
|
||||
75,
|
||||
20
|
||||
],
|
||||
"incoming_viewing_secret_key": [
|
||||
251,
|
||||
201,
|
||||
22,
|
||||
154,
|
||||
100,
|
||||
165,
|
||||
218,
|
||||
108,
|
||||
163,
|
||||
190,
|
||||
135,
|
||||
91,
|
||||
145,
|
||||
84,
|
||||
69,
|
||||
241,
|
||||
46,
|
||||
117,
|
||||
217,
|
||||
110,
|
||||
197,
|
||||
248,
|
||||
91,
|
||||
193,
|
||||
14,
|
||||
104,
|
||||
88,
|
||||
103,
|
||||
67,
|
||||
153,
|
||||
182,
|
||||
158
|
||||
],
|
||||
"outgoing_viewing_secret_key": [
|
||||
25,
|
||||
67,
|
||||
121,
|
||||
76,
|
||||
175,
|
||||
100,
|
||||
30,
|
||||
198,
|
||||
105,
|
||||
123,
|
||||
49,
|
||||
169,
|
||||
75,
|
||||
178,
|
||||
75,
|
||||
210,
|
||||
100,
|
||||
143,
|
||||
210,
|
||||
243,
|
||||
228,
|
||||
243,
|
||||
21,
|
||||
18,
|
||||
36,
|
||||
84,
|
||||
164,
|
||||
186,
|
||||
139,
|
||||
113,
|
||||
214,
|
||||
12
|
||||
]
|
||||
"nullifier_secret_key": [52, 33, 235, 245, 42, 132, 163, 182, 114, 56, 144, 187, 147, 23, 184, 227, 128, 12, 180, 142, 217, 110, 188, 177, 155, 141, 23, 127, 216, 185, 33, 126],
|
||||
"viewing_secret_key": [44, 81, 165, 166, 34, 188, 192, 240, 40, 9, 83, 189, 215, 184, 246, 154, 247, 227, 155, 16, 121, 238, 4, 245, 63, 135, 192, 213, 222, 247, 120, 86]
|
||||
},
|
||||
"nullifer_public_key": [
|
||||
63,
|
||||
202,
|
||||
178,
|
||||
231,
|
||||
183,
|
||||
82,
|
||||
237,
|
||||
212,
|
||||
216,
|
||||
221,
|
||||
215,
|
||||
255,
|
||||
153,
|
||||
101,
|
||||
177,
|
||||
161,
|
||||
254,
|
||||
210,
|
||||
128,
|
||||
122,
|
||||
54,
|
||||
190,
|
||||
230,
|
||||
151,
|
||||
183,
|
||||
64,
|
||||
225,
|
||||
229,
|
||||
113,
|
||||
1,
|
||||
228,
|
||||
97
|
||||
],
|
||||
"incoming_viewing_public_key": [
|
||||
3,
|
||||
235,
|
||||
139,
|
||||
131,
|
||||
237,
|
||||
177,
|
||||
122,
|
||||
189,
|
||||
6,
|
||||
177,
|
||||
167,
|
||||
178,
|
||||
202,
|
||||
117,
|
||||
246,
|
||||
58,
|
||||
28,
|
||||
65,
|
||||
132,
|
||||
79,
|
||||
220,
|
||||
139,
|
||||
119,
|
||||
243,
|
||||
187,
|
||||
160,
|
||||
212,
|
||||
121,
|
||||
61,
|
||||
247,
|
||||
116,
|
||||
72,
|
||||
205
|
||||
]
|
||||
"nullifer_public_key": [13, 25, 40, 5, 198, 248, 210, 248, 237, 121, 124, 145, 186, 142, 253, 216, 236, 69, 193, 32, 166, 167, 49, 133, 172, 111, 159, 46, 84, 17, 157, 23],
|
||||
"viewing_public_key": [3, 43, 116, 165, 161, 27, 150, 158, 175, 198, 215, 27, 121, 126, 158, 224, 249, 92, 168, 163, 173, 115, 120, 122, 89, 173, 133, 94, 39, 238, 62, 52, 193]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"Private": {
|
||||
"account_id": "AKTcXgJ1xoynta1Ec7y6Jso1z1JQtHqd7aPQ1h9er6xX",
|
||||
"account_id": "E8HwiTyQe4H9HK7icTvn95HQMnzx49mP9A2ddtMLpNaN",
|
||||
"account": {
|
||||
"program_owner": [
|
||||
0,
|
||||
@ -332,213 +132,13 @@
|
||||
"nonce": 0
|
||||
},
|
||||
"key_chain": {
|
||||
"secret_spending_key": [
|
||||
238,
|
||||
171,
|
||||
241,
|
||||
69,
|
||||
111,
|
||||
217,
|
||||
85,
|
||||
64,
|
||||
19,
|
||||
82,
|
||||
18,
|
||||
189,
|
||||
32,
|
||||
91,
|
||||
78,
|
||||
175,
|
||||
107,
|
||||
7,
|
||||
109,
|
||||
60,
|
||||
52,
|
||||
44,
|
||||
243,
|
||||
230,
|
||||
72,
|
||||
244,
|
||||
192,
|
||||
92,
|
||||
137,
|
||||
33,
|
||||
118,
|
||||
254
|
||||
],
|
||||
"secret_spending_key": [48, 175, 124, 10, 230, 240, 166, 14, 249, 254, 157, 226, 208, 124, 122, 177, 203, 139, 192, 180, 43, 120, 55, 151, 50, 21, 113, 22, 254, 83, 148, 56],
|
||||
"private_key_holder": {
|
||||
"nullifier_secret_key": [
|
||||
25,
|
||||
211,
|
||||
215,
|
||||
119,
|
||||
57,
|
||||
223,
|
||||
247,
|
||||
37,
|
||||
245,
|
||||
144,
|
||||
122,
|
||||
29,
|
||||
118,
|
||||
245,
|
||||
83,
|
||||
228,
|
||||
23,
|
||||
9,
|
||||
101,
|
||||
120,
|
||||
88,
|
||||
33,
|
||||
238,
|
||||
207,
|
||||
128,
|
||||
61,
|
||||
110,
|
||||
2,
|
||||
89,
|
||||
62,
|
||||
164,
|
||||
13
|
||||
],
|
||||
"incoming_viewing_secret_key": [
|
||||
193,
|
||||
181,
|
||||
14,
|
||||
196,
|
||||
142,
|
||||
84,
|
||||
15,
|
||||
65,
|
||||
128,
|
||||
101,
|
||||
70,
|
||||
196,
|
||||
241,
|
||||
47,
|
||||
130,
|
||||
221,
|
||||
23,
|
||||
146,
|
||||
161,
|
||||
237,
|
||||
221,
|
||||
40,
|
||||
19,
|
||||
126,
|
||||
59,
|
||||
15,
|
||||
169,
|
||||
236,
|
||||
25,
|
||||
105,
|
||||
104,
|
||||
231
|
||||
],
|
||||
"outgoing_viewing_secret_key": [
|
||||
20,
|
||||
170,
|
||||
220,
|
||||
108,
|
||||
41,
|
||||
23,
|
||||
155,
|
||||
217,
|
||||
247,
|
||||
190,
|
||||
175,
|
||||
168,
|
||||
247,
|
||||
34,
|
||||
105,
|
||||
134,
|
||||
114,
|
||||
74,
|
||||
104,
|
||||
91,
|
||||
211,
|
||||
62,
|
||||
126,
|
||||
13,
|
||||
130,
|
||||
100,
|
||||
241,
|
||||
214,
|
||||
250,
|
||||
236,
|
||||
38,
|
||||
150
|
||||
]
|
||||
"nullifier_secret_key": [99, 82, 190, 140, 234, 10, 61, 163, 15, 211, 179, 54, 70, 166, 87, 5, 182, 68, 117, 244, 217, 23, 99, 9, 4, 177, 230, 125, 109, 91, 160, 30],
|
||||
"viewing_secret_key": [205, 32, 76, 251, 255, 236, 96, 119, 61, 111, 65, 100, 75, 218, 12, 22, 17, 170, 55, 226, 21, 154, 161, 34, 208, 74, 27, 1, 119, 13, 88, 128]
|
||||
},
|
||||
"nullifer_public_key": [
|
||||
192,
|
||||
251,
|
||||
166,
|
||||
243,
|
||||
167,
|
||||
236,
|
||||
84,
|
||||
249,
|
||||
35,
|
||||
136,
|
||||
130,
|
||||
172,
|
||||
219,
|
||||
225,
|
||||
161,
|
||||
139,
|
||||
229,
|
||||
89,
|
||||
243,
|
||||
125,
|
||||
194,
|
||||
213,
|
||||
209,
|
||||
30,
|
||||
23,
|
||||
174,
|
||||
100,
|
||||
244,
|
||||
124,
|
||||
74,
|
||||
140,
|
||||
47
|
||||
],
|
||||
"incoming_viewing_public_key": [
|
||||
2,
|
||||
181,
|
||||
98,
|
||||
93,
|
||||
216,
|
||||
241,
|
||||
241,
|
||||
110,
|
||||
58,
|
||||
198,
|
||||
119,
|
||||
174,
|
||||
250,
|
||||
184,
|
||||
1,
|
||||
204,
|
||||
200,
|
||||
173,
|
||||
44,
|
||||
238,
|
||||
37,
|
||||
247,
|
||||
170,
|
||||
156,
|
||||
100,
|
||||
254,
|
||||
116,
|
||||
242,
|
||||
28,
|
||||
183,
|
||||
187,
|
||||
77,
|
||||
255
|
||||
]
|
||||
"nullifer_public_key": [32, 67, 72, 164, 106, 53, 66, 239, 141, 15, 52, 230, 136, 177, 2, 236, 207, 243, 134, 135, 210, 143, 87, 232, 215, 128, 194, 120, 113, 224, 4, 165],
|
||||
"viewing_public_key": [2, 79, 110, 46, 203, 29, 206, 205, 18, 86, 27, 189, 104, 103, 113, 181, 110, 53, 78, 172, 11, 171, 190, 18, 126, 214, 81, 77, 192, 154, 58, 195, 238]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,7 +20,7 @@ pub enum AccountSubcommand {
|
||||
/// Flag to get raw account data
|
||||
#[arg(short, long)]
|
||||
raw: bool,
|
||||
/// Display keys (pk for public accounts, npk/ipk for private accounts)
|
||||
/// Display keys (pk for public accounts, npk/vpk for private accounts)
|
||||
#[arg(short, long)]
|
||||
keys: bool,
|
||||
/// Valid 32 byte base58 string with privacy prefix
|
||||
@ -107,8 +107,8 @@ impl WalletSubcommand for NewSubcommand {
|
||||
);
|
||||
println!("With npk {}", hex::encode(key.nullifer_public_key.0));
|
||||
println!(
|
||||
"With ipk {}",
|
||||
hex::encode(key.incoming_viewing_public_key.to_bytes())
|
||||
"With vpk {}",
|
||||
hex::encode(key.viewing_public_key.to_bytes())
|
||||
);
|
||||
|
||||
wallet_core.store_persistent_data().await?;
|
||||
@ -207,10 +207,7 @@ impl WalletSubcommand for AccountSubcommand {
|
||||
.ok_or(anyhow::anyhow!("Private account not found in storage"))?;
|
||||
|
||||
println!("npk {}", hex::encode(key.nullifer_public_key.0));
|
||||
println!(
|
||||
"ipk {}",
|
||||
hex::encode(key.incoming_viewing_public_key.to_bytes())
|
||||
);
|
||||
println!("vpk {}", hex::encode(key.viewing_public_key.to_bytes()));
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
||||
@ -22,7 +22,7 @@ pub enum AuthTransferSubcommand {
|
||||
},
|
||||
/// Send native tokens from one account to another with variable privacy
|
||||
///
|
||||
/// If receiver is private, then `to` and (`to_npk` , `to_ipk`) is a mutually exclusive
|
||||
/// If receiver is private, then `to` and (`to_npk` , `to_vpk`) is a mutually exclusive
|
||||
/// patterns.
|
||||
///
|
||||
/// First is used for owned accounts, second otherwise.
|
||||
@ -36,9 +36,9 @@ pub enum AuthTransferSubcommand {
|
||||
/// to_npk - valid 32 byte hex string
|
||||
#[arg(long)]
|
||||
to_npk: Option<String>,
|
||||
/// to_ipk - valid 33 byte hex string
|
||||
/// to_vpk - valid 33 byte hex string
|
||||
#[arg(long)]
|
||||
to_ipk: Option<String>,
|
||||
to_vpk: Option<String>,
|
||||
/// amount - amount of balance to move
|
||||
#[arg(long)]
|
||||
amount: u128,
|
||||
@ -102,10 +102,10 @@ impl WalletSubcommand for AuthTransferSubcommand {
|
||||
from,
|
||||
to,
|
||||
to_npk,
|
||||
to_ipk,
|
||||
to_vpk,
|
||||
amount,
|
||||
} => {
|
||||
let underlying_subcommand = match (to, to_npk, to_ipk) {
|
||||
let underlying_subcommand = match (to, to_npk, to_vpk) {
|
||||
(None, None, None) => {
|
||||
anyhow::bail!(
|
||||
"Provide either account account_id of receiver or their public keys"
|
||||
@ -154,7 +154,7 @@ impl WalletSubcommand for AuthTransferSubcommand {
|
||||
}
|
||||
}
|
||||
}
|
||||
(None, Some(to_npk), Some(to_ipk)) => {
|
||||
(None, Some(to_npk), Some(to_vpk)) => {
|
||||
let (from, from_privacy) = parse_addr_with_privacy_prefix(&from)?;
|
||||
|
||||
match from_privacy {
|
||||
@ -163,7 +163,7 @@ impl WalletSubcommand for AuthTransferSubcommand {
|
||||
NativeTokenTransferProgramSubcommandPrivate::PrivateForeign {
|
||||
from,
|
||||
to_npk,
|
||||
to_ipk,
|
||||
to_vpk,
|
||||
amount,
|
||||
},
|
||||
)
|
||||
@ -173,7 +173,7 @@ impl WalletSubcommand for AuthTransferSubcommand {
|
||||
NativeTokenTransferProgramSubcommandShielded::ShieldedForeign {
|
||||
from,
|
||||
to_npk,
|
||||
to_ipk,
|
||||
to_vpk,
|
||||
amount,
|
||||
},
|
||||
)
|
||||
@ -255,9 +255,9 @@ pub enum NativeTokenTransferProgramSubcommandShielded {
|
||||
/// to_npk - valid 32 byte hex string
|
||||
#[arg(long)]
|
||||
to_npk: String,
|
||||
/// to_ipk - valid 33 byte hex string
|
||||
/// to_vpk - valid 33 byte hex string
|
||||
#[arg(long)]
|
||||
to_ipk: String,
|
||||
to_vpk: String,
|
||||
/// amount - amount of balance to move
|
||||
#[arg(long)]
|
||||
amount: u128,
|
||||
@ -292,9 +292,9 @@ pub enum NativeTokenTransferProgramSubcommandPrivate {
|
||||
/// to_npk - valid 32 byte hex string
|
||||
#[arg(long)]
|
||||
to_npk: String,
|
||||
/// to_ipk - valid 33 byte hex string
|
||||
/// to_vpk - valid 33 byte hex string
|
||||
#[arg(long)]
|
||||
to_ipk: String,
|
||||
to_vpk: String,
|
||||
/// amount - amount of balance to move
|
||||
#[arg(long)]
|
||||
amount: u128,
|
||||
@ -336,7 +336,7 @@ impl WalletSubcommand for NativeTokenTransferProgramSubcommandPrivate {
|
||||
NativeTokenTransferProgramSubcommandPrivate::PrivateForeign {
|
||||
from,
|
||||
to_npk,
|
||||
to_ipk,
|
||||
to_vpk,
|
||||
amount,
|
||||
} => {
|
||||
let from: AccountId = from.parse().unwrap();
|
||||
@ -345,14 +345,14 @@ impl WalletSubcommand for NativeTokenTransferProgramSubcommandPrivate {
|
||||
to_npk.copy_from_slice(&to_npk_res);
|
||||
let to_npk = nssa_core::NullifierPublicKey(to_npk);
|
||||
|
||||
let to_ipk_res = hex::decode(to_ipk)?;
|
||||
let mut to_ipk = [0u8; 33];
|
||||
to_ipk.copy_from_slice(&to_ipk_res);
|
||||
let to_ipk =
|
||||
nssa_core::encryption::shared_key_derivation::Secp256k1Point(to_ipk.to_vec());
|
||||
let to_vpk_res = hex::decode(to_vpk)?;
|
||||
let mut to_vpk = [0u8; 33];
|
||||
to_vpk.copy_from_slice(&to_vpk_res);
|
||||
let to_vpk =
|
||||
nssa_core::encryption::shared_key_derivation::Secp256k1Point(to_vpk.to_vec());
|
||||
|
||||
let (res, [secret_from, _]) = NativeTokenTransfer(wallet_core)
|
||||
.send_private_transfer_to_outer_account(from, to_npk, to_ipk, amount)
|
||||
.send_private_transfer_to_outer_account(from, to_npk, to_vpk, amount)
|
||||
.await?;
|
||||
|
||||
println!("Results of tx send are {res:#?}");
|
||||
@ -412,7 +412,7 @@ impl WalletSubcommand for NativeTokenTransferProgramSubcommandShielded {
|
||||
NativeTokenTransferProgramSubcommandShielded::ShieldedForeign {
|
||||
from,
|
||||
to_npk,
|
||||
to_ipk,
|
||||
to_vpk,
|
||||
amount,
|
||||
} => {
|
||||
let from: AccountId = from.parse().unwrap();
|
||||
@ -422,14 +422,14 @@ impl WalletSubcommand for NativeTokenTransferProgramSubcommandShielded {
|
||||
to_npk.copy_from_slice(&to_npk_res);
|
||||
let to_npk = nssa_core::NullifierPublicKey(to_npk);
|
||||
|
||||
let to_ipk_res = hex::decode(to_ipk)?;
|
||||
let mut to_ipk = [0u8; 33];
|
||||
to_ipk.copy_from_slice(&to_ipk_res);
|
||||
let to_ipk =
|
||||
nssa_core::encryption::shared_key_derivation::Secp256k1Point(to_ipk.to_vec());
|
||||
let to_vpk_res = hex::decode(to_vpk)?;
|
||||
let mut to_vpk = [0u8; 33];
|
||||
to_vpk.copy_from_slice(&to_vpk_res);
|
||||
let to_vpk =
|
||||
nssa_core::encryption::shared_key_derivation::Secp256k1Point(to_vpk.to_vec());
|
||||
|
||||
let (res, _) = NativeTokenTransfer(wallet_core)
|
||||
.send_shielded_transfer_to_outer_account(from, to_npk, to_ipk, amount)
|
||||
.send_shielded_transfer_to_outer_account(from, to_npk, to_vpk, amount)
|
||||
.await?;
|
||||
|
||||
println!("Results of tx send are {res:#?}");
|
||||
|
||||
@ -29,7 +29,7 @@ pub enum TokenProgramAgnosticSubcommand {
|
||||
},
|
||||
/// Send tokens from one account to another with variable privacy
|
||||
///
|
||||
/// If receiver is private, then `to` and (`to_npk` , `to_ipk`) is a mutually exclusive
|
||||
/// If receiver is private, then `to` and (`to_npk` , `to_vpk`) is a mutually exclusive
|
||||
/// patterns.
|
||||
///
|
||||
/// First is used for owned accounts, second otherwise.
|
||||
@ -43,9 +43,9 @@ pub enum TokenProgramAgnosticSubcommand {
|
||||
/// to_npk - valid 32 byte hex string
|
||||
#[arg(long)]
|
||||
to_npk: Option<String>,
|
||||
/// to_ipk - valid 33 byte hex string
|
||||
/// to_vpk - valid 33 byte hex string
|
||||
#[arg(long)]
|
||||
to_ipk: Option<String>,
|
||||
to_vpk: Option<String>,
|
||||
/// amount - amount of balance to move
|
||||
#[arg(long)]
|
||||
amount: u128,
|
||||
@ -71,7 +71,7 @@ pub enum TokenProgramAgnosticSubcommand {
|
||||
///
|
||||
/// `definition` is owned
|
||||
///
|
||||
/// If `holder` is private, then `holder` and (`holder_npk` , `holder_ipk`) is a mutually
|
||||
/// If `holder` is private, then `holder` and (`holder_npk` , `holder_vpk`) is a mutually
|
||||
/// exclusive patterns.
|
||||
///
|
||||
/// First is used for owned accounts, second otherwise.
|
||||
@ -85,9 +85,9 @@ pub enum TokenProgramAgnosticSubcommand {
|
||||
/// holder_npk - valid 32 byte hex string
|
||||
#[arg(long)]
|
||||
holder_npk: Option<String>,
|
||||
/// to_ipk - valid 33 byte hex string
|
||||
/// to_vpk - valid 33 byte hex string
|
||||
#[arg(long)]
|
||||
holder_ipk: Option<String>,
|
||||
holder_vpk: Option<String>,
|
||||
/// amount - amount of balance to mint
|
||||
#[arg(long)]
|
||||
amount: u128,
|
||||
@ -160,10 +160,10 @@ impl WalletSubcommand for TokenProgramAgnosticSubcommand {
|
||||
from,
|
||||
to,
|
||||
to_npk,
|
||||
to_ipk,
|
||||
to_vpk,
|
||||
amount,
|
||||
} => {
|
||||
let underlying_subcommand = match (to, to_npk, to_ipk) {
|
||||
let underlying_subcommand = match (to, to_npk, to_vpk) {
|
||||
(None, None, None) => {
|
||||
anyhow::bail!(
|
||||
"Provide either account account_id of receiver or their public keys"
|
||||
@ -220,7 +220,7 @@ impl WalletSubcommand for TokenProgramAgnosticSubcommand {
|
||||
}
|
||||
}
|
||||
}
|
||||
(None, Some(to_npk), Some(to_ipk)) => {
|
||||
(None, Some(to_npk), Some(to_vpk)) => {
|
||||
let (from, from_privacy) = parse_addr_with_privacy_prefix(&from)?;
|
||||
|
||||
match from_privacy {
|
||||
@ -228,7 +228,7 @@ impl WalletSubcommand for TokenProgramAgnosticSubcommand {
|
||||
TokenProgramSubcommandPrivate::TransferTokenPrivateForeign {
|
||||
sender_account_id: from,
|
||||
recipient_npk: to_npk,
|
||||
recipient_ipk: to_ipk,
|
||||
recipient_vpk: to_vpk,
|
||||
balance_to_move: amount,
|
||||
},
|
||||
),
|
||||
@ -236,7 +236,7 @@ impl WalletSubcommand for TokenProgramAgnosticSubcommand {
|
||||
TokenProgramSubcommandShielded::TransferTokenShieldedForeign {
|
||||
sender_account_id: from,
|
||||
recipient_npk: to_npk,
|
||||
recipient_ipk: to_ipk,
|
||||
recipient_vpk: to_vpk,
|
||||
balance_to_move: amount,
|
||||
},
|
||||
),
|
||||
@ -302,10 +302,10 @@ impl WalletSubcommand for TokenProgramAgnosticSubcommand {
|
||||
definition,
|
||||
holder,
|
||||
holder_npk,
|
||||
holder_ipk,
|
||||
holder_vpk,
|
||||
amount,
|
||||
} => {
|
||||
let underlying_subcommand = match (holder, holder_npk, holder_ipk) {
|
||||
let underlying_subcommand = match (holder, holder_npk, holder_vpk) {
|
||||
(None, None, None) => {
|
||||
anyhow::bail!(
|
||||
"Provide either account account_id of holder or their public keys"
|
||||
@ -363,7 +363,7 @@ impl WalletSubcommand for TokenProgramAgnosticSubcommand {
|
||||
}
|
||||
}
|
||||
}
|
||||
(None, Some(holder_npk), Some(holder_ipk)) => {
|
||||
(None, Some(holder_npk), Some(holder_vpk)) => {
|
||||
let (definition, definition_privacy) =
|
||||
parse_addr_with_privacy_prefix(&definition)?;
|
||||
|
||||
@ -372,7 +372,7 @@ impl WalletSubcommand for TokenProgramAgnosticSubcommand {
|
||||
TokenProgramSubcommandPrivate::MintTokenPrivateForeign {
|
||||
definition_account_id: definition,
|
||||
holder_npk,
|
||||
holder_ipk,
|
||||
holder_vpk,
|
||||
amount,
|
||||
},
|
||||
),
|
||||
@ -380,7 +380,7 @@ impl WalletSubcommand for TokenProgramAgnosticSubcommand {
|
||||
TokenProgramSubcommandShielded::MintTokenShieldedForeign {
|
||||
definition_account_id: definition,
|
||||
holder_npk,
|
||||
holder_ipk,
|
||||
holder_vpk,
|
||||
amount,
|
||||
},
|
||||
),
|
||||
@ -465,9 +465,9 @@ pub enum TokenProgramSubcommandPrivate {
|
||||
/// recipient_npk - valid 32 byte hex string
|
||||
#[arg(long)]
|
||||
recipient_npk: String,
|
||||
/// recipient_ipk - valid 33 byte hex string
|
||||
/// recipient_vpk - valid 33 byte hex string
|
||||
#[arg(long)]
|
||||
recipient_ipk: String,
|
||||
recipient_vpk: String,
|
||||
#[arg(short, long)]
|
||||
balance_to_move: u128,
|
||||
},
|
||||
@ -496,7 +496,7 @@ pub enum TokenProgramSubcommandPrivate {
|
||||
#[arg(short, long)]
|
||||
holder_npk: String,
|
||||
#[arg(short, long)]
|
||||
holder_ipk: String,
|
||||
holder_vpk: String,
|
||||
#[arg(short, long)]
|
||||
amount: u128,
|
||||
},
|
||||
@ -553,9 +553,9 @@ pub enum TokenProgramSubcommandShielded {
|
||||
/// recipient_npk - valid 32 byte hex string
|
||||
#[arg(long)]
|
||||
recipient_npk: String,
|
||||
/// recipient_ipk - valid 33 byte hex string
|
||||
/// recipient_vpk - valid 33 byte hex string
|
||||
#[arg(long)]
|
||||
recipient_ipk: String,
|
||||
recipient_vpk: String,
|
||||
#[arg(short, long)]
|
||||
balance_to_move: u128,
|
||||
},
|
||||
@ -584,7 +584,7 @@ pub enum TokenProgramSubcommandShielded {
|
||||
#[arg(short, long)]
|
||||
holder_npk: String,
|
||||
#[arg(short, long)]
|
||||
holder_ipk: String,
|
||||
holder_vpk: String,
|
||||
#[arg(short, long)]
|
||||
amount: u128,
|
||||
},
|
||||
@ -745,7 +745,7 @@ impl WalletSubcommand for TokenProgramSubcommandPrivate {
|
||||
TokenProgramSubcommandPrivate::TransferTokenPrivateForeign {
|
||||
sender_account_id,
|
||||
recipient_npk,
|
||||
recipient_ipk,
|
||||
recipient_vpk,
|
||||
balance_to_move,
|
||||
} => {
|
||||
let sender_account_id: AccountId = sender_account_id.parse().unwrap();
|
||||
@ -754,18 +754,18 @@ impl WalletSubcommand for TokenProgramSubcommandPrivate {
|
||||
recipient_npk.copy_from_slice(&recipient_npk_res);
|
||||
let recipient_npk = nssa_core::NullifierPublicKey(recipient_npk);
|
||||
|
||||
let recipient_ipk_res = hex::decode(recipient_ipk)?;
|
||||
let mut recipient_ipk = [0u8; 33];
|
||||
recipient_ipk.copy_from_slice(&recipient_ipk_res);
|
||||
let recipient_ipk = nssa_core::encryption::shared_key_derivation::Secp256k1Point(
|
||||
recipient_ipk.to_vec(),
|
||||
let recipient_vpk_res = hex::decode(recipient_vpk)?;
|
||||
let mut recipient_vpk = [0u8; 33];
|
||||
recipient_vpk.copy_from_slice(&recipient_vpk_res);
|
||||
let recipient_vpk = nssa_core::encryption::shared_key_derivation::Secp256k1Point(
|
||||
recipient_vpk.to_vec(),
|
||||
);
|
||||
|
||||
let (res, [secret_sender, _]) = Token(wallet_core)
|
||||
.send_transfer_transaction_private_foreign_account(
|
||||
sender_account_id,
|
||||
recipient_npk,
|
||||
recipient_ipk,
|
||||
recipient_vpk,
|
||||
balance_to_move,
|
||||
)
|
||||
.await?;
|
||||
@ -865,7 +865,7 @@ impl WalletSubcommand for TokenProgramSubcommandPrivate {
|
||||
TokenProgramSubcommandPrivate::MintTokenPrivateForeign {
|
||||
definition_account_id,
|
||||
holder_npk,
|
||||
holder_ipk,
|
||||
holder_vpk,
|
||||
amount,
|
||||
} => {
|
||||
let definition_account_id: AccountId = definition_account_id.parse().unwrap();
|
||||
@ -875,18 +875,18 @@ impl WalletSubcommand for TokenProgramSubcommandPrivate {
|
||||
holder_npk.copy_from_slice(&holder_npk_res);
|
||||
let holder_npk = nssa_core::NullifierPublicKey(holder_npk);
|
||||
|
||||
let holder_ipk_res = hex::decode(holder_ipk)?;
|
||||
let mut holder_ipk = [0u8; 33];
|
||||
holder_ipk.copy_from_slice(&holder_ipk_res);
|
||||
let holder_ipk = nssa_core::encryption::shared_key_derivation::Secp256k1Point(
|
||||
holder_ipk.to_vec(),
|
||||
let holder_vpk_res = hex::decode(holder_vpk)?;
|
||||
let mut holder_vpk = [0u8; 33];
|
||||
holder_vpk.copy_from_slice(&holder_vpk_res);
|
||||
let holder_vpk = nssa_core::encryption::shared_key_derivation::Secp256k1Point(
|
||||
holder_vpk.to_vec(),
|
||||
);
|
||||
|
||||
let (res, [secret_definition, _]) = Token(wallet_core)
|
||||
.send_mint_transaction_private_foreign_account(
|
||||
definition_account_id,
|
||||
holder_npk,
|
||||
holder_ipk,
|
||||
holder_vpk,
|
||||
amount,
|
||||
)
|
||||
.await?;
|
||||
@ -1034,7 +1034,7 @@ impl WalletSubcommand for TokenProgramSubcommandShielded {
|
||||
TokenProgramSubcommandShielded::TransferTokenShieldedForeign {
|
||||
sender_account_id,
|
||||
recipient_npk,
|
||||
recipient_ipk,
|
||||
recipient_vpk,
|
||||
balance_to_move,
|
||||
} => {
|
||||
let sender_account_id: AccountId = sender_account_id.parse().unwrap();
|
||||
@ -1043,18 +1043,18 @@ impl WalletSubcommand for TokenProgramSubcommandShielded {
|
||||
recipient_npk.copy_from_slice(&recipient_npk_res);
|
||||
let recipient_npk = nssa_core::NullifierPublicKey(recipient_npk);
|
||||
|
||||
let recipient_ipk_res = hex::decode(recipient_ipk)?;
|
||||
let mut recipient_ipk = [0u8; 33];
|
||||
recipient_ipk.copy_from_slice(&recipient_ipk_res);
|
||||
let recipient_ipk = nssa_core::encryption::shared_key_derivation::Secp256k1Point(
|
||||
recipient_ipk.to_vec(),
|
||||
let recipient_vpk_res = hex::decode(recipient_vpk)?;
|
||||
let mut recipient_vpk = [0u8; 33];
|
||||
recipient_vpk.copy_from_slice(&recipient_vpk_res);
|
||||
let recipient_vpk = nssa_core::encryption::shared_key_derivation::Secp256k1Point(
|
||||
recipient_vpk.to_vec(),
|
||||
);
|
||||
|
||||
let (res, _) = Token(wallet_core)
|
||||
.send_transfer_transaction_shielded_foreign_account(
|
||||
sender_account_id,
|
||||
recipient_npk,
|
||||
recipient_ipk,
|
||||
recipient_vpk,
|
||||
balance_to_move,
|
||||
)
|
||||
.await?;
|
||||
@ -1177,7 +1177,7 @@ impl WalletSubcommand for TokenProgramSubcommandShielded {
|
||||
TokenProgramSubcommandShielded::MintTokenShieldedForeign {
|
||||
definition_account_id,
|
||||
holder_npk,
|
||||
holder_ipk,
|
||||
holder_vpk,
|
||||
amount,
|
||||
} => {
|
||||
let definition_account_id: AccountId = definition_account_id.parse().unwrap();
|
||||
@ -1187,18 +1187,18 @@ impl WalletSubcommand for TokenProgramSubcommandShielded {
|
||||
holder_npk.copy_from_slice(&holder_npk_res);
|
||||
let holder_npk = nssa_core::NullifierPublicKey(holder_npk);
|
||||
|
||||
let holder_ipk_res = hex::decode(holder_ipk)?;
|
||||
let mut holder_ipk = [0u8; 33];
|
||||
holder_ipk.copy_from_slice(&holder_ipk_res);
|
||||
let holder_ipk = nssa_core::encryption::shared_key_derivation::Secp256k1Point(
|
||||
holder_ipk.to_vec(),
|
||||
let holder_vpk_res = hex::decode(holder_vpk)?;
|
||||
let mut holder_vpk = [0u8; 33];
|
||||
holder_vpk.copy_from_slice(&holder_vpk_res);
|
||||
let holder_vpk = nssa_core::encryption::shared_key_derivation::Secp256k1Point(
|
||||
holder_vpk.to_vec(),
|
||||
);
|
||||
|
||||
let (res, _) = Token(wallet_core)
|
||||
.send_mint_transaction_shielded_foreign_account(
|
||||
definition_account_id,
|
||||
holder_npk,
|
||||
holder_ipk,
|
||||
holder_vpk,
|
||||
amount,
|
||||
)
|
||||
.await?;
|
||||
|
||||
@ -292,7 +292,7 @@ impl Default for WalletConfig {
|
||||
},
|
||||
{
|
||||
"Private": {
|
||||
"account_id": "3oCG8gqdKLMegw4rRfyaMQvuPHpcASt7xwttsmnZLSkw",
|
||||
"account_id": "FpdcxBrMkHWqXCBQ6FG98eYfWGY6jWZRsKNSi1FwDMxy",
|
||||
"account": {
|
||||
"program_owner": [
|
||||
0,
|
||||
@ -310,218 +310,151 @@ impl Default for WalletConfig {
|
||||
},
|
||||
"key_chain": {
|
||||
"secret_spending_key": [
|
||||
251,
|
||||
82,
|
||||
235,
|
||||
1,
|
||||
146,
|
||||
96,
|
||||
30,
|
||||
81,
|
||||
162,
|
||||
234,
|
||||
239,
|
||||
27,
|
||||
159,
|
||||
83,
|
||||
199,
|
||||
194,
|
||||
132,
|
||||
33,
|
||||
15,
|
||||
123,
|
||||
129,
|
||||
116,
|
||||
0,
|
||||
20,
|
||||
28,
|
||||
217,
|
||||
103,
|
||||
101,
|
||||
57,
|
||||
27,
|
||||
125,
|
||||
84,
|
||||
136,
|
||||
176,
|
||||
70,
|
||||
190,
|
||||
224,
|
||||
57,
|
||||
19,
|
||||
86,
|
||||
98,
|
||||
135,
|
||||
161,
|
||||
54,
|
||||
134,
|
||||
142,
|
||||
154,
|
||||
1,
|
||||
18,
|
||||
251,
|
||||
242,
|
||||
189
|
||||
221,
|
||||
108,
|
||||
125,
|
||||
152,
|
||||
174,
|
||||
161,
|
||||
64,
|
||||
16,
|
||||
200
|
||||
],
|
||||
"private_key_holder": {
|
||||
"nullifier_secret_key": [
|
||||
29,
|
||||
250,
|
||||
10,
|
||||
187,
|
||||
35,
|
||||
123,
|
||||
180,
|
||||
250,
|
||||
246,
|
||||
97,
|
||||
216,
|
||||
153,
|
||||
44,
|
||||
156,
|
||||
71,
|
||||
195,
|
||||
16,
|
||||
93,
|
||||
241,
|
||||
26,
|
||||
174,
|
||||
219,
|
||||
72,
|
||||
84,
|
||||
34,
|
||||
247,
|
||||
112,
|
||||
101,
|
||||
217,
|
||||
243,
|
||||
189,
|
||||
173,
|
||||
75,
|
||||
20
|
||||
],
|
||||
"incoming_viewing_secret_key": [
|
||||
251,
|
||||
201,
|
||||
22,
|
||||
154,
|
||||
100,
|
||||
165,
|
||||
218,
|
||||
108,
|
||||
163,
|
||||
190,
|
||||
135,
|
||||
91,
|
||||
145,
|
||||
84,
|
||||
69,
|
||||
241,
|
||||
46,
|
||||
117,
|
||||
217,
|
||||
110,
|
||||
197,
|
||||
248,
|
||||
91,
|
||||
193,
|
||||
14,
|
||||
104,
|
||||
88,
|
||||
103,
|
||||
67,
|
||||
153,
|
||||
182,
|
||||
158
|
||||
],
|
||||
"outgoing_viewing_secret_key": [
|
||||
25,
|
||||
67,
|
||||
121,
|
||||
76,
|
||||
175,
|
||||
100,
|
||||
30,
|
||||
198,
|
||||
105,
|
||||
123,
|
||||
49,
|
||||
169,
|
||||
75,
|
||||
178,
|
||||
75,
|
||||
210,
|
||||
100,
|
||||
143,
|
||||
210,
|
||||
243,
|
||||
228,
|
||||
243,
|
||||
21,
|
||||
18,
|
||||
36,
|
||||
84,
|
||||
164,
|
||||
186,
|
||||
119,
|
||||
0,
|
||||
98,
|
||||
35,
|
||||
106,
|
||||
139,
|
||||
113,
|
||||
214,
|
||||
12
|
||||
82,
|
||||
145,
|
||||
50,
|
||||
27,
|
||||
140,
|
||||
206,
|
||||
19,
|
||||
53,
|
||||
122,
|
||||
166,
|
||||
76,
|
||||
195,
|
||||
0,
|
||||
16,
|
||||
19,
|
||||
21,
|
||||
143,
|
||||
155,
|
||||
119,
|
||||
9,
|
||||
200,
|
||||
81,
|
||||
105
|
||||
],
|
||||
"viewing_secret_key": [
|
||||
5,
|
||||
117,
|
||||
221,
|
||||
27,
|
||||
236,
|
||||
199,
|
||||
53,
|
||||
22,
|
||||
249,
|
||||
231,
|
||||
98,
|
||||
147,
|
||||
213,
|
||||
116,
|
||||
191,
|
||||
82,
|
||||
188,
|
||||
148,
|
||||
175,
|
||||
98,
|
||||
139,
|
||||
52,
|
||||
232,
|
||||
249,
|
||||
220,
|
||||
217,
|
||||
83,
|
||||
58,
|
||||
112,
|
||||
155,
|
||||
197,
|
||||
196
|
||||
]
|
||||
},
|
||||
"nullifer_public_key": [
|
||||
63,
|
||||
202,
|
||||
178,
|
||||
231,
|
||||
183,
|
||||
82,
|
||||
237,
|
||||
212,
|
||||
216,
|
||||
221,
|
||||
215,
|
||||
255,
|
||||
153,
|
||||
101,
|
||||
177,
|
||||
161,
|
||||
254,
|
||||
210,
|
||||
128,
|
||||
122,
|
||||
54,
|
||||
190,
|
||||
230,
|
||||
151,
|
||||
183,
|
||||
64,
|
||||
225,
|
||||
229,
|
||||
113,
|
||||
1,
|
||||
228,
|
||||
97
|
||||
],
|
||||
"incoming_viewing_public_key": [
|
||||
3,
|
||||
235,
|
||||
139,
|
||||
131,
|
||||
237,
|
||||
177,
|
||||
122,
|
||||
189,
|
||||
6,
|
||||
177,
|
||||
167,
|
||||
178,
|
||||
202,
|
||||
117,
|
||||
246,
|
||||
58,
|
||||
28,
|
||||
65,
|
||||
132,
|
||||
79,
|
||||
220,
|
||||
139,
|
||||
119,
|
||||
11,
|
||||
87,
|
||||
38,
|
||||
254,
|
||||
159,
|
||||
231,
|
||||
165,
|
||||
1,
|
||||
94,
|
||||
64,
|
||||
137,
|
||||
243,
|
||||
187,
|
||||
160,
|
||||
212,
|
||||
121,
|
||||
61,
|
||||
247,
|
||||
116,
|
||||
72,
|
||||
205
|
||||
]
|
||||
76,
|
||||
249,
|
||||
101,
|
||||
251,
|
||||
129,
|
||||
33,
|
||||
101,
|
||||
189,
|
||||
30,
|
||||
42,
|
||||
11,
|
||||
191,
|
||||
34,
|
||||
103,
|
||||
186,
|
||||
227,
|
||||
230
|
||||
],
|
||||
"viewing_public_key": [
|
||||
2, 69, 126, 43, 158, 209, 172, 144, 23, 185, 208, 25, 163, 166, 176, 200, 225, 251, 106, 211, 4, 199, 112, 243, 207, 144, 135, 56, 157, 167, 32, 219, 38]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"Private": {
|
||||
"account_id": "AKTcXgJ1xoynta1Ec7y6Jso1z1JQtHqd7aPQ1h9er6xX",
|
||||
"account_id": "E8HwiTyQe4H9HK7icTvn95HQMnzx49mP9A2ddtMLpNaN",
|
||||
"account": {
|
||||
"program_owner": [
|
||||
0,
|
||||
@ -539,211 +472,20 @@ impl Default for WalletConfig {
|
||||
},
|
||||
"key_chain": {
|
||||
"secret_spending_key": [
|
||||
238,
|
||||
171,
|
||||
241,
|
||||
69,
|
||||
111,
|
||||
217,
|
||||
85,
|
||||
64,
|
||||
19,
|
||||
82,
|
||||
18,
|
||||
189,
|
||||
32,
|
||||
91,
|
||||
78,
|
||||
175,
|
||||
107,
|
||||
7,
|
||||
109,
|
||||
60,
|
||||
52,
|
||||
44,
|
||||
243,
|
||||
230,
|
||||
72,
|
||||
244,
|
||||
192,
|
||||
92,
|
||||
137,
|
||||
33,
|
||||
118,
|
||||
254
|
||||
],
|
||||
48, 175, 124, 10, 230, 240, 166, 14, 249, 254, 157, 226, 208, 124, 122, 177, 203, 139, 192, 180, 43, 120, 55, 151, 50, 21, 113, 22, 254, 83, 148, 56],
|
||||
"private_key_holder": {
|
||||
"nullifier_secret_key": [
|
||||
25,
|
||||
211,
|
||||
215,
|
||||
119,
|
||||
57,
|
||||
223,
|
||||
247,
|
||||
37,
|
||||
245,
|
||||
144,
|
||||
122,
|
||||
29,
|
||||
118,
|
||||
245,
|
||||
83,
|
||||
228,
|
||||
23,
|
||||
9,
|
||||
101,
|
||||
120,
|
||||
88,
|
||||
33,
|
||||
238,
|
||||
207,
|
||||
128,
|
||||
61,
|
||||
110,
|
||||
2,
|
||||
89,
|
||||
62,
|
||||
164,
|
||||
13
|
||||
99, 82, 190, 140, 234, 10, 61, 163, 15, 211, 179, 54, 70, 166, 87, 5, 182, 68, 117, 244, 217, 23, 99, 9, 4, 177, 230, 125, 109, 91, 160, 30
|
||||
],
|
||||
"incoming_viewing_secret_key": [
|
||||
193,
|
||||
181,
|
||||
14,
|
||||
196,
|
||||
142,
|
||||
84,
|
||||
15,
|
||||
65,
|
||||
128,
|
||||
101,
|
||||
70,
|
||||
196,
|
||||
241,
|
||||
47,
|
||||
130,
|
||||
221,
|
||||
23,
|
||||
146,
|
||||
161,
|
||||
237,
|
||||
221,
|
||||
40,
|
||||
19,
|
||||
126,
|
||||
59,
|
||||
15,
|
||||
169,
|
||||
236,
|
||||
25,
|
||||
105,
|
||||
104,
|
||||
231
|
||||
],
|
||||
"outgoing_viewing_secret_key": [
|
||||
20,
|
||||
170,
|
||||
220,
|
||||
108,
|
||||
41,
|
||||
23,
|
||||
155,
|
||||
217,
|
||||
247,
|
||||
190,
|
||||
175,
|
||||
168,
|
||||
247,
|
||||
34,
|
||||
105,
|
||||
134,
|
||||
114,
|
||||
74,
|
||||
104,
|
||||
91,
|
||||
211,
|
||||
62,
|
||||
126,
|
||||
13,
|
||||
130,
|
||||
100,
|
||||
241,
|
||||
214,
|
||||
250,
|
||||
236,
|
||||
38,
|
||||
150
|
||||
"viewing_secret_key": [
|
||||
205, 32, 76, 251, 255, 236, 96, 119, 61, 111, 65, 100, 75, 218, 12, 22, 17, 170, 55, 226, 21, 154, 161, 34, 208, 74, 27, 1, 119, 13, 88, 128
|
||||
]
|
||||
},
|
||||
"nullifer_public_key": [
|
||||
192,
|
||||
251,
|
||||
166,
|
||||
243,
|
||||
167,
|
||||
236,
|
||||
84,
|
||||
249,
|
||||
35,
|
||||
136,
|
||||
130,
|
||||
172,
|
||||
219,
|
||||
225,
|
||||
161,
|
||||
139,
|
||||
229,
|
||||
89,
|
||||
243,
|
||||
125,
|
||||
194,
|
||||
213,
|
||||
209,
|
||||
30,
|
||||
23,
|
||||
174,
|
||||
100,
|
||||
244,
|
||||
124,
|
||||
74,
|
||||
140,
|
||||
47
|
||||
32, 67, 72, 164, 106, 53, 66, 239, 141, 15, 52, 230, 136, 177, 2, 236, 207, 243, 134, 135, 210, 143, 87, 232, 215, 128, 194, 120, 113, 224, 4, 165
|
||||
],
|
||||
"incoming_viewing_public_key": [
|
||||
2,
|
||||
181,
|
||||
98,
|
||||
93,
|
||||
216,
|
||||
241,
|
||||
241,
|
||||
110,
|
||||
58,
|
||||
198,
|
||||
119,
|
||||
174,
|
||||
250,
|
||||
184,
|
||||
1,
|
||||
204,
|
||||
200,
|
||||
173,
|
||||
44,
|
||||
238,
|
||||
37,
|
||||
247,
|
||||
170,
|
||||
156,
|
||||
100,
|
||||
254,
|
||||
116,
|
||||
242,
|
||||
28,
|
||||
183,
|
||||
187,
|
||||
77,
|
||||
255
|
||||
"viewing_public_key": [
|
||||
2, 79, 110, 46, 203, 29, 206, 205, 18, 86, 27, 189, 104, 103, 113, 181, 110, 53, 78, 172, 11, 171, 190, 18, 126, 214, 81, 77, 192, 154, 58, 195, 238
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@ -345,7 +345,7 @@ impl WalletCore {
|
||||
Vec::from_iter(acc_manager.public_account_nonces()),
|
||||
private_account_keys
|
||||
.iter()
|
||||
.map(|keys| (keys.npk.clone(), keys.ipk.clone(), keys.epk.clone()))
|
||||
.map(|keys| (keys.npk.clone(), keys.vpk.clone(), keys.epk.clone()))
|
||||
.collect(),
|
||||
output,
|
||||
)
|
||||
@ -429,7 +429,7 @@ impl WalletCore {
|
||||
.flat_map(|(acc_account_id, key_chain)| {
|
||||
let view_tag = EncryptedAccountData::compute_view_tag(
|
||||
key_chain.nullifer_public_key.clone(),
|
||||
key_chain.incoming_viewing_public_key.clone(),
|
||||
key_chain.viewing_public_key.clone(),
|
||||
);
|
||||
|
||||
tx.message()
|
||||
|
||||
@ -36,7 +36,7 @@ impl WalletCore {
|
||||
let AccountPreparedData {
|
||||
nsk: winner_nsk,
|
||||
npk: winner_npk,
|
||||
ipk: winner_ipk,
|
||||
vpk: winner_vpk,
|
||||
auth_acc: winner_pre,
|
||||
proof: _,
|
||||
} = self
|
||||
@ -50,7 +50,7 @@ impl WalletCore {
|
||||
let pinata_pre = AccountWithMetadata::new(pinata_acc.clone(), false, pinata_account_id);
|
||||
|
||||
let eph_holder_winner = EphemeralKeyHolder::new(&winner_npk);
|
||||
let shared_secret_winner = eph_holder_winner.calculate_shared_secret_sender(&winner_ipk);
|
||||
let shared_secret_winner = eph_holder_winner.calculate_shared_secret_sender(&winner_vpk);
|
||||
|
||||
let (output, proof) = circuit::execute_and_prove(
|
||||
&[pinata_pre, winner_pre],
|
||||
@ -70,7 +70,7 @@ impl WalletCore {
|
||||
vec![],
|
||||
vec![(
|
||||
winner_npk.clone(),
|
||||
winner_ipk.clone(),
|
||||
winner_vpk.clone(),
|
||||
eph_holder_winner.generate_ephemeral_public_key(),
|
||||
)],
|
||||
output,
|
||||
@ -103,7 +103,7 @@ impl WalletCore {
|
||||
let AccountPreparedData {
|
||||
nsk: _,
|
||||
npk: winner_npk,
|
||||
ipk: winner_ipk,
|
||||
vpk: winner_vpk,
|
||||
auth_acc: winner_pre,
|
||||
proof: _,
|
||||
} = self
|
||||
@ -117,7 +117,7 @@ impl WalletCore {
|
||||
let pinata_pre = AccountWithMetadata::new(pinata_acc.clone(), false, pinata_account_id);
|
||||
|
||||
let eph_holder_winner = EphemeralKeyHolder::new(&winner_npk);
|
||||
let shared_secret_winner = eph_holder_winner.calculate_shared_secret_sender(&winner_ipk);
|
||||
let shared_secret_winner = eph_holder_winner.calculate_shared_secret_sender(&winner_vpk);
|
||||
|
||||
let (output, proof) = circuit::execute_and_prove(
|
||||
&[pinata_pre, winner_pre],
|
||||
@ -137,7 +137,7 @@ impl WalletCore {
|
||||
vec![],
|
||||
vec![(
|
||||
winner_npk.clone(),
|
||||
winner_ipk.clone(),
|
||||
winner_vpk.clone(),
|
||||
eph_holder_winner.generate_ephemeral_public_key(),
|
||||
)],
|
||||
output,
|
||||
|
||||
@ -5,7 +5,7 @@ use nssa::{AccountId, PrivateKey};
|
||||
use nssa_core::{
|
||||
MembershipProof, NullifierPublicKey, NullifierSecretKey, SharedSecretKey,
|
||||
account::{AccountWithMetadata, Nonce},
|
||||
encryption::{EphemeralPublicKey, IncomingViewingPublicKey},
|
||||
encryption::{EphemeralPublicKey, ViewingPublicKey},
|
||||
};
|
||||
|
||||
use crate::WalletCore;
|
||||
@ -16,7 +16,7 @@ pub enum PrivacyPreservingAccount {
|
||||
PrivateOwned(AccountId),
|
||||
PrivateForeign {
|
||||
npk: NullifierPublicKey,
|
||||
ipk: IncomingViewingPublicKey,
|
||||
vpk: ViewingPublicKey,
|
||||
},
|
||||
}
|
||||
|
||||
@ -28,7 +28,7 @@ impl PrivacyPreservingAccount {
|
||||
pub fn is_private(&self) -> bool {
|
||||
matches!(
|
||||
&self,
|
||||
Self::PrivateOwned(_) | Self::PrivateForeign { npk: _, ipk: _ }
|
||||
Self::PrivateOwned(_) | Self::PrivateForeign { npk: _, vpk: _ }
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -36,7 +36,7 @@ impl PrivacyPreservingAccount {
|
||||
pub struct PrivateAccountKeys {
|
||||
pub npk: NullifierPublicKey,
|
||||
pub ssk: SharedSecretKey,
|
||||
pub ipk: IncomingViewingPublicKey,
|
||||
pub vpk: ViewingPublicKey,
|
||||
pub epk: EphemeralPublicKey,
|
||||
}
|
||||
|
||||
@ -80,13 +80,13 @@ impl AccountManager {
|
||||
|
||||
(State::Private(pre), mask)
|
||||
}
|
||||
PrivacyPreservingAccount::PrivateForeign { npk, ipk } => {
|
||||
PrivacyPreservingAccount::PrivateForeign { npk, vpk } => {
|
||||
let acc = nssa_core::account::Account::default();
|
||||
let auth_acc = AccountWithMetadata::new(acc, false, &npk);
|
||||
let pre = AccountPreparedData {
|
||||
nsk: None,
|
||||
npk,
|
||||
ipk,
|
||||
vpk,
|
||||
pre_state: auth_acc,
|
||||
proof: None,
|
||||
};
|
||||
@ -138,8 +138,8 @@ impl AccountManager {
|
||||
|
||||
Some(PrivateAccountKeys {
|
||||
npk: pre.npk.clone(),
|
||||
ssk: eph_holder.calculate_shared_secret_sender(&pre.ipk),
|
||||
ipk: pre.ipk.clone(),
|
||||
ssk: eph_holder.calculate_shared_secret_sender(&pre.vpk),
|
||||
vpk: pre.vpk.clone(),
|
||||
epk: eph_holder.generate_ephemeral_public_key(),
|
||||
})
|
||||
}
|
||||
@ -192,7 +192,7 @@ impl AccountManager {
|
||||
struct AccountPreparedData {
|
||||
nsk: Option<NullifierSecretKey>,
|
||||
npk: NullifierPublicKey,
|
||||
ipk: IncomingViewingPublicKey,
|
||||
vpk: ViewingPublicKey,
|
||||
pre_state: AccountWithMetadata,
|
||||
proof: Option<MembershipProof>,
|
||||
}
|
||||
@ -213,7 +213,7 @@ async fn private_acc_preparation(
|
||||
let nsk = from_keys.private_key_holder.nullifier_secret_key;
|
||||
|
||||
let from_npk = from_keys.nullifer_public_key;
|
||||
let from_ipk = from_keys.incoming_viewing_public_key;
|
||||
let from_vpk = from_keys.viewing_public_key;
|
||||
|
||||
// TODO: Remove this unwrap, error types must be compatible
|
||||
let proof = wallet
|
||||
@ -228,7 +228,7 @@ async fn private_acc_preparation(
|
||||
Ok(AccountPreparedData {
|
||||
nsk: Some(nsk),
|
||||
npk: from_npk,
|
||||
ipk: from_ipk,
|
||||
vpk: from_vpk,
|
||||
pre_state: sender_pre,
|
||||
proof,
|
||||
})
|
||||
|
||||
@ -2,7 +2,7 @@ use std::vec;
|
||||
|
||||
use common::{error::ExecutionFailureKind, rpc_primitives::requests::SendTxResponse};
|
||||
use nssa::{AccountId, program::Program};
|
||||
use nssa_core::{NullifierPublicKey, SharedSecretKey, encryption::IncomingViewingPublicKey};
|
||||
use nssa_core::{NullifierPublicKey, SharedSecretKey, encryption::ViewingPublicKey};
|
||||
|
||||
use super::{NativeTokenTransfer, auth_transfer_preparation};
|
||||
use crate::PrivacyPreservingAccount;
|
||||
@ -32,7 +32,7 @@ impl NativeTokenTransfer<'_> {
|
||||
&self,
|
||||
from: AccountId,
|
||||
to_npk: NullifierPublicKey,
|
||||
to_ipk: IncomingViewingPublicKey,
|
||||
to_vpk: ViewingPublicKey,
|
||||
balance_to_move: u128,
|
||||
) -> Result<(SendTxResponse, [SharedSecretKey; 2]), ExecutionFailureKind> {
|
||||
let (instruction_data, program, tx_pre_check) = auth_transfer_preparation(balance_to_move);
|
||||
@ -43,7 +43,7 @@ impl NativeTokenTransfer<'_> {
|
||||
PrivacyPreservingAccount::PrivateOwned(from),
|
||||
PrivacyPreservingAccount::PrivateForeign {
|
||||
npk: to_npk,
|
||||
ipk: to_ipk,
|
||||
vpk: to_vpk,
|
||||
},
|
||||
],
|
||||
instruction_data,
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
use common::{error::ExecutionFailureKind, rpc_primitives::requests::SendTxResponse};
|
||||
use nssa::AccountId;
|
||||
use nssa_core::{NullifierPublicKey, SharedSecretKey, encryption::IncomingViewingPublicKey};
|
||||
use nssa_core::{NullifierPublicKey, SharedSecretKey, encryption::ViewingPublicKey};
|
||||
|
||||
use super::{NativeTokenTransfer, auth_transfer_preparation};
|
||||
use crate::PrivacyPreservingAccount;
|
||||
@ -38,7 +38,7 @@ impl NativeTokenTransfer<'_> {
|
||||
&self,
|
||||
from: AccountId,
|
||||
to_npk: NullifierPublicKey,
|
||||
to_ipk: IncomingViewingPublicKey,
|
||||
to_vpk: ViewingPublicKey,
|
||||
balance_to_move: u128,
|
||||
) -> Result<(SendTxResponse, SharedSecretKey), ExecutionFailureKind> {
|
||||
let (instruction_data, program, tx_pre_check) = auth_transfer_preparation(balance_to_move);
|
||||
@ -49,7 +49,7 @@ impl NativeTokenTransfer<'_> {
|
||||
PrivacyPreservingAccount::Public(from),
|
||||
PrivacyPreservingAccount::PrivateForeign {
|
||||
npk: to_npk,
|
||||
ipk: to_ipk,
|
||||
vpk: to_vpk,
|
||||
},
|
||||
],
|
||||
instruction_data,
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
use common::{error::ExecutionFailureKind, rpc_primitives::requests::SendTxResponse};
|
||||
use nssa::{AccountId, program::Program};
|
||||
use nssa_core::{NullifierPublicKey, SharedSecretKey, encryption::IncomingViewingPublicKey};
|
||||
use nssa_core::{NullifierPublicKey, SharedSecretKey, encryption::ViewingPublicKey};
|
||||
use token_core::Instruction;
|
||||
|
||||
use crate::{PrivacyPreservingAccount, WalletCore};
|
||||
@ -194,7 +194,7 @@ impl Token<'_> {
|
||||
&self,
|
||||
sender_account_id: AccountId,
|
||||
recipient_npk: NullifierPublicKey,
|
||||
recipient_ipk: IncomingViewingPublicKey,
|
||||
recipient_vpk: ViewingPublicKey,
|
||||
amount: u128,
|
||||
) -> Result<(SendTxResponse, [SharedSecretKey; 2]), ExecutionFailureKind> {
|
||||
let instruction = Instruction::Transfer {
|
||||
@ -209,7 +209,7 @@ impl Token<'_> {
|
||||
PrivacyPreservingAccount::PrivateOwned(sender_account_id),
|
||||
PrivacyPreservingAccount::PrivateForeign {
|
||||
npk: recipient_npk,
|
||||
ipk: recipient_ipk,
|
||||
vpk: recipient_vpk,
|
||||
},
|
||||
],
|
||||
instruction_data,
|
||||
@ -290,7 +290,7 @@ impl Token<'_> {
|
||||
&self,
|
||||
sender_account_id: AccountId,
|
||||
recipient_npk: NullifierPublicKey,
|
||||
recipient_ipk: IncomingViewingPublicKey,
|
||||
recipient_vpk: ViewingPublicKey,
|
||||
amount: u128,
|
||||
) -> Result<(SendTxResponse, SharedSecretKey), ExecutionFailureKind> {
|
||||
let instruction = Instruction::Transfer {
|
||||
@ -305,7 +305,7 @@ impl Token<'_> {
|
||||
PrivacyPreservingAccount::Public(sender_account_id),
|
||||
PrivacyPreservingAccount::PrivateForeign {
|
||||
npk: recipient_npk,
|
||||
ipk: recipient_ipk,
|
||||
vpk: recipient_vpk,
|
||||
},
|
||||
],
|
||||
instruction_data,
|
||||
@ -525,7 +525,7 @@ impl Token<'_> {
|
||||
&self,
|
||||
definition_account_id: AccountId,
|
||||
holder_npk: NullifierPublicKey,
|
||||
holder_ipk: IncomingViewingPublicKey,
|
||||
holder_vpk: ViewingPublicKey,
|
||||
amount: u128,
|
||||
) -> Result<(SendTxResponse, [SharedSecretKey; 2]), ExecutionFailureKind> {
|
||||
let instruction = Instruction::Mint {
|
||||
@ -540,7 +540,7 @@ impl Token<'_> {
|
||||
PrivacyPreservingAccount::PrivateOwned(definition_account_id),
|
||||
PrivacyPreservingAccount::PrivateForeign {
|
||||
npk: holder_npk,
|
||||
ipk: holder_ipk,
|
||||
vpk: holder_vpk,
|
||||
},
|
||||
],
|
||||
instruction_data,
|
||||
@ -621,7 +621,7 @@ impl Token<'_> {
|
||||
&self,
|
||||
definition_account_id: AccountId,
|
||||
holder_npk: NullifierPublicKey,
|
||||
holder_ipk: IncomingViewingPublicKey,
|
||||
holder_vpk: ViewingPublicKey,
|
||||
amount: u128,
|
||||
) -> Result<(SendTxResponse, SharedSecretKey), ExecutionFailureKind> {
|
||||
let instruction = Instruction::Mint {
|
||||
@ -636,7 +636,7 @@ impl Token<'_> {
|
||||
PrivacyPreservingAccount::Public(definition_account_id),
|
||||
PrivacyPreservingAccount::PrivateForeign {
|
||||
npk: holder_npk,
|
||||
ipk: holder_ipk,
|
||||
vpk: holder_vpk,
|
||||
},
|
||||
],
|
||||
instruction_data,
|
||||
|
||||
@ -7,7 +7,7 @@ use nssa::{
|
||||
};
|
||||
use nssa_core::{
|
||||
Commitment, MembershipProof, NullifierPublicKey, NullifierSecretKey, SharedSecretKey,
|
||||
account::AccountWithMetadata, encryption::IncomingViewingPublicKey, program::InstructionData,
|
||||
account::AccountWithMetadata, encryption::ViewingPublicKey, program::InstructionData,
|
||||
};
|
||||
|
||||
use crate::{WalletCore, helperfunctions::produce_random_nonces};
|
||||
@ -15,7 +15,7 @@ use crate::{WalletCore, helperfunctions::produce_random_nonces};
|
||||
pub(crate) struct AccountPreparedData {
|
||||
pub nsk: Option<NullifierSecretKey>,
|
||||
pub npk: NullifierPublicKey,
|
||||
pub ipk: IncomingViewingPublicKey,
|
||||
pub vpk: ViewingPublicKey,
|
||||
pub auth_acc: AccountWithMetadata,
|
||||
pub proof: Option<MembershipProof>,
|
||||
}
|
||||
@ -40,7 +40,7 @@ impl WalletCore {
|
||||
let mut proof = None;
|
||||
|
||||
let from_npk = from_keys.nullifer_public_key;
|
||||
let from_ipk = from_keys.incoming_viewing_public_key;
|
||||
let from_vpk = from_keys.viewing_public_key;
|
||||
|
||||
let sender_commitment = Commitment::new(&from_npk, &from_acc);
|
||||
|
||||
@ -61,7 +61,7 @@ impl WalletCore {
|
||||
Ok(AccountPreparedData {
|
||||
nsk,
|
||||
npk: from_npk,
|
||||
ipk: from_ipk,
|
||||
vpk: from_vpk,
|
||||
auth_acc: sender_pre,
|
||||
proof,
|
||||
})
|
||||
@ -79,7 +79,7 @@ impl WalletCore {
|
||||
let AccountPreparedData {
|
||||
nsk: from_nsk,
|
||||
npk: from_npk,
|
||||
ipk: from_ipk,
|
||||
vpk: from_vpk,
|
||||
auth_acc: sender_pre,
|
||||
proof: from_proof,
|
||||
} = self.private_acc_preparation(from, true, true).await?;
|
||||
@ -87,7 +87,7 @@ impl WalletCore {
|
||||
let AccountPreparedData {
|
||||
nsk: to_nsk,
|
||||
npk: to_npk,
|
||||
ipk: to_ipk,
|
||||
vpk: to_vpk,
|
||||
auth_acc: recipient_pre,
|
||||
proof: _,
|
||||
} = self.private_acc_preparation(to, true, false).await?;
|
||||
@ -95,10 +95,10 @@ impl WalletCore {
|
||||
tx_pre_check(&sender_pre.account, &recipient_pre.account)?;
|
||||
|
||||
let eph_holder_from = EphemeralKeyHolder::new(&from_npk);
|
||||
let shared_secret_from = eph_holder_from.calculate_shared_secret_sender(&from_ipk);
|
||||
let shared_secret_from = eph_holder_from.calculate_shared_secret_sender(&from_vpk);
|
||||
|
||||
let eph_holder_to = EphemeralKeyHolder::new(&to_npk);
|
||||
let shared_secret_to = eph_holder_to.calculate_shared_secret_sender(&to_ipk);
|
||||
let shared_secret_to = eph_holder_to.calculate_shared_secret_sender(&to_vpk);
|
||||
|
||||
let (output, proof) = circuit::execute_and_prove(
|
||||
&[sender_pre, recipient_pre],
|
||||
@ -123,12 +123,12 @@ impl WalletCore {
|
||||
vec![
|
||||
(
|
||||
from_npk.clone(),
|
||||
from_ipk.clone(),
|
||||
from_vpk.clone(),
|
||||
eph_holder_from.generate_ephemeral_public_key(),
|
||||
),
|
||||
(
|
||||
to_npk.clone(),
|
||||
to_ipk.clone(),
|
||||
to_vpk.clone(),
|
||||
eph_holder_to.generate_ephemeral_public_key(),
|
||||
),
|
||||
],
|
||||
@ -156,7 +156,7 @@ impl WalletCore {
|
||||
let AccountPreparedData {
|
||||
nsk: from_nsk,
|
||||
npk: from_npk,
|
||||
ipk: from_ipk,
|
||||
vpk: from_vpk,
|
||||
auth_acc: sender_pre,
|
||||
proof: from_proof,
|
||||
} = self.private_acc_preparation(from, true, true).await?;
|
||||
@ -164,7 +164,7 @@ impl WalletCore {
|
||||
let AccountPreparedData {
|
||||
nsk: _,
|
||||
npk: to_npk,
|
||||
ipk: to_ipk,
|
||||
vpk: to_vpk,
|
||||
auth_acc: recipient_pre,
|
||||
proof: _,
|
||||
} = self.private_acc_preparation(to, false, false).await?;
|
||||
@ -172,10 +172,10 @@ impl WalletCore {
|
||||
tx_pre_check(&sender_pre.account, &recipient_pre.account)?;
|
||||
|
||||
let eph_holder_from = EphemeralKeyHolder::new(&from_npk);
|
||||
let shared_secret_from = eph_holder_from.calculate_shared_secret_sender(&from_ipk);
|
||||
let shared_secret_from = eph_holder_from.calculate_shared_secret_sender(&from_vpk);
|
||||
|
||||
let eph_holder_to = EphemeralKeyHolder::new(&to_npk);
|
||||
let shared_secret_to = eph_holder_to.calculate_shared_secret_sender(&to_ipk);
|
||||
let shared_secret_to = eph_holder_to.calculate_shared_secret_sender(&to_vpk);
|
||||
|
||||
let (output, proof) = circuit::execute_and_prove(
|
||||
&[sender_pre, recipient_pre],
|
||||
@ -197,12 +197,12 @@ impl WalletCore {
|
||||
vec![
|
||||
(
|
||||
from_npk.clone(),
|
||||
from_ipk.clone(),
|
||||
from_vpk.clone(),
|
||||
eph_holder_from.generate_ephemeral_public_key(),
|
||||
),
|
||||
(
|
||||
to_npk.clone(),
|
||||
to_ipk.clone(),
|
||||
to_vpk.clone(),
|
||||
eph_holder_to.generate_ephemeral_public_key(),
|
||||
),
|
||||
],
|
||||
@ -223,7 +223,7 @@ impl WalletCore {
|
||||
&self,
|
||||
from: AccountId,
|
||||
to_npk: NullifierPublicKey,
|
||||
to_ipk: IncomingViewingPublicKey,
|
||||
to_vpk: ViewingPublicKey,
|
||||
instruction_data: InstructionData,
|
||||
tx_pre_check: impl FnOnce(&Account, &Account) -> Result<(), ExecutionFailureKind>,
|
||||
program: Program,
|
||||
@ -231,7 +231,7 @@ impl WalletCore {
|
||||
let AccountPreparedData {
|
||||
nsk: from_nsk,
|
||||
npk: from_npk,
|
||||
ipk: from_ipk,
|
||||
vpk: from_vpk,
|
||||
auth_acc: sender_pre,
|
||||
proof: from_proof,
|
||||
} = self.private_acc_preparation(from, true, true).await?;
|
||||
@ -244,8 +244,8 @@ impl WalletCore {
|
||||
|
||||
let eph_holder = EphemeralKeyHolder::new(&to_npk);
|
||||
|
||||
let shared_secret_from = eph_holder.calculate_shared_secret_sender(&from_ipk);
|
||||
let shared_secret_to = eph_holder.calculate_shared_secret_sender(&to_ipk);
|
||||
let shared_secret_from = eph_holder.calculate_shared_secret_sender(&from_vpk);
|
||||
let shared_secret_to = eph_holder.calculate_shared_secret_sender(&to_vpk);
|
||||
|
||||
let (output, proof) = circuit::execute_and_prove(
|
||||
&[sender_pre, recipient_pre],
|
||||
@ -267,12 +267,12 @@ impl WalletCore {
|
||||
vec![
|
||||
(
|
||||
from_npk.clone(),
|
||||
from_ipk.clone(),
|
||||
from_vpk.clone(),
|
||||
eph_holder.generate_ephemeral_public_key(),
|
||||
),
|
||||
(
|
||||
to_npk.clone(),
|
||||
to_ipk.clone(),
|
||||
to_vpk.clone(),
|
||||
eph_holder.generate_ephemeral_public_key(),
|
||||
),
|
||||
],
|
||||
@ -301,7 +301,7 @@ impl WalletCore {
|
||||
let AccountPreparedData {
|
||||
nsk: from_nsk,
|
||||
npk: from_npk,
|
||||
ipk: from_ipk,
|
||||
vpk: from_vpk,
|
||||
auth_acc: sender_pre,
|
||||
proof: from_proof,
|
||||
} = self.private_acc_preparation(from, true, true).await?;
|
||||
@ -315,7 +315,7 @@ impl WalletCore {
|
||||
let recipient_pre = AccountWithMetadata::new(to_acc.clone(), false, to);
|
||||
|
||||
let eph_holder = EphemeralKeyHolder::new(&from_npk);
|
||||
let shared_secret = eph_holder.calculate_shared_secret_sender(&from_ipk);
|
||||
let shared_secret = eph_holder.calculate_shared_secret_sender(&from_vpk);
|
||||
|
||||
let (output, proof) = circuit::execute_and_prove(
|
||||
&[sender_pre, recipient_pre],
|
||||
@ -333,7 +333,7 @@ impl WalletCore {
|
||||
vec![],
|
||||
vec![(
|
||||
from_npk.clone(),
|
||||
from_ipk.clone(),
|
||||
from_vpk.clone(),
|
||||
eph_holder.generate_ephemeral_public_key(),
|
||||
)],
|
||||
output,
|
||||
@ -366,7 +366,7 @@ impl WalletCore {
|
||||
let AccountPreparedData {
|
||||
nsk: to_nsk,
|
||||
npk: to_npk,
|
||||
ipk: to_ipk,
|
||||
vpk: to_vpk,
|
||||
auth_acc: recipient_pre,
|
||||
proof: _,
|
||||
} = self.private_acc_preparation(to, true, false).await?;
|
||||
@ -376,7 +376,7 @@ impl WalletCore {
|
||||
let sender_pre = AccountWithMetadata::new(from_acc.clone(), true, from);
|
||||
|
||||
let eph_holder = EphemeralKeyHolder::new(&to_npk);
|
||||
let shared_secret = eph_holder.calculate_shared_secret_sender(&to_ipk);
|
||||
let shared_secret = eph_holder.calculate_shared_secret_sender(&to_vpk);
|
||||
|
||||
let (output, proof) = circuit::execute_and_prove(
|
||||
&[sender_pre, recipient_pre],
|
||||
@ -394,7 +394,7 @@ impl WalletCore {
|
||||
vec![from_acc.nonce],
|
||||
vec![(
|
||||
to_npk.clone(),
|
||||
to_ipk.clone(),
|
||||
to_vpk.clone(),
|
||||
eph_holder.generate_ephemeral_public_key(),
|
||||
)],
|
||||
output,
|
||||
@ -432,7 +432,7 @@ impl WalletCore {
|
||||
let AccountPreparedData {
|
||||
nsk: _,
|
||||
npk: to_npk,
|
||||
ipk: to_ipk,
|
||||
vpk: to_vpk,
|
||||
auth_acc: recipient_pre,
|
||||
proof: _,
|
||||
} = self.private_acc_preparation(to, false, false).await?;
|
||||
@ -442,7 +442,7 @@ impl WalletCore {
|
||||
let sender_pre = AccountWithMetadata::new(from_acc.clone(), true, from);
|
||||
|
||||
let eph_holder = EphemeralKeyHolder::new(&to_npk);
|
||||
let shared_secret = eph_holder.calculate_shared_secret_sender(&to_ipk);
|
||||
let shared_secret = eph_holder.calculate_shared_secret_sender(&to_vpk);
|
||||
|
||||
let (output, proof) = circuit::execute_and_prove(
|
||||
&[sender_pre, recipient_pre],
|
||||
@ -460,7 +460,7 @@ impl WalletCore {
|
||||
vec![from_acc.nonce],
|
||||
vec![(
|
||||
to_npk.clone(),
|
||||
to_ipk.clone(),
|
||||
to_vpk.clone(),
|
||||
eph_holder.generate_ephemeral_public_key(),
|
||||
)],
|
||||
output,
|
||||
@ -487,7 +487,7 @@ impl WalletCore {
|
||||
&self,
|
||||
from: AccountId,
|
||||
to_npk: NullifierPublicKey,
|
||||
to_ipk: IncomingViewingPublicKey,
|
||||
to_vpk: ViewingPublicKey,
|
||||
instruction_data: InstructionData,
|
||||
tx_pre_check: impl FnOnce(&Account, &Account) -> Result<(), ExecutionFailureKind>,
|
||||
program: Program,
|
||||
@ -504,7 +504,7 @@ impl WalletCore {
|
||||
let recipient_pre = AccountWithMetadata::new(to_acc.clone(), false, &to_npk);
|
||||
|
||||
let eph_holder = EphemeralKeyHolder::new(&to_npk);
|
||||
let shared_secret = eph_holder.calculate_shared_secret_sender(&to_ipk);
|
||||
let shared_secret = eph_holder.calculate_shared_secret_sender(&to_vpk);
|
||||
|
||||
let (output, proof) = circuit::execute_and_prove(
|
||||
&[sender_pre, recipient_pre],
|
||||
@ -522,7 +522,7 @@ impl WalletCore {
|
||||
vec![from_acc.nonce],
|
||||
vec![(
|
||||
to_npk.clone(),
|
||||
to_ipk.clone(),
|
||||
to_vpk.clone(),
|
||||
eph_holder.generate_ephemeral_public_key(),
|
||||
)],
|
||||
output,
|
||||
@ -548,13 +548,13 @@ impl WalletCore {
|
||||
let AccountPreparedData {
|
||||
nsk: _,
|
||||
npk: from_npk,
|
||||
ipk: from_ipk,
|
||||
vpk: from_vpk,
|
||||
auth_acc: sender_pre,
|
||||
proof: _,
|
||||
} = self.private_acc_preparation(from, false, false).await?;
|
||||
|
||||
let eph_holder_from = EphemeralKeyHolder::new(&from_npk);
|
||||
let shared_secret_from = eph_holder_from.calculate_shared_secret_sender(&from_ipk);
|
||||
let shared_secret_from = eph_holder_from.calculate_shared_secret_sender(&from_vpk);
|
||||
|
||||
let instruction: u128 = 0;
|
||||
|
||||
@ -574,7 +574,7 @@ impl WalletCore {
|
||||
vec![],
|
||||
vec![(
|
||||
from_npk.clone(),
|
||||
from_ipk.clone(),
|
||||
from_vpk.clone(),
|
||||
eph_holder_from.generate_ephemeral_public_key(),
|
||||
)],
|
||||
output,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user