# Leo Operators Reference

The following is a list of operators supported by Leo. The Leo operators compile down to Aleo instructions opcodes executable by the Aleo Virtual Machine (AVM).

## Table of Operators

Name | Description |
---|---|

abs | Absolute value operation |

abs_wrapped | Wrapping absolute value operation |

add | Addition operation |

add_wrapped | Wrapping addition operation |

and | AND operation |

assert_eq | Assert equality |

assert_neq | Assert non-equality |

BHP256::commit | 256-bit input BHP commitment |

BHP512::commit | 512-bit input BHP commitment |

BHP768::commit | 768-bit input BHP commitment |

BHP1024::commit | 1024-bit input BHP commitment |

Pedersen64::commit | 64-bit input Pedersen commitment |

Pedersen128::commit | 128-bit input Pedersen commitment |

div | Division operation |

div_wrapped | Wrapping division operation |

double | Double operation |

gt | Greater than comparison |

gte | Greater than or equal to comparison |

BHP256::hash | 256-bit input BHP hash |

BHP512::hash | 512-bit input BHP hash |

BHP768::hash | 768-bit input BHP hash |

BHP1024::hash | 1024-bit input BHP hash |

Pedersen64::hash | 64-bit input Pedersen hash |

Pedersen128::hash | 128-bit input Pedersen hash |

Poseidon2::hash | Poseidon hash with input rate 2 |

Poseidon4::hash | Poseidon hash with input rate 4 |

Poseidon8::hash | Poseidon hash with input rate 8 |

inv | Multiplicative inverse operation |

eq | Equality comparison |

neq | Not equal comparison |

lt | Less than comparison |

lte | Less than or equal to comparison |

mod | Arithmetic modulo operation |

mul | Multiplication operation |

mul_wrapped | Wrapping multiplication operation |

nand | `Boolean` NAND operation |

neg | Additive inverse operation |

nor | `Boolean` NOR operation |

not | NOT operation |

or | OR Operation |

pow | Exponentiation operation |

pow_wrapped | Wrapping exponentiation operation |

rem | Remainder operation |

rem_wrapped | Wrapping remainder operation |

shl | Shift left operation |

shl_wrapped | Wrapping shift left operation |

shr | Shift right operation |

shr_wrapped | Wrapping shift right operation |

square_root | Square root operation |

square | Square operation |

sub | Subtraction operation |

sub_wrapped | Wrapping subtraction operation |

ternary | Ternary select operation |

xor | XOR operation |

## Specification

The following is the specification for each opcode in the Aleo Virtual Machine (AVM).

`abs`

`let a: i8 = -1i8;`

let b: i8 = a.abs(); // 1i8

#### Description

Computes the absolute value of the input, checking for overflow, storing the result in the destination.

For integer types, a constraint is added to check for underflow. For cases where wrapping semantics are needed, see the abs_wrapped instruction. This underflow happens when the input is the minimum value of a signed integer type. For example, `abs -128i8`

would result in underflow, since `128`

cannot be represented as an `i8`

.

#### Supported Types

Input | Destination |
---|---|

`I8` | `I8` |

`I16` | `I16` |

`I32` | `I32` |

`I64` | `I64` |

`I128` | `I128` |

<!-- | `U8` |

<!-- | `U16` |

<!-- | `U32` |

<!-- | `U64` |

<!-- | `U128` |

`abs_wrapped`

`let a: i8 = -128i8;`

let b: i8 = a.abs_wrapped(); // -128i8

#### Description

Compute the absolute value of the input, wrapping around at the boundary of the type, and storing the result in the destination.

#### Supported Types

Input | Destination |
---|---|

`I8` | `I8` |

`I16` | `I16` |

`I32` | `I32` |

`I64` | `I64` |

`I128` | `I128` |

<!-- | `U8` |

<!-- | `U16` |

<!-- | `U32` |

<!-- | `U64` |

<!-- | `U128` |

`add`

`let a: u8 = 1u8;`

let b: u8 = a + 1u8; // 2u8

let c: u8 = b.add(1u8); // 3u8

#### Description

Adds `first`

with `second`

, storing the outcome in `destination`

.

For integer types, a constraint is added to check for overflow. For cases where wrapping semantics are needed for integer types, see the add_wrapped instruction.

#### Supported Types

First | Second | Destination |
---|---|---|

`Field` | `Field` | `Field` |

`Group` | `Group` | `Group` |

`I8` | `I8` | `I8` |

`I16` | `I16` | `I16` |

`I32` | `I32` | `I32` |

`I64` | `I64` | `I64` |

`I128` | `I128` | `I128` |

`U8` | `U8` | `U8` |

`U16` | `U16` | `U16` |

`U32` | `U32` | `U32` |

`U64` | `U64` | `U64` |

`U128` | `U128` | `U128` |

`Scalar` | `Scalar` | `Scalar` |

`add_wrapped`

`let a: u8 = 255u8;`

let b: u8 = a.add_wrapped(1u8); // 0u8

#### Description

Adds `first`

with `second`

, wrapping around at the boundary of the type, and storing the outcome in `destination`

.

#### Supported Types

First | Second | Destination |
---|---|---|

`I8` | `I8` | `I8` |

`I16` | `I16` | `I16` |

`I32` | `I32` | `I32` |

`I64` | `I64` | `I64` |

`I128` | `I128` | `I128` |

`U8` | `U8` | `U8` |

`U16` | `U16` | `U16` |

`U32` | `U32` | `U32` |

`U64` | `U64` | `U64` |

`U128` | `U128` | `U128` |

`and`

`let a: i8 = 1i8 & 1i8; // 1i8`

let b: i8 = 1i8.and(2i8); // 0i8

#### Description

Performs an AND operation on integer (bitwise) or boolean `first`

and `second`

,
storing the outcome in `destination`

.

#### Supported Types

First | Second | Destination |
---|---|---|

`Boolean` | `Boolean` | `Boolean` |

`I8` | `I8` | `I8` |

`I16` | `I16` | `I16` |

`I32` | `I32` | `I32` |

`I64` | `I64` | `I64` |

`I128` | `I128` | `I128` |

`U8` | `U8` | `U8` |

`U16` | `U16` | `U16` |

`U32` | `U32` | `U32` |

`U64` | `U64` | `U64` |

`U128` | `U128` | `U128` |

`assert_eq`

`let a: u8 = 1u8;`

let b: u8 = 2u8;

console.assert_eq(a, a); // will not halt

console.assert_eq(a, b); // program halts

#### Description

Checks whether `first`

and `second`

are equal, halting if they are not equal.

#### Supported Types

First | Second |
---|---|

`Address` | `Address` |

`Boolean` | `Boolean` |

`Field` | `Field` |

`Group` | `Group` |

`I8` | `I8` |

`I16` | `I16` |

`I32` | `I32` |

`I64` | `I64` |

`I128` | `I128` |

`U8` | `U8` |

`U16` | `U16` |

`U32` | `U32` |

`U64` | `U64` |

`U128` | `U128` |

`Scalar` | `Scalar` |

`Interface` | `Interface` |

`Record` | `Record` |

`assert_neq`

`let a: u8 = 1u8;`

let b: u8 = 2u8;

console.assert_neq(a, b); // will not halt

console.assert_neq(a, a); // program halts

#### Description

Checks whether `first`

and `second`

are not equal, halting if they are equal.

#### Supported Types

First | Second |
---|---|

`Address` | `Address` |

`Boolean` | `Boolean` |

`Field` | `Field` |

`Group` | `Group` |

`I8` | `I8` |

`I16` | `I16` |

`I32` | `I32` |

`I64` | `I64` |

`I128` | `I128` |

`U8` | `U8` |

`U16` | `U16` |

`U32` | `U32` |

`U64` | `U64` |

`U128` | `U128` |

`Scalar` | `Scalar` |

`Interface` | `Interface` |

`Record` | `Record` |

`BHP256::commit`

`let a: i128 = 1i128;`

let b: field = BHP256::commit(a, 1scalar);

#### Description

Computes a BHP commitment on inputs of 256-bit chunks in `first`

, and some randomness in `second`

, storing the commitment in `destination`

. Randomness should always be a `Scalar`

value, and the produced commitment will always be a `Field`

value.

The instruction will halt if the given input is smaller than 129 bits.

#### Supported Types

First | Second | Destination |
---|---|---|

`Address` | `Scalar` | `Field` |

`Boolean` | `Scalar` | `Field` |

`Field` | `Scalar` | `Field` |

`Group` | `Scalar` | `Field` |

`I8` | `Scalar` | `Field` |

`I16` | `Scalar` | `Field` |

`I32` | `Scalar` | `Field` |

`I64` | `Scalar` | `Field` |

`I128` | `Scalar` | `Field` |

`U8` | `Scalar` | `Field` |

`U16` | `Scalar` | `Field` |

`U32` | `Scalar` | `Field` |

`U64` | `Scalar` | `Field` |

`U128` | `Scalar` | `Field` |

`Scalar` | `Scalar` | `Field` |

`String` | `Scalar` | `Field` |

`Interface` | `Scalar` | `Field` |

`BHP512::commit`

`let a: i128 = 1i128;`

let b: field = BHP512::commit(a, 1scalar);

#### Description

Computes a BHP commitment on inputs of 512-bit chunks in `first`

, and some randomness in `second`

, storing the commitment in `destination`

. Randomness should always be a `Scalar`

value, and the produced commitment will always be a `Field`

value.

The instruction will halt if the given input is smaller than 171 bits.

#### Supported Types

First | Second | Destination |
---|---|---|

`Address` | `Scalar` | `Field` |

`Boolean` | `Scalar` | `Field` |

`Field` | `Scalar` | `Field` |

`Group` | `Scalar` | `Field` |

`I8` | `Scalar` | `Field` |

`I16` | `Scalar` | `Field` |

`I32` | `Scalar` | `Field` |

`I64` | `Scalar` | `Field` |

`I128` | `Scalar` | `Field` |

`U8` | `Scalar` | `Field` |

`U16` | `Scalar` | `Field` |

`U32` | `Scalar` | `Field` |

`U64` | `Scalar` | `Field` |

`U128` | `Scalar` | `Field` |

`Scalar` | `Scalar` | `Field` |

`String` | `Scalar` | `Field` |

`Interface` | `Scalar` | `Field` |

`BHP768::commit`

`let a: i128 = 1i128;`

let b: field = BHP768::commit(a, 1scalar);

#### Description

Computes a BHP commitment on inputs of 768-bit chunks in `first`

, and some randomness in `second`

, storing the commitment in `destination`

. Randomness should always be a `Scalar`

value, and the produced commitment will always be a `Field`

value.

The instruction will halt if the given input is smaller than 129 bits.

#### Supported Types

First | Second | Destination |
---|---|---|

`Address` | `Scalar` | `Field` |

`Boolean` | `Scalar` | `Field` |

`Field` | `Scalar` | `Field` |

`Group` | `Scalar` | `Field` |

`I8` | `Scalar` | `Field` |

`I16` | `Scalar` | `Field` |

`I32` | `Scalar` | `Field` |

`I64` | `Scalar` | `Field` |

