Missing range checks of the carries of emulated field multiplication
Description. gnark v0.15.0 does not range-check carries of emulated field multiplication.
Public keys in Cardano are elements of Ed25519, which has p=2^255 - 19, different from the modulus of the native field, denoted . In order to perform multiplication in the non-native field, to get , gnark first decomposes the inputs into a limb representation .
In the honest situation, a prover would compute the correct and such that . They would then consider the decomposed field elements as polynomials: , and similarly for . For , the relation is correct over the integers, and so exists. The coefficients of are small, roughly for a small constant . Importantly, they must not be so large such that wrap . Specifically, since we want the equality of these polynomials to be over the integers, the coefficients of the two sides of the equations must be , imposing a requirement on the size of the coefficients of . A sufficient bound would be .
A malicious prover can choose as they wish, choose and compute . Since is chosen such that the equation is satisfied only , the expression for is not polynomial division over the integers, and instead it is just polynomial division . As a result, exists , its limbs have size and differ from the honest bounded values. being unbounded is what allows it.
Impact. Field multiplication is used in many places in the codebase, including elliptic curve addition. This allows a malicious prover to claim they own a victim’s public key while starting from their own chosen seed.
Recommendation. Update gnark to v0.16.3 version.
Client Response. The client has fixed the issue at PR#7 by updating gnark to v0.16.3 (go.mod). The audit team has reviewed the diff, retested and confirmed the fix is valid.