Skip to content
This repository has been archived by the owner on Oct 17, 2023. It is now read-only.

adding back arrays/slices separation + huge refactor for readability #366

Merged
merged 4 commits into from
Sep 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
431 changes: 0 additions & 431 deletions docs/language_concepts/00_data_types.md

This file was deleted.

96 changes: 96 additions & 0 deletions docs/language_concepts/data_types.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
---
title: Data Types
description:
Get a clear understanding of the two categories of Noir data types - primitive types and compound
types. Learn about their characteristics, differences, and how to use them in your Noir
programming.
keywords:
[
noir,
data types,
primitive types,
compound types,
private types,
public types,
]
---

Every value in Noir has a type, which determines which operations are valid for it.

All values in Noir are fundamentally composed of `Field` elements. For a more approachable
developing experience, abstractions are added on top to introduce different data types in Noir.

Noir has two category of data types: primitive types (e.g. `Field`, integers, `bool`) and compound
types that group primitive types (e.g. arrays, tuples, structs). Each value can either be private or
public.

## Private & Public Types

A **private value** is known only to the Prover, while a **public value** is known by both the
Prover and Verifier. Mark values as `private` when the value should only be known to the prover. All
primitive types (including individual fields of compound types) in Noir are private by default, and
can be marked public when certain values are intended to be revealed to the Verifier.

> **Note:** For public values defined in Noir programs paired with smart contract verifiers, once
> the proofs are verified on-chain the values can be considered known to everyone that has access to
> that blockchain.

Public data types are treated no differently to private types apart from the fact that their values
will be revealed in proofs generated. Simply changing the value of a public type will not change the
circuit (where the same goes for changing values of private types as well).

_Private values_ are also referred to as _witnesses_ sometimes.

> **Note:** The terms private and public when applied to a type (e.g. `pub Field`) have a different
> meaning than when applied to a function (e.g. `pub fn foo() {}`).
>
> The former is a visibility modifier for the Prover to interpret if a value should be made known to
> the Verifier, while the latter is a visibility modifier for the compiler to interpret if a
> function should be made accessible to external Noir programs like in other languages.

### pub Modifier

All data types in Noir are private by default. Types are explicitly declared as public using the
`pub` modifier:

```rust
fn main(x : Field, y : pub Field) -> pub Field {
x + y
}
```

In this example, `x` is **private** while `y` and `x + y` (the return value) are **public**. Note
that visibility is handled **per variable**, so it is perfectly valid to have one input that is
private and another that is public.

> **Note:** Public types can only be declared through parameters on `main`.

## Type Aliases

A type alias is a new name for an existing type. Type aliases are declared with the keyword `type`:

```rust
type Id = u8;

fn main() {
let id: Id = 1;
let zero: u8 = 0;
assert(zero + 1 == id);
}
```

Type aliases can also be used with [generics](./06_generics.md):

```rust
type Id<Size> = Size;

fn main() {
let id: Id<u32> = 1;
let zero: u32 = 0;
assert(zero + 1 == id);
}
```

### BigInt

