cairo by example

field arithmetic

Because they use modular arithmetic, some operations of the felt252 type may seem unusual. Some things to consider:

A felt252 must be less than the Cairo prime

The following code:

fn main() {
    let cairo_prime: felt252 = 3618502788666131213697322783095070105623107215331596699973092056135872020481;
}

fails to compile with:

error: The value does not fit within the range of type core::felt252.

Operations are done modulo the Cairo prime

Expanding on the felt252 example:

fn main() {
    // max value of felt252 (P - 1)
    let x = 3618502788666131213697322783095070105623107215331596699973092056135872020480;
    assert(x + 1 == 0, '(P - 1) + 1 == 0 (mod P)');
    // assert(x == -1, 'negation is modular'); <- still not supported
    assert(x == 0 - 1, 'subtraction is modular');
    assert(x * x == 1, 'multiplication is modular');
}

Division is not floored division (it’s field division)

This means that a / b = c if and only if a = c * b, which can lead to unexpected results:

use traits::TryInto;
use option::OptionTrait;

fn main() {
    let two = TryInto::try_into(2).unwrap();

    assert(felt252_div(2, two) == 1, '2 == 1 * 2');

    // (P + 1) / 2
    let half_prime_plus_one = 1809251394333065606848661391547535052811553607665798349986546028067936010241;
    assert(felt252_div(1, two) == half_prime_plus_one, '1 == ((P + 1) / 2) * 2 (mod P)');
}

Note: currently, felt252 division has to be done explicitly via the external felt252_div function



Try it out!
  1. Install the toolchain:
    • For macOS and Linux, run our script:
    • curl -sL https://raw.githubusercontent.com/lambdaclass/cairo-by-example/main/build/installer.sh | bash -s 2.2.0
    • For Windows and others, please see the official guide
  2. Run the example:
    1. Copy the example into a field_arithmetic.cairo file and run with:
    2. %!s(<nil>) field_arithmetic.cairo

prev (felt252) next (integers)