Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[confidential-transfer] Add confidential burn proof generation and extraction #6955

Merged
merged 6 commits into from
Sep 13, 2024

Conversation

samkim-crypto
Copy link
Contributor

@samkim-crypto samkim-crypto commented Jul 1, 2024

Problem

There are no proof generation and verification logic for the new confidential mint and burn extension (#6879).

Summary of Changes

Added the proof generation and verification (context extraction) logic for the confidential mint and burn logic. There is already a community PR (#6881) that adds the extension on the program side. This PR just adds the confidential mint and burn zkp logic in the new confidential transfer submodules.

The description of the zkp can be found in #6879, but we basically need the following components:

  • The confidential burn zkp is essentially the same as that of a confidential transfer. We need the following components:
    • The ciphertext-commitment equality proof for the newly updated spendable balance in the source account exactly like in a confidential transfer.
    • The ciphertext validity proof to prove the well-formedness of the ciphertext that encrypts the burn amount. Unlike a confidential transfer, we encrypt w.r.t. source, auditor, and supply authority public keys.
    • The range proof to prove the remaining balance at the source is a positive 64-bit number and that the burn amount is a 16 and 32-bit number.
  • The confidential mint zkp is the same as that of confidential burn, but since we don't need to worry about the remaining balance at the source, we remove the ciphertext-commitment equality proof.

@github-actions github-actions bot added the stale [bot only] Added to stale content; will be closed soon label Jul 16, 2024
@samkim-crypto samkim-crypto removed the stale [bot only] Added to stale content; will be closed soon label Jul 16, 2024
@github-actions github-actions bot added the stale [bot only] Added to stale content; will be closed soon label Jul 31, 2024
@samkim-crypto samkim-crypto removed the stale [bot only] Added to stale content; will be closed soon label Jul 31, 2024
@github-actions github-actions bot added the stale [bot only] Added to stale content; will be closed soon label Aug 15, 2024
@samkim-crypto samkim-crypto removed the stale [bot only] Added to stale content; will be closed soon label Aug 17, 2024
@github-actions github-actions bot added the stale [bot only] Added to stale content; will be closed soon label Sep 2, 2024
@samkim-crypto samkim-crypto removed the stale [bot only] Added to stale content; will be closed soon label Sep 3, 2024
@samkim-crypto samkim-crypto force-pushed the confidential-mint branch 3 times, most recently from fdc24e0 to 1928685 Compare September 8, 2024 03:38
@samkim-crypto samkim-crypto marked this pull request as ready for review September 8, 2024 03:38
joncinque
joncinque previously approved these changes Sep 9, 2024
Copy link
Contributor

@joncinque joncinque left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a couple of tiny things and a question about how minting should work, but since I think you've explained the answer to me before, I'll approve to not stop this.

token/confidential-transfer/proof-generation/src/burn.rs Outdated Show resolved Hide resolved
}

pub fn mint_split_proof_data(
mint_amount: u64,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry if this is a silly question, because I think you've described it before, but I don't remember the answer.

The mint proof looks like it just adds whatever ciphertext is provided, as long as it's well-formed. Is there a check on the resulting amount in the token account at some point? What happens if you mint u64::MAX on a loop into someone's account?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah this is actually a good question. There could be two issues here. One is that the destination account ciphertext could be non-decryptable because the underlying encrypted value grows too large. This is not an issue because the mint amount is restricted to 48-bits (by range proof) and gets added to the pending balance instead of the available balance. There is a pending balance credit counter (https://github.com/solana-labs/solana-program-library/blob/master/token/program-2022/src/extension/confidential_transfer/mod.rs#L105) to limit this amount and the receiver can always do ApplyPendingBalance to flush this out.

The second issue is that the global supply itself can surpass 2^64. If each mint amount is 2^48 max, then after 2^16 ~ 65k mints, the total supply can surpass 2^64. The ElGamal ciphertexts (and Pedersen commitments) can store up to 256-bit amounts, so the supply can technically go up to this amount (it will never be able to surpass this number because you need to mint 2^208 times, which is practically impossible). I did not add it, but if we do not want the supply to surpass 2^64, then we can add an extra range-proof in the mint proof certifying that the supply ciphertext is always a 64-bit number. What do you think?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, that's a tough one. SPL Token mints are normally limited to a max supply of 2^64, so my inclination is to force the same thing here. Otherwise, people can get in strange situations where they try to deserialize their balance as a u64 and get unexpected values. If it were a totally new protocol, we could avoid the constraint totally and go with 2^256, but I worry about downstream issues. Unless there's a compelling reason for the supply to go up to 2^256, I think we'll need that extra range proof.

token/confidential-transfer/proof-extraction/src/mint.rs Outdated Show resolved Hide resolved
@mergify mergify bot dismissed joncinque’s stale review September 10, 2024 03:23

Pull request has been modified.

@samkim-crypto
Copy link
Contributor Author

I have added ciphertext-commitment equality proof and an extra range proof to the confidential mint proof data. When the supply authority creates a confidential mint instruction, it must add the mint amount to the supply in the mint and prove that this value is a 64-bit number. Since the encrypted randomness that pertains to the supply ElGamal ciphertext is not necessarily known by the supply authority, it must provide an extra commitment to the new supply and generate range proof with respect to this commitment. The ciphertext-commitment equality proof certifies that this commitment holds the same value as the new supply ciphertext.

joncinque
joncinque previously approved these changes Sep 11, 2024
Copy link
Contributor

@joncinque joncinque left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great, thanks!

@mergify mergify bot dismissed joncinque’s stale review September 13, 2024 07:00

Pull request has been modified.

@samkim-crypto samkim-crypto merged commit df498f3 into solana-labs:master Sep 13, 2024
31 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants