Safe Usage of SP1 Precompiles
This section outlines the key assumptions and properties of each precompile. Advanced users interacting directly with the precompiles are expected to ensure these assumptions are met.
If you need to interact with the precompiles directly, we strongly recommend using the API described in Precompiles rather than making an ecall
directly using unsafe Rust.
Alignment of Pointers
For all precompiles, any pointer with associated data must be a valid pointer aligned to a four-byte boundary. This requirement applies to all precompiles related to hashing, field operations, and elliptic curve operations.
Canonical Field Inputs
Certain precompiles handle non-native field arithmetic, such as field operation and elliptic curve precompiles. These precompiles take field inputs as arrays of u32
values. In such cases, the u32
values must represent the field element in its canonical form. For example, in a finite field Fp
, the value 1
must be represented by u32
limbs that encode 1
, rather than p + 1
or 2 * p + 1
. Using non-canonical representations may result in unverifiable SP1 proofs. Note that our field operation and elliptic curve operation precompiles are constrained to return field elements in their canonical representations.
Elliptic Curve Precompiles
The elliptic curve precompiles assume that inputs are valid elliptic curve points. Since this validity is not enforced within the precompile circuits, it is the responsibility of the user program to verify that the points lie on the curve. Given valid elliptic curve points as inputs, the precompile will perform point addition or doubling as expected.
For Weierstrass curves, the add
precompile additionally constrains that the two elliptic curve points have different x
-coordinates over the base field. Attempting to double a point by sending two equal curve points to the add
precompile will result in unverifiable proofs. Additionally, cases where an input or output point is a point at infinity cannot be handled by the add
or double
precompile. It is the responsibility of the user program to handle such edge cases of Weierstrass addition correctly when invoking these precompiles.
U256 Precompile
The sys_bigint
precompile efficiently constrains the computation of (x * y) % modulus
, where x, y, modulus
are all uint256
. Here, the precompile requires that x * y < 2^256 * modulus
for the resulting SP1 proof to be verifiable. This condition is satisfied, for example, when at least one of x
or y
is canonical, (i.e., less than the modulus
). It is the responsibility of the user program to ensure that this requirement is met.