Skip to content
This repository was archived by the owner on Mar 11, 2025. It is now read-only.

Commit 07ec5b8

Browse files
committed
add confidential burn proof generation
1 parent ba05751 commit 07ec5b8

File tree

3 files changed

+103
-0
lines changed

3 files changed

+103
-0
lines changed
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
use {
2+
crate::{encryption::BurnAmountCiphertext, errors::TokenProofGenerationError},
3+
solana_zk_sdk::{
4+
encryption::{
5+
elgamal::{ElGamalCiphertext, ElGamalKeypair, ElGamalPubkey},
6+
pedersen::Pedersen,
7+
},
8+
zk_elgamal_proof_program::proof_data::{
9+
BatchedRangeProofU64Data, CiphertextCommitmentEqualityProofData,
10+
GroupedCiphertext2HandlesValidityProofData,
11+
},
12+
},
13+
};
14+
15+
const BURN_AMOUNT_BIT_LENGTH: usize = 64;
16+
17+
pub fn burn_split_proof_data(
18+
burn_amount: u64,
19+
source_elgamal_keypair: &ElGamalKeypair,
20+
auditor_elgamal_pubkey: &ElGamalPubkey,
21+
current_spendable_balance: u64,
22+
current_spendable_balance_ciphertext: &ElGamalCiphertext,
23+
) -> Result<
24+
(
25+
CiphertextCommitmentEqualityProofData,
26+
GroupedCiphertext2HandlesValidityProofData,
27+
BatchedRangeProofU64Data,
28+
),
29+
TokenProofGenerationError,
30+
> {
31+
// Encrypt the burn amount under the source and auditor's ElGamal public key
32+
let (burn_amount_ciphertext, burn_amount_opening) = BurnAmountCiphertext::new(
33+
burn_amount,
34+
source_elgamal_keypair.pubkey(),
35+
auditor_elgamal_pubkey,
36+
);
37+
38+
// Copmute the remaining balance ciphertext
39+
let burn_amount_ciphertext_source = burn_amount_ciphertext.0.to_elgamal_ciphertext(0).unwrap();
40+
41+
#[allow(clippy::arithmetic_side_effects)]
42+
let remaining_balance_ciphertext =
43+
current_spendable_balance_ciphertext - burn_amount_ciphertext_source;
44+
45+
// Compute the remaining balance at the source
46+
let remaining_balance = current_spendable_balance
47+
.checked_sub(burn_amount)
48+
.ok_or(TokenProofGenerationError::NotEnoughFunds)?;
49+
50+
let (remaining_balance_commitment, remaining_balance_opening) =
51+
Pedersen::new(remaining_balance);
52+
53+
let equality_proof_data = CiphertextCommitmentEqualityProofData::new(
54+
source_elgamal_keypair,
55+
&remaining_balance_ciphertext,
56+
&remaining_balance_commitment,
57+
&remaining_balance_opening,
58+
remaining_balance,
59+
)
60+
.map_err(TokenProofGenerationError::from)?;
61+
62+
let ciphertext_validity_proof_data = GroupedCiphertext2HandlesValidityProofData::new(
63+
source_elgamal_keypair.pubkey(),
64+
auditor_elgamal_pubkey,
65+
&burn_amount_ciphertext.0,
66+
burn_amount,
67+
&burn_amount_opening,
68+
)
69+
.map_err(TokenProofGenerationError::from)?;
70+
71+
let range_proof_data = BatchedRangeProofU64Data::new(
72+
vec![&remaining_balance_commitment],
73+
vec![remaining_balance],
74+
vec![BURN_AMOUNT_BIT_LENGTH],
75+
vec![&remaining_balance_opening],
76+
)
77+
.map_err(TokenProofGenerationError::from)?;
78+
79+
Ok((
80+
equality_proof_data,
81+
ciphertext_validity_proof_data,
82+
range_proof_data,
83+
))
84+
}

token/confidential-transfer/proof-generation/src/encryption.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,21 @@ impl FeeCiphertext {
8686
self.0.handles.get(1).unwrap()
8787
}
8888
}
89+
90+
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
91+
#[repr(C)]
92+
pub struct BurnAmountCiphertext(pub(crate) GroupedElGamalCiphertext<2>);
93+
94+
impl BurnAmountCiphertext {
95+
pub fn new(
96+
amount: u64,
97+
source_pubkey: &ElGamalPubkey,
98+
auditor_pubkey: &ElGamalPubkey,
99+
) -> (Self, PedersenOpening) {
100+
let opening = PedersenOpening::new_rand();
101+
let grouped_ciphertext =
102+
GroupedElGamal::<2>::encrypt_with([source_pubkey, auditor_pubkey], amount, &opening);
103+
104+
(Self(grouped_ciphertext), opening)
105+
}
106+
}

token/confidential-transfer/proof-generation/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use {
66
},
77
};
88

9+
pub mod burn;
910
pub mod encryption;
1011
pub mod errors;
1112
pub mod transfer;

0 commit comments

Comments
 (0)