Skip to main content

Standard Operators

Table of Contents

NameDescription
absAbsolute value
abs_wrappedWrapping absolute value
addAddition
add_wrappedWrapping addition
andConjunction
assertAssert boolean true
assert_eqAssert equality
assert_neqAssert non-equality
block.heightFetch the latest block height
block.timestampFetch the latest block timestamp
Deserialize:from_bits::[TYPE]Deserialize bits to a data type
divDivision
div_wrappedWrapping division operation
doubleDouble
group::GENgroup generator
Aleo::generatorAleo group generator constant
Aleo::generator_powersPrecomputed Aleo generator powers [group; 251]
gtGreater than comparison
gteGreater than or equal to comparison
invMultiplicative inverse
eqEquality comparison
neqNon-equality comparison
ltLess than comparison
lteLess than or equal to comparison
modModulo
mulMultiplication
mul_wrappedWrapping multiplication
nandNegated conjunction
negAdditive inverse
norNegated disjunction
notLogical negation
or(Inclusive) disjunction
powExponentiation
pow_wrappedWrapping exponentiation
remRemainder
rem_wrappedWrapping remainder
Program::checksumChecksum of another (imported) program
Program::editionEdition (version) of another (imported) program
Program::program_ownerDeployer address of another (imported) program
self.addressAddress of the current program
self.callerAddress of the calling user/program
self.checksumChecksum of a program
self.editionVersion number of a program
self.idAddress of the current program (alias of self.address)
self.program_ownerAddress that submitted a program's deployment transaction
self.signerAddress of the top-level calling user
Serialize::to_bitsSerialize data to bits
shlShift left
shl_wrappedWrapping shift left
shrShift right
shr_wrappedWrapping shift right
square_rootSquare root
squareSquare
subSubtraction
sub_wrappedWrapping subtraction
ternaryTernary select
to_x_coordinateExtract x-coordinate of a group element
to_y_coordinateExtract y-coordinate of a group element
xorExclusive conjunction

Arithmetic Operators

abs

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

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

Note that execution will halt if the operation overflows. For cases where wrapping semantics are needed, see the abs_wrapped instruction. This overflow happens when the input is the minimum value of a signed integer type. For example, abs -128i8 would result in overflow, since 128 cannot be represented as an i8.

Supported Types

InputDestination
i8i8
i16i16
i32i32
i64i64
i128i128

Back to Top


abs_wrapped

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

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

Supported Types

InputDestination
i8i8
i16i16
i32i32
i64i64
i128i128

Back to Top


add

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

Adds first with second, storing the result in destination.

Note that execution will halt if the operation overflows. For cases where wrapping semantics are needed for integer types, see the add_wrapped instruction.

Supported Types

FirstSecondDestination
fieldfieldfield
groupgroupgroup
i8i8i8
i16i16i16
i32i32i32
i64i64i64
i128i128i128
u8u8u8
u16u16u16
u32u32u32
u64u64u64
u128u128u128
scalarscalarscalar

Back to Top


add_wrapped

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

Adds first with second, wrapping around at the boundary of the type, and storing the result in destination.

Supported Types

FirstSecondDestination
i8i8i8
i16i16i16
i32i32i32
i64i64i64
i128i128i128
u8u8u8
u16u16u16
u32u32u32
u64u64u64
u128u128u128

Back to Top


div

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

Performs division of the first operand by the second, storing the result in the destination. The operation halts if division by zero is attempted.

For integer types, this operation performs truncated division. Truncated division rounds towards zero, regardless of the sign of the operands. This means it cuts off any digits after the decimal, leaving the whole number whose absolute value is less than or equal to the result.

For example:

  • 7 / 3 yields 2, not 2.3333.
  • -7 / 3 yields -2, not -2.3333.

The operation halts if there is an underflow. Underflow occurs when dividing the minimum value of a signed integer type by -1. For example, -128i8 / -1i8 would result in underflow, since 128 cannot be represented as an i8.

For field types, division a / b is well-defined for any field values a and b except when b = 0field.

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

Supported Types

FirstSecondDestination
fieldfieldfield
i8i8i8
i16i16i16
i32i32i32
i64i64i64
i128i128i128
u8u8u8
u16u16u16
u32u32u32
u64u64u64
u128u128u128