You can acheive BigInt functionality using the [Noir BigInt](https://github.com/shuklaayush/noir-bigint) library.
Original file line number Diff line number Diff line change
@@ -1,26 +1,42 @@
---
title: Field Methods
title: Fields
description:
Learn about common methods on Noir Field, including to_le_bits, to_le_bytes, to_le_radix,
to_be_radix, pow_32, etc, and see code examples.
Dive deep into the Field data type in Noir. Understand its methods, practical examples, and best practices to effectively use Fields in your Noir programs.
keywords:
[
Noir Field,
to_le_bits,
to_le_bytes,
to_le_radix,
to_be_radix,
pow_32,
Little Endian,
Big Endian,
Vector,
Exponent,
noir,
field type,
methods,
examples,
best practices,
]
---

The field type corresponds to the native field type of the proving backend.

The size of a Noir field depends on the elliptic curve's finite field for the proving backend
adopted. For example, a field would be a 254-bit integer when paired with the default backend that
spans the Grumpkin curve.

Fields support integer arithmetic and are often used as the default numeric type in Noir:

```rust
fn main(x : Field, y : Field) {
let z = x + y;
}
```

`x`, `y` and `z` are all private fields in this example. Using the `let` keyword we defined a new
private value `z` constrained to be equal to `x + y`.

If proving efficiency is of priority, fields should be used as a default for solving problems.
Smaller integer types (e.g. `u64`) incur extra range constraints.

## Methods

After declaring a Field, you can use these common methods on it:

## to_le_bits
### to_le_bits

Transforms the field into an array of bits, Little Endian.

Expand All @@ -37,7 +53,7 @@ fn main() {
}
```

## to_be_bits
### to_be_bits

Transforms the field into an array of bits, Big Endian.

Expand All @@ -54,7 +70,7 @@ fn main() {
}
```

## to_le_bytes
### to_le_bytes

Transforms into an array of bytes, Little Endian

Expand All @@ -71,7 +87,7 @@ fn main() {
}
```

## to_be_bytes
### to_be_bytes

Transforms into an array of bytes, Big Endian

Expand All @@ -88,7 +104,7 @@ fn main() {
}
```

## to_le_radix
### to_le_radix

Decomposes into a vector over the specified base, Little Endian

Expand All @@ -105,7 +121,7 @@ fn main() {
}
```

## to_be_radix
### to_be_radix

Decomposes into a vector over the specified base, Big Endian

Expand All @@ -122,7 +138,7 @@ fn main() {
}
```

## pow_32
### pow_32

Returns the value to the power of the specified exponent

Expand All @@ -140,7 +156,7 @@ fn main() {
}
```

## sgn0
### sgn0

Parity of (prime) Field element, i.e. sgn0(x mod p) = 0 if x ∈ {0, ..., p-1} is even, otherwise sgn0(x mod p) = 1.

Expand Down
33 changes: 33 additions & 0 deletions docs/language_concepts/data_types/01_integers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
title: Integers
description:
Explore the Integer data type in Noir. Learn about its methods, see real-world examples, and grasp how to efficiently use Integers in your Noir code.
keywords:
[
noir,
integer types,
methods,
examples,
arithmetic,
]
---

An integer type is a range constrained field type. The Noir frontend currently supports unsigned,
arbitrary-sized integer types.

An integer type is specified first with the letter `u`, indicating its unsigned nature, followed by
its length in bits (e.g. `32`). For example, a `u32` variable can store a value in the range of
$\\([0,2^{32}-1]\\)$:

```rust
fn main(x : Field, y : u32) {
let z = x as u32 + y;
}
```

`x`, `y` and `z` are all private values in this example. However, `x` is a field while `y` and `z`
are unsigned 32-bit integers. If `y` or `z` exceeds the range $\\([0,2^{32}-1]\\)$, proofs created
will be rejected by the verifier.

> **Note:** The default backend supports both even (e.g. `u16`, `u48`) and odd (e.g. `u5`, `u3`)
> sized integer types.
30 changes: 30 additions & 0 deletions docs/language_concepts/data_types/02_booleans.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
title: Booleans
description:
Delve into the Boolean data type in Noir. Understand its methods, practical examples, and best practices for using Booleans in your Noir programs.
keywords:
[
noir,
boolean type,
methods,
examples,
logical operations,
]
---


The `bool` type in Noir has two possible values: `true` and `false`:

```rust
fn main() {
let t = true;
let f: bool = false;
}
```

> **Note:** When returning a boolean value, it will show up as a value of 1 for `true` and 0 for
> `false` in _Verifier.toml_.

The boolean type is most commonly used in conditionals like `if` expressions and `assert`
statements. More about conditionals is covered in the [Control Flow](../control_flow) and
[Assert Function](../assert) sections.
43 changes: 43 additions & 0 deletions docs/language_concepts/data_types/03_strings.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
title: Strings
description:
Discover the String data type in Noir. Learn about its methods, see real-world examples, and understand how to effectively manipulate and use Strings in Noir.
keywords:
[
noir,
string type,
methods,
examples,
concatenation,
]
---


The string type is a fixed length value defined with `str<N>`.

You can use strings in `assert()` functions or print them with
`std::println()`. See more about [Logging](../../standard_library/logging).

```rust
use dep::std;

fn main(message : pub str<11>, hex_as_string : str<4>) {
std::println(message);
assert(message == "hello world");
assert(hex_as_string == "0x41");
}
```

You can convert a `str<N>` to a byte array by calling `as_bytes()`
or a vector by calling `as_bytes_vec()`.

```rust
fn main() {
let message = "hello world";
let message_bytes = message.as_bytes();
let mut message_vec = message.as_bytes_vec();
assert(message_bytes.len() == 11);
assert(message_bytes[0] == 104);
assert(message_bytes[0] == message_vec.get(0));
}
```
Loading