Skip to content

Conversation

@samkim-crypto
Copy link
Contributor

@samkim-crypto samkim-crypto commented Jan 4, 2026

Problem

All proof transcripts in the zk-sdk use hardcoded domain strings (e.g., b"ciphertext-ciphertext-equality-instruction", b"zero-ciphertext-instruction", etc.) without a shared chain-specific personalization prefix. Proofs generated on one blockchain can be replayed on any fork or chain using this code, as transcript domains are identical across all deployments

Summary of Changes

I added a domain separation tag in the transcript by adding a concrete transcript constructor Transcript::new_zk_elgamal_transcript(...) that first hashes b"solana-zk-elgamal-proof-program-v1" to the transcript before returning it. Then I updated all the instances of Transcript::new(...) in the zk-sdk to use Transcript::new_zk_elgamal_transcript(...).

The logic changes themselves should be pretty simple. But since we are adding new domain separations, I needed to update the hard-coded tests, which added on to the number of lines changed.

@samkim-crypto samkim-crypto marked this pull request as ready for review January 6, 2026 07:36
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! I checked to make sure there are no more uses of Transcript::new anywhere (except in TranscriptProtocol)

Comment on lines +34 to +35
/// This string MUST be changed for any fork or separate deployment to prevent
/// cross-chain proof replay attacks.
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: just so I'm sure I understand, we're not differentiating this for different networks, ie testnet vs devnet vs mainnet?

If we wanted to be pedantic, we may want to include the genesis hash in the domain, but this should be fine

Copy link
Contributor Author

@samkim-crypto samkim-crypto Jan 7, 2026

Choose a reason for hiding this comment

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

Yeah we encountered this issue for alpenglow BLS as well and I thought about this briefly. I think it adds a lot of extra complications if we differentiate between testnet, devnet, and mb. We probably need to add different features (in both solana-zk-sdk and agave) that has different hardcoded domain separator targeted at different networks and validators will need to deploy network specific builds of the zk-elgamal proof program.

I guess we can have the program directly look up the genesis hash inside the program and add it as an input to the verification function, but this probably adds another set of complications. I think keeping it uniform across different networks probably simplifies testing and maintenance.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yep that's fine, just wanted to make sure

@samkim-crypto
Copy link
Contributor Author

Thanks for the review and let me merge this for now. If you feel strongly about anything related to the nit comment above, then I'll make sure to address it in a follow up 🙏

@samkim-crypto samkim-crypto merged commit afbbe3d into solana-program:main Jan 7, 2026
11 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