Back to Top


div_wrapped

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

Divides first by second, wrapping around at the boundary of the type, and storing the result in destination. Halts if second is zero.

Supported Types

FirstSecondDestination
i8i8i8
i16i16i16
i32i32i32
i64i64i64
i128i128i128
u8u8u8
u16u16u16
u32u32u32
u64u64u64
u128u128u128

Back to Top


mod

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

Takes the modulo of first with respect to second, storing the result in destination. Halts if second is zero.

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

mod ensures the remainder has the same sign as the second operand. This differs from rem, which follows truncated division and takes the sign of the first operand.

Supported Types

FirstSecondDestination
u8u8u8
u16u16u16
u32u32u32
u64u64u64
u128u128u128

Back to Top


mul

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

Multiplies first with second, storing the result in destination.

Note that execution will halt if the operation overflows/underflows. For cases where wrapping semantics are needed for integer types, see the mul_wrapped instruction.

Supported Types

FirstSecondDestination
fieldfieldfield
groupscalargroup
scalargroupgroup
i8i8i8
i16i16i16
i32i32i32
i64i64i64
i128i128i128
u8u8u8
u16u16u16
u32u32u32
u64u64u64
u128u128u128

Back to Top


mul_wrapped

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

Multiplies first with second, wrapping around at the boundary of the type, and storing the result in destination.

Supported Types

FirstSecondDestination
i8i8i8
i16i16i16
i32i32i32
i64i64i64
i128i128i128
u8u8u8
u16u16u16
u32u32u32
u64u64u64
u128u128u128

Back to Top


neg

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

Negates the first operand, storing the result in the destination.

For signed integer types, the operation halts if the minimum value is negated. For example, -128i8.neg() halts since 128 cannot be represented as an i8.

Supported Types

InputDestination
fieldfield
groupgroup
i8i8
i16i16
i32i32
i64i64
i128i128

Back to Top


pow

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

Raises first to the power of second, storing the result in destination.

Note that execution will halt if the operation overflows/underflows. 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.

FirstSecondDestination
fieldfieldfield
i8Magnitudei8
i16Magnitudei16
i32Magnitudei32
i64Magnitudei64
i128Magnitudei128
u8Magnitudeu8
u16Magnitudeu16
u32Magnitudeu32
u64Magnitudeu64
u128Magnitudeu128

Back to Top


pow_wrapped

let a: u8 = 16u8.pow_wrapped(2u8); // 0u8

Raises first to the power of second, wrapping around at the boundary of the type, storing the result in destination.

Supported Types

Magnitude can be a u8, u16, or u32.

FirstSecondDestination
i8Magnitudei8
i16Magnitudei16
i32Magnitudei32
i64Magnitudei64
i128Magnitudei128
u8Magnitudeu8
u16Magnitudeu16
u32Magnitudeu32
u64Magnitudeu64
u128Magnitudeu128

Back to Top


rem

let a: u8 = 3u8 % 2u8; // 1u8
let b: u8 = 4u8.rem(2u8); // 0u8

Computes the remainder of the division of the first operand by the second, storing the result in destination following truncated division rules:

a and b refers to first and second respectively

a % b = a - (a / b) * b

Here, a and b refer to the first and second operands, respectively

Note that execution will halt if the operation underflows or divides by zero. 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.

rem follows truncated division, meaning the remainder has the same sign as a. This differs from mod, where the remainder matches the sign of b.

Supported Types

FirstSecondDestination
i8i8i8
i16i16i16
i32i32i32
i64i64i64
i128i128i128
u8u8u8
u16u16u16
u32u32u32
u64u64u64
u128u128u128

Back to Top


rem_wrapped

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

Computes the remainder of the division of the first operand by the second following truncated division rules, storing the result in destination. Halts on division by zero. Unlike rem, rem_wrapped is always defined and does not halt, even when div would wrap around.

Notably, rem_wrapped does not introduce wrapping itself but ensures the operation remains defined where rem would be undefined.

Supported Types

FirstSecondDestination
i8i8i8
i16i16i16
i32i32i32
i64i64i64
i128i128i128
u8u8u8
u16u16u16
u32u32u32
u64u64u64
u128u128u128

Back to Top


sub

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

