## Table of contents

* [Expression support](#expression-support)
  * [Binary expressions](#binary-expressions)
  * [Casts](#cast-expressions)
  * [Functions](#function-calls)
  * [Literals](#literal-expressions)
  * [Macros](#macros)
  * [Methods](#method-calls)
  * [Paths](#paths)
* [Item support](#item-support)
* [Pattern support](#pattern-support)
* [Type support](#type-support)
* [Arcis Standard Library](#arcis-standard-library)
  * [Cryptography (Ed25519)](#cryptography-ed25519)
  * [Hash Functions (SHA3)](#hash-functions-sha3)
  * [Solana Integration](#solana-integration)
  * [Machine Learning](#machine-learning)
  * [Math Functions](#math-functions)

# Expression support:

| Expression Name   | Example                        | Support         | Comments                                                                 |
|:------------------|:-------------------------------|:----------------|:-------------------------------------------------------------------------|
| Array literal     | `[a, b]`                       | Supported       |                                                                          |
| Assignment        | `a = b;`                       | Supported       |                                                                          |
| Async block       | `async { ... }`                | Unsupported     |                                                                          |
| Await             | `foo().await`                  | Unsupported     |                                                                          |
| Binary expression | `a + b`                        | Partial Support | [See table below](#binary-expressions) for supported binary expressions. |
| Block expression  | `{ ... }`                      | Supported       |                                                                          |
| Break             | `break;`                       | Unsupported     |                                                                          |
| Function call     | `f(a, b)`                      | Partial Support | [See table below](#function-calls) for supported functions.              |
| Casts             | `a as u16`                     | Partial Support | [See table below](#cast-expressions) for supported conversions.          |
| Closures          | `\|a, b \| a + b`              | Supported       |                                                                          |
| Const block       | `const { ... }`                | Supported       |                                                                          | 
| Continue          | `continue;`                    | Unsupported     |                                                                          |
| Field access/set  | `obj.field`                    | Supported       |                                                                          |
| For loop          | `for i in expr { ... }`        | Supported       | Note that `expr` will have its length known at compile-time.             |
| If                | `if cond { ... } else { ... }` | Supported       | Complexity is in O( then_block + else_block).                            | 
| Indexing          | `a[idx]`                       | Supported       | Complexity will be in O(`a.len()`) if `idx` isn't known at compile-time. |
| If let            | `if let Some(x) = ...`         | Unsupported     |                                                                          |
| Literals          | `1u128`                        | Partial Support | [See table below](#literal-expressions) for supported literals.          |
| Loops             | `loop { ... }`                 | Unsupported     | Cannot be supported as the number of iterations is not known.            |
| Macros            | `println!("{}", q)`            | Partial Support | [See table below](#macros) for supported macros.                         |
| Match             | `match n { ... }`              | Unsupported     |                                                                          |
| Method calls      | `x.foo(a, b)`                  | Partial Support | [See table below](#method-calls) for supported methods.                  |
| Parentheses       | `(a + b)`                      | Supported       |                                                                          |
| Paths             | `Foo::bar`                     | Partial Support | [See table below](#paths) for supported paths.                           |
| Ranges            | `4..5`                         | Partial Support | Only supported for set and compile-time-known bounds.                    |
| Raw addresses     | `&raw const foo`               | Unsupported     |                                                                          |
| References        | `&mut foo`                     | Supported       |                                                                          |
| Repeat arrays     | `[4u8; 128]`                   | Supported       |                                                                          |
| Return            | `return false;`                | Unsupported     |                                                                          |
| Struct literals   | `MyStruct { a: 12, b }`        | Supported       |                                                                          |
| Try expression    | `this_call_can_err()?;`        | Unsupported     |                                                                          |
| Tuple literal     | `(a, 4, c)`                    | Supported       |                                                                          |
| Unary expressions | `!x`                           | Partial Support | User-defined unary operations are not supported.                         |
| Unsafe            | `unsafe { ... }`               | Unsupported     |                                                                          |
| While loops       | `while x < 64 { ... }`         | Unsupported     | Cannot be supported as the number of iterations is not known.            |

## Binary expressions

Note: user-defined binary operations are currently unsupported.

| Example    | Supported types                            |
|:-----------|:-------------------------------------------|
| `a + b`    | Integers, floats                           |
| `a - b`    | Integers, floats                           |
| `a * b`    | Integers, floats                           |
| `a / b`    | Integers, floats                           |
| `a % b`    | Integers                                   |
| `a && b`   | Booleans                                   |
| `a \|\| b` | Booleans                                   |
| `a ^ b`    | Booleans                                   |
| `a & b`    | Booleans                                   |
| `a \| b`   | Booleans                                   |
| `a << b`   | None                                       |
| `a >> b`   | Integers, if `b` is known at compile time. |
| `a == b`   | All. Use `derive(PartialEq)` for structs.  |
| `a != b`   | All. Use `derive(PartialEq)` for structs.  |
| `a < b`    | Booleans, integers, floats                 |
| `a <= b`   | Booleans, integers, floats                 |
| `a >= b`   | Booleans, integers, floats                 |
| `a > b`    | Booleans, integers, floats                 |
| `a += b`   | Integers, floats                           |
| `a -= b`   | Integers, floats                           |
| `a *= b`   | Integers, floats                           |
| `a /= b`   | Integers, floats                           |
| `a %= b`   | Integers                                   |
| `a ^= b`   | Booleans                                   |
| `a &= b`   | Booleans                                   |
| `a \|= b`  | Booleans                                   |
| `a <<= b`  | None                                       |
| `a >>= b`  | Integers, if `b` is known at compile time  |

## Cast expressions

`a as MyType` is only supported:

| From Type    | To Type      |
|:-------------|:-------------|
| integer type | integer type |
| `bool`       | integer type |
| integer type | `bool`       |
| `&...&T`     | `&T`         | 

## Function calls

The following function calls are supported:

* user-defined function calls (without recursion)
* `ArcisRNG::bool()` to generate a boolean.
* `ArcisRNG::gen_uniform::<T>()` to generate a uniform `T`. It works for `T` being `bool`, an integer or any combination (struct, array, tuple) of working types.
* `ArcisRNG::gen_integer_from_width(width: usize) -> u128`. Generates a secret integer between 0 and 2^width - 1 included.
* `ArcisRNG::gen_public_integer_from_width(width: usize) -> u128`. Generates a public integer between 0 and 2^width - 1 included.
* `ArcisRNG::gen_integer_in_range(min: u128, max: u128, n_attempts: usize) -> (result: u128, success: bool)`. See function doc for more information.
* `ArcisRNG::shuffle(slice)` on slices. Complexity is in `O(n*log³(n) + n*log²(n)*sizeof(T))`.
* `Mxe::get()` to be able to create MXE-owned secret data. 
* `Shared::new(public_key: ArcisX25519Pubkey)` to share private data with `public_key`.
* `ArcisX25519Pubkey::from_base58(base58_byte_string)` to create a public key from a base58-encoded address.
* `ArcisX25519Pubkey::from_uint8(u8_byte_slice)` to create a public key from a Uint8 array.
* `ArcisX25519Pubkey::new_from_x(x: BaseField)` to create a public key from its Curve25519 Montgomery X-coordinate (the standard 32-byte X25519 representation).
* `ArcisX25519Pubkey::to_x() -> BaseField` to extract the Montgomery X-coordinate from a public key.
* `Pack::new(value: T)` to bit-pack data for on-chain storage (multiple small values fit into fewer field elements).

## Literal expressions

| Example     | Support     |
|:------------|:------------|
| `"foo"`     | Unsupported |
| `b"foo"`    | Supported   |
| `c"foo"`    | Unsupported |
| `b'f'`      | Supported   |
| `'a'`       | Unsupported |
| `1`         | Supported   |
| `1u16`      | Supported   |
| `1f64`      | Supported   |
| `1.0e10f64` | Supported   |
| `true`      | Supported   |

## Macros

The following macros are supported in order to help you debug your rust code:
* `debug_assert!`, `debug_assert_ne!`, `debug_assert_eq!`. They do not change instruction behavior and are only useful for debugging your rust code.
* `eprint!`, `eprintln!`, `print!`, `println!`. They do not change instruction behavior and are only useful for debugging your rust code.
* `arcis_static_panic!(message)` to fail compilation when the branch is reached. Useful for enforcing compile-time-known constraints like array length checks.


## Method calls

The following method calls are supported:

* user-defined method calls (generics supported, recursion not supported)
* `.clone()` on all `Clone` objects.
* `.len()`, `.is_empty()`, `.swap(a, b)`, `.fill(value)`, `.reverse()`, `.iter()`, `.iter_mut()`, `.into_iter()`, `.windows(width)`, `.copy_from_slice(src)`, `.clone_from_slice(src)`, `.split_at(mid)`, `.split_at_mut(mid)`, `.rotate_left(mid)`, `.rotate_right(mid)`, `.contains(item)`, `.starts_with(needle)`, `.ends_with(needle)` on arrays and slices.
* `.sort()` on arrays of integers. Complexity is in `O(n*log²(n)*bit_size)`.
* `.enumerate()`, `.chain(other)`, `.cloned()`, `.copied()`, `.count()`, `.rev()`, `.zip(other)`, `.map(func)`, `.for_each(func)`, `.fold(init, func)`, `.sum()`, `.product()` on iterators.
* `.take(n)`, `.skip(n)`, `.step_by(n)` on iterators when `n` is compile-time known.
* `.reveal()` if not inside a `if` or a `else`
* `.to_arcis()` on `Enc`s
* `.from_arcis(x)` on `Owner`s (objects of types `Mxe` or `Shared`) if not inside a `if` or a `else`
* `.unpack()` on `Pack<T>` to extract the original value from packed storage.
* `.to_arcis_with_pubkey_and_nonce(pubkey, nonce)` on `EncData<T>` to decrypt when the key is shared across inputs (avoids duplicate decryption gates).
* `.abs()`, `.min(x)`, `.max(x)` on integers and floats
* `.abs_diff(other)`, `.is_positive()`, `.is_negative()`, `.div_ceil(other)` on integers
* `.to_le_bytes()`, `.to_be_bytes()`, `.wrapping_add(rhs)`, `.wrapping_sub(rhs)`, `.wrapping_mul(rhs)` on typed integers (does not work on integers the interpreter does not know the type)
* `.exp()`, `.exp2()`, `.ln()`, `.log2()`, `.sqrt()` on floats.

## Paths

The following paths are supported:

* `IntType::BITS`, `IntType::MIN` and `IntType::MAX` where `IntType` is an integer type.
* Paths to user-defined constants, functions and structs, as long as they don't use the unsupported `crate` or `super`.
* `std::mem::replace` and `std::mem::swap`

# Item support:

| Item Name         | Example                   | Support         | Comments                                                      |
|:------------------|:--------------------------|:----------------|:--------------------------------------------------------------|
| Constant          | `const MAX: u16 = 65535`  | Supported       |                                                               |
| Enum              | `enum MyEnum { ... }`     | Unsupported     |                                                               |
| Extern            | `extern ...`              | Unsupported     |                                                               |
| Functions         | `fn foo() -> u8 { 0 }`    | Partial Support | Recursive functions are not supported.                        |
| Generics          | `fn foo<T>(x: T) -> T`    | Supported       | Generic type params, const params, lifetime params, trait bounds, turbofish syntax, and `impl Trait` in function signatures supported. |
| Impls             | `impl MyType { ... }`     | Partial Support | Trait impls supported. Generic impls with trait bounds supported. `MyType` should not be a reference. |
| Macro Definitions | `macro_rules! ...`        | Unsupported     |                                                               |
| Macro Invocations | `println!(...)`           | Partial Support | [See table above](#macros) for supported macros.              |
| Modules           | `mod my_module { ... }`   | Supported       |                                                               |
| Statics           | `static ...`              | Unsupported     |                                                               |
| Structs           | `struct MyStruct { ... }` | Supported       |                                                               |
| Traits            | `trait MyTrait { ... }`   | Partial Support | Custom traits supported with methods, constants, and associated types. Standard library traits forbidden.¹ |
| Type Aliases      | `type MyId = usize;`      | Supported       |                                                               |
| Union             | `union MyUnion { ... }`   | Unsupported     |                                                               |                   
| Use               | `use arcis::*`            | Partial Support | Only `use arcis::` is supported.                              |

¹ Forbidden traits: Drop, Deref, AsRef, AsMut, Into, From, PartialEq, Eq, Default, PartialOrd, Ord, Clone, Fn, FnMut, FnOnce, ToOwned, ToString, Iterator, Extend, IntoIterator, DoubleEndedIterator, ExactSizeIterator, TryFrom, TryInto, FromIterator, Future, IntoFuture, AsyncFn, AsyncFnOnce, AsyncFnMut.

# Pattern support:

The following patterns are supported in function arguments and `let` statements:

* simple idents: `let ident = ...;`
* mutable idents: `let mut ident = ...;`
* ref idents: `let ref ident = ...;`
* mutable ref idents: `let ref mut ident = ...;`
* parentheses around a supported pattern: `let (...) = ...;`
* reference of a supported pattern: `let &... = ...;`
* array of supported patterns: `let [...] = ...;`
* struct of supported patterns: `let MyStruct { ... } = ...;`
* tuple of supported patterns: `let (...) = ...;`
* tuple struct of supported patterns: `let MyStruct(...) = ...;`
* type pattern of a supported pattern: `let ...: ty = ...;`
* wild pattern: `let _ = ...;`

Note: in particular, the `..` pattern is currently unsupported.

# Type support:

The following types are supported:

* `u8`, `u16`, `u32`, `u64`, `u128`, `usize`, `i8`, `i16`, `i32`, `i64`, `i128`, `isize`
* `f64`, `f32` (Note: these types are emulated by the fixed-point numbers `k*2^-52`, for `k` between `-2^250` and `2^250`.)
* tuples of supported types, including `()`
* fixed-length arrays of a supported type
* fixed-length slices
* compile-time known ranges
* (mutable) references to a supported type
* user-defined structs of supported types
* functions (but not as input or output of an encrypted instruction)
* `ArcisX25519Pubkey`, an Arcis public key wrapper.
* Arcis-defined `Enc`, `Mxe` and `Shared`.
* `Pack<T>`, a wrapper for bit-packing data into fewer field elements for on-chain storage.
* `EncData<T>`, encrypted data without embedded cipher info. Use with `.to_arcis_with_pubkey_and_nonce()` when multiple values share the same key.
* `BaseField`, a 256-bit Curve25519 field element used as the native type for circuit computations.

In particular, we do not currently support `HashMap`, `Vec`, `String` (we do not support types with a variable `len`).
Constant-size byte strings (like `b"hello_world"`) are supported.

# Arcis Standard Library

The following types and functions from the arcis standard library are available:

## Cryptography (Ed25519)

* `SecretKey` - Ed25519 secret key type for signing
* `VerifyingKey` - Ed25519 verifying key type for signature verification
* `ArcisEd25519Signature` - Ed25519 signature type
* `SecretKey::new_rand()` to generate a random secret key
* `VerifyingKey::from_secret_key(&secret_key)` to derive a verifying key from a secret key
* `ArcisEd25519Signature::from_bytes(bytes: [u8; 64])` to create a signature from bytes
* `.verify(&message, &signature)` on `VerifyingKey` to verify a signature

## Hash Functions (SHA3)

* `SHA3_256` - SHA3-256 hasher type (outputs 32 bytes)
* `SHA3_512` - SHA3-512 hasher type (outputs 64 bytes)
* `SHA3_256::new()` / `SHA3_512::new()` to create a hasher instance
* `.digest(&data)` on hasher to compute the hash digest

## Solana Integration

* `SolanaPublicKey` - Solana public key type
* `SerializedSolanaPublicKey` - Serialized (32-byte) Solana public key
* `SolanaPublicKey::from_serialized(data)` to deserialize a Solana public key

## Machine Learning

* `LogisticRegression` - Logistic regression model type
* `LogisticRegression::new(&coefficients, intercept)` to create a model from coefficients and intercept
* `.predict(&features, threshold)` on `LogisticRegression` to make a binary prediction

## Math Functions

* `ArcisMath::sigmoid(x: f64) -> f64` to compute the sigmoid function (1 / (1 + e^(-x)))
