Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add page for describing cairo builtins #1202

Closed
wants to merge 8 commits into from
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
*** xref:Smart_Contracts/starknet-events.adoc[Events]
*** xref:Smart_Contracts/contract-syntax.adoc[Migrating a contract from Cairo v1 to Cairo v2]
*** xref:Smart_Contracts/cairo-and-sierra.adoc[Cairo and Sierra]
*** xref:Smart_Contracts/builtins.adoc[Builtins]
*** xref:Smart_Contracts/serialization_of_Cairo_types.adoc[Serialization of Cairo types]
*** xref:Smart_Contracts/system-calls-cairo1.adoc[System calls]
*** xref:Smart_Contracts/execution_info.adoc[Execution information for the current block]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
= Cairo Builtins

== Introduction
xiaolou86 marked this conversation as resolved.
Show resolved Hide resolved

Builtins are predefined optimized low-level execution units which are added to the Cairo CPU board to perform predefined computations which are expensive to perform in standard Cairo. Builtins enhance the functionality of the Cairo virtual machine, allowing you to perform tasks such as Pedersen hash, Poseidon hash, range-checks, ECDSA signature verifications, Keccak hash, Bitwise operations, and EC operations efficiently and at a cheaper gas cost.
xiaolou86 marked this conversation as resolved.
Show resolved Hide resolved

== List of Cairo Builtins
xiaolou86 marked this conversation as resolved.
Show resolved Hide resolved

[cols="1,2,2"]
|===
| Builtin | Example | Explanation

| `pedersen`
| `result = pedersen(x, y)`
| `pedersen(x: felt252, y: felt252) -> felt252`

Hashes two elements and retrieves a single field element output.

| `poseidon_hash`
| `result = poseidon_hash(x, y)`
| `poseidon_hash(x: felt, y: felt) -> (res: felt)`

Hashes two elements and retrieves a single field element output.

| `poseidon_hash_single`
| `result = poseidon_hash_single(x)`
| `poseidon_hash_single(x: felt) -> (res: felt)`

Hashes one element `x` and retrieves a single field element output.

| `poseidon_hash_many`
| `result = poseidon_hash_many(n, y)`
| `poseidon_hash_many(n: felt, elements: felt*) -> (res: felt)`

Hashes n elements and retrieves a single field element output.

| `poseidon_hash_span`
| `result = poseidon_hash_span(data)`
| `poseidon_hash_span(mut span: Span<felt252>) -> felt252`

Computes the Pedersen hash of the given input `data`.

| `<`
| `a < b`
| Less than comparison .

| `\<=`
| `a \<= b`
| Less than or equal to comparison.

| `==`
| `a == b`
| Equality comparison.

| `!=`
| `a != b`
| Non-equality comparison.

| `>`
| `a > b`
| Greater than comparison.

| `>=`
| `a >= b`
| Greater than or equal to comparison.

| `check_ecdsa_signature`
| `valid = check_ecdsa_signature(message, public_key, signature_r, signature_s)`
| Checks if (signature_r, signature_s) is a valid signature for the given public_key on the given message.

Return TRUE if the signature is valid, FALSE otherwise.

| `verify_ecdsa_signature`
| `verify_ecdsa_signature(message, public_key, signature_r, signature_s)`
| Verifies that the prover knows a signature of the given public_key on the given message.

| `keccak_u256s_le_inputs`
| `keccak_u256s_le_inputs(input)`
| `keccak_u256s_le_inputs(mut input: Span<u256>) -> u256`

Computes the keccak256 of multiple u256 values.

The input values are interpreted as little-endian.

The 32-byte result is represented as a little-endian u256.

| `keccak_u256s_be_inputs`
| `keccak_u256s_be_inputs(input)`
| `keccak_u256s_be_inputs(mut input: Span<u256>) -> u256`

Computes the keccak256 of multiple u256 values.

The input values are interpreted as big-endian.

The 32-byte result is represented as a little-endian u256.

| `cairo_keccak`
| `cairo_keccak(input, last_input_word, last_input_num_bytes)`
| `cairo_keccak(ref input: Array<u64>, last_input_word: u64, last_input_num_bytes: usize) -> u256`

Computes the keccak of `input` + `last_input_num_bytes` LSB bytes of `last_input_word`.

To use this function, split the input into words of 64 bits (little endian).

| `&`
| `a & b`
| Bitwise AND.

| `\|`
| `a \| b`
| Bitwise OR.

| `^`
| `a ^ b`
| Bitwise XOR.

| `~`
| `~a`
| Bitwise NOT.

| `ec_double`
| `ec_double(p)`
| Doubles a point (computes p + p) on the EC.

| `ec_add`
| `ec_add(p, q)`
| Adds two points on the EC.

| `ec_sub`
| `ec_sub(p, q)`
| Subtracts a point from another on the EC.

| `ec_op`
| `ec_op(p, m, q)`
| `ec_op(p: EcPoint, m: felt, q: EcPoint) -> (r: EcPoint)`

Computes p + m * q on the EC.

| `ec_mul`
| `ec_mul(m, p)`
| `ec_mul(m: felt, p: EcPoint) -> (r: EcPoint)`

Computes m * p on the EC.

| `chained_ec_op`
| `chained_ec_op(p, m, q, len)`
| `chained_ec_op(p: EcPoint, m: felt*, q: EcPoint*, len: felt) -> (r: EcPoint)`

Computes p + m[0] * q[0] + m[1] * q[1] + ... m[len - 1] * q[len - 1] on the EC.

|===