-
Notifications
You must be signed in to change notification settings - Fork 4.5k
[zk-token-sdk] add range-proof proof instruction #31788
[zk-token-sdk] add range-proof proof instruction #31788
Conversation
Codecov Report
@@ Coverage Diff @@
## master #31788 +/- ##
=======================================
Coverage 81.8% 81.9%
=======================================
Files 737 738 +1
Lines 205994 206036 +42
=======================================
+ Hits 168699 168746 +47
+ Misses 37295 37290 -5 |
ProofInstruction::VerifyRangeProof64 => { | ||
if native_programs_consume_cu { | ||
invoke_context | ||
.consume_checked(105_066) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
105_066
CUs is pretty exact. Where did this come from?
I guess more generally does it make sense to have such precise values (ie, like 2,619 for VerifyPubkeyValidity
) instead of a more round number like 105_000
? These are basically just rough estimates anyway?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry I forgot to write it in the pr description. So the data verification was benchmarked on my solana devserver and the time was divided the time by 33ns (https://discordapp.com/channels/428295358100013066/977244255212937306/1027500524901253140). I was hoping to include the benchmark code on a subsequent pr. These are approximate, so they don't have to be precise.
Do you think it makes sense to round each instruction costs to a clean number? It probably makes sense to do it in a separate PR for the rest of the instructions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The very specific numbers to me convey more than a rough approximation, but practically I guess it doesn't matter much. Definitely a separate PR if we want to change them. My main argument for doing so would be for easy of future communication: 100k or even 105k is much easier to discuss than 105,066.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, I will update the numbers in a follow-up PR and perhaps also add bench code in that PR as well.
ProofInstruction::VerifyZeroBalance, | ||
ProofInstruction::VerifyWithdraw, | ||
ProofInstruction::VerifyCiphertextCiphertextEquality, | ||
ProofInstruction::VerifyTransfer, | ||
ProofInstruction::VerifyTransferWithFee, | ||
ProofInstruction::VerifyPubkeyValidity, | ||
ProofInstruction::VerifyRangeProof64, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer an instruction name that is more specific to the actual operation it's performing, which I think if I understood the comment at the top of range_proof.rs
might look more like:
ProofInstruction::VerifyRangeProof64, | |
ProofInstruction::VerifyPedersenCommitmentHoldsExactU64Value, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that is exactly what the range proof is certifying. If we do go this route though, then we would want to change the names for the other instructions as well for consistency, but the compact names for many of the instructions are not clear (#31793 (comment) and also token-2022 specific instructions like Transfer
and Withdraw
).
What do you think about naming it VerifyRangeProofBitLength64
to be a little more specific and then perhaps moving the proof descriptions on top of the instruction submodules like range_proof.rs
directly to zk_token_proof_instruction.rs
on top of each instruction?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unless there's something fundamentally different between BitLength64 and U64 that I'm missing, my preference would be for VerifyRangeProofU64
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, let's make it VerifyRangeProofU64
to make it short and simple!
/// Accounts expected by this instruction: | ||
/// | ||
/// * Creating a proof context account | ||
/// 0. `[writable]` The proof context account |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is common for all the other instructions, but I think it'd be helpful to also say that the "The proof context account" is expected to be allocated to the expected data size and assigned to the proof program before invoking this instruction
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, you are right. I'll include that remark in the instruction description.
…must be pre-allocated
@@ -132,6 +132,27 @@ pub enum ProofInstruction { | |||
/// `PubkeyValidityData` | |||
/// | |||
VerifyPubkeyValidity, | |||
|
|||
/// Verify a 64-bit range proof. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Regarding the instruction renaming to something like VerifyRangeProofBitLength64
: I feel like we could maybe deal with in comments, here, instead actually. Currently one needs to dig through the header of zk-token-sdk/src/instruction/range_proof.rs to figure out exactly what this instruction is doing. But this comment block here is going to be the first place anybody who wants to understand what the instruction is goes to. So if we boost up the docs inline here (the other docs are fine too!), then that would also mostly solve my comment (likewise for the instructions being added in the other PR)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I like the idea of flashing this out some.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great, I will move the instruction descriptions to zk_token_proof_instruction.rs
.
ProofInstruction::VerifyZeroBalance, | ||
ProofInstruction::VerifyWithdraw, | ||
ProofInstruction::VerifyCiphertextCiphertextEquality, | ||
ProofInstruction::VerifyTransfer, | ||
ProofInstruction::VerifyTransferWithFee, | ||
ProofInstruction::VerifyPubkeyValidity, | ||
ProofInstruction::VerifyRangeProof64, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unless there's something fundamentally different between BitLength64 and U64 that I'm missing, my preference would be for VerifyRangeProofU64
.
@@ -132,6 +132,27 @@ pub enum ProofInstruction { | |||
/// `PubkeyValidityData` | |||
/// | |||
VerifyPubkeyValidity, | |||
|
|||
/// Verify a 64-bit range proof. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I like the idea of flashing this out some.
}; | ||
|
||
#[cfg(not(target_os = "solana"))] | ||
const RANGEPROOF64_BIT_LENGTH: usize = 64; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be possible to use u64::BITS instead of adding this new constant?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I never knew/used u64::BITS
before. I think it will work!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
r+ nits
Co-authored-by: Tyera <teulberg@gmail.com>
Co-authored-by: Tyera <teulberg@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
Problem
The zk-token-proof program does not yet have an instruction that can verify range proof on a Pedersen commitment.
Summary of Changes
Add
VerifyRangeProof64
instruction. This instruction can be used to prove that a committed value is in a certain range.The verification for these instruction was benched in the devserver and CU units were computed assuming that 1 CU should take roughly 33ns (as per #25464 (comment)).
Fixes #