Replies: 4 comments 1 reply
-
The table here indicates that some hash and commit functions will get flagged versions, and indeed Aleo opcode docs say these hash functions will fail if the input is too large (for the Pedersen functions) or too small ( for the BHP functions). In practice, the BHP functions don't seem to fail even with
compiles to this
and runs fine, producing an output.
I don't know if this is a bug in the docs or in SnarkVM. |
Beta Was this translation helpful? Give feedback.
-
Thank you @mikebenfield for the observation! It is out-of-date documentation. The Also, the |
Beta Was this translation helpful? Give feedback.
-
LGTM! On the backward compatibility issue, I think it's fine that the (unlikely) use case of Leo programs that were actually depending on the behavior of halting operations in non-taken branches is no longer supported. It's a poor programming behavior, and I haven't seen any programs that take advantage of this. |
Beta Was this translation helpful? Give feedback.
-
Big fan of this proposal! It's important to give developers the semantics they expect. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
arc: 4
title: Flagged Operations for Conditional Code
authors: bendyarm, d0cd, acoglio, mikebenfield
discussion: ARC-0004: Flagged Operations for Conditional Code
topic: Protocol
status: Draft
created: 2025-03-09
Abstract
Some Aleo instructions can halt when passed certain arguments.
This halting behavior makes those instructions unusable
by a program that wants to try something else if a halt is detected.
We propose to add nonhalting variants of each such instruction.
The nonhalting variants additionally return an error flag.
This change would be strictly additive; none of the existing instructions
or Aleo Instructions programs would change.
Why does Aleo need this?
The need for these instructions is to enable proper compilation of
if-then-else
in a circuit. In a circuit, both thethen
statements and theelse
statements are executed (both must be executed), and then theif
condition is used to select which results will be used for further computation. If a non-taken branch halts, it still halts the entire circuit, which is not the desired behavior.Especially for code compiled from Leo, this could lead to unexpected program behavior, including possible inaccessibility of funds. The reason Leo code is especially vulnerable is that it has an
if-then-else
statement that currently has a different semantics than what a Leo programmer would expect (the non-taken branch being executed). However, the problem also exists in Aleo Instructions of not being able to write the equivalent of anif-then-else
statement where there are halting instructions in thethen
statements orelse
statements.However, even for Aleo Instructions programs not compiled from Leo, these operations will allow developers to roll their own
if-then-else
code, and will enable checking if an instruction would have halted without actually triggering a halt.Why does adding nonhalting variants solve this problem?
By using nonhalting instruction variants in
then
andelse
branches, a non-taken branch will not cause a halt, even though it is still executed. When theif
condition selects which results to use, at that time the code will trigger a halt if the taken branch would have halted if it had used a halting instruction (i.e., if the error flag was set by the nonhalting instruction).Simple example in Leo code.
If called with
y
equal to0field
, this program will halt because the division is always executed, whereas the expected result would bex
. There is currently no way to compile this Leo program to Aleo Instructions that work as expected unless there is a nonhaltingdiv
operation. (We are calling this proposed nonhalting Aleo Instructions opcodediv.flagged
.)After this ARC is implemented, the Leo compiler can be improved so that this program runs as expected.
Specification
Each flagged operation is identical to its corresponding current operation
when called with arguments that would be nonhalting, except it returns
a second return value of type boolean that is false (meaning that the
current operation would not have halted). When called with arguments
that would have been halting, it generally returns 0 (of the appropriate
output type) and true ("would have halted") for the second return value.
The flagged operations are different from wrapped (e.g.
abs.w
) orlossy (e.g.
cast.lossy
) operations. It is important that the flaggedoperation have the same semantics as the current halting instruction
except for the halting behavior and extra return value, for ease of
use by compilers.
Note that most opcodes compile into different operations based on the types
of the operands, and those operations sometimes have different halting
behavior. For example,
add
cannot halt when given field, group or scalararguments, but it can halt when given integer arguments. So
add.flagged
will not be implemented for field, group or scalar arguments. We add notes
for these cases in the table below.
Test Cases
The following note applies to all tests of Aleo Instructions. For all tests, both literal constant arguments
and variable arguments should be tested. For example, if there are two arguments, we need to test all four
combinations. This is because the Aleo Instructions compiler generates more optimized code for literal
constant arguments, and the circuits can differ substantially.
One or more arguments that causes halting for a current halting opcode should be used as an input
for the equivalent new flagged opcode to make sure it doesn't halt.
An assortment of arguments that do not cause halting for a current halting opcode should be
used as input to both halting and flagged operations to make sure they return the same value
(other than the halting flag, of course).
Audit and Formal Verification
We intend to have an audit of the implementation of the new opcodes, as well as to formally
verify the implementation.
Reference Implementations
This ARC will not be fully implemented unless approved. However, there is a proof-of-concept (PoC)
implementation with the following components:
In a snarkVM branch, Aleo Instructions
div.flagged
andinv.flagged
have been implemented, both foronly field operands.
In a Leo branch, there is a PoC change to the Leo compiler that compiles uses of
/
andinv()
(thatare applied to field operands and that are in conditionals) to the new Aleo Instructions
div.flagged
andinv.flagged
, along with the appropriate logic to make sure halts happen only when appropriate.This To try out this PoC implementation, first make sure you have already installed the
preliminaries for snarkVM
and for Leo.
At this point you can use the snarkVM CLI and the Leo CLI to make programs and run them.
This PoC fixes this Leo issue.
Similarly, implementing the full ARC will fix similar issues for all the haltable operations
when they are in conditional code.
Dependencies
The main change is to the snarkVM repository.
Any tool that needs to know what all the opcodes are needs to be changed. For example, the Aleo
Explorer and the Provable SDK.
After the ARC is implemented, the Leo compiler can use the new opcodes to improve the quality of compiled code.
However, if the Leo compiler is not changed, the resulting code will continue to work the same way it did before the ARC was implemented.
Backwards Compatibility
For snarkVM, this change is strictly additive, and does not require any changes to existing Aleo Instructions programs. Also, use of the new opcodes is optional; the change does not require any changes to how you are writing new Aleo Instructions programs.
If there are any Leo programs that were actually depending on the behavior of halting operations in non-taken branches causing halts, then those Leo programs would behave differently after being recompiled. We believe this case is very unlikely; it is more likely that the recompilation would fix latent bugs that just had not yet been encountered.
Security & Compliance
This change does not affect security or regulatory issues.
References
Example Leo bug:
ProvableHQ/leo#27482
Beta Was this translation helpful? Give feedback.
All reactions