`I128` | `Scalar` | `Field` |

`U8` | `Scalar` | `Field` |

`U16` | `Scalar` | `Field` |

`U32` | `Scalar` | `Field` |

`U64` | `Scalar` | `Field` |

`U128` | `Scalar` | `Field` |

`Scalar` | `Scalar` | `Field` |

`String` | `Scalar` | `Field` |

`Interface` | `Scalar` | `Field` |

`BHP1024::commit`

`let a: i128 = 1i128;`

let b: field = BHP1024::commit(a, 1scalar);

#### Description

Computes a BHP commitment on inputs of 1024-bit chunks in `first`

, and some randomness in `second`

, storing the commitment in `destination`

. Randomness should always be a `Scalar`

value, and the produced commitment will always be a `Field`

value.

The instruction will halt if the given input is smaller than 171 bits.

#### Supported Types

First | Second | Destination |
---|---|---|

`Address` | `Scalar` | `Field` |

`Boolean` | `Scalar` | `Field` |

`Field` | `Scalar` | `Field` |

`Group` | `Scalar` | `Field` |

`I8` | `Scalar` | `Field` |

`I16` | `Scalar` | `Field` |

`I32` | `Scalar` | `Field` |

`I64` | `Scalar` | `Field` |

`I128` | `Scalar` | `Field` |

`U8` | `Scalar` | `Field` |

`U16` | `Scalar` | `Field` |

`U32` | `Scalar` | `Field` |

`U64` | `Scalar` | `Field` |

`U128` | `Scalar` | `Field` |

`Scalar` | `Scalar` | `Field` |

`String` | `Scalar` | `Field` |

`Interface` | `Scalar` | `Field` |

`Pedersen64::commit`

`let a: i64 = 1i64;`

let b: group = Pedersen64::commit(a, 1scalar);

#### Description

Computes a Pedersen commitment up to a 64-bit input in `first`

, and some randomness in `second`

, storing the commitment in `destination`

. Randomness should always be a `Scalar`

value, and the produced commitment will always be a `Group`

value.

The instruction will halt if the given `String`

or `Interface`

value exceeds the 64-bit limit.

#### Supported Types

First | Second | Destination |
---|---|---|

`Boolean` | `Scalar` | `Group` |

`I8` | `Scalar` | `Group` |

`I16` | `Scalar` | `Group` |

`I32` | `Scalar` | `Group` |

`I64` | `Scalar` | `Group` |

`U8` | `Scalar` | `Group` |

`U16` | `Scalar` | `Group` |

`U32` | `Scalar` | `Group` |

`U64` | `Scalar` | `Group` |

`String` | `Scalar` | `Group` |

`Interface` | `Scalar` | `Group` |

`Pedersen128::commit`

`let a: i128 = 1i128;`

let b: group = Pedersen128::commit(a, 1scalar);

#### Description

Computes a Pedersen commitment up to a 128-bit input in `first`

, and some randomness in `second`

, storing the commitment in `destination`

. Randomness should always be a `Scalar`

value, and the produced commitment will always be a `Group`

value.

The instruction will halt if the given `String`

or `Interface`

value exceeds the 128-bit limit.

#### Supported Types

First | Second | Destination |
---|---|---|

`Boolean` | `Scalar` | `Group` |

`I8` | `Scalar` | `Group` |

`I16` | `Scalar` | `Group` |

`I32` | `Scalar` | `Group` |

`I64` | `Scalar` | `Group` |

`I128` | `Scalar` | `Group` |

`U8` | `Scalar` | `Group` |

`U16` | `Scalar` | `Group` |

`U32` | `Scalar` | `Group` |

`U64` | `Scalar` | `Group` |

`U128` | `Scalar` | `Group` |

`String` | `Scalar` | `Group` |

`Interface` | `Scalar` | `Group` |

`div`

`let a: u8 = 4u8;`

let b: u8 = a / 2u8; // 2u8

let c: u8 = b.div(2u8); // 1u8

#### Description

Divides `first`

by `second`

, storing the outcome in `destination`

. Halts on division by zero.

For integer types, this operation performs truncated division. Furthermore, a constraint is added to check for underflow. This underflow happens when dividing the minimum value of a signed integer type by `-1`

. For example, `div -128i8 -1i8`

would result in underflow, since `128`

cannot be represented as an `i8`

.

For cases where wrapping semantics are needed for integer types, see the div_wrapped instruction.

#### Supported Types

First | Second | Destination |
---|---|---|

`Field` | `Field` | `Field` |

`I8` | `I8` | `I8` |

`I16` | `I16` | `I16` |

`I32` | `I32` | `I32` |

`I64` | `I64` | `I64` |

`I128` | `I128` | `I128` |

`U8` | `U8` | `U8` |

`U16` | `U16` | `U16` |

`U32` | `U32` | `U32` |

`U64` | `U64` | `U64` |

`U128` | `U128` | `U128` |

`div_wrapped`

`let a: i8 = -128i8;`

let b: i8 = a.div_wrapped(-1i8); // -128i8

#### Description

Divides `first`

by `second`

, wrapping around at the boundary of the type, and storing the outcome in `destination`

.

#### Supported Types

First | Second | Destination |
---|---|---|

`I8` | `I8` | `I8` |

`I16` | `I16` | `I16` |

`I32` | `I32` | `I32` |

`I64` | `I64` | `I64` |

`I128` | `I128` | `I128` |

`U8` | `U8` | `U8` |

`U16` | `U16` | `U16` |

`U32` | `U32` | `U32` |

`U64` | `U64` | `U64` |

`U128` | `U128` | `U128` |

`double`

`let a: group = (0, 4)group;`

let b: group = a.double();

#### Description

Doubles the input, storing the outcome in `destination`

.

#### Supported Types

Input | Destination |
---|---|

`Field` | `Field` |

`Group` | `Group` |

`gt`

`let a: bool = 2u8 > 1u8; // true`

let b: bool = 1u8.gt(1u8); // false

#### Description

Checks if `first`

is greater than `second`

, storing the result in `destination`

.

#### Supported Types

First | Second | Destination |
---|---|---|

`Field` | `Field` | `Boolean` |

`I8` | `I8` | `Boolean` |

`I16` | `I16` | `Boolean` |

`I32` | `I32` | `Boolean` |

`I64` | `I64` | `Boolean` |

`I128` | `I128` | `Boolean` |

`U8` | `U8` | `Boolean` |

`U16` | `U16` | `Boolean` |

`U32` | `U32` | `Boolean` |

`U64` | `U64` | `Boolean` |

`U128` | `U128` | `Boolean` |

`Scalar` | `Scalar` | `Boolean` |

<!-- | `Address` | `Address` |

`gte`

`let a: bool = 2u8 >= 1u8; // true`

let b: bool = 1u8.gte(1u8); // true

#### Description

Checks if `first`

is greater than or equal to `second`

, storing the result in `destination`

.

#### Supported Types

First | Second | Destination |
---|---|---|

`Field` | `Field` | `Boolean` |

`I8` | `I8` | `Boolean` |

`I16` | `I16` | `Boolean` |

`I32` | `I32` | `Boolean` |

`I64` | `I64` | `Boolean` |

`I128` | `I128` | `Boolean` |

`U8` | `U8` | `Boolean` |

`U16` | `U16` | `Boolean` |

`U32` | `U32` | `Boolean` |

`U64` | `U64` | `Boolean` |

`U128` | `U128` | `Boolean` |

`Scalar` | `Scalar` | `Boolean` |

<!-- | `Address` | `Address` |

`BHP256::hash`

`let a: address = aleo10qerras5799u6k7rjtc9y3hcwxuykr45qra7x7dp6jgnc0923czqm0lgta;`

let b: field = BHP256::hash(a);

#### Description

Computes a BHP hash on inputs of 256-bit chunks in `first`

, storing the hash in `destination`

. The produced hash will always be a `Field`

value.

The instruction will halt if the given input is smaller than 129 bits.

#### Supported Types

First | Destination |
---|---|

`Address` | `Field` |

`Boolean` | `Field` |

`Field` | `Field` |

`Group` | `Field` |

`I8` | `Field` |

`I16` | `Field` |

`I32` | `Field` |

`I64` | `Field` |

`I128` | `Field` |

`U8` | `Field` |

`U16` | `Field` |

`U32` | `Field` |

`U64` | `Field` |

`U128` | `Field` |

`Scalar` | `Field` |

`String` | `Field` |

`Interface` | `Field` |

`BHP512::hash`

`let a: address = aleo10qerras5799u6k7rjtc9y3hcwxuykr45qra7x7dp6jgnc0923czqm0lgta;`

let b: field = BHP512::hash(a);

#### Description

Computes a BHP hash on inputs of 512-bit chunks in `first`

, storing the hash in `destination`

. The produced hash will always be a `Field`

value.

The instruction will halt if the given input is smaller than 171 bits.

#### Supported Types

First | Destination |
---|---|

`Address` | `Field` |

`Boolean` | `Field` |

`Field` | `Field` |

`Group` | `Field` |

`I8` | `Field` |

`I16` | `Field` |

`I32` | `Field` |

`I64` | `Field` |

`I128` | `Field` |

`U8` | `Field` |

`U16` | `Field` |

`U32` | `Field` |

`U64` | `Field` |

`U128` | `Field` |

`Scalar` | `Field` |

`String` | `Field` |

`Interface` | `Field` |

`BHP768::hash`

`let a: address = aleo10qerras5799u6k7rjtc9y3hcwxuykr45qra7x7dp6jgnc0923czqm0lgta;`

let b: field = BHP768::hash(a);

#### Description

Computes a BHP hash on inputs of 768-bit chunks in `first`

, storing the hash in `destination`

. The produced hash will always be a `Field`

value.

The instruction will halt if the given input is smaller than 129 bits.

#### Supported Types

First | Destination |
---|---|

`Address` | `Field` |

`Boolean` | `Field` |

`Field` | `Field` |

`Group` | `Field` |

`I8` | `Field` |

`I16` | `Field` |

`I32` | `Field` |

`I64` | `Field` |

`I128` | `Field` |

`U8` | `Field` |

`U16` | `Field` |

`U32` | `Field` |

`U64` | `Field` |

`U128` | `Field` |

`Scalar` | `Field` |

`String` | `Field` |

`Interface` | `Field` |

`BHP1024::hash`

`let a: address = aleo10qerras5799u6k7rjtc9y3hcwxuykr45qra7x7dp6jgnc0923czqm0lgta;`

let b: field = BHP1024::hash(a);

#### Description

Computes a BHP hash on inputs of 1024-bit chunks in `first`

, storing the hash in `destination`

. The produced hash will always be a `Field`

value.

The instruction will halt if the given input is smaller than 171 bits.

#### Supported Types

First | Destination |
---|---|

`Address` | `Field` |

`Boolean` | `Field` |

`Field` | `Field` |

`Group` | `Field` |

`I8` | `Field` |

`I16` | `Field` |

`I32` | `Field` |

`I64` | `Field` |

`I128` | `Field` |

`U8` | `Field` |

`U16` | `Field` |

`U32` | `Field` |

`U64` | `Field` |

`U128` | `Field` |

`Scalar` | `Field` |

`String` | `Field` |

`Interface` | `Field` |

`Pedersen64::hash`

`let a: field = Pedersen64::hash(1u64);`

#### Description

Computes a Pedersen hash up to a 64-bit input in `first`

, storing the hash in `destination`

. The produced hash will always be a `Field`

value.

The instruction will halt if the given `String`

or `Interface`

value exceeds the 64-bit limit.

#### Supported Types

First | Destination |
---|---|

`Boolean` | `Field` |

`I8` | `Field` |

`I16` | `Field` |

`I32` | `Field` |

`I64` | `Field` |

`U8` | `Field` |

`U16` | `Field` |

`U32` | `Field` |

`U64` | `Field` |

`String` | `Field` |

`Interface` | `Field` |

`Pedersen128::hash`

`let a: field = Pedersen64::hash(1u64);`

#### Description

Computes a Pedersen hash up to a 128-bit input in `first`

, storing the hash in `destination`

. The produced hash will always be a `Field`

value.

The instruction will halt if the given `String`

or `Interface`

value exceeds the 128-bit limit.

#### Supported Types

First | Destination |
---|---|

`Boolean` | `Field` |

`I8` | `Field` |

`I16` | `Field` |

`I32` | `Field` |

`I64` | `Field` |

`I128` | `Field` |

`U8` | `Field` |

`U16` | `Field` |

`U32` | `Field` |

`U64` | `Field` |

`U128` | `Field` |

`String` | `Field` |

`Interface` | `Field` |

`Poseidon2::hash`

`let a: field = Poseidon2::hash(1u128);`

#### Description

Calculates a Poseidon hash with an input rate of 2, from an input in `first`

, storing the hash in `destination`

. The produced hash will always be a `Field`

value.

#### Supported Types

First | Destination |
---|---|

`Field` | `Field` |

`I8` | `Field` |

`I16` | `Field` |

`I32` | `Field` |

`I64` | `Field` |

`I128` | `Field` |

`U8` | `Field` |

`U16` | `Field` |

`U32` | `Field` |

`U64` | `Field` |

`U128` | `Field` |

`Scalar` | `Field` |

`String` | `Field` |

`Interface` | `Field` |

`Poseidon4::hash`

`let a: field = Poseidon4::hash(1u128);`

#### Description

Calculates a Poseidon hash with an input rate of 4, from an input in `first`

, storing the hash in `destination`

. The produced hash will always be a `Field`

value.

#### Supported Types

First | Destination |
---|---|

`Field` | `Field` |

`I8` | `Field` |

`I16` | `Field` |

`I32` | `Field` |

`I64` | `Field` |

`I128` | `Field` |

`U8` | `Field` |

`U16` | `Field` |

`U32` | `Field` |

`U64` | `Field` |

`U128` | `Field` |

`Scalar` | `Field` |

`String` | `Field` |

`Interface` | `Field` |

`Poseidon8::hash`

`let a: field = Poseidon8::hash(1u128);`

#### Description

Calculates a Poseidon hash with an input rate of 8, from an input in `first`

, storing the hash in `destination`

. The produced hash will always be a `Field`

value.

#### Supported Types

First | Destination |
---|---|

`Field` | `Field` |

`I8` | `Field` |

`I16` | `Field` |

`I32` | `Field` |

`I64` | `Field` |

`I128` | `Field` |

`U8` | `Field` |

`U16` | `Field` |

`U32` | `Field` |

`U64` | `Field` |

`U128` | `Field` |

`Scalar` | `Field` |

`String` | `Field` |

`Interface` | `Field` |

`inv`

`let a: field = 1field.inv();`

#### Description

Computes the multiplicative inverse of the input, storing the outcome in `destination`

.

#### Supported Types

Input | Destination |
---|---|

`Field` | `Field` |

`eq`

`let a: bool = 1u8 == 1u8; // true`

let b: bool = 1u8.eq(2u8); // false

#### Description

Compares `first`

and `second`

, storing the result in `destination`

.

#### Supported Types

First | Second | Destination |
---|---|---|

`Address` | `Address` | `Address` |

`Boolean` | `Boolean` | `Boolean` |

`Field` | `Field` | `Field` |

`Group` | `Group` | `Group` |

`I8` | `I8` | `I8` |

`I16` | `I16` | `I16` |

`I32` | `I32` | `I32` |

`I64` | `I64` | `I64` |

`I128` | `I128` | `I128` |

`U8` | `U8` | `U8` |

`U16` | `U16` | `U16` |

`U32` | `U32` | `U32` |

`U64` | `U64` | `U64` |

`U128` | `U128` | `U128` |

`Scalar` | `Scalar` | `Scalar` |

`Interface` | `Interface` | `Interface` |

`Record` | `Record` | `Record` |

`neq`

`let a: bool = 1u8 != 1u8; // false`

let b: bool = 1u8.neq(2u8); // true

#### Description

Returns true if `first`

is not equal to `second`

, storing the result in `destination`

.

#### Supported Types

First | Second | Destination |
---|---|---|

`Address` | `Address` | `Address` |

`Boolean` | `Boolean` | `Boolean` |

`Field` | `Field` | `Field` |

`Group` | `Group` | `Group` |

`I8` | `I8` | `I8` |

`I16` | `I16` | `I16` |

`I32` | `I32` | `I32` |

`I64` | `I64` | `I64` |

`I128` | `I128` | `I128` |

`U8` | `U8` | `U8` |

`U16` | `U16` | `U16` |

`U32` | `U32` | `U32` |

`U64` | `U64` | `U64` |

`U128` | `U128` | `U128` |

`Scalar` | `Scalar` | `Scalar` |

`Interface` | `Interface` | `Interface` |

`Record` | `Record` | `Record` |

`lt`

`let a: bool = 1u8 < 2u8; // true`

let b: bool = 1u8.lt(1u8); // false

#### Description

Checks if `first`

is less than `second`

, storing the outcome in `destination`

.

#### Supported Types

First | Second | Destination |
---|---|---|

`Field` | `Field` | `Boolean` |

`I8` | `I8` | `Boolean` |

`I16` | `I16` | `Boolean` |

`I32` | `I32` | `Boolean` |

`I64` | `I64` | `Boolean` |

`I128` | `I128` | `Boolean` |

`U8` | `U8` | `Boolean` |

`U16` | `U16` | `Boolean` |

`U32` | `U32` | `Boolean` |

`U64` | `U64` | `Boolean` |

`U128` | `U128` | `Boolean` |

`Scalar` | `Scalar` | `Boolean` |

<!-- | `Address` | `Address` |

`lte`

`let a: bool = 1u8 <= 2u8; // true`

let b: bool = 1u8.lte(1u8); // true

#### Description

Checks if `first`

is less than or equal to `second`

, storing the outcome in `destination`

.

#### Supported Types

First | Second | Destination |
---|---|---|

`Field` | `Field` | `Boolean` |

`I8` | `I8` | `Boolean` |

`I16` | `I16` | `Boolean` |

`I32` | `I32` | `Boolean` |

`I64` | `I64` | `Boolean` |

`I128` | `I128` | `Boolean` |

`U8` | `U8` | `Boolean` |

`U16` | `U16` | `Boolean` |

`U32` | `U32` | `Boolean` |

`U64` | `U64` | `Boolean` |

`U128` | `U128` | `Boolean` |

`Scalar` | `Scalar` | `Boolean` |

<!-- | `Address` | `Address` |

`mod`

`let a: u8 = 3u8.mod(2u8); // 1u8`

#### Description

Takes the modulus of `first`

with respect to `second`

, storing the outcome in `destination`

. Halts if `second`

is zero.

The semantics of this operation are consistent with the mathematical definition of modulo operation.

#### Supported Types

First | Second | Destination |
---|---|---|

`U8` | `U8` | `U8` |

`U16` | `U16` | `U16` |

`U32` | `U32` | `U32` |

`U64` | `U64` | `U64` |

`U128` | `U128` | `U128` |

`mul`

`let a: u8 = 2u8 * 2u8; // 4u8`

let b: u8 = a.mul(2u8); // 8u8

#### Description

Multiplies `first`

with `second`

, storing the outcome in `destination`

.

For integer types, a constraint is added to check for overflow/underflow. For cases where wrapping semantics are needed for integer types, see the mul_wrapped instruction.

#### Supported Types

First | Second | Destination |
---|---|---|

`Field` | `Field` | `Field` |

`Group` | `Scalar` | `Group` |

`Scalar` | `Group` | `Group` |

`I8` | `I8` | `I8` |

`I16` | `I16` | `I16` |

`I32` | `I32` | `I32` |

`I64` | `I64` | `I64` |

`I128` | `I128` | `I128` |

`U8` | `U8` | `U8` |

`U16` | `U16` | `U16` |

`U32` | `U32` | `U32` |

`U64` | `U64` | `U64` |

`U128` | `U128` | `U128` |

`mul_wrapped`

`let a: u8 = 128u8.mul_wrapped(2u8); // 0u8`

#### Description

Multiplies `first`

with `second`

, wrapping around at the boundary of the type, and storing the outcome in `destination`

.

#### Supported Types

First | Second | Destination |
---|---|---|

`I8` | `I8` | `I8` |

`I16` | `I16` | `I16` |

`I32` | `I32` | `I32` |

`I64` | `I64` | `I64` |

`I128` | `I128` | `I128` |

`U8` | `U8` | `U8` |

`U16` | `U16` | `U16` |

`U32` | `U32` | `U32` |

`U64` | `U64` | `U64` |

`U128` | `U128` | `U128` |

`nand`

`let a: bool = true.nand(false); // true`

#### Description

Returns false only if `first`

and `second`

are true, storing the outcome in `destination`

.

#### Supported Types

First | Second | Destination |
---|---|---|

`Boolean` | `Boolean` | `Boolean` |

`neg`

`let a: i8 = -1i8.neg(); // 1i8`

#### Description

Negates `first`

, storing the outcome in `destination`

.

For signed integer types, calling `neg`

on the minimum value is an invalid operation. For example, the input `-128i8`

would not be valid since `128`

cannot be represented as an `i8`

.

#### Supported Types

Input | Destination |
---|---|

`Field` | `Field` |

`Group` | `Group` |

`I8` | `I8` |

`I16` | `I16` |

`I32` | `I32` |

`I64` | `I64` |

`I128` | `I128` |

`nor`

`let a: bool = false.nor(false); // true`

#### Description

Returns true when neither `first`

nor `second`

is true, storing the outcome in `destination`

.

#### Supported Type

First | Second | Destination |
---|---|---|

`Boolean` | `Boolean` | `Boolean` |

`not`

`let a: bool = true.not(); // false`

#### Description

Perform a NOT operation on an integer (bitwise) or boolean input, storing the outcome in `destination`

.

#### Supported Types

Input | Destination |
---|---|

`Boolean` | `Boolean` |

`I8` | `I8` |

`I16` | `I16` |

`I32` | `I32` |

`I64` | `I64` |

`I128` | `I128` |

`U8` | `U8` |

`U16` | `U16` |

`U32` | `U32` |

`U64` | `U64` |

`U128` | `U128` |

### or

`let a: bool = true || false; // true`

let b: bool = false.or(false); // false

#### Description

Performs an OR operation on integer (bitwise) or boolean `first`

and `second`

, storing the outcome in `destination`

.

#### Supported Types

First | Second | Destination |
---|---|---|

`Boolean` | `Boolean` | `Boolean` |

`I8` | `I8` | `I8` |

`I16` | `I16` | `I16` |

`I32` | `I32` | `I32` |

`I64` | `I64` | `I64` |

`I128` | `I128` | `I128` |

`U8` | `U8` | `U8` |

`U16` | `U16` | `U16` |

`U32` | `U32` | `U32` |

`U64` | `U64` | `U64` |

`U128` | `U128` | `U128` |

`pow`

`let a: u8 = 2u8 ** 2u8; // 4u8`

let b: u8 = b.pow(2u8); // 16u8

#### Description

Raises `first`

to the power of `second`

, storing the outcome in `destination`

.

For integer types, a constraint is added to check for overflow/underflow. For cases where wrapping semantics are needed for integer types, see the pow_wrapped instruction.

#### Supported Types

`Magnitude`

can be a `U8`

, `U16`

, or `U32`

.

First | Second | Destination |
---|---|---|

`Field` | `Field` | `Field` |

`I8` | `Magnitude` | `I8` |

`I16` | `Magnitude` | `I16` |

`I32` | `Magnitude` | `I32` |

`I64` | `Magnitude` | `I64` |

`I128` | `Magnitude` | `I128` |

`U8` | `Magnitude` | `U8` |

`U16` | `Magnitude` | `U16` |

`U32` | `Magnitude` | `U32` |

`U64` | `Magnitude` | `U64` |

`U128` | `Magnitude` | `U128` |

`pow_wrapped`

`let a: u8 = 16u8 ** 2u8; // 0u8`

#### Description

Raises `first`

to the power of `second`

, wrapping around at the boundary of the type, storing the outcome in `destination`

.

#### Supported Types

`Magnitude`

can be a `U8`

, `U16`

, or `U32`

.

First | Second | Destination |
---|---|---|

`I8` | `Magnitude` | `I8` |

`I16` | `Magnitude` | `I16` |

`I32` | `Magnitude` | `I32` |

`I64` | `Magnitude` | `I64` |

`I128` | `Magnitude` | `I128` |

`U8` | `Magnitude` | `U8` |

`U16` | `Magnitude` | `U16` |

`U32` | `Magnitude` | `U32` |

`U64` | `Magnitude` | `U64` |

`U128` | `Magnitude` | `U128` |

`rem`

`let a: u8 = 3u8 % 2u8; // 1u8`

let b: u8 = 4u8.rem(2u8); // 0u8

#### Description

Computes the truncated remainder of `first`

divided by `second`

, storing the outcome in `destination`

. Halts on division by zero.

A constraint is added to check for underflow. This underflow happens when the associated division operation, div, underflows.

For cases where wrapping semantics are needed for integer types, see the rem_wrapped instruction.

#### Supported Types

First | Second | Destination |
---|---|---|

`I8` | `I8` | `I8` |

`I16` | `I16` | `I16` |

`I32` | `I32` | `I32` |

`I64` | `I64` | `I64` |

`I128` | `I128` | `I128` |

`U8` | `U8` | `U8` |

`U16` | `U16` | `U16` |

`U32` | `U32` | `U32` |

`U64` | `U64` | `U64` |

`U128` | `U128` | `U128` |

`rem_wrapped`

`let a: i128 = -128i8;`

let b: i128 = a.rem_wrapped(-1i8); // 0i8

#### Description

Computes the truncated remainder of `first`

divided by `second`

, wrapping around at the boundary of the type, and storing the outcome in destination.

#### Supported Types

First | Second | Destination |
---|---|---|

`I8` | `I8` | `I8` |

`I16` | `I16` | `I16` |

`I32` | `I32` | `I32` |

`I64` | `I64` | `I64` |

`I128` | `I128` | `I128` |

`U8` | `U8` | `U8` |

`U16` | `U16` | `U16` |

`U32` | `U32` | `U32` |

`U64` | `U64` | `U64` |

`U128` | `U128` | `U128` |

`shl`

`let a: u8 = 1u8 << 1u8; // 2u8`

let b: u8 = a.shl(1u8); // 4u8

#### Description

Shifts `first`

left by `second`

bits, storing the outcome in `destination`

.

#### Supported Types

`Magnitude`

can be a `U8`

, `U16`

, or `U32`

.

First | Second | Destination |
---|---|---|

`I8` | `Magnitude` | `I8` |

`I16` | `Magnitude` | `I16` |

`I32` | `Magnitude` | `I32` |

`I64` | `Magnitude` | `I64` |

`I128` | `Magnitude` | `I128` |

`U8` | `Magnitude` | `U8` |

`U16` | `Magnitude` | `U16` |

`U32` | `Magnitude` | `U32` |

`U64` | `Magnitude` | `U64` |

`U128` | `Magnitude` | `U128` |

`shl_wrapped`

`let a: u8 = 128u8.shl_wrapped(1u8); // 0u8`

#### Description

Shifts `first`

left by `second`

bits, wrapping around at the boundary of the type, storing the outcome in `destination`

.

#### Supported Types

`Magnitude`

can be a `U8`

, `U16`

, or `U32`

.

First | Second | Destination |
---|---|---|

`I8` | `Magnitude` | `I8` |

`I16` | `Magnitude` | `I16` |

`I32` | `Magnitude` | `I32` |

`I64` | `Magnitude` | `I64` |

`I128` | `Magnitude` | `I128` |

`U8` | `Magnitude` | `U8` |

`U16` | `Magnitude` | `U16` |

`U32` | `Magnitude` | `U32` |

`U64` | `Magnitude` | `U64` |

`U128` | `Magnitude` | `U128` |

`shr`

`let a: u8 = 4u8 >> 1u8; // 2u8 `

let b: u8 = a.shr(1u8); // 1u8

#### Description

Shifts `first`

right by `second`

bits, storing the outcome in `destination`

.

#### Supported Types

`Magnitude`

can be a `U8`

, `U16`

, or `U32`

.

First | Second | Destination |
---|---|---|

`I8` | `Magnitude` | `I8` |

`I16` | `Magnitude` | `I16` |

`I32` | `Magnitude` | `I32` |

`I64` | `Magnitude` | `I64` |

`I128` | `Magnitude` | `I128` |

`U8` | `Magnitude` | `U8` |

`U16` | `Magnitude` | `U16` |

`U32` | `Magnitude` | `U32` |

`U64` | `Magnitude` | `U64` |

`U128` | `Magnitude` | `U128` |

`shr_wrapped`

`let a: u8 = 128u8.shr_wrapped(7u8); // 1u8`

#### Description

Shifts `first`

right by `second`

bits, wrapping around at the boundary of the type, storing the outcome in `destination`

.

#### Supported Types

`Magnitude`

can be a `U8`

, `U16`

, or `U32`

.

First | Second | Destination |
---|---|---|

`I8` | `Magnitude` | `I8` |

`I16` | `Magnitude` | `I16` |

`I32` | `Magnitude` | `I32` |

`I64` | `Magnitude` | `I64` |

`I128` | `Magnitude` | `I128` |

`U8` | `Magnitude` | `U8` |

`U16` | `Magnitude` | `U16` |

`U32` | `Magnitude` | `U32` |

`U64` | `Magnitude` | `U64` |

`U128` | `Magnitude` | `U128` |

`square`

`let a: field = 1field.square(); // 1field`

#### Description

Squares the input, storing the outcome in `destination`

.

#### Supported Types

Input | Destination |
---|---|

`Field` | `Field` |

`square_root`

`let a: field = 1field.square_root(); // 1field`

#### Description

Computes the square root of the input, storing the outcome in `destination`

.

#### Supported Types

Input | Destination |
---|---|

`Field` | `Field` |

`sub`

`let a: u8 = 2u8 - 1u8; // 1u8`

let b: u8 = a.sub(1u8); // 0u8

#### Description

Computes `first - second`

, storing the outcome in `destination`

.

#### Supported Types

First | Second | Destination |
---|---|---|

`Field` | `Field` | `Field` |

`Group` | `Group` | `Group` |

`I8` | `I8` | `I8` |

`I16` | `I16` | `I16` |

`I32` | `I32` | `I32` |

`I64` | `I64` | `I64` |

`I128` | `I128` | `I128` |

`U8` | `U8` | `U8` |

`U16` | `U16` | `U16` |

`U32` | `U32` | `U32` |

`U64` | `U64` | `U64` |

`U128` | `U128` | `U128` |

`sub_wrapped`

`let a: u8 = 0u8.sub_wrapped(1u8); // 255u8`

#### Description

Computes `first - second`

, wrapping around at the boundary of the type, and storing the outcome in `destination`

.

#### Supported Types

First | Second | Destination |
---|---|---|

`I8` | `I8` | `I8` |

`I16` | `I16` | `I16` |

`I32` | `I32` | `I32` |

`I64` | `I64` | `I64` |

`I128` | `I128` | `I128` |

`U8` | `U8` | `U8` |

`U16` | `U16` | `U16` |

`U32` | `U32` | `U32` |

`U64` | `U64` | `U64` |

`U128` | `U128` | `U128` |

`ternary`

`let a: u8 = true ? 1u8 : 2u8; // 1u8`

#### Description

Selects `first`

, if `condition`

is true, otherwise selects `second`

, storing the result in `destination`

.

#### Supported Types

Condition | First | Second | Destination |
---|---|---|---|

`Boolean` | `Boolean` | `Boolean` | `Boolean` |

`Boolean` | `Field` | `Field` | `Field` |

`Boolean` | `Group` | `Group` | `Group` |

`Boolean` | `I8` | `I8` | `I8` |

`Boolean` | `I16` | `I16` | `I16` |

`Boolean` | `I32` | `I32` | `I32` |

`Boolean` | `I64` | `I64` | `I64` |

`Boolean` | `I128` | `I128` | `I128` |

`Boolean` | `U8` | `U8` | `U8` |

`Boolean` | `U16` | `U16` | `U16` |

`Boolean` | `U32` | `U32` | `U32` |

`Boolean` | `U64` | `U64` | `U64` |

`Boolean` | `U128` | `U128` | `U128` |

`Boolean` | `Scalar` | `Scalar` | `Scalar` |

`xor`

`let a: bool = true.xor(false); // true`

#### Description

Performs a XOR operation on integer (bitwise) or boolean `first`

and `second`

, storing the outcome in `destination`

.

#### Supported Types

First | Second | Destination |
---|---|---|

`Boolean` | `Boolean` | `Boolean` |

`I8` | `I8` | `I8` |

`I16` | `I16` | `I16` |

`I32` | `I32` | `I32` |

`I64` | `I64` | `I64` |

`I128` | `I128` | `I128` |

`U8` | `U8` | `U8` |

`U16` | `U16` | `U16` |

`U32` | `U32` | `U32` |

`U64` | `U64` | `U64` |

`U128` | `U128` | `U128` |