#41027 [BC-Insight] Breaking asset surjection proof assumptions
Submitted on Mar 9th 2025 at 17:58:59 UTC by @Blockian for IOP | Zano
Report ID: #41027
Report Type: Blockchain/DLT
Report severity: Insight
Target: https://github.com/immunefi-team/zano-iop/tree/main/src/currency_core/currency_format_utils.cpp
Impacts:
Cryptographic inconsistency
Description
Note: I'm relying on two checks in you code base:
static const size_t N_max = 256;
(src/crypto/one_out_of_many_proofs.cpp:23)static_assert(CURRENCY_TX_MAX_ALLOWED_INPUTS <= N_max, "CURRENCY_TX_MAX_ALLOWED_INPUTS is inconsistent with one-out-of-many proof limits");
(src/crypto/one_out_of_many_proofs.cpp:26)CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(N <= N_max, 3);
(src/crypto/one_out_of_many_proofs.cpp:79) They state that the aggregated surjection proof can only work up to 256 inputs.
I don't know if by having more inputs than that the proof can be bypassed, or if it only breaks it so that it won't work at all
Impact
The impact is that one out of many
verify_BGE_proof
(used for aggregated asset surjection) can be called with a ring size that is larger than 256
which is the maximum that is consistent with the one-out-of-many proof (as per this comment: src/crypto/one_out_of_many_proofs.cpp:23
)
Root Cause
The root cause is that the number of inputs isn't validated anywhere.
Deep Dive
Can search
vin.size()
andCURRENCY_TX_MAX_ALLOWED_INPUTS
accross the codebase to validate
Suggested Fix
Validate tx.vin.size()
Severity
As stated, I don't know. If this does nothing to the proof and the comment is wrong, than it's only an insight. If this breaks the proof, than it's dependent on what breaks. A critical if the checks can be completely bypassed in some instances, less otherwise. I'm not sure I have enough time to dive into this aggregation proof as I'm trying to cover as much code as possible.
Proof of Concept
Proof of Concept
Any transaction with more than 256 inputs.
Was this helpful?