Computes first - second, storing the result in destination. The operation halts if the result is negative in an unsigned type or if it exceeds the minimum representable value in a signed type.

Supported Types

FirstSecondDestination
fieldfieldfield
groupgroupgroup
i8i8i8
i16i16i16
i32i32i32
i64i64i64
i128i128i128
u8u8u8
u16u16u16
u32u32u32
u64u64u64
u128u128u128

Back to Top


sub_wrapped

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

Computes first - second, wrapping around at the boundary of the type, and storing the result in destination.

Supported Types

FirstSecondDestination
i8i8i8
i16i16i16
i32i32i32
i64i64i64
i128i128i128
u8u8u8
u16u16u16
u32u32u32
u64u64u64
u128u128u128

Back to Top


Boolean/Bitwise Operators

and

// Integer (bitwise) AND
let a: i8 = 1i8 & 1i8;
let b: i8 = 1i8.and(2i8);

// Boolean (logical) AND
let c: bool = true && true;
let d: bool = true.and(false);

Performs an AND operation on integer (bitwise) or boolean first and second, storing the result in destination.

Supported Types

FirstSecondDestination
boolboolbool
i8i8i8
i16i16i16
i32i32i32
i64i64i64
i128i128i128
u8u8u8
u16u16u16
u32u32u32
u64u64u64
u128u128u128

Back to Top


nand

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

Calculates the negated conjunction of first and second, storing the result in destination. The result is false if and only if both first and second are true.

Supported Types

FirstSecondDestination
boolboolbool

Back to Top


nor

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

Calculates the negated (inclusive) disjunction of first and second, storing the result in destination. The result is true if and only if both first and second are false.

Supported Type

FirstSecondDestination
boolboolbool

Back to Top


not

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

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

Supported Types

InputDestination
boolbool
i8i8
i16i16
i32i32
i64i64
i128i128
u8u8
u16u16
u32u32
u64u64
u128u128

Back to Top


or

// Integer (bitwise) OR
let a: i8 = 1i8 | 2i8;
let b: i8 = 1i8.or(2i8);

// Boolean (logical) OR
let c: bool = true || true;
let d: bool = true.or(false);

Performs an inclusive OR operation on integer (bitwise) or boolean first and second, storing the result in destination.

Supported Types

FirstSecondDestination
boolboolbool
i8i8i8
i16i16i16
i32i32i32
i64i64i64
i128i128i128
u8u8u8
u16u16u16
u32u32u32
u64u64u64
u128u128u128

Back to Top


shl

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

Shifts first left by second bits, storing the result in destination. The operation halts if the shift distance exceeds the bit size of first, or if the shifted result does not fit within the type of first.

Supported Types

Magnitude can be a u8, u16, or u32.

FirstSecondDestination
i8Magnitudei8
i16Magnitudei16
i32Magnitudei32
i64Magnitudei64
i128Magnitudei128
u8Magnitudeu8
u16Magnitudeu16
u32Magnitudeu32
u64Magnitudeu64
u128Magnitudeu128

Back to Top


shl_wrapped

let a: u8 = 128u8.shl_wrapped(1u8); // 0u8
let b: i8 = 64i8.shl_wrapped(2u8); // -128i8

Shifts first left by second bits, wrapping around at the boundary of the type, storing the result in destination. The shift distance is masked to the bit width of first, ensuring that shifting by n is equivalent to shifting by n % bit_size.

If bits are shifted beyond the type's range, they are discarded, which may cause sign changes for signed integers.

Supported Types

Magnitude can be a u8, u16, or u32.

FirstSecondDestination
i8Magnitudei8
i16Magnitudei16
i32Magnitudei32
i64Magnitudei64
i128Magnitudei128
u8Magnitudeu8
u16Magnitudeu16
u32Magnitudeu32
u64Magnitudeu64
u128Magnitudeu128

Back to Top


shr

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

Shifts first right by second bits, storing the result in destination. The operation halts if the shift distance exceeds the bit size of first.

Supported Types

Magnitude can be a u8, u16, or u32.

FirstSecondDestination
i8Magnitudei8
i16Magnitudei16
i32Magnitudei32
i64Magnitudei64
i128Magnitudei128
u8Magnitudeu8
u16Magnitudeu16
u32Magnitudeu32
u64Magnitudeu64
u128Magnitudeu128

Back to Top


shr_wrapped

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

Shifts first right by second bits, wrapping around at the boundary of the type, storing the result in destination. The shift distance is masked to the bit width of first, ensuring that shifting by n is equivalent to shifting by n % bit_size.

Supported Types

Magnitude can be a u8, u16, or u32.

FirstSecondDestination
i8Magnitudei8
i16Magnitudei16
i32Magnitudei32
i64Magnitudei64
i128Magnitudei128
u8Magnitudeu8
u16Magnitudeu16
u32Magnitudeu32
u64Magnitudeu64
u128Magnitudeu128

Back to Top


xor

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

Performs a XOR operation on integer (bitwise) or boolean first and second, storing the result in destination.

Supported Types

FirstSecondDestination
boolboolbool
i8i8i8
i16i16i16
i32i32i32
i64i64i64
i128i128i128
u8u8u8
u16u16u16
u32u32u32
u64u64u64
u128u128u128

Back to Top


Comparators

gt

let a: bool = 2u8 > 1u8; // true
let b: bool = 1u8.gt(1u8); // false

Checks if first is greater than second, storing the result in destination.

Supported Types

FirstSecondDestination
fieldfieldbool
i8i8bool
i16i16bool
i32i32bool
i64i64bool
i128i128bool
u8u8bool
u16u16bool
u32u32bool
u64u64bool
u128u128bool
scalarscalarbool

Back to Top


gte

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

Checks if first is greater than or equal to second, storing the result in destination.

Supported Types

FirstSecondDestination
fieldfieldbool
i8i8bool
i16i16bool
i32i32bool
i64i64bool
i128i128bool
u8u8bool
u16u16bool
u32u32bool
u64u64bool
u128u128bool
scalarscalarbool

Back to Top


eq

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

Compares first and second for equality, storing the result in destination.

Supported Types

FirstSecondDestination
addressaddressbool
boolboolbool
fieldfieldbool
groupgroupbool
i8i8bool
i16i16bool
i32i32bool
i64i64bool
i128i128bool
u8u8bool
u16u16bool
u32u32bool
u64u64bool
u128u128bool
scalarscalarbool
SignatureSignaturebool
structstructbool
RecordRecordbool

Back to Top


neq

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

Compares first and second for non-equality, storing the result in destination.

Supported Types

FirstSecondDestination
addressaddressbool
boolboolbool
fieldfieldbool
groupgroupbool
i8i8bool
i16i16bool
i32i32bool
i64i64bool
i128i128bool
u8u8bool
u16u16bool
u32u32bool
u64u64bool
u128u128bool
scalarscalarbool
SignatureSignaturebool
structstructbool
RecordRecordbool

Back to Top


lt

let a: bool = 1u8 < 2u8; // true
let b: bool = 1u8.lt(1u8); // false

Checks if first is less than second, storing the result in destination.

Supported Types

FirstSecondDestination
fieldfieldbool
i8i8bool
i16i16bool
i32i32bool
i64i64bool
i128i128bool
u8u8bool
u16u16bool
u32u32bool
u64u64bool
u128u128bool
scalarscalarbool

Back to Top


lte

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

Checks if first is less than or equal to second, storing the result in destination.

Supported Types

FirstSecondDestination
fieldfieldbool
i8i8bool
i16i16bool
i32i32bool
i64i64bool
i128i128bool
u8u8bool
u16u16bool
u32u32bool
u64u64bool
u128u128bool
scalarscalarbool

Back to Top


Context-dependent Expressions

block.height

fn matches_height(height: u32) -> Final {
return final {
assert_eq(height, block.height);
};
}

The block.height operator is used to fetch the latest block height in a Leo program. It represents the number of blocks in the chain. In the above example, block.height is used in a final { } block to fetch the latest block height in a program.

info
  • The block.height operator can only be used in on-chain context — a final { } block, a final fn, or a constructor. It is rejected in entry fn bodies, helper fns, and constant initialisers, since chain state is only observable in the finalization context.
  • The block.height operator doesn't take any parameters.

Back to Top


block.timestamp

fn matches_timestamp(timestamp: i64) -> Final {
return final {
assert_eq(timestamp, block.timestamp);
};
}

The block.timestamp operator is used to fetch the UNIX timestamp of the latest block in a Leo program. In the above example, block.timestamp is used in a final { } block to fetch the latest block timestamp in a program.

info
  • The block.timestamp operator can only be used in on-chain context — a final { } block, a final fn, or a constructor. It is rejected in entry fn bodies, helper fns, and constant initialisers, since chain state is only observable in the finalization context.
  • The block.timestamp operator doesn't take any parameters.

Back to Top


self.address

fn get_program_address() -> address {
return self.address;
}

The self.address operator returns the address of the program that calls it. While programs are identified by their name ({PROGRAM_NAME}.aleo), under the hood they have a corresponding Aleo address.

info
  • The self.address operator may be used in any function context (entry fn, helper fn, final fn, final { } block, or constructor).
  • The self.address operator doesn't take any parameters.

Back to Top


self.caller

fn matches_caller(addr: address) -> bool {
return self.caller == addr;
}

The self.caller operator returns the address of the account/program that invoked the current entry function. Note that if the function was called as part of an external program, this operation will return the address of the program, NOT the address of the top-level user.

info
  • The self.caller operator can only be used in proof context — inside an entry fn body or a helper fn body, but not inside a final { } block, a final fn, or a constructor. The notion of "the function's immediate caller" only exists in the proof context; finalization runs after the call has been validated. The compiler emits an error if self.caller is used in an on-chain context.
  • The self.caller operator doesn't take any parameters.

Back to Top


self.checksum

fn matches_checksum(checksum: [u8; 32]) -> Final {
return final {
assert_eq(self.checksum, checksum);
};
}

The self.checksum operator returns the current program's checksum, which is a unique identifier for the program's code. To reference another program's checksum, see Program::checksum.

info
  • The self.checksum operator may be used in any function context (entry fn, helper fn, final fn, final { } block, or constructor).
  • The self.checksum operator doesn't take any parameters.

Back to Top


Program::checksum

let ext_checksum: [u8; 32] = Program::checksum(credits.aleo);

The Program::checksum operator returns the on-chain checksum of an imported program — the same value that program would observe with self.checksum. The argument must be a program-ID literal of the form name.aleo, not a runtime address.

Supported Types

ArgumentDestination
program ID literal[u8; 32]
info
  • The Program::checksum(other.aleo) operator can only be used in on-chain context — a final { } block, a final fn, or a constructor. Using it elsewhere will result in a compilation error.
  • The argument must be a program-ID literal (e.g. credits.aleo), not a variable typed as address.
  • To reference another program's checksum, you will need to import that program first.

Back to Top


self.edition

fn matches_edition(edition: u16) -> Final {
return final {
assert_eq(self.edition, edition);
};
}

The self.edition operator returns the current program's edition, which is the program's version number. A program's edition starts at zero and is incremented by one for each upgrade. The edition is tracked automatically on the network. To reference another program's edition, see Program::edition.

info
  • The self.edition operator may be used in any function context (entry fn, helper fn, final fn, final { } block, or constructor).
  • The self.edition operator doesn't take any parameters.

Back to Top


Program::edition

let ext_edition: u16 = Program::edition(credits.aleo);

The Program::edition operator returns the on-chain edition of an imported program — the same value that program would observe with self.edition. Useful for guarding logic against specific upgrade versions of a dependency. The argument must be a program-ID literal.

Supported Types

ArgumentDestination
program ID literalu16
info
  • The Program::edition(other.aleo) operator can only be used in on-chain context — a final { } block, a final fn, or a constructor. Using it elsewhere will result in a compilation error.
  • The argument must be a program-ID literal (e.g. credits.aleo), not a variable typed as address.
  • To reference another program's edition, you will need to import that program first.

Back to Top


self.id

fn get_program_id() -> address {
return self.id;
}

The self.id operator returns the on-chain address of the program containing the call site. It is an alias of self.address and lowers to the same Aleo instruction; the alternate spelling reads more naturally when comparing program identifiers.

info
  • The self.id operator may be used in any function context (entry fn, helper fn, final fn, final { } block, or constructor).
  • The self.id operator doesn't take any parameters.

Back to Top


self.program_owner

fn matches_owner(owner: address) -> Final {
return final {
assert_eq(self.program_owner, owner);
};
}

The self.program_owner operator returns the address that submitted the deployment transaction for the current program. To reference another program's owner, see Program::program_owner.

info
  • The self.program_owner operator can only be used in on-chain context — a final { } block, a final fn, or a constructor. Using it elsewhere will result in a compilation error.
  • The self.program_owner operator doesn't take any parameters.
  • Programs deployed before the upgradability feature shipped (Leo < v3.1.0) do not have a program_owner. Reading self.program_owner on such a program halts at runtime.

Back to Top


Program::program_owner

let ext_owner: address = Program::program_owner(credits.aleo);

The Program::program_owner operator returns the address that submitted the deployment transaction for an imported program — the same value that program would observe with self.program_owner. The argument must be a program-ID literal.

Supported Types

ArgumentDestination
program ID literaladdress
info
  • The Program::program_owner(other.aleo) operator can only be used in on-chain context — a final { } block, a final fn, or a constructor. Using it elsewhere will result in a compilation error.
  • The argument must be a program-ID literal (e.g. credits.aleo), not a variable typed as address.
  • To reference another program's owner, you will need to import that program first.
  • If the target program was deployed before the upgradability feature shipped, this call halts at runtime.

Back to Top


self.signer

fn matches_signer(addr: address) -> bool {
return self.signer == addr;
}

The self.signer operator returns the address of the account that invoked the top-level entry function. This will be the user account that signed the transaction.

info
  • The self.signer operator can only be used in proof context — inside an entry fn body or a helper fn body, but not inside a final { } block, a final fn, or a constructor. Finalization values must be derived in proof context and passed forward as inputs. If you need the signer's address inside a final { } block, capture it in proof context first and pass it as an argument to the finalize call.
  • The self.signer operator doesn't take any parameters.

Back to Top


Group/Field Specific Operators

group::GEN

let g: group = group::GEN; // the group generator

Returns the generator of the algebraic group that the group type consists of.

The compilation of Leo is based on an elliptic curve, whose points form a group, and on a specified point on that curve, which generates a subgroup, whose elements form the type group.

This is a constant, not a function. Thus, it takes no inputs, and just returns an output.

It is an associated constant, whose name is GEN and whose associated type is group.

Supported Types

Destination
group

Back to Top


Aleo::generator

let g: group = Aleo::generator();

Returns the generator point of the Aleo group. This is equivalent to group::GEN but expressed through the Aleo namespace for consistency with the other Aleo::* operators. Like group::GEN, it is a constant that takes no inputs.

Supported Types

Destination
group

Back to Top


Aleo::generator_powers

let powers: [group; 251] = Aleo::generator_powers();

Returns a precomputed array of the first 251 consecutive powers of the Aleo group generator: [G^0, G^1, G^2, ..., G^250]. Useful for efficient scalar multiplication without recomputing the powers at runtime.

The array always has exactly 251 elements. Indexing beyond 250u32 is rejected at compile time by Leo's array bounds check — there is no runtime halt specific to this operator.

Supported Types

Destination
[group; 251]

Back to Top


double

let a: group = 2group;
let b: group = a.double();

Adds the input to itself, storing the result in destination.

Supported Types

InputDestination
fieldfield
groupgroup

Back to Top


inv

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

Computes the multiplicative inverse of the input, storing the result in destination.

Supported Types

InputDestination
fieldfield

Back to Top


square

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

Squares the input, storing the result in destination.

Supported Types

InputDestination
fieldfield

Back to Top


square_root

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

Computes the square root of the input, storing the result in destination. If the input is a quadratic residue, the function returns the smaller of the two possible roots based on modular ordering. If the input is not a quadratic residue, execution halts.

Supported Types

InputDestination
fieldfield

Back to Top


to_x_coordinate

let x: field = 0group.to_x_coordinate(); // 0field

Extracts the x-coordinate of the group element as a field element.

Supported Types

InputDestination
groupfield

Back to Top


to_y_coordinate

let y: field = 0group.to_y_coordinate(); // 1field

Extracts the y-coordinate of the group element as a field element.

Supported Types

InputDestination
groupfield

Back to Top


Serialization / Deserialization

Serialize::to_bits

// Standard serialization (includes type metadata)
let value: u32 = 1u32;
let bits: [bool; 58] = Serialize::to_bits(value);

// Raw serialization (no metadata, just raw bits)
let bits2: [bool; 32] = Serialize::to_bits_raw(value);

// Works with arrays too
let bits3: [bool; 128] = Serialize::to_bits_raw([1u32, 2u32, 3u32, 4u32]);

By appending _raw to the end of the function, the function will omit the metadata of a type and directly serialize the input bits.

Supported Types

FirstDestinationDestination (Raw)
address[bool; 279][bool; 253]
bool[bool; 27][bool; 1]
field[bool; 279][bool; 253]
group[bool; 279][bool; 253]
i8[bool; 34][bool; 8]
i16[bool; 42][bool; 16]
i32[bool; 58][bool; 32]
i64[bool; 90][bool; 64]
i128[bool; 154][bool; 128]
u8[bool; 34][bool; 8]
u16[bool; 42][bool; 16]
u32[bool; 58][bool; 32]
u64[bool; 90][bool; 64]
u128[bool; 154][bool; 128]
scalar[bool; 277][bool; 251]

Back to Top


Deserialize::from_bits::[TYPE]

// Standard deserialization (includes type metadata)
let bits1: [bool; 58] = Serialize::to_bits(1u32);
let value1: u32 = Deserialize::from_bits::[u32](bits1);

// Raw deserialization (no metadata, just raw bits)
let bits2: [bool; 32] = Serialize::to_bits_raw(1u32);
let value2: u32 = Deserialize::from_bits_raw::[u32](bits2);

// Works with arrays too
let bits3: [bool; 128] = Serialize::to_bits_raw([1u32, 2u32, 3u32, 4u32]);
let arr: [u32; 4] = Deserialize::from_bits_raw::[[u32; 4]](bits3);

By appending _raw to the end of the function, the function will omit the metadata of a type and directly serialize the input bits.

Supported Types

TYPEInputInput (Raw)Destination
address[bool; 279][bool; 253]address
bool[bool; 27][bool; 1]bool
field[bool; 279][bool; 253]field
group[bool; 279][bool; 253]group
i8[bool; 34][bool; 8]i8
i16[bool; 42][bool; 16]i16
i32[bool; 58][bool; 32]i32
i64[bool; 90][bool; 64]i64
i128[bool; 154][bool; 128]i128
u8[bool; 34][bool; 8]u8
u16[bool; 42][bool; 16]u16
u32[bool; 58][bool; 32]u32
u64[bool; 90][bool; 64]u64
u128[bool; 154][bool; 128]u128
scalar[bool; 277][bool; 251]scalar

Back to Top


Miscellaneous

assert

let a: bool = true;
let b: bool = false;

assert(a); // will not halt
assert(b); // program halts

Checks whether the expression evaluates to a true boolean value, halting if evaluates to false.

Supported Types

Expression
bool

Back to Top


assert_eq

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

assert_eq(a, a); // will not halt
assert_eq(a, b); // program halts

Checks whether first and second are equal, halting if they are not equal.

Supported Types

FirstSecond
addressaddress
boolbool
fieldfield
groupgroup
i8i8
i16i16
i32i32
i64i64
i128i128
u8u8
u16u16
u32u32
u64u64
u128u128
scalarscalar
SignatureSignature
structstruct
RecordRecord

Back to Top


assert_neq

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

assert_neq(a, b); // will not halt
assert_neq(a, a); // program halts

Checks whether first and second are not equal, halting if they are equal.

Supported Types

FirstSecond
addressaddress
boolbool
fieldfield
groupgroup
i8i8
i16i16
i32i32
i64i64
i128i128
u8u8
u16u16
u32u32
u64u64
u128u128
scalarscalar
SignatureSignature
structstruct
RecordRecord

Back to Top


ternary

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

Selects first, if condition is true, otherwise selects second, storing the result in destination.

Supported Types

ConditionFirstSecondDestination
boolboolboolbool
boolfieldfieldfield
boolgroupgroupgroup
booli8i8i8
booli16i16i16
booli32i32i32
booli64i64i64
booli128i128i128
boolu8u8u8
boolu16u16u16
boolu32u32u32
boolu64u64u64
boolu128u128u128
boolscalarscalarscalar
boolSignatureSignatureSignature

Back to Top