AleoNet / snarkVM

A Virtual Machine for Zero-Knowledge Executions
https://snarkvm.org
Apache License 2.0
1.08k stars 1.5k forks source link

[Fix] Avoid ejecting the scalar value when loading and storing a circuit. #2534

Open d0cd opened 3 months ago

d0cd commented 3 months ago

This PR avoids ejecting the scalar value when loading and storing a circuit.

Failing Case

This issue was found in a deployed program.

Suppose that we have a program cast operation from a field to a scalar. Suppose that r0 is a field element that is larger than the scalar modulus.

function foo:
    input r0 as field.private;
    cast r0 into r1 as scalar;

When the cast instruction is executed, constraints are added to check that the casted scalar value is correct. During deployment, these constraints are not checked for satisfaction (by design), and an invalid scalar element is stored into the registers. store_circuit ejects the stored value and checks for type equality. However, the implementation of Eject for Scalar requires that the element is a valid a scalar and panics otherwise.

Solution

The eject is done to check that the type of the stored value is correct. To avoid this failing case, we directly check for type equality against the circuit value.

Testing

This PR includes an integration test that enumerates all LiteralType combinations of cast and cast.lossy and tests them in a program context.

CI is running in this branch.

Considerations

We considered alternate solutions including: