## 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:
| 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.
| `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:
| 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
| `"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.
* `include_bytes!("file_path")` to include an array of bytes.
* `include!("file_path")` but only in item position, not in expression position.
* `arcis_static_panic!(message)` to fail compilation when the branch is reached. Useful for enforcing compile-time-known constraints like array length checks.
* `encrypted_mod!("path/to/my_module_name.rs")` or `encrypted_mod!("path/to/my_module.rs", my_module_name)` to use another file as a module. The other file needs to look like this:
```
use arcis::*;
#[encrypted_library]
mod arcis_library {
// Put your content here.
// Accessible through `my_module_name::MY_CONST`.
pub const MY_CONST: usize = 67;
}
```
## 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)`, `.as_slice()`, `.as_mut_slice()` on arrays and slices.
* `.map(f)`, `.each_ref()`, `.each_mut()` on arrays
* `.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()`, `.collect::<Box<[_]>>()` 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.
* `.set(val)`, `.swap(other)`, `.update(f)`, `.replace(val)`, `.into_inner()`, `.get()`, `.get_mut()` on `Cell`.
## 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`
* `Box::leak`, `Box::new`, `Cell::new`, `Cell::from_mut`.
# Item support:
| 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`.)
* `BaseField25519`, integers modulo 2^255 - 19.
* 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)
* `Box<T>` and `Cell<T>`.
* `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)))