From 455399fa42161dccfd507872805fa2bb64c557e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Pedro=20Sousa?= Date: Mon, 22 Jan 2024 14:04:15 +0000 Subject: [PATCH 01/70] chore(docs): removing oracles from 0.22.0 (#4104) # Description Removes Oracles documentation from version 0.22.0.. ## Problem\* We went on documenting oracles for 0.22.0 (and a lil bit painfully, gonna be honest). Unforgivable. ![image](https://github.com/noir-lang/noir/assets/20129824/10f1fb82-13eb-4e16-9502-8dbdb0bf723a) Closes #4096 --------- Co-authored-by: Tom French --- .github/workflows/docs-pr.yml | 2 +- .../explainers/explainer-oracle.md | 57 ---- .../version-v0.22.0/how_to/how-to-oracles.md | 280 ------------------ .../version-v0.22.0/noir/syntax/oracles.md | 23 -- 4 files changed, 1 insertion(+), 361 deletions(-) delete mode 100644 docs/versioned_docs/version-v0.22.0/explainers/explainer-oracle.md delete mode 100644 docs/versioned_docs/version-v0.22.0/how_to/how-to-oracles.md delete mode 100644 docs/versioned_docs/version-v0.22.0/noir/syntax/oracles.md diff --git a/.github/workflows/docs-pr.yml b/.github/workflows/docs-pr.yml index cf40b9357cd..f4a1be826a8 100644 --- a/.github/workflows/docs-pr.yml +++ b/.github/workflows/docs-pr.yml @@ -40,7 +40,7 @@ jobs: script: | const labels = context.payload.pull_request.labels.map(label => label.name); if (!labels.includes('documentation')) { - github.issues.addLabels({ + github.rest.issues.addLabels({ owner: context.repo.owner, repo: context.repo.repo, issue_number: context.issue.number, diff --git a/docs/versioned_docs/version-v0.22.0/explainers/explainer-oracle.md b/docs/versioned_docs/version-v0.22.0/explainers/explainer-oracle.md deleted file mode 100644 index 76dd0e36d6c..00000000000 --- a/docs/versioned_docs/version-v0.22.0/explainers/explainer-oracle.md +++ /dev/null @@ -1,57 +0,0 @@ ---- -title: Oracles -description: This guide provides an in-depth understanding of how Oracles work in Noir programming. Learn how to use outside calculations in your programs, constrain oracles, and understand their uses and limitations. -keywords: - - Noir Programming - - Oracles - - JSON-RPC - - Foreign Call Handlers - - Constrained Functions - - Blockchain Programming -sidebar_position: 1 ---- - -If you've seen "The Matrix" you may recall "The Oracle" as Gloria Foster smoking cigarettes and baking cookies. While she appears to "know things", she is actually providing a calculation of a pre-determined future. Noir Oracles are similar, in a way. They don't calculate the future (yet), but they allow you to use outside calculations in your programs. - -![matrix oracle prediction](@site/static/img/memes/matrix_oracle.jpeg) - -A Noir program is usually self-contained. You can pass certain inputs to it, and it will generate a deterministic output for those inputs. But what if you wanted to defer some calculation to an outside process or source? - -Oracles are functions that provide this feature. - -## Use cases - -An example usage for Oracles is proving something on-chain. For example, proving that the ETH-USDC quote was below a certain target at a certain block time. Or even making more complex proofs like proving the ownership of an NFT as an anonymous login method. - -Another interesting use case is to defer expensive calculations to be made outside of the Noir program, and then constraining the result; similar to the use of [unconstrained functions](../noir/syntax/unconstrained.md). - -In short, anything that can be constrained in a Noir program but needs to be fetched from an external source is a great candidate to be used in oracles. - -## Constraining oracles - -Just like in The Matrix, Oracles are powerful. But with great power, comes great responsibility. Just because you're using them in a Noir program doesn't mean they're true. Noir has no superpowers. If you want to prove that Portugal won the Euro Cup 2016, you're still relying on potentially untrusted information. - -To give a concrete example, Alice wants to login to the [NounsDAO](https://nouns.wtf/) forum with her username "noir_nouner" by proving she owns a noun without revealing her ethereum address. Her Noir program could have a oracle call like this: - -```rust -#[oracle(getNoun)] -unconstrained fn get_noun(address: Field) -> Field -``` - -This oracle could naively resolve with the number of Nouns she possesses. However, it is useless as a trusted source, as the oracle could resolve to anything Alice wants. In order to make this oracle call actually useful, Alice would need to constrain the response from the oracle, by proving her address and the noun count belongs to the state tree of the contract. - -In short, **Oracles don't prove anything. Your Noir program does.** - -:::danger - -If you don't constrain the return of your oracle, you could be clearly opening an attack vector on your Noir program. Make double-triple sure that the return of an oracle call is constrained! - -::: - -## How to use Oracles - -On CLI, Nargo resolves oracles by making JSON RPC calls, which means it would require an RPC node to be running. - -In JavaScript, NoirJS accepts and resolves arbitrary call handlers (that is, not limited to JSON) as long as they matches the expected types the developer defines. Refer to [Foreign Call Handler](../reference/NoirJS/noir_js/type-aliases/ForeignCallHandler.md) to learn more about NoirJS's call handling. - -If you want to build using oracles, follow through to the [oracle guide](../how_to/how-to-oracles.md) for a simple example on how to do that. diff --git a/docs/versioned_docs/version-v0.22.0/how_to/how-to-oracles.md b/docs/versioned_docs/version-v0.22.0/how_to/how-to-oracles.md deleted file mode 100644 index 61cabe586e6..00000000000 --- a/docs/versioned_docs/version-v0.22.0/how_to/how-to-oracles.md +++ /dev/null @@ -1,280 +0,0 @@ ---- -title: How to use Oracles -description: Learn how to use oracles in your Noir program with examples in both Nargo and NoirJS. This guide also covers writing a JSON RPC server and providing custom foreign call handlers for NoirJS. -keywords: - - Noir Programming - - Oracles - - Nargo - - NoirJS - - JSON RPC Server - - Foreign Call Handlers -sidebar_position: 1 ---- - -This guide shows you how to use oracles in your Noir program. For the sake of clarity, it assumes that: - -- You have read the [explainer on Oracles](../explainers/explainer-oracle.md) and are comfortable with the concept. -- You have a Noir program to add oracles to. You can create one using the [vite-hardhat starter](https://github.com/noir-lang/noir-starter/tree/main/vite-hardhat) as a boilerplate. -- You understand the concept of a JSON-RPC server. Visit the [JSON-RPC website](https://www.jsonrpc.org/) if you need a refresher. -- You are comfortable with server-side JavaScript (e.g. Node.js, managing packages, etc.). - -For reference, you can find the snippets used in this tutorial on the [Aztec DevRel Repository](https://github.com/AztecProtocol/dev-rel/tree/main/how_to_oracles/code-snippets/how-to-oracles). - -## Rundown - -This guide has 3 major steps: - -1. How to modify our Noir program to make use of oracle calls as unconstrained functions -2. How to write a JSON RPC Server to resolve these oracle calls with Nargo -3. How to use them in Nargo and how to provide a custom resolver in NoirJS - -## Step 1 - Modify your Noir program - -An oracle is defined in a Noir program by defining two methods: - -- An unconstrained method - This tells the compiler that it is executing an [unconstrained functions](../noir/syntax/unconstrained.md). -- A decorated oracle method - This tells the compiler that this method is an RPC call. - -An example of an oracle that returns a `Field` would be: - -```rust -#[oracle(getSqrt)] -unconstrained fn sqrt(number: Field) -> Field { } - -unconstrained fn get_sqrt(number: Field) -> Field { - sqrt(number) -} -``` - -In this example, we're wrapping our oracle function in a unconstrained method, and decorating it with `oracle(getSqrt)`. We can then call the unconstrained function as we would call any other function: - -```rust -fn main(input: Field) { - let sqrt = get_sqrt(input); -} -``` - -In the next section, we will make this `getSqrt` (defined on the `sqrt` decorator) be a method of the RPC server Noir will use. - -:::danger - -As explained in the [Oracle Explainer](../explainers/explainer-oracle.md), this `main` function is unsafe unless you constrain its return value. For example: - -```rust -fn main(input: Field) { - let sqrt = get_sqrt(input); - assert(sqrt[0].pow_32(2) as u64 == input as u64); // <---- constrain the return of an oracle! -} -``` - -::: - -:::info - -Currently, oracles only work with single params or array params. For example: - -```rust -#[oracle(getSqrt)] -unconstrained fn sqrt([Field; 2]) -> [Field; 2] { } -``` - -::: - -## Step 2 - Write an RPC server - -Brillig will call *one* RPC server. Most likely you will have to write your own, and you can do it in whatever language you prefer. In this guide, we will do it in Javascript. - -Let's use the above example of an oracle that consumes an array with two `Field` and returns their square roots: - -```rust -#[oracle(getSqrt)] -unconstrained fn sqrt(input: [Field; 2]) -> [Field; 2] { } - -unconstrained fn get_sqrt(input: [Field; 2]) -> [Field; 2] { - sqrt(input) -} - -fn main(input: [Field; 2]) { - let sqrt = get_sqrt(input); - assert(sqrt[0].pow_32(2) as u64 == input[0] as u64); - assert(sqrt[1].pow_32(2) as u64 == input[1] as u64); -} -``` - -:::info - -Why square root? - -In general, computing square roots is computationally more expensive than multiplications, which takes a toll when speaking about ZK applications. In this case, instead of calculating the square root in Noir, we are using our oracle to offload that computation to be made in plain. In our circuit we can simply multiply the two values. - -::: - -Now, we should write the correspondent RPC server, starting with the [default JSON-RPC 2.0 boilerplate](https://www.npmjs.com/package/json-rpc-2.0#example): - -```js -import { JSONRPCServer } from "json-rpc-2.0"; -import express from "express"; -import bodyParser from "body-parser"; - -const app = express(); -app.use(bodyParser.json()); - -const server = new JSONRPCServer(); -app.post("/", (req, res) => { - const jsonRPCRequest = req.body; - server.receive(jsonRPCRequest).then((jsonRPCResponse) => { - if (jsonRPCResponse) { - res.json(jsonRPCResponse); - } else { - res.sendStatus(204); - } - }); -}); - -app.listen(5555); -``` - -Now, we will add our `getSqrt` method, as expected by the `#[oracle(getSqrt)]` decorator in our Noir code. It maps through the params array and returns their square roots: - -```js -server.addMethod("getSqrt", async (params) => { - const values = params[0].Array.map(({ inner }) => { - return { inner: `${Math.sqrt(parseInt(inner, 16))}` }; - }); - return { values: [{ Array: values }] }; -}); -``` - -:::tip - -Brillig expects an object with an array of values. Each value is an object declaring to be `Single` or `Array` and returning a `inner` property *as a string*. For example: - -```json -{ "values": [{ "Array": [{ "inner": "1" }, { "inner": "2"}]}]} -{ "values": [{ "Single": { "inner": "1" }}]} -{ "values": [{ "Single": { "inner": "1" }}, { "Array": [{ "inner": "1", { "inner": "2" }}]}]} -``` - -If you're using Typescript, the following types may be helpful in understanding the expected return value and making sure they're easy to follow: - -```js -interface Value { - inner: string, -} - -interface SingleForeignCallParam { - Single: Value, -} - -interface ArrayForeignCallParam { - Array: Value[], -} - -type ForeignCallParam = SingleForeignCallParam | ArrayForeignCallParam; - -interface ForeignCallResult { - values: ForeignCallParam[], -} -``` - -::: - -## Step 3 - Usage with Nargo - -Using the [`nargo` CLI tool](../getting_started/installation/index.md), you can use oracles in the `nargo test`, `nargo execute` and `nargo prove` commands by passing a value to `--oracle-resolver`. For example: - -```bash -nargo test --oracle-resolver http://localhost:5555 -``` - -This tells `nargo` to use your RPC Server URL whenever it finds an oracle decorator. - -## Step 4 - Usage with NoirJS - -In a JS environment, an RPC server is not strictly necessary, as you may want to resolve your oracles without needing any JSON call at all. NoirJS simply expects that you pass a callback function when you generate proofs, and that callback function can be anything. - -For example, if your Noir program expects the host machine to provide CPU pseudo-randomness, you could simply pass it as the `foreignCallHandler`. You don't strictly need to create an RPC server to serve pseudo-randomness, as you may as well get it directly in your app: - -```js -const foreignCallHandler = (name, inputs) => crypto.randomBytes(16) // etc - -await noir.generateFinalProof(inputs, foreignCallHandler) -``` - -As one can see, in NoirJS, the [`foreignCallHandler`](../reference/NoirJS/noir_js/type-aliases/ForeignCallHandler.md) function simply means "a callback function that returns a value of type [`ForeignCallOutput`](../reference/NoirJS/noir_js/type-aliases/ForeignCallOutput.md). It doesn't have to be an RPC call like in the case for Nargo. - -:::tip - -Does this mean you don't have to write an RPC server like in [Step #2](#step-2---write-an-rpc-server)? - -You don't technically have to, but then how would you run `nargo test` or `nargo prove`? To use both `Nargo` and `NoirJS` in your development flow, you will have to write a JSON RPC server. - -::: - -In this case, let's make `foreignCallHandler` call the JSON RPC Server we created in [Step #2](#step-2---write-an-rpc-server), by making it a JSON RPC Client. - -For example, using the same `getSqrt` program in [Step #1](#step-1---modify-your-noir-program) (comments in the code): - -```js -import { JSONRPCClient } from "json-rpc-2.0"; - -// declaring the JSONRPCClient -const client = new JSONRPCClient((jsonRPCRequest) => { -// hitting the same JSON RPC Server we coded above - return fetch("http://localhost:5555", { - method: "POST", - headers: { - "content-type": "application/json", - }, - body: JSON.stringify(jsonRPCRequest), - }).then((response) => { - if (response.status === 200) { - return response - .json() - .then((jsonRPCResponse) => client.receive(jsonRPCResponse)); - } else if (jsonRPCRequest.id !== undefined) { - return Promise.reject(new Error(response.statusText)); - } - }); -}); - -// declaring a function that takes the name of the foreign call (getSqrt) and the inputs -const foreignCallHandler = async (name, input) => { - // notice that the "inputs" parameter contains *all* the inputs - // in this case we to make the RPC request with the first parameter "numbers", which would be input[0] - const oracleReturn = await client.request(name, [ - { Array: input[0].map((i) => ({ inner: i.toString("hex") })) }, - ]); - return [oracleReturn.values[0].Array.map((x) => x.inner)]; -}; - -// the rest of your NoirJS code -const input = { input: [4, 16] }; -const { witness } = await noir.execute(numbers, foreignCallHandler); -``` - -:::tip - -If you're in a NoirJS environment running your RPC server together with a frontend app, you'll probably hit a familiar problem in full-stack development: requests being blocked by [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) policy. For development only, you can simply install and use the [`cors` npm package](https://www.npmjs.com/package/cors) to get around the problem: - -```bash -yarn add cors -``` - -and use it as a middleware: - -```js -import cors from "cors"; - -const app = express(); -app.use(cors()) -``` - -::: - -## Conclusion - -Hopefully by the end of this guide, you should be able to: - -- Write your own logic around Oracles and how to write a JSON RPC server to make them work with your Nargo commands. -- Provide custom foreign call handlers for NoirJS. diff --git a/docs/versioned_docs/version-v0.22.0/noir/syntax/oracles.md b/docs/versioned_docs/version-v0.22.0/noir/syntax/oracles.md deleted file mode 100644 index 2e6a6818d48..00000000000 --- a/docs/versioned_docs/version-v0.22.0/noir/syntax/oracles.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -title: Oracles -description: Dive into how Noir supports Oracles via RPC calls, and learn how to declare an Oracle in Noir with our comprehensive guide. -keywords: - - Noir - - Oracles - - RPC Calls - - Unconstrained Functions - - Programming - - Blockchain -sidebar_position: 6 ---- - -Noir has support for Oracles via RPC calls. This means Noir will make an RPC call and use the return value for proof generation. - -Since Oracles are not resolved by Noir, they are [`unconstrained` functions](./unconstrained.md) - -You can declare an Oracle through the `#[oracle()]` flag. Example: - -```rust -#[oracle(get_number_sequence)] -unconstrained fn get_number_sequence(_size: Field) -> [Field] {} -``` From 199d129bd7ae02c4336399455ecda69905dfa1bd Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Mon, 22 Jan 2024 14:09:36 +0000 Subject: [PATCH 02/70] chore: replace explicit subtractions with nots (#4097) # Description ## Problem\* Resolves ## Summary\* Small PR to replace usage of `(1-x)` instead of `not(x)` for boolean `x`. This improves readability of the codegen imo. ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- .../noirc_evaluator/src/ssa/function_builder/mod.rs | 8 +++++--- compiler/noirc_evaluator/src/ssa/ssa_gen/context.rs | 12 +++++++----- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/compiler/noirc_evaluator/src/ssa/function_builder/mod.rs b/compiler/noirc_evaluator/src/ssa/function_builder/mod.rs index 852848afb81..44be423be10 100644 --- a/compiler/noirc_evaluator/src/ssa/function_builder/mod.rs +++ b/compiler/noirc_evaluator/src/ssa/function_builder/mod.rs @@ -367,10 +367,12 @@ impl FunctionBuilder { let r_squared = self.insert_binary(r, BinaryOp::Mul, r); let a = self.insert_binary(r_squared, BinaryOp::Mul, lhs); let idx = self.field_constant(FieldElement::from((bit_size - i) as i128)); - let b = self.insert_array_get(rhs_bits, idx, Type::field()); + let b = self.insert_array_get(rhs_bits, idx, Type::bool()); + let not_b = self.insert_not(b); + let b = self.insert_cast(b, Type::field()); + let not_b = self.insert_cast(not_b, Type::field()); let r1 = self.insert_binary(a, BinaryOp::Mul, b); - let c = self.insert_binary(one, BinaryOp::Sub, b); - let r2 = self.insert_binary(c, BinaryOp::Mul, r_squared); + let r2 = self.insert_binary(r_squared, BinaryOp::Mul, not_b); r = self.insert_binary(r1, BinaryOp::Add, r2); } r diff --git a/compiler/noirc_evaluator/src/ssa/ssa_gen/context.rs b/compiler/noirc_evaluator/src/ssa/ssa_gen/context.rs index f1a2154d3a8..0e155776545 100644 --- a/compiler/noirc_evaluator/src/ssa/ssa_gen/context.rs +++ b/compiler/noirc_evaluator/src/ssa/ssa_gen/context.rs @@ -270,11 +270,12 @@ impl<'a> FunctionContext<'a> { /// helper function which add instructions to the block computing the absolute value of the /// given signed integer input. When the input is negative, we return its two complement, and itself when it is positive. fn absolute_value_helper(&mut self, input: ValueId, sign: ValueId, bit_size: u32) -> ValueId { + assert_eq!(self.builder.type_of_value(sign), Type::bool()); + // We compute the absolute value of lhs - let one = self.builder.numeric_constant(FieldElement::one(), Type::bool()); let bit_width = self.builder.numeric_constant(FieldElement::from(2_i128.pow(bit_size)), Type::field()); - let sign_not = self.builder.insert_binary(one, BinaryOp::Sub, sign); + let sign_not = self.builder.insert_not(sign); // We use unsafe casts here, this is fine as we're casting to a `field` type. let as_field = self.builder.insert_cast(input, Type::field()); @@ -472,7 +473,6 @@ impl<'a> FunctionContext<'a> { location: Location, ) { let is_sub = operator == BinaryOpKind::Subtract; - let one = self.builder.numeric_constant(FieldElement::one(), Type::bool()); let half_width = self.builder.numeric_constant( FieldElement::from(2_i128.pow(bit_size - 1)), Type::unsigned(bit_size), @@ -484,7 +484,7 @@ impl<'a> FunctionContext<'a> { let mut rhs_sign = self.builder.insert_binary(rhs_as_unsigned, BinaryOp::Lt, half_width); let message = if is_sub { // lhs - rhs = lhs + (-rhs) - rhs_sign = self.builder.insert_binary(one, BinaryOp::Sub, rhs_sign); + rhs_sign = self.builder.insert_not(rhs_sign); "attempt to subtract with overflow".to_string() } else { "attempt to add with overflow".to_string() @@ -518,13 +518,15 @@ impl<'a> FunctionContext<'a> { let product = self.builder.insert_cast(product_field, Type::unsigned(bit_size)); // Then we check the signed product fits in a signed integer of bit_size-bits - let not_same = self.builder.insert_binary(one, BinaryOp::Sub, same_sign); + let not_same = self.builder.insert_not(same_sign); let not_same_sign_field = self.insert_safe_cast(not_same, Type::unsigned(bit_size), location); let positive_maximum_with_offset = self.builder.insert_binary(half_width, BinaryOp::Add, not_same_sign_field); let product_overflow_check = self.builder.insert_binary(product, BinaryOp::Lt, positive_maximum_with_offset); + + let one = self.builder.numeric_constant(FieldElement::one(), Type::bool()); self.builder.set_location(location).insert_constrain( product_overflow_check, one, From 5be9f9d7e2f39ca228df10e5a530474af0331704 Mon Sep 17 00:00:00 2001 From: kevaundray Date: Mon, 22 Jan 2024 15:16:33 +0000 Subject: [PATCH 03/70] chore: Release Noir(0.23.0) (#3862) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit :robot: I have created a release *beep* *boop* ---
0.23.0 ## [0.23.0](https://github.com/noir-lang/noir/compare/v0.22.0...v0.23.0) (2024-01-22) ### ⚠ BREAKING CHANGES * Ban nested slices ([#4018](https://github.com/noir-lang/noir/issues/4018)) * Breaking changes from aztec-packages ([#3955](https://github.com/noir-lang/noir/issues/3955)) * Rename Arithmetic opcode to AssertZero ([#3840](https://github.com/noir-lang/noir/issues/3840)) * remove circuit methods from noir_wasm ([#3869](https://github.com/noir-lang/noir/issues/3869)) ### Features * Add `assert_max_bit_size` method to `Field` ([#4016](https://github.com/noir-lang/noir/issues/4016)) ([bc9a44f](https://github.com/noir-lang/noir/commit/bc9a44f285e0569825a307b06ee8acd93461c87e)) * Add `noir-compiler` checks to `aztec_macros` ([#4031](https://github.com/noir-lang/noir/issues/4031)) ([420a5c7](https://github.com/noir-lang/noir/commit/420a5c74a14dcfeede04337a42282093a7b5e63e)) * Add a `--force` flag to force a full recompile ([#4054](https://github.com/noir-lang/noir/issues/4054)) ([27a8e68](https://github.com/noir-lang/noir/commit/27a8e6864643d81d96e84990e2e26cd16596a695)) * Add dependency resolver for `noir_wasm` and implement `FileManager` for consistency with native interface ([#3891](https://github.com/noir-lang/noir/issues/3891)) ([c29c7d7](https://github.com/noir-lang/noir/commit/c29c7d7c9615b9f45c696b1bdc1c497d55469dfa)) * Add foreign call support to `noir_codegen` functions ([#3933](https://github.com/noir-lang/noir/issues/3933)) ([e5e52a8](https://github.com/noir-lang/noir/commit/e5e52a81b31d7735b680e97a9bef89a010a99763)) * Add MVP `nargo export` command ([#3870](https://github.com/noir-lang/noir/issues/3870)) ([fbb51ed](https://github.com/noir-lang/noir/commit/fbb51ed33e9e4d9105d8946cdfc4ea387c85258e)) * Add support for codegenning multiple functions which use the same structs in their interface ([#3868](https://github.com/noir-lang/noir/issues/3868)) ([1dcfcc5](https://github.com/noir-lang/noir/commit/1dcfcc5265f618685a783504b1d4be213e4cda2d)) * Added efficient field comparisons for bn254 ([#4042](https://github.com/noir-lang/noir/issues/4042)) ([1f9cad0](https://github.com/noir-lang/noir/commit/1f9cad00c57ea257f57419d2446a46938beb19f9)) * Assert maximum bit size when creating a U128 from an integer ([#4024](https://github.com/noir-lang/noir/issues/4024)) ([8f9c7e4](https://github.com/noir-lang/noir/commit/8f9c7e4de9f2ae5b39714d8e0d26b2befcd11c4a)) * Avoid unnecessary range checks by inspecting instructions for casts ([#4039](https://github.com/noir-lang/noir/issues/4039)) ([378c18e](https://github.com/noir-lang/noir/commit/378c18eb42d75852b97f849d05c9e3f650601339)) * Breaking changes from aztec-packages ([#3955](https://github.com/noir-lang/noir/issues/3955)) ([5be049e](https://github.com/noir-lang/noir/commit/5be049eee6c342649462282ee04f6411e6ea392c)) * Bubble up `Instruction::Constrain`s to be applied as early as possible. ([#4065](https://github.com/noir-lang/noir/issues/4065)) ([66f5cdd](https://github.com/noir-lang/noir/commit/66f5cddc133ba0311028eba96c0ff6ec2ecaee59)) * Cached LSP parsing ([#4083](https://github.com/noir-lang/noir/issues/4083)) ([b4f724e](https://github.com/noir-lang/noir/commit/b4f724e848b291a733e417c394ac3fc7649c08c5)) * Comparison for signed integers ([#3873](https://github.com/noir-lang/noir/issues/3873)) ([bcbd49b](https://github.com/noir-lang/noir/commit/bcbd49b8b44749e149f83c1240094fa2f0a19087)) * Decompose `Instruction::Cast` to have an explicit truncation instruction ([#3946](https://github.com/noir-lang/noir/issues/3946)) ([35f18ef](https://github.com/noir-lang/noir/commit/35f18ef4d7c8041e3cf622a5643748d0793c2aa6)) * Decompose `Instruction::Constrain` into multiple more basic constraints ([#3892](https://github.com/noir-lang/noir/issues/3892)) ([51cf9d3](https://github.com/noir-lang/noir/commit/51cf9d37c8b9fbb14bb54b178d93129a7563e131)) * Docker testing flow ([#3895](https://github.com/noir-lang/noir/issues/3895)) ([179c90d](https://github.com/noir-lang/noir/commit/179c90dc3263c85de105c57925d9c5894427e8e1)) * Extract parsing to its own pass and do it in parallel ([#4063](https://github.com/noir-lang/noir/issues/4063)) ([569cbbc](https://github.com/noir-lang/noir/commit/569cbbc231a242c32821cba56f3649f3228a1cc7)) * Implement `Eq` trait on curve points ([#3944](https://github.com/noir-lang/noir/issues/3944)) ([abf751a](https://github.com/noir-lang/noir/commit/abf751ab7f57f87520be16b2bc6168efdf95a430)) * Implement DAP protocol in Nargo ([#3627](https://github.com/noir-lang/noir/issues/3627)) ([13834d4](https://github.com/noir-lang/noir/commit/13834d43bd876909cb50494a41b42297f7e6375b)) * Implement generic traits ([#4000](https://github.com/noir-lang/noir/issues/4000)) ([916fd15](https://github.com/noir-lang/noir/commit/916fd158aa361ac80d32767f575ad896c3462b15)) * Implement Operator Overloading ([#3931](https://github.com/noir-lang/noir/issues/3931)) ([4b16090](https://github.com/noir-lang/noir/commit/4b16090beecd0fcdd41c9e7b8f615c4625c26a5b)) * **lsp:** Cache definitions for goto requests ([#3930](https://github.com/noir-lang/noir/issues/3930)) ([4a2140f](https://github.com/noir-lang/noir/commit/4a2140f1f36bbe3afbc006f8db74820308ae27d5)) * **lsp:** Goto global ([#4043](https://github.com/noir-lang/noir/issues/4043)) ([15237b3](https://github.com/noir-lang/noir/commit/15237b34dbce5ea54973a178449e67cca8ac4f9d)) * **lsp:** Goto struct member inside Impl method ([#3918](https://github.com/noir-lang/noir/issues/3918)) ([99c2c5a](https://github.com/noir-lang/noir/commit/99c2c5a2c2c0da6bad783b60d9e3de8d9a1f4ee4)) * **lsp:** Goto trait from trait impl ([#3956](https://github.com/noir-lang/noir/issues/3956)) ([eb566e2](https://github.com/noir-lang/noir/commit/eb566e2125e847a3e3efbd2bc15a88a1c454a7df)) * **lsp:** Goto trait method declaration ([#3991](https://github.com/noir-lang/noir/issues/3991)) ([eb79166](https://github.com/noir-lang/noir/commit/eb79166f7d2b7aa45c9c6c0aa37db1c0a5dfa00f)) * **lsp:** Goto type alias ([#4061](https://github.com/noir-lang/noir/issues/4061)) ([dc83385](https://github.com/noir-lang/noir/commit/dc83385e9fe5766cd8218265be38c54243cae76e)) * **lsp:** Goto type definition ([#4029](https://github.com/noir-lang/noir/issues/4029)) ([8bb4ddf](https://github.com/noir-lang/noir/commit/8bb4ddfdd81d491ff713a056a7eae522f329d173)) * **lsp:** Re-add code lens feature with improved performance ([#3829](https://github.com/noir-lang/noir/issues/3829)) ([8f5cd6c](https://github.com/noir-lang/noir/commit/8f5cd6c0b641b3970bf626e8910b2a4c7cc8c310)) * Optimize array ops for arrays of structs ([#4027](https://github.com/noir-lang/noir/issues/4027)) ([c9ec0d8](https://github.com/noir-lang/noir/commit/c9ec0d811ddc8653201ed765b51585a7c1b946fb)) * Optimize logic gate ACIR-gen ([#3897](https://github.com/noir-lang/noir/issues/3897)) ([926460a](https://github.com/noir-lang/noir/commit/926460a0c70e21e2f4720148cf424e44ab9b0678)) * Prefer `AcirContext`-native methods for performing logic operations ([#3898](https://github.com/noir-lang/noir/issues/3898)) ([0ec39b8](https://github.com/noir-lang/noir/commit/0ec39b8396084ed1e7f20609c8ad8a5844a86674)) * Remove range constraints from witnesses which are constrained to be constants ([#3928](https://github.com/noir-lang/noir/issues/3928)) ([afe9c7a](https://github.com/noir-lang/noir/commit/afe9c7a38bb9d4245205d3aa46d4ce23d70a5671)) * Remove truncation from brillig casts ([#3997](https://github.com/noir-lang/noir/issues/3997)) ([857ff97](https://github.com/noir-lang/noir/commit/857ff97b196174a0999f0fe7e387bfca5c3b7cd3)) * Remove truncations which can be seen to be noops using type information ([#3953](https://github.com/noir-lang/noir/issues/3953)) ([cc3c2c2](https://github.com/noir-lang/noir/commit/cc3c2c22644f0b5d8369bad2362ea6e9112a0713)) * Remove unnecessary predicate from `Lt` instruction ([#3922](https://github.com/noir-lang/noir/issues/3922)) ([a63433f](https://github.com/noir-lang/noir/commit/a63433fb8747722ec3cf2c6eb85d34e5b04bc15c)) * Simplify chains of casts to be all in terms of the original `ValueId` ([#3984](https://github.com/noir-lang/noir/issues/3984)) ([2384d3e](https://github.com/noir-lang/noir/commit/2384d3e97af24a8718fbf57f6b276a5ce1de06fe)) * Simplify multiplications by `0` or `1` in ACIR gen ([#3924](https://github.com/noir-lang/noir/issues/3924)) ([e58844d](https://github.com/noir-lang/noir/commit/e58844daf9f040626a3a7595f8c4f831e48a4037)) * Support for u128 ([#3913](https://github.com/noir-lang/noir/issues/3913)) ([b4911dc](https://github.com/noir-lang/noir/commit/b4911dcf676f0925ac631ba6f60fc9c4945b2fee)) * Support printing more types ([#4071](https://github.com/noir-lang/noir/issues/4071)) ([f5c4632](https://github.com/noir-lang/noir/commit/f5c4632e174beba508e1e31d0e2ae3f6d028ae2c)) * Sync `aztec-packages` ([#4011](https://github.com/noir-lang/noir/issues/4011)) ([fee2452](https://github.com/noir-lang/noir/commit/fee24523c427c27f0bdaf98ea09a852a2da3e94c)) * Sync commits from `aztec-packages` ([#4068](https://github.com/noir-lang/noir/issues/4068)) ([7a8f3a3](https://github.com/noir-lang/noir/commit/7a8f3a33b57875e681e3d81e667e3570a1cdbdcc)) * Use singleton `WasmBlackBoxFunctionSolver` in `noir_js` ([#3966](https://github.com/noir-lang/noir/issues/3966)) ([10b28de](https://github.com/noir-lang/noir/commit/10b28def4d74822b7af2c19a1cc693788272b00b)) ### Bug Fixes * Acir gen doesn't panic on unsupported BB function ([#3866](https://github.com/noir-lang/noir/issues/3866)) ([34fd978](https://github.com/noir-lang/noir/commit/34fd978d206789a9e9f5167bfd690a34386834d0)) * Allow abi encoding arrays of structs from JS ([#3867](https://github.com/noir-lang/noir/issues/3867)) ([9b713f8](https://github.com/noir-lang/noir/commit/9b713f8cf599df262a12ec1098136c50b2b46766)) * Allow abi encoding tuples from JS ([#3894](https://github.com/noir-lang/noir/issues/3894)) ([f7fa181](https://github.com/noir-lang/noir/commit/f7fa1811ad2591020c914976f26e2f11a91cd177)) * Allow ast when macro errors ([#4005](https://github.com/noir-lang/noir/issues/4005)) ([efccec3](https://github.com/noir-lang/noir/commit/efccec3c24eb093fba99b1c29f01a78aae5776d0)) * Allow lsp to run inside of a docker container ([#3876](https://github.com/noir-lang/noir/issues/3876)) ([2529977](https://github.com/noir-lang/noir/commit/2529977acd684219f57ef086415557cc07af043b)) * Bit-shifts for signed integers ([#3890](https://github.com/noir-lang/noir/issues/3890)) ([6ddd98a](https://github.com/noir-lang/noir/commit/6ddd98ab7d3fefde491cf12b785f76bf0585609e)) * Checks for cyclic dependencies ([#3699](https://github.com/noir-lang/noir/issues/3699)) ([642011a](https://github.com/noir-lang/noir/commit/642011ab6ebbe8f012eda1da1abbf8660500723d)) * **debugger:** Crash when stepping through locations spanning multiple lines ([#3920](https://github.com/noir-lang/noir/issues/3920)) ([223e860](https://github.com/noir-lang/noir/commit/223e860975c2698bd5043340b937de74552ec15b)) * Don't fail if no tests and the user didn't provide a pattern ([#3864](https://github.com/noir-lang/noir/issues/3864)) ([decbd0f](https://github.com/noir-lang/noir/commit/decbd0f0c019844cd2b235e7804d2f6ba7b23897)) * Fix advisory issue in cargo-deny ([#4077](https://github.com/noir-lang/noir/issues/4077)) ([19baea0](https://github.com/noir-lang/noir/commit/19baea0d18e2d26bd04b649f79dd8e681488d1dc)) * Fixing dark mode background on the CTA button ([#3882](https://github.com/noir-lang/noir/issues/3882)) ([57eae42](https://github.com/noir-lang/noir/commit/57eae42080d6a928e8010c6bc77489964a5777ef)) * Fixup exports from `noir_wasm` ([#4022](https://github.com/noir-lang/noir/issues/4022)) ([358cdd2](https://github.com/noir-lang/noir/commit/358cdd2725444091b3322c47754e3cbd9b1d3614)) * Handle multiple imports in the same file ([#3903](https://github.com/noir-lang/noir/issues/3903)) ([219423e](https://github.com/noir-lang/noir/commit/219423eb87fa12bd8cca2a6fd2ce4c06e308783c)) * Hoist constraints on inputs to top of program ([#4076](https://github.com/noir-lang/noir/issues/4076)) ([447aa34](https://github.com/noir-lang/noir/commit/447aa343555cbd5a7cd735876e08f43271ecdd40)) * Implement missing codegen for `BlackBoxFunc::EcdsaSecp256r1` in brillig ([#3943](https://github.com/noir-lang/noir/issues/3943)) ([2c5eceb](https://github.com/noir-lang/noir/commit/2c5eceb04ab6bc38e954492642121c7fe3da866f)) * Improve `nargo test` output ([#3973](https://github.com/noir-lang/noir/issues/3973)) ([3ab5ff4](https://github.com/noir-lang/noir/commit/3ab5ff431145a1f747b698caed15caebaa145f04)) * Make `constant_to_radix` emit a slice instead of an array ([#4049](https://github.com/noir-lang/noir/issues/4049)) ([5cdb1d0](https://github.com/noir-lang/noir/commit/5cdb1d0dabe2e38a1610f718747cc2fb4263339d)) * Operator overloading & static trait method references resolving to generic impls ([#3967](https://github.com/noir-lang/noir/issues/3967)) ([f1de8fa](https://github.com/noir-lang/noir/commit/f1de8fa3247bcee624bcd7a0f89fe7c7cd8430f1)) * Preserve brillig entrypoint functions without arguments ([#3951](https://github.com/noir-lang/noir/issues/3951)) ([1111465](https://github.com/noir-lang/noir/commit/1111465551557ed9e97e4b43d6eccc4b5896a39f)) * Prevent `Instruction::Constrain`s for non-primitive types ([#3916](https://github.com/noir-lang/noir/issues/3916)) ([467948f](https://github.com/noir-lang/noir/commit/467948f9ee9ae65b4e2badaa1d15835fced3e835)) * Remove panic for adding an invalid crate name in wasm compiler ([#3977](https://github.com/noir-lang/noir/issues/3977)) ([7a1baa5](https://github.com/noir-lang/noir/commit/7a1baa56faa2deb385ef1b6c9da9073dafd5a376)) * Return error rather instead of panicking on invalid circuit ([#3976](https://github.com/noir-lang/noir/issues/3976)) ([67201bf](https://github.com/noir-lang/noir/commit/67201bfc21a9c8858aa86be9cd47d463fb78d925)) * Search all levels of struct nesting before codegenning primitive types ([#3970](https://github.com/noir-lang/noir/issues/3970)) ([13ae014](https://github.com/noir-lang/noir/commit/13ae014ddcbd9eddb401c563b95053f7a1a89f1c)) * Update generics docs to mention we have traits now ([#3980](https://github.com/noir-lang/noir/issues/3980)) ([c2acdf1](https://github.com/noir-lang/noir/commit/c2acdf1793a67abc9a074457e057a44da3b82c39)) ### Miscellaneous Chores * Ban nested slices ([#4018](https://github.com/noir-lang/noir/issues/4018)) ([f8a1fb7](https://github.com/noir-lang/noir/commit/f8a1fb7eed1ae4a9779eb16b142a64094aa603c6)) * Remove circuit methods from noir_wasm ([#3869](https://github.com/noir-lang/noir/issues/3869)) ([12d884e](https://github.com/noir-lang/noir/commit/12d884e2b74efab7257626d8878ea1a7455ecf85)) * Rename Arithmetic opcode to AssertZero ([#3840](https://github.com/noir-lang/noir/issues/3840)) ([836f171](https://github.com/noir-lang/noir/commit/836f17145c2901060706294461c2d282dd121b3e))
0.39.0 ## [0.39.0](https://github.com/noir-lang/noir/compare/v0.38.0...v0.39.0) (2024-01-22) ### ⚠ BREAKING CHANGES * Breaking changes from aztec-packages ([#3955](https://github.com/noir-lang/noir/issues/3955)) * Rename Arithmetic opcode to AssertZero ([#3840](https://github.com/noir-lang/noir/issues/3840)) * Remove unused methods on ACIR opcodes ([#3841](https://github.com/noir-lang/noir/issues/3841)) * Remove partial backend feature ([#3805](https://github.com/noir-lang/noir/issues/3805)) ### Features * Aztec-packages ([#3754](https://github.com/noir-lang/noir/issues/3754)) ([c043265](https://github.com/noir-lang/noir/commit/c043265e550b59bd4296504826fe15d3ce3e9ad2)) * Breaking changes from aztec-packages ([#3955](https://github.com/noir-lang/noir/issues/3955)) ([5be049e](https://github.com/noir-lang/noir/commit/5be049eee6c342649462282ee04f6411e6ea392c)) * Remove range constraints from witnesses which are constrained to be constants ([#3928](https://github.com/noir-lang/noir/issues/3928)) ([afe9c7a](https://github.com/noir-lang/noir/commit/afe9c7a38bb9d4245205d3aa46d4ce23d70a5671)) * Speed up transformation of debug messages ([#3815](https://github.com/noir-lang/noir/issues/3815)) ([2a8af1e](https://github.com/noir-lang/noir/commit/2a8af1e4141ffff61547ee1c2837a6392bd5db48)) * Sync `aztec-packages` ([#4011](https://github.com/noir-lang/noir/issues/4011)) ([fee2452](https://github.com/noir-lang/noir/commit/fee24523c427c27f0bdaf98ea09a852a2da3e94c)) * Sync commits from `aztec-packages` ([#4068](https://github.com/noir-lang/noir/issues/4068)) ([7a8f3a3](https://github.com/noir-lang/noir/commit/7a8f3a33b57875e681e3d81e667e3570a1cdbdcc)) ### Bug Fixes * Deserialize odd length hex literals ([#3747](https://github.com/noir-lang/noir/issues/3747)) ([4000fb2](https://github.com/noir-lang/noir/commit/4000fb279221eb07187d657bfaa7f1c7b311abf2)) * Return error rather instead of panicking on invalid circuit ([#3976](https://github.com/noir-lang/noir/issues/3976)) ([67201bf](https://github.com/noir-lang/noir/commit/67201bfc21a9c8858aa86be9cd47d463fb78d925)) ### Miscellaneous Chores * Remove partial backend feature ([#3805](https://github.com/noir-lang/noir/issues/3805)) ([0383100](https://github.com/noir-lang/noir/commit/0383100853a80a5b28b797cdfeae0d271f1b7805)) * Remove unused methods on ACIR opcodes ([#3841](https://github.com/noir-lang/noir/issues/3841)) ([9e5d0e8](https://github.com/noir-lang/noir/commit/9e5d0e813d61a0bfb5ee68174ed287c5a20f1579)) * Rename Arithmetic opcode to AssertZero ([#3840](https://github.com/noir-lang/noir/issues/3840)) ([836f171](https://github.com/noir-lang/noir/commit/836f17145c2901060706294461c2d282dd121b3e))
--- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). --------- Co-authored-by: TomAFrench --- .release-please-manifest.json | 4 +- CHANGELOG.md | 92 +++++++++++++++++++ Cargo.lock | 52 +++++------ Cargo.toml | 16 ++-- acvm-repo/CHANGELOG.md | 32 +++++++ acvm-repo/acir/Cargo.toml | 2 +- acvm-repo/acir_field/Cargo.toml | 2 +- acvm-repo/acvm/Cargo.toml | 2 +- acvm-repo/acvm_js/Cargo.toml | 2 +- acvm-repo/acvm_js/package.json | 2 +- acvm-repo/blackbox_solver/Cargo.toml | 2 +- acvm-repo/bn254_blackbox_solver/Cargo.toml | 2 +- acvm-repo/brillig/Cargo.toml | 2 +- acvm-repo/brillig_vm/Cargo.toml | 2 +- compiler/wasm/package.json | 2 +- flake.nix | 2 +- tooling/noir_codegen/package.json | 2 +- tooling/noir_js/package.json | 2 +- .../noir_js_backend_barretenberg/package.json | 2 +- tooling/noir_js_types/package.json | 2 +- tooling/noirc_abi_wasm/package.json | 2 +- yarn.lock | 74 ++++++++++++++- 22 files changed, 246 insertions(+), 56 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 01f6fb140b1..f440a7a2c51 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,4 +1,4 @@ { - ".": "0.22.0", - "acvm-repo": "0.38.0" + ".": "0.23.0", + "acvm-repo": "0.39.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 3fc044076a0..af7eb5b2f19 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,97 @@ # Changelog +## [0.23.0](https://github.com/noir-lang/noir/compare/v0.22.0...v0.23.0) (2024-01-22) + + +### ⚠ BREAKING CHANGES + +* Ban nested slices ([#4018](https://github.com/noir-lang/noir/issues/4018)) +* Breaking changes from aztec-packages ([#3955](https://github.com/noir-lang/noir/issues/3955)) +* Rename Arithmetic opcode to AssertZero ([#3840](https://github.com/noir-lang/noir/issues/3840)) +* remove circuit methods from noir_wasm ([#3869](https://github.com/noir-lang/noir/issues/3869)) + +### Features + +* Add `assert_max_bit_size` method to `Field` ([#4016](https://github.com/noir-lang/noir/issues/4016)) ([bc9a44f](https://github.com/noir-lang/noir/commit/bc9a44f285e0569825a307b06ee8acd93461c87e)) +* Add `noir-compiler` checks to `aztec_macros` ([#4031](https://github.com/noir-lang/noir/issues/4031)) ([420a5c7](https://github.com/noir-lang/noir/commit/420a5c74a14dcfeede04337a42282093a7b5e63e)) +* Add a `--force` flag to force a full recompile ([#4054](https://github.com/noir-lang/noir/issues/4054)) ([27a8e68](https://github.com/noir-lang/noir/commit/27a8e6864643d81d96e84990e2e26cd16596a695)) +* Add dependency resolver for `noir_wasm` and implement `FileManager` for consistency with native interface ([#3891](https://github.com/noir-lang/noir/issues/3891)) ([c29c7d7](https://github.com/noir-lang/noir/commit/c29c7d7c9615b9f45c696b1bdc1c497d55469dfa)) +* Add foreign call support to `noir_codegen` functions ([#3933](https://github.com/noir-lang/noir/issues/3933)) ([e5e52a8](https://github.com/noir-lang/noir/commit/e5e52a81b31d7735b680e97a9bef89a010a99763)) +* Add MVP `nargo export` command ([#3870](https://github.com/noir-lang/noir/issues/3870)) ([fbb51ed](https://github.com/noir-lang/noir/commit/fbb51ed33e9e4d9105d8946cdfc4ea387c85258e)) +* Add support for codegenning multiple functions which use the same structs in their interface ([#3868](https://github.com/noir-lang/noir/issues/3868)) ([1dcfcc5](https://github.com/noir-lang/noir/commit/1dcfcc5265f618685a783504b1d4be213e4cda2d)) +* Added efficient field comparisons for bn254 ([#4042](https://github.com/noir-lang/noir/issues/4042)) ([1f9cad0](https://github.com/noir-lang/noir/commit/1f9cad00c57ea257f57419d2446a46938beb19f9)) +* Assert maximum bit size when creating a U128 from an integer ([#4024](https://github.com/noir-lang/noir/issues/4024)) ([8f9c7e4](https://github.com/noir-lang/noir/commit/8f9c7e4de9f2ae5b39714d8e0d26b2befcd11c4a)) +* Avoid unnecessary range checks by inspecting instructions for casts ([#4039](https://github.com/noir-lang/noir/issues/4039)) ([378c18e](https://github.com/noir-lang/noir/commit/378c18eb42d75852b97f849d05c9e3f650601339)) +* Breaking changes from aztec-packages ([#3955](https://github.com/noir-lang/noir/issues/3955)) ([5be049e](https://github.com/noir-lang/noir/commit/5be049eee6c342649462282ee04f6411e6ea392c)) +* Bubble up `Instruction::Constrain`s to be applied as early as possible. ([#4065](https://github.com/noir-lang/noir/issues/4065)) ([66f5cdd](https://github.com/noir-lang/noir/commit/66f5cddc133ba0311028eba96c0ff6ec2ecaee59)) +* Cached LSP parsing ([#4083](https://github.com/noir-lang/noir/issues/4083)) ([b4f724e](https://github.com/noir-lang/noir/commit/b4f724e848b291a733e417c394ac3fc7649c08c5)) +* Comparison for signed integers ([#3873](https://github.com/noir-lang/noir/issues/3873)) ([bcbd49b](https://github.com/noir-lang/noir/commit/bcbd49b8b44749e149f83c1240094fa2f0a19087)) +* Decompose `Instruction::Cast` to have an explicit truncation instruction ([#3946](https://github.com/noir-lang/noir/issues/3946)) ([35f18ef](https://github.com/noir-lang/noir/commit/35f18ef4d7c8041e3cf622a5643748d0793c2aa6)) +* Decompose `Instruction::Constrain` into multiple more basic constraints ([#3892](https://github.com/noir-lang/noir/issues/3892)) ([51cf9d3](https://github.com/noir-lang/noir/commit/51cf9d37c8b9fbb14bb54b178d93129a7563e131)) +* Docker testing flow ([#3895](https://github.com/noir-lang/noir/issues/3895)) ([179c90d](https://github.com/noir-lang/noir/commit/179c90dc3263c85de105c57925d9c5894427e8e1)) +* Extract parsing to its own pass and do it in parallel ([#4063](https://github.com/noir-lang/noir/issues/4063)) ([569cbbc](https://github.com/noir-lang/noir/commit/569cbbc231a242c32821cba56f3649f3228a1cc7)) +* Implement `Eq` trait on curve points ([#3944](https://github.com/noir-lang/noir/issues/3944)) ([abf751a](https://github.com/noir-lang/noir/commit/abf751ab7f57f87520be16b2bc6168efdf95a430)) +* Implement DAP protocol in Nargo ([#3627](https://github.com/noir-lang/noir/issues/3627)) ([13834d4](https://github.com/noir-lang/noir/commit/13834d43bd876909cb50494a41b42297f7e6375b)) +* Implement generic traits ([#4000](https://github.com/noir-lang/noir/issues/4000)) ([916fd15](https://github.com/noir-lang/noir/commit/916fd158aa361ac80d32767f575ad896c3462b15)) +* Implement Operator Overloading ([#3931](https://github.com/noir-lang/noir/issues/3931)) ([4b16090](https://github.com/noir-lang/noir/commit/4b16090beecd0fcdd41c9e7b8f615c4625c26a5b)) +* **lsp:** Cache definitions for goto requests ([#3930](https://github.com/noir-lang/noir/issues/3930)) ([4a2140f](https://github.com/noir-lang/noir/commit/4a2140f1f36bbe3afbc006f8db74820308ae27d5)) +* **lsp:** Goto global ([#4043](https://github.com/noir-lang/noir/issues/4043)) ([15237b3](https://github.com/noir-lang/noir/commit/15237b34dbce5ea54973a178449e67cca8ac4f9d)) +* **lsp:** Goto struct member inside Impl method ([#3918](https://github.com/noir-lang/noir/issues/3918)) ([99c2c5a](https://github.com/noir-lang/noir/commit/99c2c5a2c2c0da6bad783b60d9e3de8d9a1f4ee4)) +* **lsp:** Goto trait from trait impl ([#3956](https://github.com/noir-lang/noir/issues/3956)) ([eb566e2](https://github.com/noir-lang/noir/commit/eb566e2125e847a3e3efbd2bc15a88a1c454a7df)) +* **lsp:** Goto trait method declaration ([#3991](https://github.com/noir-lang/noir/issues/3991)) ([eb79166](https://github.com/noir-lang/noir/commit/eb79166f7d2b7aa45c9c6c0aa37db1c0a5dfa00f)) +* **lsp:** Goto type alias ([#4061](https://github.com/noir-lang/noir/issues/4061)) ([dc83385](https://github.com/noir-lang/noir/commit/dc83385e9fe5766cd8218265be38c54243cae76e)) +* **lsp:** Goto type definition ([#4029](https://github.com/noir-lang/noir/issues/4029)) ([8bb4ddf](https://github.com/noir-lang/noir/commit/8bb4ddfdd81d491ff713a056a7eae522f329d173)) +* **lsp:** Re-add code lens feature with improved performance ([#3829](https://github.com/noir-lang/noir/issues/3829)) ([8f5cd6c](https://github.com/noir-lang/noir/commit/8f5cd6c0b641b3970bf626e8910b2a4c7cc8c310)) +* Optimize array ops for arrays of structs ([#4027](https://github.com/noir-lang/noir/issues/4027)) ([c9ec0d8](https://github.com/noir-lang/noir/commit/c9ec0d811ddc8653201ed765b51585a7c1b946fb)) +* Optimize logic gate ACIR-gen ([#3897](https://github.com/noir-lang/noir/issues/3897)) ([926460a](https://github.com/noir-lang/noir/commit/926460a0c70e21e2f4720148cf424e44ab9b0678)) +* Prefer `AcirContext`-native methods for performing logic operations ([#3898](https://github.com/noir-lang/noir/issues/3898)) ([0ec39b8](https://github.com/noir-lang/noir/commit/0ec39b8396084ed1e7f20609c8ad8a5844a86674)) +* Remove range constraints from witnesses which are constrained to be constants ([#3928](https://github.com/noir-lang/noir/issues/3928)) ([afe9c7a](https://github.com/noir-lang/noir/commit/afe9c7a38bb9d4245205d3aa46d4ce23d70a5671)) +* Remove truncation from brillig casts ([#3997](https://github.com/noir-lang/noir/issues/3997)) ([857ff97](https://github.com/noir-lang/noir/commit/857ff97b196174a0999f0fe7e387bfca5c3b7cd3)) +* Remove truncations which can be seen to be noops using type information ([#3953](https://github.com/noir-lang/noir/issues/3953)) ([cc3c2c2](https://github.com/noir-lang/noir/commit/cc3c2c22644f0b5d8369bad2362ea6e9112a0713)) +* Remove unnecessary predicate from `Lt` instruction ([#3922](https://github.com/noir-lang/noir/issues/3922)) ([a63433f](https://github.com/noir-lang/noir/commit/a63433fb8747722ec3cf2c6eb85d34e5b04bc15c)) +* Simplify chains of casts to be all in terms of the original `ValueId` ([#3984](https://github.com/noir-lang/noir/issues/3984)) ([2384d3e](https://github.com/noir-lang/noir/commit/2384d3e97af24a8718fbf57f6b276a5ce1de06fe)) +* Simplify multiplications by `0` or `1` in ACIR gen ([#3924](https://github.com/noir-lang/noir/issues/3924)) ([e58844d](https://github.com/noir-lang/noir/commit/e58844daf9f040626a3a7595f8c4f831e48a4037)) +* Support for u128 ([#3913](https://github.com/noir-lang/noir/issues/3913)) ([b4911dc](https://github.com/noir-lang/noir/commit/b4911dcf676f0925ac631ba6f60fc9c4945b2fee)) +* Support printing more types ([#4071](https://github.com/noir-lang/noir/issues/4071)) ([f5c4632](https://github.com/noir-lang/noir/commit/f5c4632e174beba508e1e31d0e2ae3f6d028ae2c)) +* Sync `aztec-packages` ([#4011](https://github.com/noir-lang/noir/issues/4011)) ([fee2452](https://github.com/noir-lang/noir/commit/fee24523c427c27f0bdaf98ea09a852a2da3e94c)) +* Sync commits from `aztec-packages` ([#4068](https://github.com/noir-lang/noir/issues/4068)) ([7a8f3a3](https://github.com/noir-lang/noir/commit/7a8f3a33b57875e681e3d81e667e3570a1cdbdcc)) +* Use singleton `WasmBlackBoxFunctionSolver` in `noir_js` ([#3966](https://github.com/noir-lang/noir/issues/3966)) ([10b28de](https://github.com/noir-lang/noir/commit/10b28def4d74822b7af2c19a1cc693788272b00b)) + + +### Bug Fixes + +* Acir gen doesn't panic on unsupported BB function ([#3866](https://github.com/noir-lang/noir/issues/3866)) ([34fd978](https://github.com/noir-lang/noir/commit/34fd978d206789a9e9f5167bfd690a34386834d0)) +* Allow abi encoding arrays of structs from JS ([#3867](https://github.com/noir-lang/noir/issues/3867)) ([9b713f8](https://github.com/noir-lang/noir/commit/9b713f8cf599df262a12ec1098136c50b2b46766)) +* Allow abi encoding tuples from JS ([#3894](https://github.com/noir-lang/noir/issues/3894)) ([f7fa181](https://github.com/noir-lang/noir/commit/f7fa1811ad2591020c914976f26e2f11a91cd177)) +* Allow ast when macro errors ([#4005](https://github.com/noir-lang/noir/issues/4005)) ([efccec3](https://github.com/noir-lang/noir/commit/efccec3c24eb093fba99b1c29f01a78aae5776d0)) +* Allow lsp to run inside of a docker container ([#3876](https://github.com/noir-lang/noir/issues/3876)) ([2529977](https://github.com/noir-lang/noir/commit/2529977acd684219f57ef086415557cc07af043b)) +* Bit-shifts for signed integers ([#3890](https://github.com/noir-lang/noir/issues/3890)) ([6ddd98a](https://github.com/noir-lang/noir/commit/6ddd98ab7d3fefde491cf12b785f76bf0585609e)) +* Checks for cyclic dependencies ([#3699](https://github.com/noir-lang/noir/issues/3699)) ([642011a](https://github.com/noir-lang/noir/commit/642011ab6ebbe8f012eda1da1abbf8660500723d)) +* **debugger:** Crash when stepping through locations spanning multiple lines ([#3920](https://github.com/noir-lang/noir/issues/3920)) ([223e860](https://github.com/noir-lang/noir/commit/223e860975c2698bd5043340b937de74552ec15b)) +* Don't fail if no tests and the user didn't provide a pattern ([#3864](https://github.com/noir-lang/noir/issues/3864)) ([decbd0f](https://github.com/noir-lang/noir/commit/decbd0f0c019844cd2b235e7804d2f6ba7b23897)) +* Fix advisory issue in cargo-deny ([#4077](https://github.com/noir-lang/noir/issues/4077)) ([19baea0](https://github.com/noir-lang/noir/commit/19baea0d18e2d26bd04b649f79dd8e681488d1dc)) +* Fixing dark mode background on the CTA button ([#3882](https://github.com/noir-lang/noir/issues/3882)) ([57eae42](https://github.com/noir-lang/noir/commit/57eae42080d6a928e8010c6bc77489964a5777ef)) +* Fixup exports from `noir_wasm` ([#4022](https://github.com/noir-lang/noir/issues/4022)) ([358cdd2](https://github.com/noir-lang/noir/commit/358cdd2725444091b3322c47754e3cbd9b1d3614)) +* Handle multiple imports in the same file ([#3903](https://github.com/noir-lang/noir/issues/3903)) ([219423e](https://github.com/noir-lang/noir/commit/219423eb87fa12bd8cca2a6fd2ce4c06e308783c)) +* Hoist constraints on inputs to top of program ([#4076](https://github.com/noir-lang/noir/issues/4076)) ([447aa34](https://github.com/noir-lang/noir/commit/447aa343555cbd5a7cd735876e08f43271ecdd40)) +* Implement missing codegen for `BlackBoxFunc::EcdsaSecp256r1` in brillig ([#3943](https://github.com/noir-lang/noir/issues/3943)) ([2c5eceb](https://github.com/noir-lang/noir/commit/2c5eceb04ab6bc38e954492642121c7fe3da866f)) +* Improve `nargo test` output ([#3973](https://github.com/noir-lang/noir/issues/3973)) ([3ab5ff4](https://github.com/noir-lang/noir/commit/3ab5ff431145a1f747b698caed15caebaa145f04)) +* Make `constant_to_radix` emit a slice instead of an array ([#4049](https://github.com/noir-lang/noir/issues/4049)) ([5cdb1d0](https://github.com/noir-lang/noir/commit/5cdb1d0dabe2e38a1610f718747cc2fb4263339d)) +* Operator overloading & static trait method references resolving to generic impls ([#3967](https://github.com/noir-lang/noir/issues/3967)) ([f1de8fa](https://github.com/noir-lang/noir/commit/f1de8fa3247bcee624bcd7a0f89fe7c7cd8430f1)) +* Preserve brillig entrypoint functions without arguments ([#3951](https://github.com/noir-lang/noir/issues/3951)) ([1111465](https://github.com/noir-lang/noir/commit/1111465551557ed9e97e4b43d6eccc4b5896a39f)) +* Prevent `Instruction::Constrain`s for non-primitive types ([#3916](https://github.com/noir-lang/noir/issues/3916)) ([467948f](https://github.com/noir-lang/noir/commit/467948f9ee9ae65b4e2badaa1d15835fced3e835)) +* Remove panic for adding an invalid crate name in wasm compiler ([#3977](https://github.com/noir-lang/noir/issues/3977)) ([7a1baa5](https://github.com/noir-lang/noir/commit/7a1baa56faa2deb385ef1b6c9da9073dafd5a376)) +* Return error rather instead of panicking on invalid circuit ([#3976](https://github.com/noir-lang/noir/issues/3976)) ([67201bf](https://github.com/noir-lang/noir/commit/67201bfc21a9c8858aa86be9cd47d463fb78d925)) +* Search all levels of struct nesting before codegenning primitive types ([#3970](https://github.com/noir-lang/noir/issues/3970)) ([13ae014](https://github.com/noir-lang/noir/commit/13ae014ddcbd9eddb401c563b95053f7a1a89f1c)) +* Update generics docs to mention we have traits now ([#3980](https://github.com/noir-lang/noir/issues/3980)) ([c2acdf1](https://github.com/noir-lang/noir/commit/c2acdf1793a67abc9a074457e057a44da3b82c39)) + + +### Miscellaneous Chores + +* Ban nested slices ([#4018](https://github.com/noir-lang/noir/issues/4018)) ([f8a1fb7](https://github.com/noir-lang/noir/commit/f8a1fb7eed1ae4a9779eb16b142a64094aa603c6)) +* Remove circuit methods from noir_wasm ([#3869](https://github.com/noir-lang/noir/issues/3869)) ([12d884e](https://github.com/noir-lang/noir/commit/12d884e2b74efab7257626d8878ea1a7455ecf85)) +* Rename Arithmetic opcode to AssertZero ([#3840](https://github.com/noir-lang/noir/issues/3840)) ([836f171](https://github.com/noir-lang/noir/commit/836f17145c2901060706294461c2d282dd121b3e)) + ## [0.22.0](https://github.com/noir-lang/noir/compare/v0.21.0...v0.22.0) (2023-12-18) diff --git a/Cargo.lock b/Cargo.lock index 95be87306ce..93f1d25fc76 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,7 +4,7 @@ version = 3 [[package]] name = "acir" -version = "0.38.0" +version = "0.39.0" dependencies = [ "acir_field", "base64 0.21.2", @@ -23,7 +23,7 @@ dependencies = [ [[package]] name = "acir_field" -version = "0.38.0" +version = "0.39.0" dependencies = [ "ark-bls12-381", "ark-bn254", @@ -37,7 +37,7 @@ dependencies = [ [[package]] name = "acvm" -version = "0.38.0" +version = "0.39.0" dependencies = [ "acir", "acvm_blackbox_solver", @@ -53,7 +53,7 @@ dependencies = [ [[package]] name = "acvm_blackbox_solver" -version = "0.38.0" +version = "0.39.0" dependencies = [ "acir", "blake2", @@ -68,7 +68,7 @@ dependencies = [ [[package]] name = "acvm_js" -version = "0.38.0" +version = "0.39.0" dependencies = [ "acvm", "bn254_blackbox_solver", @@ -212,7 +212,7 @@ checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" [[package]] name = "arena" -version = "0.22.0" +version = "0.23.0" dependencies = [ "generational-arena", ] @@ -416,7 +416,7 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "aztec_macros" -version = "0.22.0" +version = "0.23.0" dependencies = [ "iter-extended", "noirc_frontend", @@ -580,7 +580,7 @@ dependencies = [ [[package]] name = "bn254_blackbox_solver" -version = "0.38.0" +version = "0.39.0" dependencies = [ "acir", "acvm_blackbox_solver", @@ -602,7 +602,7 @@ dependencies = [ [[package]] name = "brillig" -version = "0.38.0" +version = "0.39.0" dependencies = [ "acir_field", "serde", @@ -610,7 +610,7 @@ dependencies = [ [[package]] name = "brillig_vm" -version = "0.38.0" +version = "0.39.0" dependencies = [ "acir", "acvm_blackbox_solver", @@ -1683,7 +1683,7 @@ dependencies = [ [[package]] name = "fm" -version = "0.22.0" +version = "0.23.0" dependencies = [ "codespan-reporting", "iter-extended", @@ -2295,7 +2295,7 @@ dependencies = [ [[package]] name = "iter-extended" -version = "0.22.0" +version = "0.23.0" [[package]] name = "itertools" @@ -2648,7 +2648,7 @@ checksum = "7843ec2de400bcbc6a6328c958dc38e5359da6e93e72e37bc5246bf1ae776389" [[package]] name = "nargo" -version = "0.22.0" +version = "0.23.0" dependencies = [ "acvm", "codespan-reporting", @@ -2676,7 +2676,7 @@ dependencies = [ [[package]] name = "nargo_cli" -version = "0.22.0" +version = "0.23.0" dependencies = [ "acvm", "assert_cmd", @@ -2727,7 +2727,7 @@ dependencies = [ [[package]] name = "nargo_fmt" -version = "0.22.0" +version = "0.23.0" dependencies = [ "bytecount", "noirc_frontend", @@ -2739,7 +2739,7 @@ dependencies = [ [[package]] name = "nargo_toml" -version = "0.22.0" +version = "0.23.0" dependencies = [ "dirs", "fm", @@ -2812,7 +2812,7 @@ dependencies = [ [[package]] name = "noir_debugger" -version = "0.22.0" +version = "0.23.0" dependencies = [ "acvm", "assert_cmd", @@ -2835,7 +2835,7 @@ dependencies = [ [[package]] name = "noir_lsp" -version = "0.22.0" +version = "0.23.0" dependencies = [ "acvm", "async-lsp", @@ -2861,7 +2861,7 @@ dependencies = [ [[package]] name = "noir_wasm" -version = "0.22.0" +version = "0.23.0" dependencies = [ "acvm", "build-data", @@ -2884,7 +2884,7 @@ dependencies = [ [[package]] name = "noirc_abi" -version = "0.22.0" +version = "0.23.0" dependencies = [ "acvm", "iter-extended", @@ -2901,7 +2901,7 @@ dependencies = [ [[package]] name = "noirc_abi_wasm" -version = "0.22.0" +version = "0.23.0" dependencies = [ "acvm", "build-data", @@ -2918,7 +2918,7 @@ dependencies = [ [[package]] name = "noirc_driver" -version = "0.22.0" +version = "0.23.0" dependencies = [ "acvm", "aztec_macros", @@ -2938,7 +2938,7 @@ dependencies = [ [[package]] name = "noirc_errors" -version = "0.22.0" +version = "0.23.0" dependencies = [ "acvm", "base64 0.21.2", @@ -2955,7 +2955,7 @@ dependencies = [ [[package]] name = "noirc_evaluator" -version = "0.22.0" +version = "0.23.0" dependencies = [ "acvm", "fxhash", @@ -2971,7 +2971,7 @@ dependencies = [ [[package]] name = "noirc_frontend" -version = "0.22.0" +version = "0.23.0" dependencies = [ "acvm", "arena", @@ -2995,7 +2995,7 @@ dependencies = [ [[package]] name = "noirc_printable_type" -version = "0.22.0" +version = "0.23.0" dependencies = [ "acvm", "iter-extended", diff --git a/Cargo.toml b/Cargo.toml index f0fc7249efc..8a827cacfcd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,7 +38,7 @@ resolver = "2" [workspace.package] # x-release-please-start-version -version = "0.22.0" +version = "0.23.0" # x-release-please-end authors = ["The Noir Team "] edition = "2021" @@ -49,14 +49,14 @@ repository = "https://github.com/noir-lang/noir/" [workspace.dependencies] # ACVM workspace dependencies -acir_field = { version = "0.38.0", path = "acvm-repo/acir_field", default-features = false } -acir = { version = "0.38.0", path = "acvm-repo/acir", default-features = false } -acvm = { version = "0.38.0", path = "acvm-repo/acvm" } +acir_field = { version = "0.39.0", path = "acvm-repo/acir_field", default-features = false } +acir = { version = "0.39.0", path = "acvm-repo/acir", default-features = false } +acvm = { version = "0.39.0", path = "acvm-repo/acvm" } stdlib = { version = "0.37.1", package = "acvm_stdlib", path = "acvm-repo/stdlib", default-features = false } -brillig = { version = "0.38.0", path = "acvm-repo/brillig", default-features = false } -brillig_vm = { version = "0.38.0", path = "acvm-repo/brillig_vm", default-features = false } -acvm_blackbox_solver = { version = "0.38.0", path = "acvm-repo/blackbox_solver", default-features = false } -bn254_blackbox_solver = { version = "0.38.0", path = "acvm-repo/bn254_blackbox_solver", default-features = false } +brillig = { version = "0.39.0", path = "acvm-repo/brillig", default-features = false } +brillig_vm = { version = "0.39.0", path = "acvm-repo/brillig_vm", default-features = false } +acvm_blackbox_solver = { version = "0.39.0", path = "acvm-repo/blackbox_solver", default-features = false } +bn254_blackbox_solver = { version = "0.39.0", path = "acvm-repo/bn254_blackbox_solver", default-features = false } # Noir compiler workspace dependencies arena = { path = "compiler/utils/arena" } diff --git a/acvm-repo/CHANGELOG.md b/acvm-repo/CHANGELOG.md index d413bd390c4..7f68244a7eb 100644 --- a/acvm-repo/CHANGELOG.md +++ b/acvm-repo/CHANGELOG.md @@ -5,6 +5,38 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.39.0](https://github.com/noir-lang/noir/compare/v0.38.0...v0.39.0) (2024-01-22) + + +### ⚠ BREAKING CHANGES + +* Breaking changes from aztec-packages ([#3955](https://github.com/noir-lang/noir/issues/3955)) +* Rename Arithmetic opcode to AssertZero ([#3840](https://github.com/noir-lang/noir/issues/3840)) +* Remove unused methods on ACIR opcodes ([#3841](https://github.com/noir-lang/noir/issues/3841)) +* Remove partial backend feature ([#3805](https://github.com/noir-lang/noir/issues/3805)) + +### Features + +* Aztec-packages ([#3754](https://github.com/noir-lang/noir/issues/3754)) ([c043265](https://github.com/noir-lang/noir/commit/c043265e550b59bd4296504826fe15d3ce3e9ad2)) +* Breaking changes from aztec-packages ([#3955](https://github.com/noir-lang/noir/issues/3955)) ([5be049e](https://github.com/noir-lang/noir/commit/5be049eee6c342649462282ee04f6411e6ea392c)) +* Remove range constraints from witnesses which are constrained to be constants ([#3928](https://github.com/noir-lang/noir/issues/3928)) ([afe9c7a](https://github.com/noir-lang/noir/commit/afe9c7a38bb9d4245205d3aa46d4ce23d70a5671)) +* Speed up transformation of debug messages ([#3815](https://github.com/noir-lang/noir/issues/3815)) ([2a8af1e](https://github.com/noir-lang/noir/commit/2a8af1e4141ffff61547ee1c2837a6392bd5db48)) +* Sync `aztec-packages` ([#4011](https://github.com/noir-lang/noir/issues/4011)) ([fee2452](https://github.com/noir-lang/noir/commit/fee24523c427c27f0bdaf98ea09a852a2da3e94c)) +* Sync commits from `aztec-packages` ([#4068](https://github.com/noir-lang/noir/issues/4068)) ([7a8f3a3](https://github.com/noir-lang/noir/commit/7a8f3a33b57875e681e3d81e667e3570a1cdbdcc)) + + +### Bug Fixes + +* Deserialize odd length hex literals ([#3747](https://github.com/noir-lang/noir/issues/3747)) ([4000fb2](https://github.com/noir-lang/noir/commit/4000fb279221eb07187d657bfaa7f1c7b311abf2)) +* Return error rather instead of panicking on invalid circuit ([#3976](https://github.com/noir-lang/noir/issues/3976)) ([67201bf](https://github.com/noir-lang/noir/commit/67201bfc21a9c8858aa86be9cd47d463fb78d925)) + + +### Miscellaneous Chores + +* Remove partial backend feature ([#3805](https://github.com/noir-lang/noir/issues/3805)) ([0383100](https://github.com/noir-lang/noir/commit/0383100853a80a5b28b797cdfeae0d271f1b7805)) +* Remove unused methods on ACIR opcodes ([#3841](https://github.com/noir-lang/noir/issues/3841)) ([9e5d0e8](https://github.com/noir-lang/noir/commit/9e5d0e813d61a0bfb5ee68174ed287c5a20f1579)) +* Rename Arithmetic opcode to AssertZero ([#3840](https://github.com/noir-lang/noir/issues/3840)) ([836f171](https://github.com/noir-lang/noir/commit/836f17145c2901060706294461c2d282dd121b3e)) + ## [0.38.0](https://github.com/noir-lang/noir/compare/v0.37.1...v0.38.0) (2023-12-18) diff --git a/acvm-repo/acir/Cargo.toml b/acvm-repo/acir/Cargo.toml index b44c64dd838..49b10c57cc8 100644 --- a/acvm-repo/acir/Cargo.toml +++ b/acvm-repo/acir/Cargo.toml @@ -2,7 +2,7 @@ name = "acir" description = "ACIR is the IR that the VM processes, it is analogous to LLVM IR" # x-release-please-start-version -version = "0.38.0" +version = "0.39.0" # x-release-please-end authors.workspace = true edition.workspace = true diff --git a/acvm-repo/acir_field/Cargo.toml b/acvm-repo/acir_field/Cargo.toml index cedfc66e734..dde121f4029 100644 --- a/acvm-repo/acir_field/Cargo.toml +++ b/acvm-repo/acir_field/Cargo.toml @@ -2,7 +2,7 @@ name = "acir_field" description = "The field implementation being used by ACIR." # x-release-please-start-version -version = "0.38.0" +version = "0.39.0" # x-release-please-end authors.workspace = true edition.workspace = true diff --git a/acvm-repo/acvm/Cargo.toml b/acvm-repo/acvm/Cargo.toml index be2391a3216..a40148a01ef 100644 --- a/acvm-repo/acvm/Cargo.toml +++ b/acvm-repo/acvm/Cargo.toml @@ -2,7 +2,7 @@ name = "acvm" description = "The virtual machine that processes ACIR given a backend/proof system." # x-release-please-start-version -version = "0.38.0" +version = "0.39.0" # x-release-please-end authors.workspace = true edition.workspace = true diff --git a/acvm-repo/acvm_js/Cargo.toml b/acvm-repo/acvm_js/Cargo.toml index e8d46b9717e..226e273c306 100644 --- a/acvm-repo/acvm_js/Cargo.toml +++ b/acvm-repo/acvm_js/Cargo.toml @@ -2,7 +2,7 @@ name = "acvm_js" description = "Typescript wrapper around the ACVM allowing execution of ACIR code" # x-release-please-start-version -version = "0.38.0" +version = "0.39.0" # x-release-please-end authors.workspace = true edition.workspace = true diff --git a/acvm-repo/acvm_js/package.json b/acvm-repo/acvm_js/package.json index 2d878e961da..4ec9b1a2da3 100644 --- a/acvm-repo/acvm_js/package.json +++ b/acvm-repo/acvm_js/package.json @@ -1,6 +1,6 @@ { "name": "@noir-lang/acvm_js", - "version": "0.38.0", + "version": "0.39.0", "publishConfig": { "access": "public" }, diff --git a/acvm-repo/blackbox_solver/Cargo.toml b/acvm-repo/blackbox_solver/Cargo.toml index 749ef8f289a..7359cf307e4 100644 --- a/acvm-repo/blackbox_solver/Cargo.toml +++ b/acvm-repo/blackbox_solver/Cargo.toml @@ -2,7 +2,7 @@ name = "acvm_blackbox_solver" description = "A solver for the blackbox functions found in ACIR and Brillig" # x-release-please-start-version -version = "0.38.0" +version = "0.39.0" # x-release-please-end authors.workspace = true edition.workspace = true diff --git a/acvm-repo/bn254_blackbox_solver/Cargo.toml b/acvm-repo/bn254_blackbox_solver/Cargo.toml index b98bb370f74..a73aded231f 100644 --- a/acvm-repo/bn254_blackbox_solver/Cargo.toml +++ b/acvm-repo/bn254_blackbox_solver/Cargo.toml @@ -2,7 +2,7 @@ name = "bn254_blackbox_solver" description = "Solvers for black box functions which are specific for the bn254 curve" # x-release-please-start-version -version = "0.38.0" +version = "0.39.0" # x-release-please-end authors.workspace = true edition.workspace = true diff --git a/acvm-repo/brillig/Cargo.toml b/acvm-repo/brillig/Cargo.toml index ee8651faeec..b9cedfe8d60 100644 --- a/acvm-repo/brillig/Cargo.toml +++ b/acvm-repo/brillig/Cargo.toml @@ -2,7 +2,7 @@ name = "brillig" description = "Brillig is the bytecode ACIR uses for non-determinism." # x-release-please-start-version -version = "0.38.0" +version = "0.39.0" # x-release-please-end authors.workspace = true edition.workspace = true diff --git a/acvm-repo/brillig_vm/Cargo.toml b/acvm-repo/brillig_vm/Cargo.toml index 91bef2572bb..5a8a34be881 100644 --- a/acvm-repo/brillig_vm/Cargo.toml +++ b/acvm-repo/brillig_vm/Cargo.toml @@ -2,7 +2,7 @@ name = "brillig_vm" description = "The virtual machine that processes Brillig bytecode, used to introduce non-determinism to the ACVM" # x-release-please-start-version -version = "0.38.0" +version = "0.39.0" # x-release-please-end authors.workspace = true edition.workspace = true diff --git a/compiler/wasm/package.json b/compiler/wasm/package.json index 412e9c82f9a..2aaf4a494df 100644 --- a/compiler/wasm/package.json +++ b/compiler/wasm/package.json @@ -3,7 +3,7 @@ "contributors": [ "The Noir Team " ], - "version": "0.22.0", + "version": "0.23.0", "license": "(MIT OR Apache-2.0)", "main": "dist/main.js", "types": "./dist/types/src/index.d.cts", diff --git a/flake.nix b/flake.nix index 2300d009114..6849dc0a0ad 100644 --- a/flake.nix +++ b/flake.nix @@ -73,7 +73,7 @@ # Configuration shared between builds config = { # x-release-please-start-version - version = "0.22.0"; + version = "0.23.0"; # x-release-please-end src = pkgs.lib.cleanSourceWith { diff --git a/tooling/noir_codegen/package.json b/tooling/noir_codegen/package.json index 7d76b1a9138..60ccf5ec2a5 100644 --- a/tooling/noir_codegen/package.json +++ b/tooling/noir_codegen/package.json @@ -3,7 +3,7 @@ "contributors": [ "The Noir Team " ], - "version": "0.22.0", + "version": "0.23.0", "packageManager": "yarn@3.5.1", "license": "(MIT OR Apache-2.0)", "type": "module", diff --git a/tooling/noir_js/package.json b/tooling/noir_js/package.json index ed2fd225810..356909a1e35 100644 --- a/tooling/noir_js/package.json +++ b/tooling/noir_js/package.json @@ -3,7 +3,7 @@ "contributors": [ "The Noir Team " ], - "version": "0.22.0", + "version": "0.23.0", "packageManager": "yarn@3.5.1", "license": "(MIT OR Apache-2.0)", "type": "module", diff --git a/tooling/noir_js_backend_barretenberg/package.json b/tooling/noir_js_backend_barretenberg/package.json index e22ea2ff49d..cd2a6354ac4 100644 --- a/tooling/noir_js_backend_barretenberg/package.json +++ b/tooling/noir_js_backend_barretenberg/package.json @@ -3,7 +3,7 @@ "contributors": [ "The Noir Team " ], - "version": "0.22.0", + "version": "0.23.0", "packageManager": "yarn@3.5.1", "license": "(MIT OR Apache-2.0)", "type": "module", diff --git a/tooling/noir_js_types/package.json b/tooling/noir_js_types/package.json index 0276b8d087c..ef75f3d2fb3 100644 --- a/tooling/noir_js_types/package.json +++ b/tooling/noir_js_types/package.json @@ -4,7 +4,7 @@ "The Noir Team " ], "packageManager": "yarn@3.5.1", - "version": "0.22.0", + "version": "0.23.0", "license": "(MIT OR Apache-2.0)", "homepage": "https://noir-lang.org/", "repository": { diff --git a/tooling/noirc_abi_wasm/package.json b/tooling/noirc_abi_wasm/package.json index d023e1e4391..db0f6c29153 100644 --- a/tooling/noirc_abi_wasm/package.json +++ b/tooling/noirc_abi_wasm/package.json @@ -3,7 +3,7 @@ "contributors": [ "The Noir Team " ], - "version": "0.22.0", + "version": "0.23.0", "license": "(MIT OR Apache-2.0)", "homepage": "https://noir-lang.org/", "repository": { diff --git a/yarn.lock b/yarn.lock index e7822f59bdc..db3f493bc62 100644 --- a/yarn.lock +++ b/yarn.lock @@ -221,6 +221,20 @@ __metadata: languageName: node linkType: hard +"@aztec/bb.js@npm:0.16.0": + version: 0.16.0 + resolution: "@aztec/bb.js@npm:0.16.0" + dependencies: + comlink: ^4.4.1 + commander: ^10.0.1 + debug: ^4.3.4 + tslib: ^2.4.0 + bin: + bb.js: dest/node/main.js + checksum: 5f68b4ad16284a3a871e0ad21fea05aed670383bc639c9d07ab3bf9b7a9d15cc8a4e5cda404a9290775ad5023924739543a8aac37d602892dd1fb5087521970b + languageName: node + linkType: hard + "@aztec/bb.js@npm:0.19.0": version: 0.19.0 resolution: "@aztec/bb.js@npm:0.19.0" @@ -4381,6 +4395,13 @@ __metadata: languageName: node linkType: hard +"@noir-lang/acvm_js@npm:0.38.0": + version: 0.38.0 + resolution: "@noir-lang/acvm_js@npm:0.38.0" + checksum: 42a5bba45135d1df0d0eb3f7b65439733e016580bad610e859e140638d42200d6b856ff11c4b30417b74ce011da7c39861aafb1c5b8c7211de2172aea449c635 + languageName: node + linkType: hard + "@noir-lang/acvm_js@workspace:*, @noir-lang/acvm_js@workspace:acvm-repo/acvm_js": version: 0.0.0-use.local resolution: "@noir-lang/acvm_js@workspace:acvm-repo/acvm_js" @@ -4399,7 +4420,18 @@ __metadata: languageName: unknown linkType: soft -"@noir-lang/backend_barretenberg@^0.22.0, @noir-lang/backend_barretenberg@workspace:*, @noir-lang/backend_barretenberg@workspace:tooling/noir_js_backend_barretenberg": +"@noir-lang/backend_barretenberg@npm:^0.22.0": + version: 0.22.0 + resolution: "@noir-lang/backend_barretenberg@npm:0.22.0" + dependencies: + "@aztec/bb.js": 0.16.0 + "@noir-lang/types": 0.22.0 + fflate: ^0.8.0 + checksum: ead456218ba61d925e0fc5b47d1b94272e980b44a220f1262fb6cdc73cff7cd4232ddc69dd67bb21e50f0b43e7696d4a96fde15e3eadc0bf223ec6d59e014e23 + languageName: node + linkType: hard + +"@noir-lang/backend_barretenberg@workspace:*, @noir-lang/backend_barretenberg@workspace:tooling/noir_js_backend_barretenberg": version: 0.0.0-use.local resolution: "@noir-lang/backend_barretenberg@workspace:tooling/noir_js_backend_barretenberg" dependencies: @@ -4443,7 +4475,18 @@ __metadata: languageName: unknown linkType: soft -"@noir-lang/noir_js@^0.22.0, @noir-lang/noir_js@workspace:*, @noir-lang/noir_js@workspace:tooling/noir_js": +"@noir-lang/noir_js@npm:^0.22.0": + version: 0.22.0 + resolution: "@noir-lang/noir_js@npm:0.22.0" + dependencies: + "@noir-lang/acvm_js": 0.38.0 + "@noir-lang/noirc_abi": 0.22.0 + "@noir-lang/types": 0.22.0 + checksum: 3b0873ad87521415af11208bebe5690191d03fa06dcd515789f0a63f7641146cdcb01d292b208452856ea3967e196c8332cb2618e013f9e7e5ce7d6e09de043d + languageName: node + linkType: hard + +"@noir-lang/noir_js@workspace:*, @noir-lang/noir_js@workspace:tooling/noir_js": version: 0.0.0-use.local resolution: "@noir-lang/noir_js@workspace:tooling/noir_js" dependencies: @@ -4466,7 +4509,14 @@ __metadata: languageName: unknown linkType: soft -"@noir-lang/noir_wasm@^0.22.0, @noir-lang/noir_wasm@workspace:*, @noir-lang/noir_wasm@workspace:compiler/wasm": +"@noir-lang/noir_wasm@npm:^0.22.0": + version: 0.22.0 + resolution: "@noir-lang/noir_wasm@npm:0.22.0" + checksum: 7ac0ca170bf312df761d7ccfd32a67a27f88f15ad4eed1807864295d761d3b2176ffb82f4c6931e1bc06b225d6f738519962c79ffbce9a33d5ef8a6a2bdea82c + languageName: node + linkType: hard + +"@noir-lang/noir_wasm@workspace:*, @noir-lang/noir_wasm@workspace:compiler/wasm": version: 0.0.0-use.local resolution: "@noir-lang/noir_wasm@workspace:compiler/wasm" dependencies: @@ -4510,6 +4560,13 @@ __metadata: languageName: unknown linkType: soft +"@noir-lang/noirc_abi@npm:0.22.0": + version: 0.22.0 + resolution: "@noir-lang/noirc_abi@npm:0.22.0" + checksum: a250c6cc5ca37fcf02663f8d6b027776f0e58920fb8f8a84efcf74f079f235bb11bbad682ba332211d9b9a79b6a3eb7faede7701cd88582b682971a41ca6212d + languageName: node + linkType: hard + "@noir-lang/noirc_abi@workspace:*, @noir-lang/noirc_abi@workspace:tooling/noirc_abi_wasm": version: 0.0.0-use.local resolution: "@noir-lang/noirc_abi@workspace:tooling/noirc_abi_wasm" @@ -4540,7 +4597,16 @@ __metadata: languageName: unknown linkType: soft -"@noir-lang/types@^0.22.0, @noir-lang/types@workspace:*, @noir-lang/types@workspace:tooling/noir_js_types": +"@noir-lang/types@npm:0.22.0, @noir-lang/types@npm:^0.22.0": + version: 0.22.0 + resolution: "@noir-lang/types@npm:0.22.0" + dependencies: + "@noir-lang/noirc_abi": 0.22.0 + checksum: 5dd1badf0449c518e755172de1d2f2c1b95bfaf7b7328b7de00b8ce9ba68bd447ca65e827185da7d737e7e88dcaf296b29687ffe2e1f5b4d5cc31ce3e3b4f208 + languageName: node + linkType: hard + +"@noir-lang/types@workspace:*, @noir-lang/types@workspace:tooling/noir_js_types": version: 0.0.0-use.local resolution: "@noir-lang/types@workspace:tooling/noir_js_types" dependencies: From 189aa48c6c32fb6621b0e38a1f2d5d76d26ff0f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Rodr=C3=ADguez?= Date: Mon, 22 Jan 2024 16:48:58 +0100 Subject: [PATCH 04/70] fix: Respect order in bubble up for redundant asserts (#4109) # Description ## Problem\* Bubble up was reordering redundant assertions for the same data. This PR makes it respect the order for those. ## Summary\* ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [ ] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --------- Co-authored-by: Tom French <15848336+TomAFrench@users.noreply.github.com> --- .../src/ssa/opt/bubble_up_constrains.rs | 126 ++++++++++++++++-- 1 file changed, 118 insertions(+), 8 deletions(-) diff --git a/compiler/noirc_evaluator/src/ssa/opt/bubble_up_constrains.rs b/compiler/noirc_evaluator/src/ssa/opt/bubble_up_constrains.rs index cb9519eeb2e..8a903cbd87b 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/bubble_up_constrains.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/bubble_up_constrains.rs @@ -1,4 +1,9 @@ -use crate::ssa::{ir::instruction::Instruction, ssa_gen::Ssa}; +use std::collections::HashMap; + +use crate::ssa::{ + ir::instruction::{Instruction, InstructionId}, + ssa_gen::Ssa, +}; impl Ssa { /// A simple SSA pass to go through each instruction and move every `Instruction::Constrain` to immediately @@ -10,6 +15,12 @@ impl Ssa { let instructions = function.dfg[block].take_instructions(); let mut filtered_instructions = Vec::with_capacity(instructions.len()); + // Multiple constrains can bubble up to sit under a single instruction. We want to maintain the ordering of these constraints, + // so we need to keep track of how many constraints are attached to a given instruction. + // Some assertions don't operate on instruction results, so we use Option so we also track the None case + let mut inserted_at_instruction: HashMap, usize> = + HashMap::with_capacity(instructions.len()); + let dfg = &function.dfg; for instruction in instructions { let (lhs, rhs) = match dfg[instruction] { @@ -20,19 +31,38 @@ impl Ssa { } }; - let index = filtered_instructions + let last_instruction_that_creates_inputs = filtered_instructions .iter() .rev() - .position(|instruction_id| { - let results = dfg.instruction_results(*instruction_id).to_vec(); + .position(|&instruction_id| { + let results = dfg.instruction_results(instruction_id).to_vec(); results.contains(&lhs) || results.contains(&rhs) }) // We iterate through the previous instructions in reverse order so the index is from the - // back of the vector. Subtract from vector length to get correct index. - .map(|reversed_index| filtered_instructions.len() - reversed_index) - .unwrap_or(0); + // back of the vector + .map(|reversed_index| filtered_instructions.len() - reversed_index - 1); + + let insertion_index = last_instruction_that_creates_inputs + .map(|index| { + // We want to insert just after the last instruction that creates the inputs + index + 1 + }) + // If it doesn't depend from the previous instructions, then we insert at the start + .unwrap_or_default(); + + let already_inserted_for_this_instruction = inserted_at_instruction + .entry( + last_instruction_that_creates_inputs + .map(|index| filtered_instructions[index]), + ) + .or_default(); - filtered_instructions.insert(index, instruction); + filtered_instructions.insert( + insertion_index + *already_inserted_for_this_instruction, + instruction, + ); + + *already_inserted_for_this_instruction += 1; } *function.dfg[block].instructions_mut() = filtered_instructions; @@ -41,3 +71,83 @@ impl Ssa { self } } + +#[cfg(test)] +mod test { + use crate::ssa::{ + function_builder::FunctionBuilder, + ir::{ + function::RuntimeType, + instruction::{Binary, BinaryOp, Instruction}, + map::Id, + types::Type, + }, + }; + + #[test] + fn check_bubble_up_constrains() { + // fn main f0 { + // b0(v0: Field): + // v1 = add v0, Field 1 + // v2 = add v1, Field 1 + // constrain v0 == Field 1 'With message' + // constrain v2 == Field 3 + // constrain v0 == Field 1 + // constrain v1 == Field 2 + // constrain v1 == Field 2 'With message' + // } + // + let main_id = Id::test_new(0); + + // Compiling main + let mut builder = FunctionBuilder::new("main".into(), main_id, RuntimeType::Acir); + let v0 = builder.add_parameter(Type::field()); + + let one = builder.field_constant(1u128); + let two = builder.field_constant(2u128); + let three = builder.field_constant(3u128); + + let v1 = builder.insert_binary(v0, BinaryOp::Add, one); + let v2 = builder.insert_binary(v1, BinaryOp::Add, one); + builder.insert_constrain(v0, one, Some("With message".to_string())); + builder.insert_constrain(v2, three, None); + builder.insert_constrain(v0, one, None); + builder.insert_constrain(v1, two, None); + builder.insert_constrain(v1, two, Some("With message".to_string())); + builder.terminate_with_return(vec![]); + + let ssa = builder.finish(); + + // Expected output: + // + // fn main f0 { + // b0(v0: Field): + // constrain v0 == Field 1 'With message' + // constrain v0 == Field 1 + // v1 = add v0, Field 1 + // constrain v1 == Field 2 + // constrain v1 == Field 2 'With message' + // v2 = add v1, Field 1 + // constrain v2 == Field 3 + // } + // + let ssa = ssa.bubble_up_constrains(); + let main = ssa.main(); + let block = &main.dfg[main.entry_block()]; + assert_eq!(block.instructions().len(), 7); + + let expected_instructions = vec![ + Instruction::Constrain(v0, one, Some("With message".to_string())), + Instruction::Constrain(v0, one, None), + Instruction::Binary(Binary { lhs: v0, rhs: one, operator: BinaryOp::Add }), + Instruction::Constrain(v1, two, None), + Instruction::Constrain(v1, two, Some("With message".to_string())), + Instruction::Binary(Binary { lhs: v1, rhs: one, operator: BinaryOp::Add }), + Instruction::Constrain(v2, three, None), + ]; + + for (index, instruction) in block.instructions().iter().enumerate() { + assert_eq!(&main.dfg[*instruction], &expected_instructions[index]); + } + } +} From 0a5bd4faa880dfcadf74372d8caeb458b2b55132 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustavo=20Gir=C3=A1ldez?= Date: Mon, 22 Jan 2024 11:42:22 -0500 Subject: [PATCH 05/70] fix: save the data bus to the current function before generating others (#4047) # Description ## Problem\* Resolves #4046 ## Summary\* This PR changes saves the data bus configuration before processing the other queued functions during SSA gen phase. ## Additional Context With the current implementation the databus will be incorrectly saved to the last generated function instead of the main function, causing a panic in a later optimization phase. ## Documentation\* Check one: - [X] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [X] I have tested the changes locally. - [X] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- compiler/noirc_evaluator/src/ssa/ssa_gen/mod.rs | 6 +++--- .../execution_success/databus/src/main.nr | 14 ++++++++------ 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/compiler/noirc_evaluator/src/ssa/ssa_gen/mod.rs b/compiler/noirc_evaluator/src/ssa/ssa_gen/mod.rs index eb35ba9a65b..9d9635fed34 100644 --- a/compiler/noirc_evaluator/src/ssa/ssa_gen/mod.rs +++ b/compiler/noirc_evaluator/src/ssa/ssa_gen/mod.rs @@ -96,6 +96,9 @@ pub(crate) fn generate_ssa(program: Program) -> Result { _ => unreachable!("ICE - expect return on the last block"), } } + // we save the data bus inside the dfg + function_context.builder.current_function.dfg.data_bus = + DataBus::get_data_bus(call_data, return_data); // Main has now been compiled and any other functions referenced within have been added to the // function queue as they were found in codegen_ident. This queueing will happen each time a @@ -106,9 +109,6 @@ pub(crate) fn generate_ssa(program: Program) -> Result { function_context.new_function(dest_id, function); function_context.codegen_function_body(&function.body)?; } - // we save the data bus inside the dfg - function_context.builder.current_function.dfg.data_bus = - DataBus::get_data_bus(call_data, return_data); Ok(function_context.builder.finish()) } diff --git a/test_programs/execution_success/databus/src/main.nr b/test_programs/execution_success/databus/src/main.nr index 631331ef2d7..61a9637f5fe 100644 --- a/test_programs/execution_success/databus/src/main.nr +++ b/test_programs/execution_success/databus/src/main.nr @@ -1,10 +1,12 @@ -// Test unsafe integer multiplication with overflow: 12^8 = 429 981 696 -// The circuit should handle properly the growth of the bit size use dep::std; -fn main(mut x: u32, y: call_data u32, z: call_data [u32;4] ) -> return_data u32 { - -let a = z[x]; - a+y +fn main(mut x: u32, y: call_data u32, z: call_data [u32;4]) -> return_data u32 { + let a = z[x]; + a+foo(y) +} +// Use an unconstrained function to force the compiler to avoid inlining +unconstrained fn foo(x: u32) -> u32 { + x+1 } + From 00f394c7729ac1b2805a1d7bc06a55d42ee71ba1 Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Mon, 22 Jan 2024 16:37:30 +0000 Subject: [PATCH 06/70] chore: move comments into doc comments in `noir_js_backend_barretenberg` (#4108) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Description ## Problem\* Resolves ## Summary\* We've got documentation in this package which should probably be in the jsdoc but isn't. I've then moved it across into there so it becomes part of the autogenerated docs. ## Additional Context ## Documentation\* Check one: - [ ] No documentation needed. - [x] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --------- Co-authored-by: José Pedro Sousa --- .../noir_js_backend_barretenberg/src/index.ts | 54 +++++++++---------- 1 file changed, 26 insertions(+), 28 deletions(-) diff --git a/tooling/noir_js_backend_barretenberg/src/index.ts b/tooling/noir_js_backend_barretenberg/src/index.ts index 6e619fd59cf..270567a0416 100644 --- a/tooling/noir_js_backend_barretenberg/src/index.ts +++ b/tooling/noir_js_backend_barretenberg/src/index.ts @@ -20,7 +20,7 @@ export class BarretenbergBackend implements Backend { private acirUncompressedBytecode: Uint8Array; constructor( - private acirCircuit: CompiledCircuit, + acirCircuit: CompiledCircuit, private options: BackendOptions = { threads: 1 }, ) { const acirBytecodeBase64 = acirCircuit.bytecode; @@ -46,29 +46,25 @@ export class BarretenbergBackend implements Backend { } } - // Generate an outer proof. This is the proof for the circuit which will verify - // inner proofs and or can be seen as the proof created for regular circuits. - // - // The settings for this proof are the same as the settings for a "normal" proof - // ie one that is not in the recursive setting. + /** + * Generate a final proof. This is the proof for the circuit which will verify + * intermediate proofs and or can be seen as the proof created for regular circuits. + */ async generateFinalProof(decompressedWitness: Uint8Array): Promise { + // The settings for this proof are the same as the settings for a "normal" proof + // i.e. one that is not in the recursive setting. const makeEasyToVerifyInCircuit = false; return this.generateProof(decompressedWitness, makeEasyToVerifyInCircuit); } - // Generates an inner proof. This is the proof that will be verified - // in another circuit. - // - // This is sometimes referred to as a recursive proof. - // We avoid this terminology as the only property of this proof - // that matters, is the fact that it is easy to verify in another - // circuit. We _could_ choose to verify this proof in the CLI. - // - // We set `makeEasyToVerifyInCircuit` to true, which will tell the backend to - // generate the proof using components that will make the proof - // easier to verify in a circuit. - /** + * Generates an intermediate proof. This is the proof that can be verified + * in another circuit. + * + * This is sometimes referred to as a recursive proof. + * We avoid this terminology as the only property of this proof + * that matters is the fact that it is easy to verify in another circuit. + * We _could_ choose to verify this proof outside of a circuit just as easily. * * @example * ```typescript @@ -76,6 +72,9 @@ export class BarretenbergBackend implements Backend { * ``` */ async generateIntermediateProof(witness: Uint8Array): Promise { + // We set `makeEasyToVerifyInCircuit` to true, which will tell the backend to + // generate the proof using components that will make the proof + // easier to verify in a circuit. const makeEasyToVerifyInCircuit = true; return this.generateProof(witness, makeEasyToVerifyInCircuit); } @@ -99,17 +98,16 @@ export class BarretenbergBackend implements Backend { return { proof, publicInputs }; } - // Generates artifacts that will be passed to a circuit that will verify this proof. - // - // Instead of passing the proof and verification key as a byte array, we pass them - // as fields which makes it cheaper to verify in a circuit. - // - // The proof that is passed here will have been created using the `generateInnerProof` - // method. - // - // The number of public inputs denotes how many public inputs are in the inner proof. - /** + * Generates artifacts that will be passed to a circuit that will verify this proof. + * + * Instead of passing the proof and verification key as a byte array, we pass them + * as fields which makes it cheaper to verify in a circuit. + * + * The proof that is passed here will have been created using the `generateIntermediateProof` + * method. + * + * The number of public inputs denotes how many public inputs are in the inner proof. * * @example * ```typescript From 636376501639677116f64ac2ecebe3e17170530c Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Mon, 22 Jan 2024 16:38:21 +0000 Subject: [PATCH 07/70] chore: rename aztec macro errors (#4087) # Description ## Problem\* Resolves ## Summary\* This enum is dangerously close to triggering https://rust-lang.github.io/rust-clippy/master/#/clippy::enum_variant_names so I've renamed some things. I've also delayed where we convert from an `AztecMacroError` to a `MacroError` to avoid a number of `into()`s ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- aztec_macros/src/lib.rs | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/aztec_macros/src/lib.rs b/aztec_macros/src/lib.rs index 7c62f8f8169..c9adece4eb5 100644 --- a/aztec_macros/src/lib.rs +++ b/aztec_macros/src/lib.rs @@ -36,32 +36,32 @@ const MAX_CONTRACT_FUNCTIONS: usize = 2_usize.pow(FUNCTION_TREE_HEIGHT); #[derive(Debug, Clone)] pub enum AztecMacroError { - AztecNotFound, - AztecComputeNoteHashAndNullifierNotFound { span: Span }, - AztecContractHasTooManyFunctions { span: Span }, - AztecContractConstructorMissing { span: Span }, + AztecDepNotFound, + ComputeNoteHashAndNullifierNotFound { span: Span }, + ContractHasTooManyFunctions { span: Span }, + ContractConstructorMissing { span: Span }, UnsupportedFunctionArgumentType { span: Span, typ: UnresolvedTypeData }, } impl From for MacroError { fn from(err: AztecMacroError) -> Self { match err { - AztecMacroError::AztecNotFound {} => MacroError { + AztecMacroError::AztecDepNotFound {} => MacroError { primary_message: "Aztec dependency not found. Please add aztec as a dependency in your Cargo.toml. For more information go to https://docs.aztec.network/dev_docs/debugging/aztecnr-errors#aztec-dependency-not-found-please-add-aztec-as-a-dependency-in-your-nargotoml".to_owned(), secondary_message: None, span: None, }, - AztecMacroError::AztecComputeNoteHashAndNullifierNotFound { span } => MacroError { + AztecMacroError::ComputeNoteHashAndNullifierNotFound { span } => MacroError { primary_message: "compute_note_hash_and_nullifier function not found. Define it in your contract. For more information go to https://docs.aztec.network/dev_docs/debugging/aztecnr-errors#compute_note_hash_and_nullifier-function-not-found-define-it-in-your-contract".to_owned(), secondary_message: None, span: Some(span), }, - AztecMacroError::AztecContractHasTooManyFunctions { span } => MacroError { + AztecMacroError::ContractHasTooManyFunctions { span } => MacroError { primary_message: format!("Contract can only have a maximum of {} functions", MAX_CONTRACT_FUNCTIONS), secondary_message: None, span: Some(span), }, - AztecMacroError::AztecContractConstructorMissing { span } => MacroError { + AztecMacroError::ContractConstructorMissing { span } => MacroError { primary_message: "Contract must have a constructor function".to_owned(), secondary_message: None, span: Some(span), @@ -222,7 +222,9 @@ fn transform( // Covers all functions in the ast for submodule in ast.submodules.iter_mut().filter(|submodule| submodule.is_contract) { - if transform_module(&mut submodule.contents, crate_id, context)? { + if transform_module(&mut submodule.contents, crate_id, context) + .map_err(|(err, file_id)| (err.into(), file_id))? + { check_for_aztec_dependency(crate_id, context)?; include_relevant_imports(&mut submodule.contents); } @@ -264,7 +266,7 @@ fn check_for_aztec_dependency( if has_aztec_dependency { Ok(()) } else { - Err((AztecMacroError::AztecNotFound.into(), crate_graph.root_file_id)) + Err((AztecMacroError::AztecDepNotFound.into(), crate_graph.root_file_id)) } } @@ -323,7 +325,7 @@ fn transform_module( module: &mut SortedModule, crate_id: &CrateId, context: &HirContext, -) -> Result { +) -> Result { let mut has_transformed_module = false; // Check for a user defined storage struct @@ -332,8 +334,7 @@ fn transform_module( if storage_defined && !check_for_compute_note_hash_and_nullifier_definition(module) { let crate_graph = &context.crate_graph[crate_id]; return Err(( - AztecMacroError::AztecComputeNoteHashAndNullifierNotFound { span: Span::default() } - .into(), + AztecMacroError::ComputeNoteHashAndNullifierNotFound { span: Span::default() }, crate_graph.root_file_id, )); } @@ -350,11 +351,11 @@ fn transform_module( let crate_graph = &context.crate_graph[crate_id]; if is_custom_attribute(&secondary_attribute, "aztec(private)") { transform_function("Private", func, storage_defined) - .map_err(|err| (err.into(), crate_graph.root_file_id))?; + .map_err(|err| (err, crate_graph.root_file_id))?; has_transformed_module = true; } else if is_custom_attribute(&secondary_attribute, "aztec(public)") { transform_function("Public", func, storage_defined) - .map_err(|err| (err.into(), crate_graph.root_file_id))?; + .map_err(|err| (err, crate_graph.root_file_id))?; has_transformed_module = true; } } @@ -371,7 +372,7 @@ fn transform_module( if module.functions.len() > MAX_CONTRACT_FUNCTIONS { let crate_graph = &context.crate_graph[crate_id]; return Err(( - AztecMacroError::AztecContractHasTooManyFunctions { span: Span::default() }.into(), + AztecMacroError::ContractHasTooManyFunctions { span: Span::default() }, crate_graph.root_file_id, )); } @@ -380,7 +381,7 @@ fn transform_module( if !constructor_defined { let crate_graph = &context.crate_graph[crate_id]; return Err(( - AztecMacroError::AztecContractConstructorMissing { span: Span::default() }.into(), + AztecMacroError::ContractConstructorMissing { span: Span::default() }, crate_graph.root_file_id, )); } From ae5c630c17646e3f841b530ee7a67e68c51b5183 Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Mon, 22 Jan 2024 16:40:16 +0000 Subject: [PATCH 08/70] chore: add better type safety in `noir_js_backend_barretenberg` (#4103) # Description ## Problem\* Resolves ## Summary\* This PR stops `api` from being the `any` type so we get type safety when calling methods on it. This doesn't affect the lazy loading of bb.js as we're only importing types which get stripped out by typescript. ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- tooling/noir_js_backend_barretenberg/src/index.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tooling/noir_js_backend_barretenberg/src/index.ts b/tooling/noir_js_backend_barretenberg/src/index.ts index 270567a0416..61094a3451f 100644 --- a/tooling/noir_js_backend_barretenberg/src/index.ts +++ b/tooling/noir_js_backend_barretenberg/src/index.ts @@ -1,11 +1,12 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ import { decompressSync as gunzip } from 'fflate'; import { acirToUint8Array } from './serialize.js'; import { Backend, CompiledCircuit, ProofData } from '@noir-lang/types'; import { BackendOptions } from './types.js'; import { deflattenPublicInputs, flattenPublicInputsAsArray } from './public_inputs.js'; +import { type Barretenberg } from '@aztec/bb.js'; export { publicInputsToWitnessMap } from './public_inputs.js'; + // This is the number of bytes in a UltraPlonk proof // minus the public inputs. const numBytesInProofWithoutPublicInputs: number = 2144; @@ -15,7 +16,9 @@ export class BarretenbergBackend implements Backend { // have to initialize `api` and `acirComposer` in the constructor. // These are initialized asynchronously in the `init` function, // constructors cannot be asynchronous which is why we do this. - private api: any; + + private api!: Barretenberg; + // eslint-disable-next-line @typescript-eslint/no-explicit-any private acirComposer: any; private acirUncompressedBytecode: Uint8Array; @@ -30,8 +33,6 @@ export class BarretenbergBackend implements Backend { /** @ignore */ async instantiate(): Promise { if (!this.api) { - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - //@ts-ignore const { Barretenberg, RawBuffer, Crs } = await import('@aztec/bb.js'); const api = await Barretenberg.new({ threads: this.options.threads }); From 7f3abbbc8231e6174310172e38e76ad016b807dd Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Mon, 22 Jan 2024 16:43:33 +0000 Subject: [PATCH 09/70] chore(docs): fix dead links (#4111) # Description ## Problem\* Resolves #3999 ## Summary\* This PR fixes a bunch of cases of dead links where the target has been moved or in one case never existed in the first place. ## Additional Context ## Documentation\* Check one: - [ ] No documentation needed. - [x] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- docs/docs/how_to/how-to-oracles.md | 2 +- docs/docs/how_to/how-to-recursion.md | 2 +- .../standard_library/cryptographic_primitives/ec_primitives.md | 2 +- docs/docs/tutorials/noirjs_app.md | 2 +- .../version-v0.17.0/getting_started/01_hello_world.md | 2 +- .../version-v0.17.0/language_concepts/06_generics.md | 2 +- .../version-v0.17.0/noir_js/getting_started/01_tiny_noir_app.md | 2 +- .../cryptographic_primitives/04_ec_primitives.md | 2 +- .../version-v0.19.0/getting_started/01_hello_world.md | 2 +- .../version-v0.19.0/noir_js/getting_started/01_tiny_noir_app.md | 2 +- .../cryptographic_primitives/04_ec_primitives.md | 2 +- .../version-v0.19.1/getting_started/01_hello_world.md | 2 +- .../version-v0.19.1/language_concepts/06_generics.md | 2 +- .../version-v0.19.1/noir_js/getting_started/01_tiny_noir_app.md | 2 +- .../cryptographic_primitives/04_ec_primitives.md | 2 +- .../version-v0.19.2/getting_started/01_hello_world.md | 2 +- .../version-v0.19.2/language_concepts/06_generics.md | 2 +- .../version-v0.19.2/noir_js/getting_started/01_tiny_noir_app.md | 2 +- .../cryptographic_primitives/04_ec_primitives.md | 2 +- .../version-v0.19.3/getting_started/01_hello_world.md | 2 +- .../version-v0.19.3/language_concepts/06_generics.md | 2 +- .../version-v0.19.3/noir_js/getting_started/01_tiny_noir_app.md | 2 +- .../cryptographic_primitives/04_ec_primitives.md | 2 +- .../version-v0.19.4/getting_started/01_hello_world.md | 2 +- .../version-v0.19.4/language_concepts/06_generics.md | 2 +- .../version-v0.19.4/noir_js/getting_started/01_tiny_noir_app.md | 2 +- .../cryptographic_primitives/04_ec_primitives.md | 2 +- docs/versioned_docs/version-v0.22.0/how_to/how-to-recursion.md | 2 +- .../standard_library/cryptographic_primitives/ec_primitives.md | 2 +- docs/versioned_docs/version-v0.22.0/noir/syntax/generics.md | 2 +- docs/versioned_docs/version-v0.22.0/tutorials/noirjs_app.md | 2 +- 31 files changed, 31 insertions(+), 31 deletions(-) diff --git a/docs/docs/how_to/how-to-oracles.md b/docs/docs/how_to/how-to-oracles.md index bdb2b1332ba..0d84d992320 100644 --- a/docs/docs/how_to/how-to-oracles.md +++ b/docs/docs/how_to/how-to-oracles.md @@ -18,7 +18,7 @@ This guide shows you how to use oracles in your Noir program. For the sake of cl - You understand the concept of a JSON-RPC server. Visit the [JSON-RPC website](https://www.jsonrpc.org/) if you need a refresher. - You are comfortable with server-side JavaScript (e.g. Node.js, managing packages, etc.). -For reference, you can find the snippets used in this tutorial on the [Aztec DevRel Repository](https://github.com/AztecProtocol/dev-rel/tree/main/how_to_oracles/code-snippets/how-to-oracles). +For reference, you can find the snippets used in this tutorial on the [Aztec DevRel Repository](https://github.com/AztecProtocol/dev-rel/tree/main/code-snippets/how-to-oracles). ## Rundown diff --git a/docs/docs/how_to/how-to-recursion.md b/docs/docs/how_to/how-to-recursion.md index f60aa3ff2d9..39db23f1f3a 100644 --- a/docs/docs/how_to/how-to-recursion.md +++ b/docs/docs/how_to/how-to-recursion.md @@ -47,7 +47,7 @@ In a standard recursive app, you're also dealing with at least two circuits. For - `main`: a circuit of type `assert(x != y)` - `recursive`: a circuit that verifies `main` -For a full example on how recursive proofs work, please refer to the [noir-examples](https://github.com/noir/noir-examples) repository. We will *not* be using it as a reference for this guide. +For a full example on how recursive proofs work, please refer to the [noir-examples](https://github.com/noir-lang/noir-examples) repository. We will *not* be using it as a reference for this guide. ## Step 1: Setup diff --git a/docs/docs/noir/standard_library/cryptographic_primitives/ec_primitives.md b/docs/docs/noir/standard_library/cryptographic_primitives/ec_primitives.md index 8d573adb3be..d2b42d67b7c 100644 --- a/docs/docs/noir/standard_library/cryptographic_primitives/ec_primitives.md +++ b/docs/docs/noir/standard_library/cryptographic_primitives/ec_primitives.md @@ -72,7 +72,7 @@ does indeed lie on `c` by calling `c.contains(p1)`. ## Examples The -[ec_baby_jubjub test](https://github.com/noir-lang/noir/blob/master/crates/nargo_cli/tests/test_data/ec_baby_jubjub/src/main.nr) +[ec_baby_jubjub test](https://github.com/noir-lang/noir/blob/master/test_programs/compile_success_empty/ec_baby_jubjub/src/main.nr) illustrates all of the above primitives on various forms of the Baby Jubjub curve. A couple of more interesting examples in Noir would be: diff --git a/docs/docs/tutorials/noirjs_app.md b/docs/docs/tutorials/noirjs_app.md index 4293aa053fc..9f83def914b 100644 --- a/docs/docs/tutorials/noirjs_app.md +++ b/docs/docs/tutorials/noirjs_app.md @@ -273,6 +273,6 @@ You have successfully generated a client-side Noir web app! ## Further Reading -You can see how noirjs is used in a full stack Next.js hardhat application in the [noir-starter repo here](https://github.com/noir-lang/noir-starter/tree/main/next-hardhat). The example shows how to calculate a proof in the browser and verify it with a deployed Solidity verifier contract from noirjs. +You can see how noirjs is used in a full stack Next.js hardhat application in the [noir-starter repo here](https://github.com/noir-lang/noir-starter/tree/main/vite-hardhat). The example shows how to calculate a proof in the browser and verify it with a deployed Solidity verifier contract from noirjs. You should also check out the more advanced examples in the [noir-examples repo](https://github.com/noir-lang/noir-examples), where you'll find reference usage for some cool apps. diff --git a/docs/versioned_docs/version-v0.17.0/getting_started/01_hello_world.md b/docs/versioned_docs/version-v0.17.0/getting_started/01_hello_world.md index 8b4416beba1..d4daae605a2 100644 --- a/docs/versioned_docs/version-v0.17.0/getting_started/01_hello_world.md +++ b/docs/versioned_docs/version-v0.17.0/getting_started/01_hello_world.md @@ -144,4 +144,4 @@ corresponding error instead. Congratulations, you have now created and verified a proof for your very first Noir program! -In the [next section](breakdown), we will go into more detail on each step performed. +In the [next section](./02_breakdown.md), we will go into more detail on each step performed. diff --git a/docs/versioned_docs/version-v0.17.0/language_concepts/06_generics.md b/docs/versioned_docs/version-v0.17.0/language_concepts/06_generics.md index 9fb4177c2a8..36c2b593fcd 100644 --- a/docs/versioned_docs/version-v0.17.0/language_concepts/06_generics.md +++ b/docs/versioned_docs/version-v0.17.0/language_concepts/06_generics.md @@ -110,4 +110,4 @@ fn main() { ``` You can see an example of generics in the tests -[here](https://github.com/noir-lang/noir/blob/master/tooling/nargo_cli/tests/execution_success/generics/src/main.nr). +[here](https://github.com/noir-lang/noir/blob/master/test_programs/execution_success/generics/src/main.nr). diff --git a/docs/versioned_docs/version-v0.17.0/noir_js/getting_started/01_tiny_noir_app.md b/docs/versioned_docs/version-v0.17.0/noir_js/getting_started/01_tiny_noir_app.md index 6955f7a1e64..142cd02b94c 100644 --- a/docs/versioned_docs/version-v0.17.0/noir_js/getting_started/01_tiny_noir_app.md +++ b/docs/versioned_docs/version-v0.17.0/noir_js/getting_started/01_tiny_noir_app.md @@ -251,6 +251,6 @@ By saving, your app will refresh and here's our complete Tiny Noir App! ## Further Reading -You can see how noirjs is used in a full stack Next.js hardhat application in the [noir-starter repo here](https://github.com/noir-lang/noir-starter/tree/main/next-hardhat). The example shows how to calculate a proof in the browser and verify it with a deployed Solidity verifier contract from noirjs. +You can see how noirjs is used in a full stack Next.js hardhat application in the [noir-starter repo here](https://github.com/noir-lang/noir-starter/tree/main/vite-hardhat). The example shows how to calculate a proof in the browser and verify it with a deployed Solidity verifier contract from noirjs. You should also check out the more advanced examples in the [noir-examples repo](https://github.com/noir-lang/noir-examples), where you'll find reference usage for some cool apps. diff --git a/docs/versioned_docs/version-v0.17.0/standard_library/cryptographic_primitives/04_ec_primitives.md b/docs/versioned_docs/version-v0.17.0/standard_library/cryptographic_primitives/04_ec_primitives.md index 6e6b19b6861..d3af3cf7c3b 100644 --- a/docs/versioned_docs/version-v0.17.0/standard_library/cryptographic_primitives/04_ec_primitives.md +++ b/docs/versioned_docs/version-v0.17.0/standard_library/cryptographic_primitives/04_ec_primitives.md @@ -71,7 +71,7 @@ does indeed lie on `c` by calling `c.contains(p1)`. ## Examples The -[ec_baby_jubjub test](https://github.com/noir-lang/noir/blob/master/crates/nargo_cli/tests/test_data/ec_baby_jubjub/src/main.nr) +[ec_baby_jubjub test](https://github.com/noir-lang/noir/blob/master/test_programs/compile_success_empty/ec_baby_jubjub/src/main.nr) illustrates all of the above primitives on various forms of the Baby Jubjub curve. A couple of more interesting examples in Noir would be: diff --git a/docs/versioned_docs/version-v0.19.0/getting_started/01_hello_world.md b/docs/versioned_docs/version-v0.19.0/getting_started/01_hello_world.md index 8b4416beba1..d4daae605a2 100644 --- a/docs/versioned_docs/version-v0.19.0/getting_started/01_hello_world.md +++ b/docs/versioned_docs/version-v0.19.0/getting_started/01_hello_world.md @@ -144,4 +144,4 @@ corresponding error instead. Congratulations, you have now created and verified a proof for your very first Noir program! -In the [next section](breakdown), we will go into more detail on each step performed. +In the [next section](./02_breakdown.md), we will go into more detail on each step performed. diff --git a/docs/versioned_docs/version-v0.19.0/noir_js/getting_started/01_tiny_noir_app.md b/docs/versioned_docs/version-v0.19.0/noir_js/getting_started/01_tiny_noir_app.md index c51ed61de52..795baa59d59 100644 --- a/docs/versioned_docs/version-v0.19.0/noir_js/getting_started/01_tiny_noir_app.md +++ b/docs/versioned_docs/version-v0.19.0/noir_js/getting_started/01_tiny_noir_app.md @@ -255,6 +255,6 @@ You can find the complete app code for this guide [here](https://github.com/noir ## Further Reading -You can see how noirjs is used in a full stack Next.js hardhat application in the [noir-starter repo here](https://github.com/noir-lang/noir-starter/tree/main/next-hardhat). The example shows how to calculate a proof in the browser and verify it with a deployed Solidity verifier contract from noirjs. +You can see how noirjs is used in a full stack Next.js hardhat application in the [noir-starter repo here](https://github.com/noir-lang/noir-starter/tree/main/vite-hardhat). The example shows how to calculate a proof in the browser and verify it with a deployed Solidity verifier contract from noirjs. You should also check out the more advanced examples in the [noir-examples repo](https://github.com/noir-lang/noir-examples), where you'll find reference usage for some cool apps. diff --git a/docs/versioned_docs/version-v0.19.0/standard_library/cryptographic_primitives/04_ec_primitives.md b/docs/versioned_docs/version-v0.19.0/standard_library/cryptographic_primitives/04_ec_primitives.md index 6e6b19b6861..d3af3cf7c3b 100644 --- a/docs/versioned_docs/version-v0.19.0/standard_library/cryptographic_primitives/04_ec_primitives.md +++ b/docs/versioned_docs/version-v0.19.0/standard_library/cryptographic_primitives/04_ec_primitives.md @@ -71,7 +71,7 @@ does indeed lie on `c` by calling `c.contains(p1)`. ## Examples The -[ec_baby_jubjub test](https://github.com/noir-lang/noir/blob/master/crates/nargo_cli/tests/test_data/ec_baby_jubjub/src/main.nr) +[ec_baby_jubjub test](https://github.com/noir-lang/noir/blob/master/test_programs/compile_success_empty/ec_baby_jubjub/src/main.nr) illustrates all of the above primitives on various forms of the Baby Jubjub curve. A couple of more interesting examples in Noir would be: diff --git a/docs/versioned_docs/version-v0.19.1/getting_started/01_hello_world.md b/docs/versioned_docs/version-v0.19.1/getting_started/01_hello_world.md index 8b4416beba1..d4daae605a2 100644 --- a/docs/versioned_docs/version-v0.19.1/getting_started/01_hello_world.md +++ b/docs/versioned_docs/version-v0.19.1/getting_started/01_hello_world.md @@ -144,4 +144,4 @@ corresponding error instead. Congratulations, you have now created and verified a proof for your very first Noir program! -In the [next section](breakdown), we will go into more detail on each step performed. +In the [next section](./02_breakdown.md), we will go into more detail on each step performed. diff --git a/docs/versioned_docs/version-v0.19.1/language_concepts/06_generics.md b/docs/versioned_docs/version-v0.19.1/language_concepts/06_generics.md index 9fb4177c2a8..36c2b593fcd 100644 --- a/docs/versioned_docs/version-v0.19.1/language_concepts/06_generics.md +++ b/docs/versioned_docs/version-v0.19.1/language_concepts/06_generics.md @@ -110,4 +110,4 @@ fn main() { ``` You can see an example of generics in the tests -[here](https://github.com/noir-lang/noir/blob/master/tooling/nargo_cli/tests/execution_success/generics/src/main.nr). +[here](https://github.com/noir-lang/noir/blob/master/test_programs/execution_success/generics/src/main.nr). diff --git a/docs/versioned_docs/version-v0.19.1/noir_js/getting_started/01_tiny_noir_app.md b/docs/versioned_docs/version-v0.19.1/noir_js/getting_started/01_tiny_noir_app.md index c51ed61de52..795baa59d59 100644 --- a/docs/versioned_docs/version-v0.19.1/noir_js/getting_started/01_tiny_noir_app.md +++ b/docs/versioned_docs/version-v0.19.1/noir_js/getting_started/01_tiny_noir_app.md @@ -255,6 +255,6 @@ You can find the complete app code for this guide [here](https://github.com/noir ## Further Reading -You can see how noirjs is used in a full stack Next.js hardhat application in the [noir-starter repo here](https://github.com/noir-lang/noir-starter/tree/main/next-hardhat). The example shows how to calculate a proof in the browser and verify it with a deployed Solidity verifier contract from noirjs. +You can see how noirjs is used in a full stack Next.js hardhat application in the [noir-starter repo here](https://github.com/noir-lang/noir-starter/tree/main/vite-hardhat). The example shows how to calculate a proof in the browser and verify it with a deployed Solidity verifier contract from noirjs. You should also check out the more advanced examples in the [noir-examples repo](https://github.com/noir-lang/noir-examples), where you'll find reference usage for some cool apps. diff --git a/docs/versioned_docs/version-v0.19.1/standard_library/cryptographic_primitives/04_ec_primitives.md b/docs/versioned_docs/version-v0.19.1/standard_library/cryptographic_primitives/04_ec_primitives.md index 6e6b19b6861..d3af3cf7c3b 100644 --- a/docs/versioned_docs/version-v0.19.1/standard_library/cryptographic_primitives/04_ec_primitives.md +++ b/docs/versioned_docs/version-v0.19.1/standard_library/cryptographic_primitives/04_ec_primitives.md @@ -71,7 +71,7 @@ does indeed lie on `c` by calling `c.contains(p1)`. ## Examples The -[ec_baby_jubjub test](https://github.com/noir-lang/noir/blob/master/crates/nargo_cli/tests/test_data/ec_baby_jubjub/src/main.nr) +[ec_baby_jubjub test](https://github.com/noir-lang/noir/blob/master/test_programs/compile_success_empty/ec_baby_jubjub/src/main.nr) illustrates all of the above primitives on various forms of the Baby Jubjub curve. A couple of more interesting examples in Noir would be: diff --git a/docs/versioned_docs/version-v0.19.2/getting_started/01_hello_world.md b/docs/versioned_docs/version-v0.19.2/getting_started/01_hello_world.md index 8b4416beba1..d4daae605a2 100644 --- a/docs/versioned_docs/version-v0.19.2/getting_started/01_hello_world.md +++ b/docs/versioned_docs/version-v0.19.2/getting_started/01_hello_world.md @@ -144,4 +144,4 @@ corresponding error instead. Congratulations, you have now created and verified a proof for your very first Noir program! -In the [next section](breakdown), we will go into more detail on each step performed. +In the [next section](./02_breakdown.md), we will go into more detail on each step performed. diff --git a/docs/versioned_docs/version-v0.19.2/language_concepts/06_generics.md b/docs/versioned_docs/version-v0.19.2/language_concepts/06_generics.md index 9fb4177c2a8..36c2b593fcd 100644 --- a/docs/versioned_docs/version-v0.19.2/language_concepts/06_generics.md +++ b/docs/versioned_docs/version-v0.19.2/language_concepts/06_generics.md @@ -110,4 +110,4 @@ fn main() { ``` You can see an example of generics in the tests -[here](https://github.com/noir-lang/noir/blob/master/tooling/nargo_cli/tests/execution_success/generics/src/main.nr). +[here](https://github.com/noir-lang/noir/blob/master/test_programs/execution_success/generics/src/main.nr). diff --git a/docs/versioned_docs/version-v0.19.2/noir_js/getting_started/01_tiny_noir_app.md b/docs/versioned_docs/version-v0.19.2/noir_js/getting_started/01_tiny_noir_app.md index c51ed61de52..795baa59d59 100644 --- a/docs/versioned_docs/version-v0.19.2/noir_js/getting_started/01_tiny_noir_app.md +++ b/docs/versioned_docs/version-v0.19.2/noir_js/getting_started/01_tiny_noir_app.md @@ -255,6 +255,6 @@ You can find the complete app code for this guide [here](https://github.com/noir ## Further Reading -You can see how noirjs is used in a full stack Next.js hardhat application in the [noir-starter repo here](https://github.com/noir-lang/noir-starter/tree/main/next-hardhat). The example shows how to calculate a proof in the browser and verify it with a deployed Solidity verifier contract from noirjs. +You can see how noirjs is used in a full stack Next.js hardhat application in the [noir-starter repo here](https://github.com/noir-lang/noir-starter/tree/main/vite-hardhat). The example shows how to calculate a proof in the browser and verify it with a deployed Solidity verifier contract from noirjs. You should also check out the more advanced examples in the [noir-examples repo](https://github.com/noir-lang/noir-examples), where you'll find reference usage for some cool apps. diff --git a/docs/versioned_docs/version-v0.19.2/standard_library/cryptographic_primitives/04_ec_primitives.md b/docs/versioned_docs/version-v0.19.2/standard_library/cryptographic_primitives/04_ec_primitives.md index 6e6b19b6861..d3af3cf7c3b 100644 --- a/docs/versioned_docs/version-v0.19.2/standard_library/cryptographic_primitives/04_ec_primitives.md +++ b/docs/versioned_docs/version-v0.19.2/standard_library/cryptographic_primitives/04_ec_primitives.md @@ -71,7 +71,7 @@ does indeed lie on `c` by calling `c.contains(p1)`. ## Examples The -[ec_baby_jubjub test](https://github.com/noir-lang/noir/blob/master/crates/nargo_cli/tests/test_data/ec_baby_jubjub/src/main.nr) +[ec_baby_jubjub test](https://github.com/noir-lang/noir/blob/master/test_programs/compile_success_empty/ec_baby_jubjub/src/main.nr) illustrates all of the above primitives on various forms of the Baby Jubjub curve. A couple of more interesting examples in Noir would be: diff --git a/docs/versioned_docs/version-v0.19.3/getting_started/01_hello_world.md b/docs/versioned_docs/version-v0.19.3/getting_started/01_hello_world.md index 8b4416beba1..d4daae605a2 100644 --- a/docs/versioned_docs/version-v0.19.3/getting_started/01_hello_world.md +++ b/docs/versioned_docs/version-v0.19.3/getting_started/01_hello_world.md @@ -144,4 +144,4 @@ corresponding error instead. Congratulations, you have now created and verified a proof for your very first Noir program! -In the [next section](breakdown), we will go into more detail on each step performed. +In the [next section](./02_breakdown.md), we will go into more detail on each step performed. diff --git a/docs/versioned_docs/version-v0.19.3/language_concepts/06_generics.md b/docs/versioned_docs/version-v0.19.3/language_concepts/06_generics.md index 9fb4177c2a8..36c2b593fcd 100644 --- a/docs/versioned_docs/version-v0.19.3/language_concepts/06_generics.md +++ b/docs/versioned_docs/version-v0.19.3/language_concepts/06_generics.md @@ -110,4 +110,4 @@ fn main() { ``` You can see an example of generics in the tests -[here](https://github.com/noir-lang/noir/blob/master/tooling/nargo_cli/tests/execution_success/generics/src/main.nr). +[here](https://github.com/noir-lang/noir/blob/master/test_programs/execution_success/generics/src/main.nr). diff --git a/docs/versioned_docs/version-v0.19.3/noir_js/getting_started/01_tiny_noir_app.md b/docs/versioned_docs/version-v0.19.3/noir_js/getting_started/01_tiny_noir_app.md index c51ed61de52..795baa59d59 100644 --- a/docs/versioned_docs/version-v0.19.3/noir_js/getting_started/01_tiny_noir_app.md +++ b/docs/versioned_docs/version-v0.19.3/noir_js/getting_started/01_tiny_noir_app.md @@ -255,6 +255,6 @@ You can find the complete app code for this guide [here](https://github.com/noir ## Further Reading -You can see how noirjs is used in a full stack Next.js hardhat application in the [noir-starter repo here](https://github.com/noir-lang/noir-starter/tree/main/next-hardhat). The example shows how to calculate a proof in the browser and verify it with a deployed Solidity verifier contract from noirjs. +You can see how noirjs is used in a full stack Next.js hardhat application in the [noir-starter repo here](https://github.com/noir-lang/noir-starter/tree/main/vite-hardhat). The example shows how to calculate a proof in the browser and verify it with a deployed Solidity verifier contract from noirjs. You should also check out the more advanced examples in the [noir-examples repo](https://github.com/noir-lang/noir-examples), where you'll find reference usage for some cool apps. diff --git a/docs/versioned_docs/version-v0.19.3/standard_library/cryptographic_primitives/04_ec_primitives.md b/docs/versioned_docs/version-v0.19.3/standard_library/cryptographic_primitives/04_ec_primitives.md index 6e6b19b6861..d3af3cf7c3b 100644 --- a/docs/versioned_docs/version-v0.19.3/standard_library/cryptographic_primitives/04_ec_primitives.md +++ b/docs/versioned_docs/version-v0.19.3/standard_library/cryptographic_primitives/04_ec_primitives.md @@ -71,7 +71,7 @@ does indeed lie on `c` by calling `c.contains(p1)`. ## Examples The -[ec_baby_jubjub test](https://github.com/noir-lang/noir/blob/master/crates/nargo_cli/tests/test_data/ec_baby_jubjub/src/main.nr) +[ec_baby_jubjub test](https://github.com/noir-lang/noir/blob/master/test_programs/compile_success_empty/ec_baby_jubjub/src/main.nr) illustrates all of the above primitives on various forms of the Baby Jubjub curve. A couple of more interesting examples in Noir would be: diff --git a/docs/versioned_docs/version-v0.19.4/getting_started/01_hello_world.md b/docs/versioned_docs/version-v0.19.4/getting_started/01_hello_world.md index 8b4416beba1..d4daae605a2 100644 --- a/docs/versioned_docs/version-v0.19.4/getting_started/01_hello_world.md +++ b/docs/versioned_docs/version-v0.19.4/getting_started/01_hello_world.md @@ -144,4 +144,4 @@ corresponding error instead. Congratulations, you have now created and verified a proof for your very first Noir program! -In the [next section](breakdown), we will go into more detail on each step performed. +In the [next section](./02_breakdown.md), we will go into more detail on each step performed. diff --git a/docs/versioned_docs/version-v0.19.4/language_concepts/06_generics.md b/docs/versioned_docs/version-v0.19.4/language_concepts/06_generics.md index 9fb4177c2a8..36c2b593fcd 100644 --- a/docs/versioned_docs/version-v0.19.4/language_concepts/06_generics.md +++ b/docs/versioned_docs/version-v0.19.4/language_concepts/06_generics.md @@ -110,4 +110,4 @@ fn main() { ``` You can see an example of generics in the tests -[here](https://github.com/noir-lang/noir/blob/master/tooling/nargo_cli/tests/execution_success/generics/src/main.nr). +[here](https://github.com/noir-lang/noir/blob/master/test_programs/execution_success/generics/src/main.nr). diff --git a/docs/versioned_docs/version-v0.19.4/noir_js/getting_started/01_tiny_noir_app.md b/docs/versioned_docs/version-v0.19.4/noir_js/getting_started/01_tiny_noir_app.md index c51ed61de52..795baa59d59 100644 --- a/docs/versioned_docs/version-v0.19.4/noir_js/getting_started/01_tiny_noir_app.md +++ b/docs/versioned_docs/version-v0.19.4/noir_js/getting_started/01_tiny_noir_app.md @@ -255,6 +255,6 @@ You can find the complete app code for this guide [here](https://github.com/noir ## Further Reading -You can see how noirjs is used in a full stack Next.js hardhat application in the [noir-starter repo here](https://github.com/noir-lang/noir-starter/tree/main/next-hardhat). The example shows how to calculate a proof in the browser and verify it with a deployed Solidity verifier contract from noirjs. +You can see how noirjs is used in a full stack Next.js hardhat application in the [noir-starter repo here](https://github.com/noir-lang/noir-starter/tree/main/vite-hardhat). The example shows how to calculate a proof in the browser and verify it with a deployed Solidity verifier contract from noirjs. You should also check out the more advanced examples in the [noir-examples repo](https://github.com/noir-lang/noir-examples), where you'll find reference usage for some cool apps. diff --git a/docs/versioned_docs/version-v0.19.4/standard_library/cryptographic_primitives/04_ec_primitives.md b/docs/versioned_docs/version-v0.19.4/standard_library/cryptographic_primitives/04_ec_primitives.md index 6e6b19b6861..d3af3cf7c3b 100644 --- a/docs/versioned_docs/version-v0.19.4/standard_library/cryptographic_primitives/04_ec_primitives.md +++ b/docs/versioned_docs/version-v0.19.4/standard_library/cryptographic_primitives/04_ec_primitives.md @@ -71,7 +71,7 @@ does indeed lie on `c` by calling `c.contains(p1)`. ## Examples The -[ec_baby_jubjub test](https://github.com/noir-lang/noir/blob/master/crates/nargo_cli/tests/test_data/ec_baby_jubjub/src/main.nr) +[ec_baby_jubjub test](https://github.com/noir-lang/noir/blob/master/test_programs/compile_success_empty/ec_baby_jubjub/src/main.nr) illustrates all of the above primitives on various forms of the Baby Jubjub curve. A couple of more interesting examples in Noir would be: diff --git a/docs/versioned_docs/version-v0.22.0/how_to/how-to-recursion.md b/docs/versioned_docs/version-v0.22.0/how_to/how-to-recursion.md index db9ad0e99f8..2f7be604401 100644 --- a/docs/versioned_docs/version-v0.22.0/how_to/how-to-recursion.md +++ b/docs/versioned_docs/version-v0.22.0/how_to/how-to-recursion.md @@ -47,7 +47,7 @@ In a standard recursive app, you're also dealing with at least two circuits. For - `main`: a circuit of type `assert(x != y)` - `recursive`: a circuit that verifies `main` -For a full example on how recursive proofs work, please refer to the [noir-examples](https://github.com/noir/noir-examples) repository. We will *not* be using it as a reference for this guide. +For a full example on how recursive proofs work, please refer to the [noir-examples](https://github.com/noir-lang/noir-examples) repository. We will *not* be using it as a reference for this guide. ## Step 1: Setup diff --git a/docs/versioned_docs/version-v0.22.0/noir/standard_library/cryptographic_primitives/ec_primitives.md b/docs/versioned_docs/version-v0.22.0/noir/standard_library/cryptographic_primitives/ec_primitives.md index 8d573adb3be..d2b42d67b7c 100644 --- a/docs/versioned_docs/version-v0.22.0/noir/standard_library/cryptographic_primitives/ec_primitives.md +++ b/docs/versioned_docs/version-v0.22.0/noir/standard_library/cryptographic_primitives/ec_primitives.md @@ -72,7 +72,7 @@ does indeed lie on `c` by calling `c.contains(p1)`. ## Examples The -[ec_baby_jubjub test](https://github.com/noir-lang/noir/blob/master/crates/nargo_cli/tests/test_data/ec_baby_jubjub/src/main.nr) +[ec_baby_jubjub test](https://github.com/noir-lang/noir/blob/master/test_programs/compile_success_empty/ec_baby_jubjub/src/main.nr) illustrates all of the above primitives on various forms of the Baby Jubjub curve. A couple of more interesting examples in Noir would be: diff --git a/docs/versioned_docs/version-v0.22.0/noir/syntax/generics.md b/docs/versioned_docs/version-v0.22.0/noir/syntax/generics.md index 443ca2b45a5..d59e4c5d7c6 100644 --- a/docs/versioned_docs/version-v0.22.0/noir/syntax/generics.md +++ b/docs/versioned_docs/version-v0.22.0/noir/syntax/generics.md @@ -111,4 +111,4 @@ fn main() { ``` You can see an example of generics in the tests -[here](https://github.com/noir-lang/noir/blob/master/tooling/nargo_cli/tests/execution_success/generics/src/main.nr). +[here](https://github.com/noir-lang/noir/blob/master/test_programs/execution_success/generics/src/main.nr). diff --git a/docs/versioned_docs/version-v0.22.0/tutorials/noirjs_app.md b/docs/versioned_docs/version-v0.22.0/tutorials/noirjs_app.md index 302ee4aeade..0763b6224c9 100644 --- a/docs/versioned_docs/version-v0.22.0/tutorials/noirjs_app.md +++ b/docs/versioned_docs/version-v0.22.0/tutorials/noirjs_app.md @@ -256,6 +256,6 @@ You can find the complete app code for this guide [here](https://github.com/noir ## Further Reading -You can see how noirjs is used in a full stack Next.js hardhat application in the [noir-starter repo here](https://github.com/noir-lang/noir-starter/tree/main/next-hardhat). The example shows how to calculate a proof in the browser and verify it with a deployed Solidity verifier contract from noirjs. +You can see how noirjs is used in a full stack Next.js hardhat application in the [noir-starter repo here](https://github.com/noir-lang/noir-starter/tree/main/vite-hardhat). The example shows how to calculate a proof in the browser and verify it with a deployed Solidity verifier contract from noirjs. You should also check out the more advanced examples in the [noir-examples repo](https://github.com/noir-lang/noir-examples), where you'll find reference usage for some cool apps. From 2e714444c46d2ba12f7c1171795f948417b1d94a Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Mon, 22 Jan 2024 17:56:13 +0000 Subject: [PATCH 10/70] chore: remove `compile_bin_package` (#4099) # Description ## Problem\* Resolves https://github.com/noir-lang/noir/issues/2608 ## Summary\* This PR removes the `compile_bin_package` function as it's pretty unnecessary. At the same time I've added filters to other commands which only make sense on binary packages to avoid #2608 ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- compiler/noirc_driver/src/contract.rs | 2 +- compiler/noirc_driver/tests/contracts.rs | 42 +++++++++++++++++++ .../multiple_contracts/Nargo.toml | 5 --- .../multiple_contracts/src/main.nr | 3 -- .../nargo_cli/src/cli/codegen_verifier_cmd.rs | 20 ++++++--- tooling/nargo_cli/src/cli/compile_cmd.rs | 30 ------------- tooling/nargo_cli/src/cli/dap_cmd.rs | 16 +++++-- tooling/nargo_cli/src/cli/debug_cmd.rs | 13 +++++- tooling/nargo_cli/src/cli/execute_cmd.rs | 17 ++++++-- tooling/nargo_cli/src/cli/prove_cmd.rs | 18 ++++++-- tooling/nargo_cli/src/cli/verify_cmd.rs | 22 ++++++---- 11 files changed, 123 insertions(+), 65 deletions(-) create mode 100644 compiler/noirc_driver/tests/contracts.rs delete mode 100644 test_programs/compile_failure/multiple_contracts/Nargo.toml delete mode 100644 test_programs/compile_failure/multiple_contracts/src/main.nr diff --git a/compiler/noirc_driver/src/contract.rs b/compiler/noirc_driver/src/contract.rs index ae55d239cf3..4d6d57ba9b6 100644 --- a/compiler/noirc_driver/src/contract.rs +++ b/compiler/noirc_driver/src/contract.rs @@ -26,7 +26,7 @@ pub enum ContractFunctionType { Unconstrained, } -#[derive(Serialize, Deserialize)] +#[derive(Debug, Serialize, Deserialize)] pub struct CompiledContract { pub noir_version: String, diff --git a/compiler/noirc_driver/tests/contracts.rs b/compiler/noirc_driver/tests/contracts.rs new file mode 100644 index 00000000000..c3041292352 --- /dev/null +++ b/compiler/noirc_driver/tests/contracts.rs @@ -0,0 +1,42 @@ +use std::path::Path; + +use fm::FileId; +use noirc_driver::{file_manager_with_stdlib, prepare_crate, CompileOptions, ErrorsAndWarnings}; +use noirc_errors::CustomDiagnostic; +use noirc_frontend::hir::{def_map::parse_file, Context}; + +#[test] +fn reject_crates_containing_multiple_contracts() -> Result<(), ErrorsAndWarnings> { + let source = " +contract Foo {} + +contract Bar {}"; + + let root = Path::new(""); + let file_name = Path::new("main.nr"); + let mut file_manager = file_manager_with_stdlib(root); + file_manager.add_file_with_source(file_name, source.to_owned()).expect( + "Adding source buffer to file manager should never fail when file manager is empty", + ); + let parsed_files = file_manager + .as_file_map() + .all_file_ids() + .map(|&file_id| (file_id, parse_file(&file_manager, file_id))) + .collect(); + + let mut context = Context::new(file_manager, parsed_files); + let root_crate_id = prepare_crate(&mut context, file_name); + + let errors = + noirc_driver::compile_contract(&mut context, root_crate_id, &CompileOptions::default()) + .unwrap_err(); + + assert_eq!( + errors, + vec![CustomDiagnostic::from_message("Packages are limited to a single contract") + .in_file(FileId::default())], + "stdlib is producing warnings" + ); + + Ok(()) +} diff --git a/test_programs/compile_failure/multiple_contracts/Nargo.toml b/test_programs/compile_failure/multiple_contracts/Nargo.toml deleted file mode 100644 index d6e4e632f95..00000000000 --- a/test_programs/compile_failure/multiple_contracts/Nargo.toml +++ /dev/null @@ -1,5 +0,0 @@ -[package] -name = "multiple_contracts" -type = "contract" -authors = [""] -[dependencies] diff --git a/test_programs/compile_failure/multiple_contracts/src/main.nr b/test_programs/compile_failure/multiple_contracts/src/main.nr deleted file mode 100644 index a6c49d75378..00000000000 --- a/test_programs/compile_failure/multiple_contracts/src/main.nr +++ /dev/null @@ -1,3 +0,0 @@ -contract Foo {} - -contract Bar {} diff --git a/tooling/nargo_cli/src/cli/codegen_verifier_cmd.rs b/tooling/nargo_cli/src/cli/codegen_verifier_cmd.rs index 8bf12ee4100..e7ab86f343a 100644 --- a/tooling/nargo_cli/src/cli/codegen_verifier_cmd.rs +++ b/tooling/nargo_cli/src/cli/codegen_verifier_cmd.rs @@ -1,12 +1,11 @@ +use super::fs::{create_named_dir, write_to_file}; use super::NargoConfig; -use super::{ - compile_cmd::compile_bin_package, - fs::{create_named_dir, write_to_file}, -}; use crate::backends::Backend; +use crate::cli::compile_cmd::report_errors; use crate::errors::CliError; use clap::Args; +use nargo::ops::compile_program; use nargo::{insert_all_files_for_workspace_into_file_manager, parse_all}; use nargo_toml::{get_package_manifest, resolve_workspace_from_toml, PackageSelection}; use noirc_driver::{file_manager_with_stdlib, CompileOptions, NOIR_ARTIFACT_VERSION_STRING}; @@ -47,13 +46,22 @@ pub(crate) fn run( let parsed_files = parse_all(&workspace_file_manager); let expression_width = backend.get_backend_info()?; - for package in &workspace { - let program = compile_bin_package( + let binary_packages = workspace.into_iter().filter(|package| package.is_binary()); + for package in binary_packages { + let compilation_result = compile_program( &workspace_file_manager, &parsed_files, package, &args.compile_options, expression_width, + None, + ); + + let program = report_errors( + compilation_result, + &workspace_file_manager, + args.compile_options.deny_warnings, + args.compile_options.silence_warnings, )?; let smart_contract_string = backend.eth_contract(&program.circuit)?; diff --git a/tooling/nargo_cli/src/cli/compile_cmd.rs b/tooling/nargo_cli/src/cli/compile_cmd.rs index aa9a46f39ef..29e6012996a 100644 --- a/tooling/nargo_cli/src/cli/compile_cmd.rs +++ b/tooling/nargo_cli/src/cli/compile_cmd.rs @@ -158,36 +158,6 @@ pub(super) fn compile_workspace( Ok((compiled_programs, compiled_contracts)) } -pub(crate) fn compile_bin_package( - file_manager: &FileManager, - parsed_files: &ParsedFiles, - package: &Package, - compile_options: &CompileOptions, - expression_width: ExpressionWidth, -) -> Result { - if package.is_library() { - return Err(CompileError::LibraryCrate(package.name.clone()).into()); - } - - let compilation_result = compile_program( - file_manager, - parsed_files, - package, - compile_options, - expression_width, - None, - ); - - let program = report_errors( - compilation_result, - file_manager, - compile_options.deny_warnings, - compile_options.silence_warnings, - )?; - - Ok(program) -} - pub(super) fn save_program( program: CompiledProgram, package: &Package, diff --git a/tooling/nargo_cli/src/cli/dap_cmd.rs b/tooling/nargo_cli/src/cli/dap_cmd.rs index 9798cbedfeb..c028545c11c 100644 --- a/tooling/nargo_cli/src/cli/dap_cmd.rs +++ b/tooling/nargo_cli/src/cli/dap_cmd.rs @@ -2,6 +2,7 @@ use acvm::acir::native_types::WitnessMap; use backend_interface::Backend; use clap::Args; use nargo::constants::PROVER_INPUT_FILE; +use nargo::ops::compile_program; use nargo::workspace::Workspace; use nargo::{insert_all_files_for_workspace_into_file_manager, parse_all}; use nargo_toml::{get_package_manifest, resolve_workspace_from_toml, PackageSelection}; @@ -21,7 +22,7 @@ use dap::server::Server; use dap::types::Capabilities; use serde_json::Value; -use super::compile_cmd::compile_bin_package; +use super::compile_cmd::report_errors; use super::fs::inputs::read_inputs_from_file; use crate::errors::CliError; @@ -72,12 +73,21 @@ fn load_and_compile_project( insert_all_files_for_workspace_into_file_manager(&workspace, &mut workspace_file_manager); let parsed_files = parse_all(&workspace_file_manager); - let compiled_program = compile_bin_package( + let compile_options = CompileOptions::default(); + let compilation_result = compile_program( &workspace_file_manager, &parsed_files, package, - &CompileOptions::default(), + &compile_options, expression_width, + None, + ); + + let compiled_program = report_errors( + compilation_result, + &workspace_file_manager, + compile_options.deny_warnings, + compile_options.silence_warnings, ) .map_err(|_| LoadError("Failed to compile project"))?; diff --git a/tooling/nargo_cli/src/cli/debug_cmd.rs b/tooling/nargo_cli/src/cli/debug_cmd.rs index e62cbc11ec8..ce89324a3b9 100644 --- a/tooling/nargo_cli/src/cli/debug_cmd.rs +++ b/tooling/nargo_cli/src/cli/debug_cmd.rs @@ -6,6 +6,7 @@ use clap::Args; use nargo::artifacts::debug::DebugArtifact; use nargo::constants::PROVER_INPUT_FILE; +use nargo::ops::compile_program; use nargo::package::Package; use nargo::{insert_all_files_for_workspace_into_file_manager, parse_all}; use nargo_toml::{get_package_manifest, resolve_workspace_from_toml, PackageSelection}; @@ -16,7 +17,7 @@ use noirc_driver::{ }; use noirc_frontend::graph::CrateName; -use super::compile_cmd::compile_bin_package; +use super::compile_cmd::report_errors; use super::fs::{inputs::read_inputs_from_file, witness::save_witness_to_dir}; use super::NargoConfig; use crate::backends::Backend; @@ -66,12 +67,20 @@ pub(crate) fn run( return Ok(()); }; - let compiled_program = compile_bin_package( + let compilation_result = compile_program( &workspace_file_manager, &parsed_files, package, &args.compile_options, expression_width, + None, + ); + + let compiled_program = report_errors( + compilation_result, + &workspace_file_manager, + args.compile_options.deny_warnings, + args.compile_options.silence_warnings, )?; run_async(package, compiled_program, &args.prover_name, &args.witness_name, target_dir) diff --git a/tooling/nargo_cli/src/cli/execute_cmd.rs b/tooling/nargo_cli/src/cli/execute_cmd.rs index cf0d46a0718..a84b2821f1e 100644 --- a/tooling/nargo_cli/src/cli/execute_cmd.rs +++ b/tooling/nargo_cli/src/cli/execute_cmd.rs @@ -5,7 +5,7 @@ use clap::Args; use nargo::artifacts::debug::DebugArtifact; use nargo::constants::PROVER_INPUT_FILE; use nargo::errors::try_to_diagnose_runtime_error; -use nargo::ops::DefaultForeignCallExecutor; +use nargo::ops::{compile_program, DefaultForeignCallExecutor}; use nargo::package::Package; use nargo::{insert_all_files_for_workspace_into_file_manager, parse_all}; use nargo_toml::{get_package_manifest, resolve_workspace_from_toml, PackageSelection}; @@ -16,10 +16,10 @@ use noirc_driver::{ }; use noirc_frontend::graph::CrateName; -use super::compile_cmd::compile_bin_package; use super::fs::{inputs::read_inputs_from_file, witness::save_witness_to_dir}; use super::NargoConfig; use crate::backends::Backend; +use crate::cli::compile_cmd::report_errors; use crate::errors::CliError; /// Executes a circuit to calculate its return value @@ -69,13 +69,22 @@ pub(crate) fn run( let parsed_files = parse_all(&workspace_file_manager); let expression_width = backend.get_backend_info_or_default(); - for package in &workspace { - let compiled_program = compile_bin_package( + let binary_packages = workspace.into_iter().filter(|package| package.is_binary()); + for package in binary_packages { + let compilation_result = compile_program( &workspace_file_manager, &parsed_files, package, &args.compile_options, expression_width, + None, + ); + + let compiled_program = report_errors( + compilation_result, + &workspace_file_manager, + args.compile_options.deny_warnings, + args.compile_options.silence_warnings, )?; let (return_value, solved_witness) = execute_program_and_decode( diff --git a/tooling/nargo_cli/src/cli/prove_cmd.rs b/tooling/nargo_cli/src/cli/prove_cmd.rs index d02464fd6df..a79c21c81c9 100644 --- a/tooling/nargo_cli/src/cli/prove_cmd.rs +++ b/tooling/nargo_cli/src/cli/prove_cmd.rs @@ -1,5 +1,6 @@ use clap::Args; use nargo::constants::{PROVER_INPUT_FILE, VERIFIER_INPUT_FILE}; +use nargo::ops::compile_program; use nargo::package::Package; use nargo::workspace::Workspace; use nargo::{insert_all_files_for_workspace_into_file_manager, parse_all}; @@ -10,7 +11,7 @@ use noirc_driver::{ }; use noirc_frontend::graph::CrateName; -use super::compile_cmd::compile_bin_package; +use super::compile_cmd::report_errors; use super::fs::{ inputs::{read_inputs_from_file, write_inputs_to_file}, proof::save_proof_to_dir, @@ -69,20 +70,29 @@ pub(crate) fn run( let parsed_files = parse_all(&workspace_file_manager); let expression_width = backend.get_backend_info()?; - for package in &workspace { - let program = compile_bin_package( + let binary_packages = workspace.into_iter().filter(|package| package.is_binary()); + for package in binary_packages { + let compilation_result = compile_program( &workspace_file_manager, &parsed_files, package, &args.compile_options, expression_width, + None, + ); + + let compiled_program = report_errors( + compilation_result, + &workspace_file_manager, + args.compile_options.deny_warnings, + args.compile_options.silence_warnings, )?; prove_package( backend, &workspace, package, - program, + compiled_program, &args.prover_name, &args.verifier_name, args.verify, diff --git a/tooling/nargo_cli/src/cli/verify_cmd.rs b/tooling/nargo_cli/src/cli/verify_cmd.rs index 1701b9e063c..daf623c10c6 100644 --- a/tooling/nargo_cli/src/cli/verify_cmd.rs +++ b/tooling/nargo_cli/src/cli/verify_cmd.rs @@ -1,12 +1,11 @@ +use super::compile_cmd::report_errors; +use super::fs::{inputs::read_inputs_from_file, load_hex_data}; use super::NargoConfig; -use super::{ - compile_cmd::compile_bin_package, - fs::{inputs::read_inputs_from_file, load_hex_data}, -}; use crate::{backends::Backend, errors::CliError}; use clap::Args; use nargo::constants::{PROOF_EXT, VERIFIER_INPUT_FILE}; +use nargo::ops::compile_program; use nargo::package::Package; use nargo::workspace::Workspace; use nargo::{insert_all_files_for_workspace_into_file_manager, parse_all}; @@ -56,16 +55,25 @@ pub(crate) fn run( let parsed_files = parse_all(&workspace_file_manager); let expression_width = backend.get_backend_info()?; - for package in &workspace { - let program = compile_bin_package( + let binary_packages = workspace.into_iter().filter(|package| package.is_binary()); + for package in binary_packages { + let compilation_result = compile_program( &workspace_file_manager, &parsed_files, package, &args.compile_options, expression_width, + None, + ); + + let compiled_program = report_errors( + compilation_result, + &workspace_file_manager, + args.compile_options.deny_warnings, + args.compile_options.silence_warnings, )?; - verify_package(backend, &workspace, package, program, &args.verifier_name)?; + verify_package(backend, &workspace, package, compiled_program, &args.verifier_name)?; } Ok(()) From bb1aa6890aeb2564c9c55fd267aa0338c2dccf49 Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Mon, 22 Jan 2024 18:05:43 +0000 Subject: [PATCH 11/70] chore: improve warning message for returning a constant value (#4106) # Description ## Problem\* Resolves ## Summary\* This message is a bit strong for a warning (constant return values are technically allowed, there's just generally not much reason for them). It also doesn't give much information on why they may not be a good idea. I've updated the warning to something which I think is more useful. Happy to take feedback on this however. ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- compiler/noirc_evaluator/src/errors.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/noirc_evaluator/src/errors.rs b/compiler/noirc_evaluator/src/errors.rs index d7229c0adc5..2582c48555a 100644 --- a/compiler/noirc_evaluator/src/errors.rs +++ b/compiler/noirc_evaluator/src/errors.rs @@ -68,7 +68,7 @@ impl From for FileDiagnostic { let message = warning.to_string(); let (secondary_message, call_stack) = match warning { InternalWarning::ReturnConstant { call_stack } => { - ("constant value".to_string(), call_stack) + ("This variable contains a value which is constrained to be a constant. Consider removing this value as additional return values increase proving/verification time".to_string(), call_stack) }, InternalWarning::VerifyProof { call_stack } => { ("verify_proof(...) aggregates data for the verifier, the actual verification will be done when the full proof is verified using nargo verify. nargo prove may generate an invalid proof if bad data is used as input to verify_proof".to_string(), call_stack) @@ -87,7 +87,7 @@ impl From for FileDiagnostic { #[derive(Debug, PartialEq, Eq, Clone, Error, Serialize, Deserialize)] pub enum InternalWarning { - #[error("Returning a constant value is not allowed")] + #[error("Return variable contains a constant value")] ReturnConstant { call_stack: CallStack }, #[error("Calling std::verify_proof(...) does not verify a proof")] VerifyProof { call_stack: CallStack }, From 1107373bbbb9a8ca088dd6ac43131392cb2f33e1 Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Mon, 22 Jan 2024 18:44:44 +0000 Subject: [PATCH 12/70] fix: check for tests in all packages before failing due to an unsatisfied test filter (#4114) # Description ## Problem\* Resolves ## Summary\* Currently if you're running tests in a workspace and are filtering them by name, if any of the packages doesn't contain a matching test then we will immediately return an error. This PR fixes this so that we wait until we have checked the entire workspace, should there still be no matching tests then we throw an error but otherwise pass. ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- tooling/nargo_cli/src/cli/test_cmd.rs | 98 ++++++++++++++------------- 1 file changed, 52 insertions(+), 46 deletions(-) diff --git a/tooling/nargo_cli/src/cli/test_cmd.rs b/tooling/nargo_cli/src/cli/test_cmd.rs index 5db842609e5..9fee27b9172 100644 --- a/tooling/nargo_cli/src/cli/test_cmd.rs +++ b/tooling/nargo_cli/src/cli/test_cmd.rs @@ -83,22 +83,44 @@ pub(crate) fn run( }; let blackbox_solver = Bn254BlackBoxSolver::new(); - for package in &workspace { - // By unwrapping here with `?`, we stop the test runner upon a package failing - // TODO: We should run the whole suite even if there are failures in a package - run_tests( - &workspace_file_manager, - &parsed_files, - &blackbox_solver, - package, - pattern, - args.show_output, - args.oracle_resolver.as_deref(), - &args.compile_options, - )?; + + let test_reports: Vec> = workspace + .into_iter() + .map(|package| { + run_tests( + &workspace_file_manager, + &parsed_files, + &blackbox_solver, + package, + pattern, + args.show_output, + args.oracle_resolver.as_deref(), + &args.compile_options, + ) + }) + .collect::>()?; + let test_report: Vec<(String, TestStatus)> = test_reports.into_iter().flatten().collect(); + + if test_report.is_empty() { + match &pattern { + FunctionNameMatch::Exact(pattern) => { + return Err(CliError::Generic( + format!("Found 0 tests matching input '{pattern}'.",), + )) + } + FunctionNameMatch::Contains(pattern) => { + return Err(CliError::Generic(format!("Found 0 tests containing '{pattern}'.",))) + } + // If we are running all tests in a crate, having none is not an error + FunctionNameMatch::Anything => {} + }; } - Ok(()) + if test_report.iter().any(|(_, status)| !matches!(status, TestStatus::Fail { .. })) { + Ok(()) + } else { + Err(CliError::Generic(String::new())) + } } #[allow(clippy::too_many_arguments)] @@ -111,7 +133,7 @@ fn run_tests( show_output: bool, foreign_call_resolver_url: Option<&str>, compile_options: &CompileOptions, -) -> Result<(), CliError> { +) -> Result, CliError> { let (mut context, crate_id) = prepare_package(file_manager, parsed_files, package); check_crate_and_report_errors( &mut context, @@ -123,45 +145,29 @@ fn run_tests( let test_functions = context.get_all_test_functions_in_crate_matching(&crate_id, fn_name); let count_all = test_functions.len(); - if count_all == 0 { - match &fn_name { - FunctionNameMatch::Exact(pattern) => { - return Err(CliError::Generic(format!( - "[{}] Found 0 tests matching input '{pattern}'.", - package.name - ))) - } - FunctionNameMatch::Contains(pattern) => { - return Err(CliError::Generic(format!( - "[{}] Found 0 tests containing '{pattern}'.", - package.name - ))) - } - // If we are running all tests in a crate, having none is not an error - FunctionNameMatch::Anything => {} - }; - } let plural = if count_all == 1 { "" } else { "s" }; println!("[{}] Running {count_all} test function{plural}", package.name); - let mut count_failed = 0; let writer = StandardStream::stderr(ColorChoice::Always); let mut writer = writer.lock(); + let mut test_report: Vec<(String, TestStatus)> = Vec::new(); for (test_name, test_function) in test_functions { write!(writer, "[{}] Testing {test_name}... ", package.name) .expect("Failed to write to stderr"); writer.flush().expect("Failed to flush writer"); - match run_test( + let test_status = run_test( blackbox_solver, &context, test_function, show_output, foreign_call_resolver_url, compile_options, - ) { + ); + + match &test_status { TestStatus::Pass { .. } => { writer .set_color(ColorSpec::new().set_fg(Some(Color::Green))) @@ -176,35 +182,36 @@ fn run_tests( if let Some(diag) = error_diagnostic { noirc_errors::reporter::report_all( context.file_manager.as_file_map(), - &[diag], + &[diag.clone()], compile_options.deny_warnings, compile_options.silence_warnings, ); } - count_failed += 1; } TestStatus::CompileError(err) => { noirc_errors::reporter::report_all( context.file_manager.as_file_map(), - &[err], + &[err.clone()], compile_options.deny_warnings, compile_options.silence_warnings, ); - count_failed += 1; } } + + test_report.push((test_name, test_status)); + writer.reset().expect("Failed to reset writer"); } write!(writer, "[{}] ", package.name).expect("Failed to write to stderr"); + let count_failed = + test_report.iter().filter(|(_, status)| !matches!(status, TestStatus::Pass)).count(); if count_failed == 0 { writer.set_color(ColorSpec::new().set_fg(Some(Color::Green))).expect("Failed to set color"); write!(writer, "{count_all} test{plural} passed").expect("Failed to write to stderr"); writer.reset().expect("Failed to reset writer"); writeln!(writer).expect("Failed to write to stderr"); - - Ok(()) } else { let count_passed = count_all - count_failed; let plural_failed = if count_failed == 1 { "" } else { "s" }; @@ -219,11 +226,10 @@ fn run_tests( } writer.set_color(ColorSpec::new().set_fg(Some(Color::Red))).expect("Failed to set color"); - write!(writer, "{count_failed} test{plural_failed} failed") + writeln!(writer, "{count_failed} test{plural_failed} failed") .expect("Failed to write to stderr"); writer.reset().expect("Failed to reset writer"); - - // Writes final newline. - Err(CliError::Generic(String::new())) } + + Ok(test_report) } From 4738beba6953602d65f410c010c79bd6c72d5e98 Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Mon, 22 Jan 2024 18:57:53 +0000 Subject: [PATCH 13/70] chore: remove remaining reference to ACVM stdlib (#4112) # Description ## Problem\* Resolves ## Summary\* :saluting_face: ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 8a827cacfcd..5dfff3dbb5d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -52,7 +52,6 @@ repository = "https://github.com/noir-lang/noir/" acir_field = { version = "0.39.0", path = "acvm-repo/acir_field", default-features = false } acir = { version = "0.39.0", path = "acvm-repo/acir", default-features = false } acvm = { version = "0.39.0", path = "acvm-repo/acvm" } -stdlib = { version = "0.37.1", package = "acvm_stdlib", path = "acvm-repo/stdlib", default-features = false } brillig = { version = "0.39.0", path = "acvm-repo/brillig", default-features = false } brillig_vm = { version = "0.39.0", path = "acvm-repo/brillig_vm", default-features = false } acvm_blackbox_solver = { version = "0.39.0", path = "acvm-repo/blackbox_solver", default-features = false } From 80f7e29340ceb88781dc80a13325468ace3b0cf3 Mon Sep 17 00:00:00 2001 From: Michael J Klein Date: Mon, 22 Jan 2024 14:50:12 -0500 Subject: [PATCH 14/70] feat: add option to print monomorphized program (#4119) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Description Debugging optimizations often requires inspecting the monomorphized program. This adds an option to enable this. ## Problem\* https://github.com/noir-lang/noir/issues/4067 ## Summary\* Example usage: ```bash ❯ (cd test_programs/compile_success_contract/simple_contract && cargo run compile --show-monomorphized) Compiling nargo_cli v0.23.0 (/Users/michaelklein/Coding/rust/noir/tooling/nargo_cli) Finished dev [optimized + debuginfo] target(s) in 1.79s Running `/Users/michaelklein/Coding/rust/noir/target/debug/nargo compile --show-monomorphized` Monomorphized AST for program with hash: 18020856208726922572 fn triple$f0(x$l0: Field) -> Field { (x$l0 * 3) } Monomorphized AST for program with hash: 9305131916264092540 fn skibbidy$f0(x$l0: Field) -> Field { (x$l0 * 5) } Monomorphized AST for program with hash: 17799031513160233728 fn double$f0(x$l0: Field) -> Field { (x$l0 * 2) } Monomorphized AST for program with hash: 16417890415031598568 fn quadruple$f0(x$l0: Field) -> Field { (x$l0 * 4) } ``` ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. (hidden option) - [ ] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [ ] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --------- Co-authored-by: jfecher --- compiler/noirc_driver/src/lib.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/compiler/noirc_driver/src/lib.rs b/compiler/noirc_driver/src/lib.rs index db69d41c704..a2570b26f3e 100644 --- a/compiler/noirc_driver/src/lib.rs +++ b/compiler/noirc_driver/src/lib.rs @@ -75,6 +75,10 @@ pub struct CompileOptions { /// Disables the builtin macros being used in the compiler #[arg(long, hide = true)] pub disable_macros: bool, + + /// Outputs the monomorphized IR to stdout for debugging + #[arg(long, hide = true)] + pub show_monomorphized: bool, } /// Helper type used to signify where only warnings are expected in file diagnostics @@ -391,6 +395,9 @@ pub fn compile_no_check( let hash = fxhash::hash64(&program); let hashes_match = cached_program.as_ref().map_or(false, |program| program.hash == hash); + if options.show_monomorphized { + println!("{program}"); + } // If user has specified that they want to see intermediate steps printed then we should // force compilation even if the program hasn't changed. From d56cac2af7dc1cce0795f8e9701bb17cc3e67e14 Mon Sep 17 00:00:00 2001 From: Koby Hall <102518238+kobyhallx@users.noreply.github.com> Date: Mon, 22 Jan 2024 21:46:24 +0100 Subject: [PATCH 15/70] feat(lsp): goto type reference for Struct (#4091) # Description ## Problem\* Resolves feat(lsp): goto type reference #4090 ## Summary\* Allows to go to type reference from symbol representing struct, ie. function return. ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- .../noirc_frontend/src/hir/resolution/resolver.rs | 14 +++++++++++++- compiler/noirc_frontend/src/hir_def/types.rs | 2 +- compiler/noirc_frontend/src/node_interner.rs | 10 +++++++++- compiler/noirc_frontend/src/resolve_locations.rs | 13 ++++++++++++- 4 files changed, 35 insertions(+), 4 deletions(-) diff --git a/compiler/noirc_frontend/src/hir/resolution/resolver.rs b/compiler/noirc_frontend/src/hir/resolution/resolver.rs index 1d4f60ffd51..492e96a4715 100644 --- a/compiler/noirc_frontend/src/hir/resolution/resolver.rs +++ b/compiler/noirc_frontend/src/hir/resolution/resolver.rs @@ -449,7 +449,7 @@ impl<'a> Resolver<'a> { fn resolve_type_inner(&mut self, typ: UnresolvedType, new_variables: &mut Generics) -> Type { use UnresolvedTypeData::*; - match typ.typ { + let resolved_type = match typ.typ { FieldElement => Type::FieldElement, Array(size, elem) => { let elem = Box::new(self.resolve_type_inner(*elem, new_variables)); @@ -510,7 +510,18 @@ impl<'a> Resolver<'a> { Type::MutableReference(Box::new(self.resolve_type_inner(*element, new_variables))) } Parenthesized(typ) => self.resolve_type_inner(*typ, new_variables), + }; + + if let Type::Struct(_, _) = resolved_type { + if let Some(unresolved_span) = typ.span { + // Record the location of the type reference + self.interner.push_type_ref_location( + resolved_type.clone(), + Location::new(unresolved_span, self.file), + ); + } } + resolved_type } fn find_generic(&self, target_name: &str) -> Option<&(Rc, TypeVariable, Span)> { @@ -714,6 +725,7 @@ impl<'a> Resolver<'a> { if resolved_type.is_nested_slice() { self.errors.push(ResolverError::NestedSlices { span: span.unwrap() }); } + resolved_type } diff --git a/compiler/noirc_frontend/src/hir_def/types.rs b/compiler/noirc_frontend/src/hir_def/types.rs index 8979d60c005..2c08a980d23 100644 --- a/compiler/noirc_frontend/src/hir_def/types.rs +++ b/compiler/noirc_frontend/src/hir_def/types.rs @@ -64,7 +64,7 @@ pub enum Type { TypeVariable(TypeVariable, TypeVariableKind), /// `impl Trait` when used in a type position. - /// These are only matched based on the TraitId. The trait name paramer is only + /// These are only matched based on the TraitId. The trait name parameter is only /// used for displaying error messages using the name of the trait. TraitAsType(TraitId, /*name:*/ Rc, /*generics:*/ Vec), diff --git a/compiler/noirc_frontend/src/node_interner.rs b/compiler/noirc_frontend/src/node_interner.rs index e734161e360..b856b54f6ca 100644 --- a/compiler/noirc_frontend/src/node_interner.rs +++ b/compiler/noirc_frontend/src/node_interner.rs @@ -146,6 +146,9 @@ pub struct NodeInterner { /// A list of all type aliases that are referenced in the program. /// Searched by LSP to resolve [Location]s of [TypeAliasType]s pub(crate) type_alias_ref: Vec<(TypeAliasId, Location)>, + + /// Stores the [Location] of a [Type] reference + pub(crate) type_ref_locations: Vec<(Type, Location)>, } /// A trait implementation is either a normal implementation that is present in the source @@ -455,6 +458,7 @@ impl Default for NodeInterner { struct_methods: HashMap::new(), primitive_methods: HashMap::new(), type_alias_ref: Vec::new(), + type_ref_locations: Vec::new(), }; // An empty block expression is used often, we add this into the `node` on startup @@ -607,6 +611,11 @@ impl NodeInterner { self.id_to_type.insert(definition_id.into(), typ); } + /// Store [Location] of [Type] reference + pub fn push_type_ref_location(&mut self, typ: Type, location: Location) { + self.type_ref_locations.push((typ, location)); + } + pub fn push_global(&mut self, stmt_id: StmtId, ident: Ident, local_id: LocalModuleId) { self.globals.insert(stmt_id, GlobalInfo { ident, local_id }); } @@ -1186,7 +1195,6 @@ impl NodeInterner { } /// Adds a trait implementation to the list of known implementations. - #[tracing::instrument(skip(self))] pub fn add_trait_implementation( &mut self, object_type: Type, diff --git a/compiler/noirc_frontend/src/resolve_locations.rs b/compiler/noirc_frontend/src/resolve_locations.rs index 02325de4da8..cfb88966b9d 100644 --- a/compiler/noirc_frontend/src/resolve_locations.rs +++ b/compiler/noirc_frontend/src/resolve_locations.rs @@ -42,6 +42,7 @@ impl NodeInterner { .and_then(|index| self.resolve_location(index, return_type_location_instead)) .or_else(|| self.try_resolve_trait_impl_location(location)) .or_else(|| self.try_resolve_trait_method_declaration(location)) + .or_else(|| self.try_resolve_type_ref(location)) .or_else(|| self.try_resolve_type_alias(location)) } @@ -196,7 +197,17 @@ impl NodeInterner { }) } - #[tracing::instrument(skip(self), ret)] + /// Attempts to resolve [Location] of [Type] based on [Location] of reference in code + pub(crate) fn try_resolve_type_ref(&self, location: Location) -> Option { + self.type_ref_locations + .iter() + .find(|(_typ, type_ref_location)| type_ref_location.contains(&location)) + .and_then(|(typ, _)| match typ { + Type::Struct(struct_typ, _) => Some(struct_typ.borrow().location), + _ => None, + }) + } + fn try_resolve_type_alias(&self, location: Location) -> Option { self.type_alias_ref .iter() From 09d1d5c91af2724dbc997353e754f46d7518999e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Pedro=20Sousa?= Date: Tue, 23 Jan 2024 13:14:39 +0000 Subject: [PATCH 16/70] chore(docs): Solidity Learning Journey (#4081) # Description As part of DevRel's work on Learning Journey's, this PR improves them. ## Problem\* Relates to [this DevRel issue](https://github.com/AztecProtocol/dev-rel/issues/119) ## Summary\* - Puts the "Creating a Project" and "Project Breakdown" pages inside a dropdown called "Hello Noir" - Refactors the Solidity Verifier How-To to include a Remix IDE verification example with images and more context - Refactors the Noir landing page to incorporate a "Noir Basics" role, improves UI, adds a header image and a tabs feature, and favouring links to awesome-noir instead of hardcoded library examples - Refactors the Homepage with buttons to immediately start the Solidity Learning journey ## Additional Context Here's the Solidity Learning Journey. For now only 3 levels deep, assuming the user would have enough autonomy to proceed after the 3rd page. This will be reassessed in the future. ![Screenshot 2024-01-18 at 10 29 44](https://github.com/noir-lang/noir/assets/20129824/cc9e2db1-911a-4d17-b77e-b57aec141c61) --------- Co-authored-by: James Zaki Co-authored-by: josh crites --- cspell.json | 4 +- docs/README.md | 18 +- .../hello_noir/_category_.json | 5 + .../index.md} | 10 +- .../{ => hello_noir}/project_breakdown.md | 22 +- .../getting_started/installation/index.md | 3 + .../getting_started/tooling/_category_.json | 2 +- docs/docs/how_to/how-to-solidity-verifier.md | 231 ++++++++++++++++++ docs/docs/how_to/solidity_verifier.md | 130 ---------- docs/docs/index.md | 85 ------- docs/docs/index.mdx | 67 +++++ docs/docs/tutorials/noirjs_app.md | 5 +- docs/src/css/custom.css | 84 ++++++- docs/src/pages/index.jsx | 60 ++++- docs/static/img/aztec_logo.png | Bin 0 -> 38182 bytes .../img/how-tos/solidity_verifier_1.png | Bin 0 -> 33611 bytes .../img/how-tos/solidity_verifier_2.png | Bin 0 -> 66931 bytes .../img/how-tos/solidity_verifier_3.png | Bin 0 -> 63153 bytes .../img/how-tos/solidity_verifier_4.png | Bin 0 -> 79069 bytes .../img/how-tos/solidity_verifier_5.png | Bin 0 -> 48989 bytes docs/static/img/logo.png | Bin 0 -> 178782 bytes docs/static/img/solidity_verifier_ex.png | Bin 0 -> 1177990 bytes 22 files changed, 472 insertions(+), 254 deletions(-) create mode 100644 docs/docs/getting_started/hello_noir/_category_.json rename docs/docs/getting_started/{create_a_project.md => hello_noir/index.md} (92%) rename docs/docs/getting_started/{ => hello_noir}/project_breakdown.md (86%) create mode 100644 docs/docs/how_to/how-to-solidity-verifier.md delete mode 100644 docs/docs/how_to/solidity_verifier.md delete mode 100644 docs/docs/index.md create mode 100644 docs/docs/index.mdx create mode 100644 docs/static/img/aztec_logo.png create mode 100644 docs/static/img/how-tos/solidity_verifier_1.png create mode 100644 docs/static/img/how-tos/solidity_verifier_2.png create mode 100644 docs/static/img/how-tos/solidity_verifier_3.png create mode 100644 docs/static/img/how-tos/solidity_verifier_4.png create mode 100644 docs/static/img/how-tos/solidity_verifier_5.png create mode 100644 docs/static/img/logo.png create mode 100644 docs/static/img/solidity_verifier_ex.png diff --git a/cspell.json b/cspell.json index 0547b956d72..7aae298f417 100644 --- a/cspell.json +++ b/cspell.json @@ -174,7 +174,9 @@ "Weierstraß", "zshell", "nouner", - "devcontainer" + "devcontainer", + "boilerplate", + "boilerplates" ], "ignorePaths": [ "./**/node_modules/**", diff --git a/docs/README.md b/docs/README.md index 92f6c5f41f7..c1d2bbd6d4e 100644 --- a/docs/README.md +++ b/docs/README.md @@ -2,7 +2,7 @@ This is the source code for the Noir documentation site at [noir-lang.org](https://noir-lang.org). -This website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website +This website is built using [Docusaurus 3](https://docusaurus.io/), a modern static website generator. ## Contributing @@ -15,14 +15,20 @@ Check out the contributing guide [here](../CONTRIBUTING.md). ### Installation +This project requires recent versions of rust and cargo to be installed. +Any build errors should indicate dependencies that need installing, and at what version. + +On the root folder of the repository, run: + ``` yarn +yarn build ``` ### Local Development ``` -yarn start +yarn workspace docs start ``` This command starts a local development server and opens up a browser window. Most changes are @@ -31,8 +37,12 @@ reflected live without having to restart the server. ### Build ``` -yarn build +yarn workspace docs build ``` This command generates static content into the `build` directory and can be served using any static -contents hosting service. +contents hosting service. You can see a preview by running: + +``` +yarn workspace docs serve +``` diff --git a/docs/docs/getting_started/hello_noir/_category_.json b/docs/docs/getting_started/hello_noir/_category_.json new file mode 100644 index 00000000000..23b560f610b --- /dev/null +++ b/docs/docs/getting_started/hello_noir/_category_.json @@ -0,0 +1,5 @@ +{ + "position": 1, + "collapsible": true, + "collapsed": true +} diff --git a/docs/docs/getting_started/create_a_project.md b/docs/docs/getting_started/hello_noir/index.md similarity index 92% rename from docs/docs/getting_started/create_a_project.md rename to docs/docs/getting_started/hello_noir/index.md index 26ff265c389..743c4d8d634 100644 --- a/docs/docs/getting_started/create_a_project.md +++ b/docs/docs/getting_started/hello_noir/index.md @@ -1,5 +1,5 @@ --- -title: Creating A Project +title: Creating a Project description: Learn how to create and verify your first Noir program using Nargo, a programming language for zero-knowledge proofs. @@ -48,7 +48,7 @@ nargo new hello_world > `test`). A `hello_world` folder would be created. Similar to Rust, the folder houses _src/main.nr_ and -_Nargo.toml_ that contains the source code and environmental options of your Noir program +_Nargo.toml_ which contain the source code and environmental options of your Noir program respectively. ### Intro to Noir Syntax @@ -69,7 +69,7 @@ x : Field, y : pub Field Program inputs in Noir are private by default (e.g. `x`), but can be labeled public using the keyword `pub` (e.g. `y`). To learn more about private and public values, check the -[Data Types](../noir/concepts/data_types/index.md) section. +[Data Types](../../noir/concepts/data_types/index.md) section. The next line of the program specifies its body: @@ -79,7 +79,7 @@ assert(x != y); The Noir syntax `assert` can be interpreted as something similar to constraints in other zk-contract languages. -For more Noir syntax, check the [Language Concepts](../noir/concepts/comments.md) chapter. +For more Noir syntax, check the [Language Concepts](../../noir/concepts/comments.md) chapter. ## Build In/Output Files @@ -96,7 +96,7 @@ _Prover.toml_ houses input values, and _Verifier.toml_ houses public values. ## Prove Our Noir Program -Now that the project is set up, we can create a proof of correct execution on our Noir program. +Now that the project is set up, we can create a proof of correct execution of our Noir program. Fill in input values for execution in the _Prover.toml_ file. For example: diff --git a/docs/docs/getting_started/project_breakdown.md b/docs/docs/getting_started/hello_noir/project_breakdown.md similarity index 86% rename from docs/docs/getting_started/project_breakdown.md rename to docs/docs/getting_started/hello_noir/project_breakdown.md index c4e2a9ae003..6160a102c6c 100644 --- a/docs/docs/getting_started/project_breakdown.md +++ b/docs/docs/getting_started/hello_noir/project_breakdown.md @@ -8,8 +8,8 @@ keywords: sidebar_position: 2 --- -This section breaks down our hello world program in section _1.2_. We elaborate on the project -structure and what the `prove` and `verify` commands did in the previous section. +This section breaks down our hello world program from the previous section. We elaborate on the project +structure and what the `prove` and `verify` commands did. ## Anatomy of a Nargo Project @@ -52,7 +52,7 @@ license = "MIT" ecrecover = {tag = "v0.9.0", git = "https://github.com/colinnielsen/ecrecover-noir.git"} ``` -Nargo.toml for a [workspace](../noir/modules_packages_crates/workspaces.md) will look a bit different. For example: +Nargo.toml for a [workspace](../../noir/modules_packages_crates/workspaces.md) will look a bit different. For example: ```toml [workspace] @@ -62,7 +62,7 @@ default-member = "crates/a" #### Package section -The package section requires a number of fields including: +The package section defines a number of fields including: - `name` (**required**) - the name of the package - `type` (**required**) - can be "bin", "lib", or "contract" to specify whether its a binary, library or Aztec contract @@ -75,7 +75,7 @@ The package section requires a number of fields including: #### Dependencies section -This is where you will specify any dependencies for your project. See the [Dependencies page](../noir/modules_packages_crates/dependencies.md) for more info. +This is where you will specify any dependencies for your project. See the [Dependencies page](../../noir/modules_packages_crates/dependencies.md) for more info. `./proofs/` and `./contract/` directories will not be immediately visible until you create a proof or verifier contract respectively. @@ -98,7 +98,7 @@ verifying the proof. The prover supplies the values for `x` and `y` in the _Prover.toml_ file. -As for the program body, `assert` ensures the satisfaction of the condition (e.g. `x != y`) is +As for the program body, `assert` ensures that the condition to be satisfied (e.g. `x != y`) is constrained by the proof of the execution of said program (i.e. if the condition was not met, the verifier would reject the proof as an invalid proof). @@ -116,8 +116,8 @@ y = "2" When the command `nargo prove` is executed, two processes happen: -1. Noir creates a proof that `x` which holds the value of `1` and `y` which holds the value of `2` - is not equal. This not equal constraint is due to the line `assert(x != y)`. +1. Noir creates a proof that `x`, which holds the value of `1`, and `y`, which holds the value of `2`, + is not equal. This inequality constraint is due to the line `assert(x != y)`. 2. Noir creates and stores the proof of this statement in the _proofs_ directory in a file called your-project.proof. So if your project is named "private_voting" (defined in the project Nargo.toml), the proof will be saved at `./proofs/private_voting.proof`. Opening this file will display the proof in hex format. @@ -183,12 +183,12 @@ When the command `nargo verify` is executed, two processes happen: In production, the prover and the verifier are usually two separate entities. A prover would retrieve the necessary inputs, execute the Noir program, generate a proof and pass it to the -verifier. The verifier would then retrieve the public inputs from usually external sources and -verifies the validity of the proof against it. +verifier. The verifier would then retrieve the public inputs, usually from external sources, and +verify the validity of the proof against it. Take a private asset transfer as an example: -A user on browser as the prover would retrieve private inputs (e.g. the user's private key) and +A person using a browser as the prover would retrieve private inputs locally (e.g. the user's private key) and public inputs (e.g. the user's encrypted balance on-chain), compute the transfer, generate a proof and submit it to the verifier smart contract. diff --git a/docs/docs/getting_started/installation/index.md b/docs/docs/getting_started/installation/index.md index 27eeeca88ed..4ef86aa5914 100644 --- a/docs/docs/getting_started/installation/index.md +++ b/docs/docs/getting_started/installation/index.md @@ -16,6 +16,7 @@ keywords: [ Branches Noirup Repository ] +pagination_next: getting_started/hello_noir/index --- `nargo` is the one-stop-shop for almost everything related with Noir. The name comes from our love for Rust and its package manager `cargo`. @@ -43,3 +44,5 @@ Done. That's it. You should have the latest version working. You can check with You can also install nightlies, specific versions or branches. Check out the [noirup repository](https://github.com/noir-lang/noirup) for more information. + +Now we're ready to start working on [our first Noir program!](../hello_noir/index.md) diff --git a/docs/docs/getting_started/tooling/_category_.json b/docs/docs/getting_started/tooling/_category_.json index dff520ebc41..55804c03a71 100644 --- a/docs/docs/getting_started/tooling/_category_.json +++ b/docs/docs/getting_started/tooling/_category_.json @@ -1,5 +1,5 @@ { - "position": 3, + "position": 2, "label": "Tooling", "collapsible": true, "collapsed": true diff --git a/docs/docs/how_to/how-to-solidity-verifier.md b/docs/docs/how_to/how-to-solidity-verifier.md new file mode 100644 index 00000000000..e3c7c1065da --- /dev/null +++ b/docs/docs/how_to/how-to-solidity-verifier.md @@ -0,0 +1,231 @@ +--- +title: Generate a Solidity Verifier +description: + Learn how to run the verifier as a smart contract on the blockchain. Compile a Solidity verifier + contract for your Noir program and deploy it on any EVM blockchain acting as a verifier smart + contract. Read more to find out +keywords: + [ + solidity verifier, + smart contract, + blockchain, + compiler, + plonk_vk.sol, + EVM blockchain, + verifying Noir programs, + proving backend, + Barretenberg, + ] +sidebar_position: 0 +pagination_next: tutorials/noirjs_app +--- + +Noir has the ability to generate a verifier contract in Solidity, which can be deployed in many EVM-compatible blockchains such as Ethereum. + +This allows for a powerful feature set, as one can make use of the conciseness and the privacy provided by Noir in an immutable ledger. Applications can range from simple P2P guessing games, to complex private DeFi interactions. + +This guide shows you how to generate a Solidity Verifier and deploy it on the [Remix IDE](https://remix.ethereum.org/). It is assumed that: + +- You are comfortable with the Solidity programming language and understand how contracts are deployed on the Ethereum network +- You have Noir installed and you have a Noir program. If you don't, [get started](../getting_started/installation/index.md) with Nargo and the example Hello Noir circuit +- You are comfortable navigating RemixIDE. If you aren't or you need a refresher, you can find some video tutorials [here](https://www.youtube.com/channel/UCjTUPyFEr2xDGN6Cg8nKDaA) that could help you. + +## Rundown + +Generating a Solidity Verifier contract is actually a one-command process. However, compiling it and deploying it can have some caveats. Here's the rundown of this guide: + +1. How to generate a solidity smart contract +2. How to compile the smart contract in the RemixIDE +3. How to deploy it to a testnet + +## Step 1 - Generate a contract + +This is by far the most straight-forward step. Just run: + +```sh +nargo codegen-verifier +``` + +A new `contract` folder would then be generated in your project directory, containing the Solidity +file `plonk_vk.sol`. It can be deployed to any EVM blockchain acting as a verifier smart contract. + +:::info + +It is possible to generate verifier contracts of Noir programs for other smart contract platforms as long as the proving backend supplies an implementation. + +Barretenberg, the default proving backend for Nargo, supports generation of verifier contracts, for the time being these are only in Solidity. +::: + +## Step 2 - Compiling + +We will mostly skip the details of RemixIDE, as the UI can change from version to version. For now, we can just open +Remix and create a blank workspace. + +![Create Workspace](@site/static/img/how-tos/solidity_verifier_1.png) + +We will create a new file to contain the contract Nargo generated, and copy-paste its content. + +:::warning + +You'll likely see a warning advising you to not trust pasted code. While it is an important warning, it is irrelevant in the context of this guide and can be ignored. We will not be deploying anywhere near a mainnet. + +::: + +To compile our the verifier, we can navigate to the compilation tab: + +![Compilation Tab](@site/static/img/how-tos/solidity_verifier_2.png) + +Remix should automatically match a suitable compiler version. However, hitting the "Compile" button will most likely generate a "Stack too deep" error: + +![Stack too deep](@site/static/img/how-tos/solidity_verifier_3.png) + +This is due to the verify function needing to put many variables on the stack, but enabling the optimizer resolves the issue. To do this, let's open the "Advanced Configurations" tab and enable optimization. The default 200 runs will suffice. + +:::info + +This time we will see a warning about an unused function parameter. This is expected, as the `verify` function doesn't use the `_proof` parameter inside a solidity block, it is loaded from calldata and used in assembly. + +::: + +![Compilation success](@site/static/img/how-tos/solidity_verifier_4.png) + +## Step 3 - Deploying + +At this point we should have a compiled contract read to deploy. If we navigate to the deploy section in Remix, we will see many different environments we can deploy to. The steps to deploy on each environment would be out-of-scope for this guide, so we will just use the default Remix VM. + +Looking closely, we will notice that our "Solidity Verifier" is actually three contracts working together: + +- An `UltraVerificationKey` library which simply stores the verification key for our circuit. +- An abstract contract `BaseUltraVerifier` containing most of the verifying logic. +- A main `UltraVerifier` contract that inherits from the Base and uses the Key contract. + +Remix will take care of the dependencies for us so we can simply deploy the UltraVerifier contract by selecting it and hitting "deploy": + +![Deploying UltraVerifier](@site/static/img/how-tos/solidity_verifier_5.png) + +A contract will show up in the "Deployed Contracts" section, where we can retrieve the Verification Key Hash. This is particularly useful for double-checking the deployer contract is the correct one. + +:::note + +Why "UltraVerifier"? + +To be precise, the Noir compiler (`nargo`) doesn't generate the verifier contract directly. It compiles the Noir code into an intermediate language (ACIR), which is then executed by the backend. So it is the backend that returns the verifier smart contract, not Noir. + +In this case, the Barretenberg Backend uses the UltraPlonk proving system, hence the "UltraVerifier" name. + +::: + +## Step 4 - Verifying + +To verify a proof using the Solidity verifier contract, we call the `verify` function in this extended contract: + +```solidity +function verify(bytes calldata _proof, bytes32[] calldata _publicInputs) external view returns (bool) +``` + +When using the default example in the [Hello Noir](../getting_started/hello_noir/index.md) guide, the easiest way to confirm that the verifier contract is doing its job is by calling the `verify` function via remix with the required parameters. For `_proof`, run `nargo prove` and use the string in `proof/.proof` (adding the hex `0x` prefix). We can also copy the public input from `Verifier.toml`, as it will be properly formatted as 32-byte strings: + +``` +0x...... , [0x0000.....02] +``` + +A programmatic example of how the `verify` function is called can be seen in the example zk voting application [here](https://github.com/noir-lang/noir-examples/blob/33e598c257e2402ea3a6b68dd4c5ad492bce1b0a/foundry-voting/src/zkVote.sol#L35): + +```solidity +function castVote(bytes calldata proof, uint proposalId, uint vote, bytes32 nullifierHash) public returns (bool) { + // ... + bytes32[] memory publicInputs = new bytes32[](4); + publicInputs[0] = merkleRoot; + publicInputs[1] = bytes32(proposalId); + publicInputs[2] = bytes32(vote); + publicInputs[3] = nullifierHash; + require(verifier.verify(proof, publicInputs), "Invalid proof"); +``` + +:::info[Return Values] + +A circuit doesn't have the concept of a return value. Return values are just syntactic sugar in +Noir. + +Under the hood, the return value is passed as an input to the circuit and is checked at the end of +the circuit program. + +For example, if you have Noir program like this: + +```rust +fn main( + // Public inputs + pubkey_x: pub Field, + pubkey_y: pub Field, + // Private inputs + priv_key: Field, +) -> pub Field +``` + +the `verify` function will expect the public inputs array (second function parameter) to be of length 3, the two inputs and the return value. Like before, these values are populated in Verifier.toml after running `nargo prove`. + +Passing only two inputs will result in an error such as `PUBLIC_INPUT_COUNT_INVALID(3, 2)`. + +In this case, the inputs parameter to `verify` would be an array ordered as `[pubkey_x, pubkey_y, return]`. + +::: + +:::tip[Structs] + +You can pass structs to the verifier contract. They will be flattened so that the array of inputs is 1-dimensional array. + +For example, consider the following program: + +```rust +struct Type1 { + val1: Field, + val2: Field, +} + +struct Nested { + t1: Type1, + is_true: bool, +} + +fn main(x: pub Field, nested: pub Nested, y: pub Field) { + //... +} +``` + +The order of these inputs would be flattened to: `[x, nested.t1.val1, nested.t1.val2, nested.is_true, y]` + +::: + +The other function you can call is our entrypoint `verify` function, as defined above. + +:::tip + +It's worth noticing that the `verify` function is actually a `view` function. A `view` function does not alter the blockchain state, so it doesn't need to be distributed (i.e. it will run only on the executing node), and therefore doesn't cost any gas. + +This can be particularly useful in some situations. If Alice generated a proof and wants Bob to verify its correctness, Bob doesn't need to run Nargo, NoirJS, or any Noir specific infrastructure. He can simply make a call to the blockchain with the proof and verify it is correct without paying any gas. + +It would be incorrect to say that a Noir proof verification costs any gas at all. However, most of the time the result of `verify` is used to modify state (for example, to update a balance, a game state, etc). In that case the whole network needs to execute it, which does incur gas costs (calldata and execution, but not storage). + +::: + +## A Note on EVM chains + +ZK-SNARK verification depends on some precompiled cryptographic primitives such as Elliptic Curve Pairings (if you like complex math, you can read about EC Pairings [here](https://medium.com/@VitalikButerin/exploring-elliptic-curve-pairings-c73c1864e627)). Not all EVM chains support EC Pairings, notably some of the ZK-EVMs. This means that you won't be able to use the verifier contract in all of them. + +For example, chains like `zkSync ERA` and `Polygon zkEVM` do not currently support these precompiles, so proof verification via Solidity verifier contracts won't work. Here's a quick list of EVM chains that have been tested and are known to work: + +- Optimism +- Arbitrum +- Polygon PoS +- Scroll +- Celo + +If you test any other chains, please open a PR on this page to update the list. See [this doc](https://github.com/noir-lang/noir-starter/tree/main/with-foundry#testing-on-chain) for more info about testing verifier contracts on different EVM chains. + +## What's next + +Now that you know how to call a Noir Solidity Verifier on a smart contract using Remix, you should be comfortable with using it with some programmatic frameworks, such as [hardhat](https://github.com/noir-lang/noir-starter/tree/main/vite-hardhat) and [foundry](https://github.com/noir-lang/noir-starter/tree/main/with-foundry). + +You can find other tools, examples, boilerplates and libraries in the [awesome-noir](https://github.com/noir-lang/awesome-noir) repository. + +You should also be ready to write and deploy your first NoirJS app and start generating proofs on websites, phones, and NodeJS environments! Head on to the [NoirJS tutorial](../tutorials/noirjs_app.md) to learn how to do that. diff --git a/docs/docs/how_to/solidity_verifier.md b/docs/docs/how_to/solidity_verifier.md deleted file mode 100644 index 8022b0e5f20..00000000000 --- a/docs/docs/how_to/solidity_verifier.md +++ /dev/null @@ -1,130 +0,0 @@ ---- -title: Generate a Solidity Verifier -description: - Learn how to run the verifier as a smart contract on the blockchain. Compile a Solidity verifier - contract for your Noir program and deploy it on any EVM blockchain acting as a verifier smart - contract. Read more to find out -keywords: - [ - solidity verifier, - smart contract, - blockchain, - compiler, - plonk_vk.sol, - EVM blockchain, - verifying Noir programs, - proving backend, - Barretenberg, - ] -sidebar_position: 0 ---- - -For certain applications, it may be desirable to run the verifier as a smart contract instead of on -a local machine. - -Compile a Solidity verifier contract for your Noir program by running: - -```sh -nargo codegen-verifier -``` - -A new `contract` folder would then be generated in your project directory, containing the Solidity -file `plonk_vk.sol`. It can be deployed on any EVM blockchain acting as a verifier smart contract. - -> **Note:** It is possible to compile verifier contracts of Noir programs for other smart contract -> platforms as long as the proving backend supplies an implementation. -> -> Barretenberg, the default proving backend for Nargo, supports compilation of verifier contracts in -> Solidity only for the time being. - -## Verify - -To verify a proof using the Solidity verifier contract, call the `verify` function with the -following signature: - -```solidity -function verify(bytes calldata _proof, bytes32[] calldata _publicInputs) external view returns (bool) -``` - -You can see an example of how the `verify` function is called in the example zk voting application [here](https://github.com/noir-lang/noir-examples/blob/33e598c257e2402ea3a6b68dd4c5ad492bce1b0a/foundry-voting/src/zkVote.sol#L35): - -```solidity -function castVote(bytes calldata proof, uint proposalId, uint vote, bytes32 nullifierHash) public returns (bool) { - // ... - bytes32[] memory publicInputs = new bytes32[](4); - publicInputs[0] = merkleRoot; - publicInputs[1] = bytes32(proposalId); - publicInputs[2] = bytes32(vote); - publicInputs[3] = nullifierHash; - require(verifier.verify(proof, publicInputs), "Invalid proof"); -``` - -### Public Inputs - -:::tip - -A circuit doesn't have the concept of a return value. Return values are just syntactic sugar in -Noir. - -Under the hood, the return value is passed as an input to the circuit and is checked at the end of -the circuit program. - -::: - -The verifier contract uses the output (return) value of a Noir program as a public input. So if you -have the following function - -```rust -fn main( - // Public inputs - pubkey_x: pub Field, - pubkey_y: pub Field, - // Private inputs - priv_key: Field, -) -> pub Field -``` - -then `verify` in `plonk_vk.sol` will expect 3 public inputs. Passing two inputs will result in an -error like `Reason: PUBLIC_INPUT_COUNT_INVALID(3, 2)`. - -In this case the 3 inputs to `verify` would be ordered as `[pubkey_x, pubkey_y, return]`. - -#### Struct inputs - -Consider the following program: - -```rust -struct Type1 { - val1: Field, - val2: Field, -} - -struct Nested { - t1: Type1, - is_true: bool, -} - -fn main(x: pub Field, nested: pub Nested, y: pub Field) { - //... -} -``` - -Structs will be flattened so that the array of inputs is 1-dimensional array. The order of these inputs would be flattened to: `[x, nested.t1.val1, nested.t1.val2, nested.is_true, y]` - -## Noir for EVM chains - -You can currently deploy the Solidity verifier contracts to most EVM compatible chains. EVM chains that have been tested and are known to work include: - -- Optimism -- Arbitrum -- Polygon PoS -- Scroll -- Celo - -Other EVM chains should work, but have not been tested directly by our team. If you test any other chains, please open a PR on this page to update the list. See [this doc](https://github.com/noir-lang/noir-starter/tree/main/with-foundry#testing-on-chain) for more info about testing verifier contracts on different EVM chains. - -### Unsupported chains - -Unfortunately not all "EVM" chains are supported. - -**zkSync** and the **Polygon zkEVM** do _not_ currently support proof verification via Solidity verifier contracts. They are missing the bn256 precompile contract that the verifier contract requires. Once these chains support this precompile, they may work. diff --git a/docs/docs/index.md b/docs/docs/index.md deleted file mode 100644 index ab8c2f8acd2..00000000000 --- a/docs/docs/index.md +++ /dev/null @@ -1,85 +0,0 @@ ---- -title: Noir -description: - Learn about the public alpha release of Noir, a domain specific language heavily influenced by Rust that compiles to - an intermediate language which can be compiled to an arithmetic circuit or a rank-1 constraint system. -keywords: - [ - Noir, - Domain Specific Language, - Rust, - Intermediate Language, - Arithmetic Circuit, - Rank-1 Constraint System, - Ethereum Developers, - Protocol Developers, - Blockchain Developers, - Proving System, - Smart Contract Language, - ] -sidebar_position: 0 ---- - -## What's new about Noir? - -Noir, a domain-specific language crafted for SNARK proving systems, stands out with its simplicity, flexibility, -and robust capabilities. Unlike conventional approaches that compile directly to a fixed NP-complete language, -Noir takes a two-pronged path. First, Noir compiles to an adaptable intermediate language known as ACIR. - -From there, depending on a given project's needs, ACIR can be further compiled into an arithmetic circuit for integration with Aztec's -barretenberg backend, or transformed into a rank-1 constraint system suitable for R1CS backends like Arkworks' Marlin -backend (among others). - -This innovative design introduces unique challenges; however, this approach also strategically separates the programming language from the -backend. Noir's approach echoes the modular philosophy of LLVM, offering developers a versatile toolkit for cryptographic -programming. - -## Who is Noir for? - -### Solidity Developers - -Noir streamlines the creation of Solidity contracts that interface with SNARK systems. -[`Utilize the nargo codegen-verifier`](./reference/nargo_commands.md#nargo-codegen-verifier) command to construct verifier -contracts efficiently. While the current alpha version offers this as a direct feature, future updates aim -to modularize this process for even greater ease of use. - -Noir currently includes a command to create a Solidity contract which verifies your Noir program. This will be -modularized in the future; however, as of the alpha, you can use the `nargo codegen-verifier` command to create a verifier contract. - -### Protocol Developers - -Should the Aztec backend not align with your existing tech stack, or if you're inclined to integrate alternative -proving systems, Noir's agnostic compilation to a proof-agnostic intermediate language offers unmatched flexibility. -This allows protocol engineers the freedom to substitute the default PLONK-based system with an alternative of their -choice, tailoring the proving system to their specific needs. - -### Blockchain developers - -Blockchain developers often face environmental constraints, such as predetermined proving systems and smart contract -languages. Noir addresses this by enabling the implementation of custom proving system backends and smart contract -interfaces, ensuring seamless integration with your blockchain's architecture, and expanding the horizons for innovation -within your projects. - -## Libraries - -Noir does not currently have an official package manager. You can find a list of some of the available Noir libraries in the -[awesome-noir repo here](https://github.com/noir-lang/awesome-noir#libraries). - -Some libraries that are available today include: - -- [Standard Library](https://github.com/noir-lang/noir/tree/master/noir_stdlib) - the Noir Standard Library -- [Ethereum Storage Proof Verification](https://github.com/aragonzkresearch/noir-trie-proofs) - a library that contains - the primitives necessary for RLP decoding (in the form of look-up table construction) and Ethereum state and storage - proof verification (or verification of any trie proof involving 32-byte long keys) -- [BigInt](https://github.com/shuklaayush/noir-bigint) - a library that provides a custom BigUint56 data type, allowing - for computations on large unsigned integers -- [ECrecover](https://github.com/colinnielsen/ecrecover-noir/tree/main) - a library to verify an ECDSA signature and - return the source Ethereum address -- [Sparse Merkle Tree Verifier](https://github.com/vocdoni/smtverifier-noir/tree/main) - a library for verification of - sparse Merkle trees -- [Signed Int](https://github.com/resurgencelabs/signed_int) - a library for accessing a custom Signed Integer data - type, allowing access to negative numbers on Noir -- [Fraction](https://github.com/resurgencelabs/fraction) - a library for accessing fractional number data type in Noir, - allowing results that aren't whole numbers - -See the section on [dependencies](noir/modules_packages_crates/dependencies.md) for more information. diff --git a/docs/docs/index.mdx b/docs/docs/index.mdx new file mode 100644 index 00000000000..2cec2397051 --- /dev/null +++ b/docs/docs/index.mdx @@ -0,0 +1,67 @@ +--- +title: Noir Lang +hide_title: true +description: + Learn about the public alpha release of Noir, a domain specific language heavily influenced by Rust that compiles to + an intermediate language which can be compiled to an arithmetic circuit or a rank-1 constraint system. +keywords: + [Noir, + Domain Specific Language, + Rust, + Intermediate Language, + Arithmetic Circuit, + Rank-1 Constraint System, + Ethereum Developers, + Protocol Developers, + Blockchain Developers, + Proving System, + Smart Contract Language] +sidebar_position: 0 +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +Noir Logo + +Noir is a Domain-Specific Language for SNARK proving systems developed by [Aztec Labs](https://aztec.network/). It allows you to generate complex Zero-Knowledge Programs (ZKP) by using simple and flexible syntax, requiring no previous knowledge on the underlying mathematics or cryptography. + +ZK programs are programs that can generate short proofs of a certain statement without revealing some details about it. You can read more about ZKPs [here](https://dev.to/spalladino/a-beginners-intro-to-coding-zero-knowledge-proofs-c56). + +## What's new about Noir? + +Noir works differently from most ZK languages by taking a two-pronged path. First, it compiles the program to an adaptable intermediate language known as ACIR. From there, depending on a given project's needs, ACIR can be further compiled into an arithmetic circuit for integration with the proving backend. + +:::info + +Noir is backend agnostic, which means it makes no assumptions on which proving backend powers the ZK proof. Being the language that powers [Aztec Contracts](https://docs.aztec.network/dev_docs/contracts/main), it defaults to Aztec's Barretenberg proving backend. + +However, the ACIR output can be transformed to be compatible with other PLONK-based backends, or into a [rank-1 constraint system](https://www.rareskills.io/post/rank-1-constraint-system) suitable for backends such as Arkwork's Marlin. + +::: + +## Who is Noir for? + +Noir can be used both in complex cloud-based backends and in user's smartphones, requiring no knowledge on the underlying math or cryptography. From authorization systems that keep a password in the user's device, to complex on-chain verification of recursive proofs, Noir is designed to abstract away complexity without any significant overhead. Here are some examples of situations where Noir can be used: + + + + Noir Logo + + Aztec Contracts leverage Noir to allow for the storage and execution of private information. Writing an Aztec Contract is as easy as writing Noir, and Aztec developers can easily interact with the network storage and execution through the [Aztec.nr](https://docs.aztec.network/dev_docs/contracts/main) library. + + + Soliditry Verifier Example + Noir can auto-generate Solidity verifier contracts that verify Noir proofs. This allows for non-interactive verification of proofs containing private information in an immutable system. This feature powers a multitude of use-case scenarios, from P2P chess tournaments, to [Aztec Layer-2 Blockchain](https://docs.aztec.network/) + + + Aztec Labs developed NoirJS, an easy interface to generate and verify Noir proofs in a Javascript environment. This allows for Noir to be used in webpages, mobile apps, games, and any other environment supporting JS execution in a standalone manner. + + + + +## Libraries + +Noir is meant to be easy to extend by simply importing Noir libraries just like in Rust. +The [awesome-noir repo](https://github.com/noir-lang/awesome-noir#libraries) is a collection of libraries developed by the Noir community. +Writing a new library is easy and makes code be composable and easy to reuse. See the section on [dependencies](noir/modules_packages_crates/dependencies.md) for more information. diff --git a/docs/docs/tutorials/noirjs_app.md b/docs/docs/tutorials/noirjs_app.md index 9f83def914b..23534795dde 100644 --- a/docs/docs/tutorials/noirjs_app.md +++ b/docs/docs/tutorials/noirjs_app.md @@ -3,6 +3,7 @@ title: Building a web app with NoirJS description: Learn how to setup a new app that uses Noir to generate and verify zero-knowledge SNARK proofs in a typescript or javascript environment. keywords: [how to, guide, javascript, typescript, noir, barretenberg, zero-knowledge, proofs, app] sidebar_position: 0 +pagination_next: noir/concepts/data_types/index --- NoirJS is a set of packages meant to work both in a browser and a server environment. In this tutorial, we will build a simple web app using them. From here, you should get an idea on how to proceed with your own Noir projects! @@ -70,7 +71,7 @@ At this point in the tutorial, your folder structure should look like this: ### Node and Vite If you want to explore Nargo, feel free to go on a side-quest now and follow the steps in the -[getting started](../getting_started/create_a_project) guide. However, we want our app to run on the browser, so we need Vite. +[getting started](../getting_started/hello_noir/index.md) guide. However, we want our app to run on the browser, so we need Vite. Vite is a powerful tool to generate static websites. While it provides all kinds of features, let's just go barebones with some good old vanilla JS. @@ -205,7 +206,7 @@ We're starting with the good stuff now. If you've compiled the circuit as descri import circuit from '../circuit/target/circuit.json'; ``` -[Noir is backend-agnostic](../index.md#whats-new-about-noir). We write Noir, but we also need a proving backend. That's why we need to import and instantiate the two dependencies we installed above: `BarretenbergBackend` and `Noir`. Let's import them right below: +[Noir is backend-agnostic](../index.mdx#whats-new-about-noir). We write Noir, but we also need a proving backend. That's why we need to import and instantiate the two dependencies we installed above: `BarretenbergBackend` and `Noir`. Let's import them right below: ```js import { BarretenbergBackend } from '@noir-lang/backend_barretenberg'; diff --git a/docs/src/css/custom.css b/docs/src/css/custom.css index c96e9df9832..5a526ec5bfd 100644 --- a/docs/src/css/custom.css +++ b/docs/src/css/custom.css @@ -89,25 +89,103 @@ html[data-theme='dark'] { text-align: center; } +.homepage_h2 { + display: flex; + margin-top: 40px; + justify-content: center; + width: 100%; +} + .homepage_p { display: block; margin: 0 auto; text-align: center; } +.homepage_cta_header_container { + display: flex; + justify-content: center; +} + .homepage_cta_container { display: flex; justify-content: center; margin: 0 auto; text-align: center; border: none; - width: 50%; + flex-wrap: wrap; + margin-right: 20px; + width: 100%; } +[data-theme='dark'] .homepage_cta_container a button { + color: var(--ifm-font-color-base-inverse); +} + +.homepage_cta_container a { + flex: 1 1; + display: flex; + color: var(--ifm-font-color-base-inverse); +} + +@media screen and (min-width: 584px) { + .homepage_cta_container a:first-child { + margin-right: 20px; + } + .homepage_cta_container:last-child { + margin-right: 0; + } +} + + .homepage_cta { - display: block; - margin: 50px auto; + display: flex; + margin: 20px auto; text-align: center; + flex: 1 auto; + justify-content: center; +} + + +.homepage_cta_lj_container { + display: flex; + justify-content: center; +} + +@media screen and (max-width: 584px) { + .homepage_cta_container { + margin: 20px auto; + padding: 0.5rem 2rem; + } + + .homepage_cta_lj_container { + flex-wrap: wrap; + } + + .homepage_cta_lj_container .homepage_cta_container { + border: var(--ifm-global-border-width) solid #BEC2C3; + } + + .homepage_cta_lj_container .homepage_cta_container a { + width: 100%; + flex: auto; + } + +} + +.homepage_cta_lj_container .homepage_cta_container a button { + background-color: var(--ifm-color-primary-lightest); + border-color: var(--ifm-color-primary-lightest); +} + +[data-theme='dark'] .homepage_cta_lj_container .homepage_cta_container a button { + background-color: var(--ifm-color-primary-light); + border-color: var(--ifm-color-primary-light); +} + +.homepage_cta_lj_container .homepage_cta_container a:last-of-type button { + background-color: var(--ifm-color-secondary-dark); + border-color: var(--ifm-color-secondary-dark); } .cards__container { diff --git a/docs/src/pages/index.jsx b/docs/src/pages/index.jsx index d5cbfcba977..6b52628a5ff 100644 --- a/docs/src/pages/index.jsx +++ b/docs/src/pages/index.jsx @@ -2,7 +2,7 @@ import React, { lazy, Suspense } from 'react'; import Layout from '@theme/Layout'; import Link from '@docusaurus/Link'; -import headerPic from '../../static/img/homepage_header_pic.png'; +import headerPic from '@site/static/img/homepage_header_pic.png'; import { BeatLoader } from 'react-spinners'; const NoirEditor = lazy(() => import('@signorecello/noir_playground')); @@ -41,7 +41,23 @@ export default function Landing() { compatible proving system. Its design choices are influenced heavily by Rust and focuses on a simple, familiar syntax.

- + {!tryIt && ( +
+
+ + + + + + +
+
+ )} {tryIt && ( }> @@ -52,16 +68,36 @@ export default function Landing() { )} {!tryIt && ( -
- - - - +
+
+

Learn

+ + + + + + +
+
+

Coming from...

+ + + + + + +
+
+

New to Everything

+ + + + + + +
)}
diff --git a/docs/static/img/aztec_logo.png b/docs/static/img/aztec_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..8e7c3b640398eff385fc2fa4e8664ff7fd333ffc GIT binary patch literal 38182 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

^%-8T#Hjk*RaM)g*DqER0<&F(C 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 literal 0 HcmV?d00001 diff --git a/docs/static/img/how-tos/solidity_verifier_1.png b/docs/static/img/how-tos/solidity_verifier_1.png new file mode 100644 index 0000000000000000000000000000000000000000..8a959f156a06a4a30ed88efec38b5198cee79705 GIT binary patch literal 33611 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 literal 0 HcmV?d00001 diff --git a/docs/static/img/how-tos/solidity_verifier_3.png b/docs/static/img/how-tos/solidity_verifier_3.png new file mode 100644 index 0000000000000000000000000000000000000000..e30186e32d621e5b78e0a7393790a4a39ac91cab GIT binary patch literal 63153 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 literal 0 HcmV?d00001 diff --git a/docs/static/img/how-tos/solidity_verifier_4.png b/docs/static/img/how-tos/solidity_verifier_4.png new file mode 100644 index 0000000000000000000000000000000000000000..aacb906f2891f45b6697bdbaf7bc9ea70a28416a GIT binary patch literal 79069 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 literal 0 HcmV?d00001 diff --git a/docs/static/img/logo.png b/docs/static/img/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..83d3a66f2b19c95b4a61503dfed64d9423fc6903 GIT binary patch literal 178782 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 z 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μlIktv+m3 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 z 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 literal 0 HcmV?d00001 diff --git a/docs/static/img/solidity_verifier_ex.png b/docs/static/img/solidity_verifier_ex.png new file mode 100644 index 0000000000000000000000000000000000000000..e0f381ff424d8abeefc19e82f20678e922252095 GIT binary patch literal 1177990 zcmXuLcQ{-B|Noze2(dS{OKa6?6}1whrQ;>kY_(PgZ53^)oy1mc(Mbm}OKlyfmDp5k z6tzi=+L9m=nLqE(_xk;HuIpUqI_Hn`cwUd^{eHhao=+Sd>;$1lpa1|s@Vve4WdJ~A z4*-B@@bVnqDTvo09$tWtF56iHss`lO003pcd0Q)&2(Qi9JB>?5Re|GdY5bgBw83Eb zDWrEX&jpb_UJ>90(>IhAlgcOD2HaKxSoXmN5rtyW2ie4V6lWJRkL9oiQS4m?io+mc zIR})DanwEs!JP9VMGjJu_CXt2`@(PMF-}{mlR*uX|2;y5VWob?bl0->nb$QLk%PpQ zx_M2MF+F%*lmACmM;*QeI~@w+kCM5)NbUYlsrBH$>gQMGTCQTZ?gsB^G7m=B{VjCq zgAm=Mr`*z&KgrM@k`0BpXUYmr#Z2nToI{c(e zgU0At-{hqcA(Hu1zj34Q*a@t)F*7>yi#e9%)jE1L&I*_vh%k=%1}uutGMZW9G~r8j zW`aUWG-*ye)4BIfEwv+->HAFsU@5)5$yj^QREk~~QUUxSUpIMm=Vgj+jB}gahly|O zAV8Q$vo+l~Yv>*GX0gSsEPgF_{Gw;iGi`v24)50YhpQ63WhE{Z0 zhF3UlKiiEKfbT!-kOQ;o*(T*R76E8kDWX?ACGC@ndJHfK`{^Dc^g=7 zX3MRV@jBFBOwEBP^kw#fQi)MubBo=I2>=jK2=-95x>kt;OzrS|G>AxT`hcL>=P z=&3jDM2MPVF~TTUc;<5VX6Ng|?=$A7AQwr1Vtoh;>IJz0)^8%WC4+=e)oiYQ$4EAd zTbT9amflQH`}hFzpGY1W@43IXv`?bYG&_{9phm3B8@J1p2*l^L+0kdNlC_LxF1D3c z-hV%u+bReE3fDIrpg4 zYvL$;T64ilx@p3pT0?PyO`b5`r>yT%B_@A}dUCDP(9zHcv=RQp5} z&3S|w$W-QBP&#++_#7zfX{t9_!CPFe=(jhPoB4`N`>W)041B%%;#)t?v?&bnq}px; zqJy&0P{h*I%V>RgRSA^$(qQ*=G>hey$s^F<>}e?thGJ;5AugrcEE5&j)12eAym_hAnnz2bX>o?#KW2ibmbrgiR@p4`8#H zww42IF>lxrWpjD`&089wsNse%X6L{8vE5zh^igyDJWG##7mb%tSvzJ6@PU%@P)kN4 z#rd9D{H?girT`{o1Fe-{PXA5iTm^rnBmuSN|9 zifUsF3Qs{v^4?fN(dp-?p8s0syExyPtAC&(3CQE6a|MJAch}`kJ1m=sMJc&0A;;9! zOJ6DX!i+;LhOKWTWz1$%tD}6l(Z0!m&QWv|ZU&qomC(?<`4b_dKf#UCjhik>cBE`H71-SNOuL+Mp!rM}$SRuH4*b9^$~P@}n^(`S#K*-$NJ%8b{|RG}EZ&J_2{P=hunNL~U{*4euHnWb zn@kH!vT1vRs|I|NHs?Os`Z(#%$))g^&S;mxO%J_^1h-|owP0n;&&2#sY@~seF1Dun)AIN?9Je2R56M{VtL@oAC&H5RW?Mi`~|9v_H8p z^Y_U%f%9}rTQUFu1@#Eap8&1xQ)|;+cCn3{tsaDHO9WW6MLd(1M(SssFR72s9ehe4 zCNr|w^z)>Va^B?gQO!2_VKz&ARl(P+_ST9sjoqf{Zs{#%<7{szyD~1U$ugXK>V8}# zOb=gmAO0H5nNp9fh%2M*dJ0VpYCCaZTDIrWF`(_2l#y3QxNEd@LNL~tl+Eito1=wk zd~S6%*X7SP3V$YJH$R0kCA#eb;agtcgc7P(IntCmA06jg{+RX=|u@?^HE?ZPYXz-YZAj@c*gj1#eRFeyA~9b|RJ`;_`o+1lG(#--6^q4ww}qDaFgDDUTzl zf2i@76U?oaK6rYZq{>LI68|}^S#8r}9B6UFuK|JWI`07euj$`M0|58n6{`EKquxwz zCPLd%i#>O*C0qiz)s3j<;+3xV4sxsEMAG~Au~+g2rI^w#+|zQnDy~?XLK~k6h(|MX z#S3QKS+2HJzpy1tre<-s#5Nw~u%GXgW!6Uz649-qh|G4x&G_#CR@dwM?IV5Z)X>-zWQ$KV=HL?BSx4%N<(rk#5&+8{@G*wMk!kv9dyW+qe+*j!RL4q zk7J``l9gY=){xrT#OrHAxDTYvPoxt_cdd4p18$*P<7AIm2Kx1SVU?MzTC4Aguh>qG zd7A!>gazaM?QZn&)|aXw*BNTG1c1aQpw+I>`1ql4EkE*%@`0>vHS(^L)$^F**1S27^?y3%q zNwm*4$g%62*8r|>lP%J7f_;L;kEEec!y74*G}2iS;UNa2o4afO)XP zd@bxy7%Uo0s*A&U#20q)U$=;t^-yY6G1O1EHajwjfUxSmZIPZ3X7ocGMGaP-FEl z7~L$S%|@;&%`foCqk_92uFai1*?6wA{75aL=YY4{X)Y>B>H^*?nu;0dEfvU(?m`r$*1#Lmh>iP_TEV&$@pNX5LPN|<{lCOuf9 zPQ+3RDx(_KDIE0t%>?!f&!y0wNvZa;LRuWkqc}Cau$7e$9r21m&sC9l1L!5+cTWU! zvT0J-oxR70gk_- z``gfF5*LLgx_}@j@qdpsT*M?!)P#Ui`_pG$H_u4U(K*yHTlvkFpfl_=$BxZweTcWc zldBhB8gu_dHz_r63Oh2QqS%R$lQI$q>f*wNCqM0KF_&H=o`62(Bg2`7W%tSkC;6s6 zcyLV!no~VxLyQxJPf7`Z@n?h#XJ~m3NoZl23fqB4ydU}L2eORz99!TK!cN47C|z9x zdDI#6G^MdQ-4&Mh+@os%3EHNYANg0(!S66_w;XkRLA7(&mma#WeZ+hK>d}!~FGk;= z=Hs+ksc3U;2QK7V9u)xYM2?@PeO6Ttm)H~!5|P+ZmlwJ$eK79Ho}+NISuNX9jt5_b zQC4k;Kj@QgvD#ajO%^ns87pK0({|Hee!4HM$+Y~&i!T1Rz+uWVvWs1x1W9Ishj$Zh zqHH8#TR@A8Tx^GomJZdd8ut(h{!&rvv*Y=+#9-d?F0(zNEu4!YKCJJv5YoX6i3BR6 zZ9ifaYHY54Z(0rSEdeR1Bnxhoq)2b_V=&b#gz4yW(3!@;{u}70L)oSrs}|M#t)Yo} z&Mm{0L{>b;!yMhvvPgW+Z#^v-DucY80Px$dZUXD_6WFhexkc9JSL2xxOo@-mNtlTk zHD~2@_Uzf$(N%+tzUOkQ_xYHZ>OSaRej@B>8^STpYEfx?a#3UM0Zf=l^^BkUvRRJu z$$$}%-uR&)#Qo+xFU2qOt69b|Q);uqHlP#e4?+=H=c_lrw=S|6kx%pH*7Va~o-BHs z2HkHBi<0Gfpl{bT-=sgJ>9s6^@?Py-j9WfcC?qj}CD!??AYS0j2>=fm!@DbPEdYLX z7yV`yK%m8Vx51j;*Woa3#`beYKj(h#?t~qkPp&*?AOndxh{%KEabzaj@@$!yi+3PRX?|_dd zB-2ca-@JIVgFcb$4V9_r)|7p>0)6ZWzy254IHm|POUvWhu^f2#XrwkgqRm)E!`Ei> z`p_!NDmhOm^}qJLD#0UQtwQIho!tv5kzu)g=$gCiL^SZLY84veOjeu>54~QyGaXl5 z8=j|XUKSY6SF;his;!V@xJxk9c$i&ZO*QVkAxXBOFAE*mE}31juPsxdn=^e&F@MD4 z|C~y<(FUxY5+N!Z>al;^y2N`w<0CNaPvTiv(kDyN$JtNC7s4TDmNlojs{Trfa}Ql% zd?rcb;|)Pb;L@GY>%n&tJCYY3^@k-mRYnj6O20C)VhxEIB~85#lj)B%pFIOA?+eO& z)I+XU>ndQ)hv4#3HLH9{}v=g`iT_@JermW1%j&;gc&=+};;Pp8anr-KbvxBTw za@D1z9TcBx4%>W!^cK)+igQ)U8wdRpnRa+%T%E|X^?7uj@gMJz%ULDIgsc1m0QNJ@ z&6+2bK$zG8RUFJj4OQo(GliVH@EnPgFEjbPk?IVswWoHZfo*|eLY$U%?>xO#f1Oox zMh0}w3$H^U-tQ{M;r>buMd;%kaU9Q*tQgD1yQ}t79iD4%0=3&opIl-8wUv4ue8i(1 zFKI`fZ`-&6_|}^ISVMsc!tCz+5e+}1RF6f4pVL{{>S;f1rl_y5*SGU;2YB|?n4jn`F0Oo1LNz0G(ASg&#Ya10hK;y)x1e%^}FdCigk zy6x;|b4Ec=GBS;r3ndAduL)U(J!AeH)@iF(w`%T>og>!2tZODxz;~{)!A?vIS6r~R zK(lm>h4eS=ow{Rruv;jl@ocF1Q1Q8LNRUfr+FJ8flo_9L8$u_(YZ7JIYUtgp0IU6H zZ{S$XX?yYepKLCI?Z=K?;;d9ZI@P?H@`R_FoLoHzk}JZkTwfuLRK)Lh0*jqF1uVWs zqz)iyR{Vr%SEXD2L==mn4Kzws>TNvm&n%x60OpN9J^`M4u4==+-fL5fnS3)H^TE_Eht&Eh>K ze&@;JY(2c`F?`Nz$iFh%8-f>Pz<&5Btr&CyBR;CmK29@JD%}N!r;wikt|eyBCFRU? zd&@yEx1p6JNzx0hFXPXfwcd)makn~gqWVC+XYcovDE4wwh(n22#ns5ePYI!~bC`Tg zTP{&T*7k=S&*iTuyprzfqdZ!B_-49&a>yWD5~SEF##RCPnwfm&!MCBCl1@q}W@-o& zsSJm`^_`~q5V$ZJW|}yV9us^A54B z3A3eFuHG5E4dQwYjId2E9lcgH5)l|)KL3y*C{9a*wOy~_35pPD&k46!P_Kzl7FLoM zm>T8A{sG`malM93Ow6mjzfo`aS&4UpXvVc|%5Xj%dy)w@7Me%oDknJ7o(MEV---d| zMPxSH;;t8>{`<2}g_49$F;Do22yZexrVXk$gYR2m-QwPxM;i~ar-fppakGsgF71i| z${}rtt+zW4{ApZ!E#s9nzRwAhD+Muf*oT$o`Hs9^`x_0O5`5z*L!{qgmNvQfec}cv z!}mdEO$hOr>}HPT>ZG`JPi@}f!nK%5Dsh)DQYte9D+xR(;X?UwEXI^^PBj_3KGH&t zLy$%Fa>5nJyYbdShQj{0IMlKJ`CdeWE8a7@{=Z{IR8QH(UI9)ghumWMpL zuamw^`h+Mz^3?W;BW&mC^yn2jYEdn{S>@8c0MFT# zU~%C2Y|G=V>~R=}#hBk_%JT_!K(6U@&W0r=oSUkBV4okK`Y-1i8T8_j<=OKQqzS7mEL+`nT zhl}wMG#+rLrI=8Ite-NLA?y%Pvmmc#JZGt4iC!XyvPf-O310z0`J)j%3y<47%0W`N zxYU#RzCDPbn46M@{CQ;L{5Q30r}=_KBo=U}`?v^g0fCq9e_8SM{k$w+mLa@A-QpoZ zol7Y{%Ey=a`e&ZOy7mO)@0zBBy`5$G`fMaFOgr{HIJwU0U=s#S4Uo3~vX3P*;G_)H z$Dh4m(W4dUX;3Z!gfX(wWP&TXQ;gF61fNaKO+)M0P}Q_$tUKF}E^ATgh*F_z@F;iM z$uiDJ=@fpC>Y&_anu*G&5z#EJcnd|?e;YnG#gEi+89mLJ59zS?>u}+id{3~3KE-Z# zgT~U+SA@=v@4n4Lp^QcT0VtPM2A~ylh3|cXf?Q9XU@E#8N+6GlAK5F9)LwQ+-EM|m zmWJKZKXF-41s?A8>KTDQ#TXL@u#zBaWzlzMw>~I{JVlQ&I0oR;@sN;sm{?{9#Z2tT zRY4xD^m9T=6N$->3X|F`Jv)+4pm2+wwM(xiVrB=B$77mze85?s2c6wuvPvoq*sk)J zWZw?&-ra18M)Rd&U*wmbksG(UyI;&n>dSpX93!k&czFPwrlT3HVe(c07b31HZ0j9u;xugk1$cfby9H=ra3bU-_k}4D-Wl`hSJD>17asqmj9{r)mU+;KnJm&IZ z&nceNrSD&JObF^?dc}X#PZ&%|}UVuQi3B$8D(AhXebwo>x0_u?A!;NZpq?a^k_ z;DblULchl0-g;w=eWrG#s!0%<1Jy6kT zMpi!T8uxD*z#w89`d=EMarKd$zW{PVBo#WLti5nrT-xiBBRJh52T4!H1(Aef>P-P} z(M`+VUOj$IVnl#|R7it@fFxX$N2C&szHJ@9jCTTW3)5gqCLVVmDm;UnF8)`0^Pp&t zYK-5`!z}bXQorK}NY}6&4_Pn6z5+=k-S{tZ?72|30<4&eM{n$e)#h$2xTFJ=0NzB} z;$~+dLORKN(~rElIAa79!KfhbIDhyIBMXvicQaeHx|??vV-S}f>&i1@k*Q#Pv37GM zJ_4UEG+{h7sNXU$z2R(rIl>^tYbZo!YdY8)0OxBkQ`>Yk+YAEMq;$r5;vcgV?Do6> zmPGbmA{eR!7N-jVxh^Kg6oT<*ADQK}^sn*6F8Z zF6Jap>gW{+TN|`p^UcmZoV^?J!(;c#9lW%z1Vtqx5S0PlBaLT0_{PtE0ge>{qB1lh zlrA~eD5OaU0;~9*QxB-KkY)!_A>6(CogbzH;!)`eXQ={@|gt z*KcWC^}Ej904^HueZ1tlDo;J;7DsPodEn;5SH^n_D4=)%V1pDV$>M2AQ2YyZ;kz+b12+f zU5+adnHZITeq@Dx=+!D|>&5-W(BG}e4U>UmQDa-u zI!3Bqw+zjxJU_K)Yi>-nZoA%(E`uA55q(CZI!~Kx_{`#1IIO5>e3j?<8tS8c#bc!B zTPQPfn1oMklnuHL<$YzSJ^7HAF}am=MW1`;Uo!>kB}Gz z%Q=#+9Pane@5Y_|WiwXF#3!=^K0g#CJ`gLpxgK!B6{Rh~!(HQrxuDgkF#0lQ}cTy5iauc20sTr`q)rLfC{$WHm|(S}oeH}6M#_kgr@ zO}Kk?_~7XmD(y3!_!pI?RTO2FLoIwbo}&2j4#p;|CjH(9eolV26u46fWOao_L;t)1|DMHQZzzv${h!ptHCojM$PTN7O! zrysR4?6}&mDlA-oaq>eB>N0L7B!z}-yZQ{{!DF*;7BxGFbAIbeLkOjCgV9Ft0=ZU{dRDn6E2mR8`9j13I*q^hgIEzMbS;xq3~3?JbkL;}@?*`z)E; zReg13;2H2J2b6Cab9GC8MK!@DPevVb&f+=AA=iOIC>QONp0@DXi zsU4|=r137H!l*W4puR)63+U%=VWe?;QfE~A31Muud1i&GR|xW#a8^4cR0c)!Ku zJ?%)&bM{g)?YcwTRT*_7Egm3CuDJMvrR45z0MhUG z#RL(XX-sh2RE~}T3d}#W8D~=ps0t?Se8i)M#RqO%XTir37oTm zTOhBmIhH>D^#-q+IaL2DU$myaUwd8u(P^B&xzE@W3!jGkyur}t_bme?{$zsord2F& zekwYVr?2nzeKd}!&NK`d2sRx5Q~bF_K-b*_?;rvfDTvR>kClz~`)Y3Ng)dRt<3t|H zt(<#2GY|Npk$KOJI=@zX%U+42JJ9){-{6W@I5ze{#*x!>n~$jI)&0Ay-(@8fOFraP zzJ0-l#X63z5$a`(m|R50$L~JVEjvBX|BC>_QEgGtd^pd_F}J)=yW`$@-Ax2C*LpK! zgasbUar93>oA!pQ;vL%+8ax5^TWwJ3I zb1tXE$mjgHCF7g8tZfNA1R_QcgdDiV&-(-IWH&eUQYTvM4)~jM&wWvWV{KwI6CLl# zI}Y^Mr<0|Wz8e{?v#`rITX>YmJi^};(dB=xTtnG(ha4}T_>5^HjXdLWs^Hk`Sq4pM z(aviH&&fV}uXlOak^O0u2Y8i(Y$6ElKti}*^^7?2D{qHv2sz48)k7NYcz#E=x5BIj zp9(j(U->crIYgo#yP+;Ir<^^v>2A_@KHoFT67d(S8!m0dyc8vhLCxyeu(_%kZ^OJT zGozr$^?o^RA3?@!8SVT0T-n~T{pyC{!lY??utFT?mk`<9vUIT|ofRIIDlNJBNH+Ca z{<7m8&c|J=kr&jCBGO2`4RfIAA<}QGexXBLs8n))+b(Aw81KW}GgD#61Y^4+EPEdu|TXkq1S^?J?1pv+tr3DD%>M?>vXp$K3`a7-!|5(7Zx8yawrRe@-e1FUC0_7y6oSRqb{P;@)`G`D8rj3O+p~*WbgT z40@wD_at*?=5sDMN;&Bz$RGj&!VMLLM^_Ypzjf}Ngr7MR5YHz#mT31A{Cu@DN}vTI zziL}2kL$&g<8n9xNh?{oE@AB+X9g`QqOKBOrG9;Yk4R?JMN66}cOue&rK6s=$nEF~ z=NAu!s?{Lo*`OD<<2#P!w@KMg$Qv&MZar8MsdQdK^BasF2HOeU^KHWyN>vMfz8S*L z4xbiN6zX6dze)X`=m`@AMh8Iz#UN5%4vwioQ5G!)HR4M7TkRr9t|YPJCpPY59C2B? zNa(2(FG$Mg18U4nHuOA>w}V%2snb-G-b5(yPB=n(Y*u3| zsBi+fz8`Jg7Pq^aOvc6GF|h`VdT{m8)hG{qWK2FuS|ZXj#PuL$^E>s>#_i=)hc_hc z>(vqBlP=nyX~j2Mqnh@_%aKO`;3v*L*CjgM-z9QAQi%K}DNJ};YvE%i5 zq?J6?%l>WOhV@P9iRV2fE`OnDa&U5ZlOdtkY(YyPu#*Jq;Xn71H=qp)M^~oR@ zd8CxTq@nRhHYbti3lw>w>#(>?NiV=AB_zMqt-aG8_96Z=%FkB7jk;O29M6xeR!l8e zv>t5kJLTT4WbJ0XQP_{^l9ptO zUJOW%GGBWncHG&d^w>G;n8e->=k@lsJgdG=f9^KDNOIPKHzbuY>?D~IM>G5YUb}9t zB9yS+{+@cU=xq%xy?iD$i`jY0@;eW3`iu!9{9f-UQ?A>tf{WU{L0}A$!Sd|KT`6bB zE;@3qHqkdYYzB3>M^s^MIWkEm407yvuLy}Z;M%cRWH%3~c`6NU=24S8X8dq%2liNhRCsRSke$)CVvZX3_s_+-aXSaqCG(ASRD!geUg-v`Wr zeQLO#0nuRx7?k(q^zQ*72wipWM?2hgpvlN=+5&!#{Ps9NSQ|r~6+O=BCyQRK)sGcY zib!nE=bPSu18;Q(Z%sYE(0r;NH(lyStyd5@M5Ee4HbQ&Pz;geQrd3Z&H*hT^aC{mG zFN4A-sSW2Ej^TsK?Aps~ezAkPY}}$$qb$NW3!_*YcA^8^t=>{HGSB>trNKTgZ0ld4 z17!0Xu1QY1^FPcQxWI2eCIdGq`KuAPPhGxww|t_7Tf~-YyNCuaaNI-2|MoU`i$iTY zhHmwSh=|;Yvy`X}JheoT^}cYxuibCv1?cpA=+pcqT6|!x6ji8(YUXI(K-?|W{)3~iBW+8D_s@qs97+#AQ2=FbG2Xhh7j{AT zRl;7<&d2`9HZ#ma?auC3-6$mwQF|&D4G7J4xadN zo&lfz)UG|AM#v?LAEHk-rR>UyCvN~vv9Ops+>THVOdT&|aA}SbWrcC*Ss09L*HEkx zaIn|t&popL1Lu^4rJn5pCi1M$FZ@L)p!6OvPuImZJOHhI$^Zo?OC!i!WNuC7-WIy0 zdd5|dZYHs<@Dzomq{qi@L)DvO<##hM)UH42T}~VzrP(#YNcorAlEMP3F0my^&?x46 zEtneZKX8#Y{~92bI}@3yr^pZTLl`t|mpwCEJFbE?WCK57*5 zXEwZt`6jt0r7>8&In>=sDe2$R7V=)9NH?f58E}*n`#qlTQt2AEKA8V-Bf*X=WIPJv zqdYEY7D~!^$&kL=tk-ltAAIfK&mXxG&FAixp2ndW{WiwZv0mMD?6NmstiJfhln&#vR&Y+7Kq`tye`j+wqoG(ew2ab$HC#D-aI6WKR6Gagp~h z1=3e;ZK`OPWB7pB?(d)Qwf>#qV1$K9-m&BA$jkZ~FMEc!o}}n+w4|*?ENzX$P^@6h z2X)n#HWK^YzD--6S|9#8m{EH!!sgm}lMn0qN>g!>z{E-)_oE*Xl3V*iXILOgyU$#D zBuMPRu4+(K%w=nlTHmKH#}CVu&#Fx}y{w+{Lxs$PZY#tme8sS7fgp_s*~$RXkkULb zZl}lW7emgkx@CMKT*d&z_2-S`<^_n!4b(_@VrttE#R$|bzeGu+-H$;x{CIdhUqmF* z1FiQ^nst+P-bfzR6{vFhzFkel!oJt&6e++RjO17)us} z{I)%7x2P)RGYZa=DAHu0ZgMu*@nRuTFY(X7w(uW|*ziT*d7!7>fUoRmFp&Y?s+Riv z1NFerQ9!B0+@no%FPwjt@AoB!tE~8H4a2?-CB<^cci*vV?;qx)(giHUrB%XS!<+P5 zgl@b~=-EouaYD07SkyZ7)&Z3wAA51AT%z<&Xr?eBUh~=N_ohm&&{j^yqM$HOWm-nJ z*^DkLEDLJ*Fl+ zlen1FzQn8V?=AdvdKsLy)pZ{Bd#GNBC07Y3Jftrv#^rN=84}wz5zU{Z6Yd1NkX}i^ zZVB+d6HbBmQeH(DUjddfsF95H+-m2Ac*s>jFSDfk9fIB+3QM9Lt5q4N0Wvy18(pBc zXN2Wa4faDizEnjg%v9S`UU_=0Sc?2bJdPGc=Bu^^$Aesbz2yJ-Z7(RXc8?y&lZ~%X z359Et*Hpl;9Ev!JXvU%z1LRCYwmOOKa;wiYlMSM&`&@Oa@UPeA7dEmMpZ^iT$ISiF z^YO$F?l8MBSpK5>jwxI_>W5a5dHMr_Y_dH?oPSUf6kI#zYyE#TCWq~^i}8w+rH*#+ z?r=kXWpEXt;|?jza<1)kKN!1>4_mpiLxm7OE9^EVxk=zVSnc&Tg7>!F% z%ghg8UgYBR3_lE!`GySFTB;YWI-;I-`RS2YdVAm6g$jdU3CNOT;NfUWbN2rjR5FK?~q-FyqGG=ZnQK;v@3zU``-= zZw}SPr{Mw923hNQ=Mb#-M)qTp^A|}&x&8Eq%e49+KM0Q2|MZkR3N1dJPLj@cq&OklC;6c5JUlv0aDQc z2@e`{>#E1%QO8yCT@P~GL6dv$T!1LTmnb0YTjO=IqfF{Bkas|PhTbVj^5en6o51j5pZUwBe~+(z7vDEZ zA%AI6Gcwf^Xn6WjeRWW{0{lIqbOFs`>NT~cvg?FqP6K@PhqiNe{*8R{Wrd0mgyTYy+Fftjdr#}c zMFpzLx*cyf7QwKwR&@>u_QzRqkRv`K`>@jaqfv7C82pf721N3g2$F7;I6EGch;5{4 zHsm5X#5h5)0LCEZdEU&P6dLtz@xDaWY=(O+$VZeofo#2w_qV;AmXr1|YnopOMc|AA<3L zmOlBj`2iP0Jdy`>Kld(Y$0%PG^pLp}5aAHtQQGMpeyKIlPWzk@u;Agxf|_1?r20>F zZH3%B^La)z#20#lfp1?jxefhF{U*!dFvaLClmWa%xLtR(e{Ik#(o(>`jhtH%ncSMC z=iIYOya43RB-Madb2wr;@~cu)UOazhs|7qVP461X*C|BA{N2T;){eshPe$N}&*)zf z`t}!4DSbV z3{Ta7Dt{AF%WYD6j0dUuXz~f^=L4T-&EgBhhgT`(4y4UTPR-Mq-M(Em29AbtX$h|6 zN!SsXD4$>@?H^&QCxI_Fh?tx>M9%c%vcEnB((|{r>Az0ME+)CTwT*4T)_q3jI8(dv z=h_$BP@FczvF_!%|O`1vf)qpEI5`BWn>%B#8%8+?3@{8HKs4UrZ{{&km^5`?0Zy zBOP83y@D3V#WXY*J_-xhE`D|~Vu=K2F!6Z=1UX?mzUw0Jvk&rFNJ4HcEB*rMKVum# zC$g^(hf5Au6S5l@`fEx3$${?}wp~Ppq4f}TsVnPMZm|eoU|}Ed3dtbOOhOqNwW!Ow8Z>1l&HbV38tnobwXL^IWs#cq=tng z4}njvGQEc#nAUS1@IOn9oAIDSJjD8j`5 z*`F%5g(9FQT+RaA_g5Wb0&e|~+*m0aV^T2!7)bS{HNZ{YX z+A}^<5bMdguR`EM=3PM`;pN9#bOq}*cxE;hkJD2A7H2bFNs@xJ4<34c zU|?l`>vuJedMN!3YwOG4ESIoQgU>}1PvB^V#;W)h+=UMw5_U5{a6q_S;T2ISr`K|Oc=rb1Cvec$RGVM z2Nk!XJhAG8#6xys4y+g3&VP|>ew#B3W!6dtiz+raIT>3jxC9SJ)s8!9@+{q|PiK^P zX84k3m>GXoxGm|Aar=|?c7&3fkzr%*l|OID;;rkiFjxkR?PcyWiY5~y&Iy3C|L$KL z>JSXiY}Y$7E*2hlnOPq7!{8nOaD4 z*7mxUvy{qg<8lIWVjJOSVCZGxp81S}-50UO{4#uSYrqfj4DTIrIl(x2@}t4$#@~*_ z-3pQO&Jf$L-_7obY`-e9s!?*5UBQ7j`>O3#JAcG)L1Wn(EQLU!C$NZ*FH+m zp((~y;giei;EtVX{>YA;X9T+?;{Oz(UOu;Gfj;W`l{TTTim)mh9-P=@Fffi^`B`}O zq-iHg=4pka`?+YFr1yOnbWViK3z4^Xw^OYz_-E+bj0z_<;n3zH4j6`@QiGsK9_!jo zA8VfRuv9zA&2Fy0%|d|(taCM`fQKj1L3;34+coDJ3Lg2b?Mz%3t{9Zu++3d!e24}7 z&ZOJVW#$XYnGUCy#!-_XGDg86KUa}kHTNZRS`#vvqfXuRdj>ee2P z>0$qCNuHu!iJz*cO5U902uT&)QveWYy-u3L8x5a4kC@5a_KW{9U}d>Ilq{+8QIy~U zD6ho!bobu@uZRXaFM#e^zoO{1+Xei(K%WU=$9jmW99i>@&6zZoB zg`WF*_OluSWBKs5l}GdOVCkpg$;O92Y0u!L`-i^-t6x}Q?Q(ypUEM|8~2-!tt_5F#H_%1;o!Mn=hsEk~Dlvd@`y-kU&0^;m#oude8{ zzG++wQU|Kh?&N5hdo?{#dogI*x3=SUdC~9pSa#$>d!GXOoK^MiiU*f6M6NN2FS`)% zzvw}OJ#^CJ$Nad8+NMouz!A$S zzy^@7l&Zuz04dj+y`%Ykg9^)ev_kQ4z=( zdlpf7n4;K?T8NV_I2b8obB20cYwnqFpOn%U2^lYoAOZyjFM0%+ar?9@hOByPO$AA= zS<1=si_~49uB1_Yo2fqFlA-zf<0op^*5H%Y^lT6q(Iq;vE)#6lnKdt`XmYrM^sk1h$6+vvnR;z@fnCrMQN>*N z(YSxmedV$yZuXjSJ@ft{BqE=8SR*RN?_Ds6Zo9E3N)cYZ#8%qcd4+{S=<{1cvmL0r zP9+*Nss^O7Ggk`y3p|q}E;hjhi3G=*DqeF3D48y_dSz{>zioL#a=r_v?^Mb>c1f6_ zn=7NOKT?+sN#U^G#y5c4jQ-^R3T+OX=B8CkX9@$0+!()V&d z?7Z`+2?pRanTr`a(uwBJA$Io*2?LICpoEgNxKRc%mJE!_cg;Sgso3ktTLCPSua5w2 z%S2sREB1dfB&XMJhgUWF*emEVOuiEE>3xbU(s$DR)X^2sm&@OyydcoKcNZf)00wo~ zVAX(uxI!FA9Tiz_h3jq8oL2Vn>&P*PnvA#XpOQdXT`W`uCyH1!I`nGww+fyu@_6j` zy1M1;XKad_*%eM>dbw74wn4K}5=J2Iy&#wTbKuM&i79TVi|S*u2PP7cbi(Efj3&42-8Ox&|_1&tR|oS|cRv!`s4eXeJ1Ho^7kk4&;4nj6xzUI0N_Q&v4kqXBmgh z?fMDc9X;VYiP<)`heKQlk{(#h8V%Z-(0INSXfXBw?;sq^U z?6t*Z8-cZ!AX$%0(nQ-XruvpftDUC#F9q=wv!eV);W)}}u!uIeos%atF@g3&J_LU0 zLyOyq&^=rZVFquPd4;c>K7TsdlTmkxZ07J#psV)A;uj&&9svwqq=uNE zm`sbar|u^FyQbrWh*BCw*y83wlohpa8*_;ywKP4TWsk*+7m>t0g}YotS_$UjBia#m znKPw|XN~fr4-X0Wf9C>NTRFG^Ctfb}0^6^PFg3@e+G;H)({!ZVY|M$xODwo)9=egtgJdXS0e!%>mV7^U~Dp&-Q>A-_%4nA~> z$?uC+mMoCmrnsCAmeH$9at>~M+JNWb2I3aUL^h0-HpGU0y8kCIa&tH7ag0JBkak$w z0tN$34cRZg%N*Jm-J7_;``ncvg8U@2e(t#k^(>Zd!yugu))8X;E>H%2DY-+|FAsc& zK8a1KRZ$r$``L`@acN8E8829L2cDHMJXGT80?6Y=U+8ZgAcZoctiw8^Wt6lb9-9;Q zYXJ_K_C(&=^*CJ8HU0PY+xwsg%;-IX5>V9;kQd~52aoBglX79}PQk&`FW|1V+Lq_B zI7(~*@-f*EPv|Q$9hN>c^VN9HQUmct>}>$rP||(vyb9&#S6X(5%d_-MX?$92^bAXr zLlYWlwA*;w_hDmunDl+7o-1wDqG_sM0iLzij&O&9ZJ4aBS@=P0lu*z`53)w9z)3j7bkJSuQ<(LxorfCZ$ zfJiycZ1q4|tzHgfO@{ZCkmG1}C8nMBiT?#Ui)B?W9QwZ!`}qZ_3KP>na8s44Jz+Y0 zpG)V$l!$BEt>zU7b81I zoYFxE`!`IL*E5-~=!uyvN?Pfg;{R|4J{3vQyF1M2+#GeGRT$&2VZ;)DkxvNkmV6R+d+Yk_ zgd7r0DaN)_Hv^{qT=+28%+UA*iT*TC*BD42D`eba1+BA7K#?gq!c}RzS+I$_nu|O9 z96v=vsgz9^+vU_EA#BB(SfZ}<%Op9)=ykw`IdcwRA>(ot3j~9(zJ8G(_i*}=i{d#w8Wcst6vcF_Z&CV1ZHMwSC1fU6_s3;)qPygs<2J?&N1Er zz~vqztV3iYkXuxNbi%0az|$)LKGc}N>V4h3gII2X{)SyQ;_Y`?XPZQvCj=}K zKfA~Z+?{*qS@iI4ws1pBdF{<}JlcDVZN7qJl8iR<4$h*>dSE339B5N2jFLM=HZaY3 z=+wdPff9u&LY>G@CaH`f#)ldV_xj(f`-yrCX`iaQlDBc}yY4^EC>u=O5i+D(UPn0X zAks^5e#a|ma|?&hh1+ue6ofqr0(1uMDYa-T*MWq_jO)IlI!x$JI`nirVLDLqzgYyC z5I{XU8g_$FbQvYSy~~2{HP2l?v`69aMshBlt9EkSj@zF@DE^n2nPRj0xue;pWhe(B z`>d~1x#=Luy5*!Pl72iXy-+)?RdMxpW>($p4N-SfZ)Oypqiltks&C8@UfjY3jeQSm zC#Vv06mV6k%-5>=sB0m`K41c!k__b>V!cEP@>YJ6FZ{w*bk0ye#}2jgdH$z+wp43{ z6pVRx**W9Sot&=wrQTnZ0nZ1$CBwC_y)R9sui?5jEtH-5`TTp+D0vu}to@l3%9u=3 z6r4@VzhWm}|0kZ&LSsd?6LMGqEPe}V1!jv;Qs7szAhKAc&e_!MZ=vI~_UH7LX#*hh zXHl8+HE+2!Op&K$^XqHvlq5i~!J;qJaadjjS+BkqwIp^uH;OyUwJynve@H{^b8bT} zvl<|op3bY3=V_=8O@=#L#BZT4oQJB9l;0m zqnD`FPyJ$+BD3r?MGYHw29;dd_u#ZC!K(VooZOASD)Ck#>p-?Hdx&tP2@Z+|zK6h6nO@C zvLT2wWfYtOUzz+$v5B3is>5G^`iCXL%8watfKD&v>>WI0%g0kBCB0}rie)LddJ7kC zxwC+7(WoC*t>o`czIZq~4;Ok=()V>$j zE@Zw18qy6}yiOxihskHFyXQahksZJ+BEc0i?t zNkR%p```DIQRM_+mT+rBGy?1SJ7th$5sj_9BD28Y`LO<~{OYkJJ?2cJ`JpRcNHy~u zF;(ytCyNJ#JGu*h7f6?VZ(Fpju{VxAz2RbQLg-m5jm>%#OBfFj(O+EHCV4ATEzDeP z#=D~{oz16eUDZ?iknDk%jbe>_pR#sa@?o>;@2%@Pfv@TK@+!V9hwEbi)7~hlfi)wM zQ`^M40B)R2xr)(SoveWW%2qt?(V}`V*w=vSyD91e&E2IeHvR6V3%>WWdOK78pzoG^ z#AkfL-Q?|Pq9HuIjaIroNj*_ycPO-ER_Gd877{^L_n@j=j7x3`W-+F=a53GN1}hRH zR*fvWLm5-Lf&rqCiP#bgBp!N0U&-f>nzFFRDz-bbqkGS5*FgCdex3KN^|-J*N&5Hn z9~YNzE<>Fsf+K)wEqo^60CM1IQ3Kq%hNFDw+wG9B@A3tN@INlbWr4}jWQC zo<~-|;#4?YYqiB!HM9{1r<=zjhyqGJt>31g-U2{Gnj)kva7KW78tnJcZAfsl6dPm;ykTW3b zZ&~0qR;zJfpVs0zOT+wrWIWcqxyy3MrEe@G{x^Rc=L8#NIo3l8xA^y3RtqVz+wV+U zJ=VPd#sZ+shrL7_xvl0|{yGM~qNazN|wWC8>B5ZgQ=|KDTqEt=!*$ilzj(OyX=y5r_j8>qjZXtUsTX=M#gvgJMEqv9m^eTAR$>wZCe*dtpA>kM|ZRD;U zEZ)Tuca+m4LC2pvOnYl#bIC&5?2TOjZ+K5(~)^zF||k zMR`^#l~9D`O;H2o)(*NGC8-a&fUy)jW1(H%-pL@erJeds5K(+MrFZ{_l#*RWrxBBw zb~O3(MSvStaKZ8#Uhzum)BJY57*UkjmJ_48tn}f3+3xX;^(0|Un-Y*NW2HWUoYVZ2OTec6xHy^yBEV9Ozv=aG~I}2sQ zebz8AywL(K)sD0JmmG-{%7#fg{a4VBzmFAMwA3O0C4RrV?40oZMJX!goi8$4OfFN= zC^&_SZqlS6JFjJ~wY0U0d3Z?zjx12D%7`M7GC53}0OwmJ$y*Eof?INx*>!}_@ru41i$Gu}EvF-HQY$#nrtsT#Ppj-4Skt-?_6)#ieyAv`0(&{YCMPZO6r-(1ccP(oW0 zN_xQS+O;aX2K)Q)5Q~LV5o5m3mHYF!t~d9xbqJ6blKYnzvRZF>;$CcnO=|%I(|~X{ z*g`r_a?gcT(l9@H|E_e1HoP!)GrUKRXbE@S)>W#H)KS#BTys=Fq@bVrh(EPYrCe26 zu+nv6$K3?U3RJ}JtXd2cC?6<^mCxG&*U47IAey|u;LmA)RjSP^uGGAd+HT!ePLu3y zI~TR`=d53=O;K%9*U#h06X*NqMY%Tw)jAx{QtwZZsfwmI!CN*vR5jDJi%KuaQWFF} zd6AHfo$qZtZRjl4aLBlmAQId17;<&qU(F^#0V} zDFGhGD?h-&wHr}Vn9F}>D-^|>YJJYxfBCi#4p*AWscsM~TI4xh!?Zuw@$j;YR|P6o z#uvffJRS;}NwDk4XO?G`&`lm_pB>FF=}^vQegD7WReZBAJ!&!SBS-(Nl0Rfl;fUxC zE^hwk@MFdYtM-JIgCsWp)(dg)MdP)js~_@PDFuD^JIq{zqe0B65y>4Kxbv;3z2fZ} z?w|uIb;lJ6$~<%8pxJw6S4YbM|9u zOk02rTReFkbmtAt?CRNOtJKFzs-bRjpv+H5@*#7Z?W9#AwnaVAqMU%D=FNGW40MJ! z%Gc^xHkak~s**o&78rFcCreGDcaN^;SQ{M4f9?^*l4)@EKAbX#YrZuvqr0-b62jch zf=-M=UGbsxXE8|7D)wk<){2h@*Saz1*D)e_#+ozBwVsoi!cJ{fJGQ>)cZMA6`NUfE z+uY71v6!21iU(fE-GF)RF+})1HLXiu2Qkim1v(l8AQt$7?K~>1CxeM%*@I&Pm>#cO z#$S1_#PsFXQXE6h!HRZz5`orzf%JC4lYTX>XM)|+O(PuFGd_ki-so!wmg7&2T+|fH zkVvfa9h4d_mR+u2=6K5FNXdU#4SHfJeXzW2xcY}x^;8=;7BTT@sz&6t2vS#OteUL| z>6LjpyCun(+C;~#ecHpUClQQzeKtC*1IMq!fZMB!aO2hy9|pTVJp*Hlo#w5x(q2bu z(hkcWfap_2EY-Qz5)yuBhuU4+{+QK4zj{0kcZn~{9d6@k zn&QHGwObO|7Js9I_Z?Sck=DwIS!4}usCUyv^zS0Bs<^%&-WlD@=;~JWd6`ccLI&zH ziA&5yY4Pm?LdF~+?d{>&6^C7{Q%cV2LgitqZJuziDKnRxzQEu+Xt%Y%5CL>^*pI1* zhosFo$rzgGXFEhSJ~q$GB!@4dGr$Q;5!eo{bb0%kdJ|BJ@lORMfj;T^3LNqwmS&b> zSX;xKTz%J6$NR!>;__4o+$wk_(IHhO&o`gSZGYmg4OlKpHOj(>2USFL6zm-`Fv*%K z*6cQ(S=Sl1iZ$*}K(ap|pV+9%JvN)>zQ1aBq|L77jG-emSR}1tCFJJ`g=mj_=_=}Z zBnY)e{;0}>4FpYYE0T25%Ejw1aEg9AK(8+MNV_K^>=5T7v_7xAie9`w6+6I{0zr?J zf302MPD=k{+dkzUZwL7}tgY4_wa@7CVr_$p3mFi5g&9>=UW6D64gPC=4gRgkkcIjlR$(_T_- zV&Ix66wZ}I*Ci*~hES49^GG$t*086|6Q0Np(u(grLnT@#{7>f6Z{4ybU$b6B7XL5k zQ8@5v7;xtl;hazA+QpKDZ|!BDB-C~(1~u1HW}7a%)F+mmb3S~*7GWUY*YYn^qmx)R!>cy-TG;0n!9FGJ@p_f1bK4mM@~~w79gg~NE4NRehn;ZfWhm9 zlrEUs22wDnELsfHuGNky=iQ(^H<}u?K+3rMo59eP!&lo)Zf3zp^ibK~Z{O&>LptNA--U5xTZxBAv3DvGA^wAR&+x|~VdA3w|NxGh`c%iQs z!?U8zre&4)0Y!_>Xz14C9PtwPT6!_9=k#)1-;LCSo+1p=r%yByGFvY;e6$2L4;kjR z@+%KHoHW4A?#{&WZkU0geq_(GfI(FyU6rVkNzr{pHY3HZ(pIq}jY=$z#`Q@Znn^s# zO6JG7pH?v=uYX>(3G3gNGHKc8nfUbk)a}xV+s9_XUqo0CY?~dkJdK$tjJPtYWJ(0{ z9r4R=9rX7$mGI*e(53N8td38EmqqfZDbdY$d1d~ zK~>E{N#5KO$s2?BExOd9S7iIA`Vs_+7P|TABV8C@s*CDZNQ|Pys=PVg^hWS8#hIe` zyFjQM+J4gL?ZVVb;oglD?V0;wt)O7$stgod7O9sKpC2x6NU+DAY z!<2gGh|zgDq4q9jT~-=bV=Wc_xRmgK1ABrcl(a;QPSrFu;i@BLa z)10oOB|ETL@_#)8DIp37cWp}rZ9&3#43wIDinr}Z+)*4X%t2n%qotnm-+cUVqW(G6S z(kkBOBRAvF=SmV%o*qe9Pk7u(s+*2Y%v$yq5d<&BB^oo`>+Vj3Uix6;LJtKpKYUfp z)=PHXzDs}SMM#k8zr~_;9p4tXcf42q^_p%QEWQ(nl@JCnvH}jaA@5_w^@`3F_x?`k zz}nAbEvWw-F(#;h%zIPU*f3lfIkMTT$Px_tR z;u^U`#z0gDEK64Czg(8fnP5CjYgjR0WlMB# z^xd3`9yx?HG^+BgD=VYuyt@Z!9>{vI&&VLy>2awNmTP;5KD`fN>jWP1_y z?cPb&I5C71xR*O+Br^?PfNB2YUL?4c_+2A5i(_0HU}jReJuu= zQ^hom?p!@(5qRpd6gqg7@FCBSh|v~(`>TF&)*x6R+lfnHjw?^1MG)P>UT26dEApMP zb}VdFp7r@=1!cC@{?*xh4^<;wQ;7Kl-R}uzOPn%iLd4>ownL5zUZonv;OD&1X-2i7W z6mjtV#0PY@(_iFE`2m&42HMG_ZKFv6d29H-yZ1q+vX9E=C?(BMlpKCOwzaR6j4ydy zbUY;}@|%!#E1`jM*6HL1;o3)({@-|XO{dMCL+)2pH@W0u@`k*?!o9SZ<>42qiY2*@= z&5SMSyDkg)%`t`EcS+7h03@ORdfL+fw%xU9hUN}6}&NRiLPX8 z`Vpq`sg9!->T40KsDDhGb>6$!(XsKbD)7DOwkO6&HxbPJGlwXQ%B?}g&G;j+SzwRh zElc7?W||3mYwX4A>`x*fobdV!1VtPLajZMM5_+$$;51fK#mrz~KwfIbp*=0vG6rm0W0zk%Zu z=-(Kr(r*3)`{+PvG0#&AiTSI`QRjBVrxq08j})|Mf{iPY-o>j~(qG{Acj-s1QthXz z^G#yR=kkBte1ki-8n0&;NhqNzD@agFWy5+H{O6&J@F3dZCqU zljo@hoi^#z!F7tixc~|x9wfP4&lOK_$N&yh zAKy~VnB{c#b`;`i8AYPAaI87q>?vx=h$iBIk`eo z=HHmv>!k2D&Ms8E^uFR~`-F%@lYk4i-2Y&GJ^%!ZwMm2nUR`zt|7dQGTUc&Ek7}|= zTT&B8SEmm6W!ow^ZG{J~iJx26?W2E9zT04-N&OD|(;vh1b5sWdaOx??fmwcJ*|hU9 zn^0knFAGZE`^?!+Gd9G;clwESz+@q|tGXZh+WsF4Ff145(0(9O`dOcZz9n1K9Ci7B zzR3i`_JF)n39f-NGUwsDCGZEO)L+4n$$LcaynF}P>BXiCmkVZ^P{Olm5HxEQD+zm9 z)Ai^|T1hm@z8w(?d0I>$CKwc2W;k;A=`hLf9Q2Mns!3pH;hA?g$cM8|c9vK>%;w@NT?U(;C$8SIcpMSPtEj9PY{h{ajD{G1-*ycJAZ zzohgCA|LphndD%+G_oWJc%c9R$)7v(0uexzjgQ!Q$ThvONh$BeP}$9|^VbG4K^ebI z|FWTm!3W6F=Jf|n@DTSK@{sgtyV@k)E7u0YeT=A0doZodbFaDymc?9ejXIi7X*>=S!iGdm8T!(-tCz0kphzminl)Q@Wmu3S^+m!@KJ8UU)5R3enDISs1w zQ0m3+Hr9k+6xw>1#*}k4DdPoXU0F8nZ-E~cv4*`|?i7H)K~O_>i4tG>6Q z^9&suHC{C=f)45WD!_Kf?+Vq|r*B=h?9*Qy-q1-)r|Fl4sLI33EKGk`NN(;8B#EcC z@!3G;8E!E6S6ulh+VX74+x6zTPe<$eaPqGPi-bptL;{4e8*(OI={FAS#4y$c*HJ-Xgo-0L_A#NX?c0u!>FT1)z6(KHr|tn^uNga9bl53m z73B%2MncS~7IH4H`)ikuJlF>V$RgK~`~-)MuaCCUC?C0lOGJDUTbO^MyFRUBH5q}Q zxt`(7vp6VGKqNWRd7!wl)zRwup&2KQ)9=1-o#B1mBl~>aJD+{xW2Gl^?jVhGpyk%0 zU~N{>EHzblQUU~-*7Qn-UVS&x9G8|Jv|s83djFW?sS0#T%}XVBQTbQ)O!WB@J|7Gv zjALUHgUr7yl*FoM0_SmZimMIss?GRu@Wjg`x*`p}-~4-uFUpl7Su^{QS0J--=`*)y zaplkwNt6&#+oPOc`HmQ8LdFSk3h2xJ!E`dh_d9-m}B+{1T!-1{ureo~X z^QwRBE;cv^j{AmNf49-gAsEnJrQJ7f3RzfznJbI;?q`}DEZe0+-fVY4eoSs2e=5>EaIM7i1?XAX}3)&iozBF1=>1+QQqjMufy}6$opWstPVMq#_(biWkit^*gA*H( zchOcd&;=&60O57$n5uyZPj&EAGREN{bvVwsS_m3X$m2_RsfIB#Jgyi{YM9Oa9xy)n z?6<_-1_1U|IFz*#06UHK?ELP=m!AQa=M{Oj0`#uF;>3{Up_36-ab+orhBY7{);v*} z$~YhXgN<4|Y)(9#r*dH=!hhN|8#Zwcx@75QPYcGfq|iNA%KWU})Tbg0-ry*b3F<=X zjE7z}^DmVM|Ll?%DZ=B;o&0AfPE{=HUnmw@*%xfw3NLb&h*0%H^A8nobZ(WlR4qG1`44&jVW52B$SGDabzw_|0 zVrgc}{{PU{B`?OtpUxTv0*%&ERdRYkOW!3THvB)h!PNGw#y%PGU!O&)d6~ZA~^x!QbRZNvANmXECzGGC3+-` zpdKC>!%1A0F*sR_^pG;YVfu5w$&Vb=BkgnRl4Sn>&nG#p+_iCF?eat?ayWLJWVRVg z@eS<(yay_YV@FJ7P?@{YkO_>zQGp~Yb<6P@XJx1k-QI&JxE9rpd5S_m=+CNE=F$}s zz#rqyCa3Rp|5pFpEoo%_S=tM(A`ww4zFR94Q->r;%r)!SW7`pRIqqNNZ)dh#yg$*` zH0xwxkzRUd*r~cy!{cNk--$nmau9Xnh0FxCnjnG;i@E>ew z<(C5@A;`WWBS6dwn(^uyKh-CEkAK&bB`kzX3dtVq;C~0F`%Ehm)HN(s zY{$o=vH#WJkNoKKNFu&A$tX8p{Cl4J7ey?p=t9W-}2HFRFg5Bvpc8I(#rb3I|U`q(tU)jl!V z{+~n<1M+J+=#$^#G`_hHfgi6u(zt7VX(FJ1-F15z2US6Pz@F7?xz19c$WI#uo+Afw z-3%7S@xq(KfSLT5V-C1J=79>Oq3mv7H>xm?=y;=T=bvV~Do<%KBxBTu*DVj1!ZivPs`Z;fceWn7AIbPo){-X*ro4XH?KGNBXkbF6F=Ru*mOwa8xE{DA@$h zBio6s|CF_IqNKsJ;nmMI?}zQHYVY7YH~af{4xf-~hp<_pJt*xS;cH@Yt}_+D#amIK z=z|_qV?^-bFw(FLotkIOGQx-QDc1qPahn7yJ*6jgJx5+*(6s!w;IsL^mG|R{S9jyg znH@og@wQX+u+YL}?KP|j$ZcbH_sN8j#0U$zk_>ny%f##%e0MXj%Nu(R^&YFqE1(1i z3H~*$0UfX&`qbud1N*1pnC)#C`7|#&=CWl2c4EL9jj~JWY{{e+ zME9SExqoUqrh-DJ0lRz%-U^=EgQ?PE98?wY=cNw6?;R9smif&6U{{GwX9ZN-GHf@> z>4}@o<7h8ry-Fq5({$R2!yrk7+R(y>>9Wa?o8i$PQ>^!`3iFUXZFVq)F^*SXr!bq+ z3LY$Mh-2}~^FD|1s%OgW4fn{2_+o94V@LE*vBk2x>1Jxt`$RsGgb+6PDbTO$)V4txM23hX5>HU2JQIhgT_qA5OUR z#ctqcAiR0+X0*y)180tI7ZY=I40BtD>n;4p*lf5Z-t=3IUAe~gCudxMSlHfbdPaB_ z&LB{EIxV5SZO8JOsInS}A|JNU>85_=^R>J47Ct-AMzTFu-y9*Y-!7#?k2Nnef7@vt zz#MoPK1=$)cdLB1*}Vb7pc1r?n+u( z*iXBPqu4HRbE~heryTd2IP?|bWEj7>f!)U5bup=4zT}M38`g-;K4HJUD%0@-7YCyM z%1)r~Hc`59A#4&QIZeOcV(0*ROV>XnCsfa_1-V;KnYy-}< zZBbg?h_%EUDF}`7#e}BDfq|Dw7COHH#(DN~LofG{%=?6Id&$!sCMiNAo!8!ec)EAH z)Smr(bN=!}z>_hb*5NW~ulgA8t<`uCX_0c6gLog14eDL_k3}^rr(9fc*6%5ilpIY* ztOVrm%fCr~uz!Oukzcwj^AiM`+{DL11&U8ljL;95$>MMJGB(K1r4EKKMS3Oc@?=i< zawnRP=KaES1(708U1-U%KyHA6k)p!9HX;xS6`l~qV(|@?nIK~fK3pk;pZyUILaMb9 zU#RAD+3m+lGB{>fv$B@6%+?+0eA%^N!txOjr_>9>l29Z8IQTJ) z6ra_!l&Pcj3f}HMl(+m*o)vQzl%kpTKhvbu6A29pzj>E()#3N;h_j0)4O*r@@Xha} zN6t~boXp)XL55R$Hi1M0Y~Epq*dg!tAb-6Y?TwtuUw1hw!KH>>AR4NpTuvI~y)6l& zT;AtR>Ut_II9mx5_bd0*K6srW{&n-bCq)HaD=y6F5DX(#w8v(LNtD)iEwNdc z_>}nnFOvkBCZR39RHR11z~TE8d1%n%&1@!TrQ4{CCwb_JNPtN3sqTvRjpkuP(5bi7 zBNtO=Vh?P`zutEf5E=b<)&5o*r>neS?xftonj$$1(e|npXHGB-bPpRYv@k{aEs zM1tz1-}tYcuP7tjZ7`sp@Xuez6x^?NltS3q2(KoJ3FcfFxz+hSNC!X`u@qo&TJN$i z-WZ(sT@s|)AjGUzR;n)h_nGVZHN4Sd2VI+wb(fsO$Cz4=@Hg%=k~enzZ2mJw;Fm|R zZCJO(gp@`t5Ak&&;k~x8De!GMR4(#8x+V*&Fusz+Olu?lSHuI(q>9Vdsr4g*cL(bj ze<^aI4La8H0S(SCmPG8K!8K|4by8n0A+~4mrfK=suxH9_VVvFda3MKv8l@ri!}qu2 zaf$1(gB$p1WqQKVYZaz}OP8FfFRxPNZKoBb`opVC~7_013 z=u%&lM0E0Nq^o);3ta2Z6ld0W+BTczO$|}_&|5@*PP@PZW2LIPnAS2<_1sUr(s_0$ zu_O=oh(2K=rj7dM5vq@c$hzEqkA7xhXS@03lnN3c5VLVOkBp$8;8(w4w9QlmkVAVh z$bU{$xjElabA$kF^kUM7>+Z>U-8P}PxbXevlRsTm%Dc09jg?$M*aHgC{tLfd@AiJD z$@*R3qvJ6VqS~`pyllo4<@TB;l#_96aT!|qT|s5?%iSA z)$}JOsG$`=wdx0m#at@p`Nt+ZV|W#N%=h#W37?saHF)L(o79Xfq-13sIZorIpM}1D zFSId&?eB5>Sk|{6E4p|COR%o95G=m1|Cs7zSkfFYt)VShyYS29D_uI)Z>z>yt2IeI zesMC>IwwKXkdXRM`glp>&f+)!fGHpF^^q+v&@W74^{*oJ^14B{m2uUn9@S_jAT6n+ zF%q}}3Xla@(q)y1j6aT(n3RHvf_tIT@;WE6Sc@*o?TWd|{6x>gBDWx`KN{e>N%?e@ zjJJ{UvV>oSo!DXfRsFUpwp9}G$b;MM{TR}bC#?Zr^DiUcSR%=N-*3e+1nb@4LrbAJ zN#eoeoG!mj3L-;*&ITv8w)~W0-oD*A8QPewE=rQ`b-6TKu&(9&mjQqE)LcIUY`b9K zWd%w~N9|RtmYiFqMgS6`8(1@F#Yd@YGhF^lzpv#NJ;*aSG{WBpOBI@EB`b>t(VEMC z{u?`!LJQ47^b8`jm&Vryx_v#X!<)0nW>b3iCn985` z57WB?<0gR6SnQPp=JrpyPt_Lp+OrfYaf50nyY|Py$Ap80?N2%cKIljDYe+C?&G!dFo0~?zuf=ZFRj88{(r^$7HRwI#9sx>Oy~3Au zyjv#N9AqQ=`|e8C^i%klz<*nbe_amsS4ubSoYgK@)mN_i07?gf7JX+*8#J@uEdqJ9eb+t}g!|1`c&Qrt=C~}QH z>>-gUX+FR+oM?5Z{SiGWI7${G7d`BuCE}%=73*v`YNy%T>-9hXC@0o&T&Vz zUc?`?Fcx@pX9N1Y6#b@AQUfX-q=Z|PZEyG6As5#!1p8!kt?J!=LQ?niLIBD zhAL*`fD4;Ko6mRqA(#_;B4Uwq0L@KN^{f6-Y~ zy@$R=*Q%CyM`z9=A~mM#sc{P_3WLh`fL2nvdIPf@3M}`yu={yquZNaARhp-OUo=;W z7cKslnSNSA;Q(*rzT}@crihZr+N_yNHInFg8+IeU^JGVbFYy*mPovJ3gYKpVR6fsx zXia84Z;X*IHrb)w=5xB%zCpw5+&m)l^h2p}OPpa_5zFs^$DSn?Rkji#%OHIINnyzP zicHfJZ%J>3;10;XxC-w20wTvHW)R4Qk?G4koimz$Y!WBS4$`i^^7Y>o_l_9>xU;ZuHSyoPG^*QddToOb?S_MRtY3p3(<9_Ap+&Mz5-cX&!(SabGk5}<)`7_arI!Ty1d8${2iswtXnNq- z@7CXsfAT;4RjZ64{;M^6(QMDov11)~PVuNDdiqdU7+A*m!lafCo@*7xy`YY(rX83& z^B5%VaadN|7995mxe&imXmi1ZT#09&vBZnHQu2CStWla9zBOEKXStpN+i{C^W3c1x zMA%%G(1<4g{Ath)=!B<`sRUGrNn1L^PznmWOjJys(tuLAG$-RTxI!k({ehpLFpgn+ z2uLZuEJ?35V)Uyr5$G!N_lS4XzFxz*!E8I(CW=l~b^}u6CT@`%1(qHT)5_9eSrQ&b zDeW;DepB9Xc0F9gL8D>?Sop#P2%oGMjWb#k9}sZGk$Z)=z_DkT5@*qF@bstN)U(Um zk`VjltVtziI(ME(137Ct;;RK(oXzrTZ~L8ADo*VKCoU>$i_rnE@7G(0BKpl)e3C6u z9WFe|59^A!_W5`Ez}ooy4PY$% z_B$3hp?LoCcF89M-dS&n<+(RC=Xi!`d&hL!N7p0^dYh6gSo_7hKVYF#HP<`d{!>z9iMRB#!U;#Cg=L$m}Qa{vUuPToy1zP!_b?12JkFAI{RUstm3@)mND%s^jSyGK4U`4jxxgajvO467SW1N-#y(UMF87yf#k4n>h|< z4QF+JR}(Bm0pds4Urnm-38nWOJ9rc`NkQ|6G_z|#nKrxfjs>ttVbLo@BQD!$<3Bs!;}9@#f^v;i?8!(c)fTE+MHlrBG{-WFuzu8q9S@< znU5d6fHQq!c9h)Tt5xb=E%B5*6Vop$hi|P+)>Kg4zAh?RfkAx0^^v(t-Vim& zTd0iMU)Am^g^ysiLq&uqB4$!oOV^t$YzXfCQgnV-homUhOeosKlnsd-AFNeIOTWV& z{;8WF7lKX}Z7xq&admMrn)MB+P>Gcme!dbAooSCXQwpVAiM)R<;9CIM(s{BneQ06z z6Sl4A2+bJKHdAL)nh0bc+|R%~U;d9jZ@ZWELO<+&m?e1A_&51?f4t=swy*8md}hO# zt)z4nA(u0r7Vxw+PvPEF&gyQ=fysLaDO7GJKO%~s(4Uppywk{S^u4&(k8{5yMH7za zyyr|w;Xi<5e9`_dF0Q|@9=|4i8n(}1%?W+Bb4U%@HQ1G&g{%kP zYQOgvl3%>Ij$)5q@W!eJ$c+3Zdcksv@cmlzm$s35Ken$rgr2bOE#&(Ne{#*b# zz-U6%swXUIckjLZwN^e}y&>M*dX93ok$-9SSgYxCg6LQ?aW^@bDhs)wXl)<&*0I+$ zp;sh1m7P2_HU8*4)3ve-sw^Uix;Z^Yjo(k3r5vMuHEucg=Xd~_y-W(=+85#=&!Hp* zzn`B$YGL~@2i}x+7^nyw55gvFai@1{idVZn7>Nnkw&U`E9dUBtR3`;P6RzV1 zW-WU?JJ#oL4gx;hBmF*6-M7@s`xJ>N?(^>gKMHOCWl_KqUZ63hnp4(nFEBPzT2-+V*zmO?6&1|^491B_e6w_)wNVn^1hcQ*prjtko48R!ImdF1vom1L512a z3P5@Lk0sS0{HW17FhOyV!?iP0>l7DF904`k`3)Bm_XfttIY@45-LP4n{#d(?(F?nc zeEFNPsVMEh(hi82@S~$Pfkk~c)7pM*{Bqw)Aai=WiH`H5IvR59;|IbBG<(}}LZvhE zA~6?o`7&`*Zxz_lWq?rwhFRb`)KMc*W&f|SSI`bnrl2s52|ckJaKj~%YrRFFqOCL< zw+~_WDn{u^Qju}DBI_{gkIO?9=_UzfPY##({=Rhd@RGW6K~8E!^lk_+=MR;&X62(#6DWO;F!7DHJ;K_mZ`U=<%C89#6E% z+*TT(FE~#HymFf=``~C_4g{wQ`(&)|z|hC4L}0o~L7&qAUv$o#VYwH^er_wyb1D(` zoZrpxz!OSm&Y<8W%##*}t7XNmJqjKhgXo^mW(;Ysl;3L>rTq<-Bm`1sRV2}|y$w&? zio4*P1g^%l>?(vCHszYI?HH2cY<%C;ys}8=?bj8feR@Ns{K)!csN4*0{O4gbH2Gz> z^p7hlTdh{>-=}K@ON%W2Y+c!O`Zn0}^19iWdzYWfDe61$sfVCJJG+s*$#(>K=v5_u zpowXxZHcVv9#`HJbq3qIagt~EUy97j`(&KE^)=uv4_xjbVCqV3$a|Uh{}J^b{#5^e z{P#JBV`k6HgUTLF`y8uip(q+SlG3oU=NUGIQc>a%g@_{=S?AbFBH8O$Wjn@Mjx(b?Kb}Dd|GzE);fUoYDvBF;a8>f&9CfW z{IfA-gJZ@Srurq4A5XT%o`O|Bf#0Iayc48I24C^V-WqOu(!y{evX@gA77!;UG`MzJ zJ~IUmIX`YQDP&!93cmDkVEJ9Wy?zH|BK*|_#*gKiXC!Az@a2}*Va*QqtPVkkomPQ! zwhOdO6y^*6Twf(>q)O6woFlRYdRoLLmd zZGQL3SHO_zRLpk#g$Uxld9U|8rH5O=W9Q;afxx*kJq^O z#KIjPt(lnAthpa|EKb)d?vtHu8voA0K1$F>&vV3S;&MO89M;8zC`SYU$18pDr@FcD z=oAP0e0ojt4hz`fdhubgR=+LvtUC1a{?DckdfBzXe~{1zf|*zqn{v)xx2GkkHSdXe za>igN>I$x@8AZRNxrf{TAmBRG#r1vtmK*yIlB0!JR7eH!!L;B&g=9yt*v-5Y3L2RP z*#ZMQXr*0+e2$z(if5}FUjpkj&%5e{LPtsWq(`ELg(FQj$QPg@`zdxle7q|yd|0bU zvA~l0ErgWB%456R{6fFD^!YoQJleI4h`^qIoBl^njPJ#D$MB*N0qswbaq{AFb&A*_ z&LYpEQ|riGmF6*R3gJzm;aA4p4siX7**5ABc`WZ(In@TKPDBA&!tf6`^1}_@c_%Y;bL*p-VzRTzx_n6ONZ+3ve$nHiej~%sV zQ5}g$qG&_hV?B;tX!!z&d5jp4F`F~`Tg@*#Y&ijcAJ>6^ox{YoTZ=^zW0j6W8leRN z?=ntFd{N||^b8w}6Z+V$Fk@og#huBli0_F0cZnW$!#_8xRyiUn+}Py*XFYb^=yH#C zE)0)psM)~fegBc)MvM9$vCr8L=3z>Xzp#F8$K*N7HMV1Ur`>A|0V{>vNHB(AJekhM z?C4@uCB>H^GUD^!iuN0uWM>5+=lE;QIJD*A)tWV!Uvla}?a9KPKib{G^CdH+Z>J<1 z&K#*Q6b+#5!O#x{CHps$C+f-vVeStMXrGd!&HQuTUg6i)jXovh z)NBz4Z`3UAg%e&Lgwq@y8>YirprZkU;&+dsM1g(eK307QG&UJi4;Iw}i=8txdZ2js zoMEpEoAqrT-U7IqOTTYsfK^mCnw@^{C~IcAx&5#Mr`~Y3o1p&I%aHkBtAZCgH=nNq?paeq%ubz zC@qkShcBlUg86Rz=Wox=Ud5w$j{5&H`h1V~F>$t#MW!(SZ2c>gL2OVu&T@Kd)pW}kv1~(CZgg@vOglOv2%uk1+aMrf(2ikTD0du2o zdby`(T;@g#12m8X;{XUq*b2z^868uS)eX182x*KTp3S$QzskGyU((~k-{>a<)gY1m zY(r+s|Kvg&l#42Sy?N9`Kv!`3P7FX#FmP*uN3wELz7K8+@S!dDRBBUk^>e`Uc(+?( zPW*yA$~VlAJHRHGt$=FejQXwGCJqM5MyN}$CEyAN)^#d@o?;Y}RyEmaXf(FRxl-N9 z7-5OEKB?)a<`^`Hk)orqt^cdNx>SYoMGYoZ8BPh`@ixa~PUo zoYLSntxk|pwvC#xNEWA?EcKD70_h&=a?mX&PDY&5ocy{^WTv%8sLI=$|w7m9$Rsf z1L=6?ferHz9^#-}R@7HErl9H_hVPRhGa@3<%3}Kq7x5kWrRG*_=6>iC!B*y%=*Q;6 zsgXz8lL{gmt{>_Q>TOnwYdP5?NXR>07}t!B-Uw<9J)QpHP(Z|H1ru72Tb7k2BD}#w z5ejJ-f&_h8LTSmvWTCWglU^QNGn~uP--I(L!i7Gr&|aM;PCK&wth^AYKrdomsD4qs z>p$z=#Mq&|?V{~06~~j!PmR>;!&AB)^i@kSm;ftSHX@0^zAid;a8zLAflHPg$ZX65 zemF-25V(k{1q^IV>&zTag zKGUXf^xZ(9Pm|)pFfd@kBAeSRH(-p_;(chNYOmUyFuo!ocvo3nDaQ#gXzKn*#g!{Ta@Ny&XFq-h ze%nwXmDvZ)4R4M5va#=hDP%Pkg>ydGB`<~1-UH1TbShxH-a=siV%Opp@QYYh9+G68 z^kztf<(T;|%i!5IO4p8R4eCam(^HxJ?z>hg-h=Ys%5V z)G>R&*P0L9iXnNxfL>zetP1O0K-dSD1s2pb;7sIu+|=op`V)a_ZRkhIElQ6KI98?q zVKPTEILzziGxTzxD0({T2-NDP-Ya*3k9^G?{SKWwVT7Mzte8*M&G*>EXZ7+m zVIo= z$DZ8J-wjnaX6}%EhAX0OrDWWkcY0N=welxp^bUVP9nly-8rTpep62@-%W1Z~MBEn~ zgdC(-I*9X05~Icg-U(PdKX^lo{Sddt#-eNA&=uY^YL0dNhgg%(zq{b_aZqhvEoZuJ z?x`;F$}G0ja_`(ELfHteXs)czpr(Rq%XYv{zxXS_pA>vz{WQUMUwclVPk7<<`$%zz z-ruFus z`uIdx^U5W>wsByBNiMejT17c1`Ch`UzVF()l44m!NVFZzNy%vC^zkR$Ulm9dKh6rr za!OBoO_2e$JdZ0dDzA$$J8TPZwkM`!L37lj)WBH-_L5uDiG%660E_-}nc|OEtbS%z z{>FAs;-y2=+_FSJC$O<4>!EPm2Hd1uNL0h=^2X&lr4+f0vR1d8jASc;VZCa;hTF68 z-1pmB^X7l^A3=#gfyuK58I6pYiif8${bOz3>_*$?;uM;cAI>(EY=~QQyciSQe1;p4VLoy9lP*a!-HeU5&yk zUKqS3YiX-L3V`s~jOoU?8!kOz7Kazg6kKx7bcBih^S1MyCT9kjt2I2J8h#F{#f7!R z%IIdi5-3SX1%1i|w)Hkp3-VSAw5s z;&U}mXx$%@94H#M%P4rptJ4E!9B?{o>~jRN@h&;&uf7hxQij7eGMuxoGY`@ouE>oG z&H7*6E#`FGQtNA5&;Fpjjuno$W<2M3zqM9c&2gY}60PT+kHksEYiq`v>0%idMy%;h59KCJd1cP(> zw+8Ru$X(E1kst!iV*J5nUd=euXMrO-kv&k+KU0E7- z64y&qc$_7Q*-&%X(F1C(qVi)j#?2=RR2}{zxyX^$)^(RR>a00wZ;qtHmEc=!4 z&R<&by#9CzN`Phz)G0)a43%Z#Y|G@OXR|^>`Cu`ook?HMWn&}{r45S;vU%gL{C^}Q z0Gh^GW+QO4h>N!Sy2}2)_bS@A>0EYTi5D-q5tadF2m9YCN^FpyU>Ey?sl~7$NiqcQ zroX$ayCNa=nz8%5a)td#lV%e0>yzm~WW=Aqn=FrAvvVzp4v`+5vI*Jz zP5pM7>GBf^ApdJa1qAGMMh1hrLZ1V1Z!U+%Zqb|atSfe?&v}427QuskQ17m?@^;(c z=se7BP#ki#9yx*pTRUD9A(`6CXcwZ8wqroPT_0EcY0>K^CJKz@4HA9(3MP%(Xeo4K zGml249~Wd(j0}Yv^!SB$CT3VXk1eX}{!ec5li{7yFL!OD_2yqsb3Ipd-B_0Y4C34D zOw<+iCt94kS)ifN_|zbCUC6m1 zp$v81Gr9JIS0yGn+$p;y*L6l#IFo4&ZYfH<63+IV~_J zZDk9R3g&0VHko53KI?Of8f1HY{QaFnbywh3ZH))}TUk$ow3jY7DEg$uwGVzBf0^K~ z_<($fsJ`xB&Z5S*TA(QZQ6SsQqZhpi1)Beq1{@)03Q?B>>?UwaTf`!YNB(v=wnRDF z!h0!F5b*ZEU#Ap5UlL^1L2gbs4e4zyT7PGkza^KD-OXOV6UX6RWNaYO%oY_!u>pjy zwPxcowxs>G+4wsNNrQU8e(-lijoyjQEB`5{nFoJFCJ`ouDu7JW!@9SuI_|X@MU_x8 z)WCc1*2#PEu~yb9IA4h96?wC z;Mfj?BHZs2u>!wmJ^3Uh2~JiTk0IMuakTK*AF`0Eaf;yg2j{G7Y>A#97&;>#m`>7rXf8;Qs z_fwphi+X>P{8|5VD<0e56;U);q(Rg9Kk`=%aZ=e3ziqAA|5?~g>tEQdGNuQ7RBuZM4=CRQf zi6>=3bN|<|{X{*c(m<5KD#{orYW`#dufmqYUH9BM$VaU?DegJV9pWp;P%Db?b;}7M zGisABu_CT;oE?e6X+sN+>`QSXg@7tdCSIEMC=9}>xdr@#K4z=b*UgoyiHaP%El4fd zlbqQ7z&YlwGc}G~t*#N^y|l*iJJXRvH13~&MKA$|9iZZ5*aZjvw=)e|mT2c6vy&tk zbg*Aj!XtO(fF#+v7)81u1(2>3dz1TpD(_8!fS5byH5|c*=Fl;-faXgPdqr8fuR=EW zIFmv4Ua1U+zjjAp9MwACnBTT-XC5+2Er#;!{CoCq@+|#%?);PLE$V#uH)%kc^vWWI zJ*$}9K3mJ+eTlR9;$_13vfXl66CS-b*T6gXnZ+faSsxZ(8K%?Ci=E|~Jka%VMQ}=e z1yS+jW6xFwNcRiSQ2*Z2J?WPL%uVFx&=)CokN_w63sjm)@55nV&QTe0e$qcv#P2 zr~vGikn6X3|GTD;LQTf%FX{3}=M#>41nJVKaSGuAMyf}XIJhLrlS_bg^^K6I!$+P7 zQLQkj@K*t`!EnUd+YNmG;f+l=0VS4e+ezbllcgQI+cT9BqVsEl5H-NtOilU^dGWkM z1dOZ{m|RdXu}GBKE@#JT)9Neqw6?v<5EK!eW@I*)r zUa-V;&hy_JHvx{b5FH4d2UL4W+=X2>P`9*>V6-xbGqV$*`d7@=DmIk^AQ4-PQz?7} zXuSMKLsaEZ>8-N!JcAQlWL4w}U`CI!ckQMtU?SW(!TT)jnC0yoJI^lpw_|%?VsB*E zZMl%1(c1%v6FP__&Fi)OS%40tNhhg|_g~c~WQJ%%i=XJeBbae+nRd@Yk%SL-&?us2 z_?N~A@5O={<#p#h!=pj#NALG|QZDl?DDX)CYFhM9lt9zL3C;XD6VejvL9nR%8Q%_A zPx&V{U;HWDtrQA;Os*6T>VwfNm`e~D^-dSlh7g6x5@}hG!=rnk*&qRWHP414kiFMi zs~W3=->SF%_trysar-_@aaxJq@ARehb30Kus*qn}^(68brr!*=Ihh(I$Fjc=lQ{C= zQH-)(%OQ$G-o0+51E7S6)ZribEkF}WY6-)!um>~1kXPusTZK1GfK`iCVIj>S^?cUC zOQ9BSF$gMJfM(aw#j;#Oj?)wR%ZAd1kH6PzuI%I;$@s8NNawld30B38UStd_JXcqabvzw-}ck1eVNL-(G!?0n~t`#NLK`OVrN z`f);bcc5tfwfKF69ZCZr2Wir3rqEd z-kS$8`{Fo(|hc!x+BtW%;(HrZ@>D&I}K7 zwEG-Vg&}9%!1qO_b2gyDUB8I0%|8g%Nue-X$|9e+O-jXYb5_iii`S*GEpnHZ2F8fQ zkx7SYUArzWOXkID{~l)1HkEaL|LXryMO_?al(-H!Cpuk}jU*i6{rLlBkbn3Y88yaa z#7oedq_&@PcG(atk*fH)d%_~LCoylzfNJ^!wuVOyZTs}x1z!JcV2T{qnyr-Djgs2d zmm*TfvP`$qEv@)HYtE8(0PW)O=0vAU8=`zMsr4Z|)6DY#)k~BPdhCjHY+*;-aUk(v zbLO-e{Tl7Nv1c^vlJnOCqlJrIP39=X=VY07UTew)>=nOgmwCs4kii(61dmaCodiX? zj=}Nam;%q9gpLBERNi@K4;WJp*PD(U{-9e-k3Io?D;7ZQa!6WqZYK!+9e9*pd`K>9 zXouT8H#3ac^0WeM6vhhxYAAAdBbNh)(zNgW;%^B0nK6W9uv#(5W!M}+fT3HSCQkWH z?uhOBa#8#M!Yrp4YSeih7Yf+>Q;aiwfr7BOwD}RLnZ(d?iDGan9TtHQ$r27 z0!dQfevh?w+f?8gJnM-vCn}L{nTO_?O$0nRJdqstJ0$Jy4iN6xa;;D5{La@qNcS@p zb4NdLQuwzoW`CrdXt-^I4!PKzxRd3Dcxw;YLyaw#EbYBnmPt@19|=Jgwf%4=}Mn|5~xS~!aloYZl9xl>)c#G>|q zyLEISgvg}nLa=T;uOt`WoLaC_)_>ZtcJ2HF(Anlxd6>DZvdTk328LsATqG*;M<;<| zOTBC!@CA&smBbI;&<>*64KBddEsg?Pm&Fpz80eW&OER-tX*x0pd642UFuc6;n|~IP z4@tmSFk0Z(Gh!01B3$OZcUh-Q-Ov6^-)A*Wyt^msv(nu4*kv{Rm6KJ{jAK8`{Mh-Y z%=!bj)%`ZL1)@v;6-^}mcaJp5n60;Ma&xfc3(i&^dp9DUgIFRemfFs*-_N|1tHKVi z!$C~$H_UZ%D{RLEdBi}|=ANj<9yR%^4ugFp5A0BS;`%fMon@2ciiLk9&sf4}zxh$}{ zvF7HyTyQr)6yQB_#amUN{13f3&98oDn%AbOWvVlzN~5_wt_2;S8IBE>Hj%V&6|s0N zWC>3)R=5(+VVmRyS(uetTzz8Ian;hB88$8&%NpRh^xY!#^Y;#}3swLNuN z$zt{YHw*Cn(F;2M+)7K>ZJGv_nW_9gp5*u~Er0jxUj1VQR)yPHLF^OR?yoIg<8^@R z6awgNXuBF_Fkm;sNf3WPEC=RDNXY4IWLUu;r|2!r?cqtj$&KT=b!hx6BZxsE8Wi z(<+h-Kxo50z$YZ!EI3q$kip4Y9o9AOoX8oV(V+m>JB#{Sh* zP|Hf9mk&CZT6s2bhm;Fzdy8f06tyZYwB2@A9|F^aTNW`e%BY;0_03BYL0I!==%4p# zkbY`JccLq%rWqTlpORz@dtrnB0P|J>(O!O3|J9tIt*LP&92z9O2O;=$mFG3okK#8`ESfQpkv#>Wm8^91@jTD?!nLRYS}6 z>=vtctLQUa>-%4AU+x;7sz1bYpNWd6H+PTSdgLvrbQ?hwN`^&ZynU8%wqsJ-X~_F2 zYU9ks&Ip=KL`YQfRwey<0@g;IgD$eqr8P^0JVtg z=QEybnd~D%_3IvwRn5W}2uiEY#TU0+cJC3{Ota7?A)dP{FE0r+xG-uU4xtV_zITdoBWRw0m6+L z%UJ=-_wXj^QIVnJdf=GU|P7r(EV; zOTu$8?2+UR5YMGks!K(=uo&^J_ARyEx#XZ+^6OQyI=Hlsv*d#jrN%HG##2a2Jjp!7qqz^m`+yb=CD%JRm6Hl<4uEMSxI-yMEWg(+pQ+xNdxh*+Tsp777ruRrB;PZV+G{sy?5*l%(P%&Z$blb- zyZXdkzr84o+(3bi>C|A|L=ApvkIm16kpBLZ+Hc>Rce(>I(dF2rq{8@l(W_kL2G`%q(9) z&Mc?Mr?)aDx$Uyl6kllacZ(l*f|vVeZkUhQTOn7mUA7d$xJyI;*EAx1X5)EhRL0C z2;#g|%LIZP!aQh6e0kRs?);Xe0ZdP*G}vwmiY9wN3x(Z9ei2BQPq%ik^Z>{-{E2}IJ(>}EyqV*VnYBnHz-%>ndvwQsCWs5@td zk%<-oM@nyyo=RLeZt3y>SMa%Yk!&#TpifH|dUUe0&zYW;18pLe-0UbJjuF`1ss_w? z#=$OfjO_F!vG$E({Mzo-MP-j!1g&Re*Z3etJ>8Q*9b-gRs%#dr#t$5r{PwIw#Rpd+ z=j8b;z_9FH|KseR2R!Jul1gziOA*Gh)?{Z_uoHBkzNZbAxE^P}>uj@g1sSzaSvNsLFrh&N5} zd6aKClwatcDo*tp0?o*Fh1~J46&h#B{pvntH|3Hye~I{QUgEh(wh~)NrSzk;BSbsdt2j8aZ=zmUNfp3MLHzc*O^Tm`C3RxMR!~KqL zlB+$pwsCUK55bHO^HeEEaH{Z`javfHyu_Xd-^?>=CZAa@V$PLbmbKsCZoojO`8K`_A-Zx?|G!)qudRY>rR zXwDr7QWxGJrL)0z&$MAexWTT-c1%}y^>B2K0_R1jww5!QC+5|PE>VGsG0#VXM}-rt z9H4&5mbBn_eWlu@lV^g5!qVtjrJm0F+fO#5T2&lxu!@rXj8tF~2#oW2GOWj7@(Xhn`&v3F3Z~WOi*b?2npl z52&0BPmh)|G>vgaZ38v4X7B7%rl3CsngkgNyt8&Wv^Nq95i$5Rrzw2%Ur9lUMK_6s zD;?0_m{x91^!ReWA6mYcq+Y^2ak@Er;~+Flbow&+Zb;7S^(v`UyJ!7JlydG&w5df= z0t?tzNn<+xrV7q!uAjjqt=;^}vGp3_b7n?m5QR80Te}lDz1`};l4f#U$EC1Z_laX< zX@RRTT)~3$_VVhs5sagHfpFZ~jfc&9L1)Z9R&d&PixT(?Dn#)v!NklvTtbw&UFwSm z1{v*w)~AAPX+{spsRCy^%9VxSh$KYw>vK|%SN`a-&jLi~#4;4%met+< z%(h!0)k3N=EVNtWn9k#L-l;3$VRm1oP9YK@SH~afNFFsPts3jNe`T6tZeO?#YA|yRP*jeRXh1nxT`n9zMVxmsDLk313G8pdE)PUQwjermUh(Om&%vE zCNib5J@6qCDJi@pT6(r~=;r%KvC3G4QQ_i}>Lw98p2;o)3x%V9|J^IL)Ho7mT>QJn!Awj>(`x_o0s7=^TC^@| z3XE0!Y_y*Nx$2(`msc7_3@jlnfN!QkMB6TC1~eQtAS09g7qDZjv8+exx0<+LThqgH zpr#BVVX%50Y&C=Q+i-R}MZ+i4@GHN{T|Js4&DokT{mP$b^@9KPcbc;2+kQ4l-i5so zx##fH>Ww#CZr{Vc*A%c^m*lWZ@@99Rw6V_$|9GCXrm6R$^W=_jGpM&v)|lxj0lIWD`Jm_EZ|xLpu3}tE-5`ILR{<<^%PZbG z&r(2pmoUX6uxOj=J(O$FWVr$IknztP!XR;DJ(z9j`>oc6b+$aGQrz)Q3c^0ge&k7vd06 z@~S_7mi0XCvJuBcOJ5D!zs=Sm~;FW04bw)zc^TYCy{r{gq7DISY-ilq<$AH zBsh6*m1`^OwgUHibmFGD8(8?5GMl+8=n8H%2*8ReV|SIAeovl@F|uc3d7IWd*Y3nx z_AD<)6)zBH&P*2xBN#1E{X%EAyIm->sAFTM24;(cFGDg2yaMCV2aD7pz!-h~IeYeu z1=JMsICdh46~yV?U5P2kK_Jj2+HFf)10JLg9feIycN&cY*jOX#iX3^lTk`!#!R@@~ zxXfO4g>Vaj>f?t6zGg3)4K%Q+uJ(nv?^6zpVDw4JEe)j&3HtA|wclToYZ&TxnniWnsD$w5xzt4Ngn=bR^qyZZpS_IPj>U&V^#ZLs42L`JfZ5o!P6v0 z3wryJK(d%0y3l+gJ zqxh=JIyX&KU#pAX0s|d1SgrhF&(H}m?-vCylfm(;vjpTD2~H5HEK}RLX~5( zHHwwF;YXrK_rAD$tm$&KO0gp{MbOUo^=3%B%voBfSZ>z9pKD@}LD~t<{6Nq81J5>s zSKv%v`9%u@b5MNZAW856i@%vW?x~H!^JpR2jptV2a{Uorpz1d!nR#>X`5kf0yuAKRPwmf+~t*fw<;(S)G&)=zEh%QQa(4$qjW z^EJq_&w)8L>sWuH{x)4^kcmfl=nPJcU~1tajMg$+(~c8D2Ryy%WOW89)WxuvajP1# zy2_Arqo3+~YWVJ-nsWM|VSw*RtQw-(Ju_o% zPmcxSKa1f@eFAtM7c^)&mHw$DJp2e|>vtmbvXIQt4O*4|PCR&BKq#txUrTZAeI~nc zKPv)aJ(E$XNs4xay`OeUZf-01S2hvEM|>^TQo4O}o0|{u89n$kquBQx9dnyaXRZ^2(!NFZ5cK*ghJJ6|Me0k$pHkco z1k7CRWT;do&wt@A76wCvFiOs{t>zu#+K1dIZ9Q#hQsqDLM}=P&@J@Du_~AWuPH7I< z!UgF2awEQ8IFKY?C3*jh3Vzn~UzpUKn`GSCHlwg#xYNaNpoQsDqF0iP-zKXKC);*= z+0QjCDFdw2@uO)?MO-F-V4$+t__&0#Y~F%5DzQrA-8e%pKZ(F z`gb`g;-;0`zg~mad-=!OctEQIraynj${!L9?kzEyb5YFyE4*)d9bpY}#=^2A@SoNl zMZ>tY9GgGjTP3&4_PvA3z8|$fu%TZ_W8Cy;K!?Vd!cUGwDV}QmFO}pF*p&@0#y{%?;|M4xI zM89IriB20?-rND^=iOHS$w!)b`nRUo;BSltTPWdjeI$lF4aaTU0`3CgGHpkP6^AB? z`k9kB$qt*tXMU{5LzucFG8Us%ApQ zA_8*@GrPqI0|hMq&L z>KKtw28g%c3G!&0{dt4vSzqMUfDSjh#2eg;faVO`)i%l`N$%YI~m2GGsj@;>gCgibsGL=?)lNW zG`9{P*wT@AP8q9yx_43VkY9pz;Tg;93yvGRnGu5G*Ii{y7s150r^-NedK{Pz z7C$ESZ(@x53a+-9i*)#(132p6sqNhp1^~L)cwEG`Mf>){9Iwn*=?y9kZF*q~>hpSc zLr#B3N#SNv-&J`M+C=NF)yuf*57tQRRWQmu*w^{P6XztkKz>|6ILazNhTu0CXI4pF zx1>;N#J74$d`Ie(CC669B^D%}2k?Fu1k#=zvfYYzLAy2@-gZ&?niT^`{&?CA1!1_}T->yX47kacC`~b}0s=E)w>$a2Q9`GF7*f zgReO=`@B5fI)LwENOtQ~g~|7}vL(f&V z&d8*(Lza0eZu zoTQl=9rb{LypvIUCSL1<>Mw1%KtZ@SRUiZejWNGf?49t}cL|#+G`aCiVeWmlmxM*YmYRTaNK4 z2wunc?R*=b7mjF*K{ho9NuJVq=9|vL|ChhnCaHtplyA($povQ&0o2os=CBqTbI(n0;!KtojnWDFi7rRFMl~V$nQ;?g_5^N;kF^+k~#tC2kCEHy>OTd1%-Y zApun$%lHZuYsJssmp=7Q5|a(GxeNhOXGrQ{wm#+6Uk;Ct&r*-t%&r>t&XSnCCuFVg z^YjNki;Mg9i&5_jJl77r)i!%YS~k`EJ@cK^_?xhPvRC2l34E6pBnBwrt_%@mJpv2A zRGoSgKKHsLxo}z9h$dkY%wpCx*Pn_}m5q0YK>wMC*NZUf&2m*pC3t{RnmXkn_O@)zJNJz_lR{<+y5Dzu6P-3kq{o>d1X6e`5o8XGga~ zEep)pMplE(>s#CdR+b$=mXqbmgWbjFP?Y5O4{{z9gMk;%Ejv}qUpH4j{OlygC(s4; zH5J-QQgV0>_wDY_r4?JaQjjJjwcrbf`!K1jNFaRkjg+Gs>Hg2_1i&!}yIixh7qaKR ztnpo!C>M#cQFc_w89@yCC*e?i+H(SO!r|WgT%yNUtNyTN)i-2*6pVHhlh1)+%0F;j zbg>J_pbtHntEFBJ;TvN{l?1z~+WFOO!4@F>cDUxsXT{In{GHkZE!0Pn1(hJ)EClYL zhfsiT%N_hBWmZQJxQ&&B4Vg2Fg>lYO8+S{a*T=nk%1!#m5c*3i?d+fA=v z>npKn*MY&ff@#=ll2!I!p6>vHc7=^@@CDZsVz_vH&1bK%U<<#l^Fg?`B&@%U>*sAf z6GaSNG+33N+4!@>`Ro06GdUP>gdSInUx|E!Do~xT?8bb0qv-#%P#`w5F~%@KRPJl7 z(P#?lVBcLf=Z#$h@1U=xJCpj+KnLS(cxq^2=Sk*bY`rzgQDa)b#vg4lVg)xo_Cs`6 zOLTU-Ys7tX0rNZQh2lr&!glp}KUkMi?CcUjr)g~;n;mTuaN29XY`4-Yqtceg2>wv0 z$ZvO~cDo|?2G8{~+ZpjE+?8F$d(saAe*{=V)eSdlz_je=l{VHY^|6k2jwG3t2=W`b zvr&g%vRUQUp1v!4J&w|sEL76fC;cI58s)_PrDe@r&xwmRv8oinF+Iq`^QgWf`a+9; zR>As4$MP1t2234+{2lk{iCz_4DHj1o;#>CMsIJ6Qw$`|o!q0iGBq52d6Y?x6a_M_s zdgsn>@ z?`0)4&F0k8C&T`M!b5@`HQHa1-eTCt>>7#G`hy10DO1m7x+y`a(v=$_yTJa;+o)O0 z!Or;~an^Ay72<}dn<=T=-<>{l7)@v$pbRGMOQf;pMNTg~Nf8iOaOR%f1vFF+qt+4cvvy8d$rptJa z{NOen*)@Ew0}A$(T-mwAEv@+fW&t=G$wldHSp|yV2IJ2~9uX~wD3n+U1OI*C($;<- zM6oY6r;Qv*nu-wTj{eSGZ@{hKEx?HBU$0nb$9z=7AYk?EK}aS6E489qKO!K(>57Fi z=?6xwpXWV3Eb0dH$tzc8o{999=s-1lbrhN2|O-ku1%xx71dMpTlreKZzAAvEoRSGiAf%Uo2c zgSL&~OaAE_kxFbecYjpeAXOHWEYQMya$>ugSH1JqPYz4SQ10sBFWRRsI_ivpm3t;X zHjDu5tPm~B#;Dl%U)&e3wZah-dVL1p!|@XP)DlpdH)JC+^R8L+fZ;Un4~G{XnSKBT z@P6OwYeAC!F2Wb^b#b0w#Smdl{c^?37ewzQCAC~g?oM)d;nT>4rVeq0i?f-y`qf{a z6W>73#aaYJZ=muC7Z8(D#ZHJ}K_>ITAf?AY>PJZ!YgV4#JR4<#>hn*txDFeHjE@mL z5c+Df9>ns%*YxDo^?2G7Ta!m~qlgki8;Q(I8&ZDggG^zEq*>*0Y2cQ&>Q3w*4kgT7kU$zd0#DVOX!n~NJ&=mi6e5P)lWTnPpqOP zpHC_YB|rlL0T?YGnW(YjlY*z+%iXdiq7@65fI(HQRv#Rz1&*i?A03`6@0d#0X!+!H z#&T;o^J9WEXQ8225wPlzwQ6ez@a8;-Dvg8w*j91C?B^c#zG%lN#g+}Rbm>l#d}-r+>-p=*knUa6*E`c{_VkVSxWRauhR?XrO+++- z*oZ68V^44&e@AzM6swE>QxN#_Wo|1+RG;&<1+VrZ_tv-+!LTi$e9K(gi%)YAoFnNI zta{_TO0PpSZOCEm54J8f!V_Dwe|cUc?@%0yucDw{u1O3VcMkBup_TZ?e-P!orNMe5 zN;pSqrJ;0{b`R0@rbe1*nb z+I%4L}_4yt4(6OZT7k=o)B^#cb>Go9eO0=!q$1`4OK zp%)2+U7`zZ103nXoSSo)5L)e)C`Thau)!x-^1&t3!rZ$hVQKZ@SA-!?(eJ_{YlH+_ zJ<%W0EGv4}9iWDi#J0#N+>Eg2;E_Q?%yBQx| zEaLi43l2B-3DP}cbo}MLR(;ux)Gx}-@9%dX%rH{ylrK2c@bf<%*VGuKw*6h~ZxUPh zWDvUQP#c@G&hAP3e`tE|M=Brx|Nj`rIQEvkvO~!TonsZ197QOZDatN;oMo$w6iQYq zDzin_Id-K&$aapso#Qwh=Q!hgp0D@!^B4HRb*{(txR2WdhBe8eQuI!j}inpV?oZhyp0Z)g1) zc^9;7kTwg5+i;+R%U`S^sqd71P|gGNrr3g;RzY64RA%h)BM#kOe|04SRqPS~80U3K z+EfnwI5Fd*mA9($SIU{crIbGm)QbbJWoN;o-ff<9iBj*tcje*eU7|)4Y-ta#SQ!WcCh2q515=!{5?!{4l zPIn$+(cv9)``UojXdYFr(m|2gB?Jw4FTwN{(!S1EI>YY_pK+oK(SO1c6yw_=R(GJ>9QLqoEx#nt<`+*nUfIS0oUa z^paiY%?%(^;e|JTwmmlaDTB02PNTJ7-cMm^!B(izIDI|I9k=q;roUyszEKuWM5EeD zTIUGk9&pA+9#-RLD@;d3_(y9#yv+%k&IK3+9Z+H^caxx_8vj5}e7tY7(!l+p?E*=h z{I>`?p)^*|a{CXtq^MKtkX%W1?&Ff#de6G2R>n9r2Pt)c&o62Yt^Uh7Q0X|;>wN0b zpL%rn=3GNS-mQJM_}^*ZqkJzoToh3P%JWmg)G5{ogkkF|ptH&c`$ywg`04ZaPuDR! z#@T{X843M9(^iL55pjv!$60L#U6sh$`)QSIsN?!C5@o2g@U%i4hLOcW-kxMDiVb}o1XgP z^&hC{`J(3)tHfQ=SjK|1xT8B^LrgBQnYY)@ntM}t?`OiLI!=yT!=F^XtMxOJ)n92I zetQT34odBMxFLPgPgB;QT!AYV?^4_`Fkg-b1)fna!wytI@j(ee$&93ya^GK^l_$Iy z?c6*{969KYq#Pb679MzQ*I&Pwl1;7)=iM|`_q!#i!f*;I+x%FWniJMi@iM6S!D>NJEB z(+gsW>9o}3u39cnWRzMfR>Oa9aK|5g=Cfc!F0MfFrQSKQ?!DMnXLv0(bCHQ9RbeO< z+mAXN?^|g@bk9w@>IyfuPQ^`;{H{Va=re1d#uM=u5hje!0{j!(g+@7ZjJfq)r|M{U z=O(0$LAUM-k4ZH#yTWKu!G8pr? zNjM=e*C{kZ_zW8-B4RuzzV|ldDHF3ai6w4cVFHS9sDr^%;b9$fCB8Qsx2p$pUc$7w zBZ%HV%W$TGx04o3{IR={sVKz?i7?84LMGg4VIS|o9tr%;b^R~&;<6zYkal=M`*x6* zg6~bOX(2=1ZO%&7`A{S|FWd`Xlwt<@gH`5W#t$<*kp&hgSRGm&)mtt<{3uK3ytVUeL&bsWob4?j2G zobpb6=8Py|hVk^Bc$TrVQ?;y3(+Bqk8+oSM3?(J&D0TvN5_E3ygxF3)lx!s=!SA3g znTR%f0y>GSWllfwX*ly#le^^thHstYDQeqCbAf!9gbcD`%6n<>KRC%c10xmOIai_3 zOv$gbD$a3sylRZS#(qgsTC3g?jOX) z&!^rjZSZDkBAiZV+J?BxI{tiY{Ykk*oyd39~tDck_wHP@tA3wbOpY>)>_3A92&U2l|!U91lXE}w^+a&?t* z;X=f+#<^fyJqtiV-R>Wa_@gDoe?l#bJQ_?oU-l0MO_j0myu45Ju$}#QQ^nxeOu^sh z8@C^VLP5FkeO4T7@F*tO+Wq8OLeeks3Hw5k`N z(!@C{I9j~Y`z3gUWAaCOKxtRu#FD3LJ4=Yvfli{TdAL5YT`#1O*2K2|u)D2Ql~=n+ zg9X(&bx(|A!z=0dG9%5V-4(!$=ag!bGRL`zt<@a)UN$HyVxIq|^fV?LMbitp&m;y&_5GjRt;iWRnFDAD*AoGkn3|`dYn6S2_Zp z^HSi~pUHhYG-N!7`KQJ+s`955)+1`*hdYd)_8uzSS$jhnJ?dqDc#%L6=QP?X^yx}6 zWB!(p&^+IdcOATc%hYpM@~Kb%$8ncFmxMD9akrU?aGQh=ijnvHFmU+uUkEeqeXlV8 z$khGhe8&CLuXkl`uE8X&8WYjio|@>)Wz!Jvjim|X=vKJ8v9KY9B7BhFh`eJpbb+B7 zBSByaA_s9fDJ*9WHGVS1+upQ|%k}f^-~inOHr@xUvoY6&y`c@$qMIPz=q1j$njflX zOtAYq)@@w?gi2x-<0#&W_Da9;*!PTz7rcVZM-{J0KBs)MR`TJg5*Y zoXa9(2Kxl<@dZ);Qklg9+rp->_@Ii_#7U3k-BN~@FvA8XTtSt%Xr$s7i3*=l7}?mMv(g@ zlZK>9TEb(7Klhw&KxJ5X*h$ioB5tTcpRFAC$K510Dj@gZ;Zw-I$aX{34DFrIAckhp z<2}63N^`RR6)2lwHEhkvtJim(*ivla)KQ(5kE3-KnI^j$ zL};HwWk=K}rzx`d|CYMTdkjP2d`)3vEX6AIq%1*rzPx)+Y4_aCM!CS*V`~l0EaQvy zX>Qxr1Z^I071w1OJ#{CTy>#10>Y7qbujg}wd1H?gPY;rEu?;B|p!Pd4e|+-_?0b%G z^W4wM!pi%K$&Xj>C~5jZIo7W=wj&1~KZLKQ;i>tT8_b6*wh`VG&%U9MpqdU`UvTv| zO;NxzL7+C9vQ1|ybvWL2?9r1J)XV814M&9>bZ0qy41Hc2MgsIU`T2~C-T!EKQQ_?Z zhUe>81N0ehOxW`VHbJR{kwxB^Dglf805_gpVEmlmp}nHLidv(^HMN;BQE>_C#q`u6 zOUtL_>Gj=$hxI*=58mr<35iCcZWOI4y8JH`^^?0!@}~1+LG9FkCNVzmQ3eOgpu{Is zmQ3gp1Ep?cCeXC-1q~5<;~t5@)2mIHrU~qG+O-EM=F_{Zr8U%Pk$~?8sj6A^c`EMc zhhMh@nsUk>P(Xn3w4_$dDGqkC^$6W``6Hty*BSff0WInK)j7Q7&KZU8_N&T|T>KcU zxv8n=k$>v)XE!AS?X?6E#)XIqer^AH{qZ<>=RfH~2H6W??C3?F9C*Ah!8(6o^E$v1 z5KJ&(g%#`BOOcGLFoh+wa^DpK_nj^sD+>tYVl_lWpt5Vl?iEuLSpVHx;ZJ3y z8Hb$mqugSf{>%=tXXKN=`?{5tdlWK%^EN_HZ}Ev))T1@&!2LtE0Yn1?tASl)fAk9S zu|j>z`kvib77(;xIn$?%I5lr1;g=!lT+;tHub!PFDTAJI@H+7^dzsvt zhkJ`BvOV>(r8O{Nt>s+CNY6~Z#Vi+R+mhER%W7TLH{g2Jiuf<5FR>-X&FOEnW+-qJ zI`O=0=#{X}MVJ!YEw_`ETDQ!RhCi{frFJRBKHMqMBfn?Q%j39Vnf;vbL}9DCkPTr= zbZL$ZuA-6u;fKj&5yl@@AD=#u>s`PJg9?E*HMo4`Ey{fTt3v7pMiLgie?RrgCd zaY7AMr>U*~O*yZ#?1DnG7uY4)1kHE`$0H`Mo*sCT$Ng~#Fn<-}BcWI9 zb+x%}l}8$jeKgyI=g+9V>Pz=Bsi}5Rd!h!e#Y%)@}4*E4CIsHWK8wH8`e|$ zRp!W!GnYL5eLgCFUi@%rH0LVqOBwG3PtEVm%XB3NoP4HbA+V9hH9BKdOnOs5NRkp= z=A_GOpW=A2+zx@@858bwR6B(Z0}3{jvu!`TR^HgIcscf$QhKgazz-YWzzT%DuWHs{ zM-%-o*fRqPX)CXI3pq#FxRQwCo>SHjL3|J<5ILLg&5a3{y$1)gb=~_l4ERn=JnM_y z;C_Zm&$mcg=T;RJRL~3z)X)uv5s2O|ad)+@u42Om68x?5MCRG)-)QYim{d8c?9spf zBEX#vR1xc@9LCc5K4k&Z>(NVI^h0iyc(IRl)aYA0r1SN`eNx(ifj9NVPq!_d53uTX zVjgxgINb^M4zVd>8PQZ5`DLB)n4VvqILSGkrP;~@kje&*ODpPmZOnCiv5Xf_DK1`k z<~Mu#m=efQbFIN!Oeh!}CuIx3FIqC+tO-f@*9U*8S1P_XWOM*)pSL>Zd}?vobCb2C}mtX$;@WJ48(?Wq4sV&dH9GSb@EG1r|C z`$KVS%l;9@L(D*a;~eV)SLTJyis_=jYx+V~lgrI!29S7eaum6AZjOTl$4th{W4`g@BXi$WiZgtHaF zJtNOrIYF#BfRah;2JT<60|A#A?ey(Xgz$Ohygq^?8P#+r5m0eUCHdFHAA(Iz;t($) zV~&&FE>8{f-#j*G)|n}5A1C#rrT^K&Z>utCu*cj>6YSgyR+WhcBHF!qm3nX+<6(^5 zB;4P3NR{vP*yV+P!fceiZVH)xw7-m@q+>qQ%Os&M zd0X(l2H@2Ai6RKw_6-Zf`X0WT)}V)&RN(-LcvhYO`a>kyG!1!VO%k`fj{l?$u8pTs#62c zH!ks_!@n$p@C_QKYgu)nkq>`4dHL?AN`vQNPc*aJhw`zkkPNh|#BhGcv@3w5k+8t^ z=APi|*_&b9v>Yy@s!ZFr$TF7W1Pc=gCj*G=@9I)$)!;l@n>8f-xaL2Z15c9r*H?Vv zq)DEo6DpaL*NY%YO)2Jlr#O^SsngpEUHz0p`H@AjAQuQ`hN=Jb40u16`|*+_mRa+ z*tzc|iekWo{){8bPOO&Y^!9hnHSQF+k2aj`4VyV<=`Q3c9XQ<>vKx6c?#0?*vIo>^ zER)ZNVOwL5MLZB{Z=4kAS;aSHQ1nwnjkx|gVJ*T(rgS`=?kgO`z2hqMcw}Fy(THzdI`|i_8EPU-us?}3uddI z$7KN94EAZ}>`AEn%7@q5guA)%?T6XWuRhon<^qawpL@MJ(YvhBz$MIXaUapk!M5_- zTP%Rm zz(P?*U}4wYiWjBgLpj1*@HPf#*B+Th%`e0C!a{5yw1gl+6Jc+J{RIW}oF`2@l0hA3 z@uI=K`MgLn$lxZ&8uq%fkk|~bP>X!gnuXXgK|lM07WVC`E)7h08<)`=VRt&iPkZLW3@19UUcYn`W=6HcoIA5MoB~SEjr=Pg__Hlz_?P$8Z(L z7$x2}Hn0rX`xV7E^rFu*+DVajxI|#Rl!qssw{%F%m98Xb09iMT6Wq0>!0&#GAFOVU zZiXzIo3T3`-7Qc27Qo{`9b-+Yo8=SW?W=|JWUcvgmqlCE$;)@?qPgQw$T8OsZBo9Ud!jjUjc8KcgX8&2m>I^+V{Zsi$kAJ{3=}_0f*(JMdY*>lA9ZgW+yw zVon0%m>v^1j(>UrWn|VdNYiZmT@qU{w5g4mp)o4%=#lqGTV;6vBBo|H&V|r@{)0-i z!y|?Q?8RsA>ON(OFVd$zR~$T&ob!!~x#5@v#=Hm3j87u9nM6^m& zAzn)q2;yaejg&hE896^~>gI18U?fu-Sy}Kk12bj78^|`p+wkPvS!GyTk`OOw2C!bM z>bcfcb_$FbI+15}Cs-ps&894dUFnrcQZmeu5cm=|YLb%Z4zWJCBnKv=NID5VY~=;` zgCrR_Lt)$hmjwWlSdJ!Ve+%4u62WEC(6ohUh;=88mJeQ*4|%Kc0^$UE) zIIxKk;h%dpsf3L6-rI%>-0@0$ag-!CK9zfZ4PEw_^CW$qt>N$4OiGx2sXAHqN!NBo zVdtXC%%@;8kw@LJvoXM;r2ld(kc6K{c3d?oyfG$-y4H2++~?fsJ0{+2vD_LvPEDL? z?LgXhoCzqs>w&AYt{iah1t8%%67x#=Qbe^mXB+V7fN>e=PN?65);c5*uW4 ziD1EV+|{m!v$x-IEk5FVqMSjh;A_V^;)UkQeHA2Zsp4}-LPhteLh}jf8)kpysbZ`@ zC7tF`)!NE1=(u&UV5SZ2R-xD|Dt;UYdfm_Om|-VAAF|f{CYdDC_ZoUE{#teWkoQ43 zhebT-*oIx?<-%2E=GcZ^HMxNR;;tJ?Ms+KMc7 z0(Ev%-&CV0Cx6_|std%OX>s;c*|(I|YkIC`3#}wJ?c;ByIvWzn$7aX~bTI?8wbxZ9 zu1|XPzi*c8vH*+26fuA({oM-wIPsc7iunFr4O6Wh>!fB~$G?20#j;A04AZs@Bd@SV zov->CKi~;IOqc?Cx_Y8|&%iH3lb}DbmdfQ%M0YxnE#g%s{`I7+03l?8M&CGy;VJ|$sR+G}la8y( zAAHGeMmT%VIx*yw1(_KowlH=8f61mTwxdS7@C$y8H|F0A5p!a=M8poTD;pXfr!v1Y zoRV#9X*lGOn9?zRJNWws^iSH0ny9`Immut(piK5+%HlGVpEEaLf=IQw4sS8uY80Sn zvu-(#cMjI0BRUnHFeO!iqGPNXL-_q)EjK#0vEr^?thi|D&BXN&z_blpNIU%HEn?2> zHF+LfVD&LpF5z{#Heo%B@qx^vX1*H^IejvpRm)?ZM^@oj%IMn%b~Q)NJsq$)OZU~dqUmm*K}#n|Uv6nY zY(g^_Jvmf$<75^KgBid2!%RYjwOlSq?J!XL9kCr}uQs=j*CN)=Ik~`NZhAWoG8kB9 z2aL(88!PEP`4|hBPJV_;OXPkm=mQoamZm+yK3}ZJILbiW|Bz)DSh~ zA!l55@v5E8D-!3qD(*8chaz5_cF_;C1c?V-`Jf@02NbGW)>41f_N?u}MF$hOis(Vt zF=h>8d*;K!L0CNmXkxz({gZOG_uFr(pb4Et@^H0?DKi`ZI3CmXKz6IlkMr3>+;>_f zEF_o4&nky4@Y*`Yd57kC*DFo!S9yj_vAff-33l`Q2|FTMnyCVwkXyX-c8j=NcoH^G;F*H1J0VM+c>f{P;bt(zOY=>b9~T{1fPK+6@TO3AMC zaM0qm?K%jr#aInb_Dl<(aX5_W!*Z8JcXlI1>|u8G52O>mJv=uEQr$2+c!7?gGv!;0 z4n%-Q4_ICccOJNhDr?66H*2{SXLMqvhR+c2ZUrs&m?@l4`*FmCE3kvnb80Ay_Lfhk z#(K*sSC&DmEmwYmG4)2F3X!|y!u{mv|AL%R3qv~!%?$8@UQKt{KK|2uDq9cN7rn z43OF1S89@6lw~c1Lj%Hg!$wAB0h1-x1`RMKP(e8JYV3ms>)6w8Fxs`k!|#-eWiHsC45%MphWzYzleCb0Ll>jD z1%{_lMl##5P}#0Ftr6^|BeZiMi6+PrjObA4P?b&R6?+L~^H@3f7W)Pz^26sTZcq`n ziskEYaE5i?3M~70-vRFJ-S%?8WQ!=pNteIPoj0P0PNvK?1j<^r={~4+tLd1#$xYE2 z5y|nf@@4e2tad5htFFxCzsl;i7HVJs1P}mG{_RskGBn9A<3mfXC348?uV7Ju^j`SRXSq+H147(Ivbd@F>Dekxobqs$OCiJO)4i%J& zYgj_U_z+cyagW7(F@QMT$eiDN;`TUYN?@|Ef&ZrrVFn-HRT8B%sv(>rO02SP4l))0 zm&TQc0@gszt_nAs@wW&c5{Cpl%t5L5=w&lN8~3ElFw;Y>RB4c21>JN2CN4`+oB5XW zS4$9|y+6gdWeqXDPTxxgvA#I&M_KAJS>5NKk6!#=BahDDxZK%=axa&4ltcw2r8=?ru0PIC9JJz8!=4%l?hf?KE<}~jRi##MDp9BcP;+dgL3%GK!7w+D&?w;V|M9l6nNYcz#^a( zn<7A@+-{L8x-C2E8e|S%Mx+XEJXFa_Y}ctLj9Xjn*mT?w?fznV6T|%#r1k@ipA)x` zP-pYoGSIgEf7k^_o|`LQYm$He48n&!rZq`d*f&p$ZU=Xjn6p7w%B^{p+hIyd!E1Ye z%Upmob_y8f#T#RnBIrq5{~ekZuDm4`)AmM@J~po&d*j%e`7?&voYEUe67gDeTQaF> zx?58jo^-p32_9Uzbpj0BSIZzcTU=rJ^4rA(hd ztLzCW6c)>3E92;%o!CFCM|5&W8h9B6e%I!_M^#F?dH{NkJ(8!lA2f^8W>TS9Ld2~% zp3IB5(7yYbgB^pcMltAsj}B#HCV_oU^xZ`B$Wl#d9DK(br0*?qNB~zeX-8ouN*I-D zM}|k*zfi!T<@*u;wLOFGZzTO&*+Za+W? zpSi-L@KY8W9_ADfW;I&BfB z3eXvXuSHAnh5lV#=O|8Y8yY$&@1EmqCEFM6P5$1#VDeRDb~C1;qP7iL>jCjQcG|H# zhkTJ;_aC zD}vc=vRfax-_cqjojYK*)fYbFnHA#QoX37x!)@N8%drt5T18Q@)a7;))x+owTlNx< z_PAVTbl%o_#XM23#pkGvwckWMS1}Lo^PIaehuq6w%%`OWc46)&bNo#C zidH3maXh8P2L7H^;N$QJ=6Esd2rJIqwJ%@l6T7*aTpqc8-7B&1?vm;cc*|-4rf3XYhwn zf5i8bk)*ERMaq|w8FCoTJ--!JP89I%W-f1S5Z*-?*f!2>7Q7^ZT8bIDXF8vxcL`ha z!a_qM;g)P=PB5g8&|fzI!k$zW)j7rx|10n~={b9uHFd;+bfMwXF5&(Zc?@+RM}Y_V z1aY^GakYgKu_vuy4=cOTJDgIl!?V)?9^rTnUsi=DXzd?lz{|yNnDpF8XD-47pKT+^l zfl8#~vN6Gov-bk0oArVN2Y$3h&y@^7ve~ns-t}V|b(>Sf?ZWBiv@dqF#BXSp&udNq zr>0ozKPGG|FW7Y|<#vpQGZR^rcv8!}*nn3ncY#R!6DP#~s40+yEhaaAbR&~gWEsWP zAgn}33|XwN3N@F*=MPJ`ASFt;YEvuTSixk^ca|iL8RhJkNwcDu-F6SV*23iFCCdqz ziFnqcsWymn%F9Nn0%ag@Z4A3mW%B5_&E&98`d!2M>_|-F2Ly-ZP=oagWO+LU!`o9m zG3ONjunY6ew+132zwO1gT)8;=R!G;c=(dtQoadHV1x3Z`fhowCx3EspVtBr=&eTdh zQYTY5_pRu9ung#2Se z*C^g}H9y9@b|fqAuDC3m0~QiT)FB#&E29&wci-8u4U>1*NmY-4%AbB$5VQ(b4{u^C zE|%RJfV&LAPnTbR^RE;U0K@MbwL;j`Cw}OB7U^26)1h<30r>Mmu@4j8`DD!6ZzP>1B` zAzh{JYv-GwwY|4ui`#4fCjF#U_3#jepR++gsGPy6V||^w5j%&TViuS$ipL#i_IYm# zZ>X+4a~ga)_mTY3J28MOXJ8)xOknMWH0~mG@4u{qKhtNJ$*HcF{l(4i;OrCDs?v^} z6%k@dcD%P=6}!88-!oCkQ&DqiagTEF8Uhc9-AzkMGKE>ZDM!CMY?^?r zUxX`be7746?OPq$*Vv_8Wq2#2bk-hAkPR35LoWMwT=cg@=$|bd;xedeiFhRZ_IeMlk!TzjnG}=({0y2rqG&%oXIq7yCpLCp->)h%tvWX{9n{_mdOUDzclj%T7L@W`&1U) zacz||4S!8|>P|x|s!;*<1;fVb$H}P3$ww4$Uix-!{aiWY$WZ=t98j=|t}b<2m-n-5 zw`WcQvpw2{|F3dy;T%c5`k(NweGz^thmm6*F1~Q5JZZDP3&&;1aWm{)7)p!>)p`c7 zvA_OE==Az{{3Ay|15ofca0<{zEM`$u#AJgxIKQv+xCK4Ui?V=9o(_(8gd)4&Du$#A z!jiNGJIF@14Lvc39JtN1JoxC;N$^N}759o89;gR~*i!kwgVvRpToX)G+>EmN%6XGXU*z8pL z3$e&ugRl~xjcEUed@O#LwFvnptGAP(Ow*#MKBoe1V_AjJck^sq@7+Ujdp{7LlM#x{k~Cc!h|wQt$qT?>r)P&&9!tNp z-ijU6j6}0I8DlYS@eaMrqw{Mx@C!o3uhHC*_5>z}Z)^$pTR8UmGP9+wj`L}^PsPIW z+w#s8>@BA0*MV;ile_rcr=1Y_^U{VZGP*Q|w674N!fm*fB-sKhhmxVFjsQ_*wyBOUgmD)$n@! zN${UZ^1W|ACcBqSzx8+v8);6Yeb?(Bp2xDNDM$F_D0S={qi%F{EN&(709}aIp~M)L zu*7^B#ZW4DyYRO;A&Rq|>yAezyow19+>xWNK;zxEI9KD%#L8NtUo1Q^?3X|maGj(o$J#1do|J4+8h&Q62Vir8cjEDY8iX+0!`M%=eDo6?+oRz1eX25va^qm+#)c|B)EBJ z1Tc4+&4%Z71VRgbp;PFp#E@6q#@p8~Zd#ncJw?Q{Dd_M&tVk?#N)#}i074dpGeGW5 zHWj(ytEHCWdiFzFoE_{PAFX}F_=Vw)Zy@@~R}G$8cX@tNR{!4r5(M^&HN(3#wDYx< z;?SAg>gS>RmZ7V6`9fLo-r?e4n`)2bYAsTwI|dC`nQ!-DuBy*`;o$$0J>W^W_w{K; ze9DzRgBCA)?rr<#4;1G$)TS*%2j^bs_I)-=^yd3*MQRA-&g78|cp0qoLPA0AQ2ZlPtbNMb;9--sy)eh2`_cn8l^*{)`x(WuQV%Ew0xG zS?7P?0A3%8xhU)|SRn74&1;;`O2fZNDcJkSdQ!-xQED?*^mSQY+c%7-_c2*48`#wx zT3mK?p}AH5rI~E_T*IVa7P^oJA1?g371FMs{Ib%ch!O|9o^nu# z#OZd4ZCz??D{7J7!;kZkj+WrHzO!>f=^5$Mhp{KTyh6gwE#?KaaI}3e+^V&lSq@n$ z!#67gPmEtvj8G|pc6k=Jwopcvcw>~WUyYp*P^|BG=hZ+?VnNG>Zxu2~&k>I?Q*Cn= z#BwGheDnc>QMvHiiD1X=BNR8m!eH)37Q!teMcd@?e+*A^_FWF1Sy2fA3T$KTl2-0B z8A9rx-5u1#{q@nHxw0RFtp(~UXwS82_rt{lPbsJVvz)t`-@V`M^HojW{x4Q@fk)BW z+wb@8+Kq>ULT{mNv0qIMR=tLrB(_c*-7*pXg5TZ)Io>a)InAV!sAkmJO0xAC873FUayPtcc=9~AS|~u)7w+HMYRj|hpq@wwo1A0 z{Jvy2msMQyaVv<2b4sz3bY~MEZiRk}K&xPn^GifY*GpAHli}T4hiC9SsDx}J z;5#k6>vdG?6GqB_3|Sjt-~wy^-DH9;v@UW^MoZb)F^*0iBsG;Kez6eWO@2V1{hw_Y z*V8}WS*>q{QWd?i4C=H@OUCif+nAoNk_@-vJ*UNqL7p0pP>tmA7D64>2~S99fic=U zbF^|5(iCqHE#he8u$In$&_NVvPR{EkU?Gf^tK=0U>Ewxcg{PnLP4*-VmS zM#87K460!E6betIKOLyDk=v#5E8>B7_=r#jz(BY8;gdmIZo&a;v_rOMsv&?!1EuO_ zFw~(tAnb2K1VV8outB-x)grW6xwsHVIqGJ6p#8ePzDn2kI@`5eas{uUu~q1$r+f5S zHzqH@d17G!s!CFIo#hWV%!v)}Om`n~X)4-tY4Bcy`%MnGAX;vGP@svtGEC#q>G&Y4 zB=_h;cl?>vO}ZW6(2P}Sx><{xq4H%Pb^MQe8OnXeNLc|$2(caFBDtMT=3Qkq-ft6d z!XYU;gz1xUKk&i>&ROt$AjG*#Cl=rrJ}4sW=;9|6WB-qq$D&wBe@DyA?!bV7ze zhV}FAf*79N*@x>QVc#b#yU)6Alr>`+cim-k{{0zkD6mAYodA)>HlW{#No4M=4Xa}1 z2f)#)3*qoB?~lGGvVYmqmln&$*PsLQIMk`r$_hr+U*vW6j<<k~fDk>>g0QBw>e?RXpBpWHDT3y# z5tP$BPy8bgWKPloQXRMTe0#YwHCf0NbL>V)_4^Jd2$)62ywm3OufcWQa%s7Yr5GjF z>!1-on^(w-V>zLe=<}Ep)DbI7)|uFec7c0R5RS9qb;)Jm%Uv*Pt6j-!+Ra~Zt;mpI z)*5TK$H%2AE&h;mn!k`~Od}5??YzSOx9xp87XeqWbod`1GgjZeo{ZJ#S^OU%Gu7$3 z;ODx<{P02?+kv*QZttyh=I;upO(!=O&7Y}>4L%uB4ZZfqm+yWj@NU^(ci(<ald7X}J&IpP!6mk(8@|$U=*A zKvI9y@08dSrL~sZ!Zn?bmJ?bLiaMlR1`qMumgBB9=N~V^71BNWgXQp>DL3XW(mrk7 z{cq@)XK#lnWa32LhO+as7N@8%$$}5=bDv0kqPbuCzhPONOcrvtPvk2$8{N=ZTj^8! zNwb|F&4i_*%Uv~d&jNArTFrt}`kW^5tsXP9^%AiiGsph_M$crU z`nsxaf(9_DkYQ{5=*dpPlfpb70f&rw2lv+y2Ue0MEy)uIyUk=V%R*BJ#^KB(EL;QK zY0MTd_R!ewDi(nVvcg`5zo+1RtsjmvnryWih4u8W5gxn)>#d+oeLRGn1ib7&Wv0y( zr;NST<>*Qel-@59-Eqeoq{t$n@jEyJTy31}R|%5jp;yPu zT{Oavry}Gn><=?oEBOX9>PQzE!AR_|!ro;+VdfJ_SA)V=QewRn8+Q3wmDYM@$KT-~ z6{-snFSx6`r1s1Wc#NN=q^kE|NpCVJvC2XPNjk#c`tFFb^1xe(Di>+&<%6+F3l)fM z0Y(drY!A^qB7a)ke7;MpV~1t=5-G@D&c7b8?s(&`6;7S-GFBQGi!QUz>~+IZeWND~ zcc`|;@bJ?HGCLzYicoQVX=^Jw&oTesTvtj2!W2`b(gN4A2@x;72r894ejo3+ZCi@+ zqs$Y7VM*{L#zz6y`A31xx<2?_LN~LaPE6C@bNBuTA^JTR=3Lq>kz5HSyQEoS+IqacY{YfZ7_(~^#wQYV=@U8^i=3PMSX(m*gX6J%RXuL za__Ea4HXsq#^%d7^O9Vq_03<)_~XXg&Bs5n1zdy2v#J1uA61Yu%kX{65H=3&K+Ew= z!Q5icOH|;`$6^w4f+ves>k7rBp^W?~OXT=&F!iqrpegfQ6R+*jff=8I9L+W=v_@p!qqPvI+&dDv<`v%noKC$3GZku*?Zw*S^=X*h{!sPz8!`5sL^ znLxOHF>HR>h?g9YQCYF#(Z|ID#|P!ShLO&%DfJsPjRu}x;+K*f`|~BOfkRxBU(v$J z=MwHlf%$Wqkg?j6o`J`3Wfoh#A}mGxFu?-sN?;{;gK6a$h4Tcg?SBx3J^Zr6gC)KT zN2x!>K8#Yj!l#^4t@vj6NrkM-d)y#vrN7DIgeP5g4+V)$@|49p2+R(wiGe)AA4h|6 z*fLY5*K=>CeTVN!EaNrgw3tIK8up>dlpXgF92Js#Gm41?shNWmmc{dqtk1x&wheu7 z6!gypHRdI}T4*vKG<;<;N%AcEqcgXWF@C1=*vEpbqqv)pk9-Xu+Pv_Jrm;(lg>)e3 z;=!r+w4+uTm7>HW8r627;d+kp)#ly(pzfXyD$ONgk26Vfv_1n}c=opl&G<+*6b2pv zsI!ItZ_QJbCNT|#U3yd@g3^k&HX#&wJZ2 z(q%{$k8UqQEjO&wYa;flCh0(VgJugNs|&4UDi3bl@@Nc4fhCA_k{FQu%xfWR_PIHw zECPO9hSV;II@gc|bJ{PPJ{sV8pBs~-j^pMN9ZFGo@8cVTujh?7q5HVll&xku{V7}0 zS2HVJmf<`XrK|$}kB8~=XU}1uEZ6{D1O%Zwc^$QD1E5^J7(#O&BhVQuA>Ji75K<{n|1;-dT`t9gBbP>=61=YL5B^Nq)rSpixUR}wm`|FeGo3LjVIJhFe06r+2C73Se1 zzEYM|*m#t~Ttfk^A%2qq+^wXySivex(|FmF^{9b*xV%FnSauZ~BtxCZU!WaL9z?h+ zRxeMN(F7WNghUKlcJ!)!&upA6m)eth3VmQYLP#{QFY{cl>?_^XCC}~%pvcQY(a-m? zgh2b116*=D^%*k{I)kE9POUyaqg4JLa#>*LE64u7p@2c5PaJz2XsDQntN`5nWWjyF zHM1n;Z`WI4PpZ-xpKH(>SjI37rJiofYkt@QRh*Eai&G&Yd;cF*XZ_IR`+)1QF}hni zR6syb5Re)p1VtE#3J5a7z#ye-qfydCB}S;AAfX5-u~Cu|(m7JP24fqr?Yw-x=lpQ~ zg~9f|&vW1Rb)9J1XCLnYIcLa3GAY;6o-UBD+MvJ?7nED1eariY&&sT-ETOBs`fTEE z@AgjHI~%O%P)TMDqyJQKoK!CC_CF~DZWe7B>!3EjvL^janq-7DAB=oJ8o}SsY?JOg zQds#XkBOG9p5FbvpE!Xp^e^v5=tqY1tAMaH61I%4BOW*Zg=@OKtc*oqOzd1snq5f^IuX}l`!VKj z^gO9qOwSj_C9a0#sC(9&l@r`0*iry4FEA{daSd=3N<6oBvHcNK#fPXgi_&@ORA`Sb z`%HBzsq34y(Nu?PWX{{#x%EPb*8Q`;$P^cvqY0udT9B}5cCnk4%F@c2N7Dc}%#0t7 zCo4&BV#<_+!e!8b@FV@a%@5o)qT`{uGiFA5B~AnQC9Co$8kMh44NtL*yZNA+oWd?y z>NlRvpXUAuyP7wmD=Vh^^Qq>~m2XHxn9SDAdv(YjE<|Ry>sscD*>dvv*|-M%#Q;!x zX|P3WeQhSj_M9?1DC~+SxX-fXqUevfBQm#qp94Jxh%WH}rfz$hLuiW{7ucyT$Y{B| z&HhDLK}r{M_dd&qmj|nUc2V(ken}KLd|?Jwznu?LR&`pbOnXjTUsHG#DD@JQm{6x)yRY1)`RcaI2E{OyL= zop>;pz46f)F;E0sbU25t%$sne|8zDSlo*k{Ow5M`XllIeoD7JTn%Xpwl$C_ct1KUt zpy+@5szw^`Qg^2D>>oaf1@jMaGhL|k2NTrMhPb8>(t?U=Lxt{veQr_-1bqi3)IgLej{P1oMQXfr?8mH`#LR~ z6MB410N8A;=S=F(?wvt4wvy6qrLjKEkfpRbgR3ZyAvnFBxHN*&B9Nv8{M7vJHd5*+ z#CF3HBz|`d8SLX_?vq;lIE1J`kNg=~WW2VO?K&2FegT`|L1t;bJrcA22ao3bntG#G zFu7@sCPS2qt!H7}3YU;%e~!&3l5%n{GEf}$XaI5+1AFJ(27|!wHcb_}6kS(i)R`F& z99ZN13yoZ4t-cON;#{`W-qT1RHrIwhqA@j&#K;!EN$pnx0Jw62EZ91v6vI=D&J^?sPGfaYi1nEX)=fumrj>aumk#S z-oj8OgnGZ1(seZ`8wDDg7*#IB&s)wcu@`Y*Setk6xj4}BVA2E&7t>gRbKG>jJ?TBK ze6(WeZ0VnN*r34n%C^s7qq90tncOxYrh*a9o#rEuOmrP{?dbIvldGc*MvMMU$WQ*D zGM`07Ww<;P>@6EOn`)w`(iS##DRG1`CJkHN+1Pya;55p+w8)WS8#4XIj7z7b4K48w z!N{B6bp%voLVm6;(oP$ETr=B9p&F5K+uBsB2w=U7?vFCz@T$(vBrR(icnb|G zl5*e>zfTV{yTd%@_#Igi>u_JWe1tA-RddMnZ*wDY)|a{sEG5*^at5DEosof$SO|z2 zZMx@5RV-|b3rBqah#r6HO$TP;>?)%-6V`6PmaV#BiY2P`c@|LtH)p<4Vxo-VIKA8n zoDR%^lX$$>vZLXx_S`aBn5j++7w7df!+}vfEnpQfcA<3Yt}^;=E=z>ivM?{d?IF8U zLJ;&2GE!<9(<>Rh`Db@?oi9J`qT zQvlH3*Wa&>4~H+CIo)T)b-EM13mJ?8yC>%s9j8!;qwro;ay$eaP9auJmmVF?AgXAk zxfQzX>HlSO{pZbj3}^36{yU{t$&D-J64cWqcniE4hVV{s(6W`AE6akwxow7ZiY04Y z2ArPSo514AKBV}A-3YjBdCdd>wRx&+_}Bl**tS;j7@Zf6V`5P?1q*8PNN^QHN$mxs z$$%ik{6}CL7gTFBQ)XlHy>&9=WEW#w3PV}8KoF!tncnXOS-_jZ<)r*}3!@=s)4XXn zgqcB|oKpGI0l04zMB;Jp5@4@@4lxNYm#xm#Z1KY}eQ6IR3+5QUu{(jLVHIS9JhG#| zfTpBPT+DAPf4v_91}9qLlJmdN(Zrepo;!O7*&c%TqOMD|yRg)=S-OKv7`y6@AKeh*+ z7X2W0wJlPBRgwnow;|yDz*tZLxO@3+ivF$w>I$tUn)(xnl^CMQYDo=Hd!;vP(Fj6F z7t;F}m+38_5lbx80+)j^?^!E0AxyLg2e@&;Or8R)I`X0+P55Z`Gi$O5TSt2nYqf!) zpoTreiM_3@y$4E+ZDEXpds>3Eu0v0*_1PZ0{NDH~^HhC5jYF^mWvuB z>hm}!)~pUbEOU>lYWZG~vG;UeXR2BX+gjq8QrQwefM-nJ6c-Uy;IU5sc?2%aolUGR zXL>z?-#S%FrdDEuOyHVeyYSjsEuZV-J^W(FFf#Ls3Vvk6g1aueXyyKGa=R^(hv{%7 z9O=W3_34RbQo5}_@pwSYLi!=adCbN-XJ0^Lod&k;+g2g4CoeYshscb9LD@u|+YnqQ zP4+F^BHtzSNGdR!FaBxG7&)q6qi?Z(Z`?jn?3J1jf0#4?6gOys?D8xv4s;X1-b4y%9ybRVi?S2q3p7ACY`0+6gQzUK;`?ohNh6^t*mT2zL^MAR~eGk z`;a~bdHZ*j>BF*J093& znS?UXE--h8K1zdp5<>cqKsx$O=|*uPf6G?)F8yCprZaP7=w?e^M)VpiKGPDngz{Ez ze$)HOyPX}~NA*eo=UG2ygM2m2jg5MGT7)8c;D1%w>eQuf)X?(n1-w<9n}+$NNJIxV zi7SqG{n=2PE-16&D32|?Ek`v?n=|k!ua6G(!?n}7$0Un1@)8^xdlLxWZ|W5oLmH**lY=huZ|BQ;{99^v zfn{$2)MS~N^i;k7F)&4kv)J~Z@dqI|X;mF2nzNf?fdW+`O{W%~9KdZ*q4}=(vo3us zhRQC0rp*LKezekZnvQOAjym8kmh22FM9umi3^X6~pF%rH^PHltAa*HQMr59Sj;q1M z-#=CN9`bfKC7a^DQPV_^YN+$6;Cj8V8is9-_%JtIYdq=_>>HG=rZMX7%;UrpW4qI9 zp`mem3HiFp2MMr2d-HsFseRxaVUMNpTeYAXpI@m);x7tnHz<=9*G80Y1sf46Ip>lW zTe)7}^@$)zbf6Y^DJNKioMUx2fm{6%a6=3RSiD(67#s#KLnAneAK#(P4kGZkrWx+d z{zJf&f!6>7lf9zPI~^%JcKTHosDrDx>HZStvQqLLDrt?fK9?muV?jf%!aH;8+6*y;7YSFaM!w_cflOA|pnsZR3zMDEfq|U6NVp&Y@%BJsd_~xX? z^ZHssm}jKH8pw9yFdO94IaVI&115KQmnx*QF5%_CW+U88xe9%{4gZMTJ||DrE16>e z^mJa@Ux^Q5QoG+ch%G+|$hirD9VT!Mpu;f4Xd$Ha zDz3K@L!77*f0@^>3?D{CguY*>J#}=M?nQi>SwHy_p>@Mps?cD;!ljzBAL!yWOB(0# zfKmBHf!zCpd;RYq`FsSFUOJ|lKC14;0`Q+D6saroTT=+3-QC*iZ=bpENI%YxjJ0;E z$gUp7c!6qkUTx0pBbuvVf$NHxX-e1tw-9#g0mGkYu42_a7fqu|GEp)Dv@~#W_%7G_ z8Xk$FM-6JwCm8|ErIeSN`kz_4L!ubN_=(ptaX4-3X`I0msgK~v+iZ>IkrFR(b}U3h zB8=_tA;-)`==j+cRR))d#(<6PTgr740`UiU$2OgiI51ysiD@GEFKG=ZGlu^f21)jz zFE#S;XpbenN8!BG4QUdT>bqn^BuwCmBP`4>IKD%v#d}J&n`p=sS}T;>aM3|oLrf^0 zQpsNc@fGzbllsxuyr%De88v>k$KYs^6n@u?%dgjb-ZlwT2Ek54c+A|&U%ITr3zMN~V&!Ew4)U(%O{cC)_+rAt` z+9_W#W;2Z`NBBk;fXoZ+6skVneoprEitW=X2}rct`L~NqXbb~DnWtjHjNjj*-X21w zG4+grishmNxJ=C0hJ67GcKSbIYrYt~lpRA*=&`g~Y`98nP;!%bB6nElXc`L<`vl7h zc+m;mBAG0YY~$}Agy~kcg~y8@HEqZ z)NUFXC$YM2LMFrpFQ}E9RZo{~zm4N2uf*!M_!a<0f$uWr3piE(l3M={#?Y|EH8u2P z?U6zSOO9RpQr>zZQ8@IXdI(A#6U(8%p6WSnm+n%MDN(o^@%#okF0RJY*tI(lr?8xI zSIbtKbx>gf8bM^;NdeM2)}l7zRNnSC(nFTJ#5j(Yq|QHwyUh}8FSr_VbG`AOHn!tr z)9WI6E>7hUywrH_7h$!iD{xvdQ{gc=b;Xt1zCY3Kk1Oi+izmSw1gvW0&dAydatOh@ z_QPuO5Uy@|XAK9sJhdw$i^tt8)1fB~TM^o7x*2Y-fKy7U9Qa*!R`F@kG~?+1jIfZ{V`@2veAXMsCQ3 zoUwUoxUu6e*OUpk_-hQcH*H6FfkG12|1>Pa6i{a}GD6CEgTIPrt2_>eY(-!(Bu?CawZiu24(!X`pgqQR zD~)w2!`Fd?Y}GeQ#iOhQ#~i9YzCmBc;2~YfYPh%^DMrfsP5-f$7jAr+7UAQ9`(yZn z1}>JWq%yP(j4&CP8MkabYMd+w)Xy86B#m>y!2OyHRnZ;7StWQS?Pnp@pN!I79L#NN zYV!?kToY+h?G6m4fRd``%X+;v_uiGb;tit09EH`)Qx96=d~J800CgkBDl$=MFtIl% z`$G8^jrw&KAAR4fK9W*>`}Ghv+dPG7LKR7;0WMbg5!8>E73Q~PxJJHOX!+J#l^C(# z+p%2!Ei|=epvvBIFeo8z1@b?&e1m`rj1!djD~7at`?+*O7cgQy;Jxb|m!dGco7~(B zp7eV0+Wc-pd#OuF27rN3Lh4u!Pq7KT!B)YWBEa51aI*kRv&3Z0!amXJ4of>KqxGJ8 zaP$fNg?aNS|D8gu+7kqMGq`beOuRmtS;Qs2=G_$(-?5P`(g$69T3<#&^GG2h=vnVB zPh|>M%ZuoE;9}mxV}|o;ESQfE%6CqCVMp(_7US?@E<QKNE?d>UC;mV-jW091c8Hz8!6< zdX#TD4(FAlR1YApp9@+l*mIMkST8LyUdmi%zaDNF1ovr@^)U&D-{25yBe5 z@*)A(D<21Ld~S++iL#;BWHjmpp&U>T+v)$%47yP)lr5zZ`A>+rTU#%J#==dztre)O zgrInyr72&FDsk z$oZqm(Oy1Mh$w@k*@w{l{3Cef#l`@w@WiNCVCVQv@8+xtLE^SNckFq?RW7Hy@a9>m zB_hAod|E@VAItEpgNQb{DPtPg>itn|N5Q~{{G($VL45^o6#O%c-BGgS9b@9ivuttzofUTLkSYw6d;j^}#%Z;FP?MKUI9=T|@8R-!a z+?S7qhjm1WvLEIQ|6x#Jkht;&iT4-{e#bL?+hxckoqt1?DXr9TD?Qf$miaw7w>KV} zCy&+Yk9f}MNjjWrv)v`-baRh_M!GK96a2QO>7co9$6v%HEG#_sG066&2szkImkxBo zfUNR~&`>;zqZT!bsjJjx_4h3m}8kQ|;zcrh#p=REBV@@ICnh%%3I zDJ^7Q>E=dro)K5Oupiddc4bVy*zmCwX$l#X>wT^MEa{X)93GfKyDaxIirXids^I5Y zQDIGwT%_YCKv`GvJk+7_FgeelAawSup9J$Rk`) z?4_{HeP$(%zDltQbGyJwIh#gsa5MQUZj(P6WCc8>CND2CrcJlvq0SsK^`Oe}M zg|>zH8SNo_f=4$*imY)plz|`&j(w0A+}KBA%6)-q`!N;GXbn(S3*$p_&1(+(8I+A+ zUj$ivcaU?CAMp{E32*F>%f{E2rQ}7y2BI))?ZiGtvkBamrtkmonF!3KwU8@$+)m_y zmAEoGK4G{)hkICmp5f}EGqf&tHOs|pMzBQpyI&9BPDW*bGU3;x{S9G863pk{ z1jPv_%{Yg6ZB@&sl#*P3pObb8$stIIP_zMOlZ^G=ua7)ph;6}T2?SD}My4yz7KEuqS^81nQuKBtwz1wmJ-+)xMX;<9i&0q3Gyc2hu)IGQFMAOkvc42?2j>; z-COhI;dm7P4)Ov8uy{{@?0f%$qWXG!cofZN5L+bzUgYOCjzITixY6(frSgdh1?uQ+ zql5eIwaXL09(iDCDm(lI-BFLaNdG|zAmT4_MhIldJQSYzy)S`9fKZgSmsCmwG_nNL zpbj#P!B&4uh~fCOMt%fgxcbvnnEq}(PdYerWwZ4w*FWrPcsMj8s}m{xyX{MesD}Xb zPj5AN`89~ZMmD8U&oVtbU5Z{Sguqt$g&D^q%?KRjP>~_`RaykzP~r|~kQj3wqjSWn z62$vKOEvg(e(x;7sv9}Gc8t-4WjY^xMtqpO@FV>7h(l8E%Ujm6^^quQhveHl`xz{Z zscAg?upkQmw}_K!AUe8ENVPCLsi*18kRF7U&EXMMyLzrYw7H?|xT?bJ9#4I;%P*Vr z>LyF<9)`i%_IwFL7ZKG2oY`rH&{%kLr%A|sLIU}zbTE~cl*}zl`*WbqI(m?iCN{jF z-Cg}hLE8j^%av}B&-2>a`z1P9E@P<^W5yC+I>PJo9i(b&6s}3TEe;3fEHmKFC8ikol%Gcwkf`ZcV{Qra+ zteE-`Oyp}kgK*pzE($9XWuEEWqN@=HXIv3G>l4*vJ;BNeyegy2F;sK4GvXl7jU3Nd zw1B@ob0SYl#{ZE|ZSrEoqp;w+)wRSyUXeiNqS*ZvwZ`g5^UEm3M~LAxE(A#tPQ4C7 zF~(k|Am6?vW$Vr)5TlHY9fRP`-U&yuz-X;SuaqnN3@!UA<`o@q*$Mo8mPvkY0xgJFO;mc_&*1%8j zi5#`6)?S%7S+<;|&`}`K+a6hPX=SRa=is|g`PGSAx-Qz2(E!tnjzN--eRoAOOP|Rf z>~k}wvNZ?SgCriaEb4wH)rb+~Wsf#et802PZuE8TN7Nfd*TQV4i4)CdK~?F=;9A96k{K5IyvtdTD zUt^|kW+A)GS0Z&=hAn6LmrRXc^DSK#m#$*ig`yCNkzt&-3~*W>DF|e`r&}3tH;enD zseb*_45#9=NHEnJMX>~wtjx7Pgf;_HyvWhn{bL&*M-^TkI;+hE zc%hPN-JT;J%fRCi+I^2!-Xsp6I<8n5j#wB;bP6*-(oY>?)=$mOyUhQzx89pDeX7RU zyfnqErpsWxjz+Dx1bykMlGstgJ`p{*BYRR6_L`Mq3I=n=S$&0WG%iODFda@cauZ|h za^tge!#3J7+co3s4*)9zFpWI z6fOsQi_v_bN41dLW?3TM|rfm%r~R6v4cBrb@j+m(h5kF}Btb#$GqRvSmHs zN8lF$g7t&AO!S#4;;#pm&*-Snqu9de2t!KsNi(y9CP-qF+9lInfP&Rz$C5Bq97 zCch%;YB1&J;t>MpE+aY}C_f(3vBKa3T;*Z?=^-psOo4(1n#vXN&w<@8fCvJ*hq#>TU6D)V6MF`T!xhdK-l0LSDjkcUhSEMpQQ`Mp$VUA(X51X zv{&5U+J#$Y8Xirkub90u8j1e|cE+<|K!zvxEmUOYiF60Xq;b+R#lT9uAL0-AK?u;# zN7VP&*}-z}-R4)bLp^2H6aaqdNnt7hr;5MlwJHhOzr<-0SytdwshVx_{l}~7J(~?d z4n=l%4n-WbsvNXi4OjAzSGBofj?5rj3LIqv9cQ~FPSI5g%MT3W zUNWvt?1wk&_m*o)&+O5aAmE(d?^`Ki_LT6t`^8wtT<_hLpZGch7u}nIf!({&vz652 zhvCNC#<`EdA7+5Ecv0@`7oQ8nptw7!URdK~1reu#=@t8dJ~R8sy6FsFy!bDCqm*sB zX*6P-HOcwtQS1eC~WoXw;=p2lf_QGuJ?V*#hlgHycw7kF?8<_{hS7yg1stGOXg1d{J zo@5gjWq2+(GxUw|p{R1zmOGR)2&x|=ZseA5iaRbZ4tIMraqhbe`6^AVMLxg4XY|OW zV~xQc_}4t(dz4!E*jp_^h$w#_Zp`VdxDDs$cma_Os15r55T0k8(Il$u!vcU{kqV-+ zGmMBXwEZ(va7Wk_tjWUfDBd8*Ll2XtC{MW>x%myLvoUbiSZM}LT}F5cT-R8LUH1p3 zyu2Q#>v?C{E9-QdH+skquPW&1jC&XOSb6R7$Bi-8cgEg!oJouN|KQ*~*tEHc)ityFIq=V%@GxydY2Z?9qUAJ??>ZzfYm9*G-(AQz;=6q7ZDrkmkQJA-GIT@jI;%nbSeX_1HyByJQqx<|XC zA}6M+D}_m;#-VG81gG5RJ5kQ0XXt>tkIl+Ue9L@}2d!Ug*MKTu0nnF9#ba*D5r#kCHk#4_8?q-o)AuhbWnou1bDsZ!7p#C40Y_)B8F2O;Gj# z2Jk`vu+4VeSLtaixjywbD|Qb&?zeu2Wc`U=17>>KQ6-C85(d&}K9P#d^OTUsck>Hd z#XbNRz>MqE?a;wjpXe+9u+{(cb@MOW+8+7-J=(yKj2&Y_y+S!{s9Ixt$x@v(uyuKL zvFT!TgT%$J3{TWO(j%qkY??;)T<^{?I-jF|>`U1uz4;MPdi0?K6MLW1Qas~Zu}*x2 z1<$LP)3Zfpc$^tfQ~XPaeqo)m-^6>3Ja-K$xcDq)r}1xIUeadbE^lB8ls_b$gdq=b zS1B>kE${q{rH~NJyv91{_L^$BfCy6CD-JVj~N@mLpGZW!Y zd(!Adp2sa712L&ft_<{3QmBCpp-Kul4BsbtuOnMvPvEC6b5_cH={(jX`p4(rPB*_= zYX|Qt-JCW?JN_33f+D7O*AOWmkZ!xvecm14f#+>XJgP919ttl3zpPILZerF|6KW}HUWlimFV2|-En3v16rPDRRg^Zu|@1WXI$&vm~-(h?=xwvus)$OeMQKbGWnFq zSPEl!ckySLJ=|wkjy|({?CLR&DcOJ)0$m8S9HkIFkmi3&$?D8+^^JQg56KHxJuIUT zf{}H-$Ua$ zm%q+-$Mc-kophi}o_@{hoZiu!G$96b0|YIksGn0RhazQD4a*%-eB*^SvC&YP31z;PO|(; ztr@uKQTV`qVuSW>G{=UpMSd{5TQ`-*Gny!o)l=pGTG%5QfXlde!X#Ox+5jmhS%F93 zoh$d>LbtG--JkeOW%^3|kGl!idSk0^ON}yBmL%);!cuvZw|*H(Y2Qp>>trKL-r#lc zZI{~~T>c&tb&UH$>ljGM4J8*wMTk~7E`wv4Dc%AfuF$fh5p2M4e9RnFM9h4K+eqn$ z=8Nf_4QXJT#h0DRLJCv@*#73OX?y}NU~#m@bBkbb9*PU&BOlg7ZMmYamJzMZ?LjbY+o=GD?vh}=jw41};^}mIjbZzzz z4m<1DuAi0s;Dv<^=PM8D6dto&)e};WN6>;~` z!UofapR1k8swvn>OY5ml>kPXI&OX{vWi$}&Ih*`z61}gTb0ub+xN85GBY^psO<$0z z;jV1>3=Pg2%o{aV({b&})UTB~4us2R?NL25X&Gw0owK`rFa|0-<)Qg;Eg3GlnXtzkI( zW$cK#$VndZnmd~in1CJ5-6CGOjx$R!e5^D2p32aHCWvKLrw;<NavT>kY2}oRA$tk+1oqVhRVty=Ynxv>A|L|R7wn=A9}IjUtxq<{8A#?-&l%zFd*7THxG`nE zzh$?(^A#(dj={HMQDeLl&ps`rTAO_Gj5(O^Rs8R+C)JS*EG3Vk=chx+?{j_p1)NE8svfv~ z>TBQDi_y_jms_8^!JYlxhqRs_8ncx>4p|PTZ;)B`+lL(oLI=edY8=US5fA+%Y{DnsJ&%w_){ zGgCb25k_1?Tg2AG)kv^MTN=6H577kIO)v?nyJ>p^a8D}flJKgxJ%0c$ogzaSU^+1Lsg zT>CWze+o2Oq=p?u^1O(miVPa@`YI9KF}@ks$$CeGa@uu%Z{FDTKf(y~sd(-j>nz)u zbQ42($oP#J7dFvWeH4N=ORtK=l1XcQfLu_(amgh#TCPO<7NS>(+`&#$4#Znl zs_6)eWMzJO#eGtYu`{-|TH|e_!$$zk%WR(z)D)#ywR>}J`Z9)(IhoVtBe>hEZ;59{ zUO++=CyV`R+_=gRKvB&$f9vaFol_e7v#a-44u}|)+QCs1Ta?jgBEjg}_(eg)uPyW8 z-a8zsfalt__XC`WXL|=~Xq9qmw)DH}^)rW;wk;YYe;58{e7vmX@~8OevN~|76!LJC z-NNNACE_K03L42SYtFxU)yy^PR;%ow9_ay)_3yLZ25u;S4l_nYC!+a7pof^Dib?HAMp;8n6`G z)eEdzl#qHM)h&ysp4>;Z<(wsyUP$}~0TYf}oE!un6&-hmL}v)&Ox}0G`Bct~pDM+M zp^N%2ww86OcW+OB4ZU=M!8<8anD%Ra(Tn+$@|zX^Xk6puek+r&)3uvT3*I`h<}C>qhH_V8h_Yog}Xc1-OX z@1T~E-W_tip|@}^BZDn8G9^|1DI^Gp@1StJpCM=)FU-ETfAmsC^81kI8&oqB3Z8{o z@m1Jj*>'C0*CF%_%SxLDs&zW-_0u52+L5sTGwqBnmc6=_ZE82ryw#5`QLc}KY> zQmhMQX)IOCkP;!KzP=e4pdD!~#$%{hT56SKHg9me%ec=fez+UK8L|H0w%C#W)`lvN zce+9CQT^+qX~&Ck86#JNflAW%QK!ks-{ADxv(i52-{{KR+EeWSnKuUJ(L3_!``#s_ z%Sq=(NVs@|sz$^t>7SH+pL25F1*TsSX1+KD=g2D>5eO7K=ct+=G0utpx%c8d^>6l; z?zxD-FT{+Jcg{W1A!m!E^1{Qfpbp4kq=M^n14$Tp%+_-1q1%c;ww<(00Yrkj5LxT02P)fJ+|%&yp>0Bt-NYG);kzs#EV1bXwK4g;v2*e2=j zqQ<>pJOe69j6L_ZQ5m?G7TKQX#Zp=j+K2?l+&ag*WazESYlgE` zYdVB9nPVTSrTf!Pg2rB!q1#Ls<_!~0>tLVm$@vTMILBV>e--4x(7*PKQ=^BUIT5jd z(9}-!3IU4J5?%=Cc2dmUQ}%zQVGh&5evW@CRPKYAqxHRbjC zicQsP={6K83}`3v%1L`gy7xf#XR?))15J;TeSWCL+DgFb6Q=3;UmDZVxBt2x51LV{u&vJb98;js~C zWcq(w2&~czjxz76W-oX{4-2DI8XnAQ{l6~2ws3mC-GR0M%lIP@M=nB?E2X9jc!QtY zy}^hNF*LJHgWuW9p4Zr z?42`?UCgQgivothxTkA{y%pK+v`WW|PBdZrX5d_(eMf$RBPRL+GnKt}*Per(IU{6Q zUTuZRzLlhxrA_m+Wvzw2MSb5ruT5Cu6O{mDTpMb2_rz+FK?0M&JAT9}Kgo7k=A|a; zi#B7>lWc|DJkjwtRJxg2oNe^y=DeL6RMy}2-yMfyF(pIt&P*>h+M~Vhz_R>bZ@e!e{+yPu_hy4ctVUvB`<|a+IpMi1c={-tf zH0{4wZ|rVC@cmWYBT&8Y9&#s!ShOzMazQ$`NSpWcq(fB4iEcZH1I8yo+i#z!(}oSG ziMZ%u#TC0jN^%Vd#FhFHS2am z>*3k+hWLc-9VYVj^W=ItbBs1Vd)b4;rXVG;Rg+qMQ%ZsP=uj`*++`1Gr!C^d%5t5# zwx@^e4`IBCo0gz;a*^Fxl~x`J(nS}^CF1JIu!^>f%Ek6a>Mbv?!&nH&r`YYvJYbxW z;^`GG3UpRhEqIN-7))@HNy5uh@(U^xcMzZz=Ir+pH-nv0Vgy)&E}$4*rR@WhUeqd`6Kw)Z{jSz zAn(bwTS`uFJInZGCVrQn{7Q)QzP`4M#w=q|t|UY%;gz)Knq& zt(eZcE-F4>5#8V8LK09jA&1p4Nf43!%&b>Z5{X(bs9>0&w&v5culI0t#A`H0&@V09 zQMdIvAbONG!p75`XSXEY=PtWr3ANtq#FsunQNHoy=TiAgaVNxdc#k*NoEIE6*T(Kq zr>js{tYPoLQWth@hw$sjdllkF*T0|!vPw7O$in8lM7ls(lA^`{wCvUc)A{6i`~&7< zInfv5WTCiFzQ33kl&z0>Dn=vVNx?4m#{1G|6%1}zj(Bk}`t0d?>bgv$4Ft&_hT7nu z)1&2E>6n!01}5-h2v|1K&(0wGq;pT#lVvH;8tWRQkZs>x8XY{h(F3xK!bA9j1b{Ua zOt=kEyC?5wh&F2I-cR+XUXChv4m@e%(@Kcz3XzPsv`}2K#JPJz=ZHk5fh-h)QVPepKjzSJ(us!egi>&`@R>>Jrise2?(j-?bkm{O%RgoOFx)%3q7MsR( z$3|T*^~%Jpje;X_No||$#kQl_=kGQ-s8>SoL{?279W``|MOwR5wq31F^9mdNVHk*tx;o_ELiRGTf2m4S& z#AvWEQr9dzW=qLO zkHXHQb7R@o_vmmFOLM;B7`P)JXEbMBT@f{OQ(B-api#c4H#ySDrf;Twgi!IaA1B=~ z^7*FIvYH@9Qpv+!+}jb}{BJfzK=T8+Suu6_t~HfZJI@MmI7z`4<+!}lhOY3KY2%_9 zyzQwh&Tq)~p@Sp%+9#o>V5r~tN7UL_o+p#}x!CI=OQRMeU*!llk}1E+zI&9W{Mc${ zO}jLGh8T60>hdW%-sqBkA$O&`z(nkC$QGbM5jMRnl~2W{fHx{5ZT@EO*I#YKN)2Jo zYogi2?TJ6<=n+5aARa;nTw*y~Sf9;U?$-TMa*HTWJA+t#sqf4+2;+WZ$Rnqz4i0T9ld>4SyMO2i3Jz+#d^*j;`6!zhm# zJxqK7@B}6TWMSFRui1r(`gMSs=vUKxG)1Y6lfAx?dH6Epe+15c>2C+oO;6%^HWU`p zTKGRbOgA~_^awqA6hD8E4+DtrKm+bpUQid-44NjCO{7JbtIYu{Ewl9ByDT;vdN8%%6MRO*1*S=n;UF;uYYMPFU zX{S}ALod-Lu2f7RU3NFBf14eGKFOgXyNU~U*TxuUH&eBp8CNZ(Rl9=3q>AWXg=-(w z<~icw=o?z#e2zH>2mTUEAR1XTpHpjI$1ZIPcqRX86wstHwbl9^4Y3{sSWM3#f7 z>E^YcrQ;{?d*H;S1^lxatp^IaoC;^Uybq3TJ4-7}>^>B&K0v&?cOo>RVq%UA(f2$& zp5OO`|D|X_EcMIlxy>}>X$wLyka0zcIXzD3V*FOj19AIQW3vDZXKoyT1Jm05%oU7w zYR$D`G#uBpr3mC?O8Jh4@LA7d(8rr*D^!+M4yD;qPw}AL&lm^~(p*k?2)e@MF4w3f z6RJxb#GI~?ptt&AsEV@>s}2M1(><+JR5kR6TkZ-6lSqqtvk8U>zAx`lR@ zf8UPmnI5JBdOdEr(Z0fYefNm=Sgj;#;JQT>1`{0z-w0&X8TyFtkjPf53sR9OaSeVf zGMb?cqSu zMwHajxOy1Ed}2%F{+s3Sj8I(}yBFjujH7?>Lb|$V`^~Bs!&}qlUoiwY^UvQ_e42Mj zMIxC|vc8Fz7l(W&N`x^*nw%|vzqbV>gEw@bOaX8wSiYf(=Q_tMw=exfS%?`?!bSUPKB z?())=5viWgpC7O7Jn7Hz0M=CCq$~8TxB)o&Um{}}$BsNyTXr696?8b)3=H^eoAYSU z6fl@VqpTf(QfCq)o%7@X;sQI0=lX+K4l6zuVJ_oz;!)BXmR88D-FNF+Yy zb-Ihd`!nq}dDeN6KrmkMaZ{CSimUEkK0V+Wjh5>w7Q6c#x4X)Wrc=pCrk6~jf{dx2 zdeagU7iYaW09@~1+F2V1&5}dh`lC-89Q5D^yCp>` zmm~ql&_n1nZ>1Lf*2S~6bg;`>#g^}OH^LsI=EbXp(>d04V!vEr8^c)_Ob1@4?RwBo z&1#f^6~;Xdn4asOg&BUF(a-7VCuLWOz3K=DuO54l@d$>c=pO+3WWV9VfHO!PV|3G! zlFdv&fp!yvt)u2zhIgLmd(=d-MzAsM8d7^ESo2lG*(+6itGbfEf^;s!TK_nP=yjC> zZNeD7uqDCU;@}BikTT@`&|0su0n%6kMVOO@4mwgbR+JOXIH|4`(}92%+yEdgRF;^ z%sDpQL<6*Mca*VM9Bw)Mb>w{}Da4rex1x=4@%m)DReETwF{pqqx7>MK$p+s+iVMY8 z2kG`*ip~;77^IBFfq5Vl&pkwbV=&^)X~-%9uWyHHI*iA|=gv?Du{K*=TTbjRiCYnd z;R<&qyKeDf6wxh!`to{=RVm}&HWXFrYN+_v=F7Iv(TB6X|EzGN_2~O7%;;0#DKFA3 zNV!$ZU{?dA0PWT`UdRZ{f#Ls5)gjsysM3x#yK)a*T#tB77O1P7q;Uxb{>YcDnAwlH zRF!MD<2$T>la#e=r9y~yYr6@&+Uy}9tenecCC+A%VI1u}lh4ojRWy>aNDc{Pu;011 zaqsP?xnfq((A-+r^B?T{)T5Fhgmy#qKw?Ci&QVv6g)`@-`z}>(5y4JmjGXeD#W)=Bz!3 z))gdtB}M@)MKsH;86Vvg-t6lP=)Drz{~XyifuHs-9dD!+Ycb(kRimd|#y(mP30lq6<8{P5rT?Z#lPb7PYMRN4@l^9MZ}kYo<%8$3r0aezacRUjy-0pZs>4>nL=zkaFSWiuR(bZ3(Up>)Oo z=K3N6sSG;mm$vTL6CdGp4xN-`C%6&(cUkdE!d9^?8v&qxw@?Ji@P`0;nhU^vXZmSH zVmRlNvR8u>_g(XwriuMac`jr)e8ci%B$7Mxo^d2T`pQWHY46~W4qnGbTTT~EIk$@+ zU1rhY;{h?1R3BU7cqL7?iPoOgGbjHD)&npB0SZ znR_l@I{^L6c4z(J1{v7zx8FB`e|qlu;-#7O@J(Dx?9r}TV48Oj!G*(A{p8iYTA5fr z&wc+b-8kzQ&{!ZOs`Pd!SRo$Y`YaFf~GP>_Dw*}|3S zw7pUWx_u62bn%<4??tMN})TV$N0{?XXyq<7MqZRFX?2!+ENjhsdfB;FsY~U9 zw~<2&y24{KpfdIt63@_Tk3|TxX!##)z3q|qMir+zRr=>HcbQ0vDD#~L+m!;the4IX zJ?c37Qj^h0P3xM`D=N!y}Oqd(NurB4zcaqXzRW?e^n% zmD$tr|MSUaGzn6k=o$F}r-vBP*3?Zi{%W-ByS`L9_J_PR@p13F$Xp1jqq&$>X8BM9 z!99U5#&nrk;e>`=T4N?rWvfsL`pT=#(EfZ2d(^h1V~yCT{3$H&I~C%a>lt)!5BN0z z=B5~5_ym@5UDd0kaTP8&Wp#~X5*ClEHkI#ka^~%qi}2d70Nmo?ZUV2YR2#CqpR*BaZ`el+TLIG2@QDW8zGu(s3;aTjqmR{D?x@Rzv5Z~v_JIW7@q zEsx8HNIA!G8dqjQO+~qNefE!Z`+0gxXNP}T%wD)Bx~eu&`a;9nv(&?Iwb0Soy}I;s z>UZ!(t0`IEwryRZiGpJD90~9=`$V^D+$^TZ-)*bFtm)MeHC_vw3Z8Z0xM6s#?Mael zzigrGod>uA*jXz2$zCzM$mFuPwdS(Vf2_=72kC{NwkyxnJnX+_zlF{`6Iu5IT9L!r zG0H&Dl~b5$Y>o_Vx3ZoW3qePHm>Kwb+7yz0w9RB&z|pzTue5*G@Ufn7^gp5nYdXJrnpW);8zv&%19!y)-x*Jm1TzQV6pjI~g(O z%Du0XwwmALQFTV`mD}aAd&xb~ifFJ$M&;s!9g}a>>_bfI_6`j&-^DgF!b<;4z;|z0 z;|(Kt|B#O--A?Iv+}QoI&s~C`39|M%(B59>P-Oz=!GF8kbekr6kaehukcMq8db=KE zJaBI_pPOOGGN8z|NDMxbc};Eu{s?V+LwLQ2^T?c*~5A%SlibNxA)PM>1q2GTO*8pb6utWunU9x73aMOHv z$28`Cw$uqp(Z;w!%n4E>1$dl#%w}l4!%V2(OKcSJPLhY4fQGt-k*vR3V5Nx`+EdeG z^?V?6C4Tygy{LoB7(eq#~P^L*|8&HoDYU^bh00MAjgD+y5(RfRF=H)9P~ z`H~ zCIvu_FcdcO3_>+)F$S2L1P%Ltc_{5!OLK;hRn+!z;Ox{UxUn{-*uUSs(;PMN7_=TI zRptU7QmEUFDa9mN;2cTvW;GnjfI1>1_JaalLYwfIUzp5xSIFe` z%F1|WN;Jtna)*c{Rzhv82c)nw{wUfp*sy>bVkt_fdX0WBnQVEGtqi;r2rY{haKw&vI7dz{$GMgE}o_yk36!b6;b5A4)`~K@l#k^dQ7P@?8ls23$#`g*(qb;xSZ$2@Tw?I2@37KmGNz zFkSwI_J1_ZGfW1~L=WUbjiNOS<>X5+y2a~7TLQ@{a~##+w&>2)?t-0`*jKUzcvs>R z=TW_?^2y4IAPFFNNzG?E`W%R`)wMa;o-V<)%2jcA9y~bCEk8|3SbfP-S<8F`HN>e8 zNvk%tHG0E*`)_l#PRl+7>#!BdYbzJLUUR7lifjt{l;h;u<)3jYCTu+vZB@BCgHo+m z8h9_Cp)q=nm9q?M;9OVHS56E`80}e`CaK^dKPfVw5YlNqVl};p8SJ*9RMmSq13itLPJMAu zcZxztj*UNF7%DkgnDDh$&dJDEo*8;XEwgbPv^;>t>4?4J`2gVV#n~{UPwtBT=KAe0 zN4G=kw%iXj>gS3{`D6csK|b3UK<$*=^3SEGaEE_luV0CJYo{LMC{`S zDIbQ|L@EJR^3))F?a>MUfP{lkVL**G5uT5Y^j$HlV0i)U7Fw947S`#pwnVH{R|*`9 zqzrjI2LbXtr{fWEs!7Q06`R zpj^Wg@p;*iZuee=cT^`Ge6*Lt#26viaoVY(_OvSS2E(8lK0af6m3=HHx>@^u9yt@5 zm z&TFzaxm2yZL@KCQbft%s&w zW)C#D%*D1O97sUcd6uxnolLi{1R#QyBoVsC_&uh|y*P*R&f|X^+n76bth(kS{fLhY z!N;BtqV8Qw53j;pwGR8cf0~Vdo184IUb?v=C%&k#G5@j~d^!&7Bp;ZVU5-KP*pZX1 z{pF;Y1}6B}*I9K1yRNS^0W-BLURIT#A>n)2rdu451wQToBj3ygy^(}&lq10*==IQ7RI;L@tSVj;ot~ywOk?pRX&G6;U)AD z$@2zp=H5hKFGUKAzABf!k(dy)^oeIQ?=u72f%J3uc*wJ6sx7GoJF}aqm_gqr{*|So zFhPz_@dQ0N&>t=Pv~TRo8OG~PX&26PO{Wy6LC)+SwwCay9M+8AslNa3AztF5?SapPs^=0T$KIeR0F)aE4! z{r-x@kC|A>wO{!t{d=CFkQP}st$pO(NI4rI^8IMp;&2lD(aA4YxFRjm>8mr%?fEz; ze`-*XN_4~SA)cN(=gJ&D{>}Dq-@G~Gl(oB|;Zzxi{QqSEc8RiVP6;E`u6<1{`Atqf zn*l&A$>NBo8n5Nt>VF5CBt?n~l5ivMub-n}U3XeluS^h@}3`AHQ)^^dK-# z(rq<+Rka~i@Ky>l`4~ouY51dtheA5Gwf*d&ET3maD=lxeCY)x)y709T;GX&0(>Obw zjc|_J92eNdAikIwJvc;amxs+n1W=wHZ=fhRN{`)3LC0YX5~sn zL=GmmrpMJc82fo8V+HUQguTD&z{acg=`~>~akgViJ_6;PXkJZl4H*@Zkc(sy-NPns zFHE&2z5g5M*iOiA;Aa(#=i)8pm$)?hA25?u;}t9T$uUATBa;iYuSq=TdrB~5=j}LK zT~=)Mgw0?kMts5``ldX|^B^98)bnq#E76kyb@nePJ4SVz3sRdyTj8QFV`mHx(*>od z2oWNW#8EI;w!4avl{$ZJ6Ty|vyqNg2+^i0+euGssY`JKJ^z`rZkTiC(W28|FtkGlG zMJ{ELc8AW@x|GZ{3TKsSRk5DwKj%B0sByL*c#diweafeE19C@?lSto-i!Z`e>9~@P zB9Y|B=IWbwp9Wg9U9|Sl(k8&UvdKG?LB&JgV}94PtW zdrst8=PcKDGqbSuh`>n+a|oTP$NB}Hx@~}cx%(U+j#W$k&)m*#+kVn1A{CgwfQ%yZ zoRbc&2w4zsZ4GopQ&rPhsrmpCn05@vJ+Zl zqQSFy7DMSUIpN(AARf(<{2d)(y-GEO@ZDl@wQG#@dQo}Sn!tx?1dkV!km?wf&|P7D zDebir9GjAt0V7-?gMDzum6!T zd)(Jh;LV8NMf}0uJTmU@j{11}NB5QyGy1vo{(#A;Zex?(m%~Ltpl8ld8eXsIF|^_> ztD~iFv9Rq%HDdWRZgVPI&vQm@8>*;ngqN|ly&QsWQIcuyF;LgW$*7sJHEa}3xUR*s zdZDHurVl_{*BG|DB8!URys=#*x~k+}#8Ilw7kZEl$bi~N4fWhhj^C9J%bjDTJTZ`l zj709YS2#2OH!!nmV@z_IEf18Y_StX7$J}70mkD@F$3xq9RA8ws4-kSkAVx9cPDWyQ z;<|Oov6=NOne>aRKJl%&MiUhff5z#rS<0j#wUA$kb7-dsALWE=wn~{T%?|i8yJI|^4`O7P4JrdZJVJ{6 zyvIiC7FXn3YX1>4PdVcfk1DR(7>lHn>pKkILpA3t()fu!ZRyw0Lye{LQQXmnPo;GZ zeKi>)Yl@e39h$j9(rOJPiH{XMfsP7xI#e3 zHqA0fxM?i@W*fdxX3w;(IoHXXZTlp%f)U$*dQ{2xCO0sNxFmaO;e$0A?cXZxwH~^8 zxeUoSoNnDY4LlmAx64n%Af_1%<3Cav%-`I$y|NgM^HYp1EG+`vD(zf#l1l8V6Z4mU$6kF8MA4sWX?u5)vo{ZuA9lDh%WgpP6E3X%uvk zGQ6=e({fsrf;7ti5b*`1tb^X3qpnAbU~IyCPhr|%cUz^U)v{F_oFI?!&PB)*?ho6c zpLW3$l}Af)6-N0#*>m17M>_IbcXjq5J`B@Z=H!-$41Hqd7%OTi)2rIs;<1%aT&?n> zr;J?=C|k*4{*ln24#XD7;Hl>-0fmO_I1f>t9_q!KA4{0%J_@@n)JXHBF z7ogHl9avWq<5U*YbtF%yb+YtK9w9mV~I{3;3^a8#?(y9ze?!pu3dOuqV;RQv{w>RxcCW z=hylK^qy?s#3_F2P>W~1&(DP=N1hZzAz;1H1yC|2c9Ewd5{iom#m6IsWKk3wIhi!j z(<++XJls!xs$-p$;Eg}r{69!0BkCq$F~m8NXmi2%&XF*IGiSxDuJ|Gb(*N>NpT{Ct zA5b4RF|gbB^H$bJ@M!wZErs8C)L5b1ZX7H?%HOfECBxW7N->UZz-IbAU6C;L76x2{ zZ#}06je#+X!Y_*0H5I@@E*a->KXl{`E0H5fmS|&2b!@J%t%Hd~srD6hHnmzwNo!Rz zphBm8#Pe&Ew3zOVBRQ&tO@jPZ*gO~TDAwmzqlp{3jW0pk`p|V6ED7HtE@uKe z9uF{0<{wT!ulYgv30l zdCAVUBKX|zeWv-vTg`80mP8r5Y)t7cIeGMvIW?-1g6$oB-5E6&5L zPH6Fx>>X7kHOX6i2J_{@QUpy0_5!eN;r=XP<4dwNjLo|Swg)`*N7MGyULSoT5W1L9 zz0O{p`0DC??VVUQoUxY$B+)I#+_}t~kdSEV&3_(on}MWplgZDeoi+ZE>VE~YJ|)=m_)kLV z(zF`>;9F+(-h~zgCXN=a%fn;|mX#~cm~I6+|8w1&k9dc*_MqckU1$OA#*yOrrP#e90U-3a zN{G1bTPu4JVbYRg=>L7%dTG%X0Ygk z&6bHFcL@c+{ty+k4A3wiys)C6ollTJ2)`Y~SLbYFbvb&{4Bqp6$>{LV!NU2ZG_I{- z{W8s=$eGaJ%l;A0u*NRO0H{?x(p+fQ20piLdeBOO29EPw?b6FeNA4f603m)lq=swj z*8Idaz9!jMi@vNxMOxeo~@4rrn%cfBa_e(Dunt4|V;E2N6?n%Yj2H z-p!F!D{l5*+V~?89B|?44Tb|%W{jzbRT<&%WMvV0R+Da#gj6qtI{i=Et+7L=`t1KG z^oPBV+4OXKvqfQ?KfS3;SqzYiN zrnkr1j(Sp|BFU&zR`HIOqdbQGl96IIc;aMOA7COU{Zk&F+GU@1vk?rY^k+5cf1aGyLKhsoMvgJpY=6g0T5^I_DD~EYE-JvwBW) zVuF9q41ep>s`J=cA0ax18=ZAXQMf^8L^!u0C4W{?P%&AEiDID_th*^I(A#D+J6ae9 zgv|lwrzVE0g3N zKF}707n{Ul*%w^zh@-yXTIxSMCw|AY3-JjkK7JurvS;APFHvM>M8DtZk2iTUMF81o z*KZt0j!Ta`Nxc%C*8;OYyaDq4=1(i$%|q;KzgZX4{{(IjlCQ1=gb_s(l52js6>>Qc z)QxDesOBj7#46_mJ_qTVqn`279CKXct@vd!OX63V4hu!Y-C~Jz=l589A~+BG3f<4) zZ1=fe5gJZXhx^a>Tr3Wi+!d7znES#r7wC%3w#$9D0p*m6Z;S|Pgt(T1GqChlhNfzR zu@`!#o+W>LS!x%6I$aIkvN(W_cB9Sn@^)jBh#)P{wyye89sUFI%mO-qfXPM0(a6tM z;e$(lVa0z=0YAU)OF&hG5<#|oHlJmT3LUcrNPNq=RnogZOUw1Zu#x;U=*hXgFPMAm z9z)Y=6XcSX7&5^4f_ayyiYvk%yqL7k=z*lKvvY7XD2nP!t$~keUJ;p@To|+Ims9DA z1|KYJpOln*O%ny=L-i_-?8W#WXVEH=H)rQV-B^MFwm2v}F&k}MC5`F=3;-0&BHNKe z*{hh61Prnq7XyW1W*{^0cjG6uUAs>tl|%$^BgwMpyXDbiJG2U;@kL zXM*TJ(HpPtsL%zp#{q{hpAH&UKbb}`wC)nJU*Gb}^2IMzj3#g<8dpt zadP#m+~}68e9s)&6NqT$Kz=ZDV_dy%UvgCKis6~=9-*~uK;EUc`{dG**dKt6&415+ z@ll`kmdL`%4?`+{wa7F{g>c(M9Y12F8_#=i1^#|~;f(UluW3s1 z5I3I7Qg3MASq#3nt(kWrgdSPMEHgri{U&TigH@B2*_IEbq7H?5KMbnlcv0?&jiocc zf7bOtl@D|lG2LH6*k!B{H$|w$$>|zPL6&S>-*QB$-t>rjEN9=N?Bo7Kk4P`ynwia@ z4%;|U*DrSE>(BaJHj(X7KfvHCT!<<}`pIg^uW9DBw_BdIWg7cl+xBJN4^o}#M(6(B z|2e;ql9L&8zR;)x@ zcmXP~M=$YkxW$L5(7Hg^vvVEsSC~nQONFRxuCz)!mCF{` z+TfN<*WOe*MqvJk{2#y)7^nv@qUhw0Mi!&;9p9U1R6rtrGZtSS9#ITJaX+@u7J#O+JqxVVD8woQE$_!-D;f;Vc?`H?-SV%4bA zFKN+UCB4peGBE!91>?4=UwI%Z5t ztrIWpuy`h2aVRSzEaL~-aZ3d7fW?h?WwclI%Y)}Q=w|%ZLcTvyU6Z{3cru;VfVh60Kx_0fwb{ zSDQ>3d&`fZ{;%q~CNHf=gi&e|E+1Gbo-;)p(?e0$B#%mrC$uS@VMlNxIXQQ?Q$}_I zI@lZ62xI7~^V0vNWn9tUSM-s7mkfym;)N;e`tOl3adnOXPIhDe16RU7)Ns{3Mq9*w zokBK?xFqhzX57UH1u^$3@h)ChBPcao`Gw4B_OA2ChF(6piv@0lQI4Bnu{vNRBrk!Sr_Vwk;rL`qDW&s&&*y$PnM z%yY`&3nnXry-Wvzfm?P(2`D<6s}yKUQ0=Nv74dTd^Ui;rAjbwL?xfyc6f6!w#DqVi5?3`3ceARGDzfFIl)St&m z-BN%SChbEr(LZjUUfH%jE`V-HDPfuYP?Bq%kKxVtTYjqyODa-1JA<-1?J}zidU;j7 z|M_&J^p3B~yVt!tIez3;tbAOfC7V((fytKO^>8^Nkrs8NcN|Qb05kuhLUe@QDVp17 z{&0->H9}Z|L2t3NZqvCsbP5ea9W(uw(vSvaC{%`~uXTxR>4cqXe}Qa40;ecFc_{k} zcz!g@9m&@*KhG612J^r({cyg+2DfmDh&k2J>v}O$V3fV76V^z8$VfXdGn;`tOiSP> z#>P*ug-NIBYdsu(#$RL zEVp7=%LzG>w9|2?XHCBaNOl=!oPZMo#T)ZjPJliB3FG|h3Z|so43u_g);gt3s%fvE zGQf8mm~qh3jpjE=OV{;bQfFWJjqF3s^=53hr~aBDQhasq=;cetjW8PG$QcltBmB6m8@U+uOX(lSJENYH>P(EqkBUBZp8uhwsHIr zc$d1@|^ zr@}dJtDqk>kgw4fCfAfO8>IWmE85^m-@xiVXpO4OvGBCGgBI@I7@3Zsy@&yc7(w|X ze^!v*ch2vzdi9M01)>;ex7Bd8JdGS4p1Sj6SP}^6k09|1cfVkc&@WDM>apNFsN9&( zOX7pR~sP zjp7H);e3+_BHB_AnBNiK(N10*pM~STwTH0ST;90| zdCR+v;%#(cw7NoD(*Kpy#ZS;$MK)XUWlS|HlsJcRgf|! ziaNL|Strdmosc=gio4P;sp50x-@zx9GWecb!c)RhbH*mRIj_=XFaBc7|A(UVtw_JH zT*6@*$^II}&=XHvIPlu_`4u z`Q78IzGakr`<>gy9!kq6?9du2AA;>4i)d=*sR?O*f$!F`w;)@cLA=H#vTJ@FZ!bOHf9M7Jl%kQn;$G`*hEz-8P$9xEp_p8-BcP_L;Z(#e= zWuhpeK~fQP)kwgTP^WQx)VG;aLIhm2kMCgX1$8~j4q4$4YU8Ddj`Ht8;_G-T_T%PE z@LyQjh9LYR;Lb}!l3(F`J!9cn8~SbC_Sd_eVYBmRcD%d3p60F0GWv5dU4GCS@Oy3- z)TS3bukhDEG_0frwejo2v?6i0KIGy%?S_tbGjaOso}3=++z&DnPDWvV9o#S-B-+Vn zd(aW+)clp1^Tn(8yNf~5* z46;5>jP`wj^Gw>5n%a#P|0OwuC)o$wNHs>uF;sx}dnw_~@MpE|Q^l)MMghf>&U@ED zCSrk2<#Oq;P$AC8%co&8ojtcXxJM%+Dw>E(#Pn;yVc-Z}w$UA)uc5W`&i`Xm#wK?7 zi4<&zoF8*0P&mG`azzP|8Ycki$HuFBCX&DMxV8|8+VjM;LwJ9gm0Imn1tm6Cjmpl% z;xam)!9=b^K9+N96^~{vkyXmjE#&mx^b#u30I~5T)-GlI_=e2fbcOm;p8X7#%&#r{ zS&uky$7g-2YSG@(&#dFb9YaKqR*Dp4o5)CKt*xjPd+RAb`<-j2UTL}emY3k$I@L>D zq|sdCw-j6i1sdTen7|kn-)Fg5Bu7e*1@wgtv0TlC}l^U5O9^6f41RMo}ix zzy<8k`c$M8P*vOaZd%x=HeJ10# ztX~ajV&qhvF#x38_#&zpK4O%5d-;GgyRq~@43tp32=R4Ih$-J z_Vmi*!F)GHlw*tY4aO}#su-+tl6bAs?!MnGXmqtQk55rhj=dwMqC z`WrNbLimZsADQVzkEI)b=dTPzT0al zdri)*A76z3i2rP$YTS0y3LG2Zx&9!?&Xy#D`qAlBA!2vw_fGib%W9uEe@cYL z8CIU5js4x?#!oHAIaTVLSBTI3X<46q3AB>{0`J@@+ZM#P^4YfT>>^?3DG~G|#1KFIXJQ0Rlwkap*ms0kKD^@8GJ|&(up%4=rUlvX!dJ}hfIhaN z@n;ThSc(ET21+EvoA&R~GA)ViJJLFGpiv6Bn1=*U>~&Syuzux=BWVf&lGN|R#)a;Y*V2?q~xzJZ64hMJ~qM}9^9qN?$Eyyp67 zG7C@eyTvGC@8X`=cmzFamA)!qR%`L1=MwI=xR?gWN?b7CZVtQuu`TM& zY?g&KF=Pk$xYe?MKRJI*G>x=-OStpBLH&L1CM2S9Ga0nWqu>7W;OVC*G8V$Mf=CQP zw~ZIIqzuho62H@^A428%L7w7&=xH2jEn5gtlxI3hYo3BAw)b46)aDpY1oON#L`x2D zJh1~acnl3@krxA#lxA#iO~?I(IthZ3ju4e=T)lrZo9!d(ow7sr625$$_529-$~L%s z>PLzGIq76O?gB(RRbqI0uNcVW2J3^eBtjfO1Tp~F%niy|Tp%v7fz`T@%YPIuF zS&dVBET*ii&duDea=;M6n*fD?2KF@W*3su5e_L~8fP)%ctlP#@W$x}4#WwbEEppHu zd3w{08=b)PMz(8}oyXBvB0*b3C!p(^^)7Ga8f|g~-{&X0(YdQ%7wB@Cn%TKmEU+t{ z)Y+aL(pd1wP!+3im{vZKwUNbCY%ce(*CWP-9tHL9#m+z9Lj)T~-a-;6C=RO2fNhI8 zw+rp;hsA>stuy((WLCzb04ad+&ujO<*ORWKSXmFC;HE`#e@a%|j%;O}&Djh2!UPn9 zLE5k={zvy%p0+w~G9ug9Sv6UFdTN~0=$f0qw;HA^gO3fBirar`wAGSA+arxvUcW%j z23x9~7gfB1t9?q1NY<@M1~bAVu^g7Kt=c9VR;>_+Os>we(M-lJuw(7uJ5KdlJzC;E zP&sa#{Y?~*pk01pqX?q_b;cR9krVNsWt3mf;8kFc`GcxaRUf7WKTR$9SoZ@^nj2N% zc7mlOP1og#@Gqca_#%J13=8pqePLxdO0S)ba=oUm9fd0RF0WIJ&ntymb8)4l2;S=N z6gddG{GzU~h))jZXBo}WF#8GwoH@6Q6ZT731Y&EA>E=_-ZZS?@uk~lwvuYp>W`E;k z^-s2fZC68~E0w{$rC^m3xzWtPY+|HIevu220Z-;nFs z;09oSlF#^Mu-Vy8J_;ObJfp0Y5_b;&RnQzrN~6>;pivOjZui3O?#jkuI$?|lP{ED0k@_t2( zYcUntjS}-xaP?I=2sq*KjOo=fwGV#VSVWsI$a;7n5RT7Mmzyz!xh&dC!|xUD8=SH+ zKEgcmC*}^=+#pRAR^VzPr(~#C-N+*?V?z+zBnK~5T;}zQ58qne7m`HnhSpF2u#;aG z?~S!>NWCTpV>JQDi&f-o9UFUD?e4yOJ$VMIM5FOROWq#*sU$^;V*B{W!)WJQ&DobO zJE~4xs7Tozkd{FD$zkG~t{`!}zr*sHJogrLM4EUcty|4dd_qZP(^tJ=d+iuZrX-2> zoP}Po{D5d*E3Ow1r zOMK3wM7OIRDU9X*`T4`{=e(PEQ~Jo6jfT9Z4Zk)?-*(pO4;kDTbdqw`JL^)|(*vsOl@1^(9!MYyAyU9e+A z{%;G44tR9d@wh~sM-g{)TJx#jL5OckYme!nXctTmm!)#^!W<%2*mCG0&usYd#{Qas z^3NO?DVfF9MC?Othv&Va`{X|_>X;FCK9MD8NioQfD1HtL6UfOj7bn~|m2_E1A7I{pm<{Y| zSX6A~di?bK-@DeVBo6kA*}xquIQUJC`0z%8X;)EV`K|5LfPaFO!z=(Kx$E^n?zYaA z&~6?7wRo*ifi;`yjGc3!4G}#=wL-94Z}Dl)!Wucr9HdRiIeC+Bt*O`4DQjqnJpC74rKgb4F6a6BmbvZ>VNV?&|=&JpmmyFG}@5LOR zJooH+qMz^7Y3>TM?5au8?nX#@&kM}^x5Ea!5jSc@!0L$a(k}J>Yhi}lz1ef zOM@W0Y@oLh_PvA?%a`+JbADYfOtjYKN-wQ^MMvxka z0tx~u0#c&{lYyXs(gq4hC|%p=lCVGpMyOyB7QG+@MFj;3iH+`#_4a#we}3Qpf#cvf zw&%W|>w3M;)82{mfKN>8rr`kz4?(%lTvSI75?YYmY;}utHNWlXS!}h8p;pBU?Z_I!N`ekjVWlY1cg?dMG+)vSXo+T6;B{Iwsxq?iQ1 zio2n&U|+>2BK3D_>W$M#JZ^I>2riZZ&wd9E-K4f9#3X^D2HWT`f2-LKxCsY#Nu>@p zd(t>EB(dx^Xk%aR0OZ%=(vO`TvxDdhfTY#k1rhN=eSOssrW#8ml(_7^*$@DkPnx}* zelt3n2w|Za(t?b;6Md4L@=U{zoR}EMAZ%c3$pD`uuN(~J>!eW?i%YamhEhcX?!*t~ zEbgRTabuWxymUjl`_>lvloK*9PPaQ_8)>Ji+>mmbEg06gVJ&N_|!=&G38XN!UFqil8}KU zELo7KGVU)3Ew*O?^<_WUy+77TmRL&{Z2jKtfyBmQk7z7T`Uo|vRM*Hr?KN^Ae1w8`KR`?fEGwV2~Phu4`>vg7}qwe2~IuOv9*;FlB%`keB-fCo#?A^)>~9O>s4q% zX2X~(Nu4Y0xlKlb&yt!{Hv&$Z-%YXi3?sbs@;>p_#}fb18*xUq*On!{O+6F?+t7vP z3hz*#1|`{6o%F}HVnuF3#4nWm3Ok!62iLcp1opa;+`)KzDn?En0068|j;ljnEByEa6GIsz?{OW^4y&vGWo#{{VgXhTkf`K#XRu#Od zIO~(17F<$~0r$+kwur6>U|65P{K)za2B!^>BNaE*TiI0g{i7iRc25>704LA(UjXK& z?zQ$7@|)}td+>v>dnIx#V0Z^8bL6x67t}&nenc_z1D{ug(CH zQqES1;A2xWu98t}?8VD;=_j0*8F%Y0_xi^n$)v$rVIFS*fUhiFZ_v#NY0XB%6&ucxwl-+Q9`tI#vYxocLQ^nkQ#|sX=D5Vmm=OHSvXSB0x5aO-tb6 zYvgr4Yf@ZW+Q(}J$7@Qaq`9~3KCWqNzJXbreAbnAQt?c0SVQVgpqQ<~EWm0H*yQdH zc?!^kTSs3^wHzz0x`9R;2j9Ieu08tzApP%VT|nOZA(~1)K8L_P?braEA0YH-BIT`amHX2$tI$6vvZja}j?#vBQ zNvMZ+yy+%+P*~{-QRY&6?v3UDDc@E;O{`$`PJvEVtBYGh170v%UN=Fesb4-l`Zc;2 z-2;&RXMKKd$hCMBQ6s;wgg*Gu6ZjO3FdDK>yMgyMWb-6R(DTUhu!4sKr$Z zyB6RkI!#8dB5Xz8S5(V$t)jfVn!Hy^Ia+i^XNWs`Eh^2pRfWrDDcGGxOV~+H*SXIR z)u413jul+0Mabb3_jAp99mb`+^7|sbJC{(MXwQf2yW%I7wvc8NAm})U&QzuGmwST0 zMLQh=gN!Un96}O=cL&u+>F~JQrItlgK`@rkoD+7Z4jI3>QvRKPGs{6QE z`suG*#0}q`aLSQa_9lYW*Q716D49DFMOPg2Vsp);N1g%G%I);6v0;<RxMjsg^%{ z-@xd13RVd`|KT5DEE-0ixWrjevIsQ(8zoO`u7Tq7$?9sO7pG9b%10-1nJpNV|BaBy zs_O>#rL7;5SidkKeKL)*6&M?BGNE1XO^Y<9AOh#_zQ(xsJ~jnEM}+!?`$Sz1FG1V` z)rrs%hJg?6*6}p&c;=fad&_E^||;UKnBJ_c4wa4oQlE^_JOXw%GJcE$Y47&1!^| zD{;F>Poggy_TLVzNy%%5``B|gFGBvMgJ1yKg6;4t?i*6-#^|9<0YA8i2+dWX%g5_8 zD@cmwy6yhUNdfPgP37Y@uwjez<6l{Ix4gV}?q}P4rfB@pQE%(W+72*a#)@N(^_r$g znBzq?X_~-mb?j(+$2+$-Y|d#o=WWN*fT$o`%nLhSCE}85OpmERIZ_O~ChY(>*QBb= z)9-z6qwNG4K;WfNxhG)mHZ|Al#cy(EOpiGQD{`b`({um$5r!Nl^q2fMXV)H?**CGP zSNHPIt<9-lb`mxe!-aP@EvKLXQPAU*hH(KgK5YKhLVy|e_WWIToN`$Ic-{0yGfy(> zYaV%IjQr{grI;_LopZhAbU{@3DCxaHvNAGnp@TiYO~oG~luVuanUh2k5ip!3IExl+ zCurhZrr_7ZTP4yibDZtQUx_);ca+WWO!#+m%wYtV%}KN(KHRDJ%tF!}8a%3BA^IV` zaf_awM5LE_68%9w1%U??#6Y0m_;)xg6oeUPYktJ=X)?d*9T%FG5BanZh zp|<(b@{gICCl4nMQno%w4Scrzs6M?y&#lLJJM0IbBA3pFIP01bZg;j7CPBKq8U=aY zwoP!JEor%Fhn~7f%n+8orq>PG=da%3j#q+-DxEO2H(}1Wt_v8T_etzdD<&cO^R*&P zBONoL=l<(^7=bj{3!>ULD<>SS<8DnluA8tY7q>}e_@%pP>oAdLQg03%RT^}hDMEOe ziOTV(X$Z*$ipc$i1|7M7o$?FBuU{iIo%@X-4S8t*atD#O*98}mzdD1~Rkl@~f)odE z7sT~=kHDgljixXQz4^ZD+UHMzJJiW7F!(N~G2UM1X8r!7#i00u!ChJb!Ftx&49Q|( zyXH`N880&~Bb=s@&352OUF})F1!D@4Y->TKKv-}$Ix1CPw%Oxwu-Nvq>O}_?9^pVk z8f}}l?E-)|YGU)4&qkLwGLd94u_GE|Vf?sB>&~U5vcuTTv^pL(QytBIVJWsp&x=Vu z8^3q*OB3$``)&02*PB2FSLn;JMsWm5uoFWw45OQh}&`H9mZ_gel-rR^p1T$v9K={}B1t){;?zpuID;Z9s!0BBcuxss4GaQup;P2pmZ1#iF{|GT879a;Dnv zsIdd!=!?Ccl&ypN9O%E#p{rv+5AIw&y>@}(=*Ni!;1MnQ+vH4+waD9Z$tVerZTuc3 zneUz_0$t|eW;KW2>vQoNO|tb9%giTJGwvM7HQmT+N5=iI-phQyLx4T=_ceCK*E;gf zfzK)l9e1#awfVu;Jzbm$H}$As>Iux zc3PJSju+F`=3kW<3_MeLbhq5&2B?1qv?J10kcn+jE=osLCHDvZbW#4D?>9H>TC!fg z@S_m$Ea{`Q-+2Oa{2cxDSE$hs9O(Pfp0Dw7s8&TB$X?3@1QR%gGPM8vg#2VFBvTGQJ;Ncl>382v2Zm!JVA%HvA7FT66%K;Hd&nVvrEaNHbi4!crS; zs6S{Y`hL+)bt2FO@0X?02zsaz=qA*KAAW^UNm}@gD}I*$2tGE#Or3K4v~SR%##y1} zZZuv4DKuzob4Wkg|s%C<`>H{=BF zXm~S+t3wk8AKkv}X55{vw|u}Y?=_~!Y3J}){)^{z92&+u+sMNugbtW*>nJ z0Kv|BU($R{-ETN0E(Y7ELs*T2LR@%|iwlp{(;%Er;NFDeSEiuG%I3?1Xr~Fn{pXf% z&wW&kvQhzp-Xck3d1tawTE@IdM?#RpsS_IF2eGoh)RX z!>l7`KDlgFsK6}lmYsmM3Zk)2h!R<~MSEg2=f7@Gu4WnyJ^GX9#4&}exU6R^Gn^vB&ffWvXaKOx)~94C?F*ff zP&e#&PN0r!F#}4BNTfN?lD=l_+|)uW2A!%~6tCcE=ok;PR?5BF_#e^Hc2g0!EIL_m z29FYDWI7icss!|xDB}uac(ng+c!8c;BsPJaOncx1KD4b_X!~W;a{VdD_ww1wS#`c4 z-S5ZZkC;~s;!0@RdW9{$ssPrJ=dQ7e(gNRS%4m4~TEHpW>y&-G4fOQ!3)POQS4sz02L`FX?K0=CGDHJOM7&yYM{gDTR zK|0ux^UL@dFWG{#zs@PliW;3VgNCrx5QE%&ZogAt3MYdX^bx(J*!7Or0)dBy#`XdO7$c*~jP z!Y)>)gov+F^;-m3%zplWYuqcaBFA;9-8J{|!~EylBhQew~_P)l8z$;f`Xo6d5;@AtTqQm`~GTS6fZEvam z)6|1JK7K@5@cye%IBZHnS8dD6W!wBpT-(liNG$OG?mTxs_`J6-^d#nAO|7%>U1?9M z8A>E&Ct{fAJp<&XA%5BVaR#UHcWEzDMJa3@28%OxIV2Ec+*&ShjG8uZoI(t%w5r(V z#hIIL`RM*M-p8izs9~_&dknXW5pB<+I55Fj!E^vJ8aa$hRGwztG8C-g zaoXrfOxFW~kgr7p1j1vQxe?~WQu9y9bt#`K&G9dT1tfUtr5uxjca}0D69`jr@CgC> z*msPTh-)a@1H65{e(MN7K(Vq*AyA}OlvJ}5xYo3{w*vGfB z_6KU8J$HrY1CU_u&Ec-(N3b_twYguhpetq9db}{qq{x91m1%+|lIZi^tRv;xRjHQK zm(&5Su7;DZEg+`ZBjf#WBn4SR6oP9iJ)>UTK` zJQry~&o`hM-n?v~I#!DGzyLYeZ>VmRbbR^5kU5>xNbpj6zv%w;o`UgaOdB0<89yS# zw|fG15!vY8!7H~IrC~ZdQo_qb6<4CNPE5Q0J~STTEE8bX@`G1Ye;Z7X+l;I?-2ftK z>G^9Li5KI)Y%N7GTSSYGi(~*()D*Nfr^p+my#AhY(BAFK9rty?kW8?sJctb>LdbB_ zP;>?~Qkq!Ai_S%AN1gnFEjMnVk3a9FTGF1o5c4NsVwneOGTPdBtY5=K>g-xSTeLdR zDB8go=}~@*FYeBUH~l2{E@nJ=VSni=5@vWQ^>m)apWevtL~C2{#YY&NKPb0 zP!2E?9NP>mG>I_Q0Aa(<2V29+jJacS5+|k!df=mWt=@O+4L$-FndJ#nQm*~Y-*iXT zDMTE!UES8lBO-pwnjvl^%&$}Cr8cc&F7$Dbug^EH#aKwrZ*;h6XC{6RNSf)f8~a2u zM1XlO1*wifFZ&d#T<8{_;1d4fATr1t74rOh=x5wW@;Vpfwn8j#ko6`TI1bi7c<=B<)Vvo>?KPp?B3I|de_BV z#Qufw0^PoD%CfE?i1dezlwQg*kDz@nI>^;ycC^95E{%8BZ|7S#^I=9ZUuAfYGY)jhX z&e4i)l8EGuX(nn;LEl5fTrf|g3;PMY`*kZ40#)8XRz9zwxU_ufdegoOAgGwTC zYg%QC>M=x_6jb7sk|0!wqHakR>zzA#bn%TNn6z(wLP7(jJY9tli0Ee9bK)RfgGuaM zsOc23w|yEz8iyj#B#3`)-}5YvHYczKBu>PjA79R ze(*SwO2O7o9Ba04`i~PC9#&#XIt3h)0I^nSbb5{{xCbzvwt{kaIwZ06mtU8spOl7f zJyfo_R$q-i)iO^B0VuEkD3PGemkPzdu!W+V;1~;YrY>5h#Kesz9{cjd5uf0nT62--K zw;04L0oj*9t5mV0GQVBM=^sdUodd>;Yq2T7vvoAy?22&bBm{p4TRe!!{fc4CTy;TI z&Wr@zDZb!k0ebW&=QWR~>P;#8YMJ@NL8IGcm!XK57I!7Xha$r{Cl)T=H)AOBFa5sn zKKU)GxGFhvN3~V?hl_S5qq@Ea;PZjOj*w-+lIZxj7IWNT3i>Db;eI4FMeivVlrt@p zG`Zn|tk(y9UcGA!qRbQO{S(zc)r@#pEaJ|ZPfOG$;7}in^w2?$ap59{-KM{M$yGJ4 zwQ0}I?X7bHOj3Gt#I~hJo@9&%%6~Tg$VvHw{rGI@5qZf!JC^y5JF-Wo8n8u#Y`r6q zTYGGEBXwGL$cSATy+vtu@tX%$zMnd~=@>SgSw*LQ@f0=2JX%5PY|p(!wqvUXfv+D> z5I9)IQ1_k3@63=D&&|)@smYa`f^DiH;(zK0%V07@_lY=6@h3prw>yo$kMM42=M8o> zPz^k85zK4Bla8$|x}|}R3iBf22|SpaB=BNz{t0ma2tId>mk@*i_%;bTmw%!zi1ntA zSDJ|_uc}p8b24{xsx<2-%V_|6#h#e(8)u}b1=+~Vj-c%@L%irgin9Q-aai@TFip@V z=|z+aieW(_o|L@HhTqCfkZlP(VQy7<Iv%rzu&)0W$X0JH8R^S@Z+P1oIS>7T43F zj&cug`VK;>wd}#w07`6YYMxJ;ZfGC$6v)P{Kl4DJsptu}U>!NanO5dgTpb26TJh5A zVvo>`b7LY~4|zY2iyQzJ6v8!ifZ1?d(0aE+w%P_b{Gl<$PUd6F|S@as+<+!#8iT;;r8>FOxvuyW2Z5#8L})d4Q;4zpX!IL|#te?jd?d7I|pc&$Z5pYWlsA=AD7iqAiPVTVIu2wj0!xoNk(AK48jx z(c3l-sp++r3QD~4%-nbHA?-Bh-VvuwJM-Fn=l}eYCsRK6gFxkgnK04Hqks1+ z?|SoYJU-=(uBHaMdeX{aJz`!&aAU)d^W%Npj#)Bu{Ux$R4&(gXk@CPP?z@Ya1Yh=+ zQw_XxPEaA?0H!k5wkKaDqz`~Nc*sZ5Ca~35Y-pUgf0EbEQXHet5x#PpRICBUgYhq8 z5*1w3W>AVpW2RNTIoEzg-$HhU>)Ynku{HHz7miiDR!<-wDVEbTSdWU_?l$749RWY2)^!X8~y2 z2mGoeI@G#!$%1qCgxBJ99gS)yKaU;E`~_7iVn*J$LljQG>87&XC_+oav;#o@#N|@t zA0Y`BH0dr(2+pf|h~ilze7^l)s_j$OtJH~|CgikgG;kT3(2;F5Q|99}sNsCs!3*z1 zdQND9W})>7Cb6D+5x&ZXWuB>)CJttmbVPqq>~F9!W)xf z2m#~8{`^xG122$lfEu%h0mv=g>Z8i+*!ezG8D7_$LlG9i;ouRg>u3_V;xd$?s^k#} zVm+9gQIGTblLKt>etFgyG=55toFUgicwKV6PFy~pa2bAyE&t&x44JlytL)_s zeZW(tW%h_V4xTvnfItQ7YR=!AQM3A-U#sG;E&aWs$2YHG`&6RFW9*|D;{clD;V9Q} z8M`jjE;(Pl^+}|WaLpzM?Eec8_g>&%qNlvYzI;qgvK8+2&u{VRQ}NpsT2%y+y_hFM7)(*v^XV{ z`_;^pmq#mux;vuESK&85711T8Fr$R3Y^^8=LVrVshUuLY448?Q_7r{oTcEV>l`ZJR63xI*;RAlku`R{*AL%Ds?`Q z@E2opn(ZzF4V#^^;+lTbsiE%`MR`}@%L z1&<-yPw8-x=B943Q!N~i_ul>O^OR)H3THi}&?EP8bt|uy#LyL4GlQj&hq2`BzYU2c zTn`By&%IQA``reUnCh#NWU^9j>gG!KplF#5Pw&m43NbCkjo@}-;n0#CItkBCS*kSK z__xdpoF{P)f;g{}P>&JL{MJ6Y951*Puv=c&*n^=**QFHIHj6b!UQ%i7n-d#0p0D;K z7+7oQnbUZ*7h$5dYF)$P_9AI+g0hXay;0(?x$&rymzQV-uQAd>a?!`aS>U__C7(E@ zjMNMgO*?uk?{)$5kKErvxdWlbe$8|p{JV%T#T4gqi#vk}{i6TnU#EEjb}sow;vl2v zIa2-TDX?}p_9%4^uCOj(H3n^Ciup zEuhrY`q+kj@DpcAjNy3mBg#rhGG1z%kJK)?s5Gaom@cBf0UaNO`ppgudsFyRjj#wz zFE_p>cCIGX;LX4uqo?G5t^kB=o|m#Z%?NT(PMMM<(j6SF8tq446-^6O=YPciSIb1!mymp(UqI5D zuf!Hh#k>}f0!JO1P<62@ER6(;BEA{pW%RWl$LIc1W80u2j#9fdA1OzsK(1U!9vQTg zn4{FIq#Im<>c`vm#H4G+1CV<>XI#ksSbN?;JlK%<-XNPz6uJM2gDV~sO-2Rlip zbETe4Wjg#DGOkGeFryHTO&%bx2hRr*@_YVbA+r(JK@RRn{&MD&j{W+U5IQ=63(VYL zu}VKgGkppqK@#j+?pv!O=S;{NkffwAW26a9GS#T*D_YM4zxqYq>{sdrX3W z=zPU_+)uou5iS|1xo)hxujWPV&M?|-T7~o?YdoNec`|3b;FV42c>lDTLM1q4nzv1PGY08zHFJ-gqR&|m|3SW@!F@zWyF(IM&oEvJZ@)lt+V7Fzjtt2s zjRQcS2=l_r1qqK`24C*xqbD=ltoH7wrku}|LU>&276K@1hK(-TT$Z$lCk z?+BVLtt*-1g8Fe)8eS1zV$Uzt3hdo{rM&h~%syy6VyG^&D8_G{IwiR(l9a-MlwoQw z5k32X`yNv}Be14q?V)aso|_vtQ2dnoU5TjFlyAn|J#i@6JC`a6x}5gcsrVw{hASk3 zYe@g6Qb5(?*D&_IXXSaPc75}-N+nW!SNJ(nihKLFdM@`phBF~PB*7ccMI<+O*P+ER z@30QEu?532Io4iw%((%sC6<{P+%Hm{q#1gUnv#}2wBmu zUo}CO`vSVYEv$U>5;Q^e`kGI4CpnW{KLGu+AiQ#~#M3y>Ct}>JB;(Y0Z>i9GoR5Vk z@n&9{;r9g@F6f}SIlhcJv-=_@Gqb4nBwN=q#f%)j-7)5T&LD1-Kjfn9LG~@LR`<0N zzNRufI(G&~B{zc*`}t+1w@a5krNkjh7#gQk*4#KDbBt!D09jO!^N(Ciam?44LjI> zE5L{W&l;MzNJP#KqJGR2zexf&pC|QH_!#_;IEFtj!Y>=#+=j%`4XUF3CLch&^Wvq_ zQdKd&TIfRzD^SfKHgQ2au&$Zm2uxC|4F~{_rIXzhzkXt_528(wE?7SKk;Zmwi>cy> zIQn_F0P&j)I6E9dVaGz5*E{8FPcKBH6SMDRCaDiV7ZwJ%(;Ug9B z@vMsZuG=+l%k($T#Bz*=hT*;tjc-R51?HR}Cx#mWgUlt1#SmjUOL<%B&plxt4OWVm z5kh;U%!^v_#f0V`&WCi$YLo*H|v_RO|b0y7~7HTggby- zsXDR9yw8qqF7YC`Wf(kNEIuwx@Y|2?`tAm=XXx;(?{!1>D@cvt`#-p}q@6EGd-2}4O}$2E=3fX`SB_>OMHMHl zhJwJdX~B_;IA=es~0MHn>ICw^>@&tp(vc9NCyNBPhkRm05b zs=?csDkwhVy6B?_#h3sy2rE&l<;2#zK*ob;R6ey*!$fhSPpDSA)ptof>&8Bt8Vs1P zJ|kU_egkd5V#+EubV|~@=VM#{5ia`xxMhK2$-$VNKXr@yH|6b+b~ck5v=LfMz} zf`9C~8gX@o_{>)=P%g`6@NjAk)z+{J+;8SX;P@p&-PZ;=^tsrF_yh+qwU2taGb9i6+NY1YHHr`PC(GHx<3F-un#N zr|-c4ll82CDj@7J68z=zCt$jh&m;X89VBV#kf6~RpCLp{awsmUckOzyAimnX?UBW&Geiyot+x>6AQh2*!7VKf3PHZKyh1qip5u#4$OGLUNNL zVxstZUwUKrBQ+z8@OHRT-tKM|+rE7w=_V9(54d{sU>DyTG~mjEFqL`e+jzXAo<(3sbq~`)>Cp_ z#8&th>8FP5b(jxN*+w>4`(r2?*IG(>icvi+R-<(64XRdpD-E+YI0BEWcU-^U-cOZ} zzNnznk5e1S>2(FB8_JxF$F}R9mS#4?0}HXo)Oo$Vn%6`$9<>TYw9_kot2>E3g~b9( z9LE#A(!$i~9E!y10Fg24g_JgX%o2)@tmU80Ut4)t)$~YpZcZ!O%2It^3agG~AADR? z^ERZK2V|eSWv5t)>!^3{#_zAF>-(mG_yPb??P*6R4jA`$XD(-~I1fRGinqo*abiKn z<3K}xloNMz-CEjjY)cRg9^iW$>nl*A-0KEs*xM*H;#2Ml?skjUY<5;x><+@7V4fkx z!85DoN6xB|Ol_68{}oMuPoybLibp3eH|Ww7$IGY9Oq&>Np^@Btm)@DWzrQxCDi~3q z+xLe;)Uz?9)gAHjf{7o!*)nMQuw(4aH2Gmm!sD5js8r9=lpApB`IiJ|hz?H=X)vhM zcHUNlt??Fl{%y^ng`jl@9o*TMgFd7Le@hnlky-TC@KP-C8w0APRIn=tLzZ*aUsxb6 zZmw1Jg#)!Kqn@$|@a*31XD)@z+Ml3GBW3dwVwf;bM#M2zx*_`jle&gO5ci_wb6~dFL2%u{Klo+OkUXJm9{2cIbG78# z4lL;8fA;X*eb(z)GeY?WO35H|7X6Sum$R;}?X$B@5>?WRH&EO+P&~IBQysU|;^~T> z%h``(!Q@XeMc4HX-rq(#shgFsqN}hyB<(VI+?NOW)J(vmO>db?=I- z5Usvs+l2_(%a7@EwyMuk~&MURpo|*5=t8 zY&cY|>e#G=Z)P$jqymVO40##D8gYv-3o8@l-)}2u7Vz7;6|<`t!M%Ak`5uVv5=dEY zgs3(`)gt&`h2Dt&!zgdi4UTaF<%`H+IuNA~K4VYQO=?~1;a-z&oRQAq+y6W}S;Q2p zbu;+H%|IADb98J+-PU~iZ!Yl)5p!X*H|*TnojZncNAZnz$?cgoZ;_e@(ek+8F>6EY z%5mP6WZvbmWVocJtRUk*(tzIlr>^lL82kwP;2?f(##Ba3V5BWM{p4y2f2C#mJ+C!b zqDRV4a?b)P+%gXUfkCFh^q$ubq^=IUmkQ_wts6%hfXGRv}SywRj|uo8@uW^Ol# z<>FrrMYDxJG35pCG*FKC`_vvNq=vBMqr#>1`um3$kJPT_pTqalSJTF~`NIwWyHJE( zw`fycUu+lJtz8c>IRZ8YdPKoZZEw()8wselVDFg|_t)m5%i2Ec+LyQvc?rtxrleON zzUgK9J`R@MIdYqH)jJlP=^6l3edNV5rpEM=N-S{)M8u<&<3M-aqm))>j9});gC&09K!>W4x%S+ zUDTp$cC~d}D4aW3N`8s1x$UL6u^F8R1?Cg8zL5}+5j|+{q64me`HdOom09pY+Or@y z_&nZpb1PNotqb2B6ZBd%V*pJ|e^bh03WS>8w!cNFr}du=4BuLNN^pJ>)YH`ScgqOo zn~TL;Er^oLmk|J#DShkWKcEph{_NkWo_kl8i95ncjaqSS@W0V_rwL;O3@m261h!nE91SL zN3%RK53GvSm(?IoE~LZ(#WpqP$Rf`4G{GVDRhflTnW5bTEib<@XD$a-pLyk7-d3Z` z=%D4kxJ~vcmo*_86?mgPFbeb#9C+`unr#p+KR@&135uMwgIm)wYdWYK;9up0N#` z^51Y*#oZ2*Rpll~uJJalMfnpkYe=4?rqUku_+IUGWP$K+KBH-LA&BKScDneGI4ZsxNMOowKB-HImey(H+&QZ7bpy@Udclt`LtQGT_`0*;$&Mw? zzTk_sT9e1BTVD7T>wiCQVEk^O$x&A?lQLMoTwV7@hL+EU?QuL!M>@8R{1`X=`l}{h zY%<`jCvjh8T=q$?cH$z#;t8sV1%*f052<_$q=L2QoYbE}jVrDhSb$G1pa7G1?3VJh zYz47GsKKNZ0e?QI9PKe{`c>3%v-L9z5M!Cffji5T)3oLVfML&;&H=!HXi3|RONbl;kR1F zwc5p72AS~1AKrM%MNeCn5qi-)5}7cSrUmhBBL{!Aoewz0d_b=Q46*uW`j_ez3+GMv zE6{s?1S&57xn11MPZW%O{VJ8wcYag% zZ`!Hy(%UFV(MnnmUFfKyhDS0E5TNLi)%oAWKYEaG$lq&eAZHUgdp+oyo5M>g)qpC#_?(QNbTF}J@K54ZN}*yYu(3*J`t{`qC; zR_gEjonO@ZkE;=%q}=|)V;nWBXQ{^yt0R>3_KyGQt)3^;f!{j_gsEM9;^pMcv5uYk zQ5P$e@VBA@Fd#H&lghJTs`}v)_8GB{syWueu}EqDuN{9+PIyTN`(tm#Yfg{#!*5mc zj5W5+_u}?g)fs|7`X9%Z=ihm+SYmDC!Tyv*0C$;&`iHx;DoqpaT6;%Ft9IvieX8() zh}leVTj;pr)_k^;+QgcwI_K{Z_yJC*#3>UjhKak{x(;9#P~!Vaa14J& zQWkp(nAlztmt28HMBw;FmMl@>r?WRyLQ(;9pQChwQ4*ijE_D5~{>tO4*zS-ILc0to zW0`p+vmZ!P``#kitu){9Z2MgR=r%(r%S!`3MtDBs(JIBw{Ha-^Nrdq2283KffXSqI z1|i-_1(*7_T8ph|xRq{VfWLc!Qv$t_FqN;P@;^&~5zDenW!RkOQm_0Q#8=U}xnvTY zykb>WKBit08(Kdiv^|i7@3t-sO!ndN@i}2MTDop+(fW=ObkaHkcE%Hmo06)MysKV= zjMjKh&)PRpbqTkibW@qExMfLx#XBsYQFl}*kX-Jfe8bAwxN;V=(4P;WOX36~6gjs% z!43+>V?pyey>0OL#~uCCjbR%5zjD*aC6ovaHA=GNYO^pY20ex!+_O9kF?FiRslqKw zPovLR;sUT`F1zM;yMK66pytKluq+4C&KvOK>f$8gR!w};{PC+%Vx5Q<(&~`*%N3A` z#OkFeg2D461Zr$!6ViK&>?uFMuST)#taY|ytU1$!Hih;8Jlsd(GAp@gy=CUx%D#Ak zjSAaa;%Jla|5z)5Rl3K`U{lB38GVR{!JTKUa*9`5)d5NJx5g6N0iL~(Zgz_kk2tKx+%yynHD95OJImU3y%2e{OWlB z+sGzFGAhEPxR38Gn%hr?dC8>#Laa1ZcRy5dcMZJj9kLo=?OIU;vJjQSRn%n(662iOq{MPQ*_Z8DE z)MidpECevgLVjzHUxcBrTMzR>Vz-m}c%pKeyQw*?Kz-i&kJCv zjL&dJ5^ES1GbM$B;(sW6I)3~=s?PnN=|ArOW1HEW&u4QeltRh*FsGs@q@u#mNu@~6 zhi%SuaOi*%n?q6L5JgU#Q$!9S-ypQAMCcFN(UhI0J}!}LJDf-xT1)1$iYAnbP6%h}D^4H6m^+=2w^7A|iE7&L3M ztpX@a=dYw};36V?@|~nYkx+`*K_=yuhI@C1{O0PMH2(_kQ+e3)G{PC-Q_B=rAp=|P zAb8N;GG8_^)#I-1`1Gvx^GFVT(y~!9i1oZt+hN>@T72JgI&;dl{5cKYVhIaZ2ZyX-z7X6Ua8HEdlcPRdq?GD}MDN>= z$>%)u?7`sQ;|yT-$x)Y(j>p=bWAp5&Rbsj0K{d2H})BIQN3xh->@(JzEqz}{GNz)B%I6DI>5%P)nbGE)8`Oi zqU#x#;Y*Gke;g%LyB@-p8eSzM@!Tp1Q2$XjE%)%8v}21pRBc=KIfJ(sMRs3RkGVs6 zp2IDbfq=HIR|2dH8@Jz@i^$y!4y3zzYxvJwU!N+-jp#3kmTA9x(em~~;}=*lXwJ@l=c zcG$3bCbOCl;kyQ5aIN8%pgdn=1%SmB2k-Hok{OYkBDw@lx$5x-97$2fcNq}p=~TQq zm+cAur8s!c{h4JY5D2yJS^KNFIHz~ZT*~PA*YSDd#B25E+(8d@?LFBcqJ^}Wgy^C( z8OK?JnHM>%T>(4P9Gx^%vQZ)t zyEP9|+MC@#>lzs^K)dSHiavm{whrGs{*AI*fO(T-mZokJR=r>itlwy12dA+fJUM1f zQ@88oob`@AcwekahkoUFk|b<+PV#8KOx06nh0H+;mZkT(u0gmE>0ExW$|Jxb^ppY& zt*rJ!HGk$dVAW-A>Qmn1Y;z2%Z&-F&zGEH`zV{V5(tqw971-chfJtyBZiLHl)$>VL zTtx5*55f4c&5)-(RyWKC6_uZWf}DX$mxbZzk5=mX#%VWKn1+_1d#{wj^=Nm!MI%}C zj#w#=fY+%;Z7bi6E3*NjE-!mldV4 z*p?R~QNch&RD#yt`q*9JOy1XiZ6f^G^GQV6UiwnFLxc6N!y=S?X${4d*Ueyu`O}k% z(g*rDjTg}d8A-2$vM`jZpdpyu*GMk7zZ*@#bMRZ$n0B0f5@p`ES zcR~^5EuxYxI7+`85T`tTG9Tm=>c{w8f&R4Lmy59A#tGCL0BnMT8a5E0uq&%;bjk|W113dqJurX3I zbcD19tWb;z3!q}%g7j2!XJHTc3P_Q;y` z;;!i~RxzyI(pz}&?d%5)tmFwf++|ysi57QBpXAiAcVjGIKSdDhRVFU*taGBxMgvcj zIH+FglBzat z`E}p6bptC*b|Li>0#rRxwLhYNRu}l3@&Vy%c6aI!pMtQXJFoz=l z!M~>ss*Q0;1`A)8c2&V_`n^&dphG)w07$*v{59tpl#@{xppIsI46pVJd6PQ||I%kE z!YTHR{IEWk*jd>MWxQp_6!I0RE_o0X_P*;7^bl&_LR#Xp)~pnfPaY2#nt1)_6y@`5 zV|||J9^kK9yPj3jsD?Uo4qy;G($uQ4_v#r|jUkKah%8VuO+xd0njgOuAEjYzB#`re zk|3~MAQDdsL(%K5n=gcdiN5uWx@@vX$ti?>D$eXM+V0Us&fk-RBI}U5j7$r(hjKB2 zeqfGt3VQp8&trQ})_5;9bb*;>5kBd?fAHUiPxw(Vh`WfGoJUimYbXBtC{jQXxK-LW z`{JZ=+tKA$W^Mp7^Lg>avrKXH3C}x1L2?td(x6rAyuyGYsfX*^3gYKd))2M6yJqe9 zGd;>&U5EVD+fL?V=t`n@5FiISAY4amrS@h7)_5>D_x7B(t5F^vcGsEL!IuVcxBtMZ zg|B3S4^-L|MZBU-W<#0htr31tsAq}i zeo~}ovAjzmPJcE1it>*#>SKfExKl;9G(YKYMa*&v{Q?PJy9%(n=f6JAeYOAVhpJ7} zHR`~)4^}x{{n`!`-$+kuBb`~k5KjSE5kL$S#Gk;d$U+uT7Zfz`;U%gjXwmEckuyI+ zZ~n(=9z}dPFJ}pzU0I^xzTe_6GS@#!EeoUNY(1C0y8W7yv&rHLgqM1oV^lpY5IhjJ z7wrM&*<0{+WN>1=mqBB#>v38|nYIAK<S3@>HJdL7o9?fuYs4dbqtUBe>kF;uIb&G`Y)cyN8F8!Y=EL3JX^UJt&7YYh_h_?m zMlF23!2NS3KXD&6Dl`dakVFXKu94LXeCysVT*2GjI^_H)ms?(Qm+9|r1ulh4tTr)* zvXs+!x$mJGA29;9PE{0eLoBzJqJ@a;Vz|E_;6E&mq!Yc>y>?_EbZbfk?Q#2!NU^XL}_l@Pm zj5!}|3;?J$39cS9dA&7fTqM9}67312?*UgH_y$rhc+ss=iTjwBq*{S_%qAD+8;EZ# z-$$hi$fg;36qrPO-ffgw92W2_q~`Dj)bD^5+s-n1+)AwxvHZccPI7=8{s{{U(7Yh0 zgyDheS4zgF5lQ!zVB9gK0hU@kZIbgdWCl<8B9t*S6DRIO(f1sxw4GnN+1wHd-HQ&Y zU>P15r#`wZMVEi@vtq=W%^ zyfV~Gai3d7L!yJLq2syHwY?++GYP)lVHS$m0XA#lPzHbz66frMFwR7f=U$ITqIym5 zgPr8EVJR%9kjFxv^AQ@@dp7a;Qqo(pB=E*5;5BpCs5I=EY6DNef-NwYEjE-8HgbV@ z-Xc8J>MndDZQnzK=lxAsiy?PH|3Zs4u*WsX#sn{)r!%r1HbTxi7-$O)m%*&yA{DT* z8iy|NO5F4Yn!eFkIX5-;y;FZ>`0>EcQ5QXP8Wgvtu(o6$?hNz{hJ1J+a+{9BhcpN3 z=QKt2pofe2-hr6o@OA&_$qg>AhVegGpPr0L6TY7ZY@*38T}5`R&%3;}@$*043ct`^ z{OI^0Kso-LkMmtCV@i#ZNYoqZUO8#o@&Vn%VGkZklFUJD5p&9&n0>I24L$&cr>L`Xa4cgQof$Ttnq$n`Ca1{jt8~x*A6B>C@|{yqyzcW zcORXo0*se;Xku=!*51rCk_Q7^1wN7cW&y5z$!m*?YI#DZHb&ZT> zQTuvsOrla*S9b3}dICH~A4HBeyWL1jJxh93+wBB;A*GfW7L(`kJ)*n3b+Ibxu*US7 zQ%MGnlgvL6s9g7%t!tZ{`}k~0LlXbw_oc_Wo|1x1euksUg5k0W0G1JFwX&I4J!<2Y zxBD{c#qFv;0FanNLB?(8MYjdF27ud~Op;<7<^aD(l`-rv6o}V}D(a57YF1&q7ko5J zXXN*jS1f|NeVu&dgCIMW5!&2D9c&>mW!}ATg!5}izgpTS9;vHOe`iqQbq`f19{%(K z8~9nt1~0=aHGqHJui>w-{#>9rxOGJr4CNWy?`sBiy$akZSgw3$d9~gM=mhUj+xZ^z z`pi%w2yG`dp3~!m;t@gt51NP_)W+tV&xcv>Nf8%s+E1bKS*BM6FmmFK6gMdaXCYa> zofj^Yp2PO$yp_dt!CuV7{EAB;&mf*-ll%tk%)S^T`}ZhYvCB1GjzNCLv^}wZZi4Mf zas+e5mSZL~@JE`QqK$Kp+*vo9^UiAr0tDmI3o6%22`Ahrr^@EFBRtWf8?@`t0d2dW zaW)`N@bQ;sODtlwfT#26z4G#g{w*85Qj_n@L&mmGT*_97yt=o%@^46V8#O*5ZyOUC zUs^hoYIpBPYSnZMeZXG8d`~OwG8er;fKRp9Ad032q_fP#$d=R*-oS zfo%bnsVo5)3Bj;xg!C_51Z_sFl=B{p(}GLdi%!6Gibrg3E1I$OCHxU9x2}?IR@*26 zSerjE>(L`_rYcXz_iFgCrl!0X!z7E4*@-!b-TvMijd3~?T&vKeGsvN-Dblz9BKQ>s!ah{NV#f1%2^~p`y;#Viq!z2I1iefC zaLxL~X1?-n$t7F`-&#^1{vBt|KNR)d#s>xy_0N8Y??0uy=3?Lp-A{K7juX-~d|ljF zq=xhDV^W7+@l;5&jCHOV-78`{;-HJldP#XIWIcpwkm8VdLS3&4#Jbr$$tzd{^y*LoK@G7afbs z4_pA(^gsu&-+x0kxMQqTh&!gdwnPTXw#(590Up0CBb)UZ2vilL>`ab!~MlYo3Exe?wx>QCFIu|_W5D>M)D+)@DtRlC^YPqDK&rLm+O*fb* zekhO#*L8X#J;z^lg|hp8p2xrdQS^5zhjBzmv&sguiZYsnr!rKIjYNioJR&9Yrj;0H5E8SV;;d6 z0rQ;7!j~m?fH9f8Xmp1>#C79%?5Jix`Fi~YaNT%nN^uW9Z@2l2H&niV$n}Q#lWrx4 z=G>CFHTmT?0T}7urQVyk@UB56&Qi|UO=FR=}wgV^`uZ}y9F&O!T=apRBzKF&eoItvD5<|aa7%er$anI zyX4F+Y{LGxyP3M`JO6Zy0nkW(kA?I%gW~oNyK5Q$4|8fWK5ekEJjiU_qjhXMVy3)~ zSGbFaUqQBs^J{dP;6@boe(Y@6nq|bU+{9=F3E}&4)F8WEG)dC4fXR#YUV>$iDS0sA`HQQo?v=>fXLg|orqN|)kR8fw zIieR&!r?yt)jacNR_4v_&AvKgE_?A&fLJeA)YXyXgr_ztUojn~gRPzE1-2DDtoy_V zhT%&FSTpgENkOyZ;9^uUpWVKIl$_!wEs))W8G7Cv|8Y7K2m8M4u0V9Wir-yg0sVy& z8|o?z1)#F8d{!~;hs4i>Tgww`PQ8e4K23L3NjafkUkk2xjM9V*T*g(x5-Sr+2C?2e zckhYHt)!T83e`OnC|+HEs`slyX4AY@;jde6PoZha0{sZ2b`BZ4CNCW8&YKD&#q8-^ z05)H=e+3o*x%qTo=)O9g4er15tcmyWBh%VUD|5zb7o@>=^HEf~ph*xi{77Y$9LBn! z#;>+SX(&^AHb3F}!Qu+(`pqOhcc^8$c)K}Ez|$do9{I42+dbT>s$YP!~3eha2g-CZ~8f6ze#{`-MY0b zsL}8RZDlEt-ELTY>>(jxMdC0^G+qb=vrf%d!>YfbYMs#Eo$$`$M7I8Mp62jbpS|?= z{2PDbCZY}PJE#r5ey*+(CU{=i+vWupK>rB#W-_DAz$4~KM^9~x zAhy5Nnmbel_KaM?b%hvCF&R518M>{P=E3JZZ-!A!IRN-&;hql2B(}z9t}6cB3;(8P zgQ#Lu*`#%uT}kLxp8C}ViK~f8OhB#TTCd2!jjVUdDsj|)&?5tOkRY!&*$(p$n=o066pjKK)=1_iU*YXHcwtm(GOue;aKwaP_RwS9hj_oIP zJYH$lEs76U&y$iyX!qJLtpVW@lP?3$pgZk-?S^Js`U5qGA_kk(BU(>y!T3roi%mP5 zH1x5ujZfPK!|WI}<`>JdBkTQsZ&(qN5im2@t5N-?mj4@>`s}%Diq9ynz{!rMtwxQ27X;Fnd81 zp4xOGIUD#tU^6Bh*F3paB9r~S@%^woF`F-JD}QQ#fO1Fgvu{(@{*hV&*f_^FbSydU zi(A39Qae;}Kz&T0H=GtXGj{jujtnpURNmH2B6hw-V;a zSgDc`dn^QmWykaJ= zxr?|(O=%b}=MYqBS+37PDkqK?3>f9x2!@VLE9GNrtf5z*NgHm1mxI-zp5_XGWeVb z`CZBHD&xEs@jx2?Ybg0V=`k;);1O9`_bcO|II`CWk0r?luvx z?8J+D`j60gnI83Iikv+`Reoijli(fhjJoTcZJ9p_=FPj=ojHV>YsRrFf)tRnfrU%yO@n_0P9`Z zb~5=3qw4^6ObOs~5+128yWed(n5H*OnwZ5!I(L;+^6;F|+A6D}8J;HZ3Z-44AzX-_CRITea^-$xk9H7|hO_IN4FDJ~$=gtq53v{sB3WjvzU1Ld$}B#1WgV z_C=G!?}?5DNXGuZdteUs0^96#(yascG269Fc~dwz1I&J>##j1Fx?)CfXZ7Sx-iCnUHK?}v_YKI*i}13WH-iD24$ zS-R<(!o%z8ZL+ud?|~J7wAvDsujIld5L?RZboPTu{@qYjPJf6+yHHf9Vom{p&4t)k z63NWl$9b4qx$2WjR6N~K`E$inq##Z3PeAgW1Ouyx$)rV*5b*u z58OUwypn~WvR$_6WlOp@i^gHGHdc#y$y!RdH?pG%?oGD7tU*K zIk8xZJ`!8@P-Cr@v`KLM7zBvw&OVzVI*kr)vK&q9*G1<{4j9j#%%&O1hvon+Y7WWj z@m9hpz(M>$dcn~Ed?UKzCK9fIn*pHJ^hl+UoV;-F+T8fT?1S>y#nS7I6R#5_q@xGD zcpf}{f$K{!c?;#q#^+OumoIwYh>$ zxBEbu`v?$(2+78;w{+g=a)j|W&S~4Z{V})Q+r4hgF!m`;M^ioRDxMb|P)r}hTtVXu zz^b{=&I~XuHerv+U^^7J zXCZ$7>b3zrn`7?~0I2*T1aQ>UOtNn8hq?zH$I^gfVE;>g<0GPk-Xu;2&Df{sTKRR^ zu^kqbSQ*jGHR=?rb*A1NCjABbbbak5D-=np_;Y-mmAWJ(lQ^~7>?WGx#5yoC$@9d? zooZ#!Z$jz@MrATrp93aQ^ZDP(qx+^0KratY^FE$z0NZ;lHO$-?^=LT@Z%WMK z9cziL)GGE}AWJsZGvz_SUkN%}HPUQ!g}+@Wo;N0^$Ye+;Jg(7Agm>Pp;E1?#i$ak} z6_?;KYq!&<&QWMb`NJ1Sa!-lebZR5_&2;ZY=_6FPzJD;e6o&iLA)p86cLCfSBAk$1 zn2bh^i;f8BxXCfl2>0r$-P#f?JDRR6xGF7j#15IRKOiQN_?L~WtZ0LJvvQ|W5JJ$)Y|_Z|(K{@0g|FwO=TK3>Uv$^ove(F<>H94@<%stWq zM=V?wjO(?SL|%}t;QA;Ja~hE@*04xZorJZH*qa&qmijw)&+Cr#1ghhOM%4eO7DNA- z;*-`x_N~wlHqeTxdUFly(E{#CQxlR(`Mzm+c+|!IT!gI}%fY`nJr~C(0ur5>TVO;) z2i!8pAE854-0qe*fY|`YQ08dRgZaQb^{rtuxA_r&d~w3BF8RqupMi?zqyjQ zIb3`nv6GA^YprrB@d!Gq?({PDK^@fIaEWDE1ablTtqV2rq zHBC7>V$AgAT>g5HRQkyE^J~lGP$K7}lB$S0|rSsxvr&e*X#R zVF2>+#@*=66`ehN4xioLtv307EaN0UX_jww<3hTvvD-Te z!N!{Ph~TOeC^9l-4I_iNSsC^RY0FopzQO%0^7S*U?g%X=g4RNkPsV8pZq=GD9XCmW z*FxCD0G>S)IKOLdY%6`4Q+$!KX^YC{uPvB7=dRSo_j|MPX2|hH+b#|c>W9j2mQi?q zG}SHiNV2|2t@=)Ju7hgt^8LX+a3jn-8TP9N!ux`D46G>Fb6k=M*|+R-6&JnD!jt|#R(iYqSlzdEIP(K%31Wj$nBO#hNAchADMvK8ox>9=4& zF8)C1*Gly6O!8jj;}OD+idEq0=GZn%AYwZ>whyvTp7VC%k{&h)myG)w3K8!W(|8;` zKbrC*p7=J%(wCHc5&x5&V4-5TbMG)qt=dtO|C^%`73ce71AS~2Q0@uN`-@QC>`rt_ z^UM=>+pcolWURj>w?}?at1}Vg4^aB0hZudm_EBuKj5BsRa7+Kkl~CBUt<28Tsi3e4 zUe?aEtx1r;exDtHMp2HDQ!iL}&rEQAfX2iN)oE}CXcLdnvxPi>S_-tTY|#~YtrT*m zJv3yx;&>2R{HuoyU43d<(*h?OIDZ8n~iELzye{N6CF;;m?OwIv0vpGca<3NZLLY=JgKIqXADA&>tDXWV%4igri}%Vw)dU5 zgj}RU*lwMr(DpW#64T(G@akC1n@e33YP9kX9EIHx7m1b7i{}e>cBvuO>i(_CWJ&GcK0)0EnZ1 z*iKPdN8O3Up16w=S!3DIv)3Eabhh63n}y|>ZQdl!+QeIOgIosx(yYcqudl^yuM6$- zmZL8&eDx}^sF-owqyp6ESMFI-gj%k6)q64$Ty|x|Mvg}M!qq^_T#FXpSM}s=_8hH-USxKrK7onGP4M>Ly|jjlP!J`lI|yjzLoM`;J~fw)#GN=bW!t z(I35Qj@MJ-U|eV}e>vGfqzX-b##Cfw)|#S?!QFW}KNkU1YfqJY^2yYxsbp&P!4Fp= zJTMJ>iPD$5?_h_@*>Lc}Xc>Tt1e4YqRA(94swkr)E+cvL7kTId3`_gg=d|Cy1hr^Iigk`;9dr9RWgZb#DPv_&hA|UFF z$tS1LLk&z?FT{)O(ZUf$FQ;}N#;s~b;t%T6!z!H!4*Pw9a?6;4b7A*p3%A}lx^7Os zEmkyfIT6BS18kQOuGwzXlP8#%%#42kUIF%;CBRsw{b75N?c4Z;i&)DOHu+dKo};xA z1#!kFzhx)kObzKzq_7Gbp%d#tf0}^moS!t}=oxadYd62i^UVjmkT&X_<4~6$9gVH_ z9gbxa_n|ohU4Wx}d_wD!8*%}57R1}$mld>EY*~9-&V+|81(kK5()xq1ASgJU0*`vv zNmLenS2h~4tPphzO}-1t6X)+4Bg7>DkVUz~xR`)si56+Nx z4W`Ma4ee3v3aY6~kxB2;UkJ%^#~J7&aw9oLQpm@9f- z5hs8+zsw&Uw1sRQZ+oZ-`OiR}H!}y>EqN=$n-;jp(+{a?lLb=YCb`jG{Dyl>zc62+ zDlN{0$hhHV1;^&k&u~DHV-W(qW1gc1dwwLWYQfe3;9l?q#5YTd^UFe&*JFQXQ`8@+ zW#3(MSaiBn=O-@wzk|{bVCU!XMEA`b3V^6wT_I@3gsdB>%doWHKmH|D;}Kg~lsLZ= zNDeCKQYr3ERli|VMOlZe*%HiB+&j*c_Hip^lma!Th!IooL3oVi(c>MsRc0}T*#f#7Q^Mi)ru1{pNb$)!o$D6p1U6oNLI1ShZ50;M)hPnjApM49Ir>1HLZ-E^-(GP}PX*HRO-&S_n)3S>T;Pc4Fnk!yh#?xvuT% zWx9qFx`})u{RG3~yugzQ8azX~-b8Yo6T@*>Tni`N1`h?9f$KCBXf=1EnWlgyV^Lks z;oTkwNlkb{yFjOt8(FFiHGaPcegajXc}5wl?+YDC3`Nl{oT`@XVN^Y%lQ}q-cYdWh zqLEfr(@%qW2xg}ja6!8L$~Mg#+v`y|5$-ZoMNvDeL^LpN+k2ngkC-{1q_7#P>_h7~ z>)a)4t6rNoSZ{$c1En@`g|96v73p2pLnkm_eUdZea)VxtCcTX4QGYF92R8ZYm##=PyPyIBbclDP_8}=il zlH(d?N$BMiOmR`<>V~8oLS$0u5Vb$l=7a4yEc+g9@%VjmE4$CZr)@FHE=kXr34~7Q zN#^n@tl~iFRoe8dDkxmxR|<}3;C5wK7*iu9J&F+IK0_AfPR-pDVL#L>!tLdT5&ZDy z8BaFEZ~(7~u0I@`zsak&dlmEcF7?nk&wtm>IYUO`2wNj$sVK2kW?Xh6R}M6_d+azf z;6XP{f>jP=!(>;dI1i7efGls1N5M8~nKx~p9oD!w?s)x0PGsE!0^@~U=@GL_O_DEt z9Ie|}379Bj21P%69%ylKHouN|hS;@hEV?TfJqm-AJl@O)-dE3bwm(&d&bCI;(@fsX z9!G?o`=^zy+bAd0tERq0l&F|N@NsJ?wj|6qcXT!OU3!nyhM1K?b(`r3s;t1N)Tb{= zQV3xSXSGIuIEFPz4uT|^??0Xg1CpM^YG`XJ4Kcvblbcw*;*(jqv?H&EODQ&VD59>L-;S@>6NrJj@CGAC6$)At-}ITDOulVTyDsjh+#tj zKEqCw&-R@Hhd$dK+Ca`{16L@$&aeJSkMSStswJti+D%LU^1-lR><^B&P;=!yGyu&aR$l%D$HK`kzC zOO0a~iA3ppRKg$@bdIE1FJ<@q7>!j1Wh5m5VCg=p+`*t>PAR%^ z|7CJRxMawwY$Ugn9fCc*%4su@$Z=nqOGXVOBAm4Q-OhcjDK0Qwz2m09xa6<-KtaNN z$hXy~qa?7*y1V&X4NG%Q;W}4Kl1FbCXIN22$gf<%+r@5_QOO>RHIu1l3ulw}P=mu|CqQ5mu-3pLFT%tQ4s1N@y z3&0S(zo`6a`I`Xfwv=S_<^!c@=lpArOqW3VH{$d9?$pR(-Z*VsmwhKadkK8Ke|=oi z^T|sSUo}?sb(GazH!eYloB4HZ^PSWQ-fJHoCPc$pY{+a#hxu*Z7~Dk>NCd`g{Bvgz z@gLGGvkNPOcuD~YJ8NGahwsdX#OR^h|HEevMh(5cKk+H!Dx`8FWH0>ClkC`??WOGK z6BMF)fbbba2`!`vOC5kovTfF~*GisNjNW#w)D2Zs)n@IGM>xJ|H$1d1 zDm*-tS?s9P7AM$x2;&Qzk|&Ctt*G1wUB2ktpB4#!oX@_0n*0Uqcg3vsBUhN2OY`-u z+&$VS+Cu|^yre8+x<;0(7BUb_#UfpDDI^QgtB&F}axJ6p|LzgP86b3rg%?B+;Lb zEkMd~g{NV>M!K+Xms>ADax2hgVfT9Dn&?O9>}L3X`I$16X6t9zToI0v^2u!9Ed0r@Me> z;Ukz=xV7?-1I=>`v0KTzn-N9WIcORxMno~f?|8k2S2@@RWxPMqBYoohg8zvovw7P2 zs;Ra75!U4lIlnKhjR@#u6L{frL_Ii7N_mVDn-r^s3@uG&xmuA%fabEyaxw`JrROjI z2uheNz5DB29Q$jW+}4S+GA}cj)_0nS^tO`9w>;o5$3Ka@A4oq- zEOhsN=ZZyap!1N~9DmwzubWM^xHYTz8m8n0S4ZI`R!9#aj;iAv)M_)U-)uy0g~Z5S zE}WPcedf?;u)vvc)RMp!$8Jh(D6E((`a9oO8Rq{0Hk+nGbH-*-Bxoq`4b{N|^+fpP*>X5_ zqa~&7WcuT|tN41e5uViTKSaL`ont(?qrssqvDd!)ZTuQ(qAysCBX#4@^Wwh^NQ7Vf z>JICVwPmfd?x!&U_d@RIDHVBQo9RjZ-7m>zP4!%n<(yY`$eTRj-#>&%GjT zwnW!7AxotBOJQF3cqi_i7FfbNIwQn7NbMUkBFiI7+qzPZ$}*Ia&V^qJIs;hD;z z^oP(p%6rv3+-q$O$QgAFj%)*r-LJ|@C>NjB@`%yF-RZ$w7s|(zYA+j%OW)K0U>-e+ zKk(9_nUn#!s^5mKeh04*EGVT2*PYah$1$arsaLXW1Ldvq>6ScUH6^qoyZ=(#6LpiI zm_43bMhnBGbA%FK=2(Pr$9A>p@-_@2{&fDglwQCzZD2WV)gmSV>WTd0yFHzw_<*Qn zF86mU-K_f8T>0ybe#eEhNpl2Xk}>StxI6?_7)^5p^tP}4Ne@&ztBJlFrmVU{uJtDY z!O8^>`<+&B?Hgc=OHabQde7(N<$Y?IOEdB%s!9oEFz--S1fU?(WX4t<`<1J=^AkY( zcjpBn6*|yt#Aib?2m1z`hbm}ne5ebg5O|_gryl2_8^MX)d?e5o9B+P8ef~N+)H~iz z)l(NCi}5v$x@=__@%EYr?948X-T!B@!7X-YCADd&#VaTeDmmP7?CB|ViB^SP3$jK= zOK87Fm>zbI`FY5#!M(2^|5j!rIV_mw|F%nVPxpKnVv*>w6R0WIsOA}*ki*t^AjPi0 zH(y6^w=Pj@W6X#3|)!UDHIjf zf5)zXG>T~N@zvhCA;jAl+bdHh43}}jei8n8GOwW4a$^k1zo3utr9|QbWaqNg%U&v17wZO=JEw;lg>0pt}ims;R&WF z5WDjWp40!Fm;s#qlM7q?B=W`a;xhWYlzm{_2hcX*tAksyGn|BXm%KhEz?wTo176W9 z4Xy^N9rcWF?g+#-Xxpjtq&USmhm#xZ+xH!=M1VKQFWEF8yx9!FS=;BB`uG9#qp@nP z2ly9>WIL>27S&T+b?wMyq}yMtGr!F0;E&i3af6l*cqV;dU7c`;V%5RMNzg zi1`DH4LX43k_Q10C)-2KFSFFnQ|cFaR<&zS_6!D^MNtD3n=fa7*vdzaCHHwedtP~L zgO%KMBAf!O#swfw5l+T$BYN#4hFFF+CIrD%(erix!83gv<;r9)7s(BAzA1?kOe1f} zq3R!-pU`)Jn*i6FKOE%_L0bJc*Z-4f0fh*># zcZ?)6wpK68c}?>Hb)w9SOM{k z-sazSn658kF>;lAhbO~c$S()2S&q7~%!O8q3`W3}*;@fk_;2QJcd8CJ2EpHmG#<2o zoA+9!Yl+ToIqzm}1N!*H>Rf>Ej?(mFIQ%q&Fi=XJJi;Zq^*1_FX5s;)w|msk@5<)n zE>VA7DE8fvIOS3_uqJy)hTkQ+IB5b%c*R%Et3@@~_gq$+#*jUs-x^2Xp~p{=ogn3s ziL;e}Siu6B3`k)m*0NE@<1c!xRYHetg=DY$)QO!+{6clmosQWRp)auWv~bl;d+iTaAcd)MUwSX<71%Q zjd5Af+=;(4V;|W%vpij2#?7+2@ji1R{H`qA@u8Z1F5WOR_?{IecS*a>d>Z!vSMtVZ za4+~czfA#5a#*?g z)_1wk%@Nh*NZoCxs6-xG_i3!J_6LDYFeXIF#vaby!oc%KA_f_OLy!dLGosQe}*Df;Byk>)0)d85@Rg$G>6 zpn|+*UOBgZ*EPmhC)VYt-SXZ}psDT!ihWZNCB3w*X}CTCI@#RRJUN;a`8w>iOUTVr z@t;IUe)0rtM~X6iH=1j=T_&%N$$WyvS}?;Ek=VOdeO*cBgYS88A34Q6tT-cnZ{v(h zwL#Y|9JF<#I({~d-C)2nIc_!?%Ve5N=MzH*W-ieU08zW&szM-6Q~;xQP>$GspJ0oK zKE14xVyu~p5@7@j2}nB;xxVONYZc{}PbfsiTpLV<6IQR&9n00np-H0BgW{cg@fvMlFy3lHjS^ z7LY%0WgR$AGQR%D)AZ*0W#162giDT%Ir+}3*=+~D9>LHyFIEAC6UPJM(+v8v|HK7F z49P9^+DdM{{a@;HfvgY|<%NY`v*+JHYemb~*1~NUp*gf8+LT*VFQbR2jm)oy>{LSw zT+U~h%Es7+!A7kA7o^F1J}YzRiek`PQi_Fs@f}H0HM?O)X;7TDbi?#7PRAkj%b^EX z&0dBX0dFZW?eCaq-2NZ@Fn{%oYT!J8anditG*3D->z^O1&oC{Oc&RcG_Prj8LxmbL zjOR;5r*zvkb z=lLC^pR8e1QDL?3R;k7V2@qMc9{vFO!o_Y!lTl{>{dyBx1_n=EH?nW^ z)49u*^wg&tsAjkZY?eMV00NkWO~x3%PzkB(Qrb&;<=)OsCS$^Jj;&Oo{blIp4DIPhv0zW$sy08d)4yD@e-!so`l zxO;=D$i2B~1mxse6yk@!1>3ncO#w^YlS0tl@4Wt;`>rq2_nA+K&wazLY#38;%2$B3 zi%;K@ZPa$|Z42j1-nw6Fg{D+qowEQ#D$Rc1$M~;gp6>AlaM1HNxOP@~7_yHDwkbZ9 z?G3B&bt|)+r6Le%V^k-ysovIsFZ}QMSlm4Hj#&6NWF$SI=Y>$}YudTF;4@oFh2v)a zI^KhKy#peJuKqus&cmO||Bw5e;}{3W-s>1;hRPo2*isRFsI1|vt z^HJ$ht=jJzE((?FuSWGoG;+K21+Rq|+r?-FyM3`U^9*z&+w0g#B{ zGxwWaaz%Od_}-!0_W|qbPk7ls(&qX*B@wNdP~piqW}d{*FClMGD>vs|_fy&w`ug8i z+$`(H@gN0tAYCE&i5=1BT@v&=rC4iqpAvfZ<7wstU*T;Pp>!(-< z{7;uS*k`2PHvxc!5%BYfT0eoA^H5sJ&8fy!OU>Z+pT~gqoG zx?aE@XVQ~*-TrA+0!!E$*5|<;@%4-Fc2byLGU}J56XE1LjO|-&uN|vO1NS>yv3e{3 zhH7$6XEb>c+k3}i#q&2~)0dyl*wYklN+s;fPHz8ri_6axInbN5M2P~cI9m4}FPi9^ zdOG`yUnUk3v>3e~_jXwMTA+%UZJgzZb+1%zv*^6|48>wjFut6wUA8r{EiQQd>gvqV z-D3Kg0f4F88DVXtQtTsafQQWIqe3lI>mte<2OC_5^y8p-ONnq&cx|}O%7;W zgTR!4eSO{FA5DImO&Z^Ece~ql^JcucZZH{x?jNhJ`RLq+fZ0u}_lWS7x3;rJ4Q|6F z50ICDqKQOpSBl)9ka`{Iyv*HZviUd^@3@GKA!KgM0{Kbq4?uo0 zq!Lt;HZheZb(oQqX6s$h%*kIe+zl0018S1S^bN-biH(O4LHW*@^{sBlBjcD8K9_XR zX9#An(@j27$%=h~t0OqZS|!rFTcoL13T)tyf__1LD7QB0u5lY~{FXNcgxq*z@SuW|6ZCVRCbl-sFT*@CY*57 zZAwmsz@+D5Y8vnZBX=J;suL^+P*tSJW<9M}lD-~0)Qe2s>k)&VRGo}#0lk%uT9e$J z7PnpRa5`Vv9OIEFH18l~&Skky0FV;=;5)B$Yrx0bFo4pUeO6D3HsmsZ2qtAbGpt9T z{L<{5iZUK7(zguaI*-A0%&v@fN2W%g{dyTM58vqOWm@EFnl~-IoFUoZH1{gPj98*tq-CK$&iPBQ6T{t+f^VFIj1u`BBhyfv0(k zw8I`b6F_s-ph-n%kW#x)jD8)WBeQO z)U=Em<(|WZ5ut?MLvA48jSEfO zCnq2O;!U)?PVmMM?n{N$Z}roYn9~ClyG!P&(^JkW(C5fbE&q>4^v^2)*=$D$F(JRW zkHx~9e)0S!qQPEriM#ykr7&UUS{f{Cin9fDEgTImor(9*(2_(?RIQ#Q^edjbmtS&| zUL|nIw0vtv`jMx~8{*LLvM%Mp7H6NIsEApR`CqY0@Tbb=6sU7S0L0M;&XAB#^ zP5Lj4TPowtgd2N?7p+h#v)=<7ZBqg~8&^s1okO&^<(F>o`nXFDqH4N+&z;P-vycwH zYBs8&lDvNKIqN}l9`LFpL`%RP+1)4wMGl>KI!A(SHh{UCrOr<6luq1e@M6VDQ69=1 z`PI0z#}`M)bhk-8hT0~8`HjTYMSn}r(CnJ3Ry1db?fG*1398ou|4j?|$?a{2+mzIV zt4A=YM0;cO7@zCuyEWJHg`VbDZ2V z*+Ub1>gpUd@h4hvG(?5pot>kduGW(EOp_roYEI1>Cp+Lj*5zbTOrtXOPW{CFcVu#) z&E+12r)Xm)8V%+Qw8h{udorS$WX%DK6BqiISx@Rp@AugD3sU$eyO)i9E^m`X2~v5R6CNA zwid|DJwR$_r-o8mOLec#jFh=Cpj*U?Cimuz_rJQa#Fr!LjZL~Im)@U|HB^kP>UX=1F|HIA|0DU>OD@CXPrB09}Sin)lLf z>Iu%etUURJ$vw0Ac&^zSnMFK9enPp8ozL~1b+A1aO54@D>G0EA!qb(z5MjT*Snj`7 z@kAN9=JlsNt~Ca(6F z0Gk6=w;z9|Z<0))Zk9e{n-ct1tHCGJlt<08;we99BVQ!7SuQtIvUv*sBVfwD0uDb) zb6Tvm#eJ(_^@U#tmwXLx=h|mVe{Wk0V*(Afk_`{v1FqekEj-b zt)mYV^7d5iVD-r&DQx?_t!iw+LUT-GFkIsZo?9hC8X>r+%Z$)dWd0qy3jL9Y92hs9 zTRbuIvMgZi5l67>-?L)tlaG9k?)gbfOhXmO48 zb67G(#=~!3zhfD=JO+4FenqwKR)>Q%8h$0bXCH?FO`gHEagglj@VgrdOU25NwKl{g zQqhbr)!*+u79Y+KT;${kowoSXxSxw@5DX<>Kh2<;_q-m9ldNhbKAq&Bu3x}wwhM0i zLsR7TZ}s4{-x6o?5J_MQ-5jjv+4|k`)Qhg*p6cF{`-HrfO`z`KF^cgKWEVhmqX%@y z|1J~a{$TNk#xy>~j5poojycJWF9vzX@v>+{A}Y0oQ;D9ZsAQ=U=jKEu&4RTn+j*1+hTA1Zm_m9s_b0#^|VnFx5wRzd~vnOc)6dC@a>jSWc5tB-xixn4XWim{xe#`w`7I) z6FeQ{&*9>>iF$$+zfpu6N1&o}uBuMDBtc_(^tj%Yi@P&v8hh2arbSEH+e6X+K~i+p z8KBtzmj%$h^%JAF6mgH5CBl`HTxkfIG0GxZ)aiz}4-bo8 z)ooo>kroF>w^s?)!c_$T4~JYIXCeTEj88lDvEV|QpMf^v#PQg>&<2ZRPMtFU-0_~O z4Pi`RkbE`gZ;4+660)bN=C>3sEYU)w^Hb^&jdk-HRxM(Y*KM&h;w{U`=QuMavnQQv zp&B55Zqn{w(!X}o@ZR$D8ieZ4?{yD!@^1M1257D7`6aWN>u%E`?k$CgaxW_@q>Z4| ze?2CS(%fX5yA5-{|EVa1bueQXG^0U*@Eyg+Gq-Hz-tBK%aYc@ol+b-8-NLh`OQKv) z;KI#pgi~O&pU@iEo5fs?uZJY|qd8(LAGVYejkYA+PcRY>A`2Q^NZkL#wkzhsvB);X z)ag;4dmA33+I?CRORz)tY%O@Vsw5&FuU=WnAfZ zIIi|yt7fJT3x5XL3(PQE4FhQPDE=1uH4T6h#~ zQrAG&zkj=4F!4hqoSOI+$0=z5kTS)=YJ&Ni4I1{mzfhL)yBZJqdn_j!JQZ=nG5*}Q+hp_Zm7hEsTYb$1F05LY@xjco+mu&)Wfp*PE#u*YP}|Dc&~S3R@x@^i3KG2$u> zBOpTzTH?ZihpdiChi*3)0x+w)Xl={7l9(oe^%vMo>S2k|?hbNpWCR}UNY;M55cUsL zb~?!Iqrk8ay$mA~&V*cY*(i#u?s1UQBivN#cvfCvS@F`cV*H?iB0>C6gq0|#@7M_G zj=VXeb2I(g@3J4^#tet&EO9@9opb@tQMYB^mBZf?e7?p8V}Y0rYMg6bzawmx-2{}u zSq*EI0)-#IFM;tOo&R@F&N2`8Wja4BZ~AD!z;hu3naZQWpVFVdWWO_gRyLhayfYRi z`po(xzCDzfZ^K<{e5N4o4lDfQN(Mp#{3uoU!(^f0w)%K@jgb|{;zSj< zeO7kAJ*tvzD&6r`7qJ*!$jXhL;76V6 z5Z?0sjfb0*-QMW9i7{uAMI()thFxOPcWz%Xr&UY*RDJVGfJ^GE3Ox4>pwB6yBsgxp|A)mj$iW? zoPF9wra}v2C=@&Dos;>wgOZF_c8E9-s3M?LXY<>3J~IoF`ad3~Y=DL~7h%`08)tSv z&R*|Y#!7g%;lq5u*y`|C+x_+IZt@F|vd>bRr=W9NyJ7B=9!@cS${7D{d{#wiAxe)> zEx!uj=_Dx-f!Nm6au>H}TIHWUqb4GAT-u_d2cqaFUjS*{x<-%JZ2{fG8<%;@7c$%X z7~~s~`HXw?_?y#TtoQhbVP|&Bmbj4>fi8m$M@6`Lf*$d#b>P+cO#6Y!2D@ZiGU)8lzYbz zBzrTn9hejgkBRT!ny{Qm>cUJlib$=IwpjpaAe^xCrqorJqAjT-&E!3K&1`^f_Cv%~ zz7h6{5Pkx2gXdAYq}A+GDou?jXvYAVNfnp6j5Acyn3M# z;s8qz4?$9Lm~(r0B(9wEj5eip6r;I>_1$db2Cr28)jrd=UaUDD9U~%)$<1~T zL=mmn?z;v6@0Wz*OOafxEv?T;To3JxJ#1cfN&hMxF@kHK=yjY;kJ85-D@$b%e4%wm zG5XG=0p&}xQTn-)*@z-@XE^(*Ky_{R<<|iNH7DGsO?!7_)*IgI6{VOC{dukq5tshh z42W0&2K=cM0Z<^ zR|-PXf!H2|M2IVfjvF?ED!Ev4mLh{)|D+;Fc6-eJ0WeN%QxA%X2RT&Xp0~A$B%6sB zHflsoWi{J=19UB)3_eu|g1^9L8E(9i`6DA+ivQ6rx3~{owQ4cN6_4!3)@Wn$M{z+v z+>iDD!!E0THBe9O-tfxhh$zQo3Ms1#mqU~9{Vb6xz6Tc7&4K=bZMerL%&zG;jTn}n zQ%D%)Gy!+%qzO5h5Md86vOfZf)s4PRB*JQ~METZ=xuSh=T`_I=;l_Rh-jglJ;lZ+# zLLFbio<^zhxOxnjU+Jj`+OQ2X`vi7KTllxq5VL-;{R5+z z8+~8yQ>oe7brBXFpUs|rEhH{GdLjNC*9et-myI_ny>oBvANcZ&jIhfYLY43b1lx?M zX&X=lDj!KO;zt7uG)?wT$RyA!Yfiq8_>MCpnIxo+ND

N5GqT#q0#Jxgbb94*&(h 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%0D?P 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

<@<2TYLQJN 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

3&~vS!p{Udb9JJZ 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 z z1?~%!9F^WV^#2nP`7E&ptk#i66H7!ey>*$@4St>*XD6r#=?qgm1Xp}^Bk4bD5DPo* zIvHQgMKo@^ow_e;$D?rZc1jov_UeA;ID#U@fM&z_s`sqj+GbOI=hWf!8goHh|3She z(uQPc-p~~kRb+Y186eBfa@X+f$0Bd|>9Pfd){Jjgv(@QMoyfMp1~{7TIxDW(X#?rd zKT8Cqv&y}1q1==S5~h3nt5=PHmjx$G>DVLrn+Vf4D3y2S7~B14>Su-3eWVs z`!!$UI;;xGl}C=;cdZBp2=)E>R0OwXA6LeS%kgRmKUeD5Vh1wTpBr869SUre!tK%& z=;qAw7wHVR9A0_L-tgo~()F*CL1 z+Xc2Iw(LtHZa5%vg>53y#LF%LvJTF5*&`i4H)_`J$E)So}w!}I2259ztdsOx{r2q|ZE~%v`WFl+z+nsd?ZS!z4 zu``KGDH7ljg_cqxQ$(af;+T-bo>v-SJ4e&;=({6N1z(Hphy~d#*AmrrWEv2#$(X_g zhi&v-+NKiw;(EvPmRqj=EY6*mL^}%OEK!=bSY@CFsv>4Mdt?9PDC$Up7&|IKaY_~b z5zb`3)L-*_XxhPs9iBh&s1oBRe6m`7j)87>_fS!k6ObR(JAF_Awgn$CzyY14Rh7@_ zo>C2WZ=ggYnY}HG;}F4kZ3)%;e_CgwKt?USmk$y#6FiYfvv4@A$LXXk{jn7JvLc zA~wm^A}4)Fr5D`+XF7=mp9r3I*)_XN#M=c!Gl#wm)-q%|Kkk!s%0UQ%b~fUzwG zbg?APDWZ5$e68eSYDf|`2%X>6CtNZ0H|VSHhV8RMa+c!ov?9uoMEfcU9ZhGNk^cEa z+U#I*nxLit35XZ4^?zl$8J@}Ox87`8?}*DBBg`U|u`rEZ5$clm>_$A623Jp?jt5T^ zrKS=w-L)g7L<;c^`vBFV`yDg8BH2mSm!8Rs>rE|}Mcj$1i>wR%z{~>g8%0%uJ||oD z@CA3gO3VmyRJ4zOVjrhu-=M{mQ2zlaFMz&ums}N0=d~C5Dob+)z{OBRl77 zHbTxSOC~)X*h^QDAPbq{e7+!V@OCJ}mb|{z zeAD@jb5tlJYm_-t4d#Gcx73v@j*4vH)CdT+?*xbn&BSdI0Yb9Xc6b3e8jJssa zUP%Ua!zBthBv*_5U=aQ4rVkN zUk|o>O{@==HP{hLW0XD>_G3kUhd?(04uA?jNpEXF(baD3H`!ixk4TM#d0ZpJ&c(Df|C0FCOWpU=s`Jf|M}l7?=rD?6(p?=ib% zuTn)Gs8=c2`=!u}8Pt=@AOsir6G@|D7L?%(1XzG@V>h5#Enj5rjmQ>jDlc^Ni{18ox>?EDi#|vURXg!S~le##< zcc5kwuRiQRF*q2OA}n#rv%(>x=Kj!t`z_#U(1E^;wANvfPyEhCV~4aeV2ssHw-XM? zqq=YzN=4A8R0WfkC}sc1)@y1*ENPf;cY$|5oI6sB#$V?B8@~{8T8f>7k!>c8^{y_e zDj6FrZmul1vQL&#>;YZ|rIEjiiS>c&cI;uGI!hn+2HL;gDwCG^_wosEkcM)68+eAg zCjkYvB`XjHtA(CQ8q=EokUAiQx%T6|BbbEmD=St)5ryPf5G4|(FKXYNtdvTq`<^_* z8)!12jlM?RdI+?;Di);B{kuYTL_-R4qa^+_Jh{mhy}Bfu?~NDS)CMbfe-kJJ|B;dr z%;yZZ5;agDXd&;OoTf-uXJ*oyRqiDK-34}n@r|`n!FUezbYH0(;^E8DwT`u7aA+75 zrv~%zh8op>YCs`o^u05q@2be^Y^PGyhzr81($jLcWpUV48Az>w)ssA66`yso-?zK+; z&@$oe6t9%+H4fBc$H7t75O^7wKj?;Gg%L^C5ifC4LK2Z5%kUm;=_+}S!{eUc)&xL{ zf4lZ=#)iG;jpNX(Bo$r{Cx};1kK$atOH30*gFExZU#}1O_7r!Vp4Wxy-|CZH5WA{6 zTZ{%F3i;z^@_MD}A_^T`Da{%doa{CG56_zn>}3IDEjz zEr**0ofB>Zn$ew`l@wT136N{$w1K9D1U%NZ88%!N6`2Lx1QCVk`=o#s3M@EoEI|9= z$IQqV`FoumziPWbwLBZO5*#s^J;UaLB##akYw( ziX+wSYf99N7YwE5=mR~E7pY0}P85xOh%`+J=+okW0J(C=5sXxXU9uKO3)urto1&M*S8b(4A1@p zA_4H~CbrqR>v}YNv-5*Q}cUZid3F@z7LR!r?SAEhfu*T1?ErS!uhidLU+s zuAtl45N#Xn22|m87eu~#G`YqVc)SY02mUXSJMDH~2I)qeFLLAvLN_GuEk^THi&iB7 zmX#TZzK3n$l^dJE%**(15zP;n9Q4m?ftRQzs2ZabL_+GlVbm)a>ZIj$;8POm{<49N z*Hzhf*(Q7MjyyC%OY@PvrpmR%I60*8U=~#GfgGV9YMp0KX-PPhebNyKH!<80W4V(& zPSxSKddF)q7rV)xYdBo4a;J^Zp^fOmqv*(&IC1nRRB>FOloS`{ACNrgXFK}Z;)B+4VxiUK9}8e*QdeDhNXt%%khCOjP{svWEBbO zIxBD-MfL}vX-y?AaJpsx$ThW3bY;yxtzEtao(bMD!7>n`L=;p13I7+K_grWAciNYa zXw97RL@hMu`d(@JXxW!q7LS#xN59UARdVF$S-*rqsqrmK%=cW1SM5Mr&{7=xZZ=&QkeVfMDdgu&brL#N~!T#v0`%e_o)bK);zv9@rP$omM zbkWio-)^pU$kfL)WEV5)RCa+G^rhI(cC%-mDt4nZWwKB@YW{KL|D)_JgW`VIq~REW z0Kp}=2ZsNV3WaJf_rdx_W*$z+y=Mj$N!x3?tXfAw~C^uVyJ={ z=Dxf8>h231v}E;FkC?Z1tR&Tns-%&am+Hk(JrkV1yq)lg?ZmSIrL=K8+)@gLOo$5m zaj%e8lQn9aH>Q5g1aDhE-n_goSiI$Mv%ht<#b32~x5`4vQg_IgM>PA`+6iURf<2dx z#*rFR2C&nBCFr|lFbQHkZ`K(w)HX8}Bvutjo^#-_B6GMsh0)@TpOb3n` ze35m?bLHEK3Rh|={~2`MQFl?&Cs)boeMD=&V;j)$;!Cn%<7JlNP6h%P#vR0uqj7|5 z(c@Ig8{II%Sw!jhFiIZn?ggP1#4JHi%D+Q^zl;5#RNb*TesIUoP8#v!@id_cgH&>|jHehT72DV0cpza&LeqU5tFu2{X0!9I0SSsY5voCqroNX4%YqMWsK207ifdOr*`vXJhJFHlF8DH$Zy z@Z}P7KPivB3Z#-)u-|88U{De4qBabp(zfJ%EVCyh!-I-%M`Aj_&g13v_(9BZS~EUZ){*$=~O!-Jb47)>yZP| zk5qPHoNxR-7dYU0AACh{1d4?%B0}ZY{@2v<8FCgMO(Z^P*nIg*{T=A*5?J2MQOwsD z1T`zI11ZqLTR{79EyM-iyrPl8>W!B=hiIEJAS=84p&-ZN@=O+Vb7rVb9VY2 ztHzI?-fTMS;en`oIw3>|(bNrv)4y`ZZ0Lo53P=J-7wA$E2j*KXghzlAF7{jQULl_T zmhB8(ELew{Jm(V6n1H8*%y$i*-giffPks zm(9v|9`=Hzx9f#jK#~H1$pAvhpvgA0n9P(K8D*`B;sZ#j6FBq5x{tSbbXpCCO78!j zGM8OsF}NbXkpx1|!B*Cq5B@^QS||&vkA+x(R;ym<_ivq6Rnz;92it+R=pENj?oqJ7 zrZX4Kst1be?hn6*{mFa;pmWHIpj{&KNa>VBS*{UQZ*T$)sm;GR!KN0D33~`ovY4%* zzk(jw<~I!_6bM_aeeU$VS#g5Sj?}ENNpk-Y#sFzav+nEftxem1M`aPAqbj{vKJi)J1+yo=|c-w$*-SDvwtr} z%Sj7F#m(046rX}vQVqXA?jofLvGW^`0gOGZ1`C&lINxC{VpT{7+#trk@}FVr&uf_- zLn2ox7rD&tgBFlBvOAP&(46uk1OtK?BcNh4(y99dy&rZzbjtr=*BPY%mp8#BE=_u;zC3wFf`Ao@m|u z(#3&ZxnT8vHP#+a;tOWIZ zjJeO31wYRerII@jfgc1%;*WaSkS#F+(e}X6Bn^`0fYrBATfohq%Hft4ib@L? zs#ghoXl>eDoGD?OqL(!Nzf|4+gEfAmP(Ed_D1nqY4)swiCqmi>kr@LzzcW0^$#<}G zde@zb^~BA|%U_P7k!2(r7bWkJSFkBBONi(bF9M(xQcjFvzG$L+Q4r-%Mz2clMzR2L zg0r+rCo@p;C?vT}nld|oeFLvb=pf(Unw`AQf%`=*;)%zT@t7lYBka4h)qAu^oC73* zM6<(A*bYqPtub%hYsJty15E3}rQ$k~wPe0L+b<1}@#Ir=brK13US9fS06Q4QV~N_b z9F=H>tCudh*n%mOa|#jSkFg)k7w3y}1&3US{w~|GaronXyc;CA-)Tg}7%utU-Z&^GzB^4;PixT?S%wWRp7dfx18R0)~ z{%yfeKh(LfSw4tVUrzsulmhLUhCmrc^2yr2 zal@yJ{RLGQ%T4`_KPh57Va6{Gsc|kr;5<~8A-_E8wccNy) zDKe#>N`~uKrIxC>!7vRP&j_3+uCX(|lRzsRPgNpvWcN}c)h{_5HbGEt@2S6h7_DAm zM{@k<;U!p0TtaZlFNQ>(+MxVA6@Xjv$;5!U_#^XQGM)x9pvBiTQn6m&2dIzIh8%8O zJ6Bq+5b7KlJLdrjCk$D}j@Jid+(sW1i1~`wFH(U22tjH%TQbpH1;l>LZbE@sz#i6U z%;e>M9|-&|9kZ24ozlmMMWa^nV{0=QfjoTt?n)qDDI{v7J9;i$K=!fLM zG&bhlIgTT>b%2$*(w^nn`zX~~b|q#;svtXiB$eI+lhyO8rkaloRJuNdXm!$47?PY7 zQf;pZs*lxcwF+#!2fv;*rTk?gN)p3z6x+lu#W#J(DG(almVX^9PAv1O7Jnu%8<@ZB^1!e# zOxvAwBXb6M6Hk4EbNfDd- zA1hTqS5cupAR65=m?L-c6>jrU%VMu=eDkSQyM0EB0*~3deCC|0KJu3ewLE@fTcQ`%xm~FkYEo|1?}W} zzGEA@4F2x_unaiE8T5zfSu*y8Y7u82&O?`E`5m*VuWbJiCX7RuNWmME=O_yHZzpE$ zk9|;DG_-I6^cub2yrdGjUyLCf2FxCI%N{@+*-rcWJunZ2qwIwMDuA>h5cGd6D%Pui zuJ2c!h;aok!hRmPk!iphOvy10nh(!bu* zi4Xb;P!+#DRcMDK^hS5D2i|5Px>%m*J0N&ph`%*t^>O0&3214aEOkZvJD8yPi65wx z0DQAkQ12UbvPi%WjqC_}kiJw_?8zLbs!`S9_i$KKb#5oV+|rJ*gh+;SuZm=XqJkU+ z8~n%wnro_kRx~T_-^wK6ZE1yG9CiIY$+_!fjSYO2Jx;aB_+z}>nhpk4Gv;yK02*|r z#El-XK-6-n7(g1F{Hg!S4=`-4Pl{h2ss7vLDw1xHuh2P4vecU9^q+>Q_G|qebwo5m zK$yJPzv)vc6hDL8cDJGll-M>Ew#t}o zZ9xP7c{17Xxc4*)ZsV`tA71l2Cz;t5JO{9mi{;cZ8drJO|GjZSOZ>?vEA9=EAp{iY2A^rQ}gqmZR)L z*NHUoJDX6WyW-bXfC90*0afj$m7p4U@yDsNax9Di_3V?$Oz)cF>&%c#tGVZBsYQxge|o<*E; z+~h!ouU&FtJ^3592)@5pO;@5aY7gM|RN;wjWX+4siq6%J3XZt{Vqr*MUyK3uoIqvN z9or2nb~s>h-MC9)*T)7m_j@7PbIDow0c|g8M^|l|sbneT5jWs^;awa{;#!{@_!}S) zAlmtA+rD#p^liQze(i#Gr2N!Y0-{~{3Z&r`yNBqBY>FT(=lQXKxk+5*z z1Z2Mwr=gR;5f>9z`W;FB`d2p%Eln65Qg&e~hRJ8;#9X6ZrqA)@Qpp)zEY+7hxJ@PR z_u>1)ot3`lckR_HKD*OJ^@!E+qg=5=T- zvoElYIg3!Qrg0y6(z4wK*gQ4Cyyw++i50T7{%)#dC zkzF^+-NZ(yaNFH=IN0uJZ8hxyx$Np7r4Xg{`hu@$z*fGDKmB1*n6(|_Q$E`6jhvs6 zXUKxSk0)i>Ejy?~sxr8pm7hDl&UOXMt^9->{#6+b#d-MRs63OSx63QD=NXNx9*$EM zQ#zAYq0(>13hw|Pp(>9*Wpgc$dab>xfJ|3L$$@cZ(c%_o*@<8lcW5&6+lO0ngX)(d3#Y}2i8zGI z1&Eovt{?SM#9B}U+HQ>Aj3}m&xY%_FI`hOL7%<)NrW{NT6_3A-N>|!qmuj9HxEiE3$+pEpwX!`%#2Cn~c z(+=z)o>W#As4FuhfjdiGbC$W9ZhM}(A72sh=*&AL~`{n=)=H3sdbd90bIu0?7 z$q1r`nB*92Uw)hqEPP>39q+;kcBrgkmXH^<$CQhV%eN7=B3Ul}ejpWc0woxjiT~jK zHU2{A)ltf8j6N*PVZ;sYmsu7{_F>g)#}P0YoY-%jcMQo+XbX2k>Nlv32H_uqgu58} zMt)|JeT-Q?GSL*8-{j#dV^|jSZA{V?owd4ft)+hGL|Z?0$jPLACes+|I2^$)PNqUk zxlO6?Y9hBsm9kL*1LdDRWUV2S+OLq_!FJyq`K8&ZisSTQ_hx>23cSAJ?E?^@f5oKt`9+^-I)N9uQ-*Bxc2s`!VVCo0%qq54jim>p2;}#cd|z=kEj~y>H`hodz&_lpX*Fzn>9m^qY1|KtjAXKwc3!^}hI^5c0DOsc zN}7C?deF#?I2peMHu>~e^SUA1$#!?nml}7FjE-|-&v?e5eab**Zam+X$YQRI#N|)F zAg_mqQ06CBU8$&ss;}YVvSxwfR9r`89(SYyYr&+A&fAckz=SYyF0-W;V=7nDnFy6^ zEj6N}H64DayCe&_{(R}uz!WX4O`m(R=&$N$A%?3n$ofpZR-b;BK=QWliT3_86PNj$E(9C~-JlzE5?qXJ zbr{>%c?$-u!pfP)z{}PAtu-GKI}51CA-|_ZKkVfB3rLE=v0F4hI!>tn2?Lx?yY$^T z;RnDJQri=>RBxMypG8D*C}2bn|LTb(D>mGFN|!8!VC`Db8m-Mg-^*KLHiMid$a(BM zvS%p-2vT>XyWA!?TZ5*uuH3+uE!FqYXA$J0n}nQ=!FKH>p5tr}y0roNF~`fFVVE~A zJ%QsdFAE9I+?pz8y40X)HyWpUz?`=sPV}Rhu*tvo82)RU;s5yA-&yLXa_xl-6NKj7 zpj$^80@OcPMzLebNC@QxR)*%*i#WvZn?~&z)P>8%;5~OKr9Ogh;8LoYL?4UBfcEjO z3UJqi0c;&v?7Nd1!AEoL#W&2OQnwrn65&d?4R|p%K?M9NSDSDCmJc9V6Jx%{bO#bd z*j-2hlWAq~qPYaw-2`>QT}Y7+3l?^1fJiv zE82*H%ASXBwlFt0VxhM(yASXaAB~ERDn|1E{qAk#n*gl;bVL)fXXALC zfkGzabJF)s9LUEnh0NMtv#*?)zmcqv-1qBmUI%l+yJ53g&abf*9iSDydLqurZSvOK z70AsV9NG}cHhu&;%YFRkobH4t&uka7+QjubOlT*N1a<*wsf$ms#!9!|lT+Y)x$C*> z*>%?WJ{Ci4{ZH3Y`HjpPuQjwWs05;*uYqDy!9<`&ds#Er)Gvb^gKtoS;bP#-GMHnD zX^^OX8AJ*>0qle#4_#mav-GP~x|^##^z5d?>>b@UHJY?}uh&(7`fZp#fXq7>;ajYc zu>Ptp!_aR4dN$!Xxe@@ip$J?Bn4RFPAzsz*khMv%MzStN z8YLwz=va%>T2H=g$rb6{#cf53@?@zy1w3p!Cog3k@8I7Xcg_aAIyS5Z61%!yL#XG z<~Z;&hqQE4b)|4J@1k`j~pBaPA39KvMiEZ_tk6%CY#s(nQX ztObK~_%uxoB+$OJvRHz!tCuKGEj~Uh*-wrQwaZ@8I0&K$cudxF*-CJ)I(hxRGsxtR zn=Sj2X~$Bv-w!rrGFo5T98QjpryM;mQthAtbyxu}9Q;Q(A_VbJ+4y?Y(Ye;AlwG}f z`C)&l((Y~R>15D%0*o*Jr#+d%e~7Ux)RM@swvhScFoR3RzIr0+Jil6_miBwb4fP11 zSgf2O{`j8a^E^V$J5dnP-Dv|U=Fr~Hz6sygq+h%~|5a>4J1~s(T7Fy<+Id+{(CH%f zN(j>kZT+4wT2KU8VX~j7n|uSh^z|SRo|9UkeFnK`<`3NChug@>23Ol33TwhJnaD@1 zRR(BEc|x91FOyj^sODC78WdsGkl~wp@=i;me|*l2g?aWhTtcZMj1ggC6g_V*_9H5S ze}zxufxgM;*lsE+C*^c%lLECs;ZAqrk0$rbR2#Fb)PtI43OsWP_u zgH@4(&{uwx1%8el)QH4W#@>k9*K-wF+Z$xlx%#TR=atNS;S#WpNKbR2=AhH6HDcVmNsesK8ZznR_5#syf#&-35HyIXe0YMy_y{*q$ zt#t!;mWMaVJAxOrHOB2=DXZMs9XKjhJVjAJyZ&vncX*G-Y*9bh=)R8Dmdq4jD$c90 zwh67@CVsa_Q7=)5aYJrN@wyIntl6nJXCwP4AcBrp?&gy(l*FLd>pKSK5gmI=Bz0M9 zgExBUM;4lOiDFWeWy|AbRH?UAuEfk+7voD5esV z7j7LPJ(No+-mYybs%{m}l$IZjq$;#Om<)+uI~yGrIwp=>m7iRDcgI&-m}o$o$Eg%o zTc+*%3%`v`9Oyh!w6S7f-F>n^7o5zp(zAW^9X1ue@q7)Dge8P~O$&4V*dnc!t?*U5 zF}gicixj#~#bZt-Lp-ue{LjM8{|!$79#cg#Ua0LQ>(@bvOc7t%OWnh@AWEe$F$&%Ksrwq0^q}JjO{-@-j6HAI zKo?-8$Beu6*?Un<^ah?=r6nV*A?50SKw5aF&Io5QV^&9P-M{0k4d-^hMfs zX%BE95OM~Qirtfuh`%jwS_r5)Zbr9UUJ@N!St$USxZR>7(rg9&ml zR4>+3IN%c?_)uZsd*_dg$M6c!cG(Y^Kj_ria2PE|K0lg?i8q^=GhjMTrWRBCx7HAK z1@dY#H`qYfHPZpsqPKEw^%U-YhR$O*Jlb^BYESZ@ISGs;nqD|6(3})hjaD?^1q#8Myraj6Gm(zE_zo{Za-J z`ZtA`=gGyzh#JrF>7y--0OPzbHoD_QkroA$x@-iw|IlaZ6C!Hd0K}9td(dU;^dE`a zOO92cy-Wg;>7FCKYH=!fp|iZt6B5^G6VfdEIai?Y>q5^{-PUSm7Vi+qyN2Y;r(w*{ z^8s{=|C%q2vmk_f1?%_v!Cb)vS$n<#F)^-I`)G<Y_wvsg{X{CS+Wvms*wWDaYOrzpmjQwBu*(9h)mwI3aTu>a#n2J0(Abz52)-165a zem83+J783TP{`?5NnyMh)kC+QclpmmBY92uZ&8W)0@;)I5ABLFR5WbL(Rjo+yR1M9&d=8?55M-76yOXmFIE{FBntPY()!%R+b--{ zVqi`}$X|=-bJ>?-xL2WDN7y>=6@u#yhytL(N89dSVN!%b>seqI`#Py$(#_^}nHfes z%PkMD4vw@F$D6hsFG2oPyK?t}Bvx%mUo9umGZX;bUiIsuPRENw7xqmCAb=? z7`6DsnBhSX!5IalFj4na2ZP_9geTet+80CFVPk98r>&efMFVOj5%<%_tE~JA?Pa$U zKb%EG@IZcW5r)L}u<96mlC?Fc8LtamxZ9@1&7(yYy;x~Sg)sx){)Dnzs~(Ol&=5`A zBqX{us97Vk(Oyl=>k*5L%VKlz=si&Y-?{UwVtFk68yVUY&p%<;il|gHX=K4zLD?6buXjb0lCThI;XU*5`sJ<&x2uVN$yHmi*feU&oz<^Stm21j{mq#Nw6*Ve$#eM5=#7d0#KN9-? z{s4au@~6vPSwf_k037V1^%=_P z>-N(F6Vz~jCr+XL3CpJ4EwulmE~a$h**Yuq*lG2}ZJ`Wts05vV$SCQ9M}SIk7-{F) zS0t_s+aED=1pR09n?O-v>j;KP5O$`P(OcKm%rjP5=L*CeQu@|o_UPlDZ4S{a$Z6_{ zh95gq>5Y8=hA-!aSL7%ie$va3Kt17GsN|&@?`aK zZ(LCtu7}7`@$}oS9%0+dfU&Z|d}Wp?is&6fvoskbi+OvfO$N_$ zrXb(=|8p>QBl^epuw-+G`r;_bMe0ZG99N05F`vfe$4rUVFDc^b)tz?HgcTf!C;1&+Me?H6L-7W3Jz5%#QxN!nI4Ap>OVY`eYHL~zKaEj03nB!&2N$Wyhy>kv22V3{>2^orc!NJ>t1_#zhI5K3t1^- zKm^1Mh#{VqxxH{Zu1eTg}op}P|n_@BmA@7v7jzjgUp`2x0+ zC^fzZ;4Gs+1c3_^&8A!@+`aMPdi??b2z}l+uIm4zY)r3nv9EwSlpXTcBP5!XC;rf} z(bx8-kTc36~Zx5VF2@~w;%~P#Oz)> zUEs`@_T0PZ1@>y}-_%-LEatw+x}idPB@B?=|MkZx_lv0F)2=OD!_czT@rPH*?hO&B z%q0%FxY3ne>LyZq{)4@OFJ`kV(<#(ttd3QBKj18(|!9NBTcV`;6{`JE`XlFVHg$qy*seGKUa0q>fNQs|X=A zg%$TnBP0Pz&m3~Rr>Ev4%5!~PA^SVcL`F$FYnhz2cf#PuD@(b8FZDOB9HnO{8Vc7z zm+xI*u#T|4V$Yo!j{K7QznenbWk1V}4```FWtO+2qo=o{`%1gk?oVjmW-U@>YnK;I zd<$_QBpVNfx@p$mxbR-r6nM+;a^~ryqgNTJs>JWC0%uQmQ9m9X9;*{Ys{p@4henME zI!n2A$%D(S>qr@I!Ki1}Hj|IezOgj&kjgOER^Uk@{F*Q8QxJ06@+C>J+V;o2&~3h+b+>_xl$13_Nc>?%5RMwCgKxrql+0 z;p8dHzkxNDOQ5k@hb(+h>*u7Q#Yjn>4ll5L!JJUqUmnfE-{zzQGTbw*UA%WPlV|V_ ztm_4Abmsp$8ock1fyDrQ*Yz>&58vLmaWibl?t5RY8pREiPDGZD<+LKYPl?_i#ZD?y z?oMa(aoXR-az38eqvwpZrQ@?DNbv?~!*2&=$EHGDt*NAOxwr^{@d`qtj8eyWM z7;2$nTQWKtO7BkC$8wmK^m@L&JdnP_xmIGHesLtI$2awZed1C7tpAZ$`8-WiyUVZ9 zgu>_4P-ULJ7id>@h|8XKKSqjV#veP9_4UiI&jXY#Ip5g$jQw!SLhX{7LTM(1k4tra zb>k?;68Y{R$F(DG;4N-$verRG53qehPYFhN!)fv2ba5GT>%H>~GRUX+Ze?e%WDjEq zdAJU=MF#I>tP|$6fqZ`PF>*W*LHho6OieB=|4LUV+9ZtPr4fsNWTI;nV?{RC!9hEp zQ*;$o==fnKAAbQb=iw*@uJS*mGiO`-^p)n19o?5-%yfeA!6QvM4;|1YS-6W0*l{s&*M#eH>pt0}XNEM&qYi=cH%Vc;1$Pb-IW z+Otsc7I(LDwPFOfJVg{b^?)eKym7^gDj#yDXmLM7@JpnOY{Fc6Px!l2qJ+o=dVc1( zPi+`=JUeMA0|IY6hh=XFaaR}88|iT8D;!=kTwARZ_%0HaT%fFjbLg~Ot|`0{m*__A z)j=PA`eL0&)o|5616oOZ$`_fy0DXGnOz`2RYYi5vbyv z&(>DpWwv}VqJNqUP5V^oQ(XY_*I9fG4-Xy>#NTfRSW1%D$QonOP-sWW6R{tL zvRIkW4+P%Z$*0ux5a*gENW%Os`AI$$X!VPD#F<>!@W7^b5-=Una8V(W7T+;IQe3S| zXgNfC%Xa=Z?vE@tYvXt>r!FpvX6=wey#=mDg(7 z7W7b$!5=tQ3(apx1bjbX5o7k9u4%rGA(iwzoky`sVbK)^``j6JUr+900FJH=r>&hL zQlHM*R}e`pv8)$a`>W}L$rWFFNQKfRbzrnR16aRY*^7Ke@Z2*VthNjCxLXyQQGsz>5 zkt}|MGT)DPqB`m>@@J^XJr9AEp<2w6`JnrH7N2R#c>J43=|*VR4C)sxhyQp1bW*oo&3G3Y>V2)d=wj*vW#xf3n8@n) z*k%Z2Mk(UwZ(V7b$6_%LU#(2`)fty6m zr(E-5gZc|zc%*wN>ht&PodsVt2bnRdB}@AS0jD_F28S|3n!X2~b&bwj zfSw;yKtQ%ne^ij57}>M>MA^@@nC-0OV>pk@ddPU(Qnk;UlN4yYyqZqWHCM&LN%sB7 zhf#`nqZ`0=`^z|W$t{g%;o{flEbX6HY3LeL7T6|f=g|*8MVFT?j1%6DPXta|cN*7t z_VreBItpK_Bw1{*+pCNcH@?^~rhxy+RlRAI1cXAXEqj4KXbgJUOjQ;=HU^J%i6Qb{ zy{ZS62wOv$;8lXgZ%)u*o`*urj(ADTUnU|R zPocpaP9Pyg9xKff#X!DjT$PNk;6N|*!+ec<8_)29Zr{&yvldc;d{NaGryfk$+RdKo zAeG)0MF|vvhCd!Rq$4&W=-WEAB5y%$eJ&Jx97}6_580zsIslX+7@Hdb#E~8+iZ(FY z(r~c-I2_#o_2vsMqjU^@>}8F2YL=UYs@}a@&F;0Cemnxz{ zaVSE0nWi6T74v=GCRcd8aXnm|B8;q9dM=QI|I=|254{f3G`Dye(0+IIa>RS@yz(rP z79!ar%aW&{c!^Z#38ch0fP@vVBmY6Wz?J)OI;+r3JA{I>vCL9fAvwrqsfmUf>?u)(Vf?-(y3H2T;ucOkD=u`Y|Pj2lkFPiJ9xtD!Bl@RL{OPK$5qf9nUnc*tuliS`?`K$p>3MiN>D0I7$Wo92n17M zDSyd(>=^kuh}(%tPa2oA_esbv^drS5GfYvT>^XZa2@I+nQf|28n?*s=PnxdFoZ(tn ziIqlg*UcTw`>oS{QJchNBT^7c<3fk_tOGDW@0cAxr#P>0Gm&_L9v!&@nN;o4f1ym> z7%6_j_*u5Agbl4eGE^1SS=n5o~f zj*+ID*%YA+Vz81zgV$#7C5mHKui>1ay#&p_?#5xgA43nz5LE(8(q4&u_p(M}zI&h= zGcR;G`NiSm@Mo%k`>r|!q`054odDf4miY3Ige_V9lfLqmC%GV&fTD%Ey1h28SB zlr77;>6a4;sBUQJ`3bQ3AqO%Any9dz)HmskkJpbu&DZ5|iX^6|A4p_QZ+=FtArfQu z_NahXdoe!xY0eVK%A{C7)4o*P{+L@3-WMgl=b(t+R1tm;6l8jx!ruVai4qRznR|Ce zS8c#G@`T>oL)t7!{}!h>g?h&W3b@BFg-urw?se9*{qJm#d16P77FQhmXt0pA+MWAABc? z$)~gR9u&6E9A9M5s+wZAiH7Rk7lw?@mP&|CM2z%ZMwLxXYkK<6ko`u7j% z6|kw8?fk|oAiPWIa`X~?!c@Hk5hn@$z}L;w$$5AS+f@8wC>cWxp}4mhkZjbADGkh)yH{F=rO+>i~GCiG7{l5-SXqA^a^ekTWvZdVr{ zx8j501EKzYT{2_RV{#(sS$=29Ww5k8qE|nq##%M=WLa~f6=|_00$iC?PPF0b7{FW*C8GcNKa}NvIT8MoB%D)x_Y8-5e_Ti!J@76CzK?{_i!NHY zPKxjK)-ZG*3L+Pi*ix=cA}RkV+Iyu*T-g1=ONvUeGWF|iZK_xlML`b7TNNoRU0sUH zW}}30$Hn?}4{n^YKXu`Mx-4HbWjH{`!R8GfXAL-@dEf7q_pI=-!;u=>OS46H2i7DeH%vX{2v~xBkkY7koY69#Z{g7Oic;{9uYH6P}$%{Q33el9vN_ zE$KMNd&Sr-@0NKFqYCaKksaAUqveYuyqoR%u^!hZ=Oc~9T6bcxXm)#X$!c*gP0m=b=ST(=66(Xi@(deQJq2NEY$8{q_a*g9d(F97C3CJ;&g4P*BN*ELfM_2 zOX5{O*+GQ}+(D5=cj8HfcfiY$X*CyqnQVuMc2po4%2DwA(JR?Xy~uiNj}v07<-6{2 za>C{AlFQ}JkB2eXBKWwY3V4QC1Evmr_+FJ51xKh(h~S4E#oTZbDeqvJ?f|x%Nx**7 zf=X+&ang#*3XoxSm~sQqr{i8~3l#9U;(N6b3f0oN(UWgLgor_sAYpN}uAz)LPm!-`9_AgTT>Y=SidNe~C^45B8a=V>7 z!W!Bgj-AMDuRmz;lUz@wF+%HW@gpL-^Eht%y$E2e8<`5Q$5X2;?6hG@AmHi0y_eR; zZo4nvo-Q0<*60UBLs(ME`=BixU`0G2v%72$|ERogeKqX8=gRB5pPHfs_;x?I9wkV5 zo-VEpG@W(4M1+kc`Hio({y)~<0xGU;%Nh;@3vR(FJh($}FFZH_f@>hb-66PJ&?E#X zAh;%2(4d6{cXxO9`VRNK*Wc)`Z+GAK|96an!6>Sbb@pC+uC?Zz2ZpPt1}G(D?yj?7 zEnA3$;g@f8ZTmKqc<$Fzx2}$tcmcj%;*8rCS^Ua0B%;cFuq9&yhiR(^)Kq9AaO;jw zfYNx{RjjryGW(Ui+>>s+InQs(#2KLftuuAEP<*nT|2&@Y@U{YIPrlnt`E3FvzL`7i zF#EJ$I+-^Tx#*8EtBqW7_wDi*c-Y8<(Uq~1%I67uC?zEl_{?&8x*o$%Am{^Ud_ zfC)p##v=cm$$-RRpHRh1z(i?hDd3*xy@S8XB3@3NE7H@Q2|bB%?U-cWXfX7rWD#B?D5tid;Ts|DftBKf?I6Y!e?^6!OTah z?YN4JI>M&Abg!1fcS9VQD%PmrUL-s*-^Q^F-ox{&bI9)(u!~)e1h1L+x1yB$;+j5p zeZc*QyLrTj4vcV-$oxV$|(}5J~tm-jJAs8Nk)F+~)vo z9`SxqR3zlRq1S8LZK*E1g~|i~6N4Mmgh$+*n}iBC+k9R@uEw$D{xX+#el( z>ww8&JlO)zxKNz+O=r%+L7@rBYvX6?>K{8z5eX8nYRSE8)bnw$BBgKK_5I78`LzK0 z(bPW#3N<{N7YCN*!=w~Su~rYufr^Ceig?~FjJZgaHijV}78DQnwfsslK`XWt>&Dx{ z%Mg9S=PhZ56vBK`yPuDb@x8oTs|vdKwI$<3_hnR9XKH0$d+UC^UVx?0!)Jm(cE6aJ zCi4I?0}{&HwsXZ@k6geYXxe#Xt@%*>6I!1%cS*c?1xt?9X_?ESl5L5;hA5G&d}a&j zYrlj3kFkvR3sFTA0Q=(jY9TTez`Q_+tV=yt!wNK_4&WwjyqaYP&o5I_`4%v$?Qpq3 zKUg1@&EBh*7goouYf2ezZ_`=yo9g@;`msp4`w%JS3`M8F{~=vkiR*>mki`$M_Gy>i z?UBg5#q;Xeqa}^-fV>p@xuCczy&NYpoD59tm+6Fm6FnUG+$YOdxt$leY?{6k-?VEA zFAvh;15mMIQj4r!t$(zRBz9DdW4oZ2>j@YjXB{V%xi#I4oj}4$r~KXbb2(|UZ<{pf zZJhKp>H&#U=^aa{$Gh}<0g93-RY@!ryi+0`;mTSal*8)e<~kN&!YQ=go7`tjsN#6n zY*g<6$9lb&$V2#S@n5Qi1w3fnXqM=_$TR&Brj3JJP}U6}&v!{3xem0{!TgD%t}olM z4f8ER=9>GX`O4Y6#ah8i6adEr%gJ@#di!A_E|`oRD2wVR4P{wDRsQ}b6fUQEF+AJX zn{5O0*5VwHu*qh_6&<(s5mI(mpcDY*cLtRf9#l^vqhJ5guuQpJlm<-o8vAMV(b2dK zzno;pe*n(}J`Pxa@)#is7mY}u*yoQgJjk4=FAn)(R*ae^Va|C{D z?XstK?Pz)pJcWc=YW{OiJhsCA!Xq3mAoTUDz-RPjKGhj??Ief==zw$E-2sujK9dcK zuf!jSE!B;~qx^#NGxH&~Q0E7~&*Vlk>lU-s|(}7IUtF9zIT4$wqy=`>4W$x2IV!*G6umhCBH?}LzW4?ZZ_NJ~&HHL7uhSY~|e+qAwzV_4ufXCmKzZzw!6C(JddgTsXkWDEy8F{4F z+&9qKXrqWwo}suUrMztsqS4n@ftt~sEwy?`u(9`JOaT9YzaaG+mY!*# zUX`&0?aKk|JM>IpFo0X2Km*Et7@!>~xns^(0)^_>_V$5h)fA%I<_ZEdjsjrw+$0eA zo!~frt+e_VgZR@!#N4S!1dV|F;ECd-{m?oRrNMjMYU{hy8(8Z zc?E!??H_TQ!(v}xn0>i`I3k?z>Wl6D3@?xENN|O3JEFe9B}sjY>+FXLz@&DhGDo(} zHSWtQ07Y9*GC}u9YR9;QNEU!;BeH)OT`W=JhWm7h`$BG}-xb^2O<`_Skw|=2nI>dR zH0RWA3e zUDv#qaUy&l!D0e^^mpW7kQzML{V(nFf98UKa1@@R8AB8}T=j2LZ8#1U^dG+Ar^rdk zzYJED=;L(}15G435Q%+R!FW#NixrwB)g!2n73|$Vu3RVZQ-2yaoI=}fm+sD-5))@! zUO?Ez|9Xc>;SR1>;Vv$}iCiZj(tYP*m%S0Ai+`Y|DE1!n*|U`ZhZ|l+NdoIxSRJgU zyZqz@E!~S}p{+$UEVJBlY7jXBvT+fPY3k?=hHbSaWQ zccwkYJr>O~{7Y)Xd*#Lgm0~q>1<&BqzJ5^!C8ew$MPS8m;o-JEvb*EupN-X*u$}w6 z@T?E&QDzh8<o7T=bQr@DoUMJD3NV*b^@-6@3YLQXm(QopGDV@0lLjG7)z5L%R0l z8`JO@+@YSp!%TgwVBGt40sFdNE7EMaP`$HPsnLu-P(;#(e?EYI_X8sUZ;N%oGn>@Z zr);thvA!-_O)h&K!w#uMu6O#r_MWWY?Qe0$ws!QSLNft>g9Go47rTHO;=pPZ=v*lp zWNcf06L5YJB7?an8-_&@`BJ1)eM_yt!DL6of#0H!fI$wJmE9FaYHqa>qY*MHT#6pW z>+lo5TScs)XuNz$F6zQDQbx7PR0U3@wLd3t*}+%0jjX;lFvm$M~ZG<*iR#~DV^WFwbB`c>2UX7BSVmtpvoK@#?u z@&psJ7pep4KTD4OAW&^6elp-G1^1|r{aDQUfd5Yn0ZzOrx%gcoi504|+FM+pbi3p~ z8J-OAAmtTN+;+woNoLBmUlCSW0ykoEwgE&|nhl0o{8zO`ez+%e?4>q8QO61u$dxT%<~0XnvoPe#gdU)O3ucd$LNuB7ZI$N1;rJYnbK>`)#}ZnS@WZQj%_@ztVN` z?Tz0$*XPU5S2Ny6i!L#QMH=Uk+Nw~3`9i1Zp(r?wf!ra!7S?Z`M$Ibzb~iMXufGU^ z@IK=HXySxfcwK7PqaokneJ{v<(~i7VbMw2vrYDkWv%#+~^K3cwaFnoxg*K<IK8) z^bqlb97q)O>!%l6^D2m?yVHEQ@3!O6Oub?Q>6l$5h~GPESQlyR3$9$}jSpN63;{ir zch^Pb?;gHSSM4vd;!Gk#WL+fVf`eIj+~-mWF4vMqO%pt1YW`7oKnROuh1>u(mB<4f zp*CbAMsN7_>z&8u`Up#u1-uUiyFv2@f`=oVN`0D{6d_AcJuIb0vMPz&dmw)MvHwTG z`b8ShdT@xp|Mf8!EgF`}i{70T?+F@qD;O2jE<% zG#uE8*1z_B!}xq5iR1jsvbc?yBmM zti!YI`$!js9lF+SvgpqKrtSlQ-F^IFbZBr2k9 z=DMjm)YIK>y#K`o$Z;N~JmV)E<9zYID=z*cSKYZkd&Dm#mny2JXpD#PD^HJyjHwJ& zcTlQX!Ni3uCk`P*d4BEF<;kSIB{&6J9EjvK8PuvUs@F7gHdwNOxKVYRs%Y}?6rLp) z1&qC*Ws2x@kfThu=yDjE7w7wgaMAABH#$7oo*p={M3Ntab2|h^&X#)mmkH_jaY6kQ z`o`h>mNE+S%Qk%;4^VeF)aUQ=94=0INfj#F0@0wqvJnV<)PotMh;*-Tos%h7=-V$^ zXAknyTMFb2c+|g9an>o|N^w%Jk=h}B&Ad#j$Nn^8GzPigrz>1l*jffNFNbv-qk=WR zX2a9VJP3RCjKL1_$=_oBF@V7SC=T!lfV6E^*Wk8h6p~YE zV57C1t=Q4FCwU#E4!H|q6rlTr37VEgjw8#8nVrC4ryktW;xIDdoQ#T0g+#G2NYSfg z=K5nDrMnML82Ced1`Icyk3-fAM>B02lXsS6y@1TUJ!@g)5h+3u=waeBee%4(7$TX}A}-PURS1h*#3>DvTu?3ylPs$g zW&`22%r?^BO-A(3PX#&-&w<$-Dn5(c^(i4fyeI(+nUEV$Db7hWxE=6YUKUvNrr5I25z_H74!E=R$fqQHL6@T^0J;fxJDibktixv& zML7z*{l4C-0ZjQjuY14nv6BnAMaPnf(mrGkPPa60PagUw7i;CfL>|uGh`}+#u43Lc zq7q-dL5_o44SnJ-OTg*|x6ZEm;bgr}#q)GM-{<-iEnuoO2)V<(J;3+Y3ijZe{p67?m9B_SXX?Ood@m z4Aiysb#4?%5&T=F$Z3dpd(pnWQYf~8)oO6@Ah!3IKZ|2nS}v|Pktw>yTO3N1VdE+e zuxQqk|lDM)@src3%kExw+^yvFf^AV}MGGkSC$#(rI zz9vjcc!6mK$TnWQxV~j-oGe1|8p}fKtphEInDpz=SC-B>>=0)lptkATS<>qpQ#zf2O>Q5@s60 z@vq1VT70fB2C;Sn6r3kmvS*MG(3R}Z1$Gy3;D4omiUW6}YZ^)BX}&F<=y-WJB}Xnh z=RY7Vn#|S|{n*brU)u;m#vHmDmf8lS{hRkazf5~hAMi8W@wz|r7VC(=ImsT$zA%%G z8>)cw9Vj|lYYYkvlmLY2ABI-R+Mq*}M-(qUc#px3dc@E)?EfLMe`-yeg7Mvj!;mEE z+UtT846sbF=}P}8A!OI+Kwk=5 zcHHLgYZcC4<`PRj)K4JLYnK{TW)yP}e4XrX;Z3fEx9R|{_J>R{S-)XZM+QGZ z3}e3FFsFD0juK4I#8?iK2W*9cLDXG1(FGt=j~`)kZ+{0A`o@2L2D^8fb#!OA58R`d zexb0sr4T53djjT07hQ;YX$YjaU|(&{=;_r9Jj6!nI!0q#fjs$7CZv1`#U zqVN7BDwNO62UCK)M1<2w41J?Q%ttRU&aS$V$+x$DZX^TJn4Jmw1U3f4HYSS+A?~ew zie{0?b!lEv0!5h+tgke*s(XPeV>yT7y(uCMqo@CzKGF0CI{=)-AJR`G<9|Wp*qqGDOL?QSpxpq>ocraPWcT-E#yw{6*Ma$tU{*(u4?KC-wpFTW?Hfg%uzJ*7I zDF20=*y|6P`b69(i^}JSUjJ4S9XtJ!CDEIYl4`-WiUFZ>heg6;H9V#a z{$YiOs<-5;VOsXx_+`Y>mkFn?+yx$VFb-ELu5X-qQ#Gq!R~2wqz|4hzASYmX9*40c zy0&O!#{+F_}S)KH~euZTa0p zH{gy;+46&8vdCCu-AlvVY$EJ$`x2oBLn)3l)1Tr%B9inf>HK=_Ch7cCLyyhN8EIbF~dXfBKTOh7w70N*;6cyd{A>}>b=Y0Z4B9!R>^0l6jNWg(7tM;NCtbhjfthFYscq4bFTa zweAcix=DJx!r|SH_xA+#rWzb8E?E54u_7I(@`TQPO9T;C9e|}YU__Ldt4$47)R=?> z<1C+1q|fx@`4lW!Ak6R9j%wOnZPrMVt zFdhH!>afcsh_%X$AW?jhkc|;L>dCJkE|dffzKjxyt?LlU_)NJ@_D){73ZWw=;U_)& zr;n|vbR&<&`hR(JJPiQKTFu?>f-a}L?jwMfSZ!cW;AyXJ^NBSH|F8AJYh?`6P_lJAhInN-W5I9E>?6Naz)els0 z)4J$VCd*_)x34UuE1G3qE~5?~3nsLjP6upx@Nmc=HjamE{!DbCPfe(C-|=kf?tXz9S=KTz7OAkSp-` z_RHZzk>7)OXPVQBR~w7(@GMEeLP|C|qD};-hmdiL=I`zhW-bVcOa>QTuKsNH=K92b z*Sna|lF{)H4&==4LGRLg-8sl*k>}@QCr!Fzj+>~Dt|En^`GyAh_%U0@K1rWHKY<`O z|5>mo6LITKLkTp0>bo-OXE6Y73Q3WKZ1UHq1SkTt<^FmKIeC{kN!*N|l2Gyx;bBVf z0Hn?W>QYs}JB;iJeJn*jASm0>7W+Km7)D_{XAIPE{8?Y*BKoVX>@sTFUEO4^26goRkO|UA7(=fqE5jgGkmtUrh+)?_-R1~%iAaFrZ6ICX>8pPaP+&X5 zV-(lm350x*yvxj4b~qz16Oy8^I1C))2?t4r8HbCbR|XF-uUd%765&!SgZOgEbWfMY z3P#hiu_s3;?=f{*vVE~?8roI$5G>yBO5a(~EUN^iStIdjkgN>%E-$IbDZIiBr`cy% zAvXbE5#K0s!h0jcq0~>>=QDO44O)l1R}7^&8yXH>YfrE|s??PIKz&CYiV41z3w8)* ze`PW=1j1z;ioexZ=Ph|+O^kA>qU3;_*oHT~2+~Fq=_gr_CN~Ik1o6kQBC1vT-2&$c z?n5pW{C^77A8Wb!*_P49YJ-BNd&;w1y0a-~W4_0hqwmeWKH%xF^rj5G9gxMRW55G* z&0N5xQ3KK@U9t=`#rT@|?arnd;LQGGH9vkKu8&t&(BFCHGT59%7v}M)qe{{J$J;|NMEst`#3QN0A5JhN=PPH?F-Rb5E}ku3A} z6piJ>Cbc=~TUD^tF_B)U_L`+BB@Iz=wTFs6&Fk$bhR{$kI>thZIFKiPji~xET!TM9 zWzJG(UM6C%x^DA0XM7s^(xh9PvESkL*%A5(KMq%^qbZNWxX~p2J@I$Ue9*U+c-gVL z32KrPRNSJ`c-JQ)Or;ixw4-W7qwSmdhA$xTB=H# z^x8HdMB%wMMauNI)Q#HQQ4LwaM^ znYwn`(?XsFTsU)O_(yLoZNt~}#!fA;6THWY$yu4?$A4m81)!kt038oNb%r-&HXImd z1(@RCm`gJJJJ;(8iU<8r#d{%~J@$Q7?=zhB<)IUFy*VloqGz$iQeeiIpn<;Gk-@BV zkRO1;#u&PN_DmgIvCEdE_6SVTvsrX+vwV;S{F+KTXlIaC1lPvXFi3W&cAYz@bFR7G$3?}-OoXql?8;eiZ-N+NgYC~oSqWOpcWC$ z7i$d(<4FoPt5?3X)E1`hpa|6o)=)C!q6=bI%>7ee4SvEu$XT&p`I#OlF#gLX1I~

?;n!4VD~ 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%0D!dBtRaWANRJ_#0zy1PUY0Jq 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�JE>7<_kz^OM^ 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 O&s7T>^Ey-a=>G=~KfMS5 literal 0 HcmV?d00001 From c29f85fb5b1795e47282e4dbfbc1ceed2feb420c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Rodr=C3=ADguez?= Date: Tue, 23 Jan 2024 14:21:04 +0100 Subject: [PATCH 17/70] feat: Add brillig array index check (#4127) # Description ## Problem\* Adds a runtime length check to avoid out of bounds accesses, to emulate the behavior with ACIR dynamic array accesses. ## Summary\* ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- .../src/brillig/brillig_gen/brillig_block.rs | 33 +++++++++++++++++++ .../out_of_bounds_alignment/Nargo.toml | 5 +++ .../out_of_bounds_alignment/Prover.toml | 0 .../out_of_bounds_alignment/src/main.nr | 17 ++++++++++ 4 files changed, 55 insertions(+) create mode 100644 test_programs/noir_test_success/out_of_bounds_alignment/Nargo.toml create mode 100644 test_programs/noir_test_success/out_of_bounds_alignment/Prover.toml create mode 100644 test_programs/noir_test_success/out_of_bounds_alignment/src/main.nr diff --git a/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs b/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs index db005d9d438..b084042981b 100644 --- a/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs +++ b/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs @@ -564,6 +564,7 @@ impl<'block> BrilligBlock<'block> { }; let index_register = self.convert_ssa_register_value(*index, dfg); + self.validate_array_index(array_variable, index_register); self.retrieve_variable_from_array( array_pointer, index_register, @@ -582,6 +583,7 @@ impl<'block> BrilligBlock<'block> { result_ids[0], dfg, ); + self.validate_array_index(source_variable, index_register); self.convert_ssa_array_set( source_variable, @@ -690,6 +692,37 @@ impl<'block> BrilligBlock<'block> { .post_call_prep_returns_load_registers(&returned_registers, &saved_registers); } + fn validate_array_index( + &mut self, + array_variable: BrilligVariable, + index_register: RegisterIndex, + ) { + let (size_as_register, should_deallocate_size) = match array_variable { + BrilligVariable::BrilligArray(BrilligArray { size, .. }) => { + (self.brillig_context.make_constant(size.into()), true) + } + BrilligVariable::BrilligVector(BrilligVector { size, .. }) => (size, false), + _ => unreachable!("ICE: validate array index on non-array"), + }; + + let condition = self.brillig_context.allocate_register(); + + self.brillig_context.memory_op( + index_register, + size_as_register, + condition, + BinaryIntOp::LessThan, + ); + + self.brillig_context + .constrain_instruction(condition, Some("Array index out of bounds".to_owned())); + + if should_deallocate_size { + self.brillig_context.deallocate_register(size_as_register); + } + self.brillig_context.deallocate_register(condition); + } + pub(crate) fn retrieve_variable_from_array( &mut self, array_pointer: RegisterIndex, diff --git a/test_programs/noir_test_success/out_of_bounds_alignment/Nargo.toml b/test_programs/noir_test_success/out_of_bounds_alignment/Nargo.toml new file mode 100644 index 00000000000..e535c113f20 --- /dev/null +++ b/test_programs/noir_test_success/out_of_bounds_alignment/Nargo.toml @@ -0,0 +1,5 @@ +[package] +name = "out_of_bounds_alignment" +type = "bin" +authors = [""] +[dependencies] diff --git a/test_programs/noir_test_success/out_of_bounds_alignment/Prover.toml b/test_programs/noir_test_success/out_of_bounds_alignment/Prover.toml new file mode 100644 index 00000000000..e69de29bb2d diff --git a/test_programs/noir_test_success/out_of_bounds_alignment/src/main.nr b/test_programs/noir_test_success/out_of_bounds_alignment/src/main.nr new file mode 100644 index 00000000000..a47ab37eb31 --- /dev/null +++ b/test_programs/noir_test_success/out_of_bounds_alignment/src/main.nr @@ -0,0 +1,17 @@ +fn out_of_bounds(arr_1: [Field; 50]) -> Field { + arr_1[50 + 1] +} + +unconstrained fn out_of_bounds_unconstrained_wrapper(arr_1: [Field; 50], arr_2: [Field; 50]) -> Field { + out_of_bounds(arr_1) +} + +#[test(should_fail)] +fn test_acir() { + assert_eq(out_of_bounds([0; 50]), 0); +} + +#[test(should_fail)] +fn test_brillig() { + assert_eq(out_of_bounds_unconstrained_wrapper([0; 50], [0; 50]), 0); +} From 62a4e37ef2274af2839011c3bab7bfdbf9f164fa Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Tue, 23 Jan 2024 13:43:28 +0000 Subject: [PATCH 18/70] feat: Separate compilation and expression narrowing in `nargo` interface (#4100) # Description ## Problem\* ## Summary\* This PR moves the responsibility for transforming a circuit into a certain expression width into `nargo_cli`. This gives us better separation of concerns where we no longer need to know the target backend before we compile a circuit (i.e. we can save a generic artifact and then target multiple backends using this) ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- compiler/noirc_driver/src/contract.rs | 4 +-- compiler/wasm/src/compile.rs | 5 +-- compiler/wasm/src/compile_new.rs | 4 +-- tooling/lsp/src/requests/profile_run.rs | 20 +++++++---- tooling/nargo/src/artifacts/debug.rs | 12 +++---- tooling/nargo/src/ops/compile.rs | 35 +++---------------- tooling/nargo/src/ops/mod.rs | 3 ++ tooling/nargo/src/ops/optimize.rs | 18 +++------- tooling/nargo/src/ops/transform.rs | 30 ++++++++++++++++ .../nargo_cli/src/cli/codegen_verifier_cmd.rs | 3 +- tooling/nargo_cli/src/cli/compile_cmd.rs | 19 +++------- tooling/nargo_cli/src/cli/dap_cmd.rs | 12 +++---- tooling/nargo_cli/src/cli/debug_cmd.rs | 3 +- tooling/nargo_cli/src/cli/execute_cmd.rs | 3 +- tooling/nargo_cli/src/cli/info_cmd.rs | 12 +++++-- tooling/nargo_cli/src/cli/prove_cmd.rs | 3 +- tooling/nargo_cli/src/cli/verify_cmd.rs | 3 +- tooling/noirc_abi/src/lib.rs | 2 +- 18 files changed, 95 insertions(+), 96 deletions(-) create mode 100644 tooling/nargo/src/ops/transform.rs diff --git a/compiler/noirc_driver/src/contract.rs b/compiler/noirc_driver/src/contract.rs index 4d6d57ba9b6..5f4b66e7dd2 100644 --- a/compiler/noirc_driver/src/contract.rs +++ b/compiler/noirc_driver/src/contract.rs @@ -26,7 +26,7 @@ pub enum ContractFunctionType { Unconstrained, } -#[derive(Debug, Serialize, Deserialize)] +#[derive(Clone, Debug, Serialize, Deserialize)] pub struct CompiledContract { pub noir_version: String, @@ -51,7 +51,7 @@ pub struct CompiledContract { /// A contract function unlike a regular Noir program /// however can have additional properties. /// One of these being a function type. -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct ContractFunction { pub name: String, diff --git a/compiler/wasm/src/compile.rs b/compiler/wasm/src/compile.rs index 498ffe447ce..b39a27a7931 100644 --- a/compiler/wasm/src/compile.rs +++ b/compiler/wasm/src/compile.rs @@ -190,7 +190,8 @@ pub fn compile( })? .0; - let optimized_contract = nargo::ops::optimize_contract(compiled_contract, expression_width); + let optimized_contract = + nargo::ops::transform_contract(compiled_contract, expression_width); let compile_output = generate_contract_artifact(optimized_contract); Ok(JsCompileResult::new(compile_output)) @@ -205,7 +206,7 @@ pub fn compile( })? .0; - let optimized_program = nargo::ops::optimize_program(compiled_program, expression_width); + let optimized_program = nargo::ops::transform_program(compiled_program, expression_width); let compile_output = generate_program_artifact(optimized_program); Ok(JsCompileResult::new(compile_output)) diff --git a/compiler/wasm/src/compile_new.rs b/compiler/wasm/src/compile_new.rs index 6476f6d29bc..4616004ae2b 100644 --- a/compiler/wasm/src/compile_new.rs +++ b/compiler/wasm/src/compile_new.rs @@ -109,7 +109,7 @@ impl CompilerContext { })? .0; - let optimized_program = nargo::ops::optimize_program(compiled_program, np_language); + let optimized_program = nargo::ops::transform_program(compiled_program, np_language); let compile_output = generate_program_artifact(optimized_program); Ok(JsCompileResult::new(compile_output)) @@ -134,7 +134,7 @@ impl CompilerContext { })? .0; - let optimized_contract = nargo::ops::optimize_contract(compiled_contract, np_language); + let optimized_contract = nargo::ops::transform_contract(compiled_contract, np_language); let compile_output = generate_contract_artifact(optimized_contract); Ok(JsCompileResult::new(compile_output)) diff --git a/tooling/lsp/src/requests/profile_run.rs b/tooling/lsp/src/requests/profile_run.rs index 8ba91338f55..d866be8988b 100644 --- a/tooling/lsp/src/requests/profile_run.rs +++ b/tooling/lsp/src/requests/profile_run.rs @@ -64,26 +64,32 @@ fn on_profile_run_request_inner( &workspace_file_manager, &parsed_files, &workspace, - expression_width, &CompileOptions::default(), ) .map_err(|err| ResponseError::new(ErrorCode::REQUEST_FAILED, err))?; let mut opcodes_counts: HashMap = HashMap::new(); let mut file_map: BTreeMap = BTreeMap::new(); - for compiled_program in &compiled_programs { + for compiled_program in compiled_programs { + let compiled_program = + nargo::ops::transform_program(compiled_program, expression_width); + let span_opcodes = compiled_program.debug.count_span_opcodes(); let debug_artifact: DebugArtifact = compiled_program.clone().into(); opcodes_counts.extend(span_opcodes); file_map.extend(debug_artifact.file_map); } - for compiled_contract in &compiled_contracts { - let functions = &compiled_contract.functions; - let debug_artifact: DebugArtifact = compiled_contract.clone().into(); + for compiled_contract in compiled_contracts { + let compiled_contract = + nargo::ops::transform_contract(compiled_contract, expression_width); + + let function_debug_info: Vec<_> = + compiled_contract.functions.iter().map(|func| &func.debug).cloned().collect(); + let debug_artifact: DebugArtifact = compiled_contract.into(); file_map.extend(debug_artifact.file_map); - for contract_function in functions { - let span_opcodes = contract_function.debug.count_span_opcodes(); + for contract_function_debug in function_debug_info { + let span_opcodes = contract_function_debug.count_span_opcodes(); opcodes_counts.extend(span_opcodes); } } diff --git a/tooling/nargo/src/artifacts/debug.rs b/tooling/nargo/src/artifacts/debug.rs index 3f5df801b66..2e2d98f279e 100644 --- a/tooling/nargo/src/artifacts/debug.rs +++ b/tooling/nargo/src/artifacts/debug.rs @@ -126,18 +126,18 @@ impl From for DebugArtifact { } } -impl From<&CompiledContract> for DebugArtifact { - fn from(compiled_artifact: &CompiledContract) -> Self { +impl From for DebugArtifact { + fn from(compiled_artifact: CompiledContract) -> Self { let all_functions_debug: Vec = compiled_artifact .functions - .iter() - .map(|contract_function| contract_function.debug.clone()) + .into_iter() + .map(|contract_function| contract_function.debug) .collect(); DebugArtifact { debug_symbols: all_functions_debug, - file_map: compiled_artifact.file_map.clone(), - warnings: compiled_artifact.warnings.clone(), + file_map: compiled_artifact.file_map, + warnings: compiled_artifact.warnings, } } } diff --git a/tooling/nargo/src/ops/compile.rs b/tooling/nargo/src/ops/compile.rs index 866bfe39d7b..dccd2cedbf5 100644 --- a/tooling/nargo/src/ops/compile.rs +++ b/tooling/nargo/src/ops/compile.rs @@ -1,4 +1,3 @@ -use acvm::ExpressionWidth; use fm::FileManager; use noirc_driver::{CompilationResult, CompileOptions, CompiledContract, CompiledProgram}; use noirc_frontend::hir::ParsedFiles; @@ -18,7 +17,6 @@ pub fn compile_workspace( file_manager: &FileManager, parsed_files: &ParsedFiles, workspace: &Workspace, - expression_width: ExpressionWidth, compile_options: &CompileOptions, ) -> Result<(Vec, Vec), CompileError> { let (binary_packages, contract_packages): (Vec<_>, Vec<_>) = workspace @@ -30,22 +28,11 @@ pub fn compile_workspace( // Compile all of the packages in parallel. let program_results: Vec> = binary_packages .par_iter() - .map(|package| { - compile_program( - file_manager, - parsed_files, - package, - compile_options, - expression_width, - None, - ) - }) + .map(|package| compile_program(file_manager, parsed_files, package, compile_options, None)) .collect(); let contract_results: Vec> = contract_packages .par_iter() - .map(|package| { - compile_contract(file_manager, parsed_files, package, compile_options, expression_width) - }) + .map(|package| compile_contract(file_manager, parsed_files, package, compile_options)) .collect(); // Report any warnings/errors which were encountered during compilation. @@ -80,18 +67,10 @@ pub fn compile_program( parsed_files: &ParsedFiles, package: &Package, compile_options: &CompileOptions, - expression_width: ExpressionWidth, cached_program: Option, ) -> CompilationResult { let (mut context, crate_id) = prepare_package(file_manager, parsed_files, package); - - let (program, warnings) = - noirc_driver::compile_main(&mut context, crate_id, compile_options, cached_program)?; - - // Apply backend specific optimizations. - let optimized_program = crate::ops::optimize_program(program, expression_width); - - Ok((optimized_program, warnings)) + noirc_driver::compile_main(&mut context, crate_id, compile_options, cached_program) } pub fn compile_contract( @@ -99,15 +78,9 @@ pub fn compile_contract( parsed_files: &ParsedFiles, package: &Package, compile_options: &CompileOptions, - expression_width: ExpressionWidth, ) -> CompilationResult { let (mut context, crate_id) = prepare_package(file_manager, parsed_files, package); - let (contract, warnings) = - noirc_driver::compile_contract(&mut context, crate_id, compile_options)?; - - let optimized_contract = crate::ops::optimize_contract(contract, expression_width); - - Ok((optimized_contract, warnings)) + noirc_driver::compile_contract(&mut context, crate_id, compile_options) } pub(crate) fn report_errors( diff --git a/tooling/nargo/src/ops/mod.rs b/tooling/nargo/src/ops/mod.rs index 4912c84839e..4f92faa73a4 100644 --- a/tooling/nargo/src/ops/mod.rs +++ b/tooling/nargo/src/ops/mod.rs @@ -2,6 +2,8 @@ pub use self::compile::{compile_contract, compile_program, compile_workspace}; pub use self::execute::execute_circuit; pub use self::foreign_calls::{DefaultForeignCallExecutor, ForeignCallExecutor}; pub use self::optimize::{optimize_contract, optimize_program}; +pub use self::transform::{transform_contract, transform_program}; + pub use self::test::{run_test, TestStatus}; mod compile; @@ -9,3 +11,4 @@ mod execute; mod foreign_calls; mod optimize; mod test; +mod transform; diff --git a/tooling/nargo/src/ops/optimize.rs b/tooling/nargo/src/ops/optimize.rs index d3a36dd65ac..2d0c4c43d25 100644 --- a/tooling/nargo/src/ops/optimize.rs +++ b/tooling/nargo/src/ops/optimize.rs @@ -1,26 +1,16 @@ -use acvm::ExpressionWidth; use iter_extended::vecmap; use noirc_driver::{CompiledContract, CompiledProgram}; -pub fn optimize_program( - mut program: CompiledProgram, - expression_width: ExpressionWidth, -) -> CompiledProgram { - let (optimized_circuit, location_map) = - acvm::compiler::compile(program.circuit, expression_width); - +pub fn optimize_program(mut program: CompiledProgram) -> CompiledProgram { + let (optimized_circuit, location_map) = acvm::compiler::optimize(program.circuit); program.circuit = optimized_circuit; program.debug.update_acir(location_map); program } -pub fn optimize_contract( - contract: CompiledContract, - expression_width: ExpressionWidth, -) -> CompiledContract { +pub fn optimize_contract(contract: CompiledContract) -> CompiledContract { let functions = vecmap(contract.functions, |mut func| { - let (optimized_bytecode, location_map) = - acvm::compiler::compile(func.bytecode, expression_width); + let (optimized_bytecode, location_map) = acvm::compiler::optimize(func.bytecode); func.bytecode = optimized_bytecode; func.debug.update_acir(location_map); func diff --git a/tooling/nargo/src/ops/transform.rs b/tooling/nargo/src/ops/transform.rs new file mode 100644 index 00000000000..f3efd82333e --- /dev/null +++ b/tooling/nargo/src/ops/transform.rs @@ -0,0 +1,30 @@ +use acvm::ExpressionWidth; +use iter_extended::vecmap; +use noirc_driver::{CompiledContract, CompiledProgram}; + +pub fn transform_program( + mut program: CompiledProgram, + expression_width: ExpressionWidth, +) -> CompiledProgram { + let (optimized_circuit, location_map) = + acvm::compiler::compile(program.circuit, expression_width); + + program.circuit = optimized_circuit; + program.debug.update_acir(location_map); + program +} + +pub fn transform_contract( + contract: CompiledContract, + expression_width: ExpressionWidth, +) -> CompiledContract { + let functions = vecmap(contract.functions, |mut func| { + let (optimized_bytecode, location_map) = + acvm::compiler::compile(func.bytecode, expression_width); + func.bytecode = optimized_bytecode; + func.debug.update_acir(location_map); + func + }); + + CompiledContract { functions, ..contract } +} diff --git a/tooling/nargo_cli/src/cli/codegen_verifier_cmd.rs b/tooling/nargo_cli/src/cli/codegen_verifier_cmd.rs index e7ab86f343a..63d27e30836 100644 --- a/tooling/nargo_cli/src/cli/codegen_verifier_cmd.rs +++ b/tooling/nargo_cli/src/cli/codegen_verifier_cmd.rs @@ -53,7 +53,6 @@ pub(crate) fn run( &parsed_files, package, &args.compile_options, - expression_width, None, ); @@ -64,6 +63,8 @@ pub(crate) fn run( args.compile_options.silence_warnings, )?; + let program = nargo::ops::transform_program(program, expression_width); + let smart_contract_string = backend.eth_contract(&program.circuit)?; let contract_dir = workspace.contracts_directory_path(package); diff --git a/tooling/nargo_cli/src/cli/compile_cmd.rs b/tooling/nargo_cli/src/cli/compile_cmd.rs index 29e6012996a..25cf06a7310 100644 --- a/tooling/nargo_cli/src/cli/compile_cmd.rs +++ b/tooling/nargo_cli/src/cli/compile_cmd.rs @@ -1,7 +1,5 @@ use std::path::Path; -use acvm::ExpressionWidth; - use fm::FileManager; use nargo::artifacts::program::ProgramArtifact; use nargo::errors::CompileError; @@ -68,7 +66,6 @@ pub(crate) fn run( &workspace_file_manager, &parsed_files, &workspace, - expression_width, &args.compile_options, )?; @@ -81,9 +78,11 @@ pub(crate) fn run( // Save build artifacts to disk. let only_acir = args.compile_options.only_acir; for (package, program) in binary_packages.into_iter().zip(compiled_program) { + let program = nargo::ops::transform_program(program, expression_width); save_program(program.clone(), &package, &workspace.target_directory_path(), only_acir); } for (package, contract) in contract_packages.into_iter().zip(compiled_contracts) { + let contract = nargo::ops::transform_contract(contract, expression_width); save_contract(contract, &package, &circuit_dir); } @@ -94,7 +93,6 @@ pub(super) fn compile_workspace( file_manager: &FileManager, parsed_files: &ParsedFiles, workspace: &Workspace, - expression_width: ExpressionWidth, compile_options: &CompileOptions, ) -> Result<(Vec, Vec), CliError> { let (binary_packages, contract_packages): (Vec<_>, Vec<_>) = workspace @@ -114,21 +112,12 @@ pub(super) fn compile_workspace( .filter(|p| p.noir_version == NOIR_ARTIFACT_VERSION_STRING) .map(|p| p.into()); - compile_program( - file_manager, - parsed_files, - package, - compile_options, - expression_width, - cached_program, - ) + compile_program(file_manager, parsed_files, package, compile_options, cached_program) }) .collect(); let contract_results: Vec> = contract_packages .par_iter() - .map(|package| { - compile_contract(file_manager, parsed_files, package, compile_options, expression_width) - }) + .map(|package| compile_contract(file_manager, parsed_files, package, compile_options)) .collect(); // Report any warnings/errors which were encountered during compilation. diff --git a/tooling/nargo_cli/src/cli/dap_cmd.rs b/tooling/nargo_cli/src/cli/dap_cmd.rs index c028545c11c..a02cd66fd4c 100644 --- a/tooling/nargo_cli/src/cli/dap_cmd.rs +++ b/tooling/nargo_cli/src/cli/dap_cmd.rs @@ -74,14 +74,8 @@ fn load_and_compile_project( let parsed_files = parse_all(&workspace_file_manager); let compile_options = CompileOptions::default(); - let compilation_result = compile_program( - &workspace_file_manager, - &parsed_files, - package, - &compile_options, - expression_width, - None, - ); + let compilation_result = + compile_program(&workspace_file_manager, &parsed_files, package, &compile_options, None); let compiled_program = report_errors( compilation_result, @@ -91,6 +85,8 @@ fn load_and_compile_project( ) .map_err(|_| LoadError("Failed to compile project"))?; + let compiled_program = nargo::ops::transform_program(compiled_program, expression_width); + let (inputs_map, _) = read_inputs_from_file(&package.root_dir, prover_name, Format::Toml, &compiled_program.abi) .map_err(|_| LoadError("Failed to read program inputs"))?; diff --git a/tooling/nargo_cli/src/cli/debug_cmd.rs b/tooling/nargo_cli/src/cli/debug_cmd.rs index ce89324a3b9..58cc453e01b 100644 --- a/tooling/nargo_cli/src/cli/debug_cmd.rs +++ b/tooling/nargo_cli/src/cli/debug_cmd.rs @@ -72,7 +72,6 @@ pub(crate) fn run( &parsed_files, package, &args.compile_options, - expression_width, None, ); @@ -83,6 +82,8 @@ pub(crate) fn run( args.compile_options.silence_warnings, )?; + let compiled_program = nargo::ops::transform_program(compiled_program, expression_width); + run_async(package, compiled_program, &args.prover_name, &args.witness_name, target_dir) } diff --git a/tooling/nargo_cli/src/cli/execute_cmd.rs b/tooling/nargo_cli/src/cli/execute_cmd.rs index a84b2821f1e..c1fd398350c 100644 --- a/tooling/nargo_cli/src/cli/execute_cmd.rs +++ b/tooling/nargo_cli/src/cli/execute_cmd.rs @@ -76,7 +76,6 @@ pub(crate) fn run( &parsed_files, package, &args.compile_options, - expression_width, None, ); @@ -87,6 +86,8 @@ pub(crate) fn run( args.compile_options.silence_warnings, )?; + let compiled_program = nargo::ops::transform_program(compiled_program, expression_width); + let (return_value, solved_witness) = execute_program_and_decode( compiled_program, package, diff --git a/tooling/nargo_cli/src/cli/info_cmd.rs b/tooling/nargo_cli/src/cli/info_cmd.rs index 8dfff67b47f..0e9feaca1ca 100644 --- a/tooling/nargo_cli/src/cli/info_cmd.rs +++ b/tooling/nargo_cli/src/cli/info_cmd.rs @@ -74,19 +74,25 @@ pub(crate) fn run( &workspace_file_manager, &parsed_files, &workspace, - expression_width, &args.compile_options, )?; + let compiled_programs = vecmap(compiled_programs, |program| { + nargo::ops::transform_program(program, expression_width) + }); + let compiled_contracts = vecmap(compiled_contracts, |contract| { + nargo::ops::transform_contract(contract, expression_width) + }); + if args.profile_info { for compiled_program in &compiled_programs { let span_opcodes = compiled_program.debug.count_span_opcodes(); - let debug_artifact: DebugArtifact = compiled_program.clone().into(); + let debug_artifact = DebugArtifact::from(compiled_program.clone()); print_span_opcodes(span_opcodes, &debug_artifact); } for compiled_contract in &compiled_contracts { - let debug_artifact: DebugArtifact = compiled_contract.clone().into(); + let debug_artifact = DebugArtifact::from(compiled_contract.clone()); let functions = &compiled_contract.functions; for contract_function in functions { let span_opcodes = contract_function.debug.count_span_opcodes(); diff --git a/tooling/nargo_cli/src/cli/prove_cmd.rs b/tooling/nargo_cli/src/cli/prove_cmd.rs index a79c21c81c9..479ca2c9452 100644 --- a/tooling/nargo_cli/src/cli/prove_cmd.rs +++ b/tooling/nargo_cli/src/cli/prove_cmd.rs @@ -77,7 +77,6 @@ pub(crate) fn run( &parsed_files, package, &args.compile_options, - expression_width, None, ); @@ -88,6 +87,8 @@ pub(crate) fn run( args.compile_options.silence_warnings, )?; + let compiled_program = nargo::ops::transform_program(compiled_program, expression_width); + prove_package( backend, &workspace, diff --git a/tooling/nargo_cli/src/cli/verify_cmd.rs b/tooling/nargo_cli/src/cli/verify_cmd.rs index daf623c10c6..582fa32bd8b 100644 --- a/tooling/nargo_cli/src/cli/verify_cmd.rs +++ b/tooling/nargo_cli/src/cli/verify_cmd.rs @@ -62,7 +62,6 @@ pub(crate) fn run( &parsed_files, package, &args.compile_options, - expression_width, None, ); @@ -73,6 +72,8 @@ pub(crate) fn run( args.compile_options.silence_warnings, )?; + let compiled_program = nargo::ops::transform_program(compiled_program, expression_width); + verify_package(backend, &workspace, package, compiled_program, &args.verifier_name)?; } diff --git a/tooling/noirc_abi/src/lib.rs b/tooling/noirc_abi/src/lib.rs index 066b1635ced..1fc257c1676 100644 --- a/tooling/noirc_abi/src/lib.rs +++ b/tooling/noirc_abi/src/lib.rs @@ -512,7 +512,7 @@ fn decode_string_value(field_elements: &[FieldElement]) -> String { final_string.to_owned() } -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct ContractEvent { /// Event name name: String, From 5dc259e4710a18bee9e45a30a7eb7d7041408773 Mon Sep 17 00:00:00 2001 From: kevaundray Date: Tue, 23 Jan 2024 14:31:55 +0000 Subject: [PATCH 19/70] chore: install wasm-bindgen using binstall (#4123) # Description This uses a preinstalled version of wasmbindgen-cli install of recompiling each time ## Problem\* Resolves ## Summary\* ## Additional Context ## Documentation\* Check one: - [ ] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [ ] I have tested the changes locally. - [ ] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --------- Co-authored-by: Tom French --- .github/scripts/wasm-bindgen-install.sh | 4 ++-- scripts/install_wasm-bindgen.sh | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/scripts/wasm-bindgen-install.sh b/.github/scripts/wasm-bindgen-install.sh index b8c41393ab0..a147a46cde8 100755 --- a/.github/scripts/wasm-bindgen-install.sh +++ b/.github/scripts/wasm-bindgen-install.sh @@ -1,5 +1,5 @@ #!/bin/bash set -eu -curl -L --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.sh | bash -cargo-binstall wasm-bindgen-cli --version 0.2.86 -y +# TODO call this script directly +./scripts/install_wasm-bindgen.sh diff --git a/scripts/install_wasm-bindgen.sh b/scripts/install_wasm-bindgen.sh index c6e85bac50b..f34ed4c0ad0 100755 --- a/scripts/install_wasm-bindgen.sh +++ b/scripts/install_wasm-bindgen.sh @@ -3,8 +3,12 @@ set -eu cd $(dirname "$0")/.. +# Install binstall +curl -L --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.sh | bash + # Install wasm-bindgen-cli. if [ "$(wasm-bindgen --version | cut -d' ' -f2)" != "0.2.86" ]; then echo "Building wasm-bindgen..." - RUSTFLAGS="-Ctarget-feature=-crt-static" cargo install -f wasm-bindgen-cli --version 0.2.86 + cargo binstall wasm-bindgen-cli@0.2.86 --force --no-confirm fi + From 9d83c2b7d49490027bfa2974c1e2c5a85cc00aff Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Tue, 23 Jan 2024 14:57:18 +0000 Subject: [PATCH 20/70] fix: maintain correct type when simplifying `x ^ x` (#4082) # Description ## Problem\* Resolves #4080 ## Summary\* This PR fixes an incorrect type being applied to a simplification of `x ^ x` which then results in compiler panics should this result be used in addition/subtraction operations. ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- compiler/noirc_evaluator/src/ssa/ir/instruction.rs | 2 +- .../noir_test_success/regression_4080/Nargo.toml | 5 +++++ .../noir_test_success/regression_4080/Prover.toml | 1 + .../noir_test_success/regression_4080/src/main.nr | 8 ++++++++ 4 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 test_programs/noir_test_success/regression_4080/Nargo.toml create mode 100644 test_programs/noir_test_success/regression_4080/Prover.toml create mode 100644 test_programs/noir_test_success/regression_4080/src/main.nr diff --git a/compiler/noirc_evaluator/src/ssa/ir/instruction.rs b/compiler/noirc_evaluator/src/ssa/ir/instruction.rs index 457fe41de93..dbad562b6f4 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/instruction.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/instruction.rs @@ -1002,7 +1002,7 @@ impl Binary { return SimplifyResult::SimplifiedTo(self.lhs); } if dfg.resolve(self.lhs) == dfg.resolve(self.rhs) { - let zero = dfg.make_constant(FieldElement::zero(), Type::bool()); + let zero = dfg.make_constant(FieldElement::zero(), operand_type); return SimplifyResult::SimplifiedTo(zero); } } diff --git a/test_programs/noir_test_success/regression_4080/Nargo.toml b/test_programs/noir_test_success/regression_4080/Nargo.toml new file mode 100644 index 00000000000..a38baf389d6 --- /dev/null +++ b/test_programs/noir_test_success/regression_4080/Nargo.toml @@ -0,0 +1,5 @@ +[package] +name = "regression_4080" +type = "bin" +authors = [""] +[dependencies] diff --git a/test_programs/noir_test_success/regression_4080/Prover.toml b/test_programs/noir_test_success/regression_4080/Prover.toml new file mode 100644 index 00000000000..0e5dfd5638d --- /dev/null +++ b/test_programs/noir_test_success/regression_4080/Prover.toml @@ -0,0 +1 @@ +x = "5" diff --git a/test_programs/noir_test_success/regression_4080/src/main.nr b/test_programs/noir_test_success/regression_4080/src/main.nr new file mode 100644 index 00000000000..781d3e33ea3 --- /dev/null +++ b/test_programs/noir_test_success/regression_4080/src/main.nr @@ -0,0 +1,8 @@ +// This test checks that `var^var` is assigned the correct type. +// https://github.com/noir-lang/noir/issues/4080 + +#[test(should_fail_with = "attempt to add with overflow")] +fn main() { + let var1: u8 = ((255 + 1) ^ (255 + 1)) - ((255 + 1) - (255 + 1)); + assert_eq(var1, 0); +} From ec36670d3369797eba6c5663fdaaeab49b6ca086 Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Tue, 23 Jan 2024 16:24:18 +0000 Subject: [PATCH 21/70] chore: make a v0.23.0 version of docs (#4130) # Description ## Problem\* Resolves ## Summary\* The `update-docs` step of the `0.23.0` release didn't happen because of the CI issues so I've done it manually. ## Additional Context ## Documentation\* Check one: - [ ] No documentation needed. - [x] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- .../explainers/explainer-oracle.md | 57 +++ .../explainers/explainer-recursion.md | 177 ++++++++ .../getting_started/_category_.json | 5 + .../hello_noir/_category_.json | 5 + .../getting_started/hello_noir/index.md | 142 +++++++ .../hello_noir/project_breakdown.md | 199 +++++++++ .../installation/_category_.json | 6 + .../getting_started/installation/index.md | 48 +++ .../installation/other_install_methods.md | 190 +++++++++ .../getting_started/tooling/_category_.json | 6 + .../getting_started/tooling/index.mdx | 38 ++ .../tooling/language_server.md | 43 ++ .../getting_started/tooling/testing.md | 62 +++ .../version-v0.23.0/how_to/_category_.json | 5 + .../version-v0.23.0/how_to/how-to-oracles.md | 280 +++++++++++++ .../how_to/how-to-recursion.md | 184 +++++++++ .../how_to/how-to-solidity-verifier.md | 231 +++++++++++ .../version-v0.23.0/how_to/merkle-proof.mdx | 48 +++ .../how_to/using-devcontainers.mdx | 110 +++++ docs/versioned_docs/version-v0.23.0/index.mdx | 67 +++ .../version-v0.23.0/migration_notes.md | 91 ++++ .../noir/concepts/_category_.json | 6 + .../version-v0.23.0/noir/concepts/assert.md | 27 ++ .../version-v0.23.0/noir/concepts/comments.md | 33 ++ .../noir/concepts/control_flow.md | 45 ++ .../version-v0.23.0/noir/concepts/data_bus.md | 21 + .../noir/concepts/data_types/_category_.json | 5 + .../noir/concepts/data_types/arrays.md | 249 +++++++++++ .../noir/concepts/data_types/booleans.md | 31 ++ .../noir/concepts/data_types/fields.md | 166 ++++++++ .../concepts/data_types/function_types.md | 26 ++ .../noir/concepts/data_types/index.md | 96 +++++ .../noir/concepts/data_types/integers.md | 113 +++++ .../noir/concepts/data_types/references.md | 23 ++ .../noir/concepts/data_types/slices.mdx | 147 +++++++ .../noir/concepts/data_types/strings.md | 80 ++++ .../noir/concepts/data_types/structs.md | 70 ++++ .../noir/concepts/data_types/tuples.md | 48 +++ .../noir/concepts/data_types/vectors.mdx | 171 ++++++++ .../version-v0.23.0/noir/concepts/distinct.md | 64 +++ .../noir/concepts/functions.md | 226 ++++++++++ .../version-v0.23.0/noir/concepts/generics.md | 106 +++++ .../version-v0.23.0/noir/concepts/lambdas.md | 81 ++++ .../noir/concepts/mutability.md | 93 +++++ .../version-v0.23.0/noir/concepts/ops.md | 98 +++++ .../version-v0.23.0/noir/concepts/oracles.md | 23 ++ .../noir/concepts/shadowing.md | 44 ++ .../version-v0.23.0/noir/concepts/traits.md | 389 ++++++++++++++++++ .../noir/concepts/unconstrained.md | 95 +++++ .../modules_packages_crates/_category_.json | 6 + .../crates_and_packages.md | 43 ++ .../modules_packages_crates/dependencies.md | 124 ++++++ .../noir/modules_packages_crates/modules.md | 105 +++++ .../modules_packages_crates/workspaces.md | 40 ++ .../noir/standard_library/_category_.json | 6 + .../noir/standard_library/black_box_fns.md | 45 ++ .../cryptographic_primitives/_category_.json | 5 + .../cryptographic_primitives/ec_primitives.md | 102 +++++ .../ecdsa_sig_verification.mdx | 46 +++ .../cryptographic_primitives/eddsa.mdx | 18 + .../cryptographic_primitives/hashes.mdx | 167 ++++++++ .../cryptographic_primitives/index.md | 14 + .../cryptographic_primitives/scalar.mdx | 28 ++ .../cryptographic_primitives/schnorr.mdx | 38 ++ .../noir/standard_library/logging.md | 78 ++++ .../noir/standard_library/merkle_trees.md | 58 +++ .../noir/standard_library/options.md | 97 +++++ .../noir/standard_library/recursion.md | 90 ++++ .../noir/standard_library/traits.md | 284 +++++++++++++ .../noir/standard_library/zeroed.md | 25 ++ .../reference/backend_barretenberg/.nojekyll | 1 + .../classes/BarretenbergBackend.md | 185 +++++++++ .../reference/backend_barretenberg/index.md | 45 ++ .../interfaces/Backend.md | 132 ++++++ .../type-aliases/BackendOptions.md | 19 + .../type-aliases/CompiledCircuit.md | 20 + .../type-aliases/ProofData.md | 20 + .../backend_barretenberg/typedoc-sidebar.cjs | 4 + .../noir_js/reference/noir_js/.nojekyll | 1 + .../noir_js/reference/noir_js/classes/Noir.md | 131 ++++++ .../reference/noir_js/functions/and.md | 22 + .../reference/noir_js/functions/blake2s256.md | 21 + .../functions/ecdsa_secp256k1_verify.md | 29 ++ .../functions/ecdsa_secp256r1_verify.md | 28 ++ .../reference/noir_js/functions/keccak256.md | 21 + .../reference/noir_js/functions/sha256.md | 21 + .../reference/noir_js/functions/xor.md | 22 + .../noir_js/reference/noir_js/index.md | 37 ++ .../noir_js/type-aliases/CompiledCircuit.md | 20 + .../type-aliases/ForeignCallHandler.md | 24 ++ .../noir_js/type-aliases/ForeignCallInput.md | 9 + .../noir_js/type-aliases/ForeignCallOutput.md | 9 + .../noir_js/type-aliases/InputMap.md | 13 + .../noir_js/type-aliases/ProofData.md | 20 + .../noir_js/type-aliases/WitnessMap.md | 9 + .../reference/noir_js/typedoc-sidebar.cjs | 4 + .../NoirJS/backend_barretenberg/.nojekyll | 1 + .../classes/BarretenbergBackend.md | 185 +++++++++ .../NoirJS/backend_barretenberg/index.md | 46 +++ .../interfaces/Backend.md | 132 ++++++ .../type-aliases/BackendOptions.md | 19 + .../type-aliases/CompiledCircuit.md | 20 + .../type-aliases/ProofData.md | 20 + .../backend_barretenberg/typedoc-sidebar.cjs | 4 + .../reference/NoirJS/noir_js/.nojekyll | 1 + .../reference/NoirJS/noir_js/classes/Noir.md | 132 ++++++ .../reference/NoirJS/noir_js/functions/and.md | 22 + .../NoirJS/noir_js/functions/blake2s256.md | 21 + .../functions/ecdsa_secp256k1_verify.md | 28 ++ .../functions/ecdsa_secp256r1_verify.md | 28 ++ .../NoirJS/noir_js/functions/keccak256.md | 21 + .../NoirJS/noir_js/functions/sha256.md | 21 + .../reference/NoirJS/noir_js/functions/xor.md | 22 + .../reference/NoirJS/noir_js/index.md | 37 ++ .../noir_js/type-aliases/CompiledCircuit.md | 20 + .../type-aliases/ForeignCallHandler.md | 24 ++ .../noir_js/type-aliases/ForeignCallInput.md | 9 + .../noir_js/type-aliases/ForeignCallOutput.md | 9 + .../NoirJS/noir_js/type-aliases/InputMap.md | 13 + .../NoirJS/noir_js/type-aliases/ProofData.md | 20 + .../NoirJS/noir_js/type-aliases/WitnessMap.md | 9 + .../NoirJS/noir_js/typedoc-sidebar.cjs | 4 + .../version-v0.23.0/reference/_category_.json | 5 + .../reference/nargo_commands.md | 253 ++++++++++++ .../version-v0.23.0/tutorials/noirjs_app.md | 279 +++++++++++++ .../version-v0.23.0-sidebars.json | 83 ++++ 126 files changed, 8344 insertions(+) create mode 100644 docs/versioned_docs/version-v0.23.0/explainers/explainer-oracle.md create mode 100644 docs/versioned_docs/version-v0.23.0/explainers/explainer-recursion.md create mode 100644 docs/versioned_docs/version-v0.23.0/getting_started/_category_.json create mode 100644 docs/versioned_docs/version-v0.23.0/getting_started/hello_noir/_category_.json create mode 100644 docs/versioned_docs/version-v0.23.0/getting_started/hello_noir/index.md create mode 100644 docs/versioned_docs/version-v0.23.0/getting_started/hello_noir/project_breakdown.md create mode 100644 docs/versioned_docs/version-v0.23.0/getting_started/installation/_category_.json create mode 100644 docs/versioned_docs/version-v0.23.0/getting_started/installation/index.md create mode 100644 docs/versioned_docs/version-v0.23.0/getting_started/installation/other_install_methods.md create mode 100644 docs/versioned_docs/version-v0.23.0/getting_started/tooling/_category_.json create mode 100644 docs/versioned_docs/version-v0.23.0/getting_started/tooling/index.mdx create mode 100644 docs/versioned_docs/version-v0.23.0/getting_started/tooling/language_server.md create mode 100644 docs/versioned_docs/version-v0.23.0/getting_started/tooling/testing.md create mode 100644 docs/versioned_docs/version-v0.23.0/how_to/_category_.json create mode 100644 docs/versioned_docs/version-v0.23.0/how_to/how-to-oracles.md create mode 100644 docs/versioned_docs/version-v0.23.0/how_to/how-to-recursion.md create mode 100644 docs/versioned_docs/version-v0.23.0/how_to/how-to-solidity-verifier.md create mode 100644 docs/versioned_docs/version-v0.23.0/how_to/merkle-proof.mdx create mode 100644 docs/versioned_docs/version-v0.23.0/how_to/using-devcontainers.mdx create mode 100644 docs/versioned_docs/version-v0.23.0/index.mdx create mode 100644 docs/versioned_docs/version-v0.23.0/migration_notes.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir/concepts/_category_.json create mode 100644 docs/versioned_docs/version-v0.23.0/noir/concepts/assert.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir/concepts/comments.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir/concepts/control_flow.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir/concepts/data_bus.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir/concepts/data_types/_category_.json create mode 100644 docs/versioned_docs/version-v0.23.0/noir/concepts/data_types/arrays.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir/concepts/data_types/booleans.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir/concepts/data_types/fields.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir/concepts/data_types/function_types.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir/concepts/data_types/index.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir/concepts/data_types/integers.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir/concepts/data_types/references.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir/concepts/data_types/slices.mdx create mode 100644 docs/versioned_docs/version-v0.23.0/noir/concepts/data_types/strings.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir/concepts/data_types/structs.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir/concepts/data_types/tuples.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir/concepts/data_types/vectors.mdx create mode 100644 docs/versioned_docs/version-v0.23.0/noir/concepts/distinct.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir/concepts/functions.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir/concepts/generics.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir/concepts/lambdas.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir/concepts/mutability.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir/concepts/ops.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir/concepts/oracles.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir/concepts/shadowing.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir/concepts/traits.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir/concepts/unconstrained.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir/modules_packages_crates/_category_.json create mode 100644 docs/versioned_docs/version-v0.23.0/noir/modules_packages_crates/crates_and_packages.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir/modules_packages_crates/dependencies.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir/modules_packages_crates/modules.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir/modules_packages_crates/workspaces.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir/standard_library/_category_.json create mode 100644 docs/versioned_docs/version-v0.23.0/noir/standard_library/black_box_fns.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir/standard_library/cryptographic_primitives/_category_.json create mode 100644 docs/versioned_docs/version-v0.23.0/noir/standard_library/cryptographic_primitives/ec_primitives.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir/standard_library/cryptographic_primitives/ecdsa_sig_verification.mdx create mode 100644 docs/versioned_docs/version-v0.23.0/noir/standard_library/cryptographic_primitives/eddsa.mdx create mode 100644 docs/versioned_docs/version-v0.23.0/noir/standard_library/cryptographic_primitives/hashes.mdx create mode 100644 docs/versioned_docs/version-v0.23.0/noir/standard_library/cryptographic_primitives/index.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir/standard_library/cryptographic_primitives/scalar.mdx create mode 100644 docs/versioned_docs/version-v0.23.0/noir/standard_library/cryptographic_primitives/schnorr.mdx create mode 100644 docs/versioned_docs/version-v0.23.0/noir/standard_library/logging.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir/standard_library/merkle_trees.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir/standard_library/options.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir/standard_library/recursion.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir/standard_library/traits.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir/standard_library/zeroed.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir_js/reference/backend_barretenberg/.nojekyll create mode 100644 docs/versioned_docs/version-v0.23.0/noir_js/reference/backend_barretenberg/classes/BarretenbergBackend.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir_js/reference/backend_barretenberg/index.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir_js/reference/backend_barretenberg/interfaces/Backend.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir_js/reference/backend_barretenberg/type-aliases/BackendOptions.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir_js/reference/backend_barretenberg/type-aliases/CompiledCircuit.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir_js/reference/backend_barretenberg/type-aliases/ProofData.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir_js/reference/backend_barretenberg/typedoc-sidebar.cjs create mode 100644 docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/.nojekyll create mode 100644 docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/classes/Noir.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/functions/and.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/functions/blake2s256.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/functions/ecdsa_secp256k1_verify.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/functions/ecdsa_secp256r1_verify.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/functions/keccak256.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/functions/sha256.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/functions/xor.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/index.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/type-aliases/CompiledCircuit.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/type-aliases/ForeignCallHandler.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/type-aliases/ForeignCallInput.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/type-aliases/ForeignCallOutput.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/type-aliases/InputMap.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/type-aliases/ProofData.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/type-aliases/WitnessMap.md create mode 100644 docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/typedoc-sidebar.cjs create mode 100644 docs/versioned_docs/version-v0.23.0/reference/NoirJS/backend_barretenberg/.nojekyll create mode 100644 docs/versioned_docs/version-v0.23.0/reference/NoirJS/backend_barretenberg/classes/BarretenbergBackend.md create mode 100644 docs/versioned_docs/version-v0.23.0/reference/NoirJS/backend_barretenberg/index.md create mode 100644 docs/versioned_docs/version-v0.23.0/reference/NoirJS/backend_barretenberg/interfaces/Backend.md create mode 100644 docs/versioned_docs/version-v0.23.0/reference/NoirJS/backend_barretenberg/type-aliases/BackendOptions.md create mode 100644 docs/versioned_docs/version-v0.23.0/reference/NoirJS/backend_barretenberg/type-aliases/CompiledCircuit.md create mode 100644 docs/versioned_docs/version-v0.23.0/reference/NoirJS/backend_barretenberg/type-aliases/ProofData.md create mode 100644 docs/versioned_docs/version-v0.23.0/reference/NoirJS/backend_barretenberg/typedoc-sidebar.cjs create mode 100644 docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/.nojekyll create mode 100644 docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/classes/Noir.md create mode 100644 docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/functions/and.md create mode 100644 docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/functions/blake2s256.md create mode 100644 docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/functions/ecdsa_secp256k1_verify.md create mode 100644 docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/functions/ecdsa_secp256r1_verify.md create mode 100644 docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/functions/keccak256.md create mode 100644 docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/functions/sha256.md create mode 100644 docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/functions/xor.md create mode 100644 docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/index.md create mode 100644 docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/type-aliases/CompiledCircuit.md create mode 100644 docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/type-aliases/ForeignCallHandler.md create mode 100644 docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/type-aliases/ForeignCallInput.md create mode 100644 docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/type-aliases/ForeignCallOutput.md create mode 100644 docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/type-aliases/InputMap.md create mode 100644 docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/type-aliases/ProofData.md create mode 100644 docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/type-aliases/WitnessMap.md create mode 100644 docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/typedoc-sidebar.cjs create mode 100644 docs/versioned_docs/version-v0.23.0/reference/_category_.json create mode 100644 docs/versioned_docs/version-v0.23.0/reference/nargo_commands.md create mode 100644 docs/versioned_docs/version-v0.23.0/tutorials/noirjs_app.md create mode 100644 docs/versioned_sidebars/version-v0.23.0-sidebars.json diff --git a/docs/versioned_docs/version-v0.23.0/explainers/explainer-oracle.md b/docs/versioned_docs/version-v0.23.0/explainers/explainer-oracle.md new file mode 100644 index 00000000000..b84ca5dd986 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/explainers/explainer-oracle.md @@ -0,0 +1,57 @@ +--- +title: Oracles +description: This guide provides an in-depth understanding of how Oracles work in Noir programming. Learn how to use outside calculations in your programs, constrain oracles, and understand their uses and limitations. +keywords: + - Noir Programming + - Oracles + - JSON-RPC + - Foreign Call Handlers + - Constrained Functions + - Blockchain Programming +sidebar_position: 1 +--- + +If you've seen "The Matrix" you may recall "The Oracle" as Gloria Foster smoking cigarettes and baking cookies. While she appears to "know things", she is actually providing a calculation of a pre-determined future. Noir Oracles are similar, in a way. They don't calculate the future (yet), but they allow you to use outside calculations in your programs. + +![matrix oracle prediction](@site/static/img/memes/matrix_oracle.jpeg) + +A Noir program is usually self-contained. You can pass certain inputs to it, and it will generate a deterministic output for those inputs. But what if you wanted to defer some calculation to an outside process or source? + +Oracles are functions that provide this feature. + +## Use cases + +An example usage for Oracles is proving something on-chain. For example, proving that the ETH-USDC quote was below a certain target at a certain block time. Or even making more complex proofs like proving the ownership of an NFT as an anonymous login method. + +Another interesting use case is to defer expensive calculations to be made outside of the Noir program, and then constraining the result; similar to the use of [unconstrained functions](../noir/concepts//unconstrained.md). + +In short, anything that can be constrained in a Noir program but needs to be fetched from an external source is a great candidate to be used in oracles. + +## Constraining oracles + +Just like in The Matrix, Oracles are powerful. But with great power, comes great responsibility. Just because you're using them in a Noir program doesn't mean they're true. Noir has no superpowers. If you want to prove that Portugal won the Euro Cup 2016, you're still relying on potentially untrusted information. + +To give a concrete example, Alice wants to login to the [NounsDAO](https://nouns.wtf/) forum with her username "noir_nouner" by proving she owns a noun without revealing her ethereum address. Her Noir program could have a oracle call like this: + +```rust +#[oracle(getNoun)] +unconstrained fn get_noun(address: Field) -> Field +``` + +This oracle could naively resolve with the number of Nouns she possesses. However, it is useless as a trusted source, as the oracle could resolve to anything Alice wants. In order to make this oracle call actually useful, Alice would need to constrain the response from the oracle, by proving her address and the noun count belongs to the state tree of the contract. + +In short, **Oracles don't prove anything. Your Noir program does.** + +:::danger + +If you don't constrain the return of your oracle, you could be clearly opening an attack vector on your Noir program. Make double-triple sure that the return of an oracle call is constrained! + +::: + +## How to use Oracles + +On CLI, Nargo resolves oracles by making JSON RPC calls, which means it would require an RPC node to be running. + +In JavaScript, NoirJS accepts and resolves arbitrary call handlers (that is, not limited to JSON) as long as they matches the expected types the developer defines. Refer to [Foreign Call Handler](../reference/NoirJS/noir_js/type-aliases/ForeignCallHandler.md) to learn more about NoirJS's call handling. + +If you want to build using oracles, follow through to the [oracle guide](../how_to/how-to-oracles.md) for a simple example on how to do that. diff --git a/docs/versioned_docs/version-v0.23.0/explainers/explainer-recursion.md b/docs/versioned_docs/version-v0.23.0/explainers/explainer-recursion.md new file mode 100644 index 00000000000..8f992ec29fd --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/explainers/explainer-recursion.md @@ -0,0 +1,177 @@ +--- +title: Recursive proofs +description: Explore the concept of recursive proofs in Zero-Knowledge programming. Understand how recursion works in Noir, a language for writing smart contracts on the EVM blockchain. Learn through practical examples like Alice and Bob's guessing game, Charlie's recursive merkle tree, and Daniel's reusable components. Discover how to use recursive proofs to optimize computational resources and improve efficiency. + +keywords: + [ + "Recursive Proofs", + "Zero-Knowledge Programming", + "Noir", + "EVM Blockchain", + "Smart Contracts", + "Recursion in Noir", + "Alice and Bob Guessing Game", + "Recursive Merkle Tree", + "Reusable Components", + "Optimizing Computational Resources", + "Improving Efficiency", + "Verification Key", + "Aggregation Objects", + "Recursive zkSNARK schemes", + "PLONK", + "Proving and Verification Keys" + ] +sidebar_position: 1 +--- + +In programming, we tend to think of recursion as something calling itself. A classic example would be the calculation of the factorial of a number: + +```js +function factorial(n) { + if (n === 0 || n === 1) { + return 1; + } else { + return n * factorial(n - 1); + } +} +``` + +In this case, while `n` is not `1`, this function will keep calling itself until it hits the base case, bubbling up the result on the call stack: + +```md + Is `n` 1? <--------- + /\ / + / \ n = n -1 + / \ / + Yes No -------- +``` + +In Zero-Knowledge, recursion has some similarities. + +It is not a Noir function calling itself, but a proof being used as an input to another circuit. In short, you verify one proof *inside* another proof, returning the proof that both proofs are valid. + +This means that, given enough computational resources, you can prove the correctness of any arbitrary number of proofs in a single proof. This could be useful to design state channels (for which a common example would be [Bitcoin's Lightning Network](https://en.wikipedia.org/wiki/Lightning_Network)), to save on gas costs by settling one proof on-chain, or simply to make business logic less dependent on a consensus mechanism. + +## Examples + +Let us look at some of these examples + +### Alice and Bob - Guessing game + +Alice and Bob are friends, and they like guessing games. They want to play a guessing game online, but for that, they need a trusted third-party that knows both of their secrets and finishes the game once someone wins. + +So, they use zero-knowledge proofs. Alice tries to guess Bob's number, and Bob will generate a ZK proof stating whether she succeeded or failed. + +This ZK proof can go on a smart contract, revealing the winner and even giving prizes. However, this means every turn needs to be verified on-chain. This incurs some cost and waiting time that may simply make the game too expensive or time-consuming to be worth it. + +As a solution, Alice proposes the following: "what if Bob generates his proof, and instead of sending it on-chain, I verify it *within* my own proof before playing my own turn?". + +She can then generate a proof that she verified his proof, and so on. + +```md + Did you fail? <-------------------------- + / \ / + / \ n = n -1 + / \ / + Yes No / + | | / + | | / + | You win / + | / + | / +Generate proof of that / + + / + my own guess ---------------- +``` + +### Charlie - Recursive merkle tree + +Charlie is a concerned citizen, and wants to be sure his vote in an election is accounted for. He votes with a ZK proof, but he has no way of knowing that his ZK proof was included in the total vote count! + +If the vote collector puts all of the votes into a [Merkle tree](https://en.wikipedia.org/wiki/Merkle_tree), everyone can prove the verification of two proofs within one proof, as such: + +```md + abcd + __________|______________ + | | + ab cd + _____|_____ ______|______ + | | | | + alice bob charlie daniel +``` + +Doing this recursively allows us to arrive on a final proof `abcd` which if true, verifies the correctness of all the votes. + +### Daniel - Reusable components + +Daniel has a big circuit and a big headache. A part of his circuit is a setup phase that finishes with some assertions that need to be made. But that section alone takes most of the proving time, and is largely independent of the rest of the circuit. + +He might find it more efficient to generate a proof for that setup phase separately, and verify that proof recursively in the actual business logic section of his circuit. This will allow for parallelization of both proofs, which results in a considerable speedup. + +## What params do I need + +As you can see in the [recursion reference](noir/standard_library/recursion.md), a simple recursive proof requires: + +- The proof to verify +- The Verification Key of the circuit that generated the proof +- A hash of this verification key, as it's needed for some backends +- The public inputs for the proof +- The input aggregation object + +It also returns the `output aggregation object`. These aggregation objects can be confusing at times, so let's dive in a little bit. + +### Aggregation objects + +Recursive zkSNARK schemes do not necessarily "verify a proof" in the sense that you expect a true or false to be spit out by the verifier. Rather an aggregation object is built over the public inputs. + +In the case of PLONK the recursive aggregation object is two G1 points (expressed as 16 witness values). The final verifier (in our case this is most often the smart contract verifier) has to be aware of this aggregation object to execute a pairing and check the validity of these points. + +So, taking the example of Alice and Bob and their guessing game: + +- Alice makes her guess. Her proof is *not* recursive: it doesn't verify any proof within it! It's just a standard `assert(x != y)` circuit +- Bob verifies Alice's proof and makes his own guess. In this circuit, he is verifying a proof, so it needs to output an `aggregation object`: he is generating a recursive proof! +- Alice verifies Bob's *recursive proof*, and uses Bob's `output aggregation object` as the `input aggregation object` in her proof... Which in turn, generates another `output aggregation object`. + +One should notice that when Bob generates his first proof, he has no input aggregation object. Because he is not verifying an recursive proof, he has no `input aggregation object`. In this case, he may use zeros instead. + +We can imagine the `aggregation object` as the baton in a [relay race](https://en.wikipedia.org/wiki/Relay_race). The first runner doesn't have to receive the baton from anyone else, as he/she already starts with it. But when his/her turn is over, the next runner needs to receive it, run a bit more, and pass it along. Even though every runner could theoretically verify the baton mid-run (why not? 🏃🔍), only at the end of the race does the referee verify that the whole race is valid. + +## Some architecture + +As with everything in computer science, there's no one-size-fits all. But there are some patterns that could help understanding and implementing them. To give three examples: + +### Adding some logic to a proof verification + +This would be an approach for something like our guessing game, where proofs are sent back and forth and are verified by each opponent. This circuit would be divided in two sections: + +- A `recursive verification` section, which would be just the call to `std::verify_proof`, and that would be skipped on the first move (since there's no proof to verify) +- A `guessing` section, which is basically the logic part where the actual guessing happens + +In such a situation, and assuming Alice is first, she would skip the first part and try to guess Bob's number. Bob would then verify her proof on the first section of his run, and try to guess Alice's number on the second part, and so on. + +### Aggregating proofs + +In some one-way interaction situations, recursion would allow for aggregation of simple proofs that don't need to be immediately verified on-chain or elsewhere. + +To give a practical example, a barman wouldn't need to verify a "proof-of-age" on-chain every time he serves alcohol to a customer. Instead, the architecture would comprise two circuits: + +- A `main`, non-recursive circuit with some logic +- A `recursive` circuit meant to verify two proofs in one proof + +The customer's proofs would be intermediate, and made on their phones, and the barman could just verify them locally. He would then aggregate them into a final proof sent on-chain (or elsewhere) at the end of the day. + +### Recursively verifying different circuits + +Nothing prevents you from verifying different circuits in a recursive proof, for example: + +- A `circuit1` circuit +- A `circuit2` circuit +- A `recursive` circuit + +In this example, a regulator could verify that taxes were paid for a specific purchase by aggregating both a `payer` circuit (proving that a purchase was made and taxes were paid), and a `receipt` circuit (proving that the payment was received) + +## How fast is it + +At the time of writing, verifying recursive proofs is surprisingly fast. This is because most of the time is spent on generating the verification key that will be used to generate the next proof. So you are able to cache the verification key and reuse it later. + +Currently, Noir JS packages don't expose the functionality of loading proving and verification keys, but that feature exists in the underlying `bb.js` package. diff --git a/docs/versioned_docs/version-v0.23.0/getting_started/_category_.json b/docs/versioned_docs/version-v0.23.0/getting_started/_category_.json new file mode 100644 index 00000000000..5d694210bbf --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/getting_started/_category_.json @@ -0,0 +1,5 @@ +{ + "position": 0, + "collapsible": true, + "collapsed": true +} diff --git a/docs/versioned_docs/version-v0.23.0/getting_started/hello_noir/_category_.json b/docs/versioned_docs/version-v0.23.0/getting_started/hello_noir/_category_.json new file mode 100644 index 00000000000..23b560f610b --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/getting_started/hello_noir/_category_.json @@ -0,0 +1,5 @@ +{ + "position": 1, + "collapsible": true, + "collapsed": true +} diff --git a/docs/versioned_docs/version-v0.23.0/getting_started/hello_noir/index.md b/docs/versioned_docs/version-v0.23.0/getting_started/hello_noir/index.md new file mode 100644 index 00000000000..743c4d8d634 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/getting_started/hello_noir/index.md @@ -0,0 +1,142 @@ +--- +title: Creating a Project +description: + Learn how to create and verify your first Noir program using Nargo, a programming language for + zero-knowledge proofs. +keywords: + [ + Nargo, + Noir, + zero-knowledge proofs, + programming language, + create Noir program, + verify Noir program, + step-by-step guide, + ] +sidebar_position: 1 + +--- + +Now that we have installed Nargo, it is time to make our first hello world program! + +## Create a Project Directory + +Noir code can live anywhere on your computer. Let us create a _projects_ folder in the home +directory to house our Noir programs. + +For Linux, macOS, and Windows PowerShell, create the directory and change directory into it by +running: + +```sh +mkdir ~/projects +cd ~/projects +``` + +## Create Our First Nargo Project + +Now that we are in the projects directory, create a new Nargo project by running: + +```sh +nargo new hello_world +``` + +> **Note:** `hello_world` can be any arbitrary project name, we are simply using `hello_world` for +> demonstration. +> +> In production, the common practice is to name the project folder as `circuits` for better +> identifiability when sitting alongside other folders in the codebase (e.g. `contracts`, `scripts`, +> `test`). + +A `hello_world` folder would be created. Similar to Rust, the folder houses _src/main.nr_ and +_Nargo.toml_ which contain the source code and environmental options of your Noir program +respectively. + +### Intro to Noir Syntax + +Let us take a closer look at _main.nr_. The default _main.nr_ generated should look like this: + +```rust +fn main(x : Field, y : pub Field) { + assert(x != y); +} +``` + +The first line of the program specifies the program's inputs: + +```rust +x : Field, y : pub Field +``` + +Program inputs in Noir are private by default (e.g. `x`), but can be labeled public using the +keyword `pub` (e.g. `y`). To learn more about private and public values, check the +[Data Types](../../noir/concepts/data_types/index.md) section. + +The next line of the program specifies its body: + +```rust +assert(x != y); +``` + +The Noir syntax `assert` can be interpreted as something similar to constraints in other zk-contract languages. + +For more Noir syntax, check the [Language Concepts](../../noir/concepts/comments.md) chapter. + +## Build In/Output Files + +Change directory into _hello_world_ and build in/output files for your Noir program by running: + +```sh +cd hello_world +nargo check +``` + +Two additional files would be generated in your project directory: + +_Prover.toml_ houses input values, and _Verifier.toml_ houses public values. + +## Prove Our Noir Program + +Now that the project is set up, we can create a proof of correct execution of our Noir program. + +Fill in input values for execution in the _Prover.toml_ file. For example: + +```toml +x = "1" +y = "2" +``` + +Prove the valid execution of your Noir program: + +```sh +nargo prove +``` + +A new folder _proofs_ would then be generated in your project directory, containing the proof file +`.proof`, where the project name is defined in Nargo.toml. + +The _Verifier.toml_ file would also be updated with the public values computed from program +execution (in this case the value of `y`): + +```toml +y = "0x0000000000000000000000000000000000000000000000000000000000000002" +``` + +> **Note:** Values in _Verifier.toml_ are computed as 32-byte hex values. + +## Verify Our Noir Program + +Once a proof is generated, we can verify correct execution of our Noir program by verifying the +proof file. + +Verify your proof by running: + +```sh +nargo verify +``` + +The verification will complete in silence if it is successful. If it fails, it will log the +corresponding error instead. + +Congratulations, you have now created and verified a proof for your very first Noir program! + +In the [next section](./project_breakdown.md), we will go into more detail on each step performed. diff --git a/docs/versioned_docs/version-v0.23.0/getting_started/hello_noir/project_breakdown.md b/docs/versioned_docs/version-v0.23.0/getting_started/hello_noir/project_breakdown.md new file mode 100644 index 00000000000..6160a102c6c --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/getting_started/hello_noir/project_breakdown.md @@ -0,0 +1,199 @@ +--- +title: Project Breakdown +description: + Learn about the anatomy of a Nargo project, including the purpose of the Prover and Verifier TOML + files, and how to prove and verify your program. +keywords: + [Nargo, Nargo project, Prover.toml, Verifier.toml, proof verification, private asset transfer] +sidebar_position: 2 +--- + +This section breaks down our hello world program from the previous section. We elaborate on the project +structure and what the `prove` and `verify` commands did. + +## Anatomy of a Nargo Project + +Upon creating a new project with `nargo new` and building the in/output files with `nargo check` +commands, you would get a minimal Nargo project of the following structure: + + - src + - Prover.toml + - Verifier.toml + - Nargo.toml + +The source directory _src_ holds the source code for your Noir program. By default only a _main.nr_ +file will be generated within it. + +### Prover.toml + +_Prover.toml_ is used for specifying the input values for executing and proving the program. You can specify `toml` files with different names by using the `--prover-name` or `-p` flags, see the [Prover](#provertoml) section below. Optionally you may specify expected output values for prove-time checking as well. + +### Verifier.toml + +_Verifier.toml_ contains public in/output values computed when executing the Noir program. + +### Nargo.toml + +_Nargo.toml_ contains the environmental options of your project. It contains a "package" section and a "dependencies" section. + +Example Nargo.toml: + +```toml +[package] +name = "noir_starter" +type = "bin" +authors = ["Alice"] +compiler_version = "0.9.0" +description = "Getting started with Noir" +entry = "circuit/main.nr" +license = "MIT" + +[dependencies] +ecrecover = {tag = "v0.9.0", git = "https://github.com/colinnielsen/ecrecover-noir.git"} +``` + +Nargo.toml for a [workspace](../../noir/modules_packages_crates/workspaces.md) will look a bit different. For example: + +```toml +[workspace] +members = ["crates/a", "crates/b"] +default-member = "crates/a" +``` + +#### Package section + +The package section defines a number of fields including: + +- `name` (**required**) - the name of the package +- `type` (**required**) - can be "bin", "lib", or "contract" to specify whether its a binary, library or Aztec contract +- `authors` (optional) - authors of the project +- `compiler_version` - specifies the version of the compiler to use. This is enforced by the compiler and follow's [Rust's versioning](https://doc.rust-lang.org/cargo/reference/manifest.html#the-version-field), so a `compiler_version = 0.18.0` will enforce Nargo version 0.18.0, `compiler_version = ^0.18.0` will enforce anything above 0.18.0 but below 0.19.0, etc. For more information, see how [Rust handles these operators](https://docs.rs/semver/latest/semver/enum.Op.html) +- `description` (optional) +- `entry` (optional) - a relative filepath to use as the entry point into your package (overrides the default of `src/lib.nr` or `src/main.nr`) +- `backend` (optional) +- `license` (optional) + +#### Dependencies section + +This is where you will specify any dependencies for your project. See the [Dependencies page](../../noir/modules_packages_crates/dependencies.md) for more info. + +`./proofs/` and `./contract/` directories will not be immediately visible until you create a proof or +verifier contract respectively. + +### main.nr + +The _main.nr_ file contains a `main` method, this method is the entry point into your Noir program. + +In our sample program, _main.nr_ looks like this: + +```rust +fn main(x : Field, y : Field) { + assert(x != y); +} +``` + +The parameters `x` and `y` can be seen as the API for the program and must be supplied by the +prover. Since neither `x` nor `y` is marked as public, the verifier does not supply any inputs, when +verifying the proof. + +The prover supplies the values for `x` and `y` in the _Prover.toml_ file. + +As for the program body, `assert` ensures that the condition to be satisfied (e.g. `x != y`) is +constrained by the proof of the execution of said program (i.e. if the condition was not met, the +verifier would reject the proof as an invalid proof). + +### Prover.toml + +The _Prover.toml_ file is a file which the prover uses to supply his witness values(both private and +public). + +In our hello world program the _Prover.toml_ file looks like this: + +```toml +x = "1" +y = "2" +``` + +When the command `nargo prove` is executed, two processes happen: + +1. Noir creates a proof that `x`, which holds the value of `1`, and `y`, which holds the value of `2`, + is not equal. This inequality constraint is due to the line `assert(x != y)`. + +2. Noir creates and stores the proof of this statement in the _proofs_ directory in a file called your-project.proof. So if your project is named "private_voting" (defined in the project Nargo.toml), the proof will be saved at `./proofs/private_voting.proof`. Opening this file will display the proof in hex format. + +#### Arrays of Structs + +The following code shows how to pass an array of structs to a Noir program to generate a proof. + +```rust +// main.nr +struct Foo { + bar: Field, + baz: Field, +} + +fn main(foos: [Foo; 3]) -> pub Field { + foos[2].bar + foos[2].baz +} +``` + +Prover.toml: + +```toml +[[foos]] # foos[0] +bar = 0 +baz = 0 + +[[foos]] # foos[1] +bar = 0 +baz = 0 + +[[foos]] # foos[2] +bar = 1 +baz = 2 +``` + +#### Custom toml files + +You can specify a `toml` file with a different name to use for proving by using the `--prover-name` or `-p` flags. + +This command looks for proof inputs in the default **Prover.toml** and generates the proof and saves it at `./proofs/.proof`: + +```bash +nargo prove +``` + +This command looks for proof inputs in the custom **OtherProver.toml** and generates proof and saves it at `./proofs/.proof`: + +```bash +nargo prove -p OtherProver +``` + +## Verifying a Proof + +When the command `nargo verify` is executed, two processes happen: + +1. Noir checks in the _proofs_ directory for a proof file with the project name (eg. test_project.proof) + +2. If that file is found, the proof's validity is checked + +> **Note:** The validity of the proof is linked to the current Noir program; if the program is +> changed and the verifier verifies the proof, it will fail because the proof is not valid for the +> _modified_ Noir program. + +In production, the prover and the verifier are usually two separate entities. A prover would +retrieve the necessary inputs, execute the Noir program, generate a proof and pass it to the +verifier. The verifier would then retrieve the public inputs, usually from external sources, and +verify the validity of the proof against it. + +Take a private asset transfer as an example: + +A person using a browser as the prover would retrieve private inputs locally (e.g. the user's private key) and +public inputs (e.g. the user's encrypted balance on-chain), compute the transfer, generate a proof +and submit it to the verifier smart contract. + +The verifier contract would then draw the user's encrypted balance directly from the blockchain and +verify the proof submitted against it. If the verification passes, additional functions in the +verifier contract could trigger (e.g. approve the asset transfer). + +Now that you understand the concepts, you'll probably want some editor feedback while you are writing more complex code. diff --git a/docs/versioned_docs/version-v0.23.0/getting_started/installation/_category_.json b/docs/versioned_docs/version-v0.23.0/getting_started/installation/_category_.json new file mode 100644 index 00000000000..0c02fb5d4d7 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/getting_started/installation/_category_.json @@ -0,0 +1,6 @@ +{ + "position": 0, + "label": "Install Nargo", + "collapsible": true, + "collapsed": true +} diff --git a/docs/versioned_docs/version-v0.23.0/getting_started/installation/index.md b/docs/versioned_docs/version-v0.23.0/getting_started/installation/index.md new file mode 100644 index 00000000000..4ef86aa5914 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/getting_started/installation/index.md @@ -0,0 +1,48 @@ +--- +title: Nargo Installation +description: + nargo is a command line tool for interacting with Noir programs. This page is a quick guide on how to install Nargo through the most common and easy method, noirup +keywords: [ + Nargo + Noir + Rust + Cargo + Noirup + Installation + Terminal Commands + Version Check + Nightlies + Specific Versions + Branches + Noirup Repository +] +pagination_next: getting_started/hello_noir/index +--- + +`nargo` is the one-stop-shop for almost everything related with Noir. The name comes from our love for Rust and its package manager `cargo`. + +With `nargo`, you can start new projects, compile, execute, prove, verify, test, generate solidity contracts, and do pretty much all that is available in Noir. + +Similarly to `rustup`, we also maintain an easy installation method that covers most machines: `noirup`. + +## Installing Noirup + +Open a terminal on your machine, and write: + +```bash +curl -L https://raw.githubusercontent.com/noir-lang/noirup/main/install | bash +``` + +Close the terminal, open another one, and run + +```bash +noirup +``` + +Done. That's it. You should have the latest version working. You can check with `nargo --version`. + +You can also install nightlies, specific versions +or branches. Check out the [noirup repository](https://github.com/noir-lang/noirup) for more +information. + +Now we're ready to start working on [our first Noir program!](../hello_noir/index.md) diff --git a/docs/versioned_docs/version-v0.23.0/getting_started/installation/other_install_methods.md b/docs/versioned_docs/version-v0.23.0/getting_started/installation/other_install_methods.md new file mode 100644 index 00000000000..a532f83750e --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/getting_started/installation/other_install_methods.md @@ -0,0 +1,190 @@ +--- +title: Alternative Install Methods +description: + There are different ways to install Nargo, the one-stop shop and command-line tool for developing Noir programs. This guide explains other methods that don't rely on noirup, such as compiling from source, installing from binaries, and using WSL for windows +keywords: [ + Installation + Nargo + Noirup + Binaries + Compiling from Source + WSL for Windows + macOS + Linux + Nix + Direnv + Shell & editor experience + Building and testing + Uninstalling Nargo + Noir vs code extension +] +sidebar_position: 1 +--- + + +## Installation + +The most common method of installing Nargo is through [Noirup](./index.md) + +However, there are other methods for installing Nargo: + +- [Binaries](#binaries) +- [Compiling from Source](#compile-from-source) +- [WSL for Windows](#wsl-for-windows) + +### Binaries + +See [GitHub Releases](https://github.com/noir-lang/noir/releases) for the latest and previous +platform specific binaries. + +#### Step 1 + +Paste and run the following in the terminal to extract and install the binary: + +> **macOS / Linux:** If you are prompted with `Permission denied` when running commands, prepend +> `sudo` and re-run it. + +##### macOS (Apple Silicon) + +```bash +mkdir -p $HOME/.nargo/bin && \ +curl -o $HOME/.nargo/bin/nargo-aarch64-apple-darwin.tar.gz -L https://github.com/noir-lang/noir/releases/download/v0.6.0/nargo-aarch64-apple-darwin.tar.gz && \ +tar -xvf $HOME/.nargo/bin/nargo-aarch64-apple-darwin.tar.gz -C $HOME/.nargo/bin/ && \ +echo '\nexport PATH=$PATH:$HOME/.nargo/bin' >> ~/.zshrc && \ +source ~/.zshrc +``` + +##### macOS (Intel) + +```bash +mkdir -p $HOME/.nargo/bin && \ +curl -o $HOME/.nargo/bin/nargo-x86_64-apple-darwin.tar.gz -L https://github.com/noir-lang/noir/releases/download/v0.6.0/nargo-x86_64-apple-darwin.tar.gz && \ +tar -xvf $HOME/.nargo/bin/nargo-x86_64-apple-darwin.tar.gz -C $HOME/.nargo/bin/ && \ +echo '\nexport PATH=$PATH:$HOME/.nargo/bin' >> ~/.zshrc && \ +source ~/.zshrc +``` + +##### Linux (Bash) + +```bash +mkdir -p $HOME/.nargo/bin && \ +curl -o $HOME/.nargo/bin/nargo-x86_64-unknown-linux-gnu.tar.gz -L https://github.com/noir-lang/noir/releases/download/v0.6.0/nargo-x86_64-unknown-linux-gnu.tar.gz && \ +tar -xvf $HOME/.nargo/bin/nargo-x86_64-unknown-linux-gnu.tar.gz -C $HOME/.nargo/bin/ && \ +echo -e '\nexport PATH=$PATH:$HOME/.nargo/bin' >> ~/.bashrc && \ +source ~/.bashrc +``` + +#### Step 2 + +Check if the installation was successful by running `nargo --version`. You should get a version number. + +> **macOS:** If you are prompted with an OS alert, right-click and open the _nargo_ executable from +> Finder. Close the new terminal popped up and `nargo` should now be accessible. + +### Option 3: Compile from Source + +Due to the large number of native dependencies, Noir projects uses [Nix](https://nixos.org/) and [direnv](https://direnv.net/) to streamline the development experience. It helps mitigating issues commonly associated with dependency management, such as conflicts between required package versions for different projects (often referred to as "dependency hell"). + +Combined with direnv, which automatically sets or clears environment variables based on the directory, it further simplifies the development process by seamlessly integrating with the developer's shell, facilitating an efficient and reliable workflow for managing and deploying Noir projects with multiple dependencies. + +#### Setting up your environment + +For the best experience, please follow these instructions to setup your environment: + +1. Install Nix following [their guide](https://nixos.org/download.html) for your operating system. +2. Create the file `~/.config/nix/nix.conf` with the contents: + +```ini +experimental-features = nix-command +extra-experimental-features = flakes +``` + +3. Install direnv into your Nix profile by running: + +```sh +nix profile install nixpkgs#direnv +``` + +4. Add direnv to your shell following [their guide](https://direnv.net/docs/hook.html). + 1. For bash or zshell, add `eval "$(direnv hook bash)"` or `eval "$(direnv hook zsh)"` to your ~/.bashrc or ~/.zshrc file, respectively. +5. Restart your shell. + +#### Shell & editor experience + +Now that your environment is set up, you can get to work on the project. + +1. Clone the repository, such as: + +```sh +git clone git@github.com:noir-lang/noir +``` + +> Replacing `noir` with whichever repository you want to work on. + +2. Navigate to the directory: + +```sh +cd noir +``` + +> Replacing `noir` with whichever repository you cloned. + +3. You should see a **direnv error** because projects aren't allowed by default. Make sure you've reviewed and trust our `.envrc` file, then you need to run: + +```sh +direnv allow +``` + +4. Now, wait awhile for all the native dependencies to be built. This will take some time and direnv will warn you that it is taking a long time, but we just need to let it run. + +5. Once you are presented with your prompt again, you can start your editor within the project directory (we recommend [VSCode](https://code.visualstudio.com/)): + +```sh +code . +``` + +6. (Recommended) When launching VSCode for the first time, you should be prompted to install our recommended plugins. We highly recommend installing these for the best development experience. + +#### Building and testing + +Assuming you are using `direnv` to populate your environment, building and testing the project can be done +with the typical `cargo build`, `cargo test`, and `cargo clippy` commands. You'll notice that the `cargo` version matches the version we specify in `rust-toolchain.toml`, which is 1.71.1 at the time of this writing. + +If you want to build the entire project in an isolated sandbox, you can use Nix commands: + +1. `nix build .` (or `nix build . -L` for verbose output) to build the project in a Nix sandbox. +2. `nix flake check` (or `nix flake check -L` for verbose output) to run clippy and tests in a Nix sandbox. + +#### Without `direnv` + +If you have hesitations with using direnv, you can launch a subshell with `nix develop` and then launch your editor from within the subshell. However, if VSCode was already launched in the project directory, the environment won't be updated. + +Advanced: If you aren't using direnv nor launching your editor within the subshell, you can try to install Barretenberg and other global dependencies the package needs. This is an advanced workflow and likely won't receive support! + +### Option 4: WSL (for Windows) + +The default backend for Noir (Barretenberg) doesn't provide Windows binaries at this time. For that reason, Noir cannot be installed natively. However, it is available by using Windows Subsystem for Linux (WSL). + +Step 1: Follow the instructions [here](https://learn.microsoft.com/en-us/windows/wsl/install) to install and run WSL. + +step 2: Follow the [Noirup instructions](./index.md). + +## Uninstalling Nargo + +### Noirup + +If you installed Noir with `noirup`, you can uninstall Noir by removing the files in `~/.nargo`, `~/nargo` and `~/noir_cache`. + +```bash +rm -r ~/.nargo +rm -r ~/nargo +rm -r ~/noir_cache +``` + +### Nix + +If you installed Noir with Nix or from source, you can remove the binary located at `~/.nix-profile/bin/nargo`. + +```bash +rm ~/.nix-profile/bin/nargo +``` diff --git a/docs/versioned_docs/version-v0.23.0/getting_started/tooling/_category_.json b/docs/versioned_docs/version-v0.23.0/getting_started/tooling/_category_.json new file mode 100644 index 00000000000..55804c03a71 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/getting_started/tooling/_category_.json @@ -0,0 +1,6 @@ +{ + "position": 2, + "label": "Tooling", + "collapsible": true, + "collapsed": true +} diff --git a/docs/versioned_docs/version-v0.23.0/getting_started/tooling/index.mdx b/docs/versioned_docs/version-v0.23.0/getting_started/tooling/index.mdx new file mode 100644 index 00000000000..ac480f3c9f5 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/getting_started/tooling/index.mdx @@ -0,0 +1,38 @@ +--- +title: Tooling +Description: This section provides information about the various tools and utilities available for Noir development. It covers the Noir playground, IDE tools, Codespaces, and community projects. +Keywords: [Noir, Development, Playground, IDE Tools, Language Service Provider, VS Code Extension, Codespaces, noir-starter, Community Projects, Awesome Noir Repository, Developer Tooling] +--- + +Noir is meant to be easy to develop with. For that reason, a number of utilities have been put together to ease the development process as much as feasible in the zero-knowledge world. + +## Playground + +The Noir playground is an easy way to test small ideas, share snippets, and integrate in other websites. You can access it at [play.noir-lang.org](https://play.noir-lang.org). + +## IDE tools + +When you install Nargo, you're also installing a Language Service Provider (LSP), which can be used by IDEs to provide syntax highlighting, codelens, warnings, and more. + +The easiest way to use these tools is by installing the [Noir VS Code extension](https://marketplace.visualstudio.com/items?itemName=noir-lang.vscode-noir). + +## Codespaces + +Some Noir repos have leveraged Codespaces in order to ease the development process. You can visit the [noir-starter](https://github.com/noir-lang/noir-starter) for an example. + + + +## GitHub Actions + +You can use `noirup` with GitHub Actions for CI/CD and automated testing. It is as simple as +installing `noirup` and running tests in your GitHub Action `yml` file. + +See the +[config file in the Noir repo](https://github.com/TomAFrench/noir-hashes/blob/master/.github/workflows/noir.yml) for an example usage. + +## Community projects + +As an open-source project, Noir has received many contributions over time. Some of them are related with developer tooling, and you can see some of them in [Awesome Noir repository](https://github.com/noir-lang/awesome-noir#dev-tools) diff --git a/docs/versioned_docs/version-v0.23.0/getting_started/tooling/language_server.md b/docs/versioned_docs/version-v0.23.0/getting_started/tooling/language_server.md new file mode 100644 index 00000000000..81e0356ef8a --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/getting_started/tooling/language_server.md @@ -0,0 +1,43 @@ +--- +title: Language Server +description: Learn about the Noir Language Server, how to install the components, and configuration that may be required. +keywords: [Nargo, Language Server, LSP, VSCode, Visual Studio Code] +sidebar_position: 0 +--- + +This section helps you install and configure the Noir Language Server. + +The Language Server Protocol (LSP) has two components, the [Server](#language-server) and the [Client](#language-client). Below we describe each in the context of Noir. + +## Language Server + +The Server component is provided by the Nargo command line tool that you installed at the beginning of this guide. +As long as Nargo is installed and you've used it to run other commands in this guide, it should be good to go! + +If you'd like to verify that the `nargo lsp` command is available, you can run `nargo --help` and look for `lsp` in the list of commands. If you see it, you're using a version of Noir with LSP support. + +## Language Client + +The Client component is usually an editor plugin that launches the Server. It communicates LSP messages between the editor and the Server. For example, when you save a file, the Client will alert the Server, so it can try to compile the project and report any errors. + +Currently, Noir provides a Language Client for Visual Studio Code via the [vscode-noir](https://github.com/noir-lang/vscode-noir) extension. You can install it via the [Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=noir-lang.vscode-noir). + +> **Note:** Noir's Language Server Protocol support currently assumes users' VSCode workspace root to be the same as users' Noir project root (i.e. where Nargo.toml lies). +> +> If LSP features seem to be missing / malfunctioning, make sure you are opening your Noir project directly (instead of as a sub-folder) in your VSCode instance. + +When your language server is running correctly and the VSCode plugin is installed, you should see handy codelens buttons for compilation, measuring circuit size, execution, and tests: + +![Compile and Execute](@site/static/img/codelens_compile_execute.png) +![Run test](@site/static/img/codelens_run_test.png) + +You should also see your tests in the `testing` panel: + +![Testing panel](@site/static/img/codelens_testing_panel.png) + +### Configuration + +- **Noir: Enable LSP** - If checked, the extension will launch the Language Server via `nargo lsp` and communicate with it. +- **Noir: Nargo Flags** - Additional flags may be specified if you require them to be added when the extension calls `nargo lsp`. +- **Noir: Nargo Path** - An absolute path to a Nargo binary with the `lsp` command. This may be useful if Nargo is not within the `PATH` of your editor. +- **Noir > Trace: Server** - Setting this to `"messages"` or `"verbose"` will log LSP messages between the Client and Server. Useful for debugging. diff --git a/docs/versioned_docs/version-v0.23.0/getting_started/tooling/testing.md b/docs/versioned_docs/version-v0.23.0/getting_started/tooling/testing.md new file mode 100644 index 00000000000..d3e0c522473 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/getting_started/tooling/testing.md @@ -0,0 +1,62 @@ +--- +title: Testing in Noir +description: Learn how to use Nargo to test your Noir program in a quick and easy way +keywords: [Nargo, testing, Noir, compile, test] +sidebar_position: 1 +--- + +You can test your Noir programs using Noir circuits. + +Nargo will automatically compile and run any functions which have the decorator `#[test]` on them if +you run `nargo test`. + +For example if you have a program like: + +```rust +fn add(x: u64, y: u64) -> u64 { + x + y +} +#[test] +fn test_add() { + assert(add(2,2) == 4); + assert(add(0,1) == 1); + assert(add(1,0) == 1); +} +``` + +Running `nargo test` will test that the `test_add` function can be executed while satisfying all +the constraints which allows you to test that add returns the expected values. Test functions can't +have any arguments currently. + +### Test fail + +You can write tests that are expected to fail by using the decorator `#[test(should_fail)]`. For example: + +```rust +fn add(x: u64, y: u64) -> u64 { + x + y +} +#[test(should_fail)] +fn test_add() { + assert(add(2,2) == 5); +} +``` + +You can be more specific and make it fail with a specific reason by using `should_fail_with = "`: + +```rust +fn main(african_swallow_avg_speed : Field) { + assert(african_swallow_avg_speed == 65, "What is the airspeed velocity of an unladen swallow"); +} + +#[test] +fn test_king_arthur() { + main(65); +} + +#[test(should_fail_with = "What is the airspeed velocity of an unladen swallow")] +fn test_bridgekeeper() { + main(32); +} + +``` diff --git a/docs/versioned_docs/version-v0.23.0/how_to/_category_.json b/docs/versioned_docs/version-v0.23.0/how_to/_category_.json new file mode 100644 index 00000000000..23b560f610b --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/how_to/_category_.json @@ -0,0 +1,5 @@ +{ + "position": 1, + "collapsible": true, + "collapsed": true +} diff --git a/docs/versioned_docs/version-v0.23.0/how_to/how-to-oracles.md b/docs/versioned_docs/version-v0.23.0/how_to/how-to-oracles.md new file mode 100644 index 00000000000..0d84d992320 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/how_to/how-to-oracles.md @@ -0,0 +1,280 @@ +--- +title: How to use Oracles +description: Learn how to use oracles in your Noir program with examples in both Nargo and NoirJS. This guide also covers writing a JSON RPC server and providing custom foreign call handlers for NoirJS. +keywords: + - Noir Programming + - Oracles + - Nargo + - NoirJS + - JSON RPC Server + - Foreign Call Handlers +sidebar_position: 1 +--- + +This guide shows you how to use oracles in your Noir program. For the sake of clarity, it assumes that: + +- You have read the [explainer on Oracles](../explainers/explainer-oracle.md) and are comfortable with the concept. +- You have a Noir program to add oracles to. You can create one using the [vite-hardhat starter](https://github.com/noir-lang/noir-starter/tree/main/vite-hardhat) as a boilerplate. +- You understand the concept of a JSON-RPC server. Visit the [JSON-RPC website](https://www.jsonrpc.org/) if you need a refresher. +- You are comfortable with server-side JavaScript (e.g. Node.js, managing packages, etc.). + +For reference, you can find the snippets used in this tutorial on the [Aztec DevRel Repository](https://github.com/AztecProtocol/dev-rel/tree/main/code-snippets/how-to-oracles). + +## Rundown + +This guide has 3 major steps: + +1. How to modify our Noir program to make use of oracle calls as unconstrained functions +2. How to write a JSON RPC Server to resolve these oracle calls with Nargo +3. How to use them in Nargo and how to provide a custom resolver in NoirJS + +## Step 1 - Modify your Noir program + +An oracle is defined in a Noir program by defining two methods: + +- An unconstrained method - This tells the compiler that it is executing an [unconstrained functions](../noir/concepts//unconstrained.md). +- A decorated oracle method - This tells the compiler that this method is an RPC call. + +An example of an oracle that returns a `Field` would be: + +```rust +#[oracle(getSqrt)] +unconstrained fn sqrt(number: Field) -> Field { } + +unconstrained fn get_sqrt(number: Field) -> Field { + sqrt(number) +} +``` + +In this example, we're wrapping our oracle function in a unconstrained method, and decorating it with `oracle(getSqrt)`. We can then call the unconstrained function as we would call any other function: + +```rust +fn main(input: Field) { + let sqrt = get_sqrt(input); +} +``` + +In the next section, we will make this `getSqrt` (defined on the `sqrt` decorator) be a method of the RPC server Noir will use. + +:::danger + +As explained in the [Oracle Explainer](../explainers/explainer-oracle.md), this `main` function is unsafe unless you constrain its return value. For example: + +```rust +fn main(input: Field) { + let sqrt = get_sqrt(input); + assert(sqrt.pow_32(2) as u64 == input as u64); // <---- constrain the return of an oracle! +} +``` + +::: + +:::info + +Currently, oracles only work with single params or array params. For example: + +```rust +#[oracle(getSqrt)] +unconstrained fn sqrt([Field; 2]) -> [Field; 2] { } +``` + +::: + +## Step 2 - Write an RPC server + +Brillig will call *one* RPC server. Most likely you will have to write your own, and you can do it in whatever language you prefer. In this guide, we will do it in Javascript. + +Let's use the above example of an oracle that consumes an array with two `Field` and returns their square roots: + +```rust +#[oracle(getSqrt)] +unconstrained fn sqrt(input: [Field; 2]) -> [Field; 2] { } + +unconstrained fn get_sqrt(input: [Field; 2]) -> [Field; 2] { + sqrt(input) +} + +fn main(input: [Field; 2]) { + let sqrt = get_sqrt(input); + assert(sqrt[0].pow_32(2) as u64 == input[0] as u64); + assert(sqrt[1].pow_32(2) as u64 == input[1] as u64); +} +``` + +:::info + +Why square root? + +In general, computing square roots is computationally more expensive than multiplications, which takes a toll when speaking about ZK applications. In this case, instead of calculating the square root in Noir, we are using our oracle to offload that computation to be made in plain. In our circuit we can simply multiply the two values. + +::: + +Now, we should write the correspondent RPC server, starting with the [default JSON-RPC 2.0 boilerplate](https://www.npmjs.com/package/json-rpc-2.0#example): + +```js +import { JSONRPCServer } from "json-rpc-2.0"; +import express from "express"; +import bodyParser from "body-parser"; + +const app = express(); +app.use(bodyParser.json()); + +const server = new JSONRPCServer(); +app.post("/", (req, res) => { + const jsonRPCRequest = req.body; + server.receive(jsonRPCRequest).then((jsonRPCResponse) => { + if (jsonRPCResponse) { + res.json(jsonRPCResponse); + } else { + res.sendStatus(204); + } + }); +}); + +app.listen(5555); +``` + +Now, we will add our `getSqrt` method, as expected by the `#[oracle(getSqrt)]` decorator in our Noir code. It maps through the params array and returns their square roots: + +```js +server.addMethod("getSqrt", async (params) => { + const values = params[0].Array.map(({ inner }) => { + return { inner: `${Math.sqrt(parseInt(inner, 16))}` }; + }); + return { values: [{ Array: values }] }; +}); +``` + +:::tip + +Brillig expects an object with an array of values. Each value is an object declaring to be `Single` or `Array` and returning a `inner` property *as a string*. For example: + +```json +{ "values": [{ "Array": [{ "inner": "1" }, { "inner": "2"}]}]} +{ "values": [{ "Single": { "inner": "1" }}]} +{ "values": [{ "Single": { "inner": "1" }}, { "Array": [{ "inner": "1", { "inner": "2" }}]}]} +``` + +If you're using Typescript, the following types may be helpful in understanding the expected return value and making sure they're easy to follow: + +```js +interface Value { + inner: string, +} + +interface SingleForeignCallParam { + Single: Value, +} + +interface ArrayForeignCallParam { + Array: Value[], +} + +type ForeignCallParam = SingleForeignCallParam | ArrayForeignCallParam; + +interface ForeignCallResult { + values: ForeignCallParam[], +} +``` + +::: + +## Step 3 - Usage with Nargo + +Using the [`nargo` CLI tool](../getting_started/installation/index.md), you can use oracles in the `nargo test`, `nargo execute` and `nargo prove` commands by passing a value to `--oracle-resolver`. For example: + +```bash +nargo test --oracle-resolver http://localhost:5555 +``` + +This tells `nargo` to use your RPC Server URL whenever it finds an oracle decorator. + +## Step 4 - Usage with NoirJS + +In a JS environment, an RPC server is not strictly necessary, as you may want to resolve your oracles without needing any JSON call at all. NoirJS simply expects that you pass a callback function when you generate proofs, and that callback function can be anything. + +For example, if your Noir program expects the host machine to provide CPU pseudo-randomness, you could simply pass it as the `foreignCallHandler`. You don't strictly need to create an RPC server to serve pseudo-randomness, as you may as well get it directly in your app: + +```js +const foreignCallHandler = (name, inputs) => crypto.randomBytes(16) // etc + +await noir.generateFinalProof(inputs, foreignCallHandler) +``` + +As one can see, in NoirJS, the [`foreignCallHandler`](../reference/NoirJS/noir_js/type-aliases/ForeignCallHandler.md) function simply means "a callback function that returns a value of type [`ForeignCallOutput`](../reference/NoirJS/noir_js/type-aliases/ForeignCallOutput.md). It doesn't have to be an RPC call like in the case for Nargo. + +:::tip + +Does this mean you don't have to write an RPC server like in [Step #2](#step-2---write-an-rpc-server)? + +You don't technically have to, but then how would you run `nargo test` or `nargo prove`? To use both `Nargo` and `NoirJS` in your development flow, you will have to write a JSON RPC server. + +::: + +In this case, let's make `foreignCallHandler` call the JSON RPC Server we created in [Step #2](#step-2---write-an-rpc-server), by making it a JSON RPC Client. + +For example, using the same `getSqrt` program in [Step #1](#step-1---modify-your-noir-program) (comments in the code): + +```js +import { JSONRPCClient } from "json-rpc-2.0"; + +// declaring the JSONRPCClient +const client = new JSONRPCClient((jsonRPCRequest) => { +// hitting the same JSON RPC Server we coded above + return fetch("http://localhost:5555", { + method: "POST", + headers: { + "content-type": "application/json", + }, + body: JSON.stringify(jsonRPCRequest), + }).then((response) => { + if (response.status === 200) { + return response + .json() + .then((jsonRPCResponse) => client.receive(jsonRPCResponse)); + } else if (jsonRPCRequest.id !== undefined) { + return Promise.reject(new Error(response.statusText)); + } + }); +}); + +// declaring a function that takes the name of the foreign call (getSqrt) and the inputs +const foreignCallHandler = async (name, input) => { + // notice that the "inputs" parameter contains *all* the inputs + // in this case we to make the RPC request with the first parameter "numbers", which would be input[0] + const oracleReturn = await client.request(name, [ + { Array: input[0].map((i) => ({ inner: i.toString("hex") })) }, + ]); + return [oracleReturn.values[0].Array.map((x) => x.inner)]; +}; + +// the rest of your NoirJS code +const input = { input: [4, 16] }; +const { witness } = await noir.execute(numbers, foreignCallHandler); +``` + +:::tip + +If you're in a NoirJS environment running your RPC server together with a frontend app, you'll probably hit a familiar problem in full-stack development: requests being blocked by [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) policy. For development only, you can simply install and use the [`cors` npm package](https://www.npmjs.com/package/cors) to get around the problem: + +```bash +yarn add cors +``` + +and use it as a middleware: + +```js +import cors from "cors"; + +const app = express(); +app.use(cors()) +``` + +::: + +## Conclusion + +Hopefully by the end of this guide, you should be able to: + +- Write your own logic around Oracles and how to write a JSON RPC server to make them work with your Nargo commands. +- Provide custom foreign call handlers for NoirJS. diff --git a/docs/versioned_docs/version-v0.23.0/how_to/how-to-recursion.md b/docs/versioned_docs/version-v0.23.0/how_to/how-to-recursion.md new file mode 100644 index 00000000000..39db23f1f3a --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/how_to/how-to-recursion.md @@ -0,0 +1,184 @@ +--- +title: How to use recursion on NoirJS +description: Learn how to implement recursion with NoirJS, a powerful tool for creating smart contracts on the EVM blockchain. This guide assumes familiarity with NoirJS, solidity verifiers, and the Barretenberg proving backend. Discover how to generate both final and intermediate proofs using `noir_js` and `backend_barretenberg`. +keywords: + [ + "NoirJS", + "EVM blockchain", + "smart contracts", + "recursion", + "solidity verifiers", + "Barretenberg backend", + "noir_js", + "backend_barretenberg", + "intermediate proofs", + "final proofs", + "nargo compile", + "json import", + "recursive circuit", + "recursive app" + ] +sidebar_position: 1 +--- + +This guide shows you how to use recursive proofs in your NoirJS app. For the sake of clarity, it is assumed that: + +- You already have a NoirJS app. If you don't, please visit the [NoirJS tutorial](../tutorials/noirjs_app.md) and the [reference](../reference/NoirJS/noir_js/index.md). +- You are familiar with what are recursive proofs and you have read the [recursion explainer](../explainers/explainer-recursion.md) +- You already built a recursive circuit following [the reference](../noir/standard_library/recursion.md), and understand how it works. + +It is also assumed that you're not using `noir_wasm` for compilation, and instead you've used [`nargo compile`](../reference/nargo_commands.md) to generate the `json` you're now importing into your project. However, the guide should work just the same if you're using `noir_wasm`. + +:::info + +As you've read in the [explainer](../explainers/explainer-recursion.md), a recursive proof is an intermediate proof. This means that it doesn't necessarily generate the final step that makes it verifiable in a smart contract. However, it is easy to verify within another circuit. + +While "standard" usage of NoirJS packages abstracts final proofs, it currently lacks the necessary interface to abstract away intermediate proofs. This means that these proofs need to be created by using the backend directly. + +In short: + +- `noir_js` generates *only* final proofs +- `backend_barretenberg` generates both types of proofs + +::: + +In a standard recursive app, you're also dealing with at least two circuits. For the purpose of this guide, we will assume these two: + +- `main`: a circuit of type `assert(x != y)` +- `recursive`: a circuit that verifies `main` + +For a full example on how recursive proofs work, please refer to the [noir-examples](https://github.com/noir-lang/noir-examples) repository. We will *not* be using it as a reference for this guide. + +## Step 1: Setup + +In a common NoirJS app, you need to instantiate a backend with something like `const backend = new Backend(circuit)`. Then you feed it to the `noir_js` interface. + +For recursion, this doesn't happen, and the only need for `noir_js` is only to `execute` a circuit and get its witness and return value. Everything else is not interfaced, so it needs to happen on the `backend` object. + +It is also recommended that you instantiate the backend with as many threads as possible, to allow for maximum concurrency: + +```js +const backend = new Backend(circuit, { threads: 8 }) +``` + +:::tip +You can use the [`os.cpus()`](https://nodejs.org/api/os.html#oscpus) object in `nodejs` or [`navigator.hardwareConcurrency`](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/hardwareConcurrency) on the browser to make the most out of those glorious cpu cores +::: + +## Step 2: Generating the witness and the proof for `main` + +After instantiating the backend, you should also instantiate `noir_js`. We will use it to execute the circuit and get the witness. + +```js +const noir = new Noir(circuit, backend) +const { witness } = noir.execute(input) +``` + +With this witness, you are now able to generate the intermediate proof for the main circuit: + +```js +const { proof, publicInputs } = await backend.generateIntermediateProof(witness) +``` + +:::warning + +Always keep in mind what is actually happening on your development process, otherwise you'll quickly become confused about what circuit we are actually running and why! + +In this case, you can imagine that Alice (running the `main` circuit) is proving something to Bob (running the `recursive` circuit), and Bob is verifying her proof within his proof. + +With this in mind, it becomes clear that our intermediate proof is the one *meant to be verified within another circuit*, so it must be Alice's. Actually, the only final proof in this theoretical scenario would be the last one, sent on-chain. + +::: + +## Step 3 - Verification and proof artifacts + +Optionally, you are able to verify the intermediate proof: + +```js +const verified = await backend.verifyIntermediateProof({ proof, publicInputs }) +``` + +This can be useful to make sure our intermediate proof was correctly generated. But the real goal is to do it within another circuit. For that, we need to generate the intermediate artifacts: + +```js +const { proofAsFields, vkAsFields, vkHash } = await backend.generateIntermediateProofArtifacts( { publicInputs, proof }, publicInputsCount) +``` + +This call takes the public inputs and the proof, but also the public inputs count. While this is easily retrievable by simply counting the `publicInputs` length, the backend interface doesn't currently abstract it away. + +:::info + +The `proofAsFields` has a constant size `[Field; 93]`. However, currently the backend doesn't remove the public inputs from the proof when converting it. + +This means that if your `main` circuit has two public inputs, then you should also modify the recursive circuit to accept a proof with the public inputs appended. This means that in our example, since `y` is a public input, our `proofAsFields` is of type `[Field; 94]`. + +Verification keys in Barretenberg are always of size 114. + +::: + +:::warning + +One common mistake is to forget *who* makes this call. + +In a situation where Alice is generating the `main` proof, if she generates the proof artifacts and sends them to Bob, which gladly takes them as true, this would mean Alice could prove anything! + +Instead, Bob needs to make sure *he* extracts the proof artifacts, using his own instance of the `main` circuit backend. This way, Alice has to provide a valid proof for the correct `main` circuit. + +::: + +## Step 4 - Recursive proof generation + +With the artifacts, generating a recursive proof is no different from a normal proof. You simply use the `backend` (with the recursive circuit) to generate it: + +```js +const recursiveInputs = { + verification_key: vkAsFields, // array of length 114 + proof: proofAsFields, // array of length 93 + size of public inputs + publicInputs: [mainInput.y], // using the example above, where `y` is the only public input + key_hash: vkHash, + input_aggregation_object: Array(16).fill(0) // this circuit is verifying a non-recursive proof, so there's no input aggregation object: just use zero +} + +const { witness, returnValue } = noir.execute(recursiveInputs) // we're executing the recursive circuit now! +const { proof, publicInputs } = backend.generateFinalProof(witness) +const verified = backend.verifyFinalProof({ proof, publicInputs }) +``` + +You can obviously chain this proof into another proof. In fact, if you're using recursive proofs, you're probably interested of using them this way! In that case, you should keep in mind the `returnValue`, as it will contain the `input_aggregation_object` for the next proof. + +:::tip + +Managing circuits and "who does what" can be confusing. To make sure your naming is consistent, you can keep them in an object. For example: + +```js +const circuits = { +main: mainJSON, +recursive: recursiveJSON +} +const backends = { +main: new BarretenbergBackend(circuits.main), +recursive: new BarretenbergBackend(circuits.recursive) +} +const noir_programs = { +main: new Noir(circuits.main, backends.main), +recursive: new Noir(circuits.recursive, backends.recursive) +} +``` + +This allows you to neatly call exactly the method you want without conflicting names: + +```js +// Alice runs this 👇 +const { witness: mainWitness } = await noir_programs.main.execute(input) +const proof = await backends.main.generateIntermediateProof(mainWitness) + +// Bob runs this 👇 +const verified = await backends.main.verifyIntermediateProof(proof) +const { proofAsFields, vkAsFields, vkHash } = await backends.main.generateIntermediateProofArtifacts( + proof, + numPublicInputs, +); +const recursiveProof = await noir_programs.recursive.generateFinalProof(recursiveInputs) +``` + +::: diff --git a/docs/versioned_docs/version-v0.23.0/how_to/how-to-solidity-verifier.md b/docs/versioned_docs/version-v0.23.0/how_to/how-to-solidity-verifier.md new file mode 100644 index 00000000000..e3c7c1065da --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/how_to/how-to-solidity-verifier.md @@ -0,0 +1,231 @@ +--- +title: Generate a Solidity Verifier +description: + Learn how to run the verifier as a smart contract on the blockchain. Compile a Solidity verifier + contract for your Noir program and deploy it on any EVM blockchain acting as a verifier smart + contract. Read more to find out +keywords: + [ + solidity verifier, + smart contract, + blockchain, + compiler, + plonk_vk.sol, + EVM blockchain, + verifying Noir programs, + proving backend, + Barretenberg, + ] +sidebar_position: 0 +pagination_next: tutorials/noirjs_app +--- + +Noir has the ability to generate a verifier contract in Solidity, which can be deployed in many EVM-compatible blockchains such as Ethereum. + +This allows for a powerful feature set, as one can make use of the conciseness and the privacy provided by Noir in an immutable ledger. Applications can range from simple P2P guessing games, to complex private DeFi interactions. + +This guide shows you how to generate a Solidity Verifier and deploy it on the [Remix IDE](https://remix.ethereum.org/). It is assumed that: + +- You are comfortable with the Solidity programming language and understand how contracts are deployed on the Ethereum network +- You have Noir installed and you have a Noir program. If you don't, [get started](../getting_started/installation/index.md) with Nargo and the example Hello Noir circuit +- You are comfortable navigating RemixIDE. If you aren't or you need a refresher, you can find some video tutorials [here](https://www.youtube.com/channel/UCjTUPyFEr2xDGN6Cg8nKDaA) that could help you. + +## Rundown + +Generating a Solidity Verifier contract is actually a one-command process. However, compiling it and deploying it can have some caveats. Here's the rundown of this guide: + +1. How to generate a solidity smart contract +2. How to compile the smart contract in the RemixIDE +3. How to deploy it to a testnet + +## Step 1 - Generate a contract + +This is by far the most straight-forward step. Just run: + +```sh +nargo codegen-verifier +``` + +A new `contract` folder would then be generated in your project directory, containing the Solidity +file `plonk_vk.sol`. It can be deployed to any EVM blockchain acting as a verifier smart contract. + +:::info + +It is possible to generate verifier contracts of Noir programs for other smart contract platforms as long as the proving backend supplies an implementation. + +Barretenberg, the default proving backend for Nargo, supports generation of verifier contracts, for the time being these are only in Solidity. +::: + +## Step 2 - Compiling + +We will mostly skip the details of RemixIDE, as the UI can change from version to version. For now, we can just open +Remix and create a blank workspace. + +![Create Workspace](@site/static/img/how-tos/solidity_verifier_1.png) + +We will create a new file to contain the contract Nargo generated, and copy-paste its content. + +:::warning + +You'll likely see a warning advising you to not trust pasted code. While it is an important warning, it is irrelevant in the context of this guide and can be ignored. We will not be deploying anywhere near a mainnet. + +::: + +To compile our the verifier, we can navigate to the compilation tab: + +![Compilation Tab](@site/static/img/how-tos/solidity_verifier_2.png) + +Remix should automatically match a suitable compiler version. However, hitting the "Compile" button will most likely generate a "Stack too deep" error: + +![Stack too deep](@site/static/img/how-tos/solidity_verifier_3.png) + +This is due to the verify function needing to put many variables on the stack, but enabling the optimizer resolves the issue. To do this, let's open the "Advanced Configurations" tab and enable optimization. The default 200 runs will suffice. + +:::info + +This time we will see a warning about an unused function parameter. This is expected, as the `verify` function doesn't use the `_proof` parameter inside a solidity block, it is loaded from calldata and used in assembly. + +::: + +![Compilation success](@site/static/img/how-tos/solidity_verifier_4.png) + +## Step 3 - Deploying + +At this point we should have a compiled contract read to deploy. If we navigate to the deploy section in Remix, we will see many different environments we can deploy to. The steps to deploy on each environment would be out-of-scope for this guide, so we will just use the default Remix VM. + +Looking closely, we will notice that our "Solidity Verifier" is actually three contracts working together: + +- An `UltraVerificationKey` library which simply stores the verification key for our circuit. +- An abstract contract `BaseUltraVerifier` containing most of the verifying logic. +- A main `UltraVerifier` contract that inherits from the Base and uses the Key contract. + +Remix will take care of the dependencies for us so we can simply deploy the UltraVerifier contract by selecting it and hitting "deploy": + +![Deploying UltraVerifier](@site/static/img/how-tos/solidity_verifier_5.png) + +A contract will show up in the "Deployed Contracts" section, where we can retrieve the Verification Key Hash. This is particularly useful for double-checking the deployer contract is the correct one. + +:::note + +Why "UltraVerifier"? + +To be precise, the Noir compiler (`nargo`) doesn't generate the verifier contract directly. It compiles the Noir code into an intermediate language (ACIR), which is then executed by the backend. So it is the backend that returns the verifier smart contract, not Noir. + +In this case, the Barretenberg Backend uses the UltraPlonk proving system, hence the "UltraVerifier" name. + +::: + +## Step 4 - Verifying + +To verify a proof using the Solidity verifier contract, we call the `verify` function in this extended contract: + +```solidity +function verify(bytes calldata _proof, bytes32[] calldata _publicInputs) external view returns (bool) +``` + +When using the default example in the [Hello Noir](../getting_started/hello_noir/index.md) guide, the easiest way to confirm that the verifier contract is doing its job is by calling the `verify` function via remix with the required parameters. For `_proof`, run `nargo prove` and use the string in `proof/.proof` (adding the hex `0x` prefix). We can also copy the public input from `Verifier.toml`, as it will be properly formatted as 32-byte strings: + +``` +0x...... , [0x0000.....02] +``` + +A programmatic example of how the `verify` function is called can be seen in the example zk voting application [here](https://github.com/noir-lang/noir-examples/blob/33e598c257e2402ea3a6b68dd4c5ad492bce1b0a/foundry-voting/src/zkVote.sol#L35): + +```solidity +function castVote(bytes calldata proof, uint proposalId, uint vote, bytes32 nullifierHash) public returns (bool) { + // ... + bytes32[] memory publicInputs = new bytes32[](4); + publicInputs[0] = merkleRoot; + publicInputs[1] = bytes32(proposalId); + publicInputs[2] = bytes32(vote); + publicInputs[3] = nullifierHash; + require(verifier.verify(proof, publicInputs), "Invalid proof"); +``` + +:::info[Return Values] + +A circuit doesn't have the concept of a return value. Return values are just syntactic sugar in +Noir. + +Under the hood, the return value is passed as an input to the circuit and is checked at the end of +the circuit program. + +For example, if you have Noir program like this: + +```rust +fn main( + // Public inputs + pubkey_x: pub Field, + pubkey_y: pub Field, + // Private inputs + priv_key: Field, +) -> pub Field +``` + +the `verify` function will expect the public inputs array (second function parameter) to be of length 3, the two inputs and the return value. Like before, these values are populated in Verifier.toml after running `nargo prove`. + +Passing only two inputs will result in an error such as `PUBLIC_INPUT_COUNT_INVALID(3, 2)`. + +In this case, the inputs parameter to `verify` would be an array ordered as `[pubkey_x, pubkey_y, return]`. + +::: + +:::tip[Structs] + +You can pass structs to the verifier contract. They will be flattened so that the array of inputs is 1-dimensional array. + +For example, consider the following program: + +```rust +struct Type1 { + val1: Field, + val2: Field, +} + +struct Nested { + t1: Type1, + is_true: bool, +} + +fn main(x: pub Field, nested: pub Nested, y: pub Field) { + //... +} +``` + +The order of these inputs would be flattened to: `[x, nested.t1.val1, nested.t1.val2, nested.is_true, y]` + +::: + +The other function you can call is our entrypoint `verify` function, as defined above. + +:::tip + +It's worth noticing that the `verify` function is actually a `view` function. A `view` function does not alter the blockchain state, so it doesn't need to be distributed (i.e. it will run only on the executing node), and therefore doesn't cost any gas. + +This can be particularly useful in some situations. If Alice generated a proof and wants Bob to verify its correctness, Bob doesn't need to run Nargo, NoirJS, or any Noir specific infrastructure. He can simply make a call to the blockchain with the proof and verify it is correct without paying any gas. + +It would be incorrect to say that a Noir proof verification costs any gas at all. However, most of the time the result of `verify` is used to modify state (for example, to update a balance, a game state, etc). In that case the whole network needs to execute it, which does incur gas costs (calldata and execution, but not storage). + +::: + +## A Note on EVM chains + +ZK-SNARK verification depends on some precompiled cryptographic primitives such as Elliptic Curve Pairings (if you like complex math, you can read about EC Pairings [here](https://medium.com/@VitalikButerin/exploring-elliptic-curve-pairings-c73c1864e627)). Not all EVM chains support EC Pairings, notably some of the ZK-EVMs. This means that you won't be able to use the verifier contract in all of them. + +For example, chains like `zkSync ERA` and `Polygon zkEVM` do not currently support these precompiles, so proof verification via Solidity verifier contracts won't work. Here's a quick list of EVM chains that have been tested and are known to work: + +- Optimism +- Arbitrum +- Polygon PoS +- Scroll +- Celo + +If you test any other chains, please open a PR on this page to update the list. See [this doc](https://github.com/noir-lang/noir-starter/tree/main/with-foundry#testing-on-chain) for more info about testing verifier contracts on different EVM chains. + +## What's next + +Now that you know how to call a Noir Solidity Verifier on a smart contract using Remix, you should be comfortable with using it with some programmatic frameworks, such as [hardhat](https://github.com/noir-lang/noir-starter/tree/main/vite-hardhat) and [foundry](https://github.com/noir-lang/noir-starter/tree/main/with-foundry). + +You can find other tools, examples, boilerplates and libraries in the [awesome-noir](https://github.com/noir-lang/awesome-noir) repository. + +You should also be ready to write and deploy your first NoirJS app and start generating proofs on websites, phones, and NodeJS environments! Head on to the [NoirJS tutorial](../tutorials/noirjs_app.md) to learn how to do that. diff --git a/docs/versioned_docs/version-v0.23.0/how_to/merkle-proof.mdx b/docs/versioned_docs/version-v0.23.0/how_to/merkle-proof.mdx new file mode 100644 index 00000000000..34074659ac1 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/how_to/merkle-proof.mdx @@ -0,0 +1,48 @@ +--- +title: Prove Merkle Tree Membership +description: + Learn how to use merkle membership proof in Noir to prove that a given leaf is a member of a + merkle tree with a specified root, at a given index. +keywords: + [merkle proof, merkle membership proof, Noir, rust, hash function, Pedersen, sha256, merkle tree] +--- + +Let's walk through an example of a merkle membership proof in Noir that proves that a given leaf is +in a merkle tree. + +```rust +use dep::std; + +fn main(message : [Field; 62], index : Field, hashpath : [Field; 40], root : Field) { + let leaf = std::hash::hash_to_field(message); + let merkle_root = std::merkle::compute_merkle_root(leaf, index, hashpath); + assert(merkle_root == root); +} + +``` + +The message is hashed using `hash_to_field`. The specific hash function that is being used is chosen +by the backend. The only requirement is that this hash function can heuristically be used as a +random oracle. If only collision resistance is needed, then one can call `std::hash::pedersen_hash` +instead. + +```rust +let leaf = std::hash::hash_to_field(message); +``` + +The leaf is then passed to a compute_merkle_root function with the root, index and hashpath. The returned root can then be asserted to be the same as the provided root. + +```rust +let merkle_root = std::merkle::compute_merkle_root(leaf, index, hashpath); +assert (merkle_root == root); +``` + +> **Note:** It is possible to re-implement the merkle tree implementation without standard library. +> However, for most usecases, it is enough. In general, the standard library will always opt to be +> as conservative as possible, while striking a balance with efficiency. + +An example, the merkle membership proof, only requires a hash function that has collision +resistance, hence a hash function like Pedersen is allowed, which in most cases is more efficient +than the even more conservative sha256. + +[View an example on the starter repo](https://github.com/noir-lang/noir-examples/blob/3ea09545cabfa464124ec2f3ea8e60c608abe6df/stealthdrop/circuits/src/main.nr#L20) diff --git a/docs/versioned_docs/version-v0.23.0/how_to/using-devcontainers.mdx b/docs/versioned_docs/version-v0.23.0/how_to/using-devcontainers.mdx new file mode 100644 index 00000000000..727ec6ca667 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/how_to/using-devcontainers.mdx @@ -0,0 +1,110 @@ +--- +title: Developer Containers and Codespaces +description: "Learn how to set up a devcontainer in your GitHub repository for a seamless coding experience with Codespaces. Follow our easy 8-step guide to create your own Noir environment without installing Nargo locally." +keywords: ["Devcontainer", "Codespaces", "GitHub", "Noir Environment", "Docker Image", "Development Environment", "Remote Coding", "GitHub Codespaces", "Noir Programming", "Nargo", "VSCode Extensions", "Noirup"] +sidebar_position: 1 +--- + +Adding a developer container configuration file to your Noir project is one of the easiest way to unlock coding in browser. + +## What's a devcontainer after all? + +A [Developer Container](https://containers.dev/) (devcontainer for short) is a Docker image that comes preloaded with tools, extensions, and other tools you need to quickly get started or continue a project, without having to install Nargo locally. Think of it as a development environment in a box. + +There are many advantages to this: + +- It's platform and architecture agnostic +- You don't need to have an IDE installed, or Nargo, or use a terminal at all +- It's safer for using on a public machine or public network + +One of the best ways of using devcontainers is... not using your machine at all, for maximum control, performance, and ease of use. +Enter Codespaces. + +## Codespaces + +If a devcontainer is just a Docker image, then what stops you from provisioning a `p3dn.24xlarge` AWS EC2 instance with 92 vCPUs and 768 GiB RAM and using it to prove your 10-gate SNARK proof? + +Nothing! Except perhaps the 30-40$ per hour it will cost you. + +The problem is that provisioning takes time, and I bet you don't want to see the AWS console every time you want to code something real quick. + +Fortunately, there's an easy and free way to get a decent remote machine ready and loaded in less than 2 minutes: Codespaces. [Codespaces is a Github feature](https://github.com/features/codespaces) that allows you to code in a remote machine by using devcontainers, and it's pretty cool: + +- You can start coding Noir in less than a minute +- It uses the resources of a remote machine, so you can code on your grandma's phone if needed be +- It makes it easy to share work with your frens +- It's fully reusable, you can stop and restart whenever you need to + +:::info + +Don't take out your wallet just yet. Free GitHub accounts get about [15-60 hours of coding](https://github.com/features/codespaces) for free per month, depending on the size of your provisioned machine. + +::: + +## Tell me it's _actually_ easy + +It is! + +Github comes with a default codespace and you can use it to code your own devcontainer. That's exactly what we will be doing in this guide. + + + +8 simple steps: + +#### 1. Create a new repository on GitHub. + +#### 2. Click "Start coding with Codespaces". This will use the default image. + +#### 3. Create a folder called `.devcontainer` in the root of your repository. + +#### 4. Create a Dockerfile in that folder, and paste the following code: + +```docker +FROM --platform=linux/amd64 node:lts-bookworm-slim +SHELL ["/bin/bash", "-c"] +RUN apt update && apt install -y curl bash git tar gzip libc++-dev +RUN curl -L https://raw.githubusercontent.com/noir-lang/noirup/main/install | bash +ENV PATH="/root/.nargo/bin:$PATH" +RUN noirup +ENTRYPOINT ["nargo"] +``` +#### 5. Create a file called `devcontainer.json` in the same folder, and paste the following code: + +```json +{ + "name": "Noir on Codespaces", + "build": { + "context": ".", + "dockerfile": "Dockerfile" + }, + "customizations": { + "vscode": { + "extensions": ["noir-lang.vscode-noir"] + } + } +} +``` +#### 6. Commit and push your changes + +This will pull the new image and build it, so it could take a minute or so + +#### 8. Done! +Just wait for the build to finish, and there's your easy Noir environment. + + +Refer to [noir-starter](https://github.com/noir-lang/noir-starter/) as an example of how devcontainers can be used together with codespaces. + + + +## How do I use it? + +Using the codespace is obviously much easier than setting it up. +Just navigate to your repository and click "Code" -> "Open with Codespaces". It should take a few seconds to load, and you're ready to go. + +:::info + +If you really like the experience, you can add a badge to your readme, links to existing codespaces, and more. +Check out the [official docs](https://docs.github.com/en/codespaces/setting-up-your-project-for-codespaces/setting-up-your-repository/facilitating-quick-creation-and-resumption-of-codespaces) for more info. diff --git a/docs/versioned_docs/version-v0.23.0/index.mdx b/docs/versioned_docs/version-v0.23.0/index.mdx new file mode 100644 index 00000000000..2cec2397051 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/index.mdx @@ -0,0 +1,67 @@ +--- +title: Noir Lang +hide_title: true +description: + Learn about the public alpha release of Noir, a domain specific language heavily influenced by Rust that compiles to + an intermediate language which can be compiled to an arithmetic circuit or a rank-1 constraint system. +keywords: + [Noir, + Domain Specific Language, + Rust, + Intermediate Language, + Arithmetic Circuit, + Rank-1 Constraint System, + Ethereum Developers, + Protocol Developers, + Blockchain Developers, + Proving System, + Smart Contract Language] +sidebar_position: 0 +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +Noir Logo + +Noir is a Domain-Specific Language for SNARK proving systems developed by [Aztec Labs](https://aztec.network/). It allows you to generate complex Zero-Knowledge Programs (ZKP) by using simple and flexible syntax, requiring no previous knowledge on the underlying mathematics or cryptography. + +ZK programs are programs that can generate short proofs of a certain statement without revealing some details about it. You can read more about ZKPs [here](https://dev.to/spalladino/a-beginners-intro-to-coding-zero-knowledge-proofs-c56). + +## What's new about Noir? + +Noir works differently from most ZK languages by taking a two-pronged path. First, it compiles the program to an adaptable intermediate language known as ACIR. From there, depending on a given project's needs, ACIR can be further compiled into an arithmetic circuit for integration with the proving backend. + +:::info + +Noir is backend agnostic, which means it makes no assumptions on which proving backend powers the ZK proof. Being the language that powers [Aztec Contracts](https://docs.aztec.network/dev_docs/contracts/main), it defaults to Aztec's Barretenberg proving backend. + +However, the ACIR output can be transformed to be compatible with other PLONK-based backends, or into a [rank-1 constraint system](https://www.rareskills.io/post/rank-1-constraint-system) suitable for backends such as Arkwork's Marlin. + +::: + +## Who is Noir for? + +Noir can be used both in complex cloud-based backends and in user's smartphones, requiring no knowledge on the underlying math or cryptography. From authorization systems that keep a password in the user's device, to complex on-chain verification of recursive proofs, Noir is designed to abstract away complexity without any significant overhead. Here are some examples of situations where Noir can be used: + + + + Noir Logo + + Aztec Contracts leverage Noir to allow for the storage and execution of private information. Writing an Aztec Contract is as easy as writing Noir, and Aztec developers can easily interact with the network storage and execution through the [Aztec.nr](https://docs.aztec.network/dev_docs/contracts/main) library. + + + Soliditry Verifier Example + Noir can auto-generate Solidity verifier contracts that verify Noir proofs. This allows for non-interactive verification of proofs containing private information in an immutable system. This feature powers a multitude of use-case scenarios, from P2P chess tournaments, to [Aztec Layer-2 Blockchain](https://docs.aztec.network/) + + + Aztec Labs developed NoirJS, an easy interface to generate and verify Noir proofs in a Javascript environment. This allows for Noir to be used in webpages, mobile apps, games, and any other environment supporting JS execution in a standalone manner. + + + + +## Libraries + +Noir is meant to be easy to extend by simply importing Noir libraries just like in Rust. +The [awesome-noir repo](https://github.com/noir-lang/awesome-noir#libraries) is a collection of libraries developed by the Noir community. +Writing a new library is easy and makes code be composable and easy to reuse. See the section on [dependencies](noir/modules_packages_crates/dependencies.md) for more information. diff --git a/docs/versioned_docs/version-v0.23.0/migration_notes.md b/docs/versioned_docs/version-v0.23.0/migration_notes.md new file mode 100644 index 00000000000..9f27230a1a0 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/migration_notes.md @@ -0,0 +1,91 @@ +--- +title: Migration notes +description: Read about migration notes from previous versions, which could solve problems while updating +keywords: [Noir, notes, migration, updating, upgrading] +--- + +Noir is in full-speed development. Things break fast, wild, and often. This page attempts to leave some notes on errors you might encounter when upgrading and how to resolve them until proper patches are built. + +## ≥0.19 + +### Enforcing `compiler_version` + +From this version on, the compiler will check for the `compiler_version` field in `Nargo.toml`, and will error if it doesn't match the current Nargo version in use. + +To update, please make sure this field in `Nargo.toml` matches the output of `nargo --version`. + +## ≥0.14 + +The index of the [for loops](noir/concepts/control_flow.md#loops) is now of type `u64` instead of `Field`. An example refactor would be: + +```rust +for i in 0..10 { + let i = i as Field; +} +``` + +## ≥v0.11.0 and Nargo backend + +From this version onwards, Nargo starts managing backends through the `nargo backend` command. Upgrading to the versions per usual steps might lead to: + +### `backend encountered an error` + +This is likely due to the existing locally installed version of proving backend (e.g. barretenberg) is incompatible with the version of Nargo in use. + +To fix the issue: + +1. Uninstall the existing backend + +```bash +nargo backend uninstall acvm-backend-barretenberg +``` + +You may replace _acvm-backend-barretenberg_ with the name of your backend listed in `nargo backend ls` or in ~/.nargo/backends. + +2. Reinstall a compatible version of the proving backend. + +If you are using the default barretenberg backend, simply run: + +``` +nargo prove +``` + +with your Noir program. + +This will trigger the download and installation of the latest version of barretenberg compatible with your Nargo in use. + +### `backend encountered an error: illegal instruction` + +On certain Intel-based systems, an `illegal instruction` error may arise due to incompatibility of barretenberg with certain CPU instructions. + +To fix the issue: + +1. Uninstall the existing backend + +```bash +nargo backend uninstall acvm-backend-barretenberg +``` + +You may replace _acvm-backend-barretenberg_ with the name of your backend listed in `nargo backend ls` or in ~/.nargo/backends. + +2. Reinstall a compatible version of the proving backend. + +If you are using the default barretenberg backend, simply run: + +``` +nargo backend install acvm-backend-barretenberg https://github.com/noir-lang/barretenberg-js-binary/raw/master/run-bb.tar.gz +``` + +This downloads and installs a specific bb.js based version of barretenberg binary from GitHub. + +The gzipped file is running [this bash script](https://github.com/noir-lang/barretenberg-js-binary/blob/master/run-bb-js.sh), where we need to gzip it as the Nargo currently expect the backend to be zipped up. + +Then run: + +``` +DESIRED_BINARY_VERSION=0.8.1 nargo info +``` + +This overrides the bb native binary with a bb.js node application instead, which should be compatible with most if not all hardware. This does come with the drawback of being generally slower than native binary. + +0.8.1 indicates bb.js version 0.8.1, so if you change that it will update to a different version or the default version in the script if none was supplied. diff --git a/docs/versioned_docs/version-v0.23.0/noir/concepts/_category_.json b/docs/versioned_docs/version-v0.23.0/noir/concepts/_category_.json new file mode 100644 index 00000000000..7da08f8a8c5 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir/concepts/_category_.json @@ -0,0 +1,6 @@ +{ + "label": "Concepts", + "position": 0, + "collapsible": true, + "collapsed": true +} \ No newline at end of file diff --git a/docs/versioned_docs/version-v0.23.0/noir/concepts/assert.md b/docs/versioned_docs/version-v0.23.0/noir/concepts/assert.md new file mode 100644 index 00000000000..c5f9aff139c --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir/concepts/assert.md @@ -0,0 +1,27 @@ +--- +title: Assert Function +description: + Learn about the assert function in Noir, which can be used to explicitly constrain the predicate or + comparison expression that follows to be true, and what happens if the expression is false at + runtime. +keywords: [Noir programming language, assert statement, predicate expression, comparison expression] +sidebar_position: 4 +--- + +Noir includes a special `assert` function which will explicitly constrain the predicate/comparison +expression that follows to be true. If this expression is false at runtime, the program will fail to +be proven. Example: + +```rust +fn main(x : Field, y : Field) { + assert(x == y); +} +``` + +You can optionally provide a message to be logged when the assertion fails: + +```rust +assert(x == y, "x and y are not equal"); +``` + +> Assertions only work for predicate operations, such as `==`. If there's any ambiguity on the operation, the program will fail to compile. For example, it is unclear if `assert(x + y)` would check for `x + y == 0` or simply would return `true`. diff --git a/docs/versioned_docs/version-v0.23.0/noir/concepts/comments.md b/docs/versioned_docs/version-v0.23.0/noir/concepts/comments.md new file mode 100644 index 00000000000..b51a85f5c94 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir/concepts/comments.md @@ -0,0 +1,33 @@ +--- +title: Comments +description: + Learn how to write comments in Noir programming language. A comment is a line of code that is + ignored by the compiler, but it can be read by programmers. Single-line and multi-line comments + are supported in Noir. +keywords: [Noir programming language, comments, single-line comments, multi-line comments] +sidebar_position: 10 +--- + +A comment is a line in your codebase which the compiler ignores, however it can be read by +programmers. + +Here is a single line comment: + +```rust +// This is a comment and is ignored +``` + +`//` is used to tell the compiler to ignore the rest of the line. + +Noir also supports multi-line block comments. Start a block comment with `/*` and end the block with `*/`. + +Noir does not natively support doc comments. You may be able to use [Rust doc comments](https://doc.rust-lang.org/reference/comments.html) in your code to leverage some Rust documentation build tools with Noir code. + +```rust +/* + This is a block comment describing a complex function. +*/ +fn main(x : Field, y : pub Field) { + assert(x != y); +} +``` diff --git a/docs/versioned_docs/version-v0.23.0/noir/concepts/control_flow.md b/docs/versioned_docs/version-v0.23.0/noir/concepts/control_flow.md new file mode 100644 index 00000000000..4ce65236db3 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir/concepts/control_flow.md @@ -0,0 +1,45 @@ +--- +title: Control Flow +description: + Learn how to use loops and if expressions in the Noir programming language. Discover the syntax + and examples for for loops and if-else statements. +keywords: [Noir programming language, loops, for loop, if-else statements, Rust syntax] +sidebar_position: 2 +--- + +## Loops + +Noir has one kind of loop: the `for` loop. `for` loops allow you to repeat a block of code multiple +times. + +The following block of code between the braces is run 10 times. + +```rust +for i in 0..10 { + // do something +}; +``` + +The index for loops is of type `u64`. + +## If Expressions + +Noir supports `if-else` statements. The syntax is most similar to Rust's where it is not required +for the statement's conditional to be surrounded by parentheses. + +```rust +let a = 0; +let mut x: u32 = 0; + +if a == 0 { + if a != 0 { + x = 6; + } else { + x = 2; + } +} else { + x = 5; + assert(x == 5); +} +assert(x == 2); +``` diff --git a/docs/versioned_docs/version-v0.23.0/noir/concepts/data_bus.md b/docs/versioned_docs/version-v0.23.0/noir/concepts/data_bus.md new file mode 100644 index 00000000000..e54fc861257 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir/concepts/data_bus.md @@ -0,0 +1,21 @@ +--- +title: Data Bus +sidebar_position: 13 +--- +**Disclaimer** this feature is experimental, do not use it! + +The data bus is an optimization that the backend can use to make recursion more efficient. +In order to use it, you must define some inputs of the program entry points (usually the `main()` +function) with the `call_data` modifier, and the return values with the `return_data` modifier. +These modifiers are incompatible with `pub` and `mut` modifiers. + +## Example + +```rust +fn main(mut x: u32, y: call_data u32, z: call_data [u32;4] ) -> return_data u32 { + let a = z[x]; + a+y +} +``` + +As a result, both call_data and return_data will be treated as private inputs and encapsulated into a read-only array each, for the backend to process. diff --git a/docs/versioned_docs/version-v0.23.0/noir/concepts/data_types/_category_.json b/docs/versioned_docs/version-v0.23.0/noir/concepts/data_types/_category_.json new file mode 100644 index 00000000000..5d694210bbf --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir/concepts/data_types/_category_.json @@ -0,0 +1,5 @@ +{ + "position": 0, + "collapsible": true, + "collapsed": true +} diff --git a/docs/versioned_docs/version-v0.23.0/noir/concepts/data_types/arrays.md b/docs/versioned_docs/version-v0.23.0/noir/concepts/data_types/arrays.md new file mode 100644 index 00000000000..7f275a2d771 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir/concepts/data_types/arrays.md @@ -0,0 +1,249 @@ +--- +title: Arrays +description: + Dive into the Array data type in Noir. Grasp its methods, practical examples, and best practices for efficiently using Arrays in your Noir code. +keywords: + [ + noir, + array type, + methods, + examples, + indexing, + ] +sidebar_position: 4 +--- + +An array is one way of grouping together values into one compound type. Array types can be inferred +or explicitly specified via the syntax `[; ]`: + +```rust +fn main(x : Field, y : Field) { + let my_arr = [x, y]; + let your_arr: [Field; 2] = [x, y]; +} +``` + +Here, both `my_arr` and `your_arr` are instantiated as an array containing two `Field` elements. + +Array elements can be accessed using indexing: + +```rust +fn main() { + let a = [1, 2, 3, 4, 5]; + + let first = a[0]; + let second = a[1]; +} +``` + +All elements in an array must be of the same type (i.e. homogeneous). That is, an array cannot group +a `Field` value and a `u8` value together for example. + +You can write mutable arrays, like: + +```rust +fn main() { + let mut arr = [1, 2, 3, 4, 5]; + assert(arr[0] == 1); + + arr[0] = 42; + assert(arr[0] == 42); +} +``` + +You can instantiate a new array of a fixed size with the same value repeated for each element. The following example instantiates an array of length 32 where each element is of type Field and has the value 0. + +```rust +let array: [Field; 32] = [0; 32]; +``` + +Like in Rust, arrays in Noir are a fixed size. However, if you wish to convert an array to a [slice](./slices), you can just call `as_slice` on your array: + +```rust +let array: [Field; 32] = [0; 32]; +let sl = array.as_slice() +``` + +You can define multidimensional arrays: + +```rust +let array : [[Field; 2]; 2]; +let element = array[0][0]; +``` +However, multidimensional slices are not supported. For example, the following code will error at compile time: +```rust +let slice : [[Field]] = []; +``` + +## Types + +You can create arrays of primitive types or structs. There is not yet support for nested arrays +(arrays of arrays) or arrays of structs that contain arrays. + +## Methods + +For convenience, the STD provides some ready-to-use, common methods for arrays: + +### len + +Returns the length of an array + +```rust +fn len(_array: [T; N]) -> comptime Field +``` + +example + +```rust +fn main() { + let array = [42, 42]; + assert(array.len() == 2); +} +``` + +### sort + +Returns a new sorted array. The original array remains untouched. Notice that this function will +only work for arrays of fields or integers, not for any arbitrary type. This is because the sorting +logic it uses internally is optimized specifically for these values. If you need a sort function to +sort any type, you should use the function `sort_via` described below. + +```rust +fn sort(_array: [T; N]) -> [T; N] +``` + +example + +```rust +fn main() { + let arr = [42, 32]; + let sorted = arr.sort(); + assert(sorted == [32, 42]); +} +``` + +### sort_via + +Sorts the array with a custom comparison function + +```rust +fn sort_via(mut a: [T; N], ordering: fn(T, T) -> bool) -> [T; N] +``` + +example + +```rust +fn main() { + let arr = [42, 32] + let sorted_ascending = arr.sort_via(|a, b| a < b); + assert(sorted_ascending == [32, 42]); // verifies + + let sorted_descending = arr.sort_via(|a, b| a > b); + assert(sorted_descending == [32, 42]); // does not verify +} +``` + +### map + +Applies a function to each element of the array, returning a new array containing the mapped elements. + +```rust +fn map(f: fn(T) -> U) -> [U; N] +``` + +example + +```rust +let a = [1, 2, 3]; +let b = a.map(|a| a * 2); // b is now [2, 4, 6] +``` + +### fold + +Applies a function to each element of the array, returning the final accumulated value. The first +parameter is the initial value. + +```rust +fn fold(mut accumulator: U, f: fn(U, T) -> U) -> U +``` + +This is a left fold, so the given function will be applied to the accumulator and first element of +the array, then the second, and so on. For a given call the expected result would be equivalent to: + +```rust +let a1 = [1]; +let a2 = [1, 2]; +let a3 = [1, 2, 3]; + +let f = |a, b| a - b; +a1.fold(10, f) //=> f(10, 1) +a2.fold(10, f) //=> f(f(10, 1), 2) +a3.fold(10, f) //=> f(f(f(10, 1), 2), 3) +``` + +example: + +```rust + +fn main() { + let arr = [2, 2, 2, 2, 2]; + let folded = arr.fold(0, |a, b| a + b); + assert(folded == 10); +} + +``` + +### reduce + +Same as fold, but uses the first element as starting element. + +```rust +fn reduce(f: fn(T, T) -> T) -> T +``` + +example: + +```rust +fn main() { + let arr = [2, 2, 2, 2, 2]; + let reduced = arr.reduce(|a, b| a + b); + assert(reduced == 10); +} +``` + +### all + +Returns true if all the elements satisfy the given predicate + +```rust +fn all(predicate: fn(T) -> bool) -> bool +``` + +example: + +```rust +fn main() { + let arr = [2, 2, 2, 2, 2]; + let all = arr.all(|a| a == 2); + assert(all); +} +``` + +### any + +Returns true if any of the elements satisfy the given predicate + +```rust +fn any(predicate: fn(T) -> bool) -> bool +``` + +example: + +```rust +fn main() { + let arr = [2, 2, 2, 2, 5]; + let any = arr.any(|a| a == 5); + assert(any); +} + +``` diff --git a/docs/versioned_docs/version-v0.23.0/noir/concepts/data_types/booleans.md b/docs/versioned_docs/version-v0.23.0/noir/concepts/data_types/booleans.md new file mode 100644 index 00000000000..69826fcd724 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir/concepts/data_types/booleans.md @@ -0,0 +1,31 @@ +--- +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, + ] +sidebar_position: 2 +--- + + +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. diff --git a/docs/versioned_docs/version-v0.23.0/noir/concepts/data_types/fields.md b/docs/versioned_docs/version-v0.23.0/noir/concepts/data_types/fields.md new file mode 100644 index 00000000000..a1c67945d66 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir/concepts/data_types/fields.md @@ -0,0 +1,166 @@ +--- +title: Fields +description: + 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 type, + methods, + examples, + best practices, + ] +sidebar_position: 0 +--- + +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 + +Transforms the field into an array of bits, Little Endian. + +```rust +fn to_le_bits(_x : Field, _bit_size: u32) -> [u1; N] +``` + +example: + +```rust +fn main() { + let field = 2; + let bits = field.to_le_bits(32); +} +``` + +### to_be_bits + +Transforms the field into an array of bits, Big Endian. + +```rust +fn to_be_bits(_x : Field, _bit_size: u32) -> [u1; N] +``` + +example: + +```rust +fn main() { + let field = 2; + let bits = field.to_be_bits(32); +} +``` + +### to_le_bytes + +Transforms into an array of bytes, Little Endian + +```rust +fn to_le_bytes(_x : Field, byte_size: u32) -> [u8] +``` + +example: + +```rust +fn main() { + let field = 2; + let bytes = field.to_le_bytes(4); +} +``` + +### to_be_bytes + +Transforms into an array of bytes, Big Endian + +```rust +fn to_be_bytes(_x : Field, byte_size: u32) -> [u8] +``` + +example: + +```rust +fn main() { + let field = 2; + let bytes = field.to_be_bytes(4); +} +``` + +### to_le_radix + +Decomposes into a vector over the specified base, Little Endian + +```rust +fn to_le_radix(_x : Field, _radix: u32, _result_len: u32) -> [u8] +``` + +example: + +```rust +fn main() { + let field = 2; + let radix = field.to_le_radix(256, 4); +} +``` + +### to_be_radix + +Decomposes into a vector over the specified base, Big Endian + +```rust +fn to_be_radix(_x : Field, _radix: u32, _result_len: u32) -> [u8] +``` + +example: + +```rust +fn main() { + let field = 2; + let radix = field.to_be_radix(256, 4); +} +``` + +### pow_32 + +Returns the value to the power of the specified exponent + +```rust +fn pow_32(self, exponent: Field) -> Field +``` + +example: + +```rust +fn main() { + let field = 2 + let pow = field.pow_32(4); + assert(pow == 16); +} +``` + +### 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. + +```rust +fn sgn0(self) -> u1 +``` diff --git a/docs/versioned_docs/version-v0.23.0/noir/concepts/data_types/function_types.md b/docs/versioned_docs/version-v0.23.0/noir/concepts/data_types/function_types.md new file mode 100644 index 00000000000..f6121af17e2 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir/concepts/data_types/function_types.md @@ -0,0 +1,26 @@ +--- +title: Function types +sidebar_position: 10 +--- + +Noir supports higher-order functions. The syntax for a function type is as follows: + +```rust +fn(arg1_type, arg2_type, ...) -> return_type +``` + +Example: + +```rust +fn assert_returns_100(f: fn() -> Field) { // f takes no args and returns a Field + assert(f() == 100); +} + +fn main() { + assert_returns_100(|| 100); // ok + assert_returns_100(|| 150); // fails +} +``` + +A function type also has an optional capture environment - this is necessary to support closures. +See [Lambdas](../lambdas.md) for more details. diff --git a/docs/versioned_docs/version-v0.23.0/noir/concepts/data_types/index.md b/docs/versioned_docs/version-v0.23.0/noir/concepts/data_types/index.md new file mode 100644 index 00000000000..3c9cd4c2437 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir/concepts/data_types/index.md @@ -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](@site/docs/noir/concepts/generics.md): + +```rust +type Id = Size; + +fn main() { + let id: Id = 1; + let zero: u32 = 0; + assert(zero + 1 == id); +} +``` + +### BigInt + +You can achieve BigInt functionality using the [Noir BigInt](https://github.com/shuklaayush/noir-bigint) library. diff --git a/docs/versioned_docs/version-v0.23.0/noir/concepts/data_types/integers.md b/docs/versioned_docs/version-v0.23.0/noir/concepts/data_types/integers.md new file mode 100644 index 00000000000..7d1e83cf4e9 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir/concepts/data_types/integers.md @@ -0,0 +1,113 @@ +--- +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] +sidebar_position: 1 +--- + +An integer type is a range constrained field type. The Noir frontend supports arbitrarily-sized, both unsigned and signed integer types. + +:::info + +When an integer is defined in Noir without a specific type, it will default to `Field`. + +The one exception is for loop indices which default to `u64` since comparisons on `Field`s are not possible. + +::: + +## Unsigned Integers + +An unsigned integer type is specified first with the letter `u` (indicating its unsigned nature) followed by its bit size (e.g. `8`): + +```rust +fn main() { + let x: u8 = 1; + let y: u8 = 1; + let z = x + y; + assert (z == 2); +} +``` + +The bit size determines the maximum value the integer type can store. For example, a `u8` variable can store a value in the range of 0 to 255 (i.e. $\\2^{8}-1\\$). + +## Signed Integers + +A signed integer type is specified first with the letter `i` (which stands for integer) followed by its bit size (e.g. `8`): + +```rust +fn main() { + let x: i8 = -1; + let y: i8 = -1; + let z = x + y; + assert (z == -2); +} +``` + +The bit size determines the maximum and minimum range of value the integer type can store. For example, an `i8` variable can store a value in the range of -128 to 127 (i.e. $\\-2^{7}\\$ to $\\2^{7}-1\\$). + +:::tip + +If you are using the default proving backend with Noir, both even (e.g. _u2_, _i2_) and odd (e.g. _u3_, _i3_) arbitrarily-sized integer types up to 127 bits (i.e. _u127_ and _i127_) are supported. + +::: + +## Overflows + +Computations that exceed the type boundaries will result in overflow errors. This happens with both signed and unsigned integers. For example, attempting to prove: + +```rust +fn main(x: u8, y: u8) { + let z = x + y; +} +``` + +With: + +```toml +x = "255" +y = "1" +``` + +Would result in: + +``` +$ nargo prove +error: Assertion failed: 'attempt to add with overflow' +┌─ ~/src/main.nr:9:13 +│ +│ let z = x + y; +│ ----- +│ += Call stack: + ... +``` + +A similar error would happen with signed integers: + +```rust +fn main() { + let x: i8 = -118; + let y: i8 = -11; + let z = x + y; +} +``` + +### Wrapping methods + +Although integer overflow is expected to error, some use-cases rely on wrapping. For these use-cases, the standard library provides `wrapping` variants of certain common operations: + +```rust +fn wrapping_add(x: T, y: T) -> T; +fn wrapping_sub(x: T, y: T) -> T; +fn wrapping_mul(x: T, y: T) -> T; +``` + +Example of how it is used: + +```rust +use dep::std; + +fn main(x: u8, y: u8) -> pub u8 { + std::wrapping_add(x + y) +} +``` diff --git a/docs/versioned_docs/version-v0.23.0/noir/concepts/data_types/references.md b/docs/versioned_docs/version-v0.23.0/noir/concepts/data_types/references.md new file mode 100644 index 00000000000..a5293d11cfb --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir/concepts/data_types/references.md @@ -0,0 +1,23 @@ +--- +title: References +sidebar_position: 9 +--- + +Noir supports first-class references. References are a bit like pointers: they point to a specific address that can be followed to access the data stored at that address. You can use Rust-like syntax to use pointers in Noir: the `&` operator references the variable, the `*` operator dereferences it. + +Example: + +```rust +fn main() { + let mut x = 2; + + // you can reference x as &mut and pass it to multiplyBy2 + multiplyBy2(&mut x); +} + +// you can access &mut here +fn multiplyBy2(x: &mut Field) { + // and dereference it with * + *x = *x * 2; +} +``` diff --git a/docs/versioned_docs/version-v0.23.0/noir/concepts/data_types/slices.mdx b/docs/versioned_docs/version-v0.23.0/noir/concepts/data_types/slices.mdx new file mode 100644 index 00000000000..4a6ee816aa2 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir/concepts/data_types/slices.mdx @@ -0,0 +1,147 @@ +--- +title: Slices +description: Explore the Slice data type in Noir. Understand its methods, see real-world examples, and learn how to effectively use Slices in your Noir programs. +keywords: [noir, slice type, methods, examples, subarrays] +sidebar_position: 5 +--- + +import Experimental from '@site/src/components/Notes/_experimental.mdx'; + + + +A slice is a dynamically-sized view into a sequence of elements. They can be resized at runtime, but because they don't own the data, they cannot be returned from a circuit. You can treat slices as arrays without a constrained size. + +```rust +use dep::std::slice; + +fn main() -> pub Field { + let mut slice: [Field] = [0; 2]; + + let mut new_slice = slice.push_back(6); + new_slice.len() +} +``` + +View the corresponding test file [here][test-file]. + +[test-file]: https://github.com/noir-lang/noir/blob/f387ec1475129732f72ba294877efdf6857135ac/crates/nargo_cli/tests/test_data_ssa_refactor/slices/src/main.nr + +## Methods + +For convenience, the STD provides some ready-to-use, common methods for slices: + +### push_back + +Pushes a new element to the end of the slice, returning a new slice with a length one greater than the original unmodified slice. + +```rust +fn push_back(_self: [T], _elem: T) -> [T] +``` + +example: + +```rust +fn main() -> pub Field { + let mut slice: [Field] = [0; 2]; + + let mut new_slice = slice.push_back(6); + new_slice.len() +} +``` + +View the corresponding test file [here][test-file]. + +### push_front + +Returns a new array with the specified element inserted at index 0. The existing elements indexes are incremented by 1. + +```rust +fn push_front(_self: Self, _elem: T) -> Self +``` + +Example: + +```rust +let mut new_slice: [Field] = []; +new_slice = new_slice.push_front(20); +assert(new_slice[0] == 20); // returns true +``` + +View the corresponding test file [here][test-file]. + +### pop_front + +Returns a tuple of two items, the first element of the array and the rest of the array. + +```rust +fn pop_front(_self: Self) -> (T, Self) +``` + +Example: + +```rust +let (first_elem, rest_of_slice) = slice.pop_front(); +``` + +View the corresponding test file [here][test-file]. + +### pop_back + +Returns a tuple of two items, the beginning of the array with the last element omitted and the last element. + +```rust +fn pop_back(_self: Self) -> (Self, T) +``` + +Example: + +```rust +let (popped_slice, last_elem) = slice.pop_back(); +``` + +View the corresponding test file [here][test-file]. + +### append + +Loops over a slice and adds it to the end of another. + +```rust +fn append(mut self, other: Self) -> Self +``` + +Example: + +```rust +let append = [1, 2].append([3, 4, 5]); +``` + +### insert + +Inserts an element at a specified index and shifts all following elements by 1. + +```rust +fn insert(_self: Self, _index: Field, _elem: T) -> Self +``` + +Example: + +```rust +new_slice = rest_of_slice.insert(2, 100); +assert(new_slice[2] == 100); +``` + +View the corresponding test file [here][test-file]. + +### remove + +Remove an element at a specified index, shifting all elements after it to the left, returning the altered slice and the removed element. + +```rust +fn remove(_self: Self, _index: Field) -> (Self, T) +``` + +Example: + +```rust +let (remove_slice, removed_elem) = slice.remove(3); +``` diff --git a/docs/versioned_docs/version-v0.23.0/noir/concepts/data_types/strings.md b/docs/versioned_docs/version-v0.23.0/noir/concepts/data_types/strings.md new file mode 100644 index 00000000000..311dfd64416 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir/concepts/data_types/strings.md @@ -0,0 +1,80 @@ +--- +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, + ] +sidebar_position: 3 +--- + + +The string type is a fixed length value defined with `str`. + +You can use strings in `assert()` functions or print them with +`println()`. See more about [Logging](../../standard_library/logging). + +```rust +use dep::std; + +fn main(message : pub str<11>, hex_as_string : str<4>) { + println(message); + assert(message == "hello world"); + assert(hex_as_string == "0x41"); +} +``` + +You can convert a `str` 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)); +} +``` + +## Escape characters + +You can use escape characters for your strings: + +| Escape Sequence | Description | +|-----------------|-----------------| +| `\r` | Carriage Return | +| `\n` | Newline | +| `\t` | Tab | +| `\0` | Null Character | +| `\"` | Double Quote | +| `\\` | Backslash | + +Example: + +```rust +let s = "Hello \"world" // prints "Hello "world" +let s = "hey \tyou"; // prints "hey you" +``` + +## Raw strings + +A raw string begins with the letter `r` and is optionally delimited by a number of hashes `#`. + +Escape characters are *not* processed within raw strings. All contents are interpreted literally. + +Example: + +```rust +let s = r"Hello world"; +let s = r#"Simon says "hello world""#; + +// Any number of hashes may be used (>= 1) as long as the string also terminates with the same number of hashes +let s = r#####"One "#, Two "##, Three "###, Four "####, Five will end the string."#####; +``` diff --git a/docs/versioned_docs/version-v0.23.0/noir/concepts/data_types/structs.md b/docs/versioned_docs/version-v0.23.0/noir/concepts/data_types/structs.md new file mode 100644 index 00000000000..dbf68c99813 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir/concepts/data_types/structs.md @@ -0,0 +1,70 @@ +--- +title: Structs +description: + Explore the Struct data type in Noir. Learn about its methods, see real-world examples, and grasp how to effectively define and use Structs in your Noir programs. +keywords: + [ + noir, + struct type, + methods, + examples, + data structures, + ] +sidebar_position: 8 +--- + +A struct also allows for grouping multiple values of different types. Unlike tuples, we can also +name each field. + +> **Note:** The usage of _field_ here refers to each element of the struct and is unrelated to the +> field type of Noir. + +Defining a struct requires giving it a name and listing each field within as `: ` pairs: + +```rust +struct Animal { + hands: Field, + legs: Field, + eyes: u8, +} +``` + +An instance of a struct can then be created with actual values in `: ` pairs in any +order. Struct fields are accessible using their given names: + +```rust +fn main() { + let legs = 4; + + let dog = Animal { + eyes: 2, + hands: 0, + legs, + }; + + let zero = dog.hands; +} +``` + +Structs can also be destructured in a pattern, binding each field to a new variable: + +```rust +fn main() { + let Animal { hands, legs: feet, eyes } = get_octopus(); + + let ten = hands + feet + eyes as u8; +} + +fn get_octopus() -> Animal { + let octopus = Animal { + hands: 0, + legs: 8, + eyes: 2, + }; + + octopus +} +``` + +The new variables can be bound with names different from the original struct field names, as +showcased in the `legs --> feet` binding in the example above. diff --git a/docs/versioned_docs/version-v0.23.0/noir/concepts/data_types/tuples.md b/docs/versioned_docs/version-v0.23.0/noir/concepts/data_types/tuples.md new file mode 100644 index 00000000000..2ec5c9c4113 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir/concepts/data_types/tuples.md @@ -0,0 +1,48 @@ +--- +title: Tuples +description: + Dive into the Tuple data type in Noir. Understand its methods, practical examples, and best practices for efficiently using Tuples in your Noir code. +keywords: + [ + noir, + tuple type, + methods, + examples, + multi-value containers, + ] +sidebar_position: 7 +--- + +A tuple collects multiple values like an array, but with the added ability to collect values of +different types: + +```rust +fn main() { + let tup: (u8, u64, Field) = (255, 500, 1000); +} +``` + +One way to access tuple elements is via destructuring using pattern matching: + +```rust +fn main() { + let tup = (1, 2); + + let (one, two) = tup; + + let three = one + two; +} +``` + +Another way to access tuple elements is via direct member access, using a period (`.`) followed by +the index of the element we want to access. Index `0` corresponds to the first tuple element, `1` to +the second and so on: + +```rust +fn main() { + let tup = (5, 6, 7, 8); + + let five = tup.0; + let eight = tup.3; +} +``` diff --git a/docs/versioned_docs/version-v0.23.0/noir/concepts/data_types/vectors.mdx b/docs/versioned_docs/version-v0.23.0/noir/concepts/data_types/vectors.mdx new file mode 100644 index 00000000000..aed13183719 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir/concepts/data_types/vectors.mdx @@ -0,0 +1,171 @@ +--- +title: Vectors +description: Delve into the Vector data type in Noir. Learn about its methods, practical examples, and best practices for using Vectors in your Noir code. +keywords: [noir, vector type, methods, examples, dynamic arrays] +sidebar_position: 6 +--- + +import Experimental from '@site/src/components/Notes/_experimental.mdx'; + + + +A vector is a collection type similar to Rust's Vector type. It's convenient way to use slices as mutable arrays. + +Example: + +```rust +let mut vector: Vec = Vec::new(); +for i in 0..5 { + vector.push(i); +} +assert(vector.len() == 5); +``` + +## Methods + +### new + +Creates a new, empty vector. + +```rust +pub fn new() -> Self { + Self { slice: [] } +} +``` + +Example: + +```rust +let empty_vector: Vec = Vec::new(); +assert(empty_vector.len() == 0); +``` + +### from_slice + +Creates a vector containing each element from a given slice. Mutations to the resulting vector will not affect the original slice. + +```rust +pub fn from_slice(slice: [T]) -> Self { + Self { slice } +} +``` + +Example: + +```rust +let arr: [Field] = [1, 2, 3]; +let vector_from_slice = Vec::from_slice(arr); +assert(vector_from_slice.len() == 3); +``` + +### get + +Retrieves an element from the vector at a given index. Panics if the index points beyond the vector's end. + +```rust +pub fn get(self, index: Field) -> T { + self.slice[index] +} +``` + +Example: + +```rust +let vector: Vec = Vec::from_slice([10, 20, 30]); +assert(vector.get(1) == 20); +``` + +### push + +Adds a new element to the vector's end, returning a new vector with a length one greater than the original unmodified vector. + +```rust +pub fn push(&mut self, elem: T) { + self.slice = self.slice.push_back(elem); +} +``` + +Example: + +```rust +let mut vector: Vec = Vec::new(); +vector.push(10); +assert(vector.len() == 1); +``` + +### pop + +Removes an element from the vector's end, returning a new vector with a length one less than the original vector, along with the removed element. Panics if the vector's length is zero. + +```rust +pub fn pop(&mut self) -> T { + let (popped_slice, last_elem) = self.slice.pop_back(); + self.slice = popped_slice; + last_elem +} +``` + +Example: + +```rust +let mut vector = Vec::from_slice([10, 20]); +let popped_elem = vector.pop(); +assert(popped_elem == 20); +assert(vector.len() == 1); +``` + +### insert + +Inserts an element at a specified index, shifting subsequent elements to the right. + +```rust +pub fn insert(&mut self, index: Field, elem: T) { + self.slice = self.slice.insert(index, elem); +} +``` + +Example: + +```rust +let mut vector = Vec::from_slice([10, 30]); +vector.insert(1, 20); +assert(vector.get(1) == 20); +``` + +### remove + +Removes an element at a specified index, shifting subsequent elements to the left, and returns the removed element. + +```rust +pub fn remove(&mut self, index: Field) -> T { + let (new_slice, elem) = self.slice.remove(index); + self.slice = new_slice; + elem +} +``` + +Example: + +```rust +let mut vector = Vec::from_slice([10, 20, 30]); +let removed_elem = vector.remove(1); +assert(removed_elem == 20); +assert(vector.len() == 2); +``` + +### len + +Returns the number of elements in the vector. + +```rust +pub fn len(self) -> Field { + self.slice.len() +} +``` + +Example: + +```rust +let empty_vector: Vec = Vec::new(); +assert(empty_vector.len() == 0); +``` diff --git a/docs/versioned_docs/version-v0.23.0/noir/concepts/distinct.md b/docs/versioned_docs/version-v0.23.0/noir/concepts/distinct.md new file mode 100644 index 00000000000..6c993b8b5e0 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir/concepts/distinct.md @@ -0,0 +1,64 @@ +--- +title: Distinct Witnesses +sidebar_position: 11 +--- + +The `distinct` keyword prevents repetitions of witness indices in the program's ABI. This ensures +that the witnesses being returned as public inputs are all unique. + +The `distinct` keyword is only used for return values on program entry points (usually the `main()` +function). + +When using `distinct` and `pub` simultaneously, `distinct` comes first. See the example below. + +You can read more about the problem this solves +[here](https://github.com/noir-lang/noir/issues/1183). + +## Example + +Without the `distinct` keyword, the following program + +```rust +fn main(x : pub Field, y : pub Field) -> pub [Field; 4] { + let a = 1; + let b = 1; + [x + 1, y, a, b] +} +``` + +compiles to + +```json +{ + //... + "abi": { + //... + "param_witnesses": { "x": [1], "y": [2] }, + "return_witnesses": [3, 2, 4, 4] + } +} +``` + +Whereas (with the `distinct` keyword) + +```rust +fn main(x : pub Field, y : pub Field) -> distinct pub [Field; 4] { + let a = 1; + let b = 1; + [x + 1, y, a, b] +} +``` + +compiles to + +```json +{ + //... + "abi": { + //... + "param_witnesses": { "x": [1], "y": [2] }, + //... + "return_witnesses": [3, 4, 5, 6] + } +} +``` diff --git a/docs/versioned_docs/version-v0.23.0/noir/concepts/functions.md b/docs/versioned_docs/version-v0.23.0/noir/concepts/functions.md new file mode 100644 index 00000000000..48aba9cd058 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir/concepts/functions.md @@ -0,0 +1,226 @@ +--- +title: Functions +description: + Learn how to declare functions and methods in Noir, a programming language with Rust semantics. + This guide covers parameter declaration, return types, call expressions, and more. +keywords: [Noir, Rust, functions, methods, parameter declaration, return types, call expressions] +sidebar_position: 1 +--- + +Functions in Noir follow the same semantics of Rust, though Noir does not support early returns. + +To declare a function the `fn` keyword is used. + +```rust +fn foo() {} +``` + +By default, functions are visible only within the package they are defined. To make them visible outside of that package (for example, as part of a [library](../modules_packages_crates/crates_and_packages.md#libraries)), you should mark them as `pub`: + +```rust +pub fn foo() {} +``` + +You can also restrict the visibility of the function to only the crate it was defined in, by specifying `pub(crate)`: + +```rust +pub(crate) fn foo() {} //foo can only be called within its crate +``` + +All parameters in a function must have a type and all types are known at compile time. The parameter +is pre-pended with a colon and the parameter type. Multiple parameters are separated using a comma. + +```rust +fn foo(x : Field, y : Field){} +``` + +The return type of a function can be stated by using the `->` arrow notation. The function below +states that the foo function must return a `Field`. If the function returns no value, then the arrow +is omitted. + +```rust +fn foo(x : Field, y : Field) -> Field { + x + y +} +``` + +Note that a `return` keyword is unneeded in this case - the last expression in a function's body is +returned. + +## Main function + +If you're writing a binary, the `main` function is the starting point of your program. You can pass all types of expressions to it, as long as they have a fixed size at compile time: + +```rust +fn main(x : Field) // this is fine: passing a Field +fn main(x : [Field; 2]) // this is also fine: passing a Field with known size at compile-time +fn main(x : (Field, bool)) // 👌: passing a (Field, bool) tuple means size 2 +fn main(x : str<5>) // this is fine, as long as you pass a string of size 5 + +fn main(x : Vec) // can't compile, has variable size +fn main(x : [Field]) // can't compile, has variable size +fn main(....// i think you got it by now +``` + +Keep in mind [tests](../../getting_started/tooling/testing.md) don't differentiate between `main` and any other function. The following snippet passes tests, but won't compile or prove: + +```rust +fn main(x : [Field]) { + assert(x[0] == 1); +} + +#[test] +fn test_one() { + main([1, 2]); +} +``` + +```bash +$ nargo test +[testing] Running 1 test functions +[testing] Testing test_one... ok +[testing] All tests passed + +$ nargo check +The application panicked (crashed). +Message: Cannot have variable sized arrays as a parameter to main +``` + +## Call Expressions + +Calling a function in Noir is executed by using the function name and passing in the necessary +arguments. + +Below we show how to call the `foo` function from the `main` function using a call expression: + +```rust +fn main(x : Field, y : Field) { + let z = foo(x); +} + +fn foo(x : Field) -> Field { + x + x +} +``` + +## Methods + +You can define methods in Noir on any struct type in scope. + +```rust +struct MyStruct { + foo: Field, + bar: Field, +} + +impl MyStruct { + fn new(foo: Field) -> MyStruct { + MyStruct { + foo, + bar: 2, + } + } + + fn sum(self) -> Field { + self.foo + self.bar + } +} + +fn main() { + let s = MyStruct::new(40); + assert(s.sum() == 42); +} +``` + +Methods are just syntactic sugar for functions, so if we wanted to we could also call `sum` as +follows: + +```rust +assert(MyStruct::sum(s) == 42); +``` + +It is also possible to specialize which method is chosen depending on the [generic](./generics.md) type that is used. In this example, the `foo` function returns different values depending on its type: + +```rust +struct Foo {} + +impl Foo { + fn foo(self) -> Field { 1 } +} + +impl Foo { + fn foo(self) -> Field { 2 } +} + +fn main() { + let f1: Foo = Foo{}; + let f2: Foo = Foo{}; + assert(f1.foo() + f2.foo() == 3); +} +``` + +Also note that impls with the same method name defined in them cannot overlap. For example, if we already have `foo` defined for `Foo` and `Foo` like we do above, we cannot also define `foo` in an `impl Foo` since it would be ambiguous which version of `foo` to choose. + +```rust +// Including this impl in the same project as the above snippet would +// cause an overlapping impls error +impl Foo { + fn foo(self) -> Field { 3 } +} +``` + +## Lambdas + +Lambdas are anonymous functions. They follow the syntax of Rust - `|arg1, arg2, ..., argN| return_expression`. + +```rust +let add_50 = |val| val + 50; +assert(add_50(100) == 150); +``` + +See [Lambdas](./lambdas.md) for more details. + +## Attributes + +Attributes are metadata that can be applied to a function, using the following syntax: `#[attribute(value)]`. + +Supported attributes include: + +- **builtin**: the function is implemented by the compiler, for efficiency purposes. +- **deprecated**: mark the function as _deprecated_. Calling the function will generate a warning: `warning: use of deprecated function` +- **field**: Used to enable conditional compilation of code depending on the field size. See below for more details +- **oracle**: mark the function as _oracle_; meaning it is an external unconstrained function, implemented in noir_js. See [Unconstrained](./unconstrained.md) and [NoirJS](../../reference/NoirJS/noir_js/index.md) for more details. +- **test**: mark the function as unit tests. See [Tests](../../getting_started/tooling/testing.md) for more details + +### Field Attribute + +The field attribute defines which field the function is compatible for. The function is conditionally compiled, under the condition that the field attribute matches the Noir native field. +The field can be defined implicitly, by using the name of the elliptic curve usually associated to it - for instance bn254, bls12_381 - or explicitly by using the field (prime) order, in decimal or hexadecimal form. +As a result, it is possible to define multiple versions of a function with each version specialized for a different field attribute. This can be useful when a function requires different parameters depending on the underlying elliptic curve. + +Example: we define the function `foo()` three times below. Once for the default Noir bn254 curve, once for the field $\mathbb F_{23}$, which will normally never be used by Noir, and once again for the bls12_381 curve. + +```rust +#[field(bn254)] +fn foo() -> u32 { + 1 +} + +#[field(23)] +fn foo() -> u32 { + 2 +} + +// This commented code would not compile as foo would be defined twice because it is the same field as bn254 +// #[field(21888242871839275222246405745257275088548364400416034343698204186575808495617)] +// fn foo() -> u32 { +// 2 +// } + +#[field(bls12_381)] +fn foo() -> u32 { + 3 +} +``` + +If the field name is not known to Noir, it will discard the function. Field names are case insensitive. diff --git a/docs/versioned_docs/version-v0.23.0/noir/concepts/generics.md b/docs/versioned_docs/version-v0.23.0/noir/concepts/generics.md new file mode 100644 index 00000000000..ddd42bf1f9b --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir/concepts/generics.md @@ -0,0 +1,106 @@ +--- +title: Generics +description: Learn how to use Generics in Noir +keywords: [Noir, Rust, generics, functions, structs] +sidebar_position: 7 +--- + +Generics allow you to use the same functions with multiple different concrete data types. You can +read more about the concept of generics in the Rust documentation +[here](https://doc.rust-lang.org/book/ch10-01-syntax.html). + +Here is a trivial example showing the identity function that supports any type. In Rust, it is +common to refer to the most general type as `T`. We follow the same convention in Noir. + +```rust +fn id(x: T) -> T { + x +} +``` + +## In Structs + +Generics are useful for specifying types in structs. For example, we can specify that a field in a +struct will be of a certain generic type. In this case `value` is of type `T`. + +```rust +struct RepeatedValue { + value: T, + count: Field, +} + +impl RepeatedValue { + fn print(self) { + for _i in 0 .. self.count { + println(self.value); + } + } +} + +fn main() { + let repeated = RepeatedValue { value: "Hello!", count: 2 }; + repeated.print(); +} +``` + +The `print` function will print `Hello!` an arbitrary number of times, twice in this case. + +If we want to be generic over array lengths (which are type-level integers), we can use numeric +generics. Using these looks just like using regular generics, but these generics can resolve to +integers at compile-time, rather than resolving to types. Here's an example of a struct that is +generic over the size of the array it contains internally: + +```rust +struct BigInt { + limbs: [u32; N], +} + +impl BigInt { + // `N` is in scope of all methods in the impl + fn first(first: BigInt, second: BigInt) -> Self { + assert(first.limbs != second.limbs); + first + + fn second(first: BigInt, second: Self) -> Self { + assert(first.limbs != second.limbs); + second + } +} +``` + +## Calling functions on generic parameters + +Since a generic type `T` can represent any type, how can we call functions on the underlying type? +In other words, how can we go from "any type `T`" to "any type `T` that has certain methods available?" + +This is what [traits](../concepts/traits) are for in Noir. Here's an example of a function generic over +any type `T` that implements the `Eq` trait for equality: + +```rust +fn first_element_is_equal(array1: [T; N], array2: [T; N]) -> bool + where T: Eq +{ + if (array1.len() == 0) | (array2.len() == 0) { + true + } else { + array1[0] == array2[0] + } +} + +fn main() { + assert(first_element_is_equal([1, 2, 3], [1, 5, 6])); + + // We can use first_element_is_equal for arrays of any type + // as long as we have an Eq impl for the types we pass in + let array = [MyStruct::new(), MyStruct::new()]; + assert(array_eq(array, array, MyStruct::eq)); +} + +impl Eq for MyStruct { + fn eq(self, other: MyStruct) -> bool { + self.foo == other.foo + } +} +``` + +You can find more details on traits and trait implementations on the [traits page](../concepts/traits). diff --git a/docs/versioned_docs/version-v0.23.0/noir/concepts/lambdas.md b/docs/versioned_docs/version-v0.23.0/noir/concepts/lambdas.md new file mode 100644 index 00000000000..be3c7e0b5ca --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir/concepts/lambdas.md @@ -0,0 +1,81 @@ +--- +title: Lambdas +description: Learn how to use anonymous functions in Noir programming language. +keywords: [Noir programming language, lambda, closure, function, anonymous function] +sidebar_position: 9 +--- + +## Introduction + +Lambdas are anonymous functions. The syntax is `|arg1, arg2, ..., argN| return_expression`. + +```rust +let add_50 = |val| val + 50; +assert(add_50(100) == 150); +``` + +A block can be used as the body of a lambda, allowing you to declare local variables inside it: + +```rust +let cool = || { + let x = 100; + let y = 100; + x + y +} + +assert(cool() == 200); +``` + +## Closures + +Inside the body of a lambda, you can use variables defined in the enclosing function. Such lambdas are called **closures**. In this example `x` is defined inside `main` and is accessed from within the lambda: + +```rust +fn main() { + let x = 100; + let closure = || x + 150; + assert(closure() == 250); +} +``` + +## Passing closures to higher-order functions + +It may catch you by surprise that the following code fails to compile: + +```rust +fn foo(f: fn () -> Field) -> Field { + f() +} + +fn main() { + let (x, y) = (50, 50); + assert(foo(|| x + y) == 100); // error :( +} +``` + +The reason is that the closure's capture environment affects its type - we have a closure that captures two Fields and `foo` +expects a regular function as an argument - those are incompatible. +:::note + +Variables contained within the `||` are the closure's parameters, and the expression that follows it is the closure's body. The capture environment is comprised of any variables used in the closure's body that are not parameters. + +E.g. in |x| x + y, y would be a captured variable, but x would not be, since it is a parameter of the closure. + +::: +The syntax for the type of a closure is `fn[env](args) -> ret_type`, where `env` is the capture environment of the closure - +in this example that's `(Field, Field)`. + +The best solution in our case is to make `foo` generic over the environment type of its parameter, so that it can be called +with closures with any environment, as well as with regular functions: + +```rust +fn foo(f: fn[Env]() -> Field) -> Field { + f() +} + +fn main() { + let (x, y) = (50, 50); + assert(foo(|| x + y) == 100); // compiles fine + assert(foo(|| 60) == 60); // compiles fine +} +``` diff --git a/docs/versioned_docs/version-v0.23.0/noir/concepts/mutability.md b/docs/versioned_docs/version-v0.23.0/noir/concepts/mutability.md new file mode 100644 index 00000000000..9cc10429cb4 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir/concepts/mutability.md @@ -0,0 +1,93 @@ +--- +title: Mutability +description: + Learn about mutable variables, constants, and globals in Noir programming language. Discover how + to declare, modify, and use them in your programs. +keywords: [noir programming language, mutability in noir, mutable variables, constants, globals] +sidebar_position: 8 +--- + +Variables in noir can be declared mutable via the `mut` keyword. Mutable variables can be reassigned +to via an assignment expression. + +```rust +let x = 2; +x = 3; // error: x must be mutable to be assigned to + +let mut y = 3; +let y = 4; // OK +``` + +The `mut` modifier can also apply to patterns: + +```rust +let (a, mut b) = (1, 2); +a = 11; // error: a must be mutable to be assigned to +b = 12; // OK + +let mut (c, d) = (3, 4); +c = 13; // OK +d = 14; // OK + +// etc. +let MyStruct { x: mut y } = MyStruct { x: a }; +// y is now in scope +``` + +Note that mutability in noir is local and everything is passed by value, so if a called function +mutates its parameters then the parent function will keep the old value of the parameters. + +```rust +fn main() -> pub Field { + let x = 3; + helper(x); + x // x is still 3 +} + +fn helper(mut x: i32) { + x = 4; +} +``` + +## Comptime Values + +:::warning + +The 'comptime' keyword was removed in version 0.10. The comptime keyword and syntax are currently still kept and parsed for backwards compatibility, but are now deprecated and will issue a warning when used. `comptime` has been removed because it is no longer needed for accessing arrays. + +::: + +## Globals + +Noir also supports global variables. However, they must be known at compile-time. The global type can also be inferred by the compiler entirely. Globals can also be used to specify array +annotations for function parameters and can be imported from submodules. + +```rust +global N: Field = 5; // Same as `global N: Field = 5` + +fn main(x : Field, y : [Field; N]) { + let res = x * N; + + assert(res == y[0]); + + let res2 = x * my_submodule::N; + assert(res != res2); +} + +mod my_submodule { + use dep::std; + + global N: Field = 10; + + fn my_helper() -> Field { + let x = N; + x + } +} +``` + +## Why only local mutability? + +Witnesses in a proving system are immutable in nature. Noir aims to _closely_ mirror this setting +without applying additional overhead to the user. Modeling a mutable reference is not as +straightforward as on conventional architectures and would incur some possibly unexpected overhead. diff --git a/docs/versioned_docs/version-v0.23.0/noir/concepts/ops.md b/docs/versioned_docs/version-v0.23.0/noir/concepts/ops.md new file mode 100644 index 00000000000..60425cb8994 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir/concepts/ops.md @@ -0,0 +1,98 @@ +--- +title: Logical Operations +description: + Learn about the supported arithmetic and logical operations in the Noir programming language. + Discover how to perform operations on private input types, integers, and booleans. +keywords: + [ + Noir programming language, + supported operations, + arithmetic operations, + logical operations, + predicate operators, + bitwise operations, + short-circuiting, + backend, + ] +sidebar_position: 3 +--- + +# Operations + +## Table of Supported Operations + +| Operation | Description | Requirements | +| :-------- | :------------------------------------------------------------: | -------------------------------------: | +| + | Adds two private input types together | Types must be private input | +| - | Subtracts two private input types together | Types must be private input | +| \* | Multiplies two private input types together | Types must be private input | +| / | Divides two private input types together | Types must be private input | +| ^ | XOR two private input types together | Types must be integer | +| & | AND two private input types together | Types must be integer | +| \| | OR two private input types together | Types must be integer | +| \<\< | Left shift an integer by another integer amount | Types must be integer | +| >> | Right shift an integer by another integer amount | Types must be integer | +| ! | Bitwise not of a value | Type must be integer or boolean | +| \< | returns a bool if one value is less than the other | Upper bound must have a known bit size | +| \<= | returns a bool if one value is less than or equal to the other | Upper bound must have a known bit size | +| > | returns a bool if one value is more than the other | Upper bound must have a known bit size | +| >= | returns a bool if one value is more than or equal to the other | Upper bound must have a known bit size | +| == | returns a bool if one value is equal to the other | Both types must not be constants | +| != | returns a bool if one value is not equal to the other | Both types must not be constants | + +### Predicate Operators + +`<,<=, !=, == , >, >=` are known as predicate/comparison operations because they compare two values. +This differs from the operations such as `+` where the operands are used in _computation_. + +### Bitwise Operations Example + +```rust +fn main(x : Field) { + let y = x as u32; + let z = y & y; +} +``` + +`z` is implicitly constrained to be the result of `y & y`. The `&` operand is used to denote bitwise +`&`. + +> `x & x` would not compile as `x` is a `Field` and not an integer type. + +### Logical Operators + +Noir has no support for the logical operators `||` and `&&`. This is because encoding the +short-circuiting that these operators require can be inefficient for Noir's backend. Instead you can +use the bitwise operators `|` and `&` which operate identically for booleans, just without the +short-circuiting. + +```rust +let my_val = 5; + +let mut flag = 1; +if (my_val > 6) | (my_val == 0) { + flag = 0; +} +assert(flag == 1); + +if (my_val != 10) & (my_val < 50) { + flag = 0; +} +assert(flag == 0); +``` + +### Shorthand operators + +Noir shorthand operators for most of the above operators, namely `+=, -=, *=, /=, %=, &=, |=, ^=, <<=`, and `>>=`. These allow for more concise syntax. For example: + +```rust +let mut i = 0; +i = i + 1; +``` + +could be written as: + +```rust +let mut i = 0; +i += 1; +``` diff --git a/docs/versioned_docs/version-v0.23.0/noir/concepts/oracles.md b/docs/versioned_docs/version-v0.23.0/noir/concepts/oracles.md new file mode 100644 index 00000000000..2e6a6818d48 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir/concepts/oracles.md @@ -0,0 +1,23 @@ +--- +title: Oracles +description: Dive into how Noir supports Oracles via RPC calls, and learn how to declare an Oracle in Noir with our comprehensive guide. +keywords: + - Noir + - Oracles + - RPC Calls + - Unconstrained Functions + - Programming + - Blockchain +sidebar_position: 6 +--- + +Noir has support for Oracles via RPC calls. This means Noir will make an RPC call and use the return value for proof generation. + +Since Oracles are not resolved by Noir, they are [`unconstrained` functions](./unconstrained.md) + +You can declare an Oracle through the `#[oracle()]` flag. Example: + +```rust +#[oracle(get_number_sequence)] +unconstrained fn get_number_sequence(_size: Field) -> [Field] {} +``` diff --git a/docs/versioned_docs/version-v0.23.0/noir/concepts/shadowing.md b/docs/versioned_docs/version-v0.23.0/noir/concepts/shadowing.md new file mode 100644 index 00000000000..5ce6130d201 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir/concepts/shadowing.md @@ -0,0 +1,44 @@ +--- +title: Shadowing +sidebar_position: 12 +--- + +Noir allows for inheriting variables' values and re-declaring them with the same name similar to Rust, known as shadowing. + +For example, the following function is valid in Noir: + +```rust +fn main() { + let x = 5; + + { + let x = x * 2; + assert (x == 10); + } + + assert (x == 5); +} +``` + +In this example, a variable x is first defined with the value 5. + +The local scope that follows shadows the original x, i.e. creates a local mutable x based on the value of the original x. It is given a value of 2 times the original x. + +When we return to the main scope, x once again refers to just the original x, which stays at the value of 5. + +## Temporal mutability + +One way that shadowing is useful, in addition to ergonomics across scopes, is for temporarily mutating variables. + +```rust +fn main() { + let age = 30; + // age = age + 5; // Would error as `age` is immutable by default. + + let mut age = age + 5; // Temporarily mutates `age` with a new value. + + let age = age; // Locks `age`'s mutability again. + + assert (age == 35); +} +``` diff --git a/docs/versioned_docs/version-v0.23.0/noir/concepts/traits.md b/docs/versioned_docs/version-v0.23.0/noir/concepts/traits.md new file mode 100644 index 00000000000..ef1445a5907 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir/concepts/traits.md @@ -0,0 +1,389 @@ +--- +title: Traits +description: + Traits in Noir can be used to abstract out a common interface for functions across + several data types. +keywords: [noir programming language, traits, interfaces, generic, protocol] +sidebar_position: 14 +--- + +## Overview + +Traits in Noir are a useful abstraction similar to interfaces or protocols in other languages. Each trait defines +the interface of several methods contained within the trait. Types can then implement this trait by providing +implementations for these methods. For example in the program: + +```rust +struct Rectangle { + width: Field, + height: Field, +} + +impl Rectangle { + fn area(self) -> Field { + self.width * self.height + } +} + +fn log_area(r: Rectangle) { + println(r.area()); +} +``` + +We have a function `log_area` to log the area of a `Rectangle`. Now how should we change the program if we want this +function to work on `Triangle`s as well?: + +```rust +struct Triangle { + width: Field, + height: Field, +} + +impl Triangle { + fn area(self) -> Field { + self.width * self.height / 2 + } +} +``` + +Making `log_area` generic over all types `T` would be invalid since not all types have an `area` method. Instead, we can +introduce a new `Area` trait and make `log_area` generic over all types `T` that implement `Area`: + +```rust +trait Area { + fn area(self) -> Field; +} + +fn log_area(shape: T) where T: Area { + println(shape.area()); +} +``` + +We also need to explicitly implement `Area` for `Rectangle` and `Triangle`. We can do that by changing their existing +impls slightly. Note that the parameter types and return type of each of our `area` methods must match those defined +by the `Area` trait. + +```rust +impl Area for Rectangle { + fn area(self) -> Field { + self.width * self.height + } +} + +impl Area for Triangle { + fn area(self) -> Field { + self.width * self.height / 2 + } +} +``` + +Now we have a working program that is generic over any type of Shape that is used! Others can even use this program +as a library with their own types - such as `Circle` - as long as they also implement `Area` for these types. + +## Where Clauses + +As seen in `log_area` above, when we want to create a function or method that is generic over any type that implements +a trait, we can add a where clause to the generic function. + +```rust +fn log_area(shape: T) where T: Area { + println(shape.area()); +} +``` + +It is also possible to apply multiple trait constraints on the same variable at once by combining traits with the `+` +operator. Similarly, we can have multiple trait constraints by separating each with a comma: + +```rust +fn foo(elements: [T], thing: U) where + T: Default + Add + Eq, + U: Bar, +{ + let mut sum = T::default(); + + for element in elements { + sum += element; + } + + if sum == T::default() { + thing.bar(); + } +} +``` + +## Generic Implementations + +You can add generics to a trait implementation by adding the generic list after the `impl` keyword: + +```rust +trait Second { + fn second(self) -> Field; +} + +impl Second for (T, Field) { + fn second(self) -> Field { + self.1 + } +} +``` + +You can also implement a trait for every type this way: + +```rust +trait Debug { + fn debug(self); +} + +impl Debug for T { + fn debug(self) { + println(self); + } +} + +fn main() { + 1.debug(); +} +``` + +### Generic Trait Implementations With Where Clauses + +Where clauses can also be placed on trait implementations themselves to restrict generics in a similar way. +For example, while `impl Foo for T` implements the trait `Foo` for every type, `impl Foo for T where T: Bar` +will implement `Foo` only for types that also implement `Bar`. This is often used for implementing generic types. +For example, here is the implementation for array equality: + +```rust +impl Eq for [T; N] where T: Eq { + // Test if two arrays have the same elements. + // Because both arrays must have length N, we know their lengths already match. + fn eq(self, other: Self) -> bool { + let mut result = true; + + for i in 0 .. self.len() { + // The T: Eq constraint is needed to call == on the array elements here + result &= self[i] == other[i]; + } + + result + } +} +``` + +## Generic Traits + +Traits themselves can also be generic by placing the generic arguments after the trait name. These generics are in +scope of every item within the trait. + +```rust +trait Into { + // Convert `self` to type `T` + fn into(self) -> T; +} +``` + +When implementing generic traits the generic arguments of the trait must be specified. This is also true anytime +when referencing a generic trait (e.g. in a `where` clause). + +```rust +struct MyStruct { + array: [Field; 2], +} + +impl Into<[Field; 2]> for MyStruct { + fn into(self) -> [Field; 2] { + self.array + } +} + +fn as_array(x: T) -> [Field; 2] + where T: Into<[Field; 2]> +{ + x.into() +} + +fn main() { + let array = [1, 2]; + let my_struct = MyStruct { array }; + + assert_eq(as_array(my_struct), array); +} +``` + +## Trait Methods With No `self` + +A trait can contain any number of methods, each of which have access to the `Self` type which represents each type +that eventually implements the trait. Similarly, the `self` variable is available as well but is not required to be used. +For example, we can define a trait to create a default value for a type. This trait will need to return the `Self` type +but doesn't need to take any parameters: + +```rust +trait Default { + fn default() -> Self; +} +``` + +Implementing this trait can be done similarly to any other trait: + +```rust +impl Default for Field { + fn default() -> Field { + 0 + } +} + +struct MyType {} + +impl Default for MyType { + fn default() -> Field { + MyType {} + } +} +``` + +However, since there is no `self` parameter, we cannot call it via the method call syntax `object.method()`. +Instead, we'll need to refer to the function directly. This can be done either by referring to the +specific impl `MyType::default()` or referring to the trait itself `Default::default()`. In the later +case, type inference determines the impl that is selected. + +```rust +let my_struct = MyStruct::default(); + +let x: Field = Default::default(); +let result = x + Default::default(); +``` + +:::warning + +```rust +let _ = Default::default(); +``` + +If type inference cannot select which impl to use because of an ambiguous `Self` type, an impl will be +arbitrarily selected. This occurs most often when the result of a trait function call with no parameters +is unused. To avoid this, when calling a trait function with no `self` or `Self` parameters or return type, +always refer to it via the implementation type's namespace - e.g. `MyType::default()`. +This is set to change to an error in future Noir versions. + +::: + +## Default Method Implementations + +A trait can also have default implementations of its methods by giving a body to the desired functions. +Note that this body must be valid for all types that may implement the trait. As a result, the only +valid operations on `self` will be operations valid for any type or other operations on the trait itself. + +```rust +trait Numeric { + fn add(self, other: Self) -> Self; + + // Default implementation of double is (self + self) + fn double(self) -> Self { + self.add(self) + } +} +``` + +When implementing a trait with default functions, a type may choose to implement only the required functions: + +```rust +impl Numeric for Field { + fn add(self, other: Field) -> Field { + self + other + } +} +``` + +Or it may implement the optional methods as well: + +```rust +impl Numeric for u32 { + fn add(self, other: u32) -> u32 { + self + other + } + + fn double(self) -> u32 { + self * 2 + } +} +``` + +## Impl Specialization + +When implementing traits for a generic type it is possible to implement the trait for only a certain combination +of generics. This can be either as an optimization or because those specific generics are required to implement the trait. + +```rust +trait Sub { + fn sub(self, other: Self) -> Self; +} + +struct NonZero { + value: T, +} + +impl Sub for NonZero { + fn sub(self, other: Self) -> Self { + let value = self.value - other.value; + assert(value != 0); + NonZero { value } + } +} +``` + +## Overlapping Implementations + +Overlapping implementations are disallowed by Noir to ensure Noir's decision on which impl to select is never ambiguous. +This means if a trait `Foo` is already implemented +by a type `Bar` for all `T`, then we cannot also have a separate impl for `Bar` (or any other +type argument). Similarly, if there is an impl for all `T` such as `impl Debug for T`, we cannot create +any more impls to `Debug` for other types since it would be ambiguous which impl to choose for any given +method call. + +```rust +trait Trait {} + +// Previous impl defined here +impl Trait for (A, B) {} + +// error: Impl for type `(Field, Field)` overlaps with existing impl +impl Trait for (Field, Field) {} +``` + +## Trait Coherence + +Another restriction on trait implementations is coherence. This restriction ensures other crates cannot create +impls that may overlap with other impls, even if several unrelated crates are used as dependencies in the same +program. + +The coherence restriction is: to implement a trait, either the trait itself or the object type must be declared +in the crate the impl is in. + +In practice this often comes up when using types provided by libraries. If a library provides a type `Foo` that does +not implement a trait in the standard library such as `Default`, you may not `impl Default for Foo` in your own crate. +While restrictive, this prevents later issues or silent changes in the program if the `Foo` library later added its +own impl for `Default`. If you are a user of the `Foo` library in this scenario and need a trait not implemented by the +library your choices are to either submit a patch to the library or use the newtype pattern. + +### The Newtype Pattern + +The newtype pattern gets around the coherence restriction by creating a new wrapper type around the library type +that we cannot create `impl`s for. Since the new wrapper type is defined in our current crate, we can create +impls for any trait we need on it. + +```rust +struct Wrapper { + foo: dep::some_library::Foo, +} + +impl Default for Wrapper { + fn default() -> Wrapper { + Wrapper { + foo: dep::some_library::Foo::new(), + } + } +} +``` + +Since we have an impl for our own type, the behavior of this code will not change even if `some_library` is updated +to provide its own `impl Default for Foo`. The downside of this pattern is that it requires extra wrapping and +unwrapping of values when converting to and from the `Wrapper` and `Foo` types. diff --git a/docs/versioned_docs/version-v0.23.0/noir/concepts/unconstrained.md b/docs/versioned_docs/version-v0.23.0/noir/concepts/unconstrained.md new file mode 100644 index 00000000000..6b3424f7993 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir/concepts/unconstrained.md @@ -0,0 +1,95 @@ +--- +title: Unconstrained Functions +description: "Learn about what unconstrained functions in Noir are, how to use them and when you'd want to." + +keywords: [Noir programming language, unconstrained, open] +sidebar_position: 5 +--- + +Unconstrained functions are functions which do not constrain any of the included computation and allow for non-deterministic computation. + +## Why? + +Zero-knowledge (ZK) domain-specific languages (DSL) enable developers to generate ZK proofs from their programs by compiling code down to the constraints of an NP complete language (such as R1CS or PLONKish languages). However, the hard bounds of a constraint system can be very limiting to the functionality of a ZK DSL. + +Enabling a circuit language to perform unconstrained execution is a powerful tool. Said another way, unconstrained execution lets developers generate witnesses from code that does not generate any constraints. Being able to execute logic outside of a circuit is critical for both circuit performance and constructing proofs on information that is external to a circuit. + +Fetching information from somewhere external to a circuit can also be used to enable developers to improve circuit efficiency. + +A ZK DSL does not just prove computation, but proves that some computation was handled correctly. Thus, it is necessary that when we switch from performing some operation directly inside of a circuit to inside of an unconstrained environment that the appropriate constraints are still laid down elsewhere in the circuit. + +## Example + +An in depth example might help drive the point home. This example comes from the excellent [post](https://discord.com/channels/1113924620781883405/1124022445054111926/1128747641853972590) by Tom in the Noir Discord. + +Let's look at how we can optimize a function to turn a `u72` into an array of `u8`s. + +```rust +fn main(num: u72) -> pub [u8; 8] { + let mut out: [u8; 8] = [0; 8]; + for i in 0..8 { + out[i] = (num >> (56 - (i * 8)) as u72 & 0xff) as u8; + } + + out +} +``` + +``` +Total ACIR opcodes generated for language PLONKCSat { width: 3 }: 91 +Backend circuit size: 3619 +``` + +A lot of the operations in this function are optimized away by the compiler (all the bit-shifts turn into divisions by constants). However we can save a bunch of gates by casting to u8 a bit earlier. This automatically truncates the bit-shifted value to fit in a u8 which allows us to remove the XOR against 0xff. This saves us ~480 gates in total. + +```rust +fn main(num: u72) -> pub [u8; 8] { + let mut out: [u8; 8] = [0; 8]; + for i in 0..8 { + out[i] = (num >> (56 - (i * 8)) as u8; + } + + out +} +``` + +``` +Total ACIR opcodes generated for language PLONKCSat { width: 3 }: 75 +Backend circuit size: 3143 +``` + +Those are some nice savings already but we can do better. This code is all constrained so we're proving every step of calculating out using num, but we don't actually care about how we calculate this, just that it's correct. This is where brillig comes in. + +It turns out that truncating a u72 into a u8 is hard to do inside a snark, each time we do as u8 we lay down 4 ACIR opcodes which get converted into multiple gates. It's actually much easier to calculate num from out than the other way around. All we need to do is multiply each element of out by a constant and add them all together, both relatively easy operations inside a snark. + +We can then run u72_to_u8 as unconstrained brillig code in order to calculate out, then use that result in our constrained function and assert that if we were to do the reverse calculation we'd get back num. This looks a little like the below: + +```rust +fn main(num: u72) -> pub [u8; 8] { + let out = u72_to_u8(num); + + let mut reconstructed_num: u72 = 0; + for i in 0..8 { + reconstructed_num += (out[i] as u72 << (56 - (8 * i))); + } + assert(num == reconstructed_num); + out +} + +unconstrained fn u72_to_u8(num: u72) -> [u8; 8] { + let mut out: [u8; 8] = [0; 8]; + for i in 0..8 { + out[i] = (num >> (56 - (i * 8))) as u8; + } + out +} +``` + +``` +Total ACIR opcodes generated for language PLONKCSat { width: 3 }: 78 +Backend circuit size: 2902 +``` + +This ends up taking off another ~250 gates from our circuit! We've ended up with more ACIR opcodes than before but they're easier for the backend to prove (resulting in fewer gates). + +Generally we want to use brillig whenever there's something that's easy to verify but hard to compute within the circuit. For example, if you wanted to calculate a square root of a number it'll be a much better idea to calculate this in brillig and then assert that if you square the result you get back your number. diff --git a/docs/versioned_docs/version-v0.23.0/noir/modules_packages_crates/_category_.json b/docs/versioned_docs/version-v0.23.0/noir/modules_packages_crates/_category_.json new file mode 100644 index 00000000000..1debcfe7675 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir/modules_packages_crates/_category_.json @@ -0,0 +1,6 @@ +{ + "label": "Modules, Packages and Crates", + "position": 2, + "collapsible": true, + "collapsed": true +} diff --git a/docs/versioned_docs/version-v0.23.0/noir/modules_packages_crates/crates_and_packages.md b/docs/versioned_docs/version-v0.23.0/noir/modules_packages_crates/crates_and_packages.md new file mode 100644 index 00000000000..760a463094c --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir/modules_packages_crates/crates_and_packages.md @@ -0,0 +1,43 @@ +--- +title: Crates and Packages +description: Learn how to use Crates and Packages in your Noir project +keywords: [Nargo, dependencies, package management, crates, package] +sidebar_position: 0 +--- + +## Crates + +A crate is the smallest amount of code that the Noir compiler considers at a time. +Crates can contain modules, and the modules may be defined in other files that get compiled with the crate, as we’ll see in the coming sections. + +### Crate Types + +A Noir crate can come in several forms: binaries, libraries or contracts. + +#### Binaries + +_Binary crates_ are programs which you can compile to an ACIR circuit which you can then create proofs against. Each must have a function called `main` that defines the ACIR circuit which is to be proved. + +#### Libraries + +_Library crates_ don't have a `main` function and they don't compile down to ACIR. Instead they define functionality intended to be shared with multiple projects, and eventually included in a binary crate. + +#### Contracts + +Contract crates are similar to binary crates in that they compile to ACIR which you can create proofs against. They are different in that they do not have a single `main` function, but are a collection of functions to be deployed to the [Aztec network](https://aztec.network). You can learn more about the technical details of Aztec in the [monorepo](https://github.com/AztecProtocol/aztec-packages) or contract [examples](https://github.com/AztecProtocol/aztec-packages/tree/master/yarn-project/noir-contracts/contracts). + +### Crate Root + +Every crate has a root, which is the source file that the compiler starts, this is also known as the root module. The Noir compiler does not enforce any conditions on the name of the file which is the crate root, however if you are compiling via Nargo the crate root must be called `lib.nr` or `main.nr` for library or binary crates respectively. + +## Packages + +A Nargo _package_ is a collection of one of more crates that provides a set of functionality. A package must include a Nargo.toml file. + +A package _must_ contain either a library or a binary crate, but not both. + +### Differences from Cargo Packages + +One notable difference between Rust's Cargo and Noir's Nargo is that while Cargo allows a package to contain an unlimited number of binary crates and a single library crate, Nargo currently only allows a package to contain a single crate. + +In future this restriction may be lifted to allow a Nargo package to contain both a binary and library crate or multiple binary crates. diff --git a/docs/versioned_docs/version-v0.23.0/noir/modules_packages_crates/dependencies.md b/docs/versioned_docs/version-v0.23.0/noir/modules_packages_crates/dependencies.md new file mode 100644 index 00000000000..a37dc401b7d --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir/modules_packages_crates/dependencies.md @@ -0,0 +1,124 @@ +--- +title: Dependencies +description: + Learn how to specify and manage dependencies in Nargo, allowing you to upload packages to GitHub + and use them easily in your project. +keywords: [Nargo, dependencies, GitHub, package management, versioning] +sidebar_position: 1 +--- + +Nargo allows you to upload packages to GitHub and use them as dependencies. + +## Specifying a dependency + +Specifying a dependency requires a tag to a specific commit and the git url to the url containing +the package. + +Currently, there are no requirements on the tag contents. If requirements are added, it would follow +semver 2.0 guidelines. + +> Note: Without a `tag` , there would be no versioning and dependencies would change each time you +> compile your project. + +For example, to add the [ecrecover-noir library](https://github.com/colinnielsen/ecrecover-noir) to your project, add it to `Nargo.toml`: + +```toml +# Nargo.toml + +[dependencies] +ecrecover = {tag = "v0.8.0", git = "https://github.com/colinnielsen/ecrecover-noir"} +``` + +If the module is in a subdirectory, you can define a subdirectory in your git repository, for example: + +```toml +# Nargo.toml + +[dependencies] +easy_private_token_contract = {tag ="v0.1.0-alpha62", git = "https://github.com/AztecProtocol/aztec-packages", directory = "yarn-project/noir-contracts/contracts/easy_private_token_contract"} +``` + +## Specifying a local dependency + +You can also specify dependencies that are local to your machine. + +For example, this file structure has a library and binary crate + +```tree +├── binary_crate +│   ├── Nargo.toml +│   └── src +│   └── main.nr +└── lib_a + ├── Nargo.toml + └── src + └── lib.nr +``` + +Inside of the binary crate, you can specify: + +```toml +# Nargo.toml + +[dependencies] +lib_a = { path = "../lib_a" } +``` + +## Importing dependencies + +You can import a dependency to a Noir file using the following syntax. For example, to import the +ecrecover-noir library and local lib_a referenced above: + +```rust +use dep::ecrecover; +use dep::lib_a; +``` + +You can also import only the specific parts of dependency that you want to use, like so: + +```rust +use dep::std::hash::sha256; +use dep::std::scalar_mul::fixed_base_embedded_curve; +``` + +Lastly, as demonstrated in the +[elliptic curve example](../standard_library/cryptographic_primitives/ec_primitives#examples), you +can import multiple items in the same line by enclosing them in curly braces: + +```rust +use dep::std::ec::tecurve::affine::{Curve, Point}; +``` + +We don't have a way to consume libraries from inside a [workspace](./workspaces) as external dependencies right now. + +Inside a workspace, these are consumed as `{ path = "../to_lib" }` dependencies in Nargo.toml. + +## Dependencies of Dependencies + +Note that when you import a dependency, you also get access to all of the dependencies of that package. + +For example, the [phy_vector](https://github.com/resurgencelabs/phy_vector) library imports an [fraction](https://github.com/resurgencelabs/fraction) library. If you're importing the phy_vector library, then you can access the functions in fractions library like so: + +```rust +use dep::phy_vector; + +fn main(x : Field, y : pub Field) { + //... + let f = phy_vector::fraction::toFraction(true, 2, 1); + //... +} +``` + +## Available Libraries + +Noir does not currently have an official package manager. You can find a list of available Noir libraries in the [awesome-noir repo here](https://github.com/noir-lang/awesome-noir#libraries). + +Some libraries that are available today include: + +- [Standard Library](https://github.com/noir-lang/noir/tree/master/noir_stdlib) - the Noir Standard Library +- [Ethereum Storage Proof Verification](https://github.com/aragonzkresearch/noir-trie-proofs) - a library that contains the primitives necessary for RLP decoding (in the form of look-up table construction) and Ethereum state and storage proof verification (or verification of any trie proof involving 32-byte long keys) +- [BigInt](https://github.com/shuklaayush/noir-bigint) - a library that provides a custom BigUint56 data type, allowing for computations on large unsigned integers +- [ECrecover](https://github.com/colinnielsen/ecrecover-noir/tree/main) - a library to verify an ECDSA signature and return the source Ethereum address +- [Sparse Merkle Tree Verifier](https://github.com/vocdoni/smtverifier-noir/tree/main) - a library for verification of sparse Merkle trees +- [Signed Int](https://github.com/resurgencelabs/signed_int) - a library for accessing a custom Signed Integer data type, allowing access to negative numbers on Noir +- [Fraction](https://github.com/resurgencelabs/fraction) - a library for accessing fractional number data type in Noir, allowing results that aren't whole numbers diff --git a/docs/versioned_docs/version-v0.23.0/noir/modules_packages_crates/modules.md b/docs/versioned_docs/version-v0.23.0/noir/modules_packages_crates/modules.md new file mode 100644 index 00000000000..ae822a1cff4 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir/modules_packages_crates/modules.md @@ -0,0 +1,105 @@ +--- +title: Modules +description: + Learn how to organize your files using modules in Noir, following the same convention as Rust's + module system. Examples included. +keywords: [Noir, Rust, modules, organizing files, sub-modules] +sidebar_position: 2 +--- + +Noir's module system follows the same convention as the _newer_ version of Rust's module system. + +## Purpose of Modules + +Modules are used to organize files. Without modules all of your code would need to live in a single +file. In Noir, the compiler does not automatically scan all of your files to detect modules. This +must be done explicitly by the developer. + +## Examples + +### Importing a module in the crate root + +Filename : `src/main.nr` + +```rust +mod foo; + +fn main() { + foo::hello_world(); +} +``` + +Filename : `src/foo.nr` + +```rust +fn from_foo() {} +``` + +In the above snippet, the crate root is the `src/main.nr` file. The compiler sees the module +declaration `mod foo` which prompts it to look for a foo.nr file. + +Visually this module hierarchy looks like the following : + +``` +crate + ├── main + │ + └── foo + └── from_foo + +``` + +### Importing a module throughout the tree + +All modules are accessible from the `crate::` namespace. + +``` +crate + ├── bar + ├── foo + └── main + +``` + +In the above snippet, if `bar` would like to use functions in `foo`, it can do so by `use crate::foo::function_name`. + +### Sub-modules + +Filename : `src/main.nr` + +```rust +mod foo; + +fn main() { + foo::from_foo(); +} +``` + +Filename : `src/foo.nr` + +```rust +mod bar; +fn from_foo() {} +``` + +Filename : `src/foo/bar.nr` + +```rust +fn from_bar() {} +``` + +In the above snippet, we have added an extra module to the module tree; `bar`. `bar` is a submodule +of `foo` hence we declare bar in `foo.nr` with `mod bar`. Since `foo` is not the crate root, the +compiler looks for the file associated with the `bar` module in `src/foo/bar.nr` + +Visually the module hierarchy looks as follows: + +``` +crate + ├── main + │ + └── foo + ├── from_foo + └── bar + └── from_bar +``` diff --git a/docs/versioned_docs/version-v0.23.0/noir/modules_packages_crates/workspaces.md b/docs/versioned_docs/version-v0.23.0/noir/modules_packages_crates/workspaces.md new file mode 100644 index 00000000000..67a1dafa372 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir/modules_packages_crates/workspaces.md @@ -0,0 +1,40 @@ +--- +title: Workspaces +sidebar_position: 3 +--- + +Workspaces are a feature of nargo that allow you to manage multiple related Noir packages in a single repository. A workspace is essentially a group of related projects that share common build output directories and configurations. + +Each Noir project (with it's own Nargo.toml file) can be thought of as a package. Each package is expected to contain exactly one "named circuit", being the "name" defined in Nargo.toml with the program logic defined in `./src/main.nr`. + +For a project with the following structure: + +```tree +├── crates +│   ├── a +│   │   ├── Nargo.toml +│   │   └── src +│   │   └── main.nr +│   └── b +│   ├── Nargo.toml +│   └── src +│   └── main.nr +├── Nargo.toml +└── Prover.toml +``` + +You can define a workspace in Nargo.toml like so: + +```toml +[workspace] +members = ["crates/a", "crates/b"] +default-member = "crates/a" +``` + +`members` indicates which packages are included in the workspace. As such, all member packages of a workspace will be processed when the `--workspace` flag is used with various commands or if a `default-member` is not specified. + +`default-member` indicates which package various commands process by default. + +Libraries can be defined in a workspace. Inside a workspace, these are consumed as `{ path = "../to_lib" }` dependencies in Nargo.toml. + +Inside a workspace, these are consumed as `{ path = "../to_lib" }` dependencies in Nargo.toml. diff --git a/docs/versioned_docs/version-v0.23.0/noir/standard_library/_category_.json b/docs/versioned_docs/version-v0.23.0/noir/standard_library/_category_.json new file mode 100644 index 00000000000..af04c0933fd --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir/standard_library/_category_.json @@ -0,0 +1,6 @@ +{ + "label": "Standard Library", + "position": 1, + "collapsible": true, + "collapsed": true +} diff --git a/docs/versioned_docs/version-v0.23.0/noir/standard_library/black_box_fns.md b/docs/versioned_docs/version-v0.23.0/noir/standard_library/black_box_fns.md new file mode 100644 index 00000000000..4b1efbd17de --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir/standard_library/black_box_fns.md @@ -0,0 +1,45 @@ +--- +title: Black Box Functions +description: Black box functions are functions in Noir that rely on backends implementing support for specialized constraints. +keywords: [noir, black box functions] +--- + +Black box functions are functions in Noir that rely on backends implementing support for specialized constraints. This makes certain zk-snark unfriendly computations cheaper than if they were implemented in Noir. + +:::warning + +It is likely that not all backends will support a particular black box function. + +::: + +Because it is not guaranteed that all backends will support black box functions, it is possible that certain Noir programs won't compile against a particular backend if they use an unsupported black box function. It is possible to fallback to less efficient implementations written in Noir/ACIR in some cases. + +Black box functions are specified with the `#[foreign(black_box_fn)]` attribute. For example, the SHA256 function in the Noir [source code](https://github.com/noir-lang/noir/blob/v0.5.1/noir_stdlib/src/hash.nr) looks like: + +```rust +#[foreign(sha256)] +fn sha256(_input : [u8; N]) -> [u8; 32] {} +``` + +## Function list + +Here is a list of the current black box functions that are supported by UltraPlonk: + +- AES +- [SHA256](./cryptographic_primitives/hashes#sha256) +- [Schnorr signature verification](./cryptographic_primitives/schnorr) +- [Blake2s](./cryptographic_primitives/hashes#blake2s) +- [Pedersen Hash](./cryptographic_primitives/hashes#pedersen_hash) +- [Pedersen Commitment](./cryptographic_primitives/hashes#pedersen_commitment) +- [ECDSA signature verification](./cryptographic_primitives/ecdsa_sig_verification) +- [Fixed base scalar multiplication](./cryptographic_primitives/scalar) +- [Compute merkle root](./merkle_trees#compute_merkle_root) +- AND +- XOR +- RANGE +- [Keccak256](./cryptographic_primitives/hashes#keccak256) +- [Recursive proof verification](./recursion) + +Most black box functions are included as part of the Noir standard library, however `AND`, `XOR` and `RANGE` are used as part of the Noir language syntax. For instance, using the bitwise operator `&` will invoke the `AND` black box function. To ensure compatibility across backends, the ACVM has fallback implementations of `AND`, `XOR` and `RANGE` defined in its standard library which it can seamlessly fallback to if the backend doesn't support them. + +You can view the black box functions defined in the ACVM code [here](https://github.com/noir-lang/noir/blob/master/acvm-repo/acir/src/circuit/black_box_functions.rs). diff --git a/docs/versioned_docs/version-v0.23.0/noir/standard_library/cryptographic_primitives/_category_.json b/docs/versioned_docs/version-v0.23.0/noir/standard_library/cryptographic_primitives/_category_.json new file mode 100644 index 00000000000..5d694210bbf --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir/standard_library/cryptographic_primitives/_category_.json @@ -0,0 +1,5 @@ +{ + "position": 0, + "collapsible": true, + "collapsed": true +} diff --git a/docs/versioned_docs/version-v0.23.0/noir/standard_library/cryptographic_primitives/ec_primitives.md b/docs/versioned_docs/version-v0.23.0/noir/standard_library/cryptographic_primitives/ec_primitives.md new file mode 100644 index 00000000000..d2b42d67b7c --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir/standard_library/cryptographic_primitives/ec_primitives.md @@ -0,0 +1,102 @@ +--- +title: Elliptic Curve Primitives +keywords: [cryptographic primitives, Noir project] +sidebar_position: 4 +--- + +Data structures and methods on them that allow you to carry out computations involving elliptic +curves over the (mathematical) field corresponding to `Field`. For the field currently at our +disposal, applications would involve a curve embedded in BN254, e.g. the +[Baby Jubjub curve](https://eips.ethereum.org/EIPS/eip-2494). + +## Data structures + +### Elliptic curve configurations + +(`std::ec::{tecurve,montcurve,swcurve}::{affine,curvegroup}::Curve`), i.e. the specific elliptic +curve you want to use, which would be specified using any one of the methods +`std::ec::{tecurve,montcurve,swcurve}::{affine,curvegroup}::new` which take the coefficients in the +defining equation together with a generator point as parameters. You can find more detail in the +comments in +[`noir_stdlib/src/ec.nr`](https://github.com/noir-lang/noir/blob/master/noir_stdlib/src/ec.nr), but +the gist of it is that the elliptic curves of interest are usually expressed in one of the standard +forms implemented here (Twisted Edwards, Montgomery and Short Weierstraß), and in addition to that, +you could choose to use `affine` coordinates (Cartesian coordinates - the usual (x,y) - possibly +together with a point at infinity) or `curvegroup` coordinates (some form of projective coordinates +requiring more coordinates but allowing for more efficient implementations of elliptic curve +operations). Conversions between all of these forms are provided, and under the hood these +conversions are done whenever an operation is more efficient in a different representation (or a +mixed coordinate representation is employed). + +### Points + +(`std::ec::{tecurve,montcurve,swcurve}::{affine,curvegroup}::Point`), i.e. points lying on the +elliptic curve. For a curve configuration `c` and a point `p`, it may be checked that `p` +does indeed lie on `c` by calling `c.contains(p1)`. + +## Methods + +(given a choice of curve representation, e.g. use `std::ec::tecurve::affine::Curve` and use +`std::ec::tecurve::affine::Point`) + +- The **zero element** is given by `Point::zero()`, and we can verify whether a point `p: Point` is + zero by calling `p.is_zero()`. +- **Equality**: Points `p1: Point` and `p2: Point` may be checked for equality by calling + `p1.eq(p2)`. +- **Addition**: For `c: Curve` and points `p1: Point` and `p2: Point` on the curve, adding these two + points is accomplished by calling `c.add(p1,p2)`. +- **Negation**: For a point `p: Point`, `p.negate()` is its negation. +- **Subtraction**: For `c` and `p1`, `p2` as above, subtracting `p2` from `p1` is accomplished by + calling `c.subtract(p1,p2)`. +- **Scalar multiplication**: For `c` as above, `p: Point` a point on the curve and `n: Field`, + scalar multiplication is given by `c.mul(n,p)`. If instead `n :: [u1; N]`, i.e. `n` is a bit + array, the `bit_mul` method may be used instead: `c.bit_mul(n,p)` +- **Multi-scalar multiplication**: For `c` as above and arrays `n: [Field; N]` and `p: [Point; N]`, + multi-scalar multiplication is given by `c.msm(n,p)`. +- **Coordinate representation conversions**: The `into_group` method converts a point or curve + configuration in the affine representation to one in the CurveGroup representation, and + `into_affine` goes in the other direction. +- **Curve representation conversions**: `tecurve` and `montcurve` curves and points are equivalent + and may be converted between one another by calling `into_montcurve` or `into_tecurve` on their + configurations or points. `swcurve` is more general and a curve c of one of the other two types + may be converted to this representation by calling `c.into_swcurve()`, whereas a point `p` lying + on the curve given by `c` may be mapped to its corresponding `swcurve` point by calling + `c.map_into_swcurve(p)`. +- **Map-to-curve methods**: The Elligator 2 method of mapping a field element `n: Field` into a + `tecurve` or `montcurve` with configuration `c` may be called as `c.elligator2_map(n)`. For all of + the curve configurations, the SWU map-to-curve method may be called as `c.swu_map(z,n)`, where + `z: Field` depends on `Field` and `c` and must be chosen by the user (the conditions it needs to + satisfy are specified in the comments + [here](https://github.com/noir-lang/noir/blob/master/noir_stdlib/src/ec.nr)). + +## Examples + +The +[ec_baby_jubjub test](https://github.com/noir-lang/noir/blob/master/test_programs/compile_success_empty/ec_baby_jubjub/src/main.nr) +illustrates all of the above primitives on various forms of the Baby Jubjub curve. A couple of more +interesting examples in Noir would be: + +Public-key cryptography: Given an elliptic curve and a 'base point' on it, determine the public key +from the private key. This is a matter of using scalar multiplication. In the case of Baby Jubjub, +for example, this code would do: + +```rust +use dep::std::ec::tecurve::affine::{Curve, Point}; + +fn bjj_pub_key(priv_key: Field) -> Point +{ + + let bjj = Curve::new(168700, 168696, G::new(995203441582195749578291179787384436505546430278305826713579947235728471134,5472060717959818805561601436314318772137091100104008585924551046643952123905)); + + let base_pt = Point::new(5299619240641551281634865583518297030282874472190772894086521144482721001553, 16950150798460657717958625567821834550301663161624707787222815936182638968203); + + bjj.mul(priv_key,base_pt) +} +``` + +This would come in handy in a Merkle proof. + +- EdDSA signature verification: This is a matter of combining these primitives with a suitable hash + function. See + [feat(stdlib): EdDSA sig verification noir#1136](https://github.com/noir-lang/noir/pull/1136) for + the case of Baby Jubjub and the Poseidon hash function. diff --git a/docs/versioned_docs/version-v0.23.0/noir/standard_library/cryptographic_primitives/ecdsa_sig_verification.mdx b/docs/versioned_docs/version-v0.23.0/noir/standard_library/cryptographic_primitives/ecdsa_sig_verification.mdx new file mode 100644 index 00000000000..1376c51dfde --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir/standard_library/cryptographic_primitives/ecdsa_sig_verification.mdx @@ -0,0 +1,46 @@ +--- +title: ECDSA Signature Verification +description: Learn about the cryptographic primitives regarding ECDSA over the secp256k1 and secp256r1 curves +keywords: [cryptographic primitives, Noir project, ecdsa, secp256k1, secp256r1, signatures] +sidebar_position: 3 +--- + +import BlackBoxInfo from '@site/src/components/Notes/_blackbox.mdx'; + +Noir supports ECDSA signatures verification over the secp256k1 and secp256r1 curves. + +## ecdsa_secp256k1::verify_signature + +Verifier for ECDSA Secp256k1 signatures + +```rust +fn verify_signature(_public_key_x : [u8; 32], _public_key_y : [u8; 32], _signature: [u8; 64], _message: [u8]) -> bool +``` + +example: + +```rust +fn main(hashed_message : [u8;32], pub_key_x : [u8;32], pub_key_y : [u8;32], signature : [u8;64]) { + let valid_signature = std::ecdsa_secp256k1::verify_signature(pub_key_x, pub_key_y, signature, hashed_message); + assert(valid_signature); +} +``` + +## ecdsa_secp256r1::verify_signature + +Verifier for ECDSA Secp256r1 signatures + +```rust +fn verify_signature(_public_key_x : [u8; 32], _public_key_y : [u8; 32], _signature: [u8; 64], _message: [u8]) -> bool +``` + +example: + +```rust +fn main(hashed_message : [u8;32], pub_key_x : [u8;32], pub_key_y : [u8;32], signature : [u8;64]) { + let valid_signature = std::ecdsa_secp256r1::verify_signature(pub_key_x, pub_key_y, signature, hashed_message); + assert(valid_signature); +} +``` + + diff --git a/docs/versioned_docs/version-v0.23.0/noir/standard_library/cryptographic_primitives/eddsa.mdx b/docs/versioned_docs/version-v0.23.0/noir/standard_library/cryptographic_primitives/eddsa.mdx new file mode 100644 index 00000000000..a9c10da6c06 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir/standard_library/cryptographic_primitives/eddsa.mdx @@ -0,0 +1,18 @@ +--- +title: EdDSA Verification +description: Learn about the cryptographic primitives regarding EdDSA +keywords: [cryptographic primitives, Noir project, eddsa, signatures] +sidebar_position: 5 +--- + +import BlackBoxInfo from '@site/src/components/Notes/_blackbox.mdx'; + +## eddsa::eddsa_poseidon_verify + +Verifier for EdDSA signatures + +```rust +fn eddsa_poseidon_verify(public_key_x : Field, public_key_y : Field, signature_s: Field, signature_r8_x: Field, signature_r8_y: Field, message: Field) -> bool +``` + + diff --git a/docs/versioned_docs/version-v0.23.0/noir/standard_library/cryptographic_primitives/hashes.mdx b/docs/versioned_docs/version-v0.23.0/noir/standard_library/cryptographic_primitives/hashes.mdx new file mode 100644 index 00000000000..3c5f7f79603 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir/standard_library/cryptographic_primitives/hashes.mdx @@ -0,0 +1,167 @@ +--- +title: Hash methods +description: + Learn about the cryptographic primitives ready to use for any Noir project, including sha256, + blake2s, pedersen, mimc_bn254 and mimc +keywords: + [cryptographic primitives, Noir project, sha256, blake2s, pedersen, mimc_bn254, mimc, hash] +sidebar_position: 0 +--- + +import BlackBoxInfo from '@site/src/components/Notes/_blackbox.mdx'; + +## sha256 + +Given an array of bytes, returns the resulting sha256 hash. + +```rust +fn sha256(_input : [u8]) -> [u8; 32] +``` + +example: + +```rust +fn main() { + let x = [163, 117, 178, 149]; // some random bytes + let hash = std::hash::sha256(x); +} +``` + + + +## blake2s + +Given an array of bytes, returns an array with the Blake2 hash + +```rust +fn blake2s(_input : [u8]) -> [u8; 32] +``` + +example: + +```rust +fn main() { + let x = [163, 117, 178, 149]; // some random bytes + let hash = std::hash::blake2s(x); +} +``` + + + +## pedersen_hash + +Given an array of Fields, returns the Pedersen hash. + +```rust +fn pedersen_hash(_input : [Field]) -> Field +``` + +example: + +```rust +fn main() { + let x = [163, 117, 178, 149]; // some random bytes + let hash = std::hash::pedersen_hash(x); +} +``` + + + + + +## pedersen_commitment + +Given an array of Fields, returns the Pedersen commitment. + +```rust +fn pedersen_commitment(_input : [Field]) -> [Field; 2] +``` + +example: + +```rust +fn main() { + let x = [163, 117, 178, 149]; // some random bytes + let commitment = std::hash::pedersen_commitment(x); +} +``` + + + +## keccak256 + +Given an array of bytes (`u8`), returns the resulting keccak hash as an array of 32 bytes +(`[u8; 32]`). Specify a message_size to hash only the first `message_size` bytes +of the input. + +```rust +fn keccak256(_input : [u8; N], _message_size: u32) -> [u8; 32] +``` + +example: + +```rust +fn main() { + let x = [163, 117, 178, 149]; // some random bytes + let message_size = 4; + let hash = std::hash::keccak256(x, message_size); +} +``` + + + +## poseidon + +Given an array of Fields, returns a new Field with the Poseidon Hash. Mind that you need to specify +how many inputs are there to your Poseidon function. + +```rust +// example for hash_1, hash_2 accepts an array of length 2, etc +fn hash_1(input: [Field; 1]) -> Field +``` + +example: + +```rust +fn main() +{ + let hash_2 = std::hash::poseidon::bn254::hash_2([1, 2]); + assert(hash2 == 0x115cc0f5e7d690413df64c6b9662e9cf2a3617f2743245519e19607a4417189a); +} +``` + +## mimc_bn254 and mimc + +`mimc_bn254` is `mimc`, but with hardcoded parameters for the BN254 curve. You can use it by +providing an array of Fields, and it returns a Field with the hash. You can use the `mimc` method if +you're willing to input your own constants: + +```rust +fn mimc(x: Field, k: Field, constants: [Field; N], exp : Field) -> Field +``` + +otherwise, use the `mimc_bn254` method: + +```rust +fn mimc_bn254(array: [Field; N]) -> Field +``` + +example: + +```rust + +fn main() { + let x = [163, 117, 178, 149]; // some random bytes + let hash = std::hash::mimc::mimc_bn254(x); +} +``` + +## hash_to_field + +```rust +fn hash_to_field(_input : [Field; N]) -> Field {} +``` + +Calculates the `blake2s` hash of the inputs and returns the hash modulo the field modulus to return +a value which can be represented as a `Field`. + diff --git a/docs/versioned_docs/version-v0.23.0/noir/standard_library/cryptographic_primitives/index.md b/docs/versioned_docs/version-v0.23.0/noir/standard_library/cryptographic_primitives/index.md new file mode 100644 index 00000000000..650f30165d5 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir/standard_library/cryptographic_primitives/index.md @@ -0,0 +1,14 @@ +--- +title: Cryptographic Primitives +description: + Learn about the cryptographic primitives ready to use for any Noir project +keywords: + [ + cryptographic primitives, + Noir project, + ] +--- + +The Noir team is progressively adding new cryptographic primitives to the standard library. Reach out for news or if you would be interested in adding more of these calculations in Noir. + +Some methods are available thanks to the Aztec backend, not being performed using Noir. When using other backends, these methods may or may not be supplied. diff --git a/docs/versioned_docs/version-v0.23.0/noir/standard_library/cryptographic_primitives/scalar.mdx b/docs/versioned_docs/version-v0.23.0/noir/standard_library/cryptographic_primitives/scalar.mdx new file mode 100644 index 00000000000..aa4fb8cbaed --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir/standard_library/cryptographic_primitives/scalar.mdx @@ -0,0 +1,28 @@ +--- +title: Scalar multiplication +description: See how you can perform scalar multiplications over a fixed base in Noir +keywords: [cryptographic primitives, Noir project, scalar multiplication] +sidebar_position: 1 +--- + +import BlackBoxInfo from '@site/src/components/Notes/_blackbox.mdx'; + +## scalar_mul::fixed_base_embedded_curve + +Performs scalar multiplication over the embedded curve whose coordinates are defined by the +configured noir field. For the BN254 scalar field, this is BabyJubJub or Grumpkin. + +```rust +fn fixed_base_embedded_curve(_input : Field) -> [Field; 2] +``` + +example + +```rust +fn main(x : Field) { + let scal = std::scalar_mul::fixed_base_embedded_curve(x); + println(scal); +} +``` + + diff --git a/docs/versioned_docs/version-v0.23.0/noir/standard_library/cryptographic_primitives/schnorr.mdx b/docs/versioned_docs/version-v0.23.0/noir/standard_library/cryptographic_primitives/schnorr.mdx new file mode 100644 index 00000000000..7a2c9c20226 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir/standard_library/cryptographic_primitives/schnorr.mdx @@ -0,0 +1,38 @@ +--- +title: Schnorr Signatures +description: Learn how you can verify Schnorr signatures using Noir +keywords: [cryptographic primitives, Noir project, schnorr, signatures] +sidebar_position: 2 +--- + +import BlackBoxInfo from '@site/src/components/Notes/_blackbox.mdx'; + +## schnorr::verify_signature + +Verifier for Schnorr signatures over the embedded curve (for BN254 it is Grumpkin). + +```rust +fn verify_signature(_public_key_x: Field, _public_key_y: Field, _signature: [u8; 64], _message: [u8]) -> bool +``` + +where `_signature` can be generated like so using the npm package +[@noir-lang/barretenberg](https://www.npmjs.com/package/@noir-lang/barretenberg) + +```js +const { BarretenbergWasm } = require('@noir-lang/barretenberg/dest/wasm'); +const { Schnorr } = require('@noir-lang/barretenberg/dest/crypto/schnorr'); + +... + +const barretenberg = await BarretenbergWasm.new(); +const schnorr = new Schnorr(barretenberg); +const pubKey = schnorr.computePublicKey(privateKey); +const message = ... +const signature = Array.from( + schnorr.constructSignature(hash, privateKey).toBuffer() +); + +... +``` + + diff --git a/docs/versioned_docs/version-v0.23.0/noir/standard_library/logging.md b/docs/versioned_docs/version-v0.23.0/noir/standard_library/logging.md new file mode 100644 index 00000000000..db75ef9f86f --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir/standard_library/logging.md @@ -0,0 +1,78 @@ +--- +title: Logging +description: + Learn how to use the println statement for debugging in Noir with this tutorial. Understand the + basics of logging in Noir and how to implement it in your code. +keywords: + [ + noir logging, + println statement, + print statement, + debugging in noir, + noir std library, + logging tutorial, + basic logging in noir, + noir logging implementation, + noir debugging techniques, + rust, + ] +--- + +The standard library provides two familiar statements you can use: `println` and `print`. Despite being a limited implementation of rust's `println!` and `print!` macros, these constructs can be useful for debugging. + +You can print the output of both statements in your Noir code by using the `nargo execute` command or the `--show-output` flag when using `nargo test` (provided there are print statements in your tests). + +It is recommended to use `nargo execute` if you want to debug failing constraints with `println` or `print` statements. This is due to every input in a test being a constant rather than a witness, so we issue an error during compilation while we only print during execution (which comes after compilation). Neither `println`, nor `print` are callable for failed constraints caught at compile time. + +Both `print` and `println` are generic functions which can work on integers, fields, strings, and even structs or expressions. Note however, that slices are currently unsupported. For example: + +```rust +struct Person { + age: Field, + height: Field, +} + +fn main(age: Field, height: Field) { + let person = Person { + age: age, + height: height, + }; + println(person); + println(age + height); + println("Hello world!"); +} +``` + +You can print different types in the same statement (including strings) with a type called `fmtstr`. It can be specified in the same way as a normal string, just prepended with an "f" character: + +```rust + let fmt_str = f"i: {i}, j: {j}"; + println(fmt_str); + + let s = myStruct { y: x, x: y }; + println(s); + + println(f"i: {i}, s: {s}"); + + println(x); + println([x, y]); + + let foo = fooStruct { my_struct: s, foo: 15 }; + println(f"s: {s}, foo: {foo}"); + + println(15); // prints 0x0f, implicit Field + println(-1 as u8); // prints 255 + println(-1 as i8); // prints -1 +``` + +Examples shown above are interchangeable between the two `print` statements: + +```rust +let person = Person { age : age, height : height }; + +println(person); +print(person); + +println("Hello world!"); // Prints with a newline at the end of the input +print("Hello world!"); // Prints the input and keeps cursor on the same line +``` diff --git a/docs/versioned_docs/version-v0.23.0/noir/standard_library/merkle_trees.md b/docs/versioned_docs/version-v0.23.0/noir/standard_library/merkle_trees.md new file mode 100644 index 00000000000..fa488677884 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir/standard_library/merkle_trees.md @@ -0,0 +1,58 @@ +--- +title: Merkle Trees +description: Learn about Merkle Trees in Noir with this tutorial. Explore the basics of computing a merkle root using a proof, with examples. +keywords: + [ + Merkle trees in Noir, + Noir programming language, + check membership, + computing root from leaf, + Noir Merkle tree implementation, + Merkle tree tutorial, + Merkle tree code examples, + Noir libraries, + pedersen hash., + ] +--- + +## compute_merkle_root + +Returns the root of the tree from the provided leaf and its hash path, using a [Pedersen hash](./cryptographic_primitives/hashes.mdx#pedersen_hash). + +```rust +fn compute_merkle_root(leaf : Field, index : Field, hash_path: [Field]) -> Field +``` + +example: + +```rust +/** + // these values are for this example only + index = "0" + priv_key = "0x000000000000000000000000000000000000000000000000000000616c696365" + secret = "0x1929ea3ab8d9106a899386883d9428f8256cfedb3c4f6b66bf4aa4d28a79988f" + note_hash_path = [ + "0x1e61bdae0f027b1b2159e1f9d3f8d00fa668a952dddd822fda80dc745d6f65cc", + "0x0e4223f3925f98934393c74975142bd73079ab0621f4ee133cee050a3c194f1a", + "0x2fd7bb412155bf8693a3bd2a3e7581a679c95c68a052f835dddca85fa1569a40" + ] + */ +fn main(index: Field, priv_key: Field, secret: Field, note_hash_path: [Field; 3]) { + + let pubkey = std::scalar_mul::fixed_base_embedded_curve(priv_key); + let pubkey_x = pubkey[0]; + let pubkey_y = pubkey[1]; + let note_commitment = std::hash::pedersen([pubkey_x, pubkey_y, secret]); + + let root = std::merkle::compute_merkle_root(note_commitment[0], index, note_hash_path); + println(root); +} +``` + +To check merkle tree membership: + +1. Include a merkle root as a program input. +2. Compute the merkle root of a given leaf, index and hash path. +3. Assert the merkle roots are equal. + +For more info about merkle trees, see the Wikipedia [page](https://en.wikipedia.org/wiki/Merkle_tree). diff --git a/docs/versioned_docs/version-v0.23.0/noir/standard_library/options.md b/docs/versioned_docs/version-v0.23.0/noir/standard_library/options.md new file mode 100644 index 00000000000..970c9cfbf11 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir/standard_library/options.md @@ -0,0 +1,97 @@ +--- +title: Option Type +--- + +The `Option` type is a way to express that a value might be present (`Some(T))` or absent (`None`). It's a safer way to handle potential absence of values, compared to using nulls in many other languages. + +```rust +struct Option { + None, + Some(T), +} +``` + +The `Option` type, already imported into your Noir program, can be used directly: + +```rust +fn main() { + let none = Option::none(); + let some = Option::some(3); +} +``` + +See [this test](https://github.com/noir-lang/noir/blob/5cbfb9c4a06c8865c98ff2b594464b037d821a5c/crates/nargo_cli/tests/test_data/option/src/main.nr) for a more comprehensive set of examples of each of the methods described below. + +## Methods + +### none + +Constructs a none value. + +### some + +Constructs a some wrapper around a given value. + +### is_none + +Returns true if the Option is None. + +### is_some + +Returns true of the Option is Some. + +### unwrap + +Asserts `self.is_some()` and returns the wrapped value. + +### unwrap_unchecked + +Returns the inner value without asserting `self.is_some()`. This method can be useful within an if condition when we already know that `option.is_some()`. If the option is None, there is no guarantee what value will be returned, only that it will be of type T for an `Option`. + +### unwrap_or + +Returns the wrapped value if `self.is_some()`. Otherwise, returns the given default value. + +### unwrap_or_else + +Returns the wrapped value if `self.is_some()`. Otherwise, calls the given function to return a default value. + +### map + +If self is `Some(x)`, this returns `Some(f(x))`. Otherwise, this returns `None`. + +### map_or + +If self is `Some(x)`, this returns `f(x)`. Otherwise, this returns the given default value. + +### map_or_else + +If self is `Some(x)`, this returns `f(x)`. Otherwise, this returns `default()`. + +### and + +Returns None if self is None. Otherwise, this returns `other`. + +### and_then + +If self is None, this returns None. Otherwise, this calls the given function with the Some value contained within self, and returns the result of that call. In some languages this function is called `flat_map` or `bind`. + +### or + +If self is Some, return self. Otherwise, return `other`. + +### or_else + +If self is Some, return self. Otherwise, return `default()`. + +### xor + +If only one of the two Options is Some, return that option. Otherwise, if both options are Some or both are None, None is returned. + +### filter + +Returns `Some(x)` if self is `Some(x)` and `predicate(x)` is true. Otherwise, this returns `None`. + +### flatten + +Flattens an `Option>` into a `Option`. This returns `None` if the outer Option is None. Otherwise, this returns the inner Option. diff --git a/docs/versioned_docs/version-v0.23.0/noir/standard_library/recursion.md b/docs/versioned_docs/version-v0.23.0/noir/standard_library/recursion.md new file mode 100644 index 00000000000..67962082a8f --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir/standard_library/recursion.md @@ -0,0 +1,90 @@ +--- +title: Recursive Proofs +description: Learn about how to write recursive proofs in Noir. +keywords: [recursion, recursive proofs, verification_key, aggregation object, verify_proof] +--- + +Noir supports recursively verifying proofs, meaning you verify the proof of a Noir program in another Noir program. This enables creating proofs of arbitrary size by doing step-wise verification of smaller components of a large proof. + +The `verify_proof` function takes a verification key, proof and public inputs for a zk program, as well as a key hash and an input aggregation object. The key hash is used to check the validity of the verification key and the input aggregation object is required by some proving systems. The `verify_proof` function returns an output aggregation object that can then be fed into future iterations of the proof verification if required. + +```rust +#[foreign(verify_proof)] +fn verify_proof(_verification_key : [Field], _proof : [Field], _public_input : Field, _key_hash : Field, _input_aggregation_object : [Field]) -> [Field] {} +``` + +:::info + +This is a black box function. Read [this section](./black_box_fns) to learn more about black box functions in Noir. + +::: + +## Example usage + +```rust +use dep::std; + +fn main( + verification_key : [Field; 114], + proof : [Field; 94], + public_inputs : [Field; 1], + key_hash : Field, + input_aggregation_object : [Field; 16], + proof_b : [Field; 94], +) -> pub [Field; 16] { + let output_aggregation_object_a = std::verify_proof( + verification_key.as_slice(), + proof.as_slice(), + public_inputs.as_slice(), + key_hash, + input_aggregation_object + ); + + let output_aggregation_object = std::verify_proof( + verification_key.as_slice(), + proof_b.as_slice(), + public_inputs.as_slice(), + key_hash, + output_aggregation_object_a + ); + + let mut output = [0; 16]; + for i in 0..16 { + output[i] = output_aggregation_object[i]; + } + output +} +``` + +## Parameters + +### `verification_key` + +The verification key for the zk program that is being verified. + +### `proof` + +The proof for the zk program that is being verified. + +### `public_inputs` + +These represent the public inputs of the proof we are verifying. They should be checked against in the circuit after construction of a new aggregation state. + +### `key_hash` + +A key hash is used to check the validity of the verification key. The circuit implementing this opcode can use this hash to ensure that the key provided to the circuit matches the key produced by the circuit creator. + +### `input_aggregation_object` + +An aggregation object is blob of data that the top-level verifier must run some proof system specific algorithm on to complete verification. The size is proof system specific and will be set by the backend integrating this opcode. The input aggregation object is only not `None` when we are verifying a previous recursive aggregation in the current circuit. If this is the first recursive aggregation there is no input aggregation object. It is left to the backend to determine how to handle when there is no input aggregation object. + +## Return value + +### `output_aggregation_object` + +This is the result of a recursive aggregation and is what will be fed into the next verifier. +The next verifier can either perform a final verification (returning true or false) or perform another recursive aggregation where this output aggregation object will be the input aggregation object of the next recursive aggregation. + +## Example + +You can see an example of how to do recursive proofs in [this example recursion demo repo](https://github.com/noir-lang/noir-examples/tree/master/recursion). diff --git a/docs/versioned_docs/version-v0.23.0/noir/standard_library/traits.md b/docs/versioned_docs/version-v0.23.0/noir/standard_library/traits.md new file mode 100644 index 00000000000..f2960ca5080 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir/standard_library/traits.md @@ -0,0 +1,284 @@ +--- +title: Traits +description: Noir's stdlib provides a few commonly used traits. +keywords: [traits, trait, interface, protocol, default, add, eq] +--- + +## `std::default` + +### `std::default::Default` + +```rust +trait Default { + fn default() -> Self; +} +``` + +Constructs a default value of a type. + +Implementations: +```rust +impl Default for Field { .. } + +impl Default for i8 { .. } +impl Default for i16 { .. } +impl Default for i32 { .. } +impl Default for i64 { .. } + +impl Default for u8 { .. } +impl Default for u16 { .. } +impl Default for u32 { .. } +impl Default for u64 { .. } + +impl Default for () { .. } +impl Default for bool { .. } + +impl Default for [T; N] + where T: Default { .. } + +impl Default for (A, B) + where A: Default, B: Default { .. } + +impl Default for (A, B, C) + where A: Default, B: Default, C: Default { .. } + +impl Default for (A, B, C, D) + where A: Default, B: Default, C: Default, D: Default { .. } + +impl Default for (A, B, C, D, E) + where A: Default, B: Default, C: Default, D: Default, E: Default { .. } +``` + +For primitive integer types, the return value of `default` is `0`. Container +types such as arrays are filled with default values of their element type. + +## `std::cmp` + +### `std::cmp::Eq` + +```rust +trait Eq { + fn eq(self, other: Self) -> bool; +} +``` +Returns `true` if `self` is equal to `other`. Implementing this trait on a type +allows the type to be used with `==` and `!=`. + +Implementations: +```rust +impl Eq for Field { .. } + +impl Eq for i8 { .. } +impl Eq for i16 { .. } +impl Eq for i32 { .. } +impl Eq for i64 { .. } + +impl Eq for u8 { .. } +impl Eq for u16 { .. } +impl Eq for u32 { .. } +impl Eq for u64 { .. } + +impl Eq for () { .. } +impl Eq for bool { .. } + +impl Eq for [T; N] + where T: Eq { .. } + +impl Eq for (A, B) + where A: Eq, B: Eq { .. } + +impl Eq for (A, B, C) + where A: Eq, B: Eq, C: Eq { .. } + +impl Eq for (A, B, C, D) + where A: Eq, B: Eq, C: Eq, D: Eq { .. } + +impl Eq for (A, B, C, D, E) + where A: Eq, B: Eq, C: Eq, D: Eq, E: Eq { .. } +``` + +### `std::cmp::Cmp` + +```rust +trait Cmp { + fn cmp(self, other: Self) -> Ordering; +} +``` + +`a.cmp(b)` compares two values returning `Ordering::less()` if `a < b`, +`Ordering::equal()` if `a == b`, or `Ordering::greater()` if `a > b`. +Implementing this trait on a type allows `<`, `<=`, `>`, and `>=` to be +used on values of the type. + +Implementations: + +```rust +impl Ord for u8 { .. } +impl Ord for u16 { .. } +impl Ord for u32 { .. } +impl Ord for u64 { .. } + +impl Ord for i8 { .. } +impl Ord for i16 { .. } +impl Ord for i32 { .. } + +impl Ord for i64 { .. } + +impl Ord for () { .. } +impl Ord for bool { .. } + +impl Ord for [T; N] + where T: Ord { .. } + +impl Ord for (A, B) + where A: Ord, B: Ord { .. } + +impl Ord for (A, B, C) + where A: Ord, B: Ord, C: Ord { .. } + +impl Ord for (A, B, C, D) + where A: Ord, B: Ord, C: Ord, D: Ord { .. } + +impl Ord for (A, B, C, D, E) + where A: Ord, B: Ord, C: Ord, D: Ord, E: Ord { .. } +``` + +## `std::ops` + +### `std::ops::Add`, `std::ops::Sub`, `std::ops::Mul`, and `std::ops::Div` + +These traits abstract over addition, subtraction, multiplication, and division respectively. +Implementing these traits for a given type will also allow that type to be used with the corresponding operator +for that trait (`+` for Add, etc) in addition to the normal method names. + +```rust +trait Add { + fn add(self, other: Self) -> Self; +} + +trait Sub { + fn sub(self, other: Self) -> Self; +} + +trait Mul { + fn mul(self, other: Self) -> Self; +} + +trait Div { + fn div(self, other: Self) -> Self; +} +``` + +The implementations block below is given for the `Add` trait, but the same types that implement +`Add` also implement `Sub`, `Mul`, and `Div`. + +Implementations: +```rust +impl Add for Field { .. } + +impl Add for i8 { .. } +impl Add for i16 { .. } +impl Add for i32 { .. } +impl Add for i64 { .. } + +impl Add for u8 { .. } +impl Add for u16 { .. } +impl Add for u32 { .. } +impl Add for u64 { .. } +``` + +### `std::ops::Rem` + +```rust +trait Rem { + fn rem(self, other: Self) -> Self; +} +``` + +`Rem::rem(a, b)` is the remainder function returning the result of what is +left after dividing `a` and `b`. Implementing `Rem` allows the `%` operator +to be used with the implementation type. + +Unlike other numeric traits, `Rem` is not implemented for `Field`. + +Implementations: +```rust +impl Rem for u8 { fn rem(self, other: u8) -> u8 { self % other } } +impl Rem for u16 { fn rem(self, other: u16) -> u16 { self % other } } +impl Rem for u32 { fn rem(self, other: u32) -> u32 { self % other } } +impl Rem for u64 { fn rem(self, other: u64) -> u64 { self % other } } + +impl Rem for i8 { fn rem(self, other: i8) -> i8 { self % other } } +impl Rem for i16 { fn rem(self, other: i16) -> i16 { self % other } } +impl Rem for i32 { fn rem(self, other: i32) -> i32 { self % other } } +impl Rem for i64 { fn rem(self, other: i64) -> i64 { self % other } } +``` + +### `std::ops::{ BitOr, BitAnd, BitXor }` + +```rust +trait BitOr { + fn bitor(self, other: Self) -> Self; +} + +trait BitAnd { + fn bitand(self, other: Self) -> Self; +} + +trait BitXor { + fn bitxor(self, other: Self) -> Self; +} +``` + +Traits for the bitwise operations `|`, `&`, and `^`. + +Implementing `BitOr`, `BitAnd` or `BitXor` for a type allows the `|`, `&`, or `^` operator respectively +to be used with the type. + +The implementations block below is given for the `BitOr` trait, but the same types that implement +`BitOr` also implement `BitAnd` and `BitXor`. + +Implementations: +```rust +impl BitOr for bool { fn bitor(self, other: bool) -> bool { self | other } } + +impl BitOr for u8 { fn bitor(self, other: u8) -> u8 { self | other } } +impl BitOr for u16 { fn bitor(self, other: u16) -> u16 { self | other } } +impl BitOr for u32 { fn bitor(self, other: u32) -> u32 { self | other } } +impl BitOr for u64 { fn bitor(self, other: u64) -> u64 { self | other } } + +impl BitOr for i8 { fn bitor(self, other: i8) -> i8 { self | other } } +impl BitOr for i16 { fn bitor(self, other: i16) -> i16 { self | other } } +impl BitOr for i32 { fn bitor(self, other: i32) -> i32 { self | other } } +impl BitOr for i64 { fn bitor(self, other: i64) -> i64 { self | other } } +``` + +### `std::ops::{ Shl, Shr }` + +```rust +trait Shl { + fn shl(self, other: Self) -> Self; +} + +trait Shr { + fn shr(self, other: Self) -> Self; +} +``` + +Traits for a bit shift left and bit shift right. + +Implementing `Shl` for a type allows the left shift operator (`<<`) to be used with the implementation type. +Similarly, implementing `Shr` allows the right shift operator (`>>`) to be used with the type. + +Note that bit shifting is not currently implemented for signed types. + +The implementations block below is given for the `Shl` trait, but the same types that implement +`Shl` also implement `Shr`. + +Implementations: +```rust +impl Shl for u8 { fn shl(self, other: u8) -> u8 { self << other } } +impl Shl for u16 { fn shl(self, other: u16) -> u16 { self << other } } +impl Shl for u32 { fn shl(self, other: u32) -> u32 { self << other } } +impl Shl for u64 { fn shl(self, other: u64) -> u64 { self << other } } +``` diff --git a/docs/versioned_docs/version-v0.23.0/noir/standard_library/zeroed.md b/docs/versioned_docs/version-v0.23.0/noir/standard_library/zeroed.md new file mode 100644 index 00000000000..97dab02dac2 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir/standard_library/zeroed.md @@ -0,0 +1,25 @@ +--- +title: Zeroed Function +description: + The zeroed function returns a zeroed value of any type. +keywords: + [ + zeroed + ] +--- + +Implements `fn zeroed() -> T` to return a zeroed value of any type. This function is generally unsafe to use as the zeroed bit pattern is not guaranteed to be valid for all types. It can however, be useful in cases when the value is guaranteed not to be used such as in a BoundedVec library implementing a growable vector, up to a certain length, backed by an array. The array can be initialized with zeroed values which are guaranteed to be inaccessible until the vector is pushed to. Similarly, enumerations in noir can be implemented using this method by providing zeroed values for the unused variants. + +You can access the function at `std::unsafe::zeroed`. + +This function currently supports the following types: + +- Field +- Bool +- Uint +- Array +- String +- Tuple +- Function + +Using it on other types could result in unexpected behavior. diff --git a/docs/versioned_docs/version-v0.23.0/noir_js/reference/backend_barretenberg/.nojekyll b/docs/versioned_docs/version-v0.23.0/noir_js/reference/backend_barretenberg/.nojekyll new file mode 100644 index 00000000000..e2ac6616add --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir_js/reference/backend_barretenberg/.nojekyll @@ -0,0 +1 @@ +TypeDoc added this file to prevent GitHub Pages from using Jekyll. You can turn off this behavior by setting the `githubPages` option to false. \ No newline at end of file diff --git a/docs/versioned_docs/version-v0.23.0/noir_js/reference/backend_barretenberg/classes/BarretenbergBackend.md b/docs/versioned_docs/version-v0.23.0/noir_js/reference/backend_barretenberg/classes/BarretenbergBackend.md new file mode 100644 index 00000000000..5cbe9421b92 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir_js/reference/backend_barretenberg/classes/BarretenbergBackend.md @@ -0,0 +1,185 @@ +# BarretenbergBackend + +## Implements + +- [`Backend`](../interfaces/Backend.md) + +## Constructors + +### new BarretenbergBackend(acirCircuit, options) + +```ts +new BarretenbergBackend(acirCircuit, options): BarretenbergBackend +``` + +#### Parameters + +| Parameter | Type | +| :------ | :------ | +| `acirCircuit` | [`CompiledCircuit`](../type-aliases/CompiledCircuit.md) | +| `options` | [`BackendOptions`](../type-aliases/BackendOptions.md) | + +#### Returns + +[`BarretenbergBackend`](BarretenbergBackend.md) + +## Methods + +### destroy() + +```ts +destroy(): Promise +``` + +#### Returns + +`Promise`\<`void`\> + +#### Implementation of + +[`Backend`](../interfaces/Backend.md).[`destroy`](../interfaces/Backend.md#destroy) + +#### Description + +Destroys the backend + +*** + +### generateFinalProof() + +```ts +generateFinalProof(decompressedWitness): Promise +``` + +#### Parameters + +| Parameter | Type | +| :------ | :------ | +| `decompressedWitness` | `Uint8Array` | + +#### Returns + +`Promise`\<[`ProofData`](../type-aliases/ProofData.md)\> + +#### Implementation of + +[`Backend`](../interfaces/Backend.md).[`generateFinalProof`](../interfaces/Backend.md#generatefinalproof) + +#### Description + +Generates a final proof (not meant to be verified in another circuit) + +*** + +### generateIntermediateProof() + +```ts +generateIntermediateProof(witness): Promise +``` + +#### Parameters + +| Parameter | Type | +| :------ | :------ | +| `witness` | `Uint8Array` | + +#### Returns + +`Promise`\<[`ProofData`](../type-aliases/ProofData.md)\> + +#### Implementation of + +[`Backend`](../interfaces/Backend.md).[`generateIntermediateProof`](../interfaces/Backend.md#generateintermediateproof) + +#### Example + +```typescript +const intermediateProof = await backend.generateIntermediateProof(witness); +``` + +*** + +### generateIntermediateProofArtifacts() + +```ts +generateIntermediateProofArtifacts(proofData, numOfPublicInputs): Promise +``` + +#### Parameters + +| Parameter | Type | Default value | +| :------ | :------ | :------ | +| `proofData` | [`ProofData`](../type-aliases/ProofData.md) | `undefined` | +| `numOfPublicInputs` | `number` | `0` | + +#### Returns + +`Promise`\<`object`\> + +#### Implementation of + +[`Backend`](../interfaces/Backend.md).[`generateIntermediateProofArtifacts`](../interfaces/Backend.md#generateintermediateproofartifacts) + +#### Example + +```typescript +const artifacts = await backend.generateIntermediateProofArtifacts(proof, numOfPublicInputs); +``` + +*** + +### verifyFinalProof() + +```ts +verifyFinalProof(proofData): Promise +``` + +#### Parameters + +| Parameter | Type | +| :------ | :------ | +| `proofData` | [`ProofData`](../type-aliases/ProofData.md) | + +#### Returns + +`Promise`\<`boolean`\> + +#### Implementation of + +[`Backend`](../interfaces/Backend.md).[`verifyFinalProof`](../interfaces/Backend.md#verifyfinalproof) + +#### Description + +Verifies a final proof + +*** + +### verifyIntermediateProof() + +```ts +verifyIntermediateProof(proofData): Promise +``` + +#### Parameters + +| Parameter | Type | +| :------ | :------ | +| `proofData` | [`ProofData`](../type-aliases/ProofData.md) | + +#### Returns + +`Promise`\<`boolean`\> + +#### Implementation of + +[`Backend`](../interfaces/Backend.md).[`verifyIntermediateProof`](../interfaces/Backend.md#verifyintermediateproof) + +#### Example + +```typescript +const isValidIntermediate = await backend.verifyIntermediateProof(proof); +``` + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.23.0/noir_js/reference/backend_barretenberg/index.md b/docs/versioned_docs/version-v0.23.0/noir_js/reference/backend_barretenberg/index.md new file mode 100644 index 00000000000..93b248b0f65 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir_js/reference/backend_barretenberg/index.md @@ -0,0 +1,45 @@ +# Backend Barretenberg + +## Exports + +### Classes + +| Class | Description | +| :------ | :------ | +| [BarretenbergBackend](classes/BarretenbergBackend.md) | - | + +### Interfaces + +| Interface | Description | +| :------ | :------ | +| [Backend](interfaces/Backend.md) | - | + +### Type Aliases + +| Type alias | Description | +| :------ | :------ | +| [BackendOptions](type-aliases/BackendOptions.md) | - | +| [CompiledCircuit](type-aliases/CompiledCircuit.md) | - | +| [ProofData](type-aliases/ProofData.md) | - | + +## Functions + +### flattenPublicInputs() + +```ts +flattenPublicInputs(publicInputs): string[] +``` + +#### Parameters + +| Parameter | Type | +| :------ | :------ | +| `publicInputs` | `WitnessMap` | + +#### Returns + +`string`[] + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.23.0/noir_js/reference/backend_barretenberg/interfaces/Backend.md b/docs/versioned_docs/version-v0.23.0/noir_js/reference/backend_barretenberg/interfaces/Backend.md new file mode 100644 index 00000000000..3eb9645c8d2 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir_js/reference/backend_barretenberg/interfaces/Backend.md @@ -0,0 +1,132 @@ +# Backend + +## Methods + +### destroy() + +```ts +destroy(): Promise +``` + +#### Returns + +`Promise`\<`void`\> + +#### Description + +Destroys the backend + +*** + +### generateFinalProof() + +```ts +generateFinalProof(decompressedWitness): Promise +``` + +#### Parameters + +| Parameter | Type | +| :------ | :------ | +| `decompressedWitness` | `Uint8Array` | + +#### Returns + +`Promise`\<[`ProofData`](../type-aliases/ProofData.md)\> + +#### Description + +Generates a final proof (not meant to be verified in another circuit) + +*** + +### generateIntermediateProof() + +```ts +generateIntermediateProof(decompressedWitness): Promise +``` + +#### Parameters + +| Parameter | Type | +| :------ | :------ | +| `decompressedWitness` | `Uint8Array` | + +#### Returns + +`Promise`\<[`ProofData`](../type-aliases/ProofData.md)\> + +#### Description + +Generates an intermediate proof (meant to be verified in another circuit) + +*** + +### generateIntermediateProofArtifacts() + +```ts +generateIntermediateProofArtifacts(proofData, numOfPublicInputs): Promise +``` + +#### Parameters + +| Parameter | Type | +| :------ | :------ | +| `proofData` | [`ProofData`](../type-aliases/ProofData.md) | +| `numOfPublicInputs` | `number` | + +#### Returns + +`Promise`\<`object`\> + +#### Description + +Retrieves the artifacts from a proof in the Field format + +*** + +### verifyFinalProof() + +```ts +verifyFinalProof(proofData): Promise +``` + +#### Parameters + +| Parameter | Type | +| :------ | :------ | +| `proofData` | [`ProofData`](../type-aliases/ProofData.md) | + +#### Returns + +`Promise`\<`boolean`\> + +#### Description + +Verifies a final proof + +*** + +### verifyIntermediateProof() + +```ts +verifyIntermediateProof(proofData): Promise +``` + +#### Parameters + +| Parameter | Type | +| :------ | :------ | +| `proofData` | [`ProofData`](../type-aliases/ProofData.md) | + +#### Returns + +`Promise`\<`boolean`\> + +#### Description + +Verifies an intermediate proof + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.23.0/noir_js/reference/backend_barretenberg/type-aliases/BackendOptions.md b/docs/versioned_docs/version-v0.23.0/noir_js/reference/backend_barretenberg/type-aliases/BackendOptions.md new file mode 100644 index 00000000000..266ade75d17 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir_js/reference/backend_barretenberg/type-aliases/BackendOptions.md @@ -0,0 +1,19 @@ +# BackendOptions + +```ts +type BackendOptions: object; +``` + +## Description + +An options object, currently only used to specify the number of threads to use. + +## Type declaration + +| Member | Type | Description | +| :------ | :------ | :------ | +| `threads` | `number` | **Description**

Number of threads | + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.23.0/noir_js/reference/backend_barretenberg/type-aliases/CompiledCircuit.md b/docs/versioned_docs/version-v0.23.0/noir_js/reference/backend_barretenberg/type-aliases/CompiledCircuit.md new file mode 100644 index 00000000000..34e0dd04205 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir_js/reference/backend_barretenberg/type-aliases/CompiledCircuit.md @@ -0,0 +1,20 @@ +# CompiledCircuit + +```ts +type CompiledCircuit: object; +``` + +## Description + +The representation of a compiled circuit + +## Type declaration + +| Member | Type | Description | +| :------ | :------ | :------ | +| `abi` | `Abi` | **Description**

ABI representation of the circuit | +| `bytecode` | `string` | **Description**

The bytecode of the circuit | + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.23.0/noir_js/reference/backend_barretenberg/type-aliases/ProofData.md b/docs/versioned_docs/version-v0.23.0/noir_js/reference/backend_barretenberg/type-aliases/ProofData.md new file mode 100644 index 00000000000..3eb360a78f1 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir_js/reference/backend_barretenberg/type-aliases/ProofData.md @@ -0,0 +1,20 @@ +# ProofData + +```ts +type ProofData: object; +``` + +## Description + +The representation of a proof + +## Type declaration + +| Member | Type | Description | +| :------ | :------ | :------ | +| `proof` | `Uint8Array` | **Description**

An byte array representing the proof | +| `publicInputs` | `WitnessMap` | **Description**

Public inputs of a proof | + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.23.0/noir_js/reference/backend_barretenberg/typedoc-sidebar.cjs b/docs/versioned_docs/version-v0.23.0/noir_js/reference/backend_barretenberg/typedoc-sidebar.cjs new file mode 100644 index 00000000000..04e662c845f --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir_js/reference/backend_barretenberg/typedoc-sidebar.cjs @@ -0,0 +1,4 @@ +// @ts-check +/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */ +const typedocSidebar = { items: [{"type":"category","label":"Classes","items":[{"type":"doc","id":"noir_js/reference/backend_barretenberg/classes/BarretenbergBackend","label":"BarretenbergBackend"}]},{"type":"category","label":"Interfaces","items":[{"type":"doc","id":"noir_js/reference/backend_barretenberg/interfaces/Backend","label":"Backend"}]},{"type":"category","label":"Type Aliases","items":[{"type":"doc","id":"noir_js/reference/backend_barretenberg/type-aliases/BackendOptions","label":"BackendOptions"},{"type":"doc","id":"noir_js/reference/backend_barretenberg/type-aliases/CompiledCircuit","label":"CompiledCircuit"},{"type":"doc","id":"noir_js/reference/backend_barretenberg/type-aliases/ProofData","label":"ProofData"}]}]}; +module.exports = typedocSidebar.items; \ No newline at end of file diff --git a/docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/.nojekyll b/docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/.nojekyll new file mode 100644 index 00000000000..e2ac6616add --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/.nojekyll @@ -0,0 +1 @@ +TypeDoc added this file to prevent GitHub Pages from using Jekyll. You can turn off this behavior by setting the `githubPages` option to false. \ No newline at end of file diff --git a/docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/classes/Noir.md b/docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/classes/Noir.md new file mode 100644 index 00000000000..c54468891af --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/classes/Noir.md @@ -0,0 +1,131 @@ +# Noir + +## Constructors + +### new Noir(circuit, backend) + +```ts +new Noir(circuit, backend?): Noir +``` + +#### Parameters + +| Parameter | Type | +| :------ | :------ | +| `circuit` | [`CompiledCircuit`](../type-aliases/CompiledCircuit.md) | +| `backend`? | `Backend` | + +#### Returns + +[`Noir`](Noir.md) + +## Methods + +### destroy() + +```ts +destroy(): Promise +``` + +#### Returns + +`Promise`\<`void`\> + +#### Description + +Destroys the underlying backend instance. + +#### Example + +```typescript +await noir.destroy(); +``` + +*** + +### execute() + +```ts +execute(inputs, foreignCallHandler?): Promise +``` + +#### Parameters + +| Parameter | Type | +| :------ | :------ | +| `inputs` | [`InputMap`](../type-aliases/InputMap.md) | +| `foreignCallHandler`? | [`ForeignCallHandler`](../type-aliases/ForeignCallHandler.md) | + +#### Returns + +`Promise`\<`object`\> + +#### Description + +Allows to execute a circuit to get its witness and return value. + +#### Example + +```typescript +async execute(inputs) +``` + +*** + +### generateFinalProof() + +```ts +generateFinalProof(inputs): Promise +``` + +#### Parameters + +| Parameter | Type | +| :------ | :------ | +| `inputs` | [`InputMap`](../type-aliases/InputMap.md) | + +#### Returns + +`Promise`\<[`ProofData`](../type-aliases/ProofData.md)\> + +#### Description + +Generates a witness and a proof given an object as input. + +#### Example + +```typescript +async generateFinalProof(input) +``` + +*** + +### verifyFinalProof() + +```ts +verifyFinalProof(proofData): Promise +``` + +#### Parameters + +| Parameter | Type | +| :------ | :------ | +| `proofData` | [`ProofData`](../type-aliases/ProofData.md) | + +#### Returns + +`Promise`\<`boolean`\> + +#### Description + +Instantiates the verification key and verifies a proof. + +#### Example + +```typescript +async verifyFinalProof(proof) +``` + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/functions/and.md b/docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/functions/and.md new file mode 100644 index 00000000000..c783283e396 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/functions/and.md @@ -0,0 +1,22 @@ +# and() + +```ts +and(lhs, rhs): string +``` + +Performs a bitwise AND operation between `lhs` and `rhs` + +## Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `lhs` | `string` | | +| `rhs` | `string` | | + +## Returns + +`string` + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/functions/blake2s256.md b/docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/functions/blake2s256.md new file mode 100644 index 00000000000..7882d0da8d5 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/functions/blake2s256.md @@ -0,0 +1,21 @@ +# blake2s256() + +```ts +blake2s256(inputs): Uint8Array +``` + +Calculates the Blake2s256 hash of the input bytes + +## Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `inputs` | `Uint8Array` | | + +## Returns + +`Uint8Array` + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/functions/ecdsa_secp256k1_verify.md b/docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/functions/ecdsa_secp256k1_verify.md new file mode 100644 index 00000000000..0ba5783f0d5 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/functions/ecdsa_secp256k1_verify.md @@ -0,0 +1,29 @@ +# ecdsa\_secp256k1\_verify() + +```ts +ecdsa_secp256k1_verify( + hashed_msg, + public_key_x_bytes, + public_key_y_bytes, + signature): boolean +``` + +Calculates the Blake2s256 hash of the input bytes and represents these as a single field element. +Verifies a ECDSA signature over the secp256k1 curve. + +## Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `hashed_msg` | `Uint8Array` | | +| `public_key_x_bytes` | `Uint8Array` | | +| `public_key_y_bytes` | `Uint8Array` | | +| `signature` | `Uint8Array` | | + +## Returns + +`boolean` + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/functions/ecdsa_secp256r1_verify.md b/docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/functions/ecdsa_secp256r1_verify.md new file mode 100644 index 00000000000..0b20ff68957 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/functions/ecdsa_secp256r1_verify.md @@ -0,0 +1,28 @@ +# ecdsa\_secp256r1\_verify() + +```ts +ecdsa_secp256r1_verify( + hashed_msg, + public_key_x_bytes, + public_key_y_bytes, + signature): boolean +``` + +Verifies a ECDSA signature over the secp256r1 curve. + +## Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `hashed_msg` | `Uint8Array` | | +| `public_key_x_bytes` | `Uint8Array` | | +| `public_key_y_bytes` | `Uint8Array` | | +| `signature` | `Uint8Array` | | + +## Returns + +`boolean` + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/functions/keccak256.md b/docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/functions/keccak256.md new file mode 100644 index 00000000000..d10f155ce86 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/functions/keccak256.md @@ -0,0 +1,21 @@ +# keccak256() + +```ts +keccak256(inputs): Uint8Array +``` + +Calculates the Keccak256 hash of the input bytes + +## Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `inputs` | `Uint8Array` | | + +## Returns + +`Uint8Array` + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/functions/sha256.md b/docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/functions/sha256.md new file mode 100644 index 00000000000..6ba4ecac022 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/functions/sha256.md @@ -0,0 +1,21 @@ +# sha256() + +```ts +sha256(inputs): Uint8Array +``` + +Calculates the SHA256 hash of the input bytes + +## Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `inputs` | `Uint8Array` | | + +## Returns + +`Uint8Array` + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/functions/xor.md b/docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/functions/xor.md new file mode 100644 index 00000000000..8d762b895d3 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/functions/xor.md @@ -0,0 +1,22 @@ +# xor() + +```ts +xor(lhs, rhs): string +``` + +Performs a bitwise XOR operation between `lhs` and `rhs` + +## Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `lhs` | `string` | | +| `rhs` | `string` | | + +## Returns + +`string` + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/index.md b/docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/index.md new file mode 100644 index 00000000000..348453c0059 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/index.md @@ -0,0 +1,37 @@ +# Noir JS + +## Exports + +### Classes + +| Class | Description | +| :------ | :------ | +| [Noir](classes/Noir.md) | - | + +### Type Aliases + +| Type alias | Description | +| :------ | :------ | +| [CompiledCircuit](type-aliases/CompiledCircuit.md) | - | +| [ForeignCallHandler](type-aliases/ForeignCallHandler.md) | A callback which performs an foreign call and returns the response. | +| [ForeignCallInput](type-aliases/ForeignCallInput.md) | - | +| [ForeignCallOutput](type-aliases/ForeignCallOutput.md) | - | +| [InputMap](type-aliases/InputMap.md) | - | +| [ProofData](type-aliases/ProofData.md) | - | +| [WitnessMap](type-aliases/WitnessMap.md) | - | + +### Functions + +| Function | Description | +| :------ | :------ | +| [and](functions/and.md) | Performs a bitwise AND operation between `lhs` and `rhs` | +| [blake2s256](functions/blake2s256.md) | Calculates the Blake2s256 hash of the input bytes | +| [ecdsa\_secp256k1\_verify](functions/ecdsa_secp256k1_verify.md) | Calculates the Blake2s256 hash of the input bytes and represents these as a single field element. | +| [ecdsa\_secp256r1\_verify](functions/ecdsa_secp256r1_verify.md) | Verifies a ECDSA signature over the secp256r1 curve. | +| [keccak256](functions/keccak256.md) | Calculates the Keccak256 hash of the input bytes | +| [sha256](functions/sha256.md) | Calculates the SHA256 hash of the input bytes | +| [xor](functions/xor.md) | Performs a bitwise XOR operation between `lhs` and `rhs` | + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/type-aliases/CompiledCircuit.md b/docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/type-aliases/CompiledCircuit.md new file mode 100644 index 00000000000..34e0dd04205 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/type-aliases/CompiledCircuit.md @@ -0,0 +1,20 @@ +# CompiledCircuit + +```ts +type CompiledCircuit: object; +``` + +## Description + +The representation of a compiled circuit + +## Type declaration + +| Member | Type | Description | +| :------ | :------ | :------ | +| `abi` | `Abi` | **Description**

ABI representation of the circuit | +| `bytecode` | `string` | **Description**

The bytecode of the circuit | + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/type-aliases/ForeignCallHandler.md b/docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/type-aliases/ForeignCallHandler.md new file mode 100644 index 00000000000..812b8b16481 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/type-aliases/ForeignCallHandler.md @@ -0,0 +1,24 @@ +# ForeignCallHandler + +```ts +type ForeignCallHandler: (name, inputs) => Promise; +``` + +A callback which performs an foreign call and returns the response. + +## Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `name` | `string` | The identifier for the type of foreign call being performed. | +| `inputs` | [`ForeignCallInput`](ForeignCallInput.md)[] | An array of hex encoded inputs to the foreign call. | + +## Returns + +`Promise`\<[`ForeignCallOutput`](ForeignCallOutput.md)[]\> + +outputs - An array of hex encoded outputs containing the results of the foreign call. + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/type-aliases/ForeignCallInput.md b/docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/type-aliases/ForeignCallInput.md new file mode 100644 index 00000000000..dd95809186a --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/type-aliases/ForeignCallInput.md @@ -0,0 +1,9 @@ +# ForeignCallInput + +```ts +type ForeignCallInput: string[]; +``` + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/type-aliases/ForeignCallOutput.md b/docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/type-aliases/ForeignCallOutput.md new file mode 100644 index 00000000000..b71fb78a946 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/type-aliases/ForeignCallOutput.md @@ -0,0 +1,9 @@ +# ForeignCallOutput + +```ts +type ForeignCallOutput: string | string[]; +``` + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/type-aliases/InputMap.md b/docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/type-aliases/InputMap.md new file mode 100644 index 00000000000..c714e999d93 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/type-aliases/InputMap.md @@ -0,0 +1,13 @@ +# InputMap + +```ts +type InputMap: object; +``` + +## Index signature + + \[`key`: `string`\]: `InputValue` + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/type-aliases/ProofData.md b/docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/type-aliases/ProofData.md new file mode 100644 index 00000000000..3eb360a78f1 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/type-aliases/ProofData.md @@ -0,0 +1,20 @@ +# ProofData + +```ts +type ProofData: object; +``` + +## Description + +The representation of a proof + +## Type declaration + +| Member | Type | Description | +| :------ | :------ | :------ | +| `proof` | `Uint8Array` | **Description**

An byte array representing the proof | +| `publicInputs` | `WitnessMap` | **Description**

Public inputs of a proof | + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/type-aliases/WitnessMap.md b/docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/type-aliases/WitnessMap.md new file mode 100644 index 00000000000..258c46f9d0c --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/type-aliases/WitnessMap.md @@ -0,0 +1,9 @@ +# WitnessMap + +```ts +type WitnessMap: Map; +``` + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/typedoc-sidebar.cjs b/docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/typedoc-sidebar.cjs new file mode 100644 index 00000000000..077ebeb133e --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/noir_js/reference/noir_js/typedoc-sidebar.cjs @@ -0,0 +1,4 @@ +// @ts-check +/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */ +const typedocSidebar = { items: [{"type":"category","label":"Classes","items":[{"type":"doc","id":"noir_js/reference/noir_js/classes/Noir","label":"Noir"}]},{"type":"category","label":"Type Aliases","items":[{"type":"doc","id":"noir_js/reference/noir_js/type-aliases/CompiledCircuit","label":"CompiledCircuit"},{"type":"doc","id":"noir_js/reference/noir_js/type-aliases/ForeignCallHandler","label":"ForeignCallHandler"},{"type":"doc","id":"noir_js/reference/noir_js/type-aliases/ForeignCallInput","label":"ForeignCallInput"},{"type":"doc","id":"noir_js/reference/noir_js/type-aliases/ForeignCallOutput","label":"ForeignCallOutput"},{"type":"doc","id":"noir_js/reference/noir_js/type-aliases/InputMap","label":"InputMap"},{"type":"doc","id":"noir_js/reference/noir_js/type-aliases/ProofData","label":"ProofData"},{"type":"doc","id":"noir_js/reference/noir_js/type-aliases/WitnessMap","label":"WitnessMap"}]},{"type":"category","label":"Functions","items":[{"type":"doc","id":"noir_js/reference/noir_js/functions/and","label":"and"},{"type":"doc","id":"noir_js/reference/noir_js/functions/blake2s256","label":"blake2s256"},{"type":"doc","id":"noir_js/reference/noir_js/functions/ecdsa_secp256k1_verify","label":"ecdsa_secp256k1_verify"},{"type":"doc","id":"noir_js/reference/noir_js/functions/ecdsa_secp256r1_verify","label":"ecdsa_secp256r1_verify"},{"type":"doc","id":"noir_js/reference/noir_js/functions/keccak256","label":"keccak256"},{"type":"doc","id":"noir_js/reference/noir_js/functions/sha256","label":"sha256"},{"type":"doc","id":"noir_js/reference/noir_js/functions/xor","label":"xor"}]}]}; +module.exports = typedocSidebar.items; \ No newline at end of file diff --git a/docs/versioned_docs/version-v0.23.0/reference/NoirJS/backend_barretenberg/.nojekyll b/docs/versioned_docs/version-v0.23.0/reference/NoirJS/backend_barretenberg/.nojekyll new file mode 100644 index 00000000000..e2ac6616add --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/reference/NoirJS/backend_barretenberg/.nojekyll @@ -0,0 +1 @@ +TypeDoc added this file to prevent GitHub Pages from using Jekyll. You can turn off this behavior by setting the `githubPages` option to false. \ No newline at end of file diff --git a/docs/versioned_docs/version-v0.23.0/reference/NoirJS/backend_barretenberg/classes/BarretenbergBackend.md b/docs/versioned_docs/version-v0.23.0/reference/NoirJS/backend_barretenberg/classes/BarretenbergBackend.md new file mode 100644 index 00000000000..5cbe9421b92 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/reference/NoirJS/backend_barretenberg/classes/BarretenbergBackend.md @@ -0,0 +1,185 @@ +# BarretenbergBackend + +## Implements + +- [`Backend`](../interfaces/Backend.md) + +## Constructors + +### new BarretenbergBackend(acirCircuit, options) + +```ts +new BarretenbergBackend(acirCircuit, options): BarretenbergBackend +``` + +#### Parameters + +| Parameter | Type | +| :------ | :------ | +| `acirCircuit` | [`CompiledCircuit`](../type-aliases/CompiledCircuit.md) | +| `options` | [`BackendOptions`](../type-aliases/BackendOptions.md) | + +#### Returns + +[`BarretenbergBackend`](BarretenbergBackend.md) + +## Methods + +### destroy() + +```ts +destroy(): Promise +``` + +#### Returns + +`Promise`\<`void`\> + +#### Implementation of + +[`Backend`](../interfaces/Backend.md).[`destroy`](../interfaces/Backend.md#destroy) + +#### Description + +Destroys the backend + +*** + +### generateFinalProof() + +```ts +generateFinalProof(decompressedWitness): Promise +``` + +#### Parameters + +| Parameter | Type | +| :------ | :------ | +| `decompressedWitness` | `Uint8Array` | + +#### Returns + +`Promise`\<[`ProofData`](../type-aliases/ProofData.md)\> + +#### Implementation of + +[`Backend`](../interfaces/Backend.md).[`generateFinalProof`](../interfaces/Backend.md#generatefinalproof) + +#### Description + +Generates a final proof (not meant to be verified in another circuit) + +*** + +### generateIntermediateProof() + +```ts +generateIntermediateProof(witness): Promise +``` + +#### Parameters + +| Parameter | Type | +| :------ | :------ | +| `witness` | `Uint8Array` | + +#### Returns + +`Promise`\<[`ProofData`](../type-aliases/ProofData.md)\> + +#### Implementation of + +[`Backend`](../interfaces/Backend.md).[`generateIntermediateProof`](../interfaces/Backend.md#generateintermediateproof) + +#### Example + +```typescript +const intermediateProof = await backend.generateIntermediateProof(witness); +``` + +*** + +### generateIntermediateProofArtifacts() + +```ts +generateIntermediateProofArtifacts(proofData, numOfPublicInputs): Promise +``` + +#### Parameters + +| Parameter | Type | Default value | +| :------ | :------ | :------ | +| `proofData` | [`ProofData`](../type-aliases/ProofData.md) | `undefined` | +| `numOfPublicInputs` | `number` | `0` | + +#### Returns + +`Promise`\<`object`\> + +#### Implementation of + +[`Backend`](../interfaces/Backend.md).[`generateIntermediateProofArtifacts`](../interfaces/Backend.md#generateintermediateproofartifacts) + +#### Example + +```typescript +const artifacts = await backend.generateIntermediateProofArtifacts(proof, numOfPublicInputs); +``` + +*** + +### verifyFinalProof() + +```ts +verifyFinalProof(proofData): Promise +``` + +#### Parameters + +| Parameter | Type | +| :------ | :------ | +| `proofData` | [`ProofData`](../type-aliases/ProofData.md) | + +#### Returns + +`Promise`\<`boolean`\> + +#### Implementation of + +[`Backend`](../interfaces/Backend.md).[`verifyFinalProof`](../interfaces/Backend.md#verifyfinalproof) + +#### Description + +Verifies a final proof + +*** + +### verifyIntermediateProof() + +```ts +verifyIntermediateProof(proofData): Promise +``` + +#### Parameters + +| Parameter | Type | +| :------ | :------ | +| `proofData` | [`ProofData`](../type-aliases/ProofData.md) | + +#### Returns + +`Promise`\<`boolean`\> + +#### Implementation of + +[`Backend`](../interfaces/Backend.md).[`verifyIntermediateProof`](../interfaces/Backend.md#verifyintermediateproof) + +#### Example + +```typescript +const isValidIntermediate = await backend.verifyIntermediateProof(proof); +``` + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.23.0/reference/NoirJS/backend_barretenberg/index.md b/docs/versioned_docs/version-v0.23.0/reference/NoirJS/backend_barretenberg/index.md new file mode 100644 index 00000000000..e32501acb71 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/reference/NoirJS/backend_barretenberg/index.md @@ -0,0 +1,46 @@ +# backend_barretenberg + +## Exports + +### Classes + +| Class | Description | +| :------ | :------ | +| [BarretenbergBackend](classes/BarretenbergBackend.md) | - | + +### Interfaces + +| Interface | Description | +| :------ | :------ | +| [Backend](interfaces/Backend.md) | - | + +### Type Aliases + +| Type alias | Description | +| :------ | :------ | +| [BackendOptions](type-aliases/BackendOptions.md) | - | +| [CompiledCircuit](type-aliases/CompiledCircuit.md) | - | +| [ProofData](type-aliases/ProofData.md) | - | + +## Functions + +### publicInputsToWitnessMap() + +```ts +publicInputsToWitnessMap(publicInputs, abi): WitnessMap +``` + +#### Parameters + +| Parameter | Type | +| :------ | :------ | +| `publicInputs` | `string`[] | +| `abi` | `Abi` | + +#### Returns + +`WitnessMap` + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.23.0/reference/NoirJS/backend_barretenberg/interfaces/Backend.md b/docs/versioned_docs/version-v0.23.0/reference/NoirJS/backend_barretenberg/interfaces/Backend.md new file mode 100644 index 00000000000..3eb9645c8d2 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/reference/NoirJS/backend_barretenberg/interfaces/Backend.md @@ -0,0 +1,132 @@ +# Backend + +## Methods + +### destroy() + +```ts +destroy(): Promise +``` + +#### Returns + +`Promise`\<`void`\> + +#### Description + +Destroys the backend + +*** + +### generateFinalProof() + +```ts +generateFinalProof(decompressedWitness): Promise +``` + +#### Parameters + +| Parameter | Type | +| :------ | :------ | +| `decompressedWitness` | `Uint8Array` | + +#### Returns + +`Promise`\<[`ProofData`](../type-aliases/ProofData.md)\> + +#### Description + +Generates a final proof (not meant to be verified in another circuit) + +*** + +### generateIntermediateProof() + +```ts +generateIntermediateProof(decompressedWitness): Promise +``` + +#### Parameters + +| Parameter | Type | +| :------ | :------ | +| `decompressedWitness` | `Uint8Array` | + +#### Returns + +`Promise`\<[`ProofData`](../type-aliases/ProofData.md)\> + +#### Description + +Generates an intermediate proof (meant to be verified in another circuit) + +*** + +### generateIntermediateProofArtifacts() + +```ts +generateIntermediateProofArtifacts(proofData, numOfPublicInputs): Promise +``` + +#### Parameters + +| Parameter | Type | +| :------ | :------ | +| `proofData` | [`ProofData`](../type-aliases/ProofData.md) | +| `numOfPublicInputs` | `number` | + +#### Returns + +`Promise`\<`object`\> + +#### Description + +Retrieves the artifacts from a proof in the Field format + +*** + +### verifyFinalProof() + +```ts +verifyFinalProof(proofData): Promise +``` + +#### Parameters + +| Parameter | Type | +| :------ | :------ | +| `proofData` | [`ProofData`](../type-aliases/ProofData.md) | + +#### Returns + +`Promise`\<`boolean`\> + +#### Description + +Verifies a final proof + +*** + +### verifyIntermediateProof() + +```ts +verifyIntermediateProof(proofData): Promise +``` + +#### Parameters + +| Parameter | Type | +| :------ | :------ | +| `proofData` | [`ProofData`](../type-aliases/ProofData.md) | + +#### Returns + +`Promise`\<`boolean`\> + +#### Description + +Verifies an intermediate proof + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.23.0/reference/NoirJS/backend_barretenberg/type-aliases/BackendOptions.md b/docs/versioned_docs/version-v0.23.0/reference/NoirJS/backend_barretenberg/type-aliases/BackendOptions.md new file mode 100644 index 00000000000..266ade75d17 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/reference/NoirJS/backend_barretenberg/type-aliases/BackendOptions.md @@ -0,0 +1,19 @@ +# BackendOptions + +```ts +type BackendOptions: object; +``` + +## Description + +An options object, currently only used to specify the number of threads to use. + +## Type declaration + +| Member | Type | Description | +| :------ | :------ | :------ | +| `threads` | `number` | **Description**

Number of threads | + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.23.0/reference/NoirJS/backend_barretenberg/type-aliases/CompiledCircuit.md b/docs/versioned_docs/version-v0.23.0/reference/NoirJS/backend_barretenberg/type-aliases/CompiledCircuit.md new file mode 100644 index 00000000000..34e0dd04205 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/reference/NoirJS/backend_barretenberg/type-aliases/CompiledCircuit.md @@ -0,0 +1,20 @@ +# CompiledCircuit + +```ts +type CompiledCircuit: object; +``` + +## Description + +The representation of a compiled circuit + +## Type declaration + +| Member | Type | Description | +| :------ | :------ | :------ | +| `abi` | `Abi` | **Description**

ABI representation of the circuit | +| `bytecode` | `string` | **Description**

The bytecode of the circuit | + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.23.0/reference/NoirJS/backend_barretenberg/type-aliases/ProofData.md b/docs/versioned_docs/version-v0.23.0/reference/NoirJS/backend_barretenberg/type-aliases/ProofData.md new file mode 100644 index 00000000000..05cebbc4e94 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/reference/NoirJS/backend_barretenberg/type-aliases/ProofData.md @@ -0,0 +1,20 @@ +# ProofData + +```ts +type ProofData: object; +``` + +## Description + +The representation of a proof + +## Type declaration + +| Member | Type | Description | +| :------ | :------ | :------ | +| `proof` | `Uint8Array` | **Description**

An byte array representing the proof | +| `publicInputs` | `string`[] | **Description**

Public inputs of a proof | + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.23.0/reference/NoirJS/backend_barretenberg/typedoc-sidebar.cjs b/docs/versioned_docs/version-v0.23.0/reference/NoirJS/backend_barretenberg/typedoc-sidebar.cjs new file mode 100644 index 00000000000..2aaa55bccf6 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/reference/NoirJS/backend_barretenberg/typedoc-sidebar.cjs @@ -0,0 +1,4 @@ +// @ts-check +/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */ +const typedocSidebar = { items: [{"type":"category","label":"Classes","items":[{"type":"doc","id":"reference/NoirJS/backend_barretenberg/classes/BarretenbergBackend","label":"BarretenbergBackend"}]},{"type":"category","label":"Interfaces","items":[{"type":"doc","id":"reference/NoirJS/backend_barretenberg/interfaces/Backend","label":"Backend"}]},{"type":"category","label":"Type Aliases","items":[{"type":"doc","id":"reference/NoirJS/backend_barretenberg/type-aliases/BackendOptions","label":"BackendOptions"},{"type":"doc","id":"reference/NoirJS/backend_barretenberg/type-aliases/CompiledCircuit","label":"CompiledCircuit"},{"type":"doc","id":"reference/NoirJS/backend_barretenberg/type-aliases/ProofData","label":"ProofData"}]}]}; +module.exports = typedocSidebar.items; \ No newline at end of file diff --git a/docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/.nojekyll b/docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/.nojekyll new file mode 100644 index 00000000000..e2ac6616add --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/.nojekyll @@ -0,0 +1 @@ +TypeDoc added this file to prevent GitHub Pages from using Jekyll. You can turn off this behavior by setting the `githubPages` option to false. \ No newline at end of file diff --git a/docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/classes/Noir.md b/docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/classes/Noir.md new file mode 100644 index 00000000000..34e20d99684 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/classes/Noir.md @@ -0,0 +1,132 @@ +# Noir + +## Constructors + +### new Noir(circuit, backend) + +```ts +new Noir(circuit, backend?): Noir +``` + +#### Parameters + +| Parameter | Type | +| :------ | :------ | +| `circuit` | [`CompiledCircuit`](../type-aliases/CompiledCircuit.md) | +| `backend`? | `Backend` | + +#### Returns + +[`Noir`](Noir.md) + +## Methods + +### destroy() + +```ts +destroy(): Promise +``` + +#### Returns + +`Promise`\<`void`\> + +#### Description + +Destroys the underlying backend instance. + +#### Example + +```typescript +await noir.destroy(); +``` + +*** + +### execute() + +```ts +execute(inputs, foreignCallHandler?): Promise +``` + +#### Parameters + +| Parameter | Type | +| :------ | :------ | +| `inputs` | [`InputMap`](../type-aliases/InputMap.md) | +| `foreignCallHandler`? | [`ForeignCallHandler`](../type-aliases/ForeignCallHandler.md) | + +#### Returns + +`Promise`\<`object`\> + +#### Description + +Allows to execute a circuit to get its witness and return value. + +#### Example + +```typescript +async execute(inputs) +``` + +*** + +### generateFinalProof() + +```ts +generateFinalProof(inputs, foreignCallHandler?): Promise +``` + +#### Parameters + +| Parameter | Type | +| :------ | :------ | +| `inputs` | [`InputMap`](../type-aliases/InputMap.md) | +| `foreignCallHandler`? | [`ForeignCallHandler`](../type-aliases/ForeignCallHandler.md) | + +#### Returns + +`Promise`\<[`ProofData`](../type-aliases/ProofData.md)\> + +#### Description + +Generates a witness and a proof given an object as input. + +#### Example + +```typescript +async generateFinalProof(input) +``` + +*** + +### verifyFinalProof() + +```ts +verifyFinalProof(proofData): Promise +``` + +#### Parameters + +| Parameter | Type | +| :------ | :------ | +| `proofData` | [`ProofData`](../type-aliases/ProofData.md) | + +#### Returns + +`Promise`\<`boolean`\> + +#### Description + +Instantiates the verification key and verifies a proof. + +#### Example + +```typescript +async verifyFinalProof(proof) +``` + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/functions/and.md b/docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/functions/and.md new file mode 100644 index 00000000000..c783283e396 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/functions/and.md @@ -0,0 +1,22 @@ +# and() + +```ts +and(lhs, rhs): string +``` + +Performs a bitwise AND operation between `lhs` and `rhs` + +## Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `lhs` | `string` | | +| `rhs` | `string` | | + +## Returns + +`string` + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/functions/blake2s256.md b/docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/functions/blake2s256.md new file mode 100644 index 00000000000..7882d0da8d5 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/functions/blake2s256.md @@ -0,0 +1,21 @@ +# blake2s256() + +```ts +blake2s256(inputs): Uint8Array +``` + +Calculates the Blake2s256 hash of the input bytes + +## Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `inputs` | `Uint8Array` | | + +## Returns + +`Uint8Array` + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/functions/ecdsa_secp256k1_verify.md b/docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/functions/ecdsa_secp256k1_verify.md new file mode 100644 index 00000000000..5e3cd53e9d3 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/functions/ecdsa_secp256k1_verify.md @@ -0,0 +1,28 @@ +# ecdsa\_secp256k1\_verify() + +```ts +ecdsa_secp256k1_verify( + hashed_msg, + public_key_x_bytes, + public_key_y_bytes, + signature): boolean +``` + +Verifies a ECDSA signature over the secp256k1 curve. + +## Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `hashed_msg` | `Uint8Array` | | +| `public_key_x_bytes` | `Uint8Array` | | +| `public_key_y_bytes` | `Uint8Array` | | +| `signature` | `Uint8Array` | | + +## Returns + +`boolean` + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/functions/ecdsa_secp256r1_verify.md b/docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/functions/ecdsa_secp256r1_verify.md new file mode 100644 index 00000000000..0b20ff68957 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/functions/ecdsa_secp256r1_verify.md @@ -0,0 +1,28 @@ +# ecdsa\_secp256r1\_verify() + +```ts +ecdsa_secp256r1_verify( + hashed_msg, + public_key_x_bytes, + public_key_y_bytes, + signature): boolean +``` + +Verifies a ECDSA signature over the secp256r1 curve. + +## Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `hashed_msg` | `Uint8Array` | | +| `public_key_x_bytes` | `Uint8Array` | | +| `public_key_y_bytes` | `Uint8Array` | | +| `signature` | `Uint8Array` | | + +## Returns + +`boolean` + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/functions/keccak256.md b/docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/functions/keccak256.md new file mode 100644 index 00000000000..d10f155ce86 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/functions/keccak256.md @@ -0,0 +1,21 @@ +# keccak256() + +```ts +keccak256(inputs): Uint8Array +``` + +Calculates the Keccak256 hash of the input bytes + +## Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `inputs` | `Uint8Array` | | + +## Returns + +`Uint8Array` + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/functions/sha256.md b/docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/functions/sha256.md new file mode 100644 index 00000000000..6ba4ecac022 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/functions/sha256.md @@ -0,0 +1,21 @@ +# sha256() + +```ts +sha256(inputs): Uint8Array +``` + +Calculates the SHA256 hash of the input bytes + +## Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `inputs` | `Uint8Array` | | + +## Returns + +`Uint8Array` + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/functions/xor.md b/docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/functions/xor.md new file mode 100644 index 00000000000..8d762b895d3 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/functions/xor.md @@ -0,0 +1,22 @@ +# xor() + +```ts +xor(lhs, rhs): string +``` + +Performs a bitwise XOR operation between `lhs` and `rhs` + +## Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `lhs` | `string` | | +| `rhs` | `string` | | + +## Returns + +`string` + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/index.md b/docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/index.md new file mode 100644 index 00000000000..d600e21b299 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/index.md @@ -0,0 +1,37 @@ +# noir_js + +## Exports + +### Classes + +| Class | Description | +| :------ | :------ | +| [Noir](classes/Noir.md) | - | + +### Type Aliases + +| Type alias | Description | +| :------ | :------ | +| [CompiledCircuit](type-aliases/CompiledCircuit.md) | - | +| [ForeignCallHandler](type-aliases/ForeignCallHandler.md) | A callback which performs an foreign call and returns the response. | +| [ForeignCallInput](type-aliases/ForeignCallInput.md) | - | +| [ForeignCallOutput](type-aliases/ForeignCallOutput.md) | - | +| [InputMap](type-aliases/InputMap.md) | - | +| [ProofData](type-aliases/ProofData.md) | - | +| [WitnessMap](type-aliases/WitnessMap.md) | - | + +### Functions + +| Function | Description | +| :------ | :------ | +| [and](functions/and.md) | Performs a bitwise AND operation between `lhs` and `rhs` | +| [blake2s256](functions/blake2s256.md) | Calculates the Blake2s256 hash of the input bytes | +| [ecdsa\_secp256k1\_verify](functions/ecdsa_secp256k1_verify.md) | Verifies a ECDSA signature over the secp256k1 curve. | +| [ecdsa\_secp256r1\_verify](functions/ecdsa_secp256r1_verify.md) | Verifies a ECDSA signature over the secp256r1 curve. | +| [keccak256](functions/keccak256.md) | Calculates the Keccak256 hash of the input bytes | +| [sha256](functions/sha256.md) | Calculates the SHA256 hash of the input bytes | +| [xor](functions/xor.md) | Performs a bitwise XOR operation between `lhs` and `rhs` | + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/type-aliases/CompiledCircuit.md b/docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/type-aliases/CompiledCircuit.md new file mode 100644 index 00000000000..34e0dd04205 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/type-aliases/CompiledCircuit.md @@ -0,0 +1,20 @@ +# CompiledCircuit + +```ts +type CompiledCircuit: object; +``` + +## Description + +The representation of a compiled circuit + +## Type declaration + +| Member | Type | Description | +| :------ | :------ | :------ | +| `abi` | `Abi` | **Description**

ABI representation of the circuit | +| `bytecode` | `string` | **Description**

The bytecode of the circuit | + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/type-aliases/ForeignCallHandler.md b/docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/type-aliases/ForeignCallHandler.md new file mode 100644 index 00000000000..812b8b16481 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/type-aliases/ForeignCallHandler.md @@ -0,0 +1,24 @@ +# ForeignCallHandler + +```ts +type ForeignCallHandler: (name, inputs) => Promise; +``` + +A callback which performs an foreign call and returns the response. + +## Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `name` | `string` | The identifier for the type of foreign call being performed. | +| `inputs` | [`ForeignCallInput`](ForeignCallInput.md)[] | An array of hex encoded inputs to the foreign call. | + +## Returns + +`Promise`\<[`ForeignCallOutput`](ForeignCallOutput.md)[]\> + +outputs - An array of hex encoded outputs containing the results of the foreign call. + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/type-aliases/ForeignCallInput.md b/docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/type-aliases/ForeignCallInput.md new file mode 100644 index 00000000000..dd95809186a --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/type-aliases/ForeignCallInput.md @@ -0,0 +1,9 @@ +# ForeignCallInput + +```ts +type ForeignCallInput: string[]; +``` + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/type-aliases/ForeignCallOutput.md b/docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/type-aliases/ForeignCallOutput.md new file mode 100644 index 00000000000..b71fb78a946 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/type-aliases/ForeignCallOutput.md @@ -0,0 +1,9 @@ +# ForeignCallOutput + +```ts +type ForeignCallOutput: string | string[]; +``` + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/type-aliases/InputMap.md b/docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/type-aliases/InputMap.md new file mode 100644 index 00000000000..c714e999d93 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/type-aliases/InputMap.md @@ -0,0 +1,13 @@ +# InputMap + +```ts +type InputMap: object; +``` + +## Index signature + + \[`key`: `string`\]: `InputValue` + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/type-aliases/ProofData.md b/docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/type-aliases/ProofData.md new file mode 100644 index 00000000000..05cebbc4e94 --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/type-aliases/ProofData.md @@ -0,0 +1,20 @@ +# ProofData + +```ts +type ProofData: object; +``` + +## Description + +The representation of a proof + +## Type declaration + +| Member | Type | Description | +| :------ | :------ | :------ | +| `proof` | `Uint8Array` | **Description**

An byte array representing the proof | +| `publicInputs` | `string`[] | **Description**

Public inputs of a proof | + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/type-aliases/WitnessMap.md b/docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/type-aliases/WitnessMap.md new file mode 100644 index 00000000000..258c46f9d0c --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/type-aliases/WitnessMap.md @@ -0,0 +1,9 @@ +# WitnessMap + +```ts +type WitnessMap: Map; +``` + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/typedoc-sidebar.cjs b/docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/typedoc-sidebar.cjs new file mode 100644 index 00000000000..fe2629ddc9f --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/reference/NoirJS/noir_js/typedoc-sidebar.cjs @@ -0,0 +1,4 @@ +// @ts-check +/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */ +const typedocSidebar = { items: [{"type":"category","label":"Classes","items":[{"type":"doc","id":"reference/NoirJS/noir_js/classes/Noir","label":"Noir"}]},{"type":"category","label":"Type Aliases","items":[{"type":"doc","id":"reference/NoirJS/noir_js/type-aliases/CompiledCircuit","label":"CompiledCircuit"},{"type":"doc","id":"reference/NoirJS/noir_js/type-aliases/ForeignCallHandler","label":"ForeignCallHandler"},{"type":"doc","id":"reference/NoirJS/noir_js/type-aliases/ForeignCallInput","label":"ForeignCallInput"},{"type":"doc","id":"reference/NoirJS/noir_js/type-aliases/ForeignCallOutput","label":"ForeignCallOutput"},{"type":"doc","id":"reference/NoirJS/noir_js/type-aliases/InputMap","label":"InputMap"},{"type":"doc","id":"reference/NoirJS/noir_js/type-aliases/ProofData","label":"ProofData"},{"type":"doc","id":"reference/NoirJS/noir_js/type-aliases/WitnessMap","label":"WitnessMap"}]},{"type":"category","label":"Functions","items":[{"type":"doc","id":"reference/NoirJS/noir_js/functions/and","label":"and"},{"type":"doc","id":"reference/NoirJS/noir_js/functions/blake2s256","label":"blake2s256"},{"type":"doc","id":"reference/NoirJS/noir_js/functions/ecdsa_secp256k1_verify","label":"ecdsa_secp256k1_verify"},{"type":"doc","id":"reference/NoirJS/noir_js/functions/ecdsa_secp256r1_verify","label":"ecdsa_secp256r1_verify"},{"type":"doc","id":"reference/NoirJS/noir_js/functions/keccak256","label":"keccak256"},{"type":"doc","id":"reference/NoirJS/noir_js/functions/sha256","label":"sha256"},{"type":"doc","id":"reference/NoirJS/noir_js/functions/xor","label":"xor"}]}]}; +module.exports = typedocSidebar.items; \ No newline at end of file diff --git a/docs/versioned_docs/version-v0.23.0/reference/_category_.json b/docs/versioned_docs/version-v0.23.0/reference/_category_.json new file mode 100644 index 00000000000..5b6a20a609a --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/reference/_category_.json @@ -0,0 +1,5 @@ +{ + "position": 4, + "collapsible": true, + "collapsed": true +} diff --git a/docs/versioned_docs/version-v0.23.0/reference/nargo_commands.md b/docs/versioned_docs/version-v0.23.0/reference/nargo_commands.md new file mode 100644 index 00000000000..fc2671b2bfc --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/reference/nargo_commands.md @@ -0,0 +1,253 @@ +--- +title: Nargo +description: + Noir CLI Commands for Noir Prover and Verifier to create, execute, prove and verify programs, + generate Solidity verifier smart contract and compile into JSON file containing ACIR + representation and ABI of circuit. +keywords: + [ + Nargo, + Noir CLI, + Noir Prover, + Noir Verifier, + generate Solidity verifier, + compile JSON file, + ACIR representation, + ABI of circuit, + TypeScript, + ] +sidebar_position: 0 +--- + +## General options + +| Option | Description | +| -------------------- | -------------------------------------------------- | +| `--show-ssa` | Emit debug information for the intermediate SSA IR | +| `--deny-warnings` | Quit execution when warnings are emitted | +| `--silence-warnings` | Suppress warnings | +| `-h, --help` | Print help | + +## `nargo help [subcommand]` + +Prints the list of available commands or specific information of a subcommand. + +_Arguments_ + +| Argument | Description | +| -------------- | -------------------------------------------- | +| `` | The subcommand whose help message to display | + +## `nargo backend` + +Installs and selects custom backends used to generate and verify proofs. + +### Commands + +| Command | Description | +| ----------- | --------------------------------------------------------- | +| `current` | Prints the name of the currently active backend | +| `ls` | Prints the list of currently installed backends | +| `use` | Select the backend to use | +| `install` | Install a new backend from a URL | +| `uninstall` | Uninstalls a backend | +| `help` | Print this message or the help of the given subcommand(s) | + +### Options + +| Option | Description | +| ------------ | ----------- | +| `-h, --help` | Print help | + +## `nargo check` + +Generate the `Prover.toml` and `Verifier.toml` files for specifying prover and verifier in/output +values of the Noir program respectively. + +### Options + +| Option | Description | +| --------------------- | ------------------------------------- | +| `--package ` | The name of the package to check | +| `--workspace` | Check all packages in the workspace | +| `--print-acir` | Display the ACIR for compiled circuit | +| `--deny-warnings` | Treat all warnings as errors | +| `--silence-warnings` | Suppress warnings | +| `-h, --help` | Print help | + +### `nargo codegen-verifier` + +Generate a Solidity verifier smart contract for the program. + +### Options + +| Option | Description | +| --------------------- | ------------------------------------- | +| `--package ` | The name of the package to codegen | +| `--workspace` | Codegen all packages in the workspace | +| `--print-acir` | Display the ACIR for compiled circuit | +| `--deny-warnings` | Treat all warnings as errors | +| `--silence-warnings` | Suppress warnings | +| `-h, --help` | Print help | + +## `nargo compile` + +Compile the program into a JSON build artifact file containing the ACIR representation and the ABI +of the circuit. This build artifact can then be used to generate and verify proofs. + +You can also use "build" as an alias for compile (e.g. `nargo build`). + +### Options + +| Option | Description | +| --------------------- | ------------------------------------------------------------ | +| `--package ` | The name of the package to compile | +| `--workspace` | Compile all packages in the workspace | +| `--print-acir` | Display the ACIR for compiled circuit | +| `--deny-warnings` | Treat all warnings as errors | +| `--silence-warnings` | Suppress warnings | +| `-h, --help` | Print help | + +## `nargo new ` + +Creates a new Noir project in a new folder. + +**Arguments** + +| Argument | Description | +| -------- | -------------------------------- | +| `` | The path to save the new project | + +### Options + +| Option | Description | +| --------------- | ----------------------------------------------------- | +| `--name ` | Name of the package [default: package directory name] | +| `--lib` | Use a library template | +| `--bin` | Use a binary template [default] | +| `--contract` | Use a contract template | +| `-h, --help` | Print help | + +## `nargo init` + +Creates a new Noir project in the current directory. + +### Options + +| Option | Description | +| --------------- | ----------------------------------------------------- | +| `--name ` | Name of the package [default: current directory name] | +| `--lib` | Use a library template | +| `--bin` | Use a binary template [default] | +| `--contract` | Use a contract template | +| `-h, --help` | Print help | + +## `nargo execute [WITNESS_NAME]` + +Runs the Noir program and prints its return value. + +**Arguments** + +| Argument | Description | +| ---------------- | ----------------------------------------- | +| `[WITNESS_NAME]` | Write the execution witness to named file | + +### Options + +| Option | Description | +| --------------------------------- | ------------------------------------------------------------------------------------ | +| `-p, --prover-name ` | The name of the toml file which contains the inputs for the prover [default: Prover] | +| `--package ` | The name of the package to execute | +| `--workspace` | Execute all packages in the workspace | +| `--print-acir` | Display the ACIR for compiled circuit | +| `--deny-warnings` | Treat all warnings as errors | +| `--silence-warnings` | Suppress warnings | +| `--oracle-resolver` | JSON RPC url to solve oracle calls | +| `-h, --help` | Print help | + +_Usage_ + +The inputs to the circuit are read from the `Prover.toml` file generated by `nargo check`, which +must be filled in. + +To save the witness to file, run the command with a value for the `WITNESS_NAME` argument. A +`.tr` file will then be saved in the `./target` folder. + +## `nargo prove` + +Creates a proof for the program. + +### Options + +| Option | Description | +| ------------------------------------- | ---------------------------------------------------------------------------------------- | +| `-p, --prover-name ` | The name of the toml file which contains the inputs for the prover [default: Prover] | +| `-v, --verifier-name ` | The name of the toml file which contains the inputs for the verifier [default: Verifier] | +| `--verify` | Verify proof after proving | +| `--package ` | The name of the package to prove | +| `--workspace` | Prove all packages in the workspace | +| `--print-acir` | Display the ACIR for compiled circuit | +| `--deny-warnings` | Treat all warnings as errors | +| `--silence-warnings` | Suppress warnings | +| `--oracle-resolver` | JSON RPC url to solve oracle calls | +| `-h, --help` | Print help | + +## `nargo verify` + +Given a proof and a program, verify whether the proof is valid. + +### Options + +| Option | Description | +| ------------------------------------- | ---------------------------------------------------------------------------------------- | +| `-v, --verifier-name ` | The name of the toml file which contains the inputs for the verifier [default: Verifier] | +| `--package ` | The name of the package to verify | +| `--workspace` | Verify all packages in the workspace | +| `--print-acir` | Display the ACIR for compiled circuit | +| `--deny-warnings` | Treat all warnings as errors | +| `--silence-warnings` | Suppress warnings | +| `-h, --help` | Print help | + +## `nargo test [TEST_NAME]` + +Nargo will automatically compile and run any functions which have the decorator `#[test]` on them if +you run `nargo test`. To print `println` statements in tests, use the `--show-output` flag. + +Takes an optional `--exact` flag which allows you to select tests based on an exact name. + +See an example on the [testing page](../getting_started/tooling/testing.md). + +### Options + +| Option | Description | +| --------------------- | -------------------------------------- | +| `--show-output` | Display output of `println` statements | +| `--exact` | Only run tests that match exactly | +| `--package ` | The name of the package to test | +| `--workspace` | Test all packages in the workspace | +| `--print-acir` | Display the ACIR for compiled circuit | +| `--deny-warnings` | Treat all warnings as errors | +| `--silence-warnings` | Suppress warnings | +| `--oracle-resolver` | JSON RPC url to solve oracle calls | +| `-h, --help` | Print help | + +## `nargo info` + +Prints a table containing the information of the package. + +Currently the table provide + +1. The number of ACIR opcodes +2. The final number gates in the circuit used by a backend + +If the file contains a contract the table will provide the +above information about each function of the contract. + +## `nargo lsp` + +Start a long-running Language Server process that communicates over stdin/stdout. +Usually this command is not run by a user, but instead will be run by a Language Client, such as [vscode-noir](https://github.com/noir-lang/vscode-noir). + +## `nargo fmt` + +Automatically formats your Noir source code based on the default formatting settings. diff --git a/docs/versioned_docs/version-v0.23.0/tutorials/noirjs_app.md b/docs/versioned_docs/version-v0.23.0/tutorials/noirjs_app.md new file mode 100644 index 00000000000..23534795dde --- /dev/null +++ b/docs/versioned_docs/version-v0.23.0/tutorials/noirjs_app.md @@ -0,0 +1,279 @@ +--- +title: Building a web app with NoirJS +description: Learn how to setup a new app that uses Noir to generate and verify zero-knowledge SNARK proofs in a typescript or javascript environment. +keywords: [how to, guide, javascript, typescript, noir, barretenberg, zero-knowledge, proofs, app] +sidebar_position: 0 +pagination_next: noir/concepts/data_types/index +--- + +NoirJS is a set of packages meant to work both in a browser and a server environment. In this tutorial, we will build a simple web app using them. From here, you should get an idea on how to proceed with your own Noir projects! + +You can find the complete app code for this guide [here](https://github.com/noir-lang/tiny-noirjs-app). + +## Setup + +:::note + +Feel free to use whatever versions, just keep in mind that Nargo and the NoirJS packages are meant to be in sync. For example, Nargo 0.19.x matches `noir_js@0.19.x`, etc. + +In this guide, we will be pinned to 0.19.4. + +::: + +Before we start, we want to make sure we have Node and Nargo installed. + +We start by opening a terminal and executing `node --version`. If we don't get an output like `v20.10.0`, that means node is not installed. Let's do that by following the handy [nvm guide](https://github.com/nvm-sh/nvm?tab=readme-ov-file#install--update-script). + +As for `Nargo`, we can follow the the [Nargo guide](../getting_started/installation/index.md) to install it. If you're lazy, just paste this on a terminal and run `noirup`: + +```sh +curl -L https://raw.githubusercontent.com/noir-lang/noirup/main/install | bash +``` + +Easy enough. Onwards! + +## Our project + +ZK is a powerful technology. An app that doesn't reveal one of the inputs to *anyone* is almost unbelievable, yet Noir makes it as easy as a single line of code. + +In fact, it's so simple that it comes nicely packaged in `nargo`. Let's do that! + +### Nargo + +Run: + +```nargo new circuit``` + +And... That's about it. Your program is ready to be compiled and run. + +To compile, let's `cd` into the `circuit` folder to enter our project, and call: + +```nargo compile``` + +This compiles our circuit into `json` format and add it to a new `target` folder. + +:::info + +At this point in the tutorial, your folder structure should look like this: + +```tree +. +└── circuit <---- our working directory + ├── Nargo.toml + ├── src + │ └── main.nr + └── target + └── circuit.json +``` + +::: + +### Node and Vite + +If you want to explore Nargo, feel free to go on a side-quest now and follow the steps in the +[getting started](../getting_started/hello_noir/index.md) guide. However, we want our app to run on the browser, so we need Vite. + +Vite is a powerful tool to generate static websites. While it provides all kinds of features, let's just go barebones with some good old vanilla JS. + +To do this this, go back to the previous folder (`cd ..`) and create a new vite project by running `npm create vite` and choosing "Vanilla" and "Javascript". + +You should see `vite-project` appear in your root folder. This seems like a good time to `cd` into it and install our NoirJS packages: + +```bash +npm i @noir-lang/backend_barretenberg@0.19.4 @noir-lang/noir_js@0.19.4 +``` + +:::info + +At this point in the tutorial, your folder structure should look like this: + +```tree +. +└── circuit + └── ...etc... +└── vite-project <---- our working directory + └── ...etc... +``` + +::: + +#### Some cleanup + +`npx create vite` is amazing but it creates a bunch of files we don't really need for our simple example. Actually, let's just delete everything except for `index.html`, `main.js` and `package.json`. I feel lighter already. + +![my heart is ready for you, noir.js](../../static/img/memes/titanic.jpeg) + +## HTML + +Our app won't run like this, of course. We need some working HTML, at least. Let's open our broken-hearted `index.html` and replace everything with this code snippet: + +```html + + + + + + +

Noir app

+
+ + +
+
+

Logs

+

Proof

+
+ + +``` + +It *could* be a beautiful UI... Depending on which universe you live in. + +## Some good old vanilla Javascript + +Our love for Noir needs undivided attention, so let's just open `main.js` and delete everything (this is where the romantic scenery becomes a bit creepy). + +Start by pasting in this boilerplate code: + +```js +const setup = async () => { + await Promise.all([ + import("@noir-lang/noirc_abi").then(module => + module.default(new URL("@noir-lang/noirc_abi/web/noirc_abi_wasm_bg.wasm", import.meta.url).toString()) + ), + import("@noir-lang/acvm_js").then(module => + module.default(new URL("@noir-lang/acvm_js/web/acvm_js_bg.wasm", import.meta.url).toString()) + ) + ]); +} + +function display(container, msg) { + const c = document.getElementById(container); + const p = document.createElement('p'); + p.textContent = msg; + c.appendChild(p); +} + +document.getElementById('submitGuess').addEventListener('click', async () => { + try { + // here's where love happens + } catch(err) { + display("logs", "Oh 💔 Wrong guess") + } +}); + +``` + +The display function doesn't do much. We're simply manipulating our website to see stuff happening. For example, if the proof fails, it will simply log a broken heart 😢 + +As for the `setup` function, it's just a sad reminder that dealing with `wasm` on the browser is not as easy as it should. Just copy, paste, and forget. + +:::info + +At this point in the tutorial, your folder structure should look like this: + +```tree +. +└── circuit + └── ...same as above +└── vite-project + ├── main.js + ├── package.json + └── index.html +``` + +You'll see other files and folders showing up (like `package-lock.json`, `node_modules`) but you shouldn't have to care about those. + +::: + +## Some NoirJS + +We're starting with the good stuff now. If you've compiled the circuit as described above, you should have a `json` file we want to import at the very top of our `main.js` file: + +```ts +import circuit from '../circuit/target/circuit.json'; +``` + +[Noir is backend-agnostic](../index.mdx#whats-new-about-noir). We write Noir, but we also need a proving backend. That's why we need to import and instantiate the two dependencies we installed above: `BarretenbergBackend` and `Noir`. Let's import them right below: + +```js +import { BarretenbergBackend } from '@noir-lang/backend_barretenberg'; +import { Noir } from '@noir-lang/noir_js'; +``` + +And instantiate them inside our try-catch block: + +```ts +// try { +const backend = new BarretenbergBackend(circuit); +const noir = new Noir(circuit, backend); +// } +``` + +:::note + +For the remainder of the tutorial, everything will be happening inside the `try` block + +::: + +## Our app + +Now for the app itself. We're capturing whatever is in the input when people press the submit button. Just add this: + +```js +const x = parseInt(document.getElementById('guessInput').value); +const input = { x, y: 2 }; +``` + +Now we're ready to prove stuff! Let's feed some inputs to our circuit and calculate the proof: + +```js +await setup(); // let's squeeze our wasm inits here + +display('logs', 'Generating proof... ⌛'); +const proof = await noir.generateFinalProof(input); +display('logs', 'Generating proof... ✅'); +display('results', proof.proof); +``` + +You're probably eager to see stuff happening, so go and run your app now! + +From your terminal, run `npm run dev`. If it doesn't open a browser for you, just visit `localhost:5173`. You should now see the worst UI ever, with an ugly input. + +![Getting Started 0](@site/static/img/noir_getting_started_1.png) + +Now, our circuit says `fn main(x: Field, y: pub Field)`. This means only the `y` value is public, and it's hardcoded above: `input = { x, y: 2 }`. In other words, you won't need to send your secret`x` to the verifier! + +By inputting any number other than 2 in the input box and clicking "submit", you should get a valid proof. Otherwise the proof won't even generate correctly. By the way, if you're human, you shouldn't be able to understand anything on the "proof" box. That's OK. We like you, human ❤️. + +## Verifying + +Time to celebrate, yes! But we shouldn't trust machines so blindly. Let's add these lines to see our proof being verified: + +```js +display('logs', 'Verifying proof... ⌛'); +const verification = await noir.verifyFinalProof(proof); +if (verification) display('logs', 'Verifying proof... ✅'); +``` + +You have successfully generated a client-side Noir web app! + +![coded app without math knowledge](../../static/img/memes/flextape.jpeg) + +## Further Reading + +You can see how noirjs is used in a full stack Next.js hardhat application in the [noir-starter repo here](https://github.com/noir-lang/noir-starter/tree/main/vite-hardhat). The example shows how to calculate a proof in the browser and verify it with a deployed Solidity verifier contract from noirjs. + +You should also check out the more advanced examples in the [noir-examples repo](https://github.com/noir-lang/noir-examples), where you'll find reference usage for some cool apps. diff --git a/docs/versioned_sidebars/version-v0.23.0-sidebars.json b/docs/versioned_sidebars/version-v0.23.0-sidebars.json new file mode 100644 index 00000000000..b16f79cc176 --- /dev/null +++ b/docs/versioned_sidebars/version-v0.23.0-sidebars.json @@ -0,0 +1,83 @@ +{ + "sidebar": [ + { + "type": "doc", + "id": "index" + }, + { + "type": "category", + "label": "Getting Started", + "items": [ + { + "type": "autogenerated", + "dirName": "getting_started" + } + ] + }, + { + "type": "category", + "label": "The Noir Language", + "items": [ + { + "type": "autogenerated", + "dirName": "noir" + } + ] + }, + { + "type": "html", + "value": "
", + "defaultStyle": true + }, + { + "type": "category", + "label": "How To Guides", + "items": [ + { + "type": "autogenerated", + "dirName": "how_to" + } + ] + }, + { + "type": "category", + "label": "Explainers", + "items": [ + { + "type": "autogenerated", + "dirName": "explainers" + } + ] + }, + { + "type": "category", + "label": "Tutorials", + "items": [ + { + "type": "autogenerated", + "dirName": "tutorials" + } + ] + }, + { + "type": "category", + "label": "Reference", + "items": [ + { + "type": "autogenerated", + "dirName": "reference" + } + ] + }, + { + "type": "html", + "value": "
", + "defaultStyle": true + }, + { + "type": "doc", + "id": "migration_notes", + "label": "Migration notes" + } + ] +} From eb6fc0f3658bf126ed38d7aec7ee3f44ee0533b5 Mon Sep 17 00:00:00 2001 From: jfecher Date: Tue, 23 Jan 2024 09:13:01 -0800 Subject: [PATCH 22/70] fix: apply generic arguments from trait constraints before instantiating identifiers (#4121) # Description ## Problem\* Resolves #4088 ## Summary\* We were calling `instantiate` on identifiers before applying any trait constraints. So if we have a constraint like `Foo` (referring to the trait `trait Foo { ... }`, and an identifier `foo : forall T. fn(T)`, we need to apply the `T = Field` constraint before instantiating `foo` to replace `T` with a fresh type variable. ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --------- Co-authored-by: Maxim Vezenov --- .../src/hir/resolution/resolver.rs | 5 +- .../noirc_frontend/src/hir/type_check/expr.rs | 110 ++++++++++-------- .../regression_4088/Nargo.toml | 5 + .../regression_4088/Prover.toml | 2 + .../regression_4088/src/main.nr | 27 +++++ 5 files changed, 101 insertions(+), 48 deletions(-) create mode 100644 test_programs/execution_success/regression_4088/Nargo.toml create mode 100644 test_programs/execution_success/regression_4088/Prover.toml create mode 100644 test_programs/execution_success/regression_4088/src/main.nr diff --git a/compiler/noirc_frontend/src/hir/resolution/resolver.rs b/compiler/noirc_frontend/src/hir/resolution/resolver.rs index 492e96a4715..f3e3b221036 100644 --- a/compiler/noirc_frontend/src/hir/resolution/resolver.rs +++ b/compiler/noirc_frontend/src/hir/resolution/resolver.rs @@ -1746,7 +1746,8 @@ impl<'a> Resolver<'a> { // This resolves a static trait method T::trait_method by iterating over the where clause // - // Returns the trait method, object type, and the trait generics. + // Returns the trait method, trait constraint, and whether the impl is assumed from a where + // clause. This is always true since this helper searches where clauses for a generic constraint. // E.g. `t.method()` with `where T: Foo` in scope will return `(Foo::method, T, vec![Bar])` fn resolve_trait_method_by_named_generic( &mut self, @@ -1789,7 +1790,7 @@ impl<'a> Resolver<'a> { // Try to resolve the given trait method path. // - // Returns the trait method, object type, and the trait generics. + // Returns the trait method, trait constraint, and whether the impl is assumed to exist by a where clause or not // E.g. `t.method()` with `where T: Foo` in scope will return `(Foo::method, T, vec![Bar])` fn resolve_trait_generic_path( &mut self, diff --git a/compiler/noirc_frontend/src/hir/type_check/expr.rs b/compiler/noirc_frontend/src/hir/type_check/expr.rs index 58cf4e7b289..22baa9f0da5 100644 --- a/compiler/noirc_frontend/src/hir/type_check/expr.rs +++ b/compiler/noirc_frontend/src/hir/type_check/expr.rs @@ -5,8 +5,8 @@ use crate::{ hir::{resolution::resolver::verify_mutable_reference, type_check::errors::Source}, hir_def::{ expr::{ - self, HirArrayLiteral, HirBinaryOp, HirExpression, HirLiteral, HirMethodCallExpression, - HirMethodReference, HirPrefixExpression, ImplKind, + self, HirArrayLiteral, HirBinaryOp, HirExpression, HirIdent, HirLiteral, + HirMethodCallExpression, HirMethodReference, HirPrefixExpression, ImplKind, }, types::Type, }, @@ -46,50 +46,7 @@ impl<'interner> TypeChecker<'interner> { /// function `foo` to refer to. pub(crate) fn check_expression(&mut self, expr_id: &ExprId) -> Type { let typ = match self.interner.expression(expr_id) { - HirExpression::Ident(ident) => { - // An identifiers type may be forall-quantified in the case of generic functions. - // E.g. `fn foo(t: T, field: Field) -> T` has type `forall T. fn(T, Field) -> T`. - // We must instantiate identifiers at every call site to replace this T with a new type - // variable to handle generic functions. - let t = self.interner.id_type_substitute_trait_as_type(ident.id); - - // This instantiate's a trait's generics as well which need to be set - // when the constraint below is later solved for when the function is - // finished. How to link the two? - let (typ, bindings) = t.instantiate(self.interner); - - // Push any trait constraints required by this definition to the context - // to be checked later when the type of this variable is further constrained. - if let Some(definition) = self.interner.try_definition(ident.id) { - if let DefinitionKind::Function(function) = definition.kind { - let function = self.interner.function_meta(&function); - - for mut constraint in function.trait_constraints.clone() { - constraint.apply_bindings(&bindings); - self.trait_constraints.push((constraint, *expr_id)); - } - } - } - - if let ImplKind::TraitMethod(_, mut constraint, assumed) = ident.impl_kind { - constraint.apply_bindings(&bindings); - if assumed { - let trait_impl = TraitImplKind::Assumed { - object_type: constraint.typ, - trait_generics: constraint.trait_generics, - }; - self.interner.select_impl_for_expression(*expr_id, trait_impl); - } else { - // Currently only one impl can be selected per expr_id, so this - // constraint needs to be pushed after any other constraints so - // that monomorphization can resolve this trait method to the correct impl. - self.trait_constraints.push((constraint, *expr_id)); - } - } - - self.interner.store_instantiation_bindings(*expr_id, bindings); - typ - } + HirExpression::Ident(ident) => self.check_ident(ident, expr_id), HirExpression::Literal(literal) => { match literal { HirLiteral::Array(HirArrayLiteral::Standard(arr)) => { @@ -341,6 +298,67 @@ impl<'interner> TypeChecker<'interner> { typ } + /// Returns the type of the given identifier + fn check_ident(&mut self, ident: HirIdent, expr_id: &ExprId) -> Type { + let mut bindings = TypeBindings::new(); + + // Add type bindings from any constraints that were used. + // We need to do this first since otherwise instantiating the type below + // will replace each trait generic with a fresh type variable, rather than + // the type used in the trait constraint (if it exists). See #4088. + if let ImplKind::TraitMethod(_, constraint, _) = &ident.impl_kind { + let the_trait = self.interner.get_trait(constraint.trait_id); + assert_eq!(the_trait.generics.len(), constraint.trait_generics.len()); + + for (param, arg) in the_trait.generics.iter().zip(&constraint.trait_generics) { + bindings.insert(param.id(), (param.clone(), arg.clone())); + } + } + + // An identifiers type may be forall-quantified in the case of generic functions. + // E.g. `fn foo(t: T, field: Field) -> T` has type `forall T. fn(T, Field) -> T`. + // We must instantiate identifiers at every call site to replace this T with a new type + // variable to handle generic functions. + let t = self.interner.id_type_substitute_trait_as_type(ident.id); + + // This instantiates a trait's generics as well which need to be set + // when the constraint below is later solved for when the function is + // finished. How to link the two? + let (typ, bindings) = t.instantiate_with_bindings(bindings, self.interner); + + // Push any trait constraints required by this definition to the context + // to be checked later when the type of this variable is further constrained. + if let Some(definition) = self.interner.try_definition(ident.id) { + if let DefinitionKind::Function(function) = definition.kind { + let function = self.interner.function_meta(&function); + + for mut constraint in function.trait_constraints.clone() { + constraint.apply_bindings(&bindings); + self.trait_constraints.push((constraint, *expr_id)); + } + } + } + + if let ImplKind::TraitMethod(_, mut constraint, assumed) = ident.impl_kind { + constraint.apply_bindings(&bindings); + if assumed { + let trait_impl = TraitImplKind::Assumed { + object_type: constraint.typ, + trait_generics: constraint.trait_generics, + }; + self.interner.select_impl_for_expression(*expr_id, trait_impl); + } else { + // Currently only one impl can be selected per expr_id, so this + // constraint needs to be pushed after any other constraints so + // that monomorphization can resolve this trait method to the correct impl. + self.trait_constraints.push((constraint, *expr_id)); + } + } + + self.interner.store_instantiation_bindings(*expr_id, bindings); + typ + } + pub fn verify_trait_constraint( &mut self, object_type: &Type, diff --git a/test_programs/execution_success/regression_4088/Nargo.toml b/test_programs/execution_success/regression_4088/Nargo.toml new file mode 100644 index 00000000000..a5e7832b734 --- /dev/null +++ b/test_programs/execution_success/regression_4088/Nargo.toml @@ -0,0 +1,5 @@ +[package] +name = "regression_4088" +type = "bin" +authors = [""] +[dependencies] diff --git a/test_programs/execution_success/regression_4088/Prover.toml b/test_programs/execution_success/regression_4088/Prover.toml new file mode 100644 index 00000000000..839e31e7e40 --- /dev/null +++ b/test_programs/execution_success/regression_4088/Prover.toml @@ -0,0 +1,2 @@ +[note] +value = 0 diff --git a/test_programs/execution_success/regression_4088/src/main.nr b/test_programs/execution_success/regression_4088/src/main.nr new file mode 100644 index 00000000000..9e4d7892fc3 --- /dev/null +++ b/test_programs/execution_success/regression_4088/src/main.nr @@ -0,0 +1,27 @@ +trait Serialize { + fn serialize(self) -> [Field; N]; +} + +struct ValueNote { + value: Field, +} + +impl Serialize<1> for ValueNote { + fn serialize(self) -> [Field; 1] { + [self.value] + } +} + +fn check(serialized_note: [Field; N]) { + assert(serialized_note[0] == 0); +} + +fn oopsie(note: Note) where Note: Serialize { + let serialized_note = Note::serialize(note); + + check(serialized_note) +} + +fn main(mut note: ValueNote) { + oopsie(note); +} From 9ba2de6143cd678b8656a84fab890e836257a13d Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Tue, 23 Jan 2024 17:37:36 +0000 Subject: [PATCH 23/70] feat: disable constraint bubbling pass (#4131) # Description ## Problem\* Resolves ## Summary\* RIP `bubble_up_constrains` 2024-2024 ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- compiler/noirc_evaluator/src/ssa.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/compiler/noirc_evaluator/src/ssa.rs b/compiler/noirc_evaluator/src/ssa.rs index e2da5652faf..0e3076923e0 100644 --- a/compiler/noirc_evaluator/src/ssa.rs +++ b/compiler/noirc_evaluator/src/ssa.rs @@ -63,7 +63,6 @@ pub(crate) fn optimize_into_acir( .run_pass(Ssa::mem2reg, "After Mem2Reg:") .run_pass(Ssa::fold_constants, "After Constant Folding:") .run_pass(Ssa::dead_instruction_elimination, "After Dead Instruction Elimination:") - .run_pass(Ssa::bubble_up_constrains, "After Constraint Bubbling:") .finish(); let brillig = ssa.to_brillig(print_brillig_trace); From 2645c101c187633e93784a6c83e9b599245a44b1 Mon Sep 17 00:00:00 2001 From: Michael J Klein Date: Tue, 23 Jan 2024 15:53:08 -0500 Subject: [PATCH 24/70] chore: convert vec references to slices (#4133) # Description Converts usages of `&Vec` to `&[T]` ## Problem\* Resolves https://github.com/noir-lang/noir/issues/679 ## Summary\* `&Vec` can be dereferenced into `&[T]` whereas `&[T]` is more general. In all but the following two cases, the type can simply be changed: 1. Both `clone` and `to_vec` perform a copy: ```rust VMStatus::Finished => Some((vm.get_registers().clone(), vm.get_memory().clone())), VMStatus::Finished => Some((vm.get_registers().clone(), vm.get_memory().to_vec())), ``` 2. Both perform a match on the `Option`: ```rust self.name == name && (self.params.is_none() || self.params.as_ref() == Some(params)) self.name == name && (self.params.is_none() || self.params.as_deref() == Some(params)) ``` ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- acvm-repo/brillig_vm/src/lib.rs | 6 +++--- acvm-repo/brillig_vm/src/memory.rs | 2 +- compiler/noirc_driver/src/abi_gen.rs | 2 +- .../src/ssa/acir_gen/acir_ir/acir_variable.rs | 2 +- compiler/noirc_frontend/src/ast/function.rs | 2 +- compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs | 2 +- compiler/noirc_frontend/src/hir/type_check/expr.rs | 4 ++-- tooling/nargo/src/ops/foreign_calls.rs | 4 ++-- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/acvm-repo/brillig_vm/src/lib.rs b/acvm-repo/brillig_vm/src/lib.rs index df4c8135bce..00c20a704da 100644 --- a/acvm-repo/brillig_vm/src/lib.rs +++ b/acvm-repo/brillig_vm/src/lib.rs @@ -168,7 +168,7 @@ impl<'a, B: BlackBoxFunctionSolver> VM<'a, B> { self.registers.set(register_index, value); } - pub fn get_memory(&self) -> &Vec { + pub fn get_memory(&self) -> &[Value] { self.memory.values() } @@ -748,7 +748,7 @@ mod tests { let opcodes = [&start[..], &loop_body[..]].concat(); let vm = brillig_execute_and_get_vm(memory, &opcodes); - vm.get_memory().clone() + vm.get_memory().to_vec() } let memory = brillig_write_memory(vec![Value::from(0u128); 5]); @@ -904,7 +904,7 @@ mod tests { let opcodes = [&start[..], &recursive_fn[..]].concat(); let vm = brillig_execute_and_get_vm(memory, &opcodes); - vm.get_memory().clone() + vm.get_memory().to_vec() } let memory = brillig_recursive_write_memory(vec![Value::from(0u128); 5]); diff --git a/acvm-repo/brillig_vm/src/memory.rs b/acvm-repo/brillig_vm/src/memory.rs index e2309537283..8a6993f1353 100644 --- a/acvm-repo/brillig_vm/src/memory.rs +++ b/acvm-repo/brillig_vm/src/memory.rs @@ -39,7 +39,7 @@ impl Memory { } /// Returns the values of the memory - pub fn values(&self) -> &Vec { + pub fn values(&self) -> &[Value] { &self.inner } } diff --git a/compiler/noirc_driver/src/abi_gen.rs b/compiler/noirc_driver/src/abi_gen.rs index e546cd822b7..7fafa719186 100644 --- a/compiler/noirc_driver/src/abi_gen.rs +++ b/compiler/noirc_driver/src/abi_gen.rs @@ -63,7 +63,7 @@ fn into_abi_params(context: &Context, params: Vec) -> Vec { // Takes each abi parameter and shallowly maps to the expected witness range in which the // parameter's constituent values live. fn param_witnesses_from_abi_param( - abi_params: &Vec, + abi_params: &[AbiParameter], input_witnesses: Vec, ) -> BTreeMap>> { let mut idx = 0_usize; diff --git a/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs b/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs index cf7c6151110..cd96f6f8cb9 100644 --- a/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs +++ b/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs @@ -1751,7 +1751,7 @@ fn execute_brillig( // It may be finished, in-progress, failed, or may be waiting for results of a foreign call. // If it's finished then we can omit the opcode and just write in the return values. match vm_status { - VMStatus::Finished => Some((vm.get_registers().clone(), vm.get_memory().clone())), + VMStatus::Finished => Some((vm.get_registers().clone(), vm.get_memory().to_vec())), VMStatus::InProgress => unreachable!("Brillig VM has not completed execution"), VMStatus::Failure { .. } => { // TODO: Return an error stating that the brillig function failed. diff --git a/compiler/noirc_frontend/src/ast/function.rs b/compiler/noirc_frontend/src/ast/function.rs index b8f385f52d3..f20fc54b101 100644 --- a/compiler/noirc_frontend/src/ast/function.rs +++ b/compiler/noirc_frontend/src/ast/function.rs @@ -72,7 +72,7 @@ impl NoirFunction { pub fn function_attribute(&self) -> Option<&FunctionAttribute> { self.def.attributes.function.as_ref() } - pub fn secondary_attributes(&self) -> &Vec { + pub fn secondary_attributes(&self) -> &[SecondaryAttribute] { self.def.attributes.secondary.as_ref() } pub fn def(&self) -> &FunctionDefinition { diff --git a/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs b/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs index c768ea96f8f..a6ab6b1d825 100644 --- a/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs +++ b/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs @@ -460,7 +460,7 @@ fn type_check_functions( #[allow(clippy::too_many_arguments)] pub(crate) fn check_methods_signatures( resolver: &mut Resolver, - impl_methods: &Vec<(FileId, FuncId)>, + impl_methods: &[(FileId, FuncId)], trait_id: TraitId, trait_name_span: Span, // These are the generics on the trait itself from the impl. diff --git a/compiler/noirc_frontend/src/hir/type_check/expr.rs b/compiler/noirc_frontend/src/hir/type_check/expr.rs index 22baa9f0da5..3d4f37852cf 100644 --- a/compiler/noirc_frontend/src/hir/type_check/expr.rs +++ b/compiler/noirc_frontend/src/hir/type_check/expr.rs @@ -1028,9 +1028,9 @@ impl<'interner> TypeChecker<'interner> { fn bind_function_type_impl( &mut self, - fn_params: &Vec, + fn_params: &[Type], fn_ret: &Type, - callsite_args: &Vec<(Type, ExprId, Span)>, + callsite_args: &[(Type, ExprId, Span)], span: Span, ) -> Type { if fn_params.len() != callsite_args.len() { diff --git a/tooling/nargo/src/ops/foreign_calls.rs b/tooling/nargo/src/ops/foreign_calls.rs index cbe40c92b4e..e3a3174f8dc 100644 --- a/tooling/nargo/src/ops/foreign_calls.rs +++ b/tooling/nargo/src/ops/foreign_calls.rs @@ -82,8 +82,8 @@ impl MockedCall { } impl MockedCall { - fn matches(&self, name: &str, params: &Vec) -> bool { - self.name == name && (self.params.is_none() || self.params.as_ref() == Some(params)) + fn matches(&self, name: &str, params: &[ForeignCallParam]) -> bool { + self.name == name && (self.params.is_none() || self.params.as_deref() == Some(params)) } } From 21f91b6e7ed44050e2a0098e39d6f457f27e3757 Mon Sep 17 00:00:00 2001 From: Martin Verzilli Date: Wed, 24 Jan 2024 17:29:58 +0100 Subject: [PATCH 25/70] chore(debugger): Limit printed BRILLIG opcode info while stepping in REPL debugger (#4147) # Description Reduces the amount of information printed to the console after each step, when execution pauses at an ACIR BRILLIG opcode. ## Problem Part of #3015. ## Summary Before this change: ``` [1327_concrete_in_generic] Starting debugger At opcode 0: BRILLIG: inputs: [Single(Expression { mul_terms: [], linear_combinations: [], q_c: 0 }), Single(Expression { mul_terms: [], linear_combinations: [(1, Witness(0))], q_c: 0 })] outputs: [] [Mov { destination: RegisterIndex(2), source: RegisterIndex(0) }, Mov { destination: RegisterIndex(3), source: RegisterIndex(1) }, Const { destination: RegisterIndex(0), value: Value { inner: 0 } }, Const { destination: RegisterIndex(1), value: Value { inner: 0 } }, Mov { destination: RegisterIndex(2), source: RegisterIndex(2) }, Mov { destination: RegisterIndex(3), source: RegisterIndex(3) }, Call { location: 8 }, Stop, ForeignCall { function: "__debug_var_assign", destinations: [], inputs: [RegisterIndex(RegisterIndex(2)), RegisterIndex(RegisterIndex(3))] }, Return] At ~/noir/test_programs/execution_success/1327_concrete_in_generic/src/main.nr:56:9 51 ... 52 fn get_d_method_interface() -> MethodInterface { 53 MethodInterface { some_method_on_t_d: d_method } 54 } 55 // --- 56 -> fn main(input: Field) -> pub Field { 57 let b: B> = B::new(new_concrete_c_over_d); 58 let c: C = b.get_t_c(); // Singleton 59 let d: D = D { d: input }; // Note 60 let output = c.call_method_of_t_d(d); ``` After this change: ``` [1327_concrete_in_generic] Starting debugger At opcode 0: BRILLIG: ... At ~/noir/test_programs/execution_success/1327_concrete_in_generic/src/main.nr:56:9 51 ... 52 fn get_d_method_interface() -> MethodInterface { 53 MethodInterface { some_method_on_t_d: d_method } 54 } 55 // --- 56 -> fn main(input: Field) -> pub Field { 57 let b: B> = B::new(new_concrete_c_over_d); 58 let c: C = b.get_t_c(); // Singleton 59 let d: D = D { d: input }; // Note 60 let output = c.call_method_of_t_d(d); 61 ... > ``` Note: the user can still inspect the full contents of opcode 0 by using the `opcodes` command. ## Documentation Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- tooling/debugger/src/repl.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tooling/debugger/src/repl.rs b/tooling/debugger/src/repl.rs index b1af2bc2686..40ee6efdb86 100644 --- a/tooling/debugger/src/repl.rs +++ b/tooling/debugger/src/repl.rs @@ -53,7 +53,15 @@ impl<'a, B: BlackBoxFunctionSolver> ReplDebugger<'a, B> { Some(location) => { match location { OpcodeLocation::Acir(ip) => { - println!("At opcode {}: {}", ip, opcodes[ip]) + // Default Brillig display is too bloated for this context, + // so we limit it to denoting it's the start of a Brillig + // block. The user can still use the `opcodes` command to + // take a look at the whole block. + let opcode_summary = match opcodes[ip] { + Opcode::Brillig(..) => "BRILLIG: ...".into(), + _ => format!("{}", opcodes[ip]), + }; + println!("At opcode {}: {}", ip, opcode_summary); } OpcodeLocation::Brillig { acir_index, brillig_index } => { let Opcode::Brillig(ref brillig) = opcodes[acir_index] else { From 9e2d56e05aaf861903930ff02c31698f9068a5bc Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Wed, 24 Jan 2024 18:00:23 +0000 Subject: [PATCH 26/70] chore: fix creation of new docs version on release PR (#4128) # Description ## Problem\* Resolves ## Summary\* Rather than faffing about with getting `release-please` to tell us the version, let's be sensible and read from cargo.toml This fixes us trying to create a version of the docs for the version `v..` ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. Co-authored-by: kevaundray --- .github/workflows/release.yml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 22a733b38c5..3925b7ebee9 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -11,7 +11,6 @@ jobs: outputs: release-pr: ${{ steps.release.outputs.pr }} tag-name: ${{ steps.release.outputs.tag_name }} - pending-release-semver: v${{ steps.release.outputs.major }}.${{steps.release.outputs.minor}}.${{steps.release.outputs.patch}} runs-on: ubuntu-latest steps: - name: Run release-please @@ -80,9 +79,15 @@ jobs: - name: Install Yarn dependencies uses: ./.github/actions/setup + - name: Query new noir version + id: noir-version + run: | + NOIR_VERSION=$(grep '^version =' ./Cargo.toml | sed -E 's/version = "([^"]+)"/\1/') + echo "semver=$NOIR_VERSION" >> $GITHUB_OUTPUT + - name: Cut a new version working-directory: ./docs - run: yarn docusaurus docs:version ${{ needs.release-please.outputs.pending-release-semver }} + run: yarn docusaurus docs:version ${{ steps.noir-version.outputs.semver }} - name: Configure git run: | @@ -92,7 +97,7 @@ jobs: - name: Commit new documentation version run: | git add . - git commit -m "chore(docs): cut new docs version for tag ${{ needs.release-please.outputs.pending-release-semver }}" + git commit -m "chore(docs): cut new docs version for tag ${{ steps.noir-version.outputs.semver }}" git push build-binaries: From cf7130f2e19e2d241e003c5527de9bf9d74cea40 Mon Sep 17 00:00:00 2001 From: Koby Hall <102518238+kobyhallx@users.noreply.github.com> Date: Wed, 24 Jan 2024 19:21:19 +0100 Subject: [PATCH 27/70] fix(lsp): crash when file not in workspace (#4146) # Description ## Problem\* Resolves LSP crash when source file not in workspace #4143 ## Summary\* ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- tooling/lsp/src/lib.rs | 58 +++++++++++++++++++++++----------- tooling/nargo/src/workspace.rs | 2 ++ tooling/nargo_toml/src/lib.rs | 8 ++++- 3 files changed, 48 insertions(+), 20 deletions(-) diff --git a/tooling/lsp/src/lib.rs b/tooling/lsp/src/lib.rs index b64fc474b0b..a0e024c70fd 100644 --- a/tooling/lsp/src/lib.rs +++ b/tooling/lsp/src/lib.rs @@ -4,11 +4,12 @@ #![cfg_attr(not(test), warn(unused_crate_dependencies, unused_extern_crates))] use std::{ - collections::HashMap, + collections::{BTreeMap, HashMap}, future::Future, ops::{self, ControlFlow}, path::{Path, PathBuf}, pin::Pin, + str::FromStr, task::{self, Poll}, }; @@ -20,7 +21,11 @@ use async_lsp::{ use fm::{codespan_files as files, FileManager}; use fxhash::FxHashSet; use lsp_types::CodeLens; -use nargo::{parse_all, workspace::Workspace}; +use nargo::{ + package::{Package, PackageType}, + parse_all, + workspace::Workspace, +}; use nargo_toml::{find_file_manifest, resolve_workspace_from_toml, PackageSelection}; use noirc_driver::{file_manager_with_stdlib, prepare_crate, NOIR_ARTIFACT_VERSION_STRING}; use noirc_frontend::{ @@ -209,23 +214,38 @@ fn byte_span_to_range<'a, F: files::Files<'a> + ?Sized>( } pub(crate) fn resolve_workspace_for_source_path(file_path: &Path) -> Result { - let package_root = find_file_manifest(file_path); - - let toml_path = package_root.ok_or_else(|| { - LspError::WorkspaceResolutionError(format!( - "Nargo.toml not found for file: {:?}", - file_path - )) - })?; - - let workspace = resolve_workspace_from_toml( - &toml_path, - PackageSelection::All, - Some(NOIR_ARTIFACT_VERSION_STRING.to_string()), - ) - .map_err(|err| LspError::WorkspaceResolutionError(err.to_string()))?; - - Ok(workspace) + if let Some(toml_path) = find_file_manifest(file_path) { + resolve_workspace_from_toml( + &toml_path, + PackageSelection::All, + Some(NOIR_ARTIFACT_VERSION_STRING.to_string()), + ) + .map_err(|err| LspError::WorkspaceResolutionError(err.to_string())) + } else { + let Some(parent_folder) = file_path.parent().and_then(|f| f.file_name()).and_then(|file_name_os_str| file_name_os_str.to_str()) else { + return Err(LspError::WorkspaceResolutionError(format!( + "Could not resolve parent folder for file: {:?}", + file_path + ))) + }; + let assumed_package = Package { + version: None, + compiler_required_version: Some(NOIR_ARTIFACT_VERSION_STRING.to_string()), + root_dir: PathBuf::from(parent_folder), + package_type: PackageType::Binary, + entry_path: PathBuf::from(file_path), + name: CrateName::from_str(parent_folder) + .map_err(|err| LspError::WorkspaceResolutionError(err.to_string()))?, + dependencies: BTreeMap::new(), + }; + let workspace = Workspace { + root_dir: PathBuf::from(parent_folder), + members: vec![assumed_package], + selected_package_index: Some(0), + is_assumed: true, + }; + Ok(workspace) + } } /// Prepares a package from a source string diff --git a/tooling/nargo/src/workspace.rs b/tooling/nargo/src/workspace.rs index 5696a758531..0795ffd9304 100644 --- a/tooling/nargo/src/workspace.rs +++ b/tooling/nargo/src/workspace.rs @@ -20,6 +20,8 @@ pub struct Workspace { pub members: Vec, // If `Some()`, the `selected_package_index` is used to select the only `Package` when iterating a Workspace pub selected_package_index: Option, + /// If we could not resolve the workspace we would inform the user we have assumed it (ie. from lsp file path given) + pub is_assumed: bool, } impl Workspace { diff --git a/tooling/nargo_toml/src/lib.rs b/tooling/nargo_toml/src/lib.rs index cecc3f7e26a..985cb30dc24 100644 --- a/tooling/nargo_toml/src/lib.rs +++ b/tooling/nargo_toml/src/lib.rs @@ -345,6 +345,7 @@ fn toml_to_workspace( root_dir: nargo_toml.root_dir, selected_package_index: Some(0), members: vec![member], + is_assumed: false, }, } } @@ -392,7 +393,12 @@ fn toml_to_workspace( PackageSelection::All => (), } - Workspace { root_dir: nargo_toml.root_dir, members, selected_package_index } + Workspace { + root_dir: nargo_toml.root_dir, + members, + selected_package_index, + is_assumed: false, + } } }; From c7b6b6a839b4975df524b7dc91075623382936c7 Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Wed, 24 Jan 2024 19:10:51 +0000 Subject: [PATCH 28/70] chore: add `v` to semver in docs versions (#4150) # Description ## Problem\* Resolves ## Summary\* We're currently creating docs with a version of `0.23.1` instead of `v0.23.1` which is what's done for other versions. ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3925b7ebee9..7dfc844d18f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -82,7 +82,7 @@ jobs: - name: Query new noir version id: noir-version run: | - NOIR_VERSION=$(grep '^version =' ./Cargo.toml | sed -E 's/version = "([^"]+)"/\1/') + NOIR_VERSION=$(grep '^version =' ./Cargo.toml | sed -E 's/version = "([^"]+)"/v\1/') echo "semver=$NOIR_VERSION" >> $GITHUB_OUTPUT - name: Cut a new version From a66e3728b09c699ec7025591e23ca6c7201b9a6a Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Wed, 24 Jan 2024 20:49:30 +0000 Subject: [PATCH 29/70] chore: split off submodules from `instruction.rs` (#4084) # Description ## Problem\* Resolves ## Summary\* This PR decomposes `instruction.rs` into a couple of submodules based around different instruction types. This is done in the intention of breaking up the leviathan that is `instruction.rs` and making it easier to unit test in future. ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- .../noirc_evaluator/src/ssa/ir/instruction.rs | 524 +----------------- .../src/ssa/ir/instruction/binary.rs | 349 ++++++++++++ .../src/ssa/ir/instruction/cast.rs | 58 ++ .../src/ssa/ir/instruction/constrain.rs | 126 +++++ 4 files changed, 539 insertions(+), 518 deletions(-) create mode 100644 compiler/noirc_evaluator/src/ssa/ir/instruction/binary.rs create mode 100644 compiler/noirc_evaluator/src/ssa/ir/instruction/cast.rs create mode 100644 compiler/noirc_evaluator/src/ssa/ir/instruction/constrain.rs diff --git a/compiler/noirc_evaluator/src/ssa/ir/instruction.rs b/compiler/noirc_evaluator/src/ssa/ir/instruction.rs index dbad562b6f4..280a0c32e64 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/instruction.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/instruction.rs @@ -1,6 +1,5 @@ use acvm::{acir::BlackBoxFunc, FieldElement}; use iter_extended::vecmap; -use num_bigint::BigUint; use super::{ basic_block::BasicBlockId, @@ -10,9 +9,15 @@ use super::{ value::{Value, ValueId}, }; +mod binary; mod call; +mod cast; +mod constrain; +pub(crate) use binary::{Binary, BinaryOp}; use call::simplify_call; +use cast::simplify_cast; +use constrain::decompose_constrain; /// Reference to an instruction /// @@ -545,179 +550,6 @@ impl Instruction { } } -/// Try to simplify this cast instruction. If the instruction can be simplified to a known value, -/// that value is returned. Otherwise None is returned. -fn simplify_cast(value: ValueId, dst_typ: &Type, dfg: &mut DataFlowGraph) -> SimplifyResult { - use SimplifyResult::*; - let value = dfg.resolve(value); - - if let Value::Instruction { instruction, .. } = &dfg[value] { - if let Instruction::Cast(original_value, _) = &dfg[*instruction] { - return SimplifiedToInstruction(Instruction::Cast(*original_value, dst_typ.clone())); - } - } - - if let Some(constant) = dfg.get_numeric_constant(value) { - let src_typ = dfg.type_of_value(value); - match (src_typ, dst_typ) { - (Type::Numeric(NumericType::NativeField), Type::Numeric(NumericType::NativeField)) => { - // Field -> Field: use src value - SimplifiedTo(value) - } - ( - Type::Numeric(NumericType::Unsigned { .. }), - Type::Numeric(NumericType::NativeField), - ) => { - // Unsigned -> Field: redefine same constant as Field - SimplifiedTo(dfg.make_constant(constant, dst_typ.clone())) - } - ( - Type::Numeric( - NumericType::NativeField - | NumericType::Unsigned { .. } - | NumericType::Signed { .. }, - ), - Type::Numeric(NumericType::Unsigned { bit_size }), - ) => { - // Field/Unsigned -> unsigned: truncate - let integer_modulus = BigUint::from(2u128).pow(*bit_size); - let constant: BigUint = BigUint::from_bytes_be(&constant.to_be_bytes()); - let truncated = constant % integer_modulus; - let truncated = FieldElement::from_be_bytes_reduce(&truncated.to_bytes_be()); - SimplifiedTo(dfg.make_constant(truncated, dst_typ.clone())) - } - _ => None, - } - } else if *dst_typ == dfg.type_of_value(value) { - SimplifiedTo(value) - } else { - None - } -} - -/// Try to decompose this constrain instruction. This constraint will be broken down such that it instead constrains -/// all the values which are used to compute the values which were being constrained. -fn decompose_constrain( - lhs: ValueId, - rhs: ValueId, - msg: Option, - dfg: &mut DataFlowGraph, -) -> Vec { - let lhs = dfg.resolve(lhs); - let rhs = dfg.resolve(rhs); - - if lhs == rhs { - // Remove trivial case `assert_eq(x, x)` - Vec::new() - } else { - match (&dfg[lhs], &dfg[rhs]) { - (Value::NumericConstant { constant, typ }, Value::Instruction { instruction, .. }) - | (Value::Instruction { instruction, .. }, Value::NumericConstant { constant, typ }) - if *typ == Type::bool() => - { - match dfg[*instruction] { - Instruction::Binary(Binary { lhs, rhs, operator: BinaryOp::Eq }) - if constant.is_one() => - { - // Replace an explicit two step equality assertion - // - // v2 = eq v0, u32 v1 - // constrain v2 == u1 1 - // - // with a direct assertion of equality between the two values - // - // v2 = eq v0, u32 v1 - // constrain v0 == v1 - // - // Note that this doesn't remove the value `v2` as it may be used in other instructions, but it - // will likely be removed through dead instruction elimination. - - vec![Instruction::Constrain(lhs, rhs, msg)] - } - - Instruction::Binary(Binary { lhs, rhs, operator: BinaryOp::Mul }) - if constant.is_one() && dfg.type_of_value(lhs) == Type::bool() => - { - // Replace an equality assertion on a boolean multiplication - // - // v2 = mul v0, v1 - // constrain v2 == u1 1 - // - // with a direct assertion that each value is equal to 1 - // - // v2 = mul v0, v1 - // constrain v0 == 1 - // constrain v1 == 1 - // - // This is due to the fact that for `v2` to be 1 then both `v0` and `v1` are 1. - // - // Note that this doesn't remove the value `v2` as it may be used in other instructions, but it - // will likely be removed through dead instruction elimination. - let one = FieldElement::one(); - let one = dfg.make_constant(one, Type::bool()); - - [ - decompose_constrain(lhs, one, msg.clone(), dfg), - decompose_constrain(rhs, one, msg, dfg), - ] - .concat() - } - - Instruction::Binary(Binary { lhs, rhs, operator: BinaryOp::Or }) - if constant.is_zero() => - { - // Replace an equality assertion on an OR - // - // v2 = or v0, v1 - // constrain v2 == u1 0 - // - // with a direct assertion that each value is equal to 0 - // - // v2 = or v0, v1 - // constrain v0 == 0 - // constrain v1 == 0 - // - // This is due to the fact that for `v2` to be 0 then both `v0` and `v1` are 0. - // - // Note that this doesn't remove the value `v2` as it may be used in other instructions, but it - // will likely be removed through dead instruction elimination. - let zero = FieldElement::zero(); - let zero = dfg.make_constant(zero, dfg.type_of_value(lhs)); - - [ - decompose_constrain(lhs, zero, msg.clone(), dfg), - decompose_constrain(rhs, zero, msg, dfg), - ] - .concat() - } - - Instruction::Not(value) => { - // Replace an assertion that a not instruction is truthy - // - // v1 = not v0 - // constrain v1 == u1 1 - // - // with an assertion that the not instruction input is falsy - // - // v1 = not v0 - // constrain v0 == u1 0 - // - // Note that this doesn't remove the value `v1` as it may be used in other instructions, but it - // will likely be removed through dead instruction elimination. - let reversed_constant = FieldElement::from(!constant.is_one()); - let reversed_constant = dfg.make_constant(reversed_constant, Type::bool()); - decompose_constrain(value, reversed_constant, msg, dfg) - } - - _ => vec![Instruction::Constrain(lhs, rhs, msg)], - } - } - - _ => vec![Instruction::Constrain(lhs, rhs, msg)], - } - } -} - /// The possible return values for Instruction::return_types pub(crate) enum InstructionResultType { /// The result type of this instruction matches that of this operand @@ -848,350 +680,6 @@ impl TerminatorInstruction { } } -/// A binary instruction in the IR. -#[derive(Debug, PartialEq, Eq, Hash, Clone)] -pub(crate) struct Binary { - /// Left hand side of the binary operation - pub(crate) lhs: ValueId, - /// Right hand side of the binary operation - pub(crate) rhs: ValueId, - /// The binary operation to apply - pub(crate) operator: BinaryOp, -} - -impl Binary { - /// The type of this Binary instruction's result - pub(crate) fn result_type(&self) -> InstructionResultType { - match self.operator { - BinaryOp::Eq | BinaryOp::Lt => InstructionResultType::Known(Type::bool()), - _ => InstructionResultType::Operand(self.lhs), - } - } - - /// Try to simplify this binary instruction, returning the new value if possible. - fn simplify(&self, dfg: &mut DataFlowGraph) -> SimplifyResult { - let lhs = dfg.get_numeric_constant(self.lhs); - let rhs = dfg.get_numeric_constant(self.rhs); - let operand_type = dfg.type_of_value(self.lhs); - - if let (Some(lhs), Some(rhs)) = (lhs, rhs) { - return match eval_constant_binary_op(lhs, rhs, self.operator, operand_type) { - Some((result, result_type)) => { - let value = dfg.make_constant(result, result_type); - SimplifyResult::SimplifiedTo(value) - } - None => SimplifyResult::None, - }; - } - - let lhs_is_zero = lhs.map_or(false, |lhs| lhs.is_zero()); - let rhs_is_zero = rhs.map_or(false, |rhs| rhs.is_zero()); - - let lhs_is_one = lhs.map_or(false, |lhs| lhs.is_one()); - let rhs_is_one = rhs.map_or(false, |rhs| rhs.is_one()); - - match self.operator { - BinaryOp::Add => { - if lhs_is_zero { - return SimplifyResult::SimplifiedTo(self.rhs); - } - if rhs_is_zero { - return SimplifyResult::SimplifiedTo(self.lhs); - } - } - BinaryOp::Sub => { - if rhs_is_zero { - return SimplifyResult::SimplifiedTo(self.lhs); - } - } - BinaryOp::Mul => { - if lhs_is_one { - return SimplifyResult::SimplifiedTo(self.rhs); - } - if rhs_is_one { - return SimplifyResult::SimplifiedTo(self.lhs); - } - if lhs_is_zero || rhs_is_zero { - let zero = dfg.make_constant(FieldElement::zero(), operand_type); - return SimplifyResult::SimplifiedTo(zero); - } - } - BinaryOp::Div => { - if rhs_is_one { - return SimplifyResult::SimplifiedTo(self.lhs); - } - } - BinaryOp::Mod => { - if rhs_is_one { - let zero = dfg.make_constant(FieldElement::zero(), operand_type); - return SimplifyResult::SimplifiedTo(zero); - } - } - BinaryOp::Eq => { - if dfg.resolve(self.lhs) == dfg.resolve(self.rhs) { - let one = dfg.make_constant(FieldElement::one(), Type::bool()); - return SimplifyResult::SimplifiedTo(one); - } - if operand_type == Type::bool() { - // Simplify forms of `(boolean == true)` into `boolean` - if lhs_is_one { - return SimplifyResult::SimplifiedTo(self.rhs); - } - if rhs_is_one { - return SimplifyResult::SimplifiedTo(self.lhs); - } - // Simplify forms of `(boolean == false)` into `!boolean` - if lhs_is_zero { - return SimplifyResult::SimplifiedToInstruction(Instruction::Not(self.rhs)); - } - if rhs_is_zero { - return SimplifyResult::SimplifiedToInstruction(Instruction::Not(self.lhs)); - } - } - } - BinaryOp::Lt => { - if dfg.resolve(self.lhs) == dfg.resolve(self.rhs) { - let zero = dfg.make_constant(FieldElement::zero(), Type::bool()); - return SimplifyResult::SimplifiedTo(zero); - } - if operand_type.is_unsigned() { - if rhs_is_zero { - // Unsigned values cannot be less than zero. - let zero = dfg.make_constant(FieldElement::zero(), Type::bool()); - return SimplifyResult::SimplifiedTo(zero); - } else if rhs_is_one { - let zero = dfg.make_constant(FieldElement::zero(), operand_type); - return SimplifyResult::SimplifiedToInstruction(Instruction::binary( - BinaryOp::Eq, - self.lhs, - zero, - )); - } - } - } - BinaryOp::And => { - if lhs_is_zero || rhs_is_zero { - let zero = dfg.make_constant(FieldElement::zero(), operand_type); - return SimplifyResult::SimplifiedTo(zero); - } - if dfg.resolve(self.lhs) == dfg.resolve(self.rhs) { - return SimplifyResult::SimplifiedTo(self.lhs); - } - if operand_type == Type::bool() { - // Boolean AND is equivalent to multiplication, which is a cheaper operation. - let instruction = Instruction::binary(BinaryOp::Mul, self.lhs, self.rhs); - return SimplifyResult::SimplifiedToInstruction(instruction); - } - } - BinaryOp::Or => { - if lhs_is_zero { - return SimplifyResult::SimplifiedTo(self.rhs); - } - if rhs_is_zero { - return SimplifyResult::SimplifiedTo(self.lhs); - } - if dfg.resolve(self.lhs) == dfg.resolve(self.rhs) { - return SimplifyResult::SimplifiedTo(self.lhs); - } - } - BinaryOp::Xor => { - if lhs_is_zero { - return SimplifyResult::SimplifiedTo(self.rhs); - } - if rhs_is_zero { - return SimplifyResult::SimplifiedTo(self.lhs); - } - if dfg.resolve(self.lhs) == dfg.resolve(self.rhs) { - let zero = dfg.make_constant(FieldElement::zero(), operand_type); - return SimplifyResult::SimplifiedTo(zero); - } - } - } - SimplifyResult::None - } -} - -/// Evaluate a binary operation with constant arguments. -fn eval_constant_binary_op( - lhs: FieldElement, - rhs: FieldElement, - operator: BinaryOp, - mut operand_type: Type, -) -> Option<(FieldElement, Type)> { - let value = match &operand_type { - Type::Numeric(NumericType::NativeField) => { - // If the rhs of a division is zero, attempting to evaluate the division will cause a compiler panic. - // Thus, we do not evaluate the division in this method, as we want to avoid triggering a panic, - // and the operation should be handled by ACIR generation. - if matches!(operator, BinaryOp::Div | BinaryOp::Mod) && rhs == FieldElement::zero() { - return None; - } - operator.get_field_function()?(lhs, rhs) - } - Type::Numeric(NumericType::Unsigned { bit_size }) => { - let function = operator.get_u128_function(); - - let lhs = truncate(lhs.try_into_u128()?, *bit_size); - let rhs = truncate(rhs.try_into_u128()?, *bit_size); - - // The divisor is being truncated into the type of the operand, which can potentially - // lead to the rhs being zero. - // If the rhs of a division is zero, attempting to evaluate the division will cause a compiler panic. - // Thus, we do not evaluate the division in this method, as we want to avoid triggering a panic, - // and the operation should be handled by ACIR generation. - if matches!(operator, BinaryOp::Div | BinaryOp::Mod) && rhs == 0 { - return None; - } - let result = function(lhs, rhs)?; - // Check for overflow - if result >= 2u128.pow(*bit_size) { - return None; - } - result.into() - } - Type::Numeric(NumericType::Signed { bit_size }) => { - let function = operator.get_i128_function(); - - let lhs = truncate(lhs.try_into_u128()?, *bit_size); - let rhs = truncate(rhs.try_into_u128()?, *bit_size); - let l_pos = lhs < 2u128.pow(bit_size - 1); - let r_pos = rhs < 2u128.pow(bit_size - 1); - let lhs = if l_pos { lhs as i128 } else { -((2u128.pow(*bit_size) - lhs) as i128) }; - let rhs = if r_pos { rhs as i128 } else { -((2u128.pow(*bit_size) - rhs) as i128) }; - // The divisor is being truncated into the type of the operand, which can potentially - // lead to the rhs being zero. - // If the rhs of a division is zero, attempting to evaluate the division will cause a compiler panic. - // Thus, we do not evaluate the division in this method, as we want to avoid triggering a panic, - // and the operation should be handled by ACIR generation. - if matches!(operator, BinaryOp::Div | BinaryOp::Mod) && rhs == 0 { - return None; - } - - let result = function(lhs, rhs)?; - // Check for overflow - if result >= 2i128.pow(*bit_size - 1) || result < -(2i128.pow(*bit_size - 1)) { - return None; - } - let result = - if result >= 0 { result as u128 } else { (2i128.pow(*bit_size) + result) as u128 }; - result.into() - } - _ => return None, - }; - - if matches!(operator, BinaryOp::Eq | BinaryOp::Lt) { - operand_type = Type::bool(); - } - - Some((value, operand_type)) -} - -fn truncate(int: u128, bit_size: u32) -> u128 { - let max = 2u128.pow(bit_size); - int % max -} - -impl BinaryOp { - fn get_field_function(self) -> Option FieldElement> { - match self { - BinaryOp::Add => Some(std::ops::Add::add), - BinaryOp::Sub => Some(std::ops::Sub::sub), - BinaryOp::Mul => Some(std::ops::Mul::mul), - BinaryOp::Div => Some(std::ops::Div::div), - BinaryOp::Eq => Some(|x, y| (x == y).into()), - BinaryOp::Lt => Some(|x, y| (x < y).into()), - // Bitwise operators are unsupported for Fields - BinaryOp::Mod => None, - BinaryOp::And => None, - BinaryOp::Or => None, - BinaryOp::Xor => None, - } - } - - fn get_u128_function(self) -> fn(u128, u128) -> Option { - match self { - BinaryOp::Add => u128::checked_add, - BinaryOp::Sub => u128::checked_sub, - BinaryOp::Mul => u128::checked_mul, - BinaryOp::Div => u128::checked_div, - BinaryOp::Mod => u128::checked_rem, - BinaryOp::And => |x, y| Some(x & y), - BinaryOp::Or => |x, y| Some(x | y), - BinaryOp::Xor => |x, y| Some(x ^ y), - BinaryOp::Eq => |x, y| Some((x == y) as u128), - BinaryOp::Lt => |x, y| Some((x < y) as u128), - } - } - - fn get_i128_function(self) -> fn(i128, i128) -> Option { - match self { - BinaryOp::Add => i128::checked_add, - BinaryOp::Sub => i128::checked_sub, - BinaryOp::Mul => i128::checked_mul, - BinaryOp::Div => i128::checked_div, - BinaryOp::Mod => i128::checked_rem, - BinaryOp::And => |x, y| Some(x & y), - BinaryOp::Or => |x, y| Some(x | y), - BinaryOp::Xor => |x, y| Some(x ^ y), - BinaryOp::Eq => |x, y| Some((x == y) as i128), - BinaryOp::Lt => |x, y| Some((x < y) as i128), - } - } -} - -/// Binary Operations allowed in the IR. -/// Aside from the comparison operators (Eq and Lt), all operators -/// will return the same type as their operands. -/// The operand types must match for all binary operators. -/// All binary operators are also only for numeric types. To implement -/// e.g. equality for a compound type like a struct, one must add a -/// separate Eq operation for each field and combine them later with And. -#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)] -pub(crate) enum BinaryOp { - /// Addition of lhs + rhs. - Add, - /// Subtraction of lhs - rhs. - Sub, - /// Multiplication of lhs * rhs. - Mul, - /// Division of lhs / rhs. - Div, - /// Modulus of lhs % rhs. - Mod, - /// Checks whether two types are equal. - /// Returns true if the types were equal and - /// false otherwise. - Eq, - /// Checks whether the lhs is less than the rhs. - /// All other comparison operators should be translated - /// to less than. For example (a > b) = (b < a) = !(a >= b) = !(b <= a). - /// The result will always be a u1. - Lt, - /// Bitwise and (&) - And, - /// Bitwise or (|) - Or, - /// Bitwise xor (^) - Xor, -} - -impl std::fmt::Display for BinaryOp { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - BinaryOp::Add => write!(f, "add"), - BinaryOp::Sub => write!(f, "sub"), - BinaryOp::Mul => write!(f, "mul"), - BinaryOp::Div => write!(f, "div"), - BinaryOp::Eq => write!(f, "eq"), - BinaryOp::Mod => write!(f, "mod"), - BinaryOp::Lt => write!(f, "lt"), - BinaryOp::And => write!(f, "and"), - BinaryOp::Or => write!(f, "or"), - BinaryOp::Xor => write!(f, "xor"), - } - } -} - /// Contains the result to Instruction::simplify, specifying how the instruction /// should be simplified. pub(crate) enum SimplifyResult { diff --git a/compiler/noirc_evaluator/src/ssa/ir/instruction/binary.rs b/compiler/noirc_evaluator/src/ssa/ir/instruction/binary.rs new file mode 100644 index 00000000000..1cb32d94148 --- /dev/null +++ b/compiler/noirc_evaluator/src/ssa/ir/instruction/binary.rs @@ -0,0 +1,349 @@ +use acvm::FieldElement; + +use super::{ + DataFlowGraph, Instruction, InstructionResultType, NumericType, SimplifyResult, Type, ValueId, +}; + +/// Binary Operations allowed in the IR. +/// Aside from the comparison operators (Eq and Lt), all operators +/// will return the same type as their operands. +/// The operand types must match for all binary operators. +/// All binary operators are also only for numeric types. To implement +/// e.g. equality for a compound type like a struct, one must add a +/// separate Eq operation for each field and combine them later with And. +#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)] +pub(crate) enum BinaryOp { + /// Addition of lhs + rhs. + Add, + /// Subtraction of lhs - rhs. + Sub, + /// Multiplication of lhs * rhs. + Mul, + /// Division of lhs / rhs. + Div, + /// Modulus of lhs % rhs. + Mod, + /// Checks whether two types are equal. + /// Returns true if the types were equal and + /// false otherwise. + Eq, + /// Checks whether the lhs is less than the rhs. + /// All other comparison operators should be translated + /// to less than. For example (a > b) = (b < a) = !(a >= b) = !(b <= a). + /// The result will always be a u1. + Lt, + /// Bitwise and (&) + And, + /// Bitwise or (|) + Or, + /// Bitwise xor (^) + Xor, +} + +impl std::fmt::Display for BinaryOp { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + BinaryOp::Add => write!(f, "add"), + BinaryOp::Sub => write!(f, "sub"), + BinaryOp::Mul => write!(f, "mul"), + BinaryOp::Div => write!(f, "div"), + BinaryOp::Eq => write!(f, "eq"), + BinaryOp::Mod => write!(f, "mod"), + BinaryOp::Lt => write!(f, "lt"), + BinaryOp::And => write!(f, "and"), + BinaryOp::Or => write!(f, "or"), + BinaryOp::Xor => write!(f, "xor"), + } + } +} + +/// A binary instruction in the IR. +#[derive(Debug, PartialEq, Eq, Hash, Clone)] +pub(crate) struct Binary { + /// Left hand side of the binary operation + pub(crate) lhs: ValueId, + /// Right hand side of the binary operation + pub(crate) rhs: ValueId, + /// The binary operation to apply + pub(crate) operator: BinaryOp, +} + +impl Binary { + /// The type of this Binary instruction's result + pub(crate) fn result_type(&self) -> InstructionResultType { + match self.operator { + BinaryOp::Eq | BinaryOp::Lt => InstructionResultType::Known(Type::bool()), + _ => InstructionResultType::Operand(self.lhs), + } + } + + /// Try to simplify this binary instruction, returning the new value if possible. + pub(super) fn simplify(&self, dfg: &mut DataFlowGraph) -> SimplifyResult { + let lhs = dfg.get_numeric_constant(self.lhs); + let rhs = dfg.get_numeric_constant(self.rhs); + let operand_type = dfg.type_of_value(self.lhs); + + if let (Some(lhs), Some(rhs)) = (lhs, rhs) { + return match eval_constant_binary_op(lhs, rhs, self.operator, operand_type) { + Some((result, result_type)) => { + let value = dfg.make_constant(result, result_type); + SimplifyResult::SimplifiedTo(value) + } + None => SimplifyResult::None, + }; + } + + let lhs_is_zero = lhs.map_or(false, |lhs| lhs.is_zero()); + let rhs_is_zero = rhs.map_or(false, |rhs| rhs.is_zero()); + + let lhs_is_one = lhs.map_or(false, |lhs| lhs.is_one()); + let rhs_is_one = rhs.map_or(false, |rhs| rhs.is_one()); + + match self.operator { + BinaryOp::Add => { + if lhs_is_zero { + return SimplifyResult::SimplifiedTo(self.rhs); + } + if rhs_is_zero { + return SimplifyResult::SimplifiedTo(self.lhs); + } + } + BinaryOp::Sub => { + if rhs_is_zero { + return SimplifyResult::SimplifiedTo(self.lhs); + } + } + BinaryOp::Mul => { + if lhs_is_one { + return SimplifyResult::SimplifiedTo(self.rhs); + } + if rhs_is_one { + return SimplifyResult::SimplifiedTo(self.lhs); + } + if lhs_is_zero || rhs_is_zero { + let zero = dfg.make_constant(FieldElement::zero(), operand_type); + return SimplifyResult::SimplifiedTo(zero); + } + } + BinaryOp::Div => { + if rhs_is_one { + return SimplifyResult::SimplifiedTo(self.lhs); + } + } + BinaryOp::Mod => { + if rhs_is_one { + let zero = dfg.make_constant(FieldElement::zero(), operand_type); + return SimplifyResult::SimplifiedTo(zero); + } + } + BinaryOp::Eq => { + if dfg.resolve(self.lhs) == dfg.resolve(self.rhs) { + let one = dfg.make_constant(FieldElement::one(), Type::bool()); + return SimplifyResult::SimplifiedTo(one); + } + if operand_type == Type::bool() { + // Simplify forms of `(boolean == true)` into `boolean` + if lhs_is_one { + return SimplifyResult::SimplifiedTo(self.rhs); + } + if rhs_is_one { + return SimplifyResult::SimplifiedTo(self.lhs); + } + // Simplify forms of `(boolean == false)` into `!boolean` + if lhs_is_zero { + return SimplifyResult::SimplifiedToInstruction(Instruction::Not(self.rhs)); + } + if rhs_is_zero { + return SimplifyResult::SimplifiedToInstruction(Instruction::Not(self.lhs)); + } + } + } + BinaryOp::Lt => { + if dfg.resolve(self.lhs) == dfg.resolve(self.rhs) { + let zero = dfg.make_constant(FieldElement::zero(), Type::bool()); + return SimplifyResult::SimplifiedTo(zero); + } + if operand_type.is_unsigned() { + if rhs_is_zero { + // Unsigned values cannot be less than zero. + let zero = dfg.make_constant(FieldElement::zero(), Type::bool()); + return SimplifyResult::SimplifiedTo(zero); + } else if rhs_is_one { + let zero = dfg.make_constant(FieldElement::zero(), operand_type); + return SimplifyResult::SimplifiedToInstruction(Instruction::binary( + BinaryOp::Eq, + self.lhs, + zero, + )); + } + } + } + BinaryOp::And => { + if lhs_is_zero || rhs_is_zero { + let zero = dfg.make_constant(FieldElement::zero(), operand_type); + return SimplifyResult::SimplifiedTo(zero); + } + if dfg.resolve(self.lhs) == dfg.resolve(self.rhs) { + return SimplifyResult::SimplifiedTo(self.lhs); + } + if operand_type == Type::bool() { + // Boolean AND is equivalent to multiplication, which is a cheaper operation. + let instruction = Instruction::binary(BinaryOp::Mul, self.lhs, self.rhs); + return SimplifyResult::SimplifiedToInstruction(instruction); + } + } + BinaryOp::Or => { + if lhs_is_zero { + return SimplifyResult::SimplifiedTo(self.rhs); + } + if rhs_is_zero { + return SimplifyResult::SimplifiedTo(self.lhs); + } + if dfg.resolve(self.lhs) == dfg.resolve(self.rhs) { + return SimplifyResult::SimplifiedTo(self.lhs); + } + } + BinaryOp::Xor => { + if lhs_is_zero { + return SimplifyResult::SimplifiedTo(self.rhs); + } + if rhs_is_zero { + return SimplifyResult::SimplifiedTo(self.lhs); + } + if dfg.resolve(self.lhs) == dfg.resolve(self.rhs) { + let zero = dfg.make_constant(FieldElement::zero(), operand_type); + return SimplifyResult::SimplifiedTo(zero); + } + } + } + SimplifyResult::None + } +} + +/// Evaluate a binary operation with constant arguments. +fn eval_constant_binary_op( + lhs: FieldElement, + rhs: FieldElement, + operator: BinaryOp, + mut operand_type: Type, +) -> Option<(FieldElement, Type)> { + let value = match &operand_type { + Type::Numeric(NumericType::NativeField) => { + // If the rhs of a division is zero, attempting to evaluate the division will cause a compiler panic. + // Thus, we do not evaluate the division in this method, as we want to avoid triggering a panic, + // and the operation should be handled by ACIR generation. + if matches!(operator, BinaryOp::Div | BinaryOp::Mod) && rhs == FieldElement::zero() { + return None; + } + operator.get_field_function()?(lhs, rhs) + } + Type::Numeric(NumericType::Unsigned { bit_size }) => { + let function = operator.get_u128_function(); + + let lhs = truncate(lhs.try_into_u128()?, *bit_size); + let rhs = truncate(rhs.try_into_u128()?, *bit_size); + + // The divisor is being truncated into the type of the operand, which can potentially + // lead to the rhs being zero. + // If the rhs of a division is zero, attempting to evaluate the division will cause a compiler panic. + // Thus, we do not evaluate the division in this method, as we want to avoid triggering a panic, + // and the operation should be handled by ACIR generation. + if matches!(operator, BinaryOp::Div | BinaryOp::Mod) && rhs == 0 { + return None; + } + let result = function(lhs, rhs)?; + // Check for overflow + if result >= 2u128.pow(*bit_size) { + return None; + } + result.into() + } + Type::Numeric(NumericType::Signed { bit_size }) => { + let function = operator.get_i128_function(); + + let lhs = truncate(lhs.try_into_u128()?, *bit_size); + let rhs = truncate(rhs.try_into_u128()?, *bit_size); + let l_pos = lhs < 2u128.pow(bit_size - 1); + let r_pos = rhs < 2u128.pow(bit_size - 1); + let lhs = if l_pos { lhs as i128 } else { -((2u128.pow(*bit_size) - lhs) as i128) }; + let rhs = if r_pos { rhs as i128 } else { -((2u128.pow(*bit_size) - rhs) as i128) }; + // The divisor is being truncated into the type of the operand, which can potentially + // lead to the rhs being zero. + // If the rhs of a division is zero, attempting to evaluate the division will cause a compiler panic. + // Thus, we do not evaluate the division in this method, as we want to avoid triggering a panic, + // and the operation should be handled by ACIR generation. + if matches!(operator, BinaryOp::Div | BinaryOp::Mod) && rhs == 0 { + return None; + } + + let result = function(lhs, rhs)?; + // Check for overflow + if result >= 2i128.pow(*bit_size - 1) || result < -(2i128.pow(*bit_size - 1)) { + return None; + } + let result = + if result >= 0 { result as u128 } else { (2i128.pow(*bit_size) + result) as u128 }; + result.into() + } + _ => return None, + }; + + if matches!(operator, BinaryOp::Eq | BinaryOp::Lt) { + operand_type = Type::bool(); + } + + Some((value, operand_type)) +} + +fn truncate(int: u128, bit_size: u32) -> u128 { + let max = 2u128.pow(bit_size); + int % max +} + +impl BinaryOp { + fn get_field_function(self) -> Option FieldElement> { + match self { + BinaryOp::Add => Some(std::ops::Add::add), + BinaryOp::Sub => Some(std::ops::Sub::sub), + BinaryOp::Mul => Some(std::ops::Mul::mul), + BinaryOp::Div => Some(std::ops::Div::div), + BinaryOp::Eq => Some(|x, y| (x == y).into()), + BinaryOp::Lt => Some(|x, y| (x < y).into()), + // Bitwise operators are unsupported for Fields + BinaryOp::Mod => None, + BinaryOp::And => None, + BinaryOp::Or => None, + BinaryOp::Xor => None, + } + } + + fn get_u128_function(self) -> fn(u128, u128) -> Option { + match self { + BinaryOp::Add => u128::checked_add, + BinaryOp::Sub => u128::checked_sub, + BinaryOp::Mul => u128::checked_mul, + BinaryOp::Div => u128::checked_div, + BinaryOp::Mod => u128::checked_rem, + BinaryOp::And => |x, y| Some(x & y), + BinaryOp::Or => |x, y| Some(x | y), + BinaryOp::Xor => |x, y| Some(x ^ y), + BinaryOp::Eq => |x, y| Some((x == y) as u128), + BinaryOp::Lt => |x, y| Some((x < y) as u128), + } + } + + fn get_i128_function(self) -> fn(i128, i128) -> Option { + match self { + BinaryOp::Add => i128::checked_add, + BinaryOp::Sub => i128::checked_sub, + BinaryOp::Mul => i128::checked_mul, + BinaryOp::Div => i128::checked_div, + BinaryOp::Mod => i128::checked_rem, + BinaryOp::And => |x, y| Some(x & y), + BinaryOp::Or => |x, y| Some(x | y), + BinaryOp::Xor => |x, y| Some(x ^ y), + BinaryOp::Eq => |x, y| Some((x == y) as i128), + BinaryOp::Lt => |x, y| Some((x < y) as i128), + } + } +} diff --git a/compiler/noirc_evaluator/src/ssa/ir/instruction/cast.rs b/compiler/noirc_evaluator/src/ssa/ir/instruction/cast.rs new file mode 100644 index 00000000000..671820e801d --- /dev/null +++ b/compiler/noirc_evaluator/src/ssa/ir/instruction/cast.rs @@ -0,0 +1,58 @@ +use acvm::FieldElement; +use num_bigint::BigUint; + +use super::{DataFlowGraph, Instruction, NumericType, SimplifyResult, Type, Value, ValueId}; + +/// Try to simplify this cast instruction. If the instruction can be simplified to a known value, +/// that value is returned. Otherwise None is returned. +pub(super) fn simplify_cast( + value: ValueId, + dst_typ: &Type, + dfg: &mut DataFlowGraph, +) -> SimplifyResult { + use SimplifyResult::*; + let value = dfg.resolve(value); + + if let Value::Instruction { instruction, .. } = &dfg[value] { + if let Instruction::Cast(original_value, _) = &dfg[*instruction] { + return SimplifiedToInstruction(Instruction::Cast(*original_value, dst_typ.clone())); + } + } + + if let Some(constant) = dfg.get_numeric_constant(value) { + let src_typ = dfg.type_of_value(value); + match (src_typ, dst_typ) { + (Type::Numeric(NumericType::NativeField), Type::Numeric(NumericType::NativeField)) => { + // Field -> Field: use src value + SimplifiedTo(value) + } + ( + Type::Numeric(NumericType::Unsigned { .. }), + Type::Numeric(NumericType::NativeField), + ) => { + // Unsigned -> Field: redefine same constant as Field + SimplifiedTo(dfg.make_constant(constant, dst_typ.clone())) + } + ( + Type::Numeric( + NumericType::NativeField + | NumericType::Unsigned { .. } + | NumericType::Signed { .. }, + ), + Type::Numeric(NumericType::Unsigned { bit_size }), + ) => { + // Field/Unsigned -> unsigned: truncate + let integer_modulus = BigUint::from(2u128).pow(*bit_size); + let constant: BigUint = BigUint::from_bytes_be(&constant.to_be_bytes()); + let truncated = constant % integer_modulus; + let truncated = FieldElement::from_be_bytes_reduce(&truncated.to_bytes_be()); + SimplifiedTo(dfg.make_constant(truncated, dst_typ.clone())) + } + _ => None, + } + } else if *dst_typ == dfg.type_of_value(value) { + SimplifiedTo(value) + } else { + None + } +} diff --git a/compiler/noirc_evaluator/src/ssa/ir/instruction/constrain.rs b/compiler/noirc_evaluator/src/ssa/ir/instruction/constrain.rs new file mode 100644 index 00000000000..7fb0970c834 --- /dev/null +++ b/compiler/noirc_evaluator/src/ssa/ir/instruction/constrain.rs @@ -0,0 +1,126 @@ +use acvm::FieldElement; + +use super::{Binary, BinaryOp, DataFlowGraph, Instruction, Type, Value, ValueId}; + +/// Try to decompose this constrain instruction. This constraint will be broken down such that it instead constrains +/// all the values which are used to compute the values which were being constrained. +pub(super) fn decompose_constrain( + lhs: ValueId, + rhs: ValueId, + msg: Option, + dfg: &mut DataFlowGraph, +) -> Vec { + let lhs = dfg.resolve(lhs); + let rhs = dfg.resolve(rhs); + + if lhs == rhs { + // Remove trivial case `assert_eq(x, x)` + Vec::new() + } else { + match (&dfg[lhs], &dfg[rhs]) { + (Value::NumericConstant { constant, typ }, Value::Instruction { instruction, .. }) + | (Value::Instruction { instruction, .. }, Value::NumericConstant { constant, typ }) + if *typ == Type::bool() => + { + match dfg[*instruction] { + Instruction::Binary(Binary { lhs, rhs, operator: BinaryOp::Eq }) + if constant.is_one() => + { + // Replace an explicit two step equality assertion + // + // v2 = eq v0, u32 v1 + // constrain v2 == u1 1 + // + // with a direct assertion of equality between the two values + // + // v2 = eq v0, u32 v1 + // constrain v0 == v1 + // + // Note that this doesn't remove the value `v2` as it may be used in other instructions, but it + // will likely be removed through dead instruction elimination. + + vec![Instruction::Constrain(lhs, rhs, msg)] + } + + Instruction::Binary(Binary { lhs, rhs, operator: BinaryOp::Mul }) + if constant.is_one() && dfg.type_of_value(lhs) == Type::bool() => + { + // Replace an equality assertion on a boolean multiplication + // + // v2 = mul v0, v1 + // constrain v2 == u1 1 + // + // with a direct assertion that each value is equal to 1 + // + // v2 = mul v0, v1 + // constrain v0 == 1 + // constrain v1 == 1 + // + // This is due to the fact that for `v2` to be 1 then both `v0` and `v1` are 1. + // + // Note that this doesn't remove the value `v2` as it may be used in other instructions, but it + // will likely be removed through dead instruction elimination. + let one = FieldElement::one(); + let one = dfg.make_constant(one, Type::bool()); + + [ + decompose_constrain(lhs, one, msg.clone(), dfg), + decompose_constrain(rhs, one, msg, dfg), + ] + .concat() + } + + Instruction::Binary(Binary { lhs, rhs, operator: BinaryOp::Or }) + if constant.is_zero() => + { + // Replace an equality assertion on an OR + // + // v2 = or v0, v1 + // constrain v2 == u1 0 + // + // with a direct assertion that each value is equal to 0 + // + // v2 = or v0, v1 + // constrain v0 == 0 + // constrain v1 == 0 + // + // This is due to the fact that for `v2` to be 0 then both `v0` and `v1` are 0. + // + // Note that this doesn't remove the value `v2` as it may be used in other instructions, but it + // will likely be removed through dead instruction elimination. + let zero = FieldElement::zero(); + let zero = dfg.make_constant(zero, dfg.type_of_value(lhs)); + + [ + decompose_constrain(lhs, zero, msg.clone(), dfg), + decompose_constrain(rhs, zero, msg, dfg), + ] + .concat() + } + + Instruction::Not(value) => { + // Replace an assertion that a not instruction is truthy + // + // v1 = not v0 + // constrain v1 == u1 1 + // + // with an assertion that the not instruction input is falsy + // + // v1 = not v0 + // constrain v0 == u1 0 + // + // Note that this doesn't remove the value `v1` as it may be used in other instructions, but it + // will likely be removed through dead instruction elimination. + let reversed_constant = FieldElement::from(!constant.is_one()); + let reversed_constant = dfg.make_constant(reversed_constant, Type::bool()); + decompose_constrain(value, reversed_constant, msg, dfg) + } + + _ => vec![Instruction::Constrain(lhs, rhs, msg)], + } + } + + _ => vec![Instruction::Constrain(lhs, rhs, msg)], + } + } +} From d1740dda2d54fb3cff3df06eb08c10ae6d9fd865 Mon Sep 17 00:00:00 2001 From: Savio <72797635+Savio-Sou@users.noreply.github.com> Date: Thu, 25 Jan 2024 11:25:17 +0000 Subject: [PATCH 30/70] chore(github): Suspend GitHub Discussions Ideas and revert to feature request issues (#4153) # Description ## Problem\* The move towards using GitHub Discussions to suggest ideas was found premature following https://github.com/noir-lang/noir/pull/2672, as it introduced additional frictions in: - Requiring the need to switch between Issues / Discussions to distill ideas raised - Discussions are not manageable on GitHub's Project Board ## Summary\* Until we can formally define how the Ideas section in GitHub Discussions should be used, this PR reverts the repo back to using GitHub Issues for feature requests for us to move faster in the meantime. ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [ ] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- .github/ISSUE_TEMPLATE/config.yml | 4 ---- .../{idea_action_plan.yml => feature_request.yml} | 4 ++-- 2 files changed, 2 insertions(+), 6 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/config.yml rename .github/ISSUE_TEMPLATE/{idea_action_plan.yml => feature_request.yml} (90%) diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml deleted file mode 100644 index b5ded344eb9..00000000000 --- a/.github/ISSUE_TEMPLATE/config.yml +++ /dev/null @@ -1,4 +0,0 @@ -contact_links: - - name: Ideas - url: https://github.com/orgs/noir-lang/discussions/new?category=ideas - about: Share ideas for new features diff --git a/.github/ISSUE_TEMPLATE/idea_action_plan.yml b/.github/ISSUE_TEMPLATE/feature_request.yml similarity index 90% rename from .github/ISSUE_TEMPLATE/idea_action_plan.yml rename to .github/ISSUE_TEMPLATE/feature_request.yml index 02fed1fc48b..979ac75811e 100644 --- a/.github/ISSUE_TEMPLATE/idea_action_plan.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -1,5 +1,5 @@ -name: Idea Action Plan -description: Outline the scope and steps for implementing an enhancement. Start with "Ideas" instead to request and discuss new features. +name: Feature Request +description: Suggest an idea for this project. labels: ["enhancement"] body: - type: markdown From 83c5b1e0d533cc437885deb0f3ceffbfe49cba57 Mon Sep 17 00:00:00 2001 From: jfecher Date: Thu, 25 Jan 2024 03:27:01 -0800 Subject: [PATCH 31/70] chore: Add Type: Debug impl (#4156) # Description ## Problem\* Resolves #4151 ## Summary\* Adds a manual `Type: Debug` impl for displaying all the information in types a bit more succinctly. This is helpful while debugging generic code for following type variable links which are otherwise excluded from the `Type: Display` impl. ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- compiler/noirc_frontend/src/hir_def/types.rs | 110 ++++++++++++++++++- 1 file changed, 104 insertions(+), 6 deletions(-) diff --git a/compiler/noirc_frontend/src/hir_def/types.rs b/compiler/noirc_frontend/src/hir_def/types.rs index 2c08a980d23..0ba4cb2da65 100644 --- a/compiler/noirc_frontend/src/hir_def/types.rs +++ b/compiler/noirc_frontend/src/hir_def/types.rs @@ -17,7 +17,7 @@ use crate::{node_interner::StructId, Ident, Signedness}; use super::expr::{HirCallExpression, HirExpression, HirIdent}; -#[derive(Debug, PartialEq, Eq, Clone, Hash)] +#[derive(PartialEq, Eq, Clone, Hash)] pub enum Type { /// A primitive Field type FieldElement, @@ -190,7 +190,7 @@ pub type TypeBindings = HashMap; /// Represents a struct type in the type system. Each instance of this /// rust struct will be shared across all Type::Struct variants that represent /// the same struct type. -#[derive(Debug, Eq)] +#[derive(Eq)] pub struct StructType { /// A unique id representing this struct type. Used to check if two /// struct types are equal. @@ -449,7 +449,7 @@ pub enum TypeVariableKind { /// A TypeVariable is a mutable reference that is either /// bound to some type, or unbound with a given TypeVariableId. -#[derive(Debug, PartialEq, Eq, Clone, Hash)] +#[derive(PartialEq, Eq, Clone, Hash)] pub struct TypeVariable(TypeVariableId, Shared); impl TypeVariable { @@ -516,7 +516,7 @@ impl TypeVariable { /// TypeBindings are the mutable insides of a TypeVariable. /// They are either bound to some type, or are unbound. -#[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[derive(Clone, PartialEq, Eq, Hash)] pub enum TypeBinding { Bound(Type), Unbound(TypeVariableId), @@ -529,7 +529,7 @@ impl TypeBinding { } /// A unique ID used to differentiate different type variables -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +#[derive(Copy, Clone, PartialEq, Eq, Hash)] pub struct TypeVariableId(pub usize); impl Type { @@ -804,7 +804,7 @@ impl std::fmt::Display for Type { Type::Function(args, ret, env) => { let closure_env_text = match **env { Type::Unit => "".to_string(), - _ => format!(" with closure environment {env}"), + _ => format!(" with env {env}"), }; let args = vecmap(args.iter(), ToString::to_string); @@ -1661,3 +1661,101 @@ impl From<&Type> for PrintableType { } } } + +impl std::fmt::Debug for Type { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Type::FieldElement => { + write!(f, "Field") + } + Type::Array(len, typ) => { + if matches!(len.follow_bindings(), Type::NotConstant) { + write!(f, "[{typ:?}]") + } else { + write!(f, "[{typ:?}; {len:?}]") + } + } + Type::Integer(sign, num_bits) => match sign { + Signedness::Signed => write!(f, "i{num_bits}"), + Signedness::Unsigned => write!(f, "u{num_bits}"), + }, + Type::TypeVariable(var, TypeVariableKind::Normal) => write!(f, "{:?}", var), + Type::TypeVariable(binding, TypeVariableKind::IntegerOrField) => { + write!(f, "IntOrField{:?}", binding) + } + Type::TypeVariable(binding, TypeVariableKind::Constant(n)) => { + write!(f, "{}{:?}", n, binding) + } + Type::Struct(s, args) => { + let args = vecmap(args, |arg| format!("{:?}", arg)); + if args.is_empty() { + write!(f, "{:?}", s.borrow()) + } else { + write!(f, "{:?}<{}>", s.borrow(), args.join(", ")) + } + } + Type::TraitAsType(_id, name, generics) => { + write!(f, "impl {}", name)?; + if !generics.is_empty() { + let generics = vecmap(generics, |arg| format!("{:?}", arg)).join(", "); + write!(f, "<{generics}>")?; + } + Ok(()) + } + Type::Tuple(elements) => { + let elements = vecmap(elements, |arg| format!("{:?}", arg)); + write!(f, "({})", elements.join(", ")) + } + Type::Bool => write!(f, "bool"), + Type::String(len) => write!(f, "str<{len:?}>"), + Type::FmtString(len, elements) => { + write!(f, "fmtstr<{len:?}, {elements:?}>") + } + Type::Unit => write!(f, "()"), + Type::Error => write!(f, "error"), + Type::NamedGeneric(binding, name) => write!(f, "{}{:?}", name, binding), + Type::Constant(x) => x.fmt(f), + Type::Forall(typevars, typ) => { + let typevars = vecmap(typevars, |var| format!("{:?}", var)); + write!(f, "forall {}. {:?}", typevars.join(" "), typ) + } + Type::Function(args, ret, env) => { + let closure_env_text = match **env { + Type::Unit => "".to_string(), + _ => format!(" with env {env:?}"), + }; + + let args = vecmap(args.iter(), |arg| format!("{:?}", arg)); + + write!(f, "fn({}) -> {ret:?}{closure_env_text}", args.join(", ")) + } + Type::MutableReference(element) => { + write!(f, "&mut {element:?}") + } + Type::NotConstant => write!(f, "NotConstant"), + } + } +} + +impl std::fmt::Debug for TypeVariableId { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "'{}", self.0) + } +} + +impl std::fmt::Debug for TypeVariable { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{:?}", self.id())?; + + if let TypeBinding::Bound(typ) = &*self.borrow() { + write!(f, " -> {typ:?}")?; + } + Ok(()) + } +} + +impl std::fmt::Debug for StructType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.name) + } +} From ea3fa7ce7bc40db01380c7cc135ca006eea42a19 Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Thu, 25 Jan 2024 11:44:47 +0000 Subject: [PATCH 32/70] chore(ci): fix publishing of `noir_wasm` (#4163) # Description ## Problem\* Resolves https://github.com/noir-lang/noir/issues/4157 ## Summary\* https://github.com/noir-lang/noir/pull/3891 didn't update release flow so it's still trying to build `noir_wasm` using nix. This PR updates to use the new build process. ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- .github/workflows/publish-es-packages.yml | 51 ++++++++++++++--------- 1 file changed, 32 insertions(+), 19 deletions(-) diff --git a/.github/workflows/publish-es-packages.yml b/.github/workflows/publish-es-packages.yml index e360654b46a..eef3d5f8052 100644 --- a/.github/workflows/publish-es-packages.yml +++ b/.github/workflows/publish-es-packages.yml @@ -15,7 +15,7 @@ on: run-name: Publish ES Packages from ${{ inputs.noir-ref }} under @${{ inputs.npm-tag }} tag. jobs: - build-noir_wasm: + build-noirc_abi_wasm: runs-on: ubuntu-latest steps: - name: Checkout sources @@ -32,16 +32,17 @@ jobs: - name: Build wasm package run: | - nix build -L .#noir_wasm + nix build -L .#noirc_abi_wasm - uses: actions/upload-artifact@v3 with: - name: noir_wasm + name: noirc_abi_wasm path: | - result/noir_wasm/nodejs - result/noir_wasm/web + result/noirc_abi_wasm/nodejs + result/noirc_abi_wasm/web - build-noirc_abi_wasm: + build-noir_wasm: + needs: [build-noirc-abi] runs-on: ubuntu-latest steps: - name: Checkout sources @@ -49,23 +50,34 @@ jobs: with: ref: ${{ inputs.noir-ref }} - - name: Setup Nix - uses: ./.github/actions/nix + - name: Setup toolchain + uses: dtolnay/rust-toolchain@1.71.1 + + - uses: Swatinem/rust-cache@v2 with: - github-token: ${{ secrets.GITHUB_TOKEN }} - nix-cache-name: "noir" - cachix-auth-token: ${{ secrets.CACHIXAUTHTOKEN }} - - - name: Build wasm package - run: | - nix build -L .#noirc_abi_wasm + key: noir-wasm + save-if: false - - uses: actions/upload-artifact@v3 + - name: Download noirc_abi_wasm package artifact + uses: actions/download-artifact@v3 with: name: noirc_abi_wasm + path: ./tooling/noirc_abi_wasm + + - name: Install Yarn dependencies + uses: ./.github/actions/setup + + - name: Build noir_wasm + run: yarn workspace @noir-lang/noir_wasm build + + - name: Upload artifact + uses: actions/upload-artifact@v3 + with: + name: noir_wasm path: | - result/noirc_abi_wasm/nodejs - result/noirc_abi_wasm/web + ./compiler/wasm/dist + ./compiler/wasm/build + retention-days: 3 build-acvm_js: runs-on: ubuntu-latest @@ -97,7 +109,6 @@ jobs: runs-on: ubuntu-latest needs: [build-acvm_js, build-noirc_abi_wasm, build-noir_wasm] steps: - - name: Checkout sources uses: actions/checkout@v4 with: @@ -107,10 +118,12 @@ jobs: with: name: acvm_js path: acvm-repo/acvm_js + - uses: actions/download-artifact@v3 with: name: noir_wasm path: compiler/wasm + - uses: actions/download-artifact@v3 with: name: noirc_abi_wasm From 4eca52fe0542e1a122a460abe52a52e022ac834e Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Thu, 25 Jan 2024 12:42:55 +0000 Subject: [PATCH 33/70] chore: fix js package publishing workflow (#4165) # Description ## Problem\* Resolves ## Summary\* This PR fixes an issue in #4163 where the job dependency was mistyped. ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- .github/workflows/publish-es-packages.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish-es-packages.yml b/.github/workflows/publish-es-packages.yml index eef3d5f8052..4d52acd1a5d 100644 --- a/.github/workflows/publish-es-packages.yml +++ b/.github/workflows/publish-es-packages.yml @@ -42,7 +42,7 @@ jobs: result/noirc_abi_wasm/web build-noir_wasm: - needs: [build-noirc-abi] + needs: [build-noirc-abi_wasm] runs-on: ubuntu-latest steps: - name: Checkout sources From c8026d557d535b10fe455165d6445076df7a03de Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Thu, 25 Jan 2024 12:30:22 +0000 Subject: [PATCH 34/70] feat: add support for overriding expression width (#4117) # Description ## Problem\* Resolves #3854 ## Summary\* This PR adds the `expression-width` option to the CLI which allows users to specify the expression width they want to use. Passing zero will result in an unbounded width. ## Additional Context ## Documentation\* Check one: - [ ] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [ ] I have tested the changes locally. - [ ] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --------- Co-authored-by: kevaundray --- acvm-repo/acvm/src/lib.rs | 10 +++++++ compiler/noirc_driver/src/lib.rs | 18 ++++++++++-- tooling/nargo_cli/src/cli/compile_cmd.rs | 5 +++- tooling/nargo_cli/src/cli/dap_cmd.rs | 37 +++++++++++++++++++----- tooling/nargo_cli/src/cli/debug_cmd.rs | 5 +++- tooling/nargo_cli/src/cli/execute_cmd.rs | 5 +++- tooling/nargo_cli/src/cli/info_cmd.rs | 5 +++- tooling/nargo_cli/src/cli/prove_cmd.rs | 5 +++- tooling/nargo_cli/src/cli/verify_cmd.rs | 5 +++- 9 files changed, 79 insertions(+), 16 deletions(-) diff --git a/acvm-repo/acvm/src/lib.rs b/acvm-repo/acvm/src/lib.rs index 626bb2c9b91..264479d8a12 100644 --- a/acvm-repo/acvm/src/lib.rs +++ b/acvm-repo/acvm/src/lib.rs @@ -31,3 +31,13 @@ pub enum ExpressionWidth { Unbounded, Bounded { width: usize }, } + +impl From for ExpressionWidth { + fn from(width: usize) -> ExpressionWidth { + if width == 0 { + ExpressionWidth::Unbounded + } else { + ExpressionWidth::Bounded { width } + } + } +} diff --git a/compiler/noirc_driver/src/lib.rs b/compiler/noirc_driver/src/lib.rs index a2570b26f3e..6fd69f8b576 100644 --- a/compiler/noirc_driver/src/lib.rs +++ b/compiler/noirc_driver/src/lib.rs @@ -3,6 +3,7 @@ #![warn(unreachable_pub)] #![warn(clippy::semicolon_if_nothing_returned)] +use acvm::ExpressionWidth; use clap::Args; use fm::{FileId, FileManager}; use iter_extended::vecmap; @@ -16,7 +17,6 @@ use noirc_frontend::hir::Context; use noirc_frontend::macros_api::MacroProcessor; use noirc_frontend::monomorphization::monomorphize; use noirc_frontend::node_interner::FuncId; -use serde::{Deserialize, Serialize}; use std::path::Path; use tracing::info; @@ -43,8 +43,12 @@ pub const NOIRC_VERSION: &str = env!("CARGO_PKG_VERSION"); pub const NOIR_ARTIFACT_VERSION_STRING: &str = concat!(env!("CARGO_PKG_VERSION"), "+", env!("GIT_COMMIT")); -#[derive(Args, Clone, Debug, Default, Serialize, Deserialize)] +#[derive(Args, Clone, Debug, Default)] pub struct CompileOptions { + /// Override the expression width requested by the backend. + #[arg(long, value_parser = parse_expression_width)] + pub expression_width: Option, + /// Force a full recompilation. #[arg(long = "force")] pub force_compile: bool, @@ -81,6 +85,16 @@ pub struct CompileOptions { pub show_monomorphized: bool, } +fn parse_expression_width(input: &str) -> Result { + use std::io::{Error, ErrorKind}; + + let width = input + .parse::() + .map_err(|err| Error::new(ErrorKind::InvalidInput, err.to_string()))?; + + Ok(ExpressionWidth::from(width)) +} + /// Helper type used to signify where only warnings are expected in file diagnostics pub type Warnings = Vec; diff --git a/tooling/nargo_cli/src/cli/compile_cmd.rs b/tooling/nargo_cli/src/cli/compile_cmd.rs index 25cf06a7310..34fb05249b5 100644 --- a/tooling/nargo_cli/src/cli/compile_cmd.rs +++ b/tooling/nargo_cli/src/cli/compile_cmd.rs @@ -61,7 +61,10 @@ pub(crate) fn run( insert_all_files_for_workspace_into_file_manager(&workspace, &mut workspace_file_manager); let parsed_files = parse_all(&workspace_file_manager); - let expression_width = backend.get_backend_info_or_default(); + let expression_width = args + .compile_options + .expression_width + .unwrap_or_else(|| backend.get_backend_info_or_default()); let (compiled_program, compiled_contracts) = compile_workspace( &workspace_file_manager, &parsed_files, diff --git a/tooling/nargo_cli/src/cli/dap_cmd.rs b/tooling/nargo_cli/src/cli/dap_cmd.rs index a02cd66fd4c..67322b1873e 100644 --- a/tooling/nargo_cli/src/cli/dap_cmd.rs +++ b/tooling/nargo_cli/src/cli/dap_cmd.rs @@ -1,4 +1,5 @@ use acvm::acir::native_types::WitnessMap; +use acvm::ExpressionWidth; use backend_interface::Backend; use clap::Args; use nargo::constants::PROVER_INPUT_FILE; @@ -29,7 +30,21 @@ use crate::errors::CliError; use super::NargoConfig; #[derive(Debug, Clone, Args)] -pub(crate) struct DapCommand; +pub(crate) struct DapCommand { + /// Override the expression width requested by the backend. + #[arg(long, value_parser = parse_expression_width)] + expression_width: Option, +} + +fn parse_expression_width(input: &str) -> Result { + use std::io::{Error, ErrorKind}; + + let width = input + .parse::() + .map_err(|err| Error::new(ErrorKind::InvalidInput, err.to_string()))?; + + Ok(ExpressionWidth::from(width)) +} struct LoadError(&'static str); @@ -54,16 +69,14 @@ fn find_workspace(project_folder: &str, package: Option<&str>) -> Option, prover_name: &str, + expression_width: ExpressionWidth, ) -> Result<(CompiledProgram, WitnessMap), LoadError> { let workspace = find_workspace(project_folder, package).ok_or(LoadError("Cannot open workspace"))?; - let expression_width = - backend.get_backend_info().map_err(|_| LoadError("Failed to get backend info"))?; let package = workspace .into_iter() .find(|p| p.is_binary()) @@ -100,7 +113,7 @@ fn load_and_compile_project( fn loop_uninitialized_dap( mut server: Server, - backend: &Backend, + expression_width: ExpressionWidth, ) -> Result<(), ServerError> { loop { let req = match server.poll_request()? { @@ -140,7 +153,12 @@ fn loop_uninitialized_dap( eprintln!("Package: {}", package.unwrap_or("(default)")); eprintln!("Prover name: {}", prover_name); - match load_and_compile_project(backend, project_folder, package, prover_name) { + match load_and_compile_project( + project_folder, + package, + prover_name, + expression_width, + ) { Ok((compiled_program, initial_witness)) => { server.respond(req.ack()?)?; @@ -176,12 +194,15 @@ fn loop_uninitialized_dap( pub(crate) fn run( backend: &Backend, - _args: DapCommand, + args: DapCommand, _config: NargoConfig, ) -> Result<(), CliError> { let output = BufWriter::new(std::io::stdout()); let input = BufReader::new(std::io::stdin()); let server = Server::new(input, output); - loop_uninitialized_dap(server, backend).map_err(CliError::DapError) + let expression_width = + args.expression_width.unwrap_or_else(|| backend.get_backend_info_or_default()); + + loop_uninitialized_dap(server, expression_width).map_err(CliError::DapError) } diff --git a/tooling/nargo_cli/src/cli/debug_cmd.rs b/tooling/nargo_cli/src/cli/debug_cmd.rs index 58cc453e01b..a0bac3bdac1 100644 --- a/tooling/nargo_cli/src/cli/debug_cmd.rs +++ b/tooling/nargo_cli/src/cli/debug_cmd.rs @@ -54,7 +54,10 @@ pub(crate) fn run( Some(NOIR_ARTIFACT_VERSION_STRING.to_string()), )?; let target_dir = &workspace.target_directory_path(); - let expression_width = backend.get_backend_info()?; + let expression_width = args + .compile_options + .expression_width + .unwrap_or_else(|| backend.get_backend_info_or_default()); let mut workspace_file_manager = file_manager_with_stdlib(std::path::Path::new("")); insert_all_files_for_workspace_into_file_manager(&workspace, &mut workspace_file_manager); diff --git a/tooling/nargo_cli/src/cli/execute_cmd.rs b/tooling/nargo_cli/src/cli/execute_cmd.rs index c1fd398350c..a3fcebab94f 100644 --- a/tooling/nargo_cli/src/cli/execute_cmd.rs +++ b/tooling/nargo_cli/src/cli/execute_cmd.rs @@ -68,7 +68,10 @@ pub(crate) fn run( insert_all_files_for_workspace_into_file_manager(&workspace, &mut workspace_file_manager); let parsed_files = parse_all(&workspace_file_manager); - let expression_width = backend.get_backend_info_or_default(); + let expression_width = args + .compile_options + .expression_width + .unwrap_or_else(|| backend.get_backend_info_or_default()); let binary_packages = workspace.into_iter().filter(|package| package.is_binary()); for package in binary_packages { let compilation_result = compile_program( diff --git a/tooling/nargo_cli/src/cli/info_cmd.rs b/tooling/nargo_cli/src/cli/info_cmd.rs index 0e9feaca1ca..131fd6ad214 100644 --- a/tooling/nargo_cli/src/cli/info_cmd.rs +++ b/tooling/nargo_cli/src/cli/info_cmd.rs @@ -69,7 +69,10 @@ pub(crate) fn run( insert_all_files_for_workspace_into_file_manager(&workspace, &mut workspace_file_manager); let parsed_files = parse_all(&workspace_file_manager); - let expression_width = backend.get_backend_info_or_default(); + let expression_width = args + .compile_options + .expression_width + .unwrap_or_else(|| backend.get_backend_info_or_default()); let (compiled_programs, compiled_contracts) = compile_workspace( &workspace_file_manager, &parsed_files, diff --git a/tooling/nargo_cli/src/cli/prove_cmd.rs b/tooling/nargo_cli/src/cli/prove_cmd.rs index 479ca2c9452..1d20e97af85 100644 --- a/tooling/nargo_cli/src/cli/prove_cmd.rs +++ b/tooling/nargo_cli/src/cli/prove_cmd.rs @@ -69,7 +69,10 @@ pub(crate) fn run( insert_all_files_for_workspace_into_file_manager(&workspace, &mut workspace_file_manager); let parsed_files = parse_all(&workspace_file_manager); - let expression_width = backend.get_backend_info()?; + let expression_width = args + .compile_options + .expression_width + .unwrap_or_else(|| backend.get_backend_info_or_default()); let binary_packages = workspace.into_iter().filter(|package| package.is_binary()); for package in binary_packages { let compilation_result = compile_program( diff --git a/tooling/nargo_cli/src/cli/verify_cmd.rs b/tooling/nargo_cli/src/cli/verify_cmd.rs index 582fa32bd8b..ea4aaa051bb 100644 --- a/tooling/nargo_cli/src/cli/verify_cmd.rs +++ b/tooling/nargo_cli/src/cli/verify_cmd.rs @@ -54,7 +54,10 @@ pub(crate) fn run( insert_all_files_for_workspace_into_file_manager(&workspace, &mut workspace_file_manager); let parsed_files = parse_all(&workspace_file_manager); - let expression_width = backend.get_backend_info()?; + let expression_width = args + .compile_options + .expression_width + .unwrap_or_else(|| backend.get_backend_info_or_default()); let binary_packages = workspace.into_iter().filter(|package| package.is_binary()); for package in binary_packages { let compilation_result = compile_program( From 0590432515b8ac760f5cc9ecda8b909e2b4dd681 Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Thu, 25 Jan 2024 13:15:45 +0000 Subject: [PATCH 35/70] chore: Update publish-es-packages.yml (#4166) # Description ## Problem\* Resolves ## Summary\* One more attempt after #4165 :sweat_smile: ## Additional Context ## Documentation\* Check one: - [ ] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [ ] I have tested the changes locally. - [ ] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- .github/workflows/publish-es-packages.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish-es-packages.yml b/.github/workflows/publish-es-packages.yml index 4d52acd1a5d..2c825ffd45f 100644 --- a/.github/workflows/publish-es-packages.yml +++ b/.github/workflows/publish-es-packages.yml @@ -42,7 +42,7 @@ jobs: result/noirc_abi_wasm/web build-noir_wasm: - needs: [build-noirc-abi_wasm] + needs: [build-noirc_abi_wasm] runs-on: ubuntu-latest steps: - name: Checkout sources From 3f5bad3e60b8e2e72155e09f3951a73c3087a9c0 Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Thu, 25 Jan 2024 15:12:37 +0000 Subject: [PATCH 36/70] fix: zero out input to `to_radix` calls if inactive (#4116) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Description ## Problem\* Resolves ## Summary\* In situations where a `to_le_bytes` call is in an inactive if-statement, the requirement for the produced byte array to represent the input field is not disabled. This can result in situations such as below where we want to decompose a value into a number of bytes which is dependent on the inputs to the circuit. https://github.com/porco-rosso-j/safe-recovery-noir/blob/b80a1fd49d370bd095827318b378c8fdef2e2d9b/circuits/social/src/root.nr#L11-L22 All branches of this snippet are limited by the fact that the first will fail on `index` with values greater than 1. ``` fn main(x: Field, cond: bool) { if cond { let bad_byte_array = x.to_le_bytes(1); assert_eq(bad_byte_array.len(), 1); } } ``` This compiles down to ``` acir fn main f0 { b0(v0: Field, v1: u1): enable_side_effects v1 v31, v32 = call to_le_radix(v0, u32 2⁸, u32 1) v34 = cast v1 as Field v35 = mul v31, v34 constrain v35 == v34 enable_side_effects u1 1 return } ``` The `to_le_radix` will revert for all `v0 >= 8` no matter the value of `v1`. I've modified the `flatten_cfg` pass such that we multiply in the side effects variable to zero out the input should the instruction be deactivated. ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- .../noirc_evaluator/src/ssa/ir/instruction.rs | 5 ++-- .../src/ssa/opt/flatten_cfg.rs | 26 +++++++++++++++++-- .../intrinsic_die/src/main.nr | 2 -- .../execution_success/to_le_bytes/Prover.toml | 1 + .../execution_success/to_le_bytes/src/main.nr | 9 ++++++- 5 files changed, 36 insertions(+), 7 deletions(-) diff --git a/compiler/noirc_evaluator/src/ssa/ir/instruction.rs b/compiler/noirc_evaluator/src/ssa/ir/instruction.rs index 280a0c32e64..331a02a6974 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/instruction.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/instruction.rs @@ -87,6 +87,9 @@ impl Intrinsic { match self { Intrinsic::AssertConstant | Intrinsic::ApplyRangeConstraint => true, + // These apply a constraint that the input must fit into a specified number of limbs. + Intrinsic::ToBits(_) | Intrinsic::ToRadix(_) => true, + Intrinsic::Sort | Intrinsic::ArrayLen | Intrinsic::SlicePushBack @@ -96,8 +99,6 @@ impl Intrinsic { | Intrinsic::SliceInsert | Intrinsic::SliceRemove | Intrinsic::StrAsBytes - | Intrinsic::ToBits(_) - | Intrinsic::ToRadix(_) | Intrinsic::FromField | Intrinsic::AsField => false, diff --git a/compiler/noirc_evaluator/src/ssa/opt/flatten_cfg.rs b/compiler/noirc_evaluator/src/ssa/opt/flatten_cfg.rs index 6bdf2ab1c0a..1059994b9be 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/flatten_cfg.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/flatten_cfg.rs @@ -144,9 +144,9 @@ use crate::ssa::{ dfg::{CallStack, InsertInstructionResult}, function::Function, function_inserter::FunctionInserter, - instruction::{BinaryOp, Instruction, InstructionId, TerminatorInstruction}, + instruction::{BinaryOp, Instruction, InstructionId, Intrinsic, TerminatorInstruction}, types::Type, - value::ValueId, + value::{Value, ValueId}, }, ssa_gen::Ssa, }; @@ -683,6 +683,28 @@ impl<'f> Context<'f> { ); Instruction::RangeCheck { value, max_bit_size, assert_message } } + Instruction::Call { func, mut arguments } => match self.inserter.function.dfg[func] + { + Value::Intrinsic(Intrinsic::ToBits(_) | Intrinsic::ToRadix(_)) => { + let field = arguments[0]; + let argument_type = self.inserter.function.dfg.type_of_value(field); + + let casted_condition = self.insert_instruction( + Instruction::Cast(condition, argument_type), + call_stack.clone(), + ); + let field = self.insert_instruction( + Instruction::binary(BinaryOp::Mul, field, casted_condition), + call_stack.clone(), + ); + + arguments[0] = field; + + Instruction::Call { func, arguments } + } + + _ => Instruction::Call { func, arguments }, + }, other => other, } } else { diff --git a/test_programs/compile_success_empty/intrinsic_die/src/main.nr b/test_programs/compile_success_empty/intrinsic_die/src/main.nr index 88f7a3634c1..8cac707dfea 100644 --- a/test_programs/compile_success_empty/intrinsic_die/src/main.nr +++ b/test_programs/compile_success_empty/intrinsic_die/src/main.nr @@ -1,8 +1,6 @@ use dep::std; // This test checks that we perform dead-instruction-elimination on intrinsic functions. fn main(x: Field) { - let bytes = x.to_be_bytes(32); - let hash = std::hash::pedersen_commitment([x]); let _p1 = std::scalar_mul::fixed_base_embedded_curve(x, 0); } diff --git a/test_programs/execution_success/to_le_bytes/Prover.toml b/test_programs/execution_success/to_le_bytes/Prover.toml index 07fe857ac7c..bf58776d557 100644 --- a/test_programs/execution_success/to_le_bytes/Prover.toml +++ b/test_programs/execution_success/to_le_bytes/Prover.toml @@ -1 +1,2 @@ x = "2040124" +cond = false \ No newline at end of file diff --git a/test_programs/execution_success/to_le_bytes/src/main.nr b/test_programs/execution_success/to_le_bytes/src/main.nr index 05eefc0f143..a0b48efe528 100644 --- a/test_programs/execution_success/to_le_bytes/src/main.nr +++ b/test_programs/execution_success/to_le_bytes/src/main.nr @@ -1,4 +1,4 @@ -fn main(x: Field) -> pub [u8; 31] { +fn main(x: Field, cond: bool) -> pub [u8; 31] { // The result of this byte array will be little-endian let byte_array = x.to_le_bytes(31); assert(byte_array.len() == 31); @@ -7,5 +7,12 @@ fn main(x: Field) -> pub [u8; 31] { for i in 0..31 { bytes[i] = byte_array[i]; } + + if cond { + // We've set x = "2040124" so we shouldn't be able to represent this as a single byte. + let bad_byte_array = x.to_le_bytes(1); + assert_eq(bad_byte_array.len(), 1); + } + bytes } From ed14628cc6724acb092dd56c646f900579e6ff26 Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Thu, 25 Jan 2024 17:58:02 +0000 Subject: [PATCH 37/70] chore: integrate code snippets script into docs (#4164) # Description ## Problem\* Resolves ## Summary\* This PR sets up code snippets in the Noir docs. ## Additional Context ## Documentation\* Check one: - [ ] No documentation needed. - [x] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- .github/workflows/docs-pr.yml | 9 + docs/.gitignore | 2 + .../cryptographic_primitives/hashes.mdx | 31 +- docs/docs/noir/standard_library/traits.md | 69 +--- docs/docusaurus.config.ts | 1 + docs/package.json | 5 +- docs/scripts/preprocess/include_code.js | 312 ++++++++++++++++++ docs/scripts/preprocess/index.js | 141 ++++++++ noir_stdlib/src/cmp.nr | 6 +- noir_stdlib/src/ops.nr | 23 +- .../execution_success/keccak256/src/main.nr | 7 +- .../pedersen_commitment/Nargo.toml | 6 + .../pedersen_commitment/Prover.toml | 6 + .../pedersen_commitment/src/main.nr | 10 + .../pedersen_hash/Nargo.toml | 6 + .../pedersen_hash/Prover.toml | 4 + .../pedersen_hash/src/main.nr | 9 + .../poseidon_bn254_hash/src/main.nr | 2 + 18 files changed, 558 insertions(+), 91 deletions(-) create mode 100644 docs/scripts/preprocess/include_code.js create mode 100644 docs/scripts/preprocess/index.js create mode 100644 test_programs/execution_success/pedersen_commitment/Nargo.toml create mode 100644 test_programs/execution_success/pedersen_commitment/Prover.toml create mode 100644 test_programs/execution_success/pedersen_commitment/src/main.nr create mode 100644 test_programs/execution_success/pedersen_hash/Nargo.toml create mode 100644 test_programs/execution_success/pedersen_hash/Prover.toml create mode 100644 test_programs/execution_success/pedersen_hash/src/main.nr diff --git a/.github/workflows/docs-pr.yml b/.github/workflows/docs-pr.yml index f4a1be826a8..87bec37c438 100644 --- a/.github/workflows/docs-pr.yml +++ b/.github/workflows/docs-pr.yml @@ -54,6 +54,15 @@ jobs: - name: Checkout code uses: actions/checkout@v4 + - name: Setup toolchain + uses: dtolnay/rust-toolchain@1.71.1 + + - uses: Swatinem/rust-cache@v2 + with: + key: x86_64-unknown-linux-gnu + cache-on-failure: false + save-if: false + - name: Install Yarn dependencies uses: ./.github/actions/setup diff --git a/docs/.gitignore b/docs/.gitignore index 4f6eee8284e..501e7e465ea 100644 --- a/docs/.gitignore +++ b/docs/.gitignore @@ -3,6 +3,8 @@ # Production /build +processed-docs +processed-docs-cache # Generated files .docusaurus diff --git a/docs/docs/noir/standard_library/cryptographic_primitives/hashes.mdx b/docs/docs/noir/standard_library/cryptographic_primitives/hashes.mdx index 3c5f7f79603..3d33630bc1a 100644 --- a/docs/docs/noir/standard_library/cryptographic_primitives/hashes.mdx +++ b/docs/docs/noir/standard_library/cryptographic_primitives/hashes.mdx @@ -58,16 +58,10 @@ fn pedersen_hash(_input : [Field]) -> Field example: -```rust -fn main() { - let x = [163, 117, 178, 149]; // some random bytes - let hash = std::hash::pedersen_hash(x); -} -``` +#include_code pedersen-hash test_programs/execution_success/pedersen_hash/src/main.nr rust - ## pedersen_commitment @@ -79,12 +73,7 @@ fn pedersen_commitment(_input : [Field]) -> [Field; 2] example: -```rust -fn main() { - let x = [163, 117, 178, 149]; // some random bytes - let commitment = std::hash::pedersen_commitment(x); -} -``` +#include_code pedersen-commitment test_programs/execution_success/pedersen_commitment/src/main.nr rust @@ -100,13 +89,7 @@ fn keccak256(_input : [u8; N], _message_size: u32) -> [u8; 32] example: -```rust -fn main() { - let x = [163, 117, 178, 149]; // some random bytes - let message_size = 4; - let hash = std::hash::keccak256(x, message_size); -} -``` +#include_code keccak256 test_programs/execution_success/keccak256/src/main.nr rust @@ -122,13 +105,7 @@ fn hash_1(input: [Field; 1]) -> Field example: -```rust -fn main() -{ - let hash_2 = std::hash::poseidon::bn254::hash_2([1, 2]); - assert(hash2 == 0x115cc0f5e7d690413df64c6b9662e9cf2a3617f2743245519e19607a4417189a); -} -``` +#include_code poseidon test_programs/execution_success/poseidon_bn254_hash/src/main.nr rust ## mimc_bn254 and mimc diff --git a/docs/docs/noir/standard_library/traits.md b/docs/docs/noir/standard_library/traits.md index f2960ca5080..841e512e7de 100644 --- a/docs/docs/noir/standard_library/traits.md +++ b/docs/docs/noir/standard_library/traits.md @@ -56,11 +56,8 @@ types such as arrays are filled with default values of their element type. ### `std::cmp::Eq` -```rust -trait Eq { - fn eq(self, other: Self) -> bool; -} -``` +#include_code eq-trait noir_stdlib/src/cmp.nr rust + Returns `true` if `self` is equal to `other`. Implementing this trait on a type allows the type to be used with `==` and `!=`. @@ -97,13 +94,9 @@ impl Eq for (A, B, C, D, E) where A: Eq, B: Eq, C: Eq, D: Eq, E: Eq { .. } ``` -### `std::cmp::Cmp` +### `std::cmp::Ord` -```rust -trait Cmp { - fn cmp(self, other: Self) -> Ordering; -} -``` +#include_code ord-trait noir_stdlib/src/cmp.nr rust `a.cmp(b)` compares two values returning `Ordering::less()` if `a < b`, `Ordering::equal()` if `a == b`, or `Ordering::greater()` if `a > b`. @@ -151,23 +144,10 @@ These traits abstract over addition, subtraction, multiplication, and division r Implementing these traits for a given type will also allow that type to be used with the corresponding operator for that trait (`+` for Add, etc) in addition to the normal method names. -```rust -trait Add { - fn add(self, other: Self) -> Self; -} - -trait Sub { - fn sub(self, other: Self) -> Self; -} - -trait Mul { - fn mul(self, other: Self) -> Self; -} - -trait Div { - fn div(self, other: Self) -> Self; -} -``` +#include_code add-trait noir_stdlib/src/ops.nr rust +#include_code sub-trait noir_stdlib/src/ops.nr rust +#include_code mul-trait noir_stdlib/src/ops.nr rust +#include_code div-trait noir_stdlib/src/ops.nr rust The implementations block below is given for the `Add` trait, but the same types that implement `Add` also implement `Sub`, `Mul`, and `Div`. @@ -189,11 +169,7 @@ impl Add for u64 { .. } ### `std::ops::Rem` -```rust -trait Rem { - fn rem(self, other: Self) -> Self; -} -``` +#include_code rem-trait noir_stdlib/src/ops.nr rust `Rem::rem(a, b)` is the remainder function returning the result of what is left after dividing `a` and `b`. Implementing `Rem` allows the `%` operator @@ -216,19 +192,9 @@ impl Rem for i64 { fn rem(self, other: i64) -> i64 { self % other } } ### `std::ops::{ BitOr, BitAnd, BitXor }` -```rust -trait BitOr { - fn bitor(self, other: Self) -> Self; -} - -trait BitAnd { - fn bitand(self, other: Self) -> Self; -} - -trait BitXor { - fn bitxor(self, other: Self) -> Self; -} -``` +#include_code bitor-trait noir_stdlib/src/ops.nr rust +#include_code bitand-trait noir_stdlib/src/ops.nr rust +#include_code bitxor-trait noir_stdlib/src/ops.nr rust Traits for the bitwise operations `|`, `&`, and `^`. @@ -255,15 +221,8 @@ impl BitOr for i64 { fn bitor(self, other: i64) -> i64 { self | other } } ### `std::ops::{ Shl, Shr }` -```rust -trait Shl { - fn shl(self, other: Self) -> Self; -} - -trait Shr { - fn shr(self, other: Self) -> Self; -} -``` +#include_code shl-trait noir_stdlib/src/ops.nr rust +#include_code shr-trait noir_stdlib/src/ops.nr rust Traits for a bit shift left and bit shift right. diff --git a/docs/docusaurus.config.ts b/docs/docusaurus.config.ts index aacc318f5be..4e0d053f61e 100644 --- a/docs/docusaurus.config.ts +++ b/docs/docusaurus.config.ts @@ -26,6 +26,7 @@ export default { '@docusaurus/preset-classic', { docs: { + path: "processed-docs", sidebarPath: './sidebars.js', routeBasePath: '/docs', remarkPlugins: [math], diff --git a/docs/package.json b/docs/package.json index 1e3efcfe3d1..6c706e4f514 100644 --- a/docs/package.json +++ b/docs/package.json @@ -3,8 +3,9 @@ "version": "0.0.0", "private": true, "scripts": { - "start": "docusaurus start", - "build": "yarn version::stables && docusaurus build", + "preprocess": "yarn node ./scripts/preprocess/index.js", + "start": "yarn preprocess && docusaurus start", + "build": "yarn preprocess && yarn version::stables && docusaurus build", "version::stables": "ts-node ./scripts/setStable.ts", "serve": "serve build" }, diff --git a/docs/scripts/preprocess/include_code.js b/docs/scripts/preprocess/include_code.js new file mode 100644 index 00000000000..ffe50065002 --- /dev/null +++ b/docs/scripts/preprocess/include_code.js @@ -0,0 +1,312 @@ +const fs = require('fs'); +const path = require('path'); +const childProcess = require('child_process'); + +const getLineNumberFromIndex = (fileContent, index) => { + return fileContent.substring(0, index).split('\n').length; +}; + +/** + * Search for lines of the form + */ +function processHighlighting(codeSnippet, identifier) { + const lines = codeSnippet.split('\n'); + /** + * For an identifier = bar: + * + * Matches of the form: `highlight-next-line:foo:bar:baz` will be replaced with "highlight-next-line". + * Matches of the form: `highlight-next-line:foo:baz` will be replaced with "". + */ + const regex1 = /highlight-next-line:([a-zA-Z0-9-._:]+)/; + const replacement1 = 'highlight-next-line'; + const regex2 = /highlight-start:([a-zA-Z0-9-._:]+)/; + const replacement2 = 'highlight-start'; + const regex3 = /highlight-end:([a-zA-Z0-9-._:]+)/; + const replacement3 = 'highlight-end'; + const regex4 = /this-will-error:([a-zA-Z0-9-._:]+)/; + const replacement4 = 'this-will-error'; + + let result = ''; + let mutated = false; + + const processLine = (line, regex, replacement) => { + const match = line.match(regex); + if (match) { + mutated = true; + + const identifiers = match[1].split(':'); + if (identifiers.includes(identifier)) { + line = line.replace(match[0], replacement); + } else { + // Remove matched text completely + line = line.replace(match[0], ''); + } + } else { + // No match: it's an ordinary line of code. + } + return line.trim() == '//' || line.trim() == '#' ? '' : line; + }; + + for (let line of lines) { + mutated = false; + line = processLine(line, regex1, replacement1); + line = processLine(line, regex2, replacement2); + line = processLine(line, regex3, replacement3); + line = processLine(line, regex4, replacement4); + result += line === '' && mutated ? '' : line + '\n'; + } + + return result.trim(); +} + +let lastReleasedVersion; + +/** Returns the last released tag */ +function getLatestTag() { + if (!lastReleasedVersion) { + const manifest = path.resolve(__dirname, '../../../.release-please-manifest.json'); + lastReleasedVersion = JSON.parse(fs.readFileSync(manifest).toString())['.']; + } + return lastReleasedVersion ? `v${lastReleasedVersion}` : undefined; +} + +/** Returns whether to use the latest release or the current version of stuff. */ +function useLastRelease() { + return process.env.NETLIFY || process.env.INCLUDE_RELEASED_CODE; +} + +/** + * Returns the contents of a file. If the build is running for publishing, it will load the contents + * of the file in the last released version. + */ +function readFile(filePath, tag) { + if (tag && tag !== 'master') { + try { + const root = path.resolve(__dirname, '../../../'); + const relPath = path.relative(root, filePath); + const taggedPath = `${tag}:${relPath}`; + return childProcess.execSync('git show', taggedPath).toString(); + } catch (err) { + console.error(`Error reading file ${filePath} from version ${tag}. Falling back to current content.`); + } + } + return fs.readFileSync(filePath, 'utf-8'); +} + +/** Extracts a code snippet, trying with the last release if applicable, and falling back to current content. */ +function extractCodeSnippet(filePath, identifier, requesterFile) { + if (useLastRelease()) { + try { + return doExtractCodeSnippet(filePath, identifier, false); + } catch (err) { + console.error( + `Error extracting code snippet ${identifier} from ${path.basename( + filePath, + )} requested by ${requesterFile}: ${err}. Falling back to current content.`, + ); + } + } + + return doExtractCodeSnippet(filePath, identifier, true); +} + +/** + * Parse a code file, looking for identifiers of the form: + * `docs:start:${identifier}` and `docs:end:{identifier}`. + * Extract that section of code. + * + * It's complicated if code snippet identifiers overlap (i.e. the 'start' of one code snippet is in the + * middle of another code snippet). The extra logic in this function searches for all identifiers, and + * removes any which fall within the bounds of the code snippet for this particular `identifier` param. + * @returns the code snippet, and start and end line numbers which can later be used for creating a link to github source code. + */ +function doExtractCodeSnippet(filePath, identifier, useCurrent) { + const tag = useCurrent ? 'master' : getLatestTag(); + let fileContent = readFile(filePath, tag); + let lineRemovalCount = 0; + let linesToRemove = []; + + const startRegex = /(?:\/\/|#)\s+docs:start:([a-zA-Z0-9-._:]+)/g; // `g` will iterate through the regex.exec loop + const endRegex = /(?:\/\/|#)\s+docs:end:([a-zA-Z0-9-._:]+)/g; + + /** + * Search for one of the regex statements in the code file. If it's found, return the line as a string and the line number. + */ + const lookForMatch = (regex) => { + let match; + let matchFound = false; + let matchedLineNum = null; + let actualMatch = null; + let lines = fileContent.split('\n'); + while ((match = regex.exec(fileContent))) { + if (match !== null) { + const identifiers = match[1].split(':'); + let tempMatch = identifiers.includes(identifier) ? match : null; + + if (tempMatch === null) { + // If it's not a match, we'll make a note that we should remove the matched text, because it's from some other identifier and should not appear in the snippet for this identifier. + for (let i = 0; i < lines.length; i++) { + let line = lines[i]; + if (line.trim() == match[0].trim()) { + linesToRemove.push(i + 1); // lines are indexed from 1 + ++lineRemovalCount; + } + } + } else { + if (matchFound === true) { + throw new Error(`Duplicate for regex ${regex} and identifier ${identifier}`); + } + matchFound = true; + matchedLineNum = getLineNumberFromIndex(fileContent, tempMatch.index); + actualMatch = tempMatch; + } + } + } + + return [actualMatch, matchedLineNum]; + }; + + let [startMatch, startLineNum] = lookForMatch(startRegex); + let [endMatch, endLineNum] = lookForMatch(endRegex); + + // Double-check that the extracted line actually contains the required start and end identifier. + if (startMatch !== null) { + const startIdentifiers = startMatch[1].split(':'); + startMatch = startIdentifiers.includes(identifier) ? startMatch : null; + } + if (endMatch !== null) { + const endIdentifiers = endMatch[1].split(':'); + endMatch = endIdentifiers.includes(identifier) ? endMatch : null; + } + + if (startMatch === null || endMatch === null) { + if (startMatch === null && endMatch === null) { + throw new Error(`Identifier "${identifier}" not found in file "${filePath}"`); + } else if (startMatch === null) { + throw new Error(`Start line "docs:start:${identifier}" not found in file "${filePath}"`); + } else { + throw new Error(`End line "docs:end:${identifier}" not found in file "${filePath}"`); + } + } + + let lines = fileContent.split('\n'); + + // We only want to remove lines which actually fall within the bounds of our code snippet, so narrow down the list of lines that we actually want to remove. + linesToRemove = linesToRemove.filter((lineNum) => { + const removal_in_bounds = lineNum >= startLineNum && lineNum <= endLineNum; + return removal_in_bounds; + }); + + // Remove lines which contain `docs:` comments for unrelated identifiers: + lines = lines.filter((l, i) => { + return !linesToRemove.includes(i + 1); // lines are indexed from 1 + }); + + // Remove lines from the snippet which fall outside the `docs:start` and `docs:end` values. + lines = lines.filter((l, i) => { + return i + 1 > startLineNum && i + 1 < endLineNum - linesToRemove.length; // lines are indexed from 1 + }); + + // We have our code snippet! + let codeSnippet = lines.join('\n'); + + // The code snippet might contain some docusaurus highlighting comments for other identifiers. We should remove those. + codeSnippet = processHighlighting(codeSnippet, identifier); + + return [codeSnippet, startLineNum, endLineNum, tag]; +} + +/** + * Explaining this regex: + * + * E.g. `#include_code snippet_identifier /circuits/my_code.cpp cpp` + * + * #include_code\s+(\S+)\s+(\S+)\s+(\S+) + * - This is the main regex to match the above format. + * - \s+: one or more whitespace characters (space or tab) after `include_code` command. + * - (\S+): one or more non-whitespaced characters. Captures this as the first argument, which is a human-readable identifier for the code block. + * - etc. + * + * Lookaheads are needed to allow us to ignore commented-out lines: + * + * ^(?! ## Summary\* Followup to #4169 ## Additional Context ## Documentation\* Check one: - [ ] No documentation needed. - [x] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --------- Co-authored-by: jfecher --- cspell.json | 11 +++---- docs/docs/noir/standard_library/traits.md | 35 +++++++++++++++++++++++ noir_stdlib/src/convert.nr | 7 ++++- 3 files changed, 47 insertions(+), 6 deletions(-) diff --git a/cspell.json b/cspell.json index 7aae298f417..12b1e3f63d3 100644 --- a/cspell.json +++ b/cspell.json @@ -20,6 +20,8 @@ "bindgen", "bitand", "blackbox", + "boilerplate", + "boilerplates", "bridgekeeper", "brillig", "bytecount", @@ -56,6 +58,7 @@ "defunctionalized", "deque", "desugared", + "devcontainer", "direnv", "eddsa", "Elligator", @@ -96,6 +99,7 @@ "keccak", "keccakf", "krate", + "losslessly", "lvalue", "Maddiaa", "mathbb", @@ -121,6 +125,7 @@ "noirup", "nomicfoundation", "noncanonical", + "nouner", "pedersen", "peekable", "plonkc", @@ -172,11 +177,7 @@ "wasi", "wasmer", "Weierstraß", - "zshell", - "nouner", - "devcontainer", - "boilerplate", - "boilerplates" + "zshell" ], "ignorePaths": [ "./**/node_modules/**", diff --git a/docs/docs/noir/standard_library/traits.md b/docs/docs/noir/standard_library/traits.md index 493d4fcbdb7..fb6d5ae1c48 100644 --- a/docs/docs/noir/standard_library/traits.md +++ b/docs/docs/noir/standard_library/traits.md @@ -48,6 +48,41 @@ impl Default for (A, B, C, D, E) For primitive integer types, the return value of `default` is `0`. Container types such as arrays are filled with default values of their element type. + +## `std::convert` + +### `std::convert::From` + +#include_code from-trait noir_stdlib/src/convert.nr rust + +The `From` trait defines how to convert from a given type `T` to the type on which the trait is implemented. + +The Noir standard library provides a number of implementations of `From` between primitive types. +#include_code from-impls noir_stdlib/src/convert.nr rust + +#### When to implement `From` + +As a general rule of thumb, `From` may be implemented in the [situations where it would be suitable in Rust](https://doc.rust-lang.org/std/convert/trait.From.html#when-to-implement-from): + +- The conversion is *infallible*: Noir does not provide an equivalent to Rust's `TryFrom`, if the conversion can fail then provide a named method instead. +- The conversion is *lossless*: semantically, it should not lose or discard information. For example, `u32: From` can losslessly convert any `u16` into a valid `u32` such that the original `u16` can be recovered. On the other hand, `u16: From` should not be implemented as `2**16` is a `u32` which cannot be losslessly converted into a `u16`. +- The conversion is *value-preserving*: the conceptual kind and meaning of the resulting value is the same, even though the Noir type and technical representation might be different. While it's possible to infallibly and losslessly convert a `u8` into a `str<2>` hex representation, `4u8` and `"04"` are too different for `str<2>: From` to be implemented. +- The conversion is *obvious*: it's the only reasonable conversion between the two types. If there's ambiguity on how to convert between them such that the same input could potentially map to two different values then a named method should be used. For instance rather than implementing `U128: From<[u8; 16]>`, the methods `U128::from_le_bytes` and `U128::from_be_bytes` are used as otherwise the endianness of the array would be ambiguous, resulting in two potential values of `U128` from the same byte array. + +One additional recommendation specific to Noir is: +- The conversion is *efficient*: it's relatively cheap to convert between the two types. Due to being a ZK DSL, it's more important to avoid unnecessary computation compared to Rust. If the implementation of `From` would encourage users to perform unnecessary conversion, resulting in additional proving time, then it may be preferable to expose functionality such that this conversion may be avoided. + +### `std::convert::Into` + +The `Into` trait is defined as the reciprocal of `From`. It should be easy to convince yourself that if we can convert to type `A` from type `B`, then it's possible to convert type `B` into type `A`. + +For this reason, implementing `From` on a type will automatically generate a matching `Into` implementation. One should always prefer implementing `From` over `Into` as implementing `Into` will not generate a matching `From` implementation. + +#include_code into-trait noir_stdlib/src/convert.nr rust + +`Into` is most useful when passing function arguments where the types don't quite match up with what the function expects. In this case, the compiler has enough type information to perform the necessary conversion by just appending `.into()` onto the arguments in question. + + ## `std::cmp` ### `std::cmp::Eq` diff --git a/noir_stdlib/src/convert.nr b/noir_stdlib/src/convert.nr index 294b5097cd7..814f63f1cde 100644 --- a/noir_stdlib/src/convert.nr +++ b/noir_stdlib/src/convert.nr @@ -1,6 +1,8 @@ +// docs:start:from-trait trait From { fn from(input: T) -> Self; } +// docs:end:from-trait impl From for T { fn from(input: T) -> T { @@ -8,6 +10,7 @@ impl From for T { } } +// docs:start:into-trait trait Into { fn into(input: Self) -> T; } @@ -17,7 +20,9 @@ impl Into for U where T: From { T::from(input) } } +// docs:end:into-trait +// docs:start:from-impls // Unsigned integers impl From for u16 { fn from(value: u8) -> u16 { value as u16 } } @@ -53,4 +58,4 @@ impl From for i16 { fn from(value: bool) -> i16 { value as i16 } } impl From for i32 { fn from(value: bool) -> i32 { value as i32 } } impl From for i64 { fn from(value: bool) -> i64 { value as i64 } } impl From for Field { fn from(value: bool) -> Field { value as Field } } - +// docs:end:from-impls From 5e3c0f1dffb72961eb897ba90475eb9975e35cf3 Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Fri, 26 Jan 2024 18:50:32 +0000 Subject: [PATCH 44/70] chore(docs): update hashes page to pull in code (#4175) # Description ## Problem\* Resolves https://github.com/noir-lang/noir/issues/4176 ## Summary\* ## Additional Context ## Documentation\* Check one: - [ ] No documentation needed. - [x] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- .../noir/standard_library/black_box_fns.md | 22 +++--------- .../ecdsa_sig_verification.mdx | 8 ++--- .../cryptographic_primitives/hashes.mdx | 35 +++++++++++-------- .../cryptographic_primitives/scalar.mdx | 4 +-- .../cryptographic_primitives/schnorr.mdx | 4 +-- noir_stdlib/src/ecdsa_secp256k1.nr | 5 ++- noir_stdlib/src/ecdsa_secp256r1.nr | 5 ++- noir_stdlib/src/hash.nr | 30 ++++++++++++---- noir_stdlib/src/scalar_mul.nr | 8 ++++- noir_stdlib/src/schnorr.nr | 5 ++- 10 files changed, 72 insertions(+), 54 deletions(-) diff --git a/docs/docs/noir/standard_library/black_box_fns.md b/docs/docs/noir/standard_library/black_box_fns.md index 4b1efbd17de..6b22d0e7466 100644 --- a/docs/docs/noir/standard_library/black_box_fns.md +++ b/docs/docs/noir/standard_library/black_box_fns.md @@ -6,40 +6,26 @@ keywords: [noir, black box functions] Black box functions are functions in Noir that rely on backends implementing support for specialized constraints. This makes certain zk-snark unfriendly computations cheaper than if they were implemented in Noir. -:::warning - -It is likely that not all backends will support a particular black box function. - -::: - -Because it is not guaranteed that all backends will support black box functions, it is possible that certain Noir programs won't compile against a particular backend if they use an unsupported black box function. It is possible to fallback to less efficient implementations written in Noir/ACIR in some cases. - -Black box functions are specified with the `#[foreign(black_box_fn)]` attribute. For example, the SHA256 function in the Noir [source code](https://github.com/noir-lang/noir/blob/v0.5.1/noir_stdlib/src/hash.nr) looks like: - -```rust -#[foreign(sha256)] -fn sha256(_input : [u8; N]) -> [u8; 32] {} -``` +The ACVM spec defines a set of blackbox functions which backends will be expected to implement. This allows backends to use optimized implementations of these constraints if they have them, however they may also fallback to less efficient naive implementations if not. ## Function list -Here is a list of the current black box functions that are supported by UltraPlonk: +Here is a list of the current black box functions: -- AES - [SHA256](./cryptographic_primitives/hashes#sha256) - [Schnorr signature verification](./cryptographic_primitives/schnorr) - [Blake2s](./cryptographic_primitives/hashes#blake2s) +- [Blake3](./cryptographic_primitives/hashes#blake2s) - [Pedersen Hash](./cryptographic_primitives/hashes#pedersen_hash) - [Pedersen Commitment](./cryptographic_primitives/hashes#pedersen_commitment) - [ECDSA signature verification](./cryptographic_primitives/ecdsa_sig_verification) - [Fixed base scalar multiplication](./cryptographic_primitives/scalar) -- [Compute merkle root](./merkle_trees#compute_merkle_root) - AND - XOR - RANGE - [Keccak256](./cryptographic_primitives/hashes#keccak256) - [Recursive proof verification](./recursion) -Most black box functions are included as part of the Noir standard library, however `AND`, `XOR` and `RANGE` are used as part of the Noir language syntax. For instance, using the bitwise operator `&` will invoke the `AND` black box function. To ensure compatibility across backends, the ACVM has fallback implementations of `AND`, `XOR` and `RANGE` defined in its standard library which it can seamlessly fallback to if the backend doesn't support them. +Most black box functions are included as part of the Noir standard library, however `AND`, `XOR` and `RANGE` are used as part of the Noir language syntax. For instance, using the bitwise operator `&` will invoke the `AND` black box function. You can view the black box functions defined in the ACVM code [here](https://github.com/noir-lang/noir/blob/master/acvm-repo/acir/src/circuit/black_box_functions.rs). diff --git a/docs/docs/noir/standard_library/cryptographic_primitives/ecdsa_sig_verification.mdx b/docs/docs/noir/standard_library/cryptographic_primitives/ecdsa_sig_verification.mdx index 1376c51dfde..d67a1ac94df 100644 --- a/docs/docs/noir/standard_library/cryptographic_primitives/ecdsa_sig_verification.mdx +++ b/docs/docs/noir/standard_library/cryptographic_primitives/ecdsa_sig_verification.mdx @@ -13,9 +13,7 @@ Noir supports ECDSA signatures verification over the secp256k1 and secp256r1 cur Verifier for ECDSA Secp256k1 signatures -```rust -fn verify_signature(_public_key_x : [u8; 32], _public_key_y : [u8; 32], _signature: [u8; 64], _message: [u8]) -> bool -``` +#include_code ecdsa_secp256k1 noir_stdlib/src/ecdsa_secp256k1.nr rust example: @@ -30,9 +28,7 @@ fn main(hashed_message : [u8;32], pub_key_x : [u8;32], pub_key_y : [u8;32], sign Verifier for ECDSA Secp256r1 signatures -```rust -fn verify_signature(_public_key_x : [u8; 32], _public_key_y : [u8; 32], _signature: [u8; 64], _message: [u8]) -> bool -``` +#include_code ecdsa_secp256r1 noir_stdlib/src/ecdsa_secp256r1.nr rust example: diff --git a/docs/docs/noir/standard_library/cryptographic_primitives/hashes.mdx b/docs/docs/noir/standard_library/cryptographic_primitives/hashes.mdx index 3d33630bc1a..85706384eee 100644 --- a/docs/docs/noir/standard_library/cryptographic_primitives/hashes.mdx +++ b/docs/docs/noir/standard_library/cryptographic_primitives/hashes.mdx @@ -14,9 +14,7 @@ import BlackBoxInfo from '@site/src/components/Notes/_blackbox.mdx'; Given an array of bytes, returns the resulting sha256 hash. -```rust -fn sha256(_input : [u8]) -> [u8; 32] -``` +#include_code sha256 noir_stdlib/src/hash.nr rust example: @@ -33,16 +31,31 @@ fn main() { Given an array of bytes, returns an array with the Blake2 hash +#include_code blake2s noir_stdlib/src/hash.nr rust + +example: + ```rust -fn blake2s(_input : [u8]) -> [u8; 32] +fn main() { + let x = [163, 117, 178, 149]; // some random bytes + let hash = std::hash::blake2s(x); +} ``` + + +## blake3 + +Given an array of bytes, returns an array with the Blake3 hash + +#include_code blake3 noir_stdlib/src/hash.nr rust + example: ```rust fn main() { let x = [163, 117, 178, 149]; // some random bytes - let hash = std::hash::blake2s(x); + let hash = std::hash::blake3(x); } ``` @@ -52,9 +65,7 @@ fn main() { Given an array of Fields, returns the Pedersen hash. -```rust -fn pedersen_hash(_input : [Field]) -> Field -``` +#include_code pedersen_hash noir_stdlib/src/hash.nr rust example: @@ -67,9 +78,7 @@ example: Given an array of Fields, returns the Pedersen commitment. -```rust -fn pedersen_commitment(_input : [Field]) -> [Field; 2] -``` +#include_code pedersen_commitment noir_stdlib/src/hash.nr rust example: @@ -83,9 +92,7 @@ Given an array of bytes (`u8`), returns the resulting keccak hash as an array of (`[u8; 32]`). Specify a message_size to hash only the first `message_size` bytes of the input. -```rust -fn keccak256(_input : [u8; N], _message_size: u32) -> [u8; 32] -``` +#include_code keccak256 noir_stdlib/src/hash.nr rust example: diff --git a/docs/docs/noir/standard_library/cryptographic_primitives/scalar.mdx b/docs/docs/noir/standard_library/cryptographic_primitives/scalar.mdx index aa4fb8cbaed..c2946b2b73b 100644 --- a/docs/docs/noir/standard_library/cryptographic_primitives/scalar.mdx +++ b/docs/docs/noir/standard_library/cryptographic_primitives/scalar.mdx @@ -12,9 +12,7 @@ import BlackBoxInfo from '@site/src/components/Notes/_blackbox.mdx'; Performs scalar multiplication over the embedded curve whose coordinates are defined by the configured noir field. For the BN254 scalar field, this is BabyJubJub or Grumpkin. -```rust -fn fixed_base_embedded_curve(_input : Field) -> [Field; 2] -``` +#include_code fixed_base_embedded_curve noir_stdlib/src/scalar_mul.nr rust example diff --git a/docs/docs/noir/standard_library/cryptographic_primitives/schnorr.mdx b/docs/docs/noir/standard_library/cryptographic_primitives/schnorr.mdx index 7a2c9c20226..0e0c358c6e1 100644 --- a/docs/docs/noir/standard_library/cryptographic_primitives/schnorr.mdx +++ b/docs/docs/noir/standard_library/cryptographic_primitives/schnorr.mdx @@ -11,9 +11,7 @@ import BlackBoxInfo from '@site/src/components/Notes/_blackbox.mdx'; Verifier for Schnorr signatures over the embedded curve (for BN254 it is Grumpkin). -```rust -fn verify_signature(_public_key_x: Field, _public_key_y: Field, _signature: [u8; 64], _message: [u8]) -> bool -``` +#include_code schnorr_verify noir_stdlib/src/schnorr.nr rust where `_signature` can be generated like so using the npm package [@noir-lang/barretenberg](https://www.npmjs.com/package/@noir-lang/barretenberg) diff --git a/noir_stdlib/src/ecdsa_secp256k1.nr b/noir_stdlib/src/ecdsa_secp256k1.nr index b1f2b12c76b..290ccba27e5 100644 --- a/noir_stdlib/src/ecdsa_secp256k1.nr +++ b/noir_stdlib/src/ecdsa_secp256k1.nr @@ -1,7 +1,10 @@ #[foreign(ecdsa_secp256k1)] +// docs:start:ecdsa_secp256k1 pub fn verify_signature( _public_key_x: [u8; 32], _public_key_y: [u8; 32], _signature: [u8; 64], _message_hash: [u8; N] -) -> bool {} +) -> bool +// docs:end:ecdsa_secp256k1 +{} diff --git a/noir_stdlib/src/ecdsa_secp256r1.nr b/noir_stdlib/src/ecdsa_secp256r1.nr index 6c3cf4d7945..390f8ed39d2 100644 --- a/noir_stdlib/src/ecdsa_secp256r1.nr +++ b/noir_stdlib/src/ecdsa_secp256r1.nr @@ -1,7 +1,10 @@ #[foreign(ecdsa_secp256r1)] +// docs:start:ecdsa_secp256r1 pub fn verify_signature( _public_key_x: [u8; 32], _public_key_y: [u8; 32], _signature: [u8; 64], _message_hash: [u8; N] -) -> bool {} +) -> bool +// docs:end:ecdsa_secp256r1 +{} diff --git a/noir_stdlib/src/hash.nr b/noir_stdlib/src/hash.nr index 5933209d9bc..09154038f4e 100644 --- a/noir_stdlib/src/hash.nr +++ b/noir_stdlib/src/hash.nr @@ -2,20 +2,32 @@ mod poseidon; mod mimc; #[foreign(sha256)] -pub fn sha256(_input: [u8; N]) -> [u8; 32] {} +// docs:start:sha256 +pub fn sha256(_input: [u8; N]) -> [u8; 32] +// docs:end:sha256 +{} #[foreign(blake2s)] -pub fn blake2s(_input: [u8; N]) -> [u8; 32] {} +// docs:start:blake2s +pub fn blake2s(_input: [u8; N]) -> [u8; 32] +// docs:end:blake2s +{} #[foreign(blake3)] -pub fn blake3(_input: [u8; N]) -> [u8; 32] {} +// docs:start:blake3 +pub fn blake3(_input: [u8; N]) -> [u8; 32] +// docs:end:blake3 +{} +// docs:start:pedersen_commitment struct PedersenPoint { x : Field, y : Field, } -pub fn pedersen_commitment(input: [Field; N]) -> PedersenPoint { +pub fn pedersen_commitment(input: [Field; N]) -> PedersenPoint +// docs:end:pedersen_commitment +{ pedersen_commitment_with_separator(input, 0) } @@ -27,7 +39,10 @@ pub fn pedersen_commitment_with_separator(input: [Field; N], separator: u32) PedersenPoint { x: values[0], y: values[1] } } -pub fn pedersen_hash(input: [Field; N]) -> Field { +// docs:start:pedersen_hash +pub fn pedersen_hash(input: [Field; N]) -> Field +// docs:end:pedersen_hash +{ pedersen_hash_with_separator(input, 0) } @@ -49,5 +64,8 @@ pub fn hash_to_field(_input: [Field; N]) -> Field { } #[foreign(keccak256)] -pub fn keccak256(_input: [u8; N], _message_size: u32) -> [u8; 32] {} +// docs:start:keccak256 +pub fn keccak256(_input: [u8; N], _message_size: u32) -> [u8; 32] +// docs:end:keccak256 +{} diff --git a/noir_stdlib/src/scalar_mul.nr b/noir_stdlib/src/scalar_mul.nr index 37cd935cdb9..c045e72d400 100644 --- a/noir_stdlib/src/scalar_mul.nr +++ b/noir_stdlib/src/scalar_mul.nr @@ -5,4 +5,10 @@ // The embedded curve being used is decided by the // underlying proof system. #[foreign(fixed_base_scalar_mul)] -pub fn fixed_base_embedded_curve(_low: Field, _high: Field) -> [Field; 2] {} +// docs:start:fixed_base_embedded_curve +pub fn fixed_base_embedded_curve( + _low: Field, + _high: Field +) -> [Field; 2] +// docs:end:fixed_base_embedded_curve +{} diff --git a/noir_stdlib/src/schnorr.nr b/noir_stdlib/src/schnorr.nr index 5ed95096f97..025c3a0f921 100644 --- a/noir_stdlib/src/schnorr.nr +++ b/noir_stdlib/src/schnorr.nr @@ -1,7 +1,10 @@ #[foreign(schnorr_verify)] +// docs:start:schnorr_verify pub fn verify_signature( _public_key_x: Field, _public_key_y: Field, _signature: [u8; 64], _message: [u8; N] -) -> bool {} +) -> bool +// docs:end:schnorr_verify +{} From 29143104fa907b446d534ac204069572cdc6f2f9 Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Mon, 29 Jan 2024 13:02:50 +0000 Subject: [PATCH 45/70] fix(docs): codegen docs before cutting a new version (#4183) # Description ## Problem\* Resolves ## Summary\* Currently when cutting a release in CI, docusaurus is looking for `processed-docs` however this hasn't been generated. This PR then ensures this is up to date when generating a release by running `preprocess` before doing so. ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- .github/workflows/release.yml | 2 +- docs/package.json | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7dfc844d18f..71a0ab6d894 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -87,7 +87,7 @@ jobs: - name: Cut a new version working-directory: ./docs - run: yarn docusaurus docs:version ${{ steps.noir-version.outputs.semver }} + run: yarn version ${{ steps.noir-version.outputs.semver }} - name: Configure git run: | diff --git a/docs/package.json b/docs/package.json index 6c706e4f514..71b624ff565 100644 --- a/docs/package.json +++ b/docs/package.json @@ -7,7 +7,8 @@ "start": "yarn preprocess && docusaurus start", "build": "yarn preprocess && yarn version::stables && docusaurus build", "version::stables": "ts-node ./scripts/setStable.ts", - "serve": "serve build" + "serve": "serve build", + "version": "yarn preprocess && docusaurus docs:version" }, "dependencies": { "@docusaurus/core": "^3.0.1", From 09bad2c7cf659c5ddb858d2ae546396ce09a0e7e Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Mon, 29 Jan 2024 15:04:19 +0000 Subject: [PATCH 46/70] chore(docs): stop committing codegenned docs (#4186) # Description ## Problem\* Resolves ## Summary\* We shouldn't be committing codegenned docs so this PR codegens directly into the `processed-docs` dir. ## Additional Context ## Documentation\* Check one: - [ ] No documentation needed. - [x] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- .../NoirJS/backend_barretenberg/.nojekyll | 1 - .../classes/BarretenbergBackend.md | 185 ------------------ .../NoirJS/backend_barretenberg/index.md | 46 ----- .../interfaces/Backend.md | 132 ------------- .../type-aliases/BackendOptions.md | 19 -- .../type-aliases/CompiledCircuit.md | 20 -- .../type-aliases/ProofData.md | 20 -- .../backend_barretenberg/typedoc-sidebar.cjs | 4 - docs/docs/reference/NoirJS/noir_js/.nojekyll | 1 - .../reference/NoirJS/noir_js/classes/Noir.md | 132 ------------- .../reference/NoirJS/noir_js/functions/and.md | 22 --- .../NoirJS/noir_js/functions/blake2s256.md | 21 -- .../functions/ecdsa_secp256k1_verify.md | 28 --- .../functions/ecdsa_secp256r1_verify.md | 28 --- .../NoirJS/noir_js/functions/keccak256.md | 21 -- .../NoirJS/noir_js/functions/sha256.md | 21 -- .../reference/NoirJS/noir_js/functions/xor.md | 22 --- docs/docs/reference/NoirJS/noir_js/index.md | 37 ---- .../noir_js/type-aliases/CompiledCircuit.md | 20 -- .../type-aliases/ForeignCallHandler.md | 24 --- .../noir_js/type-aliases/ForeignCallInput.md | 9 - .../noir_js/type-aliases/ForeignCallOutput.md | 9 - .../NoirJS/noir_js/type-aliases/InputMap.md | 13 -- .../NoirJS/noir_js/type-aliases/ProofData.md | 20 -- .../NoirJS/noir_js/type-aliases/WitnessMap.md | 9 - .../NoirJS/noir_js/typedoc-sidebar.cjs | 4 - docs/docusaurus.config.ts | 4 +- 27 files changed, 2 insertions(+), 870 deletions(-) delete mode 100644 docs/docs/reference/NoirJS/backend_barretenberg/.nojekyll delete mode 100644 docs/docs/reference/NoirJS/backend_barretenberg/classes/BarretenbergBackend.md delete mode 100644 docs/docs/reference/NoirJS/backend_barretenberg/index.md delete mode 100644 docs/docs/reference/NoirJS/backend_barretenberg/interfaces/Backend.md delete mode 100644 docs/docs/reference/NoirJS/backend_barretenberg/type-aliases/BackendOptions.md delete mode 100644 docs/docs/reference/NoirJS/backend_barretenberg/type-aliases/CompiledCircuit.md delete mode 100644 docs/docs/reference/NoirJS/backend_barretenberg/type-aliases/ProofData.md delete mode 100644 docs/docs/reference/NoirJS/backend_barretenberg/typedoc-sidebar.cjs delete mode 100644 docs/docs/reference/NoirJS/noir_js/.nojekyll delete mode 100644 docs/docs/reference/NoirJS/noir_js/classes/Noir.md delete mode 100644 docs/docs/reference/NoirJS/noir_js/functions/and.md delete mode 100644 docs/docs/reference/NoirJS/noir_js/functions/blake2s256.md delete mode 100644 docs/docs/reference/NoirJS/noir_js/functions/ecdsa_secp256k1_verify.md delete mode 100644 docs/docs/reference/NoirJS/noir_js/functions/ecdsa_secp256r1_verify.md delete mode 100644 docs/docs/reference/NoirJS/noir_js/functions/keccak256.md delete mode 100644 docs/docs/reference/NoirJS/noir_js/functions/sha256.md delete mode 100644 docs/docs/reference/NoirJS/noir_js/functions/xor.md delete mode 100644 docs/docs/reference/NoirJS/noir_js/index.md delete mode 100644 docs/docs/reference/NoirJS/noir_js/type-aliases/CompiledCircuit.md delete mode 100644 docs/docs/reference/NoirJS/noir_js/type-aliases/ForeignCallHandler.md delete mode 100644 docs/docs/reference/NoirJS/noir_js/type-aliases/ForeignCallInput.md delete mode 100644 docs/docs/reference/NoirJS/noir_js/type-aliases/ForeignCallOutput.md delete mode 100644 docs/docs/reference/NoirJS/noir_js/type-aliases/InputMap.md delete mode 100644 docs/docs/reference/NoirJS/noir_js/type-aliases/ProofData.md delete mode 100644 docs/docs/reference/NoirJS/noir_js/type-aliases/WitnessMap.md delete mode 100644 docs/docs/reference/NoirJS/noir_js/typedoc-sidebar.cjs diff --git a/docs/docs/reference/NoirJS/backend_barretenberg/.nojekyll b/docs/docs/reference/NoirJS/backend_barretenberg/.nojekyll deleted file mode 100644 index e2ac6616add..00000000000 --- a/docs/docs/reference/NoirJS/backend_barretenberg/.nojekyll +++ /dev/null @@ -1 +0,0 @@ -TypeDoc added this file to prevent GitHub Pages from using Jekyll. You can turn off this behavior by setting the `githubPages` option to false. \ No newline at end of file diff --git a/docs/docs/reference/NoirJS/backend_barretenberg/classes/BarretenbergBackend.md b/docs/docs/reference/NoirJS/backend_barretenberg/classes/BarretenbergBackend.md deleted file mode 100644 index 5cbe9421b92..00000000000 --- a/docs/docs/reference/NoirJS/backend_barretenberg/classes/BarretenbergBackend.md +++ /dev/null @@ -1,185 +0,0 @@ -# BarretenbergBackend - -## Implements - -- [`Backend`](../interfaces/Backend.md) - -## Constructors - -### new BarretenbergBackend(acirCircuit, options) - -```ts -new BarretenbergBackend(acirCircuit, options): BarretenbergBackend -``` - -#### Parameters - -| Parameter | Type | -| :------ | :------ | -| `acirCircuit` | [`CompiledCircuit`](../type-aliases/CompiledCircuit.md) | -| `options` | [`BackendOptions`](../type-aliases/BackendOptions.md) | - -#### Returns - -[`BarretenbergBackend`](BarretenbergBackend.md) - -## Methods - -### destroy() - -```ts -destroy(): Promise -``` - -#### Returns - -`Promise`\<`void`\> - -#### Implementation of - -[`Backend`](../interfaces/Backend.md).[`destroy`](../interfaces/Backend.md#destroy) - -#### Description - -Destroys the backend - -*** - -### generateFinalProof() - -```ts -generateFinalProof(decompressedWitness): Promise -``` - -#### Parameters - -| Parameter | Type | -| :------ | :------ | -| `decompressedWitness` | `Uint8Array` | - -#### Returns - -`Promise`\<[`ProofData`](../type-aliases/ProofData.md)\> - -#### Implementation of - -[`Backend`](../interfaces/Backend.md).[`generateFinalProof`](../interfaces/Backend.md#generatefinalproof) - -#### Description - -Generates a final proof (not meant to be verified in another circuit) - -*** - -### generateIntermediateProof() - -```ts -generateIntermediateProof(witness): Promise -``` - -#### Parameters - -| Parameter | Type | -| :------ | :------ | -| `witness` | `Uint8Array` | - -#### Returns - -`Promise`\<[`ProofData`](../type-aliases/ProofData.md)\> - -#### Implementation of - -[`Backend`](../interfaces/Backend.md).[`generateIntermediateProof`](../interfaces/Backend.md#generateintermediateproof) - -#### Example - -```typescript -const intermediateProof = await backend.generateIntermediateProof(witness); -``` - -*** - -### generateIntermediateProofArtifacts() - -```ts -generateIntermediateProofArtifacts(proofData, numOfPublicInputs): Promise -``` - -#### Parameters - -| Parameter | Type | Default value | -| :------ | :------ | :------ | -| `proofData` | [`ProofData`](../type-aliases/ProofData.md) | `undefined` | -| `numOfPublicInputs` | `number` | `0` | - -#### Returns - -`Promise`\<`object`\> - -#### Implementation of - -[`Backend`](../interfaces/Backend.md).[`generateIntermediateProofArtifacts`](../interfaces/Backend.md#generateintermediateproofartifacts) - -#### Example - -```typescript -const artifacts = await backend.generateIntermediateProofArtifacts(proof, numOfPublicInputs); -``` - -*** - -### verifyFinalProof() - -```ts -verifyFinalProof(proofData): Promise -``` - -#### Parameters - -| Parameter | Type | -| :------ | :------ | -| `proofData` | [`ProofData`](../type-aliases/ProofData.md) | - -#### Returns - -`Promise`\<`boolean`\> - -#### Implementation of - -[`Backend`](../interfaces/Backend.md).[`verifyFinalProof`](../interfaces/Backend.md#verifyfinalproof) - -#### Description - -Verifies a final proof - -*** - -### verifyIntermediateProof() - -```ts -verifyIntermediateProof(proofData): Promise -``` - -#### Parameters - -| Parameter | Type | -| :------ | :------ | -| `proofData` | [`ProofData`](../type-aliases/ProofData.md) | - -#### Returns - -`Promise`\<`boolean`\> - -#### Implementation of - -[`Backend`](../interfaces/Backend.md).[`verifyIntermediateProof`](../interfaces/Backend.md#verifyintermediateproof) - -#### Example - -```typescript -const isValidIntermediate = await backend.verifyIntermediateProof(proof); -``` - -*** - -Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/docs/reference/NoirJS/backend_barretenberg/index.md b/docs/docs/reference/NoirJS/backend_barretenberg/index.md deleted file mode 100644 index e32501acb71..00000000000 --- a/docs/docs/reference/NoirJS/backend_barretenberg/index.md +++ /dev/null @@ -1,46 +0,0 @@ -# backend_barretenberg - -## Exports - -### Classes - -| Class | Description | -| :------ | :------ | -| [BarretenbergBackend](classes/BarretenbergBackend.md) | - | - -### Interfaces - -| Interface | Description | -| :------ | :------ | -| [Backend](interfaces/Backend.md) | - | - -### Type Aliases - -| Type alias | Description | -| :------ | :------ | -| [BackendOptions](type-aliases/BackendOptions.md) | - | -| [CompiledCircuit](type-aliases/CompiledCircuit.md) | - | -| [ProofData](type-aliases/ProofData.md) | - | - -## Functions - -### publicInputsToWitnessMap() - -```ts -publicInputsToWitnessMap(publicInputs, abi): WitnessMap -``` - -#### Parameters - -| Parameter | Type | -| :------ | :------ | -| `publicInputs` | `string`[] | -| `abi` | `Abi` | - -#### Returns - -`WitnessMap` - -*** - -Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/docs/reference/NoirJS/backend_barretenberg/interfaces/Backend.md b/docs/docs/reference/NoirJS/backend_barretenberg/interfaces/Backend.md deleted file mode 100644 index 3eb9645c8d2..00000000000 --- a/docs/docs/reference/NoirJS/backend_barretenberg/interfaces/Backend.md +++ /dev/null @@ -1,132 +0,0 @@ -# Backend - -## Methods - -### destroy() - -```ts -destroy(): Promise -``` - -#### Returns - -`Promise`\<`void`\> - -#### Description - -Destroys the backend - -*** - -### generateFinalProof() - -```ts -generateFinalProof(decompressedWitness): Promise -``` - -#### Parameters - -| Parameter | Type | -| :------ | :------ | -| `decompressedWitness` | `Uint8Array` | - -#### Returns - -`Promise`\<[`ProofData`](../type-aliases/ProofData.md)\> - -#### Description - -Generates a final proof (not meant to be verified in another circuit) - -*** - -### generateIntermediateProof() - -```ts -generateIntermediateProof(decompressedWitness): Promise -``` - -#### Parameters - -| Parameter | Type | -| :------ | :------ | -| `decompressedWitness` | `Uint8Array` | - -#### Returns - -`Promise`\<[`ProofData`](../type-aliases/ProofData.md)\> - -#### Description - -Generates an intermediate proof (meant to be verified in another circuit) - -*** - -### generateIntermediateProofArtifacts() - -```ts -generateIntermediateProofArtifacts(proofData, numOfPublicInputs): Promise -``` - -#### Parameters - -| Parameter | Type | -| :------ | :------ | -| `proofData` | [`ProofData`](../type-aliases/ProofData.md) | -| `numOfPublicInputs` | `number` | - -#### Returns - -`Promise`\<`object`\> - -#### Description - -Retrieves the artifacts from a proof in the Field format - -*** - -### verifyFinalProof() - -```ts -verifyFinalProof(proofData): Promise -``` - -#### Parameters - -| Parameter | Type | -| :------ | :------ | -| `proofData` | [`ProofData`](../type-aliases/ProofData.md) | - -#### Returns - -`Promise`\<`boolean`\> - -#### Description - -Verifies a final proof - -*** - -### verifyIntermediateProof() - -```ts -verifyIntermediateProof(proofData): Promise -``` - -#### Parameters - -| Parameter | Type | -| :------ | :------ | -| `proofData` | [`ProofData`](../type-aliases/ProofData.md) | - -#### Returns - -`Promise`\<`boolean`\> - -#### Description - -Verifies an intermediate proof - -*** - -Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/docs/reference/NoirJS/backend_barretenberg/type-aliases/BackendOptions.md b/docs/docs/reference/NoirJS/backend_barretenberg/type-aliases/BackendOptions.md deleted file mode 100644 index 266ade75d17..00000000000 --- a/docs/docs/reference/NoirJS/backend_barretenberg/type-aliases/BackendOptions.md +++ /dev/null @@ -1,19 +0,0 @@ -# BackendOptions - -```ts -type BackendOptions: object; -``` - -## Description - -An options object, currently only used to specify the number of threads to use. - -## Type declaration - -| Member | Type | Description | -| :------ | :------ | :------ | -| `threads` | `number` | **Description**

Number of threads | - -*** - -Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/docs/reference/NoirJS/backend_barretenberg/type-aliases/CompiledCircuit.md b/docs/docs/reference/NoirJS/backend_barretenberg/type-aliases/CompiledCircuit.md deleted file mode 100644 index 34e0dd04205..00000000000 --- a/docs/docs/reference/NoirJS/backend_barretenberg/type-aliases/CompiledCircuit.md +++ /dev/null @@ -1,20 +0,0 @@ -# CompiledCircuit - -```ts -type CompiledCircuit: object; -``` - -## Description - -The representation of a compiled circuit - -## Type declaration - -| Member | Type | Description | -| :------ | :------ | :------ | -| `abi` | `Abi` | **Description**

ABI representation of the circuit | -| `bytecode` | `string` | **Description**

The bytecode of the circuit | - -*** - -Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/docs/reference/NoirJS/backend_barretenberg/type-aliases/ProofData.md b/docs/docs/reference/NoirJS/backend_barretenberg/type-aliases/ProofData.md deleted file mode 100644 index 05cebbc4e94..00000000000 --- a/docs/docs/reference/NoirJS/backend_barretenberg/type-aliases/ProofData.md +++ /dev/null @@ -1,20 +0,0 @@ -# ProofData - -```ts -type ProofData: object; -``` - -## Description - -The representation of a proof - -## Type declaration - -| Member | Type | Description | -| :------ | :------ | :------ | -| `proof` | `Uint8Array` | **Description**

An byte array representing the proof | -| `publicInputs` | `string`[] | **Description**

Public inputs of a proof | - -*** - -Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/docs/reference/NoirJS/backend_barretenberg/typedoc-sidebar.cjs b/docs/docs/reference/NoirJS/backend_barretenberg/typedoc-sidebar.cjs deleted file mode 100644 index 2aaa55bccf6..00000000000 --- a/docs/docs/reference/NoirJS/backend_barretenberg/typedoc-sidebar.cjs +++ /dev/null @@ -1,4 +0,0 @@ -// @ts-check -/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */ -const typedocSidebar = { items: [{"type":"category","label":"Classes","items":[{"type":"doc","id":"reference/NoirJS/backend_barretenberg/classes/BarretenbergBackend","label":"BarretenbergBackend"}]},{"type":"category","label":"Interfaces","items":[{"type":"doc","id":"reference/NoirJS/backend_barretenberg/interfaces/Backend","label":"Backend"}]},{"type":"category","label":"Type Aliases","items":[{"type":"doc","id":"reference/NoirJS/backend_barretenberg/type-aliases/BackendOptions","label":"BackendOptions"},{"type":"doc","id":"reference/NoirJS/backend_barretenberg/type-aliases/CompiledCircuit","label":"CompiledCircuit"},{"type":"doc","id":"reference/NoirJS/backend_barretenberg/type-aliases/ProofData","label":"ProofData"}]}]}; -module.exports = typedocSidebar.items; \ No newline at end of file diff --git a/docs/docs/reference/NoirJS/noir_js/.nojekyll b/docs/docs/reference/NoirJS/noir_js/.nojekyll deleted file mode 100644 index e2ac6616add..00000000000 --- a/docs/docs/reference/NoirJS/noir_js/.nojekyll +++ /dev/null @@ -1 +0,0 @@ -TypeDoc added this file to prevent GitHub Pages from using Jekyll. You can turn off this behavior by setting the `githubPages` option to false. \ No newline at end of file diff --git a/docs/docs/reference/NoirJS/noir_js/classes/Noir.md b/docs/docs/reference/NoirJS/noir_js/classes/Noir.md deleted file mode 100644 index 34e20d99684..00000000000 --- a/docs/docs/reference/NoirJS/noir_js/classes/Noir.md +++ /dev/null @@ -1,132 +0,0 @@ -# Noir - -## Constructors - -### new Noir(circuit, backend) - -```ts -new Noir(circuit, backend?): Noir -``` - -#### Parameters - -| Parameter | Type | -| :------ | :------ | -| `circuit` | [`CompiledCircuit`](../type-aliases/CompiledCircuit.md) | -| `backend`? | `Backend` | - -#### Returns - -[`Noir`](Noir.md) - -## Methods - -### destroy() - -```ts -destroy(): Promise -``` - -#### Returns - -`Promise`\<`void`\> - -#### Description - -Destroys the underlying backend instance. - -#### Example - -```typescript -await noir.destroy(); -``` - -*** - -### execute() - -```ts -execute(inputs, foreignCallHandler?): Promise -``` - -#### Parameters - -| Parameter | Type | -| :------ | :------ | -| `inputs` | [`InputMap`](../type-aliases/InputMap.md) | -| `foreignCallHandler`? | [`ForeignCallHandler`](../type-aliases/ForeignCallHandler.md) | - -#### Returns - -`Promise`\<`object`\> - -#### Description - -Allows to execute a circuit to get its witness and return value. - -#### Example - -```typescript -async execute(inputs) -``` - -*** - -### generateFinalProof() - -```ts -generateFinalProof(inputs, foreignCallHandler?): Promise -``` - -#### Parameters - -| Parameter | Type | -| :------ | :------ | -| `inputs` | [`InputMap`](../type-aliases/InputMap.md) | -| `foreignCallHandler`? | [`ForeignCallHandler`](../type-aliases/ForeignCallHandler.md) | - -#### Returns - -`Promise`\<[`ProofData`](../type-aliases/ProofData.md)\> - -#### Description - -Generates a witness and a proof given an object as input. - -#### Example - -```typescript -async generateFinalProof(input) -``` - -*** - -### verifyFinalProof() - -```ts -verifyFinalProof(proofData): Promise -``` - -#### Parameters - -| Parameter | Type | -| :------ | :------ | -| `proofData` | [`ProofData`](../type-aliases/ProofData.md) | - -#### Returns - -`Promise`\<`boolean`\> - -#### Description - -Instantiates the verification key and verifies a proof. - -#### Example - -```typescript -async verifyFinalProof(proof) -``` - -*** - -Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/docs/reference/NoirJS/noir_js/functions/and.md b/docs/docs/reference/NoirJS/noir_js/functions/and.md deleted file mode 100644 index c783283e396..00000000000 --- a/docs/docs/reference/NoirJS/noir_js/functions/and.md +++ /dev/null @@ -1,22 +0,0 @@ -# and() - -```ts -and(lhs, rhs): string -``` - -Performs a bitwise AND operation between `lhs` and `rhs` - -## Parameters - -| Parameter | Type | Description | -| :------ | :------ | :------ | -| `lhs` | `string` | | -| `rhs` | `string` | | - -## Returns - -`string` - -*** - -Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/docs/reference/NoirJS/noir_js/functions/blake2s256.md b/docs/docs/reference/NoirJS/noir_js/functions/blake2s256.md deleted file mode 100644 index 7882d0da8d5..00000000000 --- a/docs/docs/reference/NoirJS/noir_js/functions/blake2s256.md +++ /dev/null @@ -1,21 +0,0 @@ -# blake2s256() - -```ts -blake2s256(inputs): Uint8Array -``` - -Calculates the Blake2s256 hash of the input bytes - -## Parameters - -| Parameter | Type | Description | -| :------ | :------ | :------ | -| `inputs` | `Uint8Array` | | - -## Returns - -`Uint8Array` - -*** - -Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/docs/reference/NoirJS/noir_js/functions/ecdsa_secp256k1_verify.md b/docs/docs/reference/NoirJS/noir_js/functions/ecdsa_secp256k1_verify.md deleted file mode 100644 index 5e3cd53e9d3..00000000000 --- a/docs/docs/reference/NoirJS/noir_js/functions/ecdsa_secp256k1_verify.md +++ /dev/null @@ -1,28 +0,0 @@ -# ecdsa\_secp256k1\_verify() - -```ts -ecdsa_secp256k1_verify( - hashed_msg, - public_key_x_bytes, - public_key_y_bytes, - signature): boolean -``` - -Verifies a ECDSA signature over the secp256k1 curve. - -## Parameters - -| Parameter | Type | Description | -| :------ | :------ | :------ | -| `hashed_msg` | `Uint8Array` | | -| `public_key_x_bytes` | `Uint8Array` | | -| `public_key_y_bytes` | `Uint8Array` | | -| `signature` | `Uint8Array` | | - -## Returns - -`boolean` - -*** - -Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/docs/reference/NoirJS/noir_js/functions/ecdsa_secp256r1_verify.md b/docs/docs/reference/NoirJS/noir_js/functions/ecdsa_secp256r1_verify.md deleted file mode 100644 index 0b20ff68957..00000000000 --- a/docs/docs/reference/NoirJS/noir_js/functions/ecdsa_secp256r1_verify.md +++ /dev/null @@ -1,28 +0,0 @@ -# ecdsa\_secp256r1\_verify() - -```ts -ecdsa_secp256r1_verify( - hashed_msg, - public_key_x_bytes, - public_key_y_bytes, - signature): boolean -``` - -Verifies a ECDSA signature over the secp256r1 curve. - -## Parameters - -| Parameter | Type | Description | -| :------ | :------ | :------ | -| `hashed_msg` | `Uint8Array` | | -| `public_key_x_bytes` | `Uint8Array` | | -| `public_key_y_bytes` | `Uint8Array` | | -| `signature` | `Uint8Array` | | - -## Returns - -`boolean` - -*** - -Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/docs/reference/NoirJS/noir_js/functions/keccak256.md b/docs/docs/reference/NoirJS/noir_js/functions/keccak256.md deleted file mode 100644 index d10f155ce86..00000000000 --- a/docs/docs/reference/NoirJS/noir_js/functions/keccak256.md +++ /dev/null @@ -1,21 +0,0 @@ -# keccak256() - -```ts -keccak256(inputs): Uint8Array -``` - -Calculates the Keccak256 hash of the input bytes - -## Parameters - -| Parameter | Type | Description | -| :------ | :------ | :------ | -| `inputs` | `Uint8Array` | | - -## Returns - -`Uint8Array` - -*** - -Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/docs/reference/NoirJS/noir_js/functions/sha256.md b/docs/docs/reference/NoirJS/noir_js/functions/sha256.md deleted file mode 100644 index 6ba4ecac022..00000000000 --- a/docs/docs/reference/NoirJS/noir_js/functions/sha256.md +++ /dev/null @@ -1,21 +0,0 @@ -# sha256() - -```ts -sha256(inputs): Uint8Array -``` - -Calculates the SHA256 hash of the input bytes - -## Parameters - -| Parameter | Type | Description | -| :------ | :------ | :------ | -| `inputs` | `Uint8Array` | | - -## Returns - -`Uint8Array` - -*** - -Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/docs/reference/NoirJS/noir_js/functions/xor.md b/docs/docs/reference/NoirJS/noir_js/functions/xor.md deleted file mode 100644 index 8d762b895d3..00000000000 --- a/docs/docs/reference/NoirJS/noir_js/functions/xor.md +++ /dev/null @@ -1,22 +0,0 @@ -# xor() - -```ts -xor(lhs, rhs): string -``` - -Performs a bitwise XOR operation between `lhs` and `rhs` - -## Parameters - -| Parameter | Type | Description | -| :------ | :------ | :------ | -| `lhs` | `string` | | -| `rhs` | `string` | | - -## Returns - -`string` - -*** - -Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/docs/reference/NoirJS/noir_js/index.md b/docs/docs/reference/NoirJS/noir_js/index.md deleted file mode 100644 index d600e21b299..00000000000 --- a/docs/docs/reference/NoirJS/noir_js/index.md +++ /dev/null @@ -1,37 +0,0 @@ -# noir_js - -## Exports - -### Classes - -| Class | Description | -| :------ | :------ | -| [Noir](classes/Noir.md) | - | - -### Type Aliases - -| Type alias | Description | -| :------ | :------ | -| [CompiledCircuit](type-aliases/CompiledCircuit.md) | - | -| [ForeignCallHandler](type-aliases/ForeignCallHandler.md) | A callback which performs an foreign call and returns the response. | -| [ForeignCallInput](type-aliases/ForeignCallInput.md) | - | -| [ForeignCallOutput](type-aliases/ForeignCallOutput.md) | - | -| [InputMap](type-aliases/InputMap.md) | - | -| [ProofData](type-aliases/ProofData.md) | - | -| [WitnessMap](type-aliases/WitnessMap.md) | - | - -### Functions - -| Function | Description | -| :------ | :------ | -| [and](functions/and.md) | Performs a bitwise AND operation between `lhs` and `rhs` | -| [blake2s256](functions/blake2s256.md) | Calculates the Blake2s256 hash of the input bytes | -| [ecdsa\_secp256k1\_verify](functions/ecdsa_secp256k1_verify.md) | Verifies a ECDSA signature over the secp256k1 curve. | -| [ecdsa\_secp256r1\_verify](functions/ecdsa_secp256r1_verify.md) | Verifies a ECDSA signature over the secp256r1 curve. | -| [keccak256](functions/keccak256.md) | Calculates the Keccak256 hash of the input bytes | -| [sha256](functions/sha256.md) | Calculates the SHA256 hash of the input bytes | -| [xor](functions/xor.md) | Performs a bitwise XOR operation between `lhs` and `rhs` | - -*** - -Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/docs/reference/NoirJS/noir_js/type-aliases/CompiledCircuit.md b/docs/docs/reference/NoirJS/noir_js/type-aliases/CompiledCircuit.md deleted file mode 100644 index 34e0dd04205..00000000000 --- a/docs/docs/reference/NoirJS/noir_js/type-aliases/CompiledCircuit.md +++ /dev/null @@ -1,20 +0,0 @@ -# CompiledCircuit - -```ts -type CompiledCircuit: object; -``` - -## Description - -The representation of a compiled circuit - -## Type declaration - -| Member | Type | Description | -| :------ | :------ | :------ | -| `abi` | `Abi` | **Description**

ABI representation of the circuit | -| `bytecode` | `string` | **Description**

The bytecode of the circuit | - -*** - -Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/docs/reference/NoirJS/noir_js/type-aliases/ForeignCallHandler.md b/docs/docs/reference/NoirJS/noir_js/type-aliases/ForeignCallHandler.md deleted file mode 100644 index 812b8b16481..00000000000 --- a/docs/docs/reference/NoirJS/noir_js/type-aliases/ForeignCallHandler.md +++ /dev/null @@ -1,24 +0,0 @@ -# ForeignCallHandler - -```ts -type ForeignCallHandler: (name, inputs) => Promise; -``` - -A callback which performs an foreign call and returns the response. - -## Parameters - -| Parameter | Type | Description | -| :------ | :------ | :------ | -| `name` | `string` | The identifier for the type of foreign call being performed. | -| `inputs` | [`ForeignCallInput`](ForeignCallInput.md)[] | An array of hex encoded inputs to the foreign call. | - -## Returns - -`Promise`\<[`ForeignCallOutput`](ForeignCallOutput.md)[]\> - -outputs - An array of hex encoded outputs containing the results of the foreign call. - -*** - -Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/docs/reference/NoirJS/noir_js/type-aliases/ForeignCallInput.md b/docs/docs/reference/NoirJS/noir_js/type-aliases/ForeignCallInput.md deleted file mode 100644 index dd95809186a..00000000000 --- a/docs/docs/reference/NoirJS/noir_js/type-aliases/ForeignCallInput.md +++ /dev/null @@ -1,9 +0,0 @@ -# ForeignCallInput - -```ts -type ForeignCallInput: string[]; -``` - -*** - -Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/docs/reference/NoirJS/noir_js/type-aliases/ForeignCallOutput.md b/docs/docs/reference/NoirJS/noir_js/type-aliases/ForeignCallOutput.md deleted file mode 100644 index b71fb78a946..00000000000 --- a/docs/docs/reference/NoirJS/noir_js/type-aliases/ForeignCallOutput.md +++ /dev/null @@ -1,9 +0,0 @@ -# ForeignCallOutput - -```ts -type ForeignCallOutput: string | string[]; -``` - -*** - -Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/docs/reference/NoirJS/noir_js/type-aliases/InputMap.md b/docs/docs/reference/NoirJS/noir_js/type-aliases/InputMap.md deleted file mode 100644 index c714e999d93..00000000000 --- a/docs/docs/reference/NoirJS/noir_js/type-aliases/InputMap.md +++ /dev/null @@ -1,13 +0,0 @@ -# InputMap - -```ts -type InputMap: object; -``` - -## Index signature - - \[`key`: `string`\]: `InputValue` - -*** - -Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/docs/reference/NoirJS/noir_js/type-aliases/ProofData.md b/docs/docs/reference/NoirJS/noir_js/type-aliases/ProofData.md deleted file mode 100644 index 05cebbc4e94..00000000000 --- a/docs/docs/reference/NoirJS/noir_js/type-aliases/ProofData.md +++ /dev/null @@ -1,20 +0,0 @@ -# ProofData - -```ts -type ProofData: object; -``` - -## Description - -The representation of a proof - -## Type declaration - -| Member | Type | Description | -| :------ | :------ | :------ | -| `proof` | `Uint8Array` | **Description**

An byte array representing the proof | -| `publicInputs` | `string`[] | **Description**

Public inputs of a proof | - -*** - -Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/docs/reference/NoirJS/noir_js/type-aliases/WitnessMap.md b/docs/docs/reference/NoirJS/noir_js/type-aliases/WitnessMap.md deleted file mode 100644 index 258c46f9d0c..00000000000 --- a/docs/docs/reference/NoirJS/noir_js/type-aliases/WitnessMap.md +++ /dev/null @@ -1,9 +0,0 @@ -# WitnessMap - -```ts -type WitnessMap: Map; -``` - -*** - -Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/docs/docs/reference/NoirJS/noir_js/typedoc-sidebar.cjs b/docs/docs/reference/NoirJS/noir_js/typedoc-sidebar.cjs deleted file mode 100644 index fe2629ddc9f..00000000000 --- a/docs/docs/reference/NoirJS/noir_js/typedoc-sidebar.cjs +++ /dev/null @@ -1,4 +0,0 @@ -// @ts-check -/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */ -const typedocSidebar = { items: [{"type":"category","label":"Classes","items":[{"type":"doc","id":"reference/NoirJS/noir_js/classes/Noir","label":"Noir"}]},{"type":"category","label":"Type Aliases","items":[{"type":"doc","id":"reference/NoirJS/noir_js/type-aliases/CompiledCircuit","label":"CompiledCircuit"},{"type":"doc","id":"reference/NoirJS/noir_js/type-aliases/ForeignCallHandler","label":"ForeignCallHandler"},{"type":"doc","id":"reference/NoirJS/noir_js/type-aliases/ForeignCallInput","label":"ForeignCallInput"},{"type":"doc","id":"reference/NoirJS/noir_js/type-aliases/ForeignCallOutput","label":"ForeignCallOutput"},{"type":"doc","id":"reference/NoirJS/noir_js/type-aliases/InputMap","label":"InputMap"},{"type":"doc","id":"reference/NoirJS/noir_js/type-aliases/ProofData","label":"ProofData"},{"type":"doc","id":"reference/NoirJS/noir_js/type-aliases/WitnessMap","label":"WitnessMap"}]},{"type":"category","label":"Functions","items":[{"type":"doc","id":"reference/NoirJS/noir_js/functions/and","label":"and"},{"type":"doc","id":"reference/NoirJS/noir_js/functions/blake2s256","label":"blake2s256"},{"type":"doc","id":"reference/NoirJS/noir_js/functions/ecdsa_secp256k1_verify","label":"ecdsa_secp256k1_verify"},{"type":"doc","id":"reference/NoirJS/noir_js/functions/ecdsa_secp256r1_verify","label":"ecdsa_secp256r1_verify"},{"type":"doc","id":"reference/NoirJS/noir_js/functions/keccak256","label":"keccak256"},{"type":"doc","id":"reference/NoirJS/noir_js/functions/sha256","label":"sha256"},{"type":"doc","id":"reference/NoirJS/noir_js/functions/xor","label":"xor"}]}]}; -module.exports = typedocSidebar.items; \ No newline at end of file diff --git a/docs/docusaurus.config.ts b/docs/docusaurus.config.ts index 4e0d053f61e..d1d344ba635 100644 --- a/docs/docusaurus.config.ts +++ b/docs/docusaurus.config.ts @@ -155,7 +155,7 @@ export default { entryPoints: ['../tooling/noir_js/src/index.ts'], tsconfig: '../tooling/noir_js/tsconfig.json', entryPointStrategy: 'resolve', - out: 'docs/reference/NoirJS/noir_js', + out: 'processed-docs/reference/NoirJS/noir_js', plugin: ['typedoc-plugin-markdown'], name: 'noir_js', disableSources: true, @@ -186,7 +186,7 @@ export default { entryPoints: ['../tooling/noir_js_backend_barretenberg/src/index.ts'], tsconfig: '../tooling/noir_js_backend_barretenberg/tsconfig.json', entryPointStrategy: 'resolve', - out: 'docs/reference/NoirJS/backend_barretenberg', + out: 'processed-docs/reference/NoirJS/backend_barretenberg', plugin: ['typedoc-plugin-markdown'], name: 'backend_barretenberg', disableSources: true, From 2e26530bf53006c1ed4fee310bcaa905c95dd95b Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Mon, 29 Jan 2024 16:07:00 +0000 Subject: [PATCH 47/70] fix: remove panic from `init_log_level` in `acvm_js` (#4195) # Description ## Problem\* Resolves ## Summary\* Looking at the [CI logs](https://github.com/noir-lang/noir/actions/runs/7698147053/job/20976987617?pr=4194#step:6:16), the ACVM JS failures seem to be happening inside the `init_log_lebel` function. I'm not sure how this panic would be triggered intermittently but this PR removes it in favour of returning a JS error as we shouldn't assume that user inputted log levels are valid. ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- acvm-repo/acvm_js/src/logging.rs | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/acvm-repo/acvm_js/src/logging.rs b/acvm-repo/acvm_js/src/logging.rs index f5d71fae067..483c23ab624 100644 --- a/acvm-repo/acvm_js/src/logging.rs +++ b/acvm-repo/acvm_js/src/logging.rs @@ -1,3 +1,4 @@ +use js_sys::{Error, JsString}; use tracing_subscriber::prelude::*; use tracing_subscriber::EnvFilter; use tracing_web::MakeWebConsoleWriter; @@ -7,12 +8,15 @@ use wasm_bindgen::prelude::*; /// /// @param {LogLevel} level - The maximum level of logging to be emitted. #[wasm_bindgen(js_name = initLogLevel, skip_jsdoc)] -pub fn init_log_level(filter: String) { +pub fn init_log_level(filter: String) -> Result<(), JsLogInitError> { // Set the static variable from Rust use std::sync::Once; - let filter: EnvFilter = - filter.parse().expect("Could not parse log filter while initializing logger"); + let filter: EnvFilter = filter.parse().map_err(|err| { + JsLogInitError::constructor( + format!("Could not parse log filter while initializing logger: {err}").into(), + ) + })?; static SET_HOOK: Once = Once::new(); SET_HOOK.call_once(|| { @@ -23,4 +27,19 @@ pub fn init_log_level(filter: String) { tracing_subscriber::registry().with(fmt_layer.with_filter(filter)).init(); }); + + Ok(()) +} + +/// `LogInitError` is a raw js error. +/// It'd be ideal that `LogInitError` was a subclass of Error, but for that we'd need to use JS snippets or a js module. +/// Currently JS snippets don't work with a nodejs target. And a module would be too much for just a custom error type. +#[wasm_bindgen] +extern "C" { + #[wasm_bindgen(extends = Error, js_name = "LogInitError", typescript_type = "LogInitError")] + #[derive(Clone, Debug, PartialEq, Eq)] + pub type JsLogInitError; + + #[wasm_bindgen(constructor, js_class = "Error")] + fn constructor(message: JsString) -> JsLogInitError; } From ebdb24f96800a2e3de7540b4656ab281cfc78d22 Mon Sep 17 00:00:00 2001 From: kevaundray Date: Mon, 29 Jan 2024 16:44:25 +0000 Subject: [PATCH 48/70] chore(doc): Add docs for `assert_max_bit_size` (#4196) # Description Resolves https://github.com/noir-lang/noir/issues/4135 ## Problem\* Resolves ## Summary\* ## Additional Context ## Documentation\* Check one: - [ ] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [ ] I have tested the changes locally. - [ ] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. Signed-off-by: Kevaundray Wedderburn --- docs/docs/noir/concepts/data_types/fields.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/docs/docs/noir/concepts/data_types/fields.md b/docs/docs/noir/concepts/data_types/fields.md index a1c67945d66..7870c98c858 100644 --- a/docs/docs/noir/concepts/data_types/fields.md +++ b/docs/docs/noir/concepts/data_types/fields.md @@ -157,6 +157,23 @@ fn main() { } ``` +### assert_max_bit_size + +Adds a constraint to specify that the field can be represented with `bit_size` number of bits + +```rust +fn assert_max_bit_size(self, bit_size: u32) +``` + +example: + +```rust +fn main() { + let field = 2 + field.assert_max_bit_size(32); +} +``` + ### 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. From 1fd3e6d7f619393f02fb456ae5942baad4b5426e Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Mon, 29 Jan 2024 18:10:20 +0000 Subject: [PATCH 49/70] chore: simplify marking black box function outputs as solvable (#4194) # Description ## Problem\* Resolves ## Summary\* smol refactor I noticed. ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- .../acvm/src/compiler/transformers/mod.rs | 46 +------------------ 1 file changed, 2 insertions(+), 44 deletions(-) diff --git a/acvm-repo/acvm/src/compiler/transformers/mod.rs b/acvm-repo/acvm/src/compiler/transformers/mod.rs index 306ea1b7c12..e184401c5d4 100644 --- a/acvm-repo/acvm/src/compiler/transformers/mod.rs +++ b/acvm-repo/acvm/src/compiler/transformers/mod.rs @@ -99,50 +99,8 @@ pub(super) fn transform_internal( } } Opcode::BlackBoxFuncCall(ref func) => { - match func { - acir::circuit::opcodes::BlackBoxFuncCall::AND { output, .. } - | acir::circuit::opcodes::BlackBoxFuncCall::XOR { output, .. } => { - transformer.mark_solvable(*output); - } - acir::circuit::opcodes::BlackBoxFuncCall::RANGE { .. } - | acir::circuit::opcodes::BlackBoxFuncCall::RecursiveAggregation { .. } => (), - acir::circuit::opcodes::BlackBoxFuncCall::SHA256 { outputs, .. } - | acir::circuit::opcodes::BlackBoxFuncCall::Keccak256 { outputs, .. } - | acir::circuit::opcodes::BlackBoxFuncCall::Keccak256VariableLength { - outputs, - .. - } - | acir::circuit::opcodes::BlackBoxFuncCall::Keccakf1600 { outputs, .. } - | acir::circuit::opcodes::BlackBoxFuncCall::Blake2s { outputs, .. } - | acir::circuit::opcodes::BlackBoxFuncCall::Blake3 { outputs, .. } => { - for witness in outputs { - transformer.mark_solvable(*witness); - } - } - acir::circuit::opcodes::BlackBoxFuncCall::FixedBaseScalarMul { - outputs, - .. - } - | acir::circuit::opcodes::BlackBoxFuncCall::EmbeddedCurveAdd { - outputs, .. - } - | acir::circuit::opcodes::BlackBoxFuncCall::EmbeddedCurveDouble { - outputs, - .. - } - | acir::circuit::opcodes::BlackBoxFuncCall::PedersenCommitment { - outputs, - .. - } => { - transformer.mark_solvable(outputs.0); - transformer.mark_solvable(outputs.1); - } - acir::circuit::opcodes::BlackBoxFuncCall::EcdsaSecp256k1 { output, .. } - | acir::circuit::opcodes::BlackBoxFuncCall::EcdsaSecp256r1 { output, .. } - | acir::circuit::opcodes::BlackBoxFuncCall::SchnorrVerify { output, .. } - | acir::circuit::opcodes::BlackBoxFuncCall::PedersenHash { output, .. } => { - transformer.mark_solvable(*output); - } + for witness in func.get_outputs_vec() { + transformer.mark_solvable(witness); } new_acir_opcode_positions.push(acir_opcode_positions[index]); From c50621f1acddfb9138d6a036fd78c7a6c08dd084 Mon Sep 17 00:00:00 2001 From: kevaundray Date: Mon, 29 Jan 2024 20:40:22 +0000 Subject: [PATCH 50/70] feat: Move bounded_vec into the noir stdlib (#4197) # Description Partially resolves #4020. Need to then remove from `aztec-packages` and move to this implementation. ## Problem\* Resolves ## Summary\* ## Additional Context ## Documentation\* Check one: - [ ] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [ ] I have tested the changes locally. - [ ] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --------- Signed-off-by: Kevaundray Wedderburn Co-authored-by: vezenovm --- noir_stdlib/src/collections.nr | 1 + noir_stdlib/src/collections/bounded_vec.nr | 88 +++++++++++++++ noir_stdlib/src/prelude.nr | 1 + .../noir_test_success/bounded_vec/Nargo.toml | 7 ++ .../noir_test_success/bounded_vec/Prover.toml | 0 .../noir_test_success/bounded_vec/src/main.nr | 105 ++++++++++++++++++ 6 files changed, 202 insertions(+) create mode 100644 noir_stdlib/src/collections/bounded_vec.nr create mode 100644 test_programs/noir_test_success/bounded_vec/Nargo.toml create mode 100644 test_programs/noir_test_success/bounded_vec/Prover.toml create mode 100644 test_programs/noir_test_success/bounded_vec/src/main.nr diff --git a/noir_stdlib/src/collections.nr b/noir_stdlib/src/collections.nr index e06c662e658..177ca96816f 100644 --- a/noir_stdlib/src/collections.nr +++ b/noir_stdlib/src/collections.nr @@ -1 +1,2 @@ mod vec; +mod bounded_vec; diff --git a/noir_stdlib/src/collections/bounded_vec.nr b/noir_stdlib/src/collections/bounded_vec.nr new file mode 100644 index 00000000000..332fefa63f9 --- /dev/null +++ b/noir_stdlib/src/collections/bounded_vec.nr @@ -0,0 +1,88 @@ +struct BoundedVec { + storage: [T; MaxLen], + // TODO: change this to return a u64 as Noir now + // uses u64 for indexing + len: Field, + empty_value: T, +} + +impl BoundedVec { + pub fn new(initial_value: T) -> Self { + BoundedVec { storage: [initial_value; MaxLen], len: 0, empty_value: initial_value } + } + + pub fn get(mut self: Self, index: Field) -> T { + assert(index as u64 < self.len as u64); + self.storage[index] + } + + pub fn get_unchecked(mut self: Self, index: Field) -> T { + self.storage[index] + } + + pub fn push(&mut self, elem: T) { + assert(self.len as u64 < MaxLen as u64, "push out of bounds"); + + self.storage[self.len] = elem; + self.len += 1; + } + + pub fn len(self) -> Field { + self.len + } + + pub fn max_len(_self: BoundedVec) -> Field { + MaxLen + } + + // This is a intermediate method, while we don't have an + // .extend method + pub fn storage(self) -> [T; MaxLen] { + self.storage + } + + pub fn extend_from_array(&mut self, array: [T; Len]) { + let new_len = self.len + array.len(); + assert(new_len as u64 <= MaxLen as u64, "extend_from_array out of bounds"); + for i in 0..array.len() { + self.storage[self.len + i] = array[i]; + } + self.len = new_len; + } + + pub fn extend_from_bounded_vec(&mut self, vec: BoundedVec) { + let append_len = vec.len(); + let new_len = self.len + append_len; + assert(new_len as u64 <= MaxLen as u64, "extend_from_bounded_vec out of bounds"); + + let mut exceeded_len = false; + for i in 0..Len { + exceeded_len |= i == append_len; + if !exceeded_len { + self.storage[self.len + (i as Field)] = vec.get_unchecked(i as Field); + } + } + self.len = new_len; + } + + pub fn pop(&mut self) -> T { + assert(self.len as u64 > 0); + self.len -= 1; + + let elem = self.storage[self.len]; + self.storage[self.len] = self.empty_value; + elem + } + + pub fn any(self, predicate: fn[Env](T) -> bool) -> bool { + let mut ret = false; + let mut exceeded_len = false; + for i in 0..MaxLen { + exceeded_len |= i == self.len; + if (!exceeded_len) { + ret |= predicate(self.storage[i]); + } + } + ret + } +} \ No newline at end of file diff --git a/noir_stdlib/src/prelude.nr b/noir_stdlib/src/prelude.nr index 26c6a805d54..3244329aa4b 100644 --- a/noir_stdlib/src/prelude.nr +++ b/noir_stdlib/src/prelude.nr @@ -1,4 +1,5 @@ use crate::collections::vec::Vec; +use crate::collections::bounded_vec::BoundedVec; use crate::option::Option; use crate::{print, println, assert_constant}; use crate::uint128::U128; diff --git a/test_programs/noir_test_success/bounded_vec/Nargo.toml b/test_programs/noir_test_success/bounded_vec/Nargo.toml new file mode 100644 index 00000000000..0d58f5872ef --- /dev/null +++ b/test_programs/noir_test_success/bounded_vec/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "bounded_vec" +type = "bin" +authors = [""] +compiler_version = ">=0.23.0" + +[dependencies] \ No newline at end of file diff --git a/test_programs/noir_test_success/bounded_vec/Prover.toml b/test_programs/noir_test_success/bounded_vec/Prover.toml new file mode 100644 index 00000000000..e69de29bb2d diff --git a/test_programs/noir_test_success/bounded_vec/src/main.nr b/test_programs/noir_test_success/bounded_vec/src/main.nr new file mode 100644 index 00000000000..d51d2cc3685 --- /dev/null +++ b/test_programs/noir_test_success/bounded_vec/src/main.nr @@ -0,0 +1,105 @@ +#[test] +fn test_vec_push_pop() { + let mut vec: BoundedVec = BoundedVec::new(0); + assert(vec.len == 0); + vec.push(2); + assert(vec.len == 1); + vec.push(4); + assert(vec.len == 2); + vec.push(6); + assert(vec.len == 3); + let x = vec.pop(); + assert(x == 6); + assert(vec.len == 2); + assert(vec.get(0) == 2); + assert(vec.get(1) == 4); +} + +#[test] +fn test_vec_extend_from_array() { + let mut vec: BoundedVec = BoundedVec::new(0); + vec.extend_from_array([2, 4]); + assert(vec.len == 2); + assert(vec.get(0) == 2); + assert(vec.get(1) == 4); +} + +#[test(should_fail_with="extend_from_array out of bounds")] +fn test_vec_extend_from_array_out_of_bound() { + let mut vec: BoundedVec = BoundedVec::new(0); + vec.extend_from_array([2, 4, 6]); +} + +#[test(should_fail_with="extend_from_array out of bounds")] +fn test_vec_extend_from_array_twice_out_of_bound() { + let mut vec: BoundedVec = BoundedVec::new(0); + vec.extend_from_array([2]); + assert(vec.len == 1); + vec.extend_from_array([4, 6]); +} + +#[test(should_fail)] +fn test_vec_get_out_of_bound() { + let mut vec: BoundedVec = BoundedVec::new(0); + vec.extend_from_array([2, 4]); + let _x = vec.get(2); +} + +#[test(should_fail)] +fn test_vec_get_not_declared() { + let mut vec: BoundedVec = BoundedVec::new(0); + vec.extend_from_array([2]); + let _x = vec.get(1); +} + +#[test(should_fail)] +fn test_vec_get_uninitialized() { + let mut vec: BoundedVec = BoundedVec::new(0); + let _x = vec.get(0); +} + +#[test(should_fail_with="push out of bounds")] +fn test_vec_push_out_of_bound() { + let mut vec: BoundedVec = BoundedVec::new(0); + vec.push(1); + vec.push(2); +} + +#[test(should_fail_with="extend_from_bounded_vec out of bounds")] +fn test_vec_extend_from_bounded_vec_out_of_bound() { + let mut vec: BoundedVec = BoundedVec::new(0); + + let mut another_vec: BoundedVec = BoundedVec::new(0); + another_vec.extend_from_array([1, 2, 3]); + + vec.extend_from_bounded_vec(another_vec); +} + +#[test(should_fail_with="extend_from_bounded_vec out of bounds")] +fn test_vec_extend_from_bounded_vec_twice_out_of_bound() { + let mut vec: BoundedVec = BoundedVec::new(0); + vec.extend_from_array([1, 2]); + + let mut another_vec: BoundedVec = BoundedVec::new(0); + another_vec.push(3); + + vec.extend_from_bounded_vec(another_vec); +} + +#[test] +fn test_vec_any() { + let mut vec: BoundedVec = BoundedVec::new(0); + vec.extend_from_array([2, 4, 6]); + assert(vec.any(|v| v == 2) == true); + assert(vec.any(|v| v == 4) == true); + assert(vec.any(|v| v == 6) == true); + assert(vec.any(|v| v == 3) == false); +} + +#[test] +fn test_vec_any_not_default() { + let default_value = 1; + let mut vec: BoundedVec = BoundedVec::new(default_value); + vec.extend_from_array([2, 4]); + assert(vec.any(|v| v == default_value) == false); +} \ No newline at end of file From 882639de109f0ecccf2a8522e2181a301145e19f Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Mon, 29 Jan 2024 22:01:10 +0000 Subject: [PATCH 51/70] feat: multiply first to allow more ACIR gen optimizations (#4201) # Description ## Problem\* Resolves ## Summary\* I noticed that we were getting suboptimal acir generation when using `.any()` on `BoundedVec` where the `exceededLen` check would get more expensive the longer the `BoundedVec` was. The issue turned out to be that because we we would sum before multiplying when performing the ORs on the length check, we weren't taking advantage of the fact that multiplication can result in one of its inputs being replaced with a single witness if the result would have been degree 3 or more. This meant that rather than having a simple `a + b - 2ab` for each OR with `a` and `b` being witnesses , `a` would consist of a quadratic and 2 linear terms. We'd then continue to pick up extra terms for each element in the `BoundedVec`. The simple fix is then whenever we are performing operations on two arguments where one of those operations is a multiplication (or anything which can result in a simplification) we should do that first in order to apply those simplifications to the other operations. ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- .../noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs b/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs index cd96f6f8cb9..e88e92ef76a 100644 --- a/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs +++ b/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs @@ -396,8 +396,8 @@ impl AcirContext { // Operands are booleans. // // a ^ b == a + b - 2*a*b - let sum = self.add_var(lhs, rhs)?; let prod = self.mul_var(lhs, rhs)?; + let sum = self.add_var(lhs, rhs)?; self.add_mul_var(sum, -FieldElement::from(2_i128), prod) } else { let inputs = vec![AcirValue::Var(lhs, typ.clone()), AcirValue::Var(rhs, typ)]; @@ -457,8 +457,8 @@ impl AcirContext { if bit_size == 1 { // Operands are booleans // a + b - ab - let sum = self.add_var(lhs, rhs)?; let mul = self.mul_var(lhs, rhs)?; + let sum = self.add_var(lhs, rhs)?; self.sub_var(sum, mul) } else { // Implement OR in terms of AND From 0205d3b4ad0cf5ffd775a43eb5af273a772cf138 Mon Sep 17 00:00:00 2001 From: Aztec Bot <49558828+AztecBot@users.noreply.github.com> Date: Tue, 30 Jan 2024 09:56:58 -0500 Subject: [PATCH 52/70] feat!: Sync commits from `aztec-packages` (#4144) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Development from [aztec-packages](https://github.com/AztecProtocol/aztec-packages). --------- Co-authored-by: ludamad Co-authored-by: ludamad Co-authored-by: kevaundray Co-authored-by: sirasistant Co-authored-by: Gregorio Juliana Co-authored-by: Tom French Co-authored-by: Maxim Vezenov Co-authored-by: Jan Beneš Co-authored-by: Charlie Lye Co-authored-by: Tom French <15848336+TomAFrench@users.noreply.github.com> Co-authored-by: ledwards2225 Co-authored-by: ledwards2225 <98505400+ledwards2225@users.noreply.github.com> Co-authored-by: Santiago Palladino Co-authored-by: James Zaki Co-authored-by: guipublic <47281315+guipublic@users.noreply.github.com> --- acvm-repo/acir/codegen/acir.cpp | 1312 +++++++++++++---- .../acir/src/circuit/black_box_functions.rs | 42 +- .../opcodes/black_box_function_call.rs | 100 +- .../src/pwg/blackbox/fixed_base_scalar_mul.rs | 21 + acvm-repo/acvm/src/pwg/blackbox/mod.rs | 25 +- .../src/curve_specific_solver.rs | 12 - .../src/fixed_base_scalar_mul.rs | 20 + acvm-repo/bn254_blackbox_solver/src/lib.rs | 20 +- acvm-repo/brillig/src/black_box.rs | 84 +- acvm-repo/brillig_vm/src/black_box.rs | 24 +- acvm-repo/brillig_vm/src/lib.rs | 7 - .../brillig/brillig_gen/brillig_black_box.rs | 149 +- .../noirc_evaluator/src/brillig/brillig_ir.rs | 8 - .../src/brillig/brillig_ir/debug_show.rs | 80 +- compiler/noirc_evaluator/src/errors.rs | 5 +- .../src/ssa/acir_gen/acir_ir.rs | 1 + .../src/ssa/acir_gen/acir_ir/acir_variable.rs | 135 +- .../src/ssa/acir_gen/acir_ir/big_int.rs | 57 + .../ssa/acir_gen/acir_ir/generated_acir.rs | 98 +- .../noirc_evaluator/src/ssa/acir_gen/mod.rs | 29 +- .../src/ssa/ir/instruction/call.rs | 15 +- noir_stdlib/src/bigint.nr | 53 + noir_stdlib/src/hash.nr | 5 + noir_stdlib/src/lib.nr | 1 + noir_stdlib/src/scalar_mul.nr | 22 + .../execution_success/scalar_mul/src/main.nr | 8 + tooling/backend_interface/src/cli/mod.rs | 2 +- tooling/bb_abstraction_leaks/build.rs | 2 +- tooling/lsp/src/solver.rs | 8 - .../noir_js_backend_barretenberg/package.json | 2 +- yarn.lock | 10 +- 31 files changed, 1915 insertions(+), 442 deletions(-) create mode 100644 compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/big_int.rs create mode 100644 noir_stdlib/src/bigint.nr diff --git a/acvm-repo/acir/codegen/acir.cpp b/acvm-repo/acir/codegen/acir.cpp index 9b74a8ea631..0f94e91ab10 100644 --- a/acvm-repo/acir/codegen/acir.cpp +++ b/acvm-repo/acir/codegen/acir.cpp @@ -157,16 +157,6 @@ namespace Circuit { static EmbeddedCurveAdd bincodeDeserialize(std::vector); }; - struct EmbeddedCurveDouble { - Circuit::FunctionInput input_x; - Circuit::FunctionInput input_y; - std::array outputs; - - friend bool operator==(const EmbeddedCurveDouble&, const EmbeddedCurveDouble&); - std::vector bincodeSerialize() const; - static EmbeddedCurveDouble bincodeDeserialize(std::vector); - }; - struct Keccak256 { std::vector inputs; std::vector outputs; @@ -206,7 +196,86 @@ namespace Circuit { static RecursiveAggregation bincodeDeserialize(std::vector); }; - std::variant value; + struct BigIntAdd { + uint32_t lhs; + uint32_t rhs; + uint32_t output; + + friend bool operator==(const BigIntAdd&, const BigIntAdd&); + std::vector bincodeSerialize() const; + static BigIntAdd bincodeDeserialize(std::vector); + }; + + struct BigIntNeg { + uint32_t lhs; + uint32_t rhs; + uint32_t output; + + friend bool operator==(const BigIntNeg&, const BigIntNeg&); + std::vector bincodeSerialize() const; + static BigIntNeg bincodeDeserialize(std::vector); + }; + + struct BigIntMul { + uint32_t lhs; + uint32_t rhs; + uint32_t output; + + friend bool operator==(const BigIntMul&, const BigIntMul&); + std::vector bincodeSerialize() const; + static BigIntMul bincodeDeserialize(std::vector); + }; + + struct BigIntDiv { + uint32_t lhs; + uint32_t rhs; + uint32_t output; + + friend bool operator==(const BigIntDiv&, const BigIntDiv&); + std::vector bincodeSerialize() const; + static BigIntDiv bincodeDeserialize(std::vector); + }; + + struct BigIntFromLeBytes { + std::vector inputs; + std::vector modulus; + uint32_t output; + + friend bool operator==(const BigIntFromLeBytes&, const BigIntFromLeBytes&); + std::vector bincodeSerialize() const; + static BigIntFromLeBytes bincodeDeserialize(std::vector); + }; + + struct BigIntToLeBytes { + uint32_t input; + std::vector outputs; + + friend bool operator==(const BigIntToLeBytes&, const BigIntToLeBytes&); + std::vector bincodeSerialize() const; + static BigIntToLeBytes bincodeDeserialize(std::vector); + }; + + struct Poseidon2Permutation { + std::vector inputs; + std::vector outputs; + uint32_t len; + + friend bool operator==(const Poseidon2Permutation&, const Poseidon2Permutation&); + std::vector bincodeSerialize() const; + static Poseidon2Permutation bincodeDeserialize(std::vector); + }; + + struct Sha256Compression { + std::vector inputs; + std::vector hash_values; + std::vector outputs; + + friend bool operator==(const Sha256Compression&, const Sha256Compression&); + std::vector bincodeSerialize() const; + static Sha256Compression bincodeDeserialize(std::vector); + }; + + std::variant value; friend bool operator==(const BlackBoxFuncCall&, const BlackBoxFuncCall&); std::vector bincodeSerialize() const; @@ -533,17 +602,86 @@ namespace Circuit { static EmbeddedCurveAdd bincodeDeserialize(std::vector); }; - struct EmbeddedCurveDouble { - Circuit::RegisterIndex input1_x; - Circuit::RegisterIndex input1_y; - Circuit::HeapArray result; + struct BigIntAdd { + Circuit::RegisterIndex lhs; + Circuit::RegisterIndex rhs; + Circuit::RegisterIndex output; + + friend bool operator==(const BigIntAdd&, const BigIntAdd&); + std::vector bincodeSerialize() const; + static BigIntAdd bincodeDeserialize(std::vector); + }; + + struct BigIntNeg { + Circuit::RegisterIndex lhs; + Circuit::RegisterIndex rhs; + Circuit::RegisterIndex output; + + friend bool operator==(const BigIntNeg&, const BigIntNeg&); + std::vector bincodeSerialize() const; + static BigIntNeg bincodeDeserialize(std::vector); + }; + + struct BigIntMul { + Circuit::RegisterIndex lhs; + Circuit::RegisterIndex rhs; + Circuit::RegisterIndex output; + + friend bool operator==(const BigIntMul&, const BigIntMul&); + std::vector bincodeSerialize() const; + static BigIntMul bincodeDeserialize(std::vector); + }; + + struct BigIntDiv { + Circuit::RegisterIndex lhs; + Circuit::RegisterIndex rhs; + Circuit::RegisterIndex output; + + friend bool operator==(const BigIntDiv&, const BigIntDiv&); + std::vector bincodeSerialize() const; + static BigIntDiv bincodeDeserialize(std::vector); + }; + + struct BigIntFromLeBytes { + Circuit::HeapVector inputs; + Circuit::HeapVector modulus; + Circuit::RegisterIndex output; + + friend bool operator==(const BigIntFromLeBytes&, const BigIntFromLeBytes&); + std::vector bincodeSerialize() const; + static BigIntFromLeBytes bincodeDeserialize(std::vector); + }; + + struct BigIntToLeBytes { + Circuit::RegisterIndex input; + Circuit::HeapVector output; - friend bool operator==(const EmbeddedCurveDouble&, const EmbeddedCurveDouble&); + friend bool operator==(const BigIntToLeBytes&, const BigIntToLeBytes&); std::vector bincodeSerialize() const; - static EmbeddedCurveDouble bincodeDeserialize(std::vector); + static BigIntToLeBytes bincodeDeserialize(std::vector); }; - std::variant value; + struct Poseidon2Permutation { + Circuit::HeapVector message; + Circuit::HeapArray output; + Circuit::RegisterIndex len; + + friend bool operator==(const Poseidon2Permutation&, const Poseidon2Permutation&); + std::vector bincodeSerialize() const; + static Poseidon2Permutation bincodeDeserialize(std::vector); + }; + + struct Sha256Compression { + Circuit::HeapVector input; + Circuit::HeapVector hash_values; + Circuit::HeapArray output; + + friend bool operator==(const Sha256Compression&, const Sha256Compression&); + std::vector bincodeSerialize() const; + static Sha256Compression bincodeDeserialize(std::vector); + }; + + std::variant value; friend bool operator==(const BlackBoxOp&, const BlackBoxOp&); std::vector bincodeSerialize() const; @@ -2252,50 +2390,6 @@ Circuit::BlackBoxFuncCall::EmbeddedCurveAdd serde::Deserializable BlackBoxFuncCall::EmbeddedCurveDouble::bincodeSerialize() const { - auto serializer = serde::BincodeSerializer(); - serde::Serializable::serialize(*this, serializer); - return std::move(serializer).bytes(); - } - - inline BlackBoxFuncCall::EmbeddedCurveDouble BlackBoxFuncCall::EmbeddedCurveDouble::bincodeDeserialize(std::vector input) { - auto deserializer = serde::BincodeDeserializer(input); - auto value = serde::Deserializable::deserialize(deserializer); - if (deserializer.get_buffer_offset() < input.size()) { - throw serde::deserialization_error("Some input bytes were not read"); - } - return value; - } - -} // end of namespace Circuit - -template <> -template -void serde::Serializable::serialize(const Circuit::BlackBoxFuncCall::EmbeddedCurveDouble &obj, Serializer &serializer) { - serde::Serializable::serialize(obj.input_x, serializer); - serde::Serializable::serialize(obj.input_y, serializer); - serde::Serializable::serialize(obj.outputs, serializer); -} - -template <> -template -Circuit::BlackBoxFuncCall::EmbeddedCurveDouble serde::Deserializable::deserialize(Deserializer &deserializer) { - Circuit::BlackBoxFuncCall::EmbeddedCurveDouble obj; - obj.input_x = serde::Deserializable::deserialize(deserializer); - obj.input_y = serde::Deserializable::deserialize(deserializer); - obj.outputs = serde::Deserializable::deserialize(deserializer); - return obj; -} - namespace Circuit { inline bool operator==(const BlackBoxFuncCall::Keccak256 &lhs, const BlackBoxFuncCall::Keccak256 &rhs) { @@ -2471,20 +2565,22 @@ Circuit::BlackBoxFuncCall::RecursiveAggregation serde::Deserializable BlackBoxOp::bincodeSerialize() const { + inline std::vector BlackBoxFuncCall::BigIntAdd::bincodeSerialize() const { auto serializer = serde::BincodeSerializer(); - serde::Serializable::serialize(*this, serializer); + serde::Serializable::serialize(*this, serializer); return std::move(serializer).bytes(); } - inline BlackBoxOp BlackBoxOp::bincodeDeserialize(std::vector input) { + inline BlackBoxFuncCall::BigIntAdd BlackBoxFuncCall::BigIntAdd::bincodeDeserialize(std::vector input) { auto deserializer = serde::BincodeDeserializer(input); - auto value = serde::Deserializable::deserialize(deserializer); + auto value = serde::Deserializable::deserialize(deserializer); if (deserializer.get_buffer_offset() < input.size()) { throw serde::deserialization_error("Some input bytes were not read"); } @@ -2495,39 +2591,40 @@ namespace Circuit { template <> template -void serde::Serializable::serialize(const Circuit::BlackBoxOp &obj, Serializer &serializer) { - serializer.increase_container_depth(); - serde::Serializable::serialize(obj.value, serializer); - serializer.decrease_container_depth(); +void serde::Serializable::serialize(const Circuit::BlackBoxFuncCall::BigIntAdd &obj, Serializer &serializer) { + serde::Serializable::serialize(obj.lhs, serializer); + serde::Serializable::serialize(obj.rhs, serializer); + serde::Serializable::serialize(obj.output, serializer); } template <> template -Circuit::BlackBoxOp serde::Deserializable::deserialize(Deserializer &deserializer) { - deserializer.increase_container_depth(); - Circuit::BlackBoxOp obj; - obj.value = serde::Deserializable::deserialize(deserializer); - deserializer.decrease_container_depth(); +Circuit::BlackBoxFuncCall::BigIntAdd serde::Deserializable::deserialize(Deserializer &deserializer) { + Circuit::BlackBoxFuncCall::BigIntAdd obj; + obj.lhs = serde::Deserializable::deserialize(deserializer); + obj.rhs = serde::Deserializable::deserialize(deserializer); + obj.output = serde::Deserializable::deserialize(deserializer); return obj; } namespace Circuit { - inline bool operator==(const BlackBoxOp::Sha256 &lhs, const BlackBoxOp::Sha256 &rhs) { - if (!(lhs.message == rhs.message)) { return false; } + inline bool operator==(const BlackBoxFuncCall::BigIntNeg &lhs, const BlackBoxFuncCall::BigIntNeg &rhs) { + if (!(lhs.lhs == rhs.lhs)) { return false; } + if (!(lhs.rhs == rhs.rhs)) { return false; } if (!(lhs.output == rhs.output)) { return false; } return true; } - inline std::vector BlackBoxOp::Sha256::bincodeSerialize() const { + inline std::vector BlackBoxFuncCall::BigIntNeg::bincodeSerialize() const { auto serializer = serde::BincodeSerializer(); - serde::Serializable::serialize(*this, serializer); + serde::Serializable::serialize(*this, serializer); return std::move(serializer).bytes(); } - inline BlackBoxOp::Sha256 BlackBoxOp::Sha256::bincodeDeserialize(std::vector input) { + inline BlackBoxFuncCall::BigIntNeg BlackBoxFuncCall::BigIntNeg::bincodeDeserialize(std::vector input) { auto deserializer = serde::BincodeDeserializer(input); - auto value = serde::Deserializable::deserialize(deserializer); + auto value = serde::Deserializable::deserialize(deserializer); if (deserializer.get_buffer_offset() < input.size()) { throw serde::deserialization_error("Some input bytes were not read"); } @@ -2538,37 +2635,40 @@ namespace Circuit { template <> template -void serde::Serializable::serialize(const Circuit::BlackBoxOp::Sha256 &obj, Serializer &serializer) { - serde::Serializable::serialize(obj.message, serializer); +void serde::Serializable::serialize(const Circuit::BlackBoxFuncCall::BigIntNeg &obj, Serializer &serializer) { + serde::Serializable::serialize(obj.lhs, serializer); + serde::Serializable::serialize(obj.rhs, serializer); serde::Serializable::serialize(obj.output, serializer); } template <> template -Circuit::BlackBoxOp::Sha256 serde::Deserializable::deserialize(Deserializer &deserializer) { - Circuit::BlackBoxOp::Sha256 obj; - obj.message = serde::Deserializable::deserialize(deserializer); +Circuit::BlackBoxFuncCall::BigIntNeg serde::Deserializable::deserialize(Deserializer &deserializer) { + Circuit::BlackBoxFuncCall::BigIntNeg obj; + obj.lhs = serde::Deserializable::deserialize(deserializer); + obj.rhs = serde::Deserializable::deserialize(deserializer); obj.output = serde::Deserializable::deserialize(deserializer); return obj; } namespace Circuit { - inline bool operator==(const BlackBoxOp::Blake2s &lhs, const BlackBoxOp::Blake2s &rhs) { - if (!(lhs.message == rhs.message)) { return false; } + inline bool operator==(const BlackBoxFuncCall::BigIntMul &lhs, const BlackBoxFuncCall::BigIntMul &rhs) { + if (!(lhs.lhs == rhs.lhs)) { return false; } + if (!(lhs.rhs == rhs.rhs)) { return false; } if (!(lhs.output == rhs.output)) { return false; } return true; } - inline std::vector BlackBoxOp::Blake2s::bincodeSerialize() const { + inline std::vector BlackBoxFuncCall::BigIntMul::bincodeSerialize() const { auto serializer = serde::BincodeSerializer(); - serde::Serializable::serialize(*this, serializer); + serde::Serializable::serialize(*this, serializer); return std::move(serializer).bytes(); } - inline BlackBoxOp::Blake2s BlackBoxOp::Blake2s::bincodeDeserialize(std::vector input) { + inline BlackBoxFuncCall::BigIntMul BlackBoxFuncCall::BigIntMul::bincodeDeserialize(std::vector input) { auto deserializer = serde::BincodeDeserializer(input); - auto value = serde::Deserializable::deserialize(deserializer); + auto value = serde::Deserializable::deserialize(deserializer); if (deserializer.get_buffer_offset() < input.size()) { throw serde::deserialization_error("Some input bytes were not read"); } @@ -2579,37 +2679,40 @@ namespace Circuit { template <> template -void serde::Serializable::serialize(const Circuit::BlackBoxOp::Blake2s &obj, Serializer &serializer) { - serde::Serializable::serialize(obj.message, serializer); +void serde::Serializable::serialize(const Circuit::BlackBoxFuncCall::BigIntMul &obj, Serializer &serializer) { + serde::Serializable::serialize(obj.lhs, serializer); + serde::Serializable::serialize(obj.rhs, serializer); serde::Serializable::serialize(obj.output, serializer); } template <> template -Circuit::BlackBoxOp::Blake2s serde::Deserializable::deserialize(Deserializer &deserializer) { - Circuit::BlackBoxOp::Blake2s obj; - obj.message = serde::Deserializable::deserialize(deserializer); +Circuit::BlackBoxFuncCall::BigIntMul serde::Deserializable::deserialize(Deserializer &deserializer) { + Circuit::BlackBoxFuncCall::BigIntMul obj; + obj.lhs = serde::Deserializable::deserialize(deserializer); + obj.rhs = serde::Deserializable::deserialize(deserializer); obj.output = serde::Deserializable::deserialize(deserializer); return obj; } namespace Circuit { - inline bool operator==(const BlackBoxOp::Blake3 &lhs, const BlackBoxOp::Blake3 &rhs) { - if (!(lhs.message == rhs.message)) { return false; } + inline bool operator==(const BlackBoxFuncCall::BigIntDiv &lhs, const BlackBoxFuncCall::BigIntDiv &rhs) { + if (!(lhs.lhs == rhs.lhs)) { return false; } + if (!(lhs.rhs == rhs.rhs)) { return false; } if (!(lhs.output == rhs.output)) { return false; } return true; } - inline std::vector BlackBoxOp::Blake3::bincodeSerialize() const { + inline std::vector BlackBoxFuncCall::BigIntDiv::bincodeSerialize() const { auto serializer = serde::BincodeSerializer(); - serde::Serializable::serialize(*this, serializer); + serde::Serializable::serialize(*this, serializer); return std::move(serializer).bytes(); } - inline BlackBoxOp::Blake3 BlackBoxOp::Blake3::bincodeDeserialize(std::vector input) { + inline BlackBoxFuncCall::BigIntDiv BlackBoxFuncCall::BigIntDiv::bincodeDeserialize(std::vector input) { auto deserializer = serde::BincodeDeserializer(input); - auto value = serde::Deserializable::deserialize(deserializer); + auto value = serde::Deserializable::deserialize(deserializer); if (deserializer.get_buffer_offset() < input.size()) { throw serde::deserialization_error("Some input bytes were not read"); } @@ -2620,37 +2723,40 @@ namespace Circuit { template <> template -void serde::Serializable::serialize(const Circuit::BlackBoxOp::Blake3 &obj, Serializer &serializer) { - serde::Serializable::serialize(obj.message, serializer); +void serde::Serializable::serialize(const Circuit::BlackBoxFuncCall::BigIntDiv &obj, Serializer &serializer) { + serde::Serializable::serialize(obj.lhs, serializer); + serde::Serializable::serialize(obj.rhs, serializer); serde::Serializable::serialize(obj.output, serializer); } template <> template -Circuit::BlackBoxOp::Blake3 serde::Deserializable::deserialize(Deserializer &deserializer) { - Circuit::BlackBoxOp::Blake3 obj; - obj.message = serde::Deserializable::deserialize(deserializer); +Circuit::BlackBoxFuncCall::BigIntDiv serde::Deserializable::deserialize(Deserializer &deserializer) { + Circuit::BlackBoxFuncCall::BigIntDiv obj; + obj.lhs = serde::Deserializable::deserialize(deserializer); + obj.rhs = serde::Deserializable::deserialize(deserializer); obj.output = serde::Deserializable::deserialize(deserializer); return obj; } namespace Circuit { - inline bool operator==(const BlackBoxOp::Keccak256 &lhs, const BlackBoxOp::Keccak256 &rhs) { - if (!(lhs.message == rhs.message)) { return false; } + inline bool operator==(const BlackBoxFuncCall::BigIntFromLeBytes &lhs, const BlackBoxFuncCall::BigIntFromLeBytes &rhs) { + if (!(lhs.inputs == rhs.inputs)) { return false; } + if (!(lhs.modulus == rhs.modulus)) { return false; } if (!(lhs.output == rhs.output)) { return false; } return true; } - inline std::vector BlackBoxOp::Keccak256::bincodeSerialize() const { + inline std::vector BlackBoxFuncCall::BigIntFromLeBytes::bincodeSerialize() const { auto serializer = serde::BincodeSerializer(); - serde::Serializable::serialize(*this, serializer); + serde::Serializable::serialize(*this, serializer); return std::move(serializer).bytes(); } - inline BlackBoxOp::Keccak256 BlackBoxOp::Keccak256::bincodeDeserialize(std::vector input) { + inline BlackBoxFuncCall::BigIntFromLeBytes BlackBoxFuncCall::BigIntFromLeBytes::bincodeDeserialize(std::vector input) { auto deserializer = serde::BincodeDeserializer(input); - auto value = serde::Deserializable::deserialize(deserializer); + auto value = serde::Deserializable::deserialize(deserializer); if (deserializer.get_buffer_offset() < input.size()) { throw serde::deserialization_error("Some input bytes were not read"); } @@ -2661,37 +2767,39 @@ namespace Circuit { template <> template -void serde::Serializable::serialize(const Circuit::BlackBoxOp::Keccak256 &obj, Serializer &serializer) { - serde::Serializable::serialize(obj.message, serializer); +void serde::Serializable::serialize(const Circuit::BlackBoxFuncCall::BigIntFromLeBytes &obj, Serializer &serializer) { + serde::Serializable::serialize(obj.inputs, serializer); + serde::Serializable::serialize(obj.modulus, serializer); serde::Serializable::serialize(obj.output, serializer); } template <> template -Circuit::BlackBoxOp::Keccak256 serde::Deserializable::deserialize(Deserializer &deserializer) { - Circuit::BlackBoxOp::Keccak256 obj; - obj.message = serde::Deserializable::deserialize(deserializer); +Circuit::BlackBoxFuncCall::BigIntFromLeBytes serde::Deserializable::deserialize(Deserializer &deserializer) { + Circuit::BlackBoxFuncCall::BigIntFromLeBytes obj; + obj.inputs = serde::Deserializable::deserialize(deserializer); + obj.modulus = serde::Deserializable::deserialize(deserializer); obj.output = serde::Deserializable::deserialize(deserializer); return obj; } namespace Circuit { - inline bool operator==(const BlackBoxOp::Keccakf1600 &lhs, const BlackBoxOp::Keccakf1600 &rhs) { - if (!(lhs.message == rhs.message)) { return false; } - if (!(lhs.output == rhs.output)) { return false; } + inline bool operator==(const BlackBoxFuncCall::BigIntToLeBytes &lhs, const BlackBoxFuncCall::BigIntToLeBytes &rhs) { + if (!(lhs.input == rhs.input)) { return false; } + if (!(lhs.outputs == rhs.outputs)) { return false; } return true; } - inline std::vector BlackBoxOp::Keccakf1600::bincodeSerialize() const { + inline std::vector BlackBoxFuncCall::BigIntToLeBytes::bincodeSerialize() const { auto serializer = serde::BincodeSerializer(); - serde::Serializable::serialize(*this, serializer); + serde::Serializable::serialize(*this, serializer); return std::move(serializer).bytes(); } - inline BlackBoxOp::Keccakf1600 BlackBoxOp::Keccakf1600::bincodeDeserialize(std::vector input) { + inline BlackBoxFuncCall::BigIntToLeBytes BlackBoxFuncCall::BigIntToLeBytes::bincodeDeserialize(std::vector input) { auto deserializer = serde::BincodeDeserializer(input); - auto value = serde::Deserializable::deserialize(deserializer); + auto value = serde::Deserializable::deserialize(deserializer); if (deserializer.get_buffer_offset() < input.size()) { throw serde::deserialization_error("Some input bytes were not read"); } @@ -2702,40 +2810,38 @@ namespace Circuit { template <> template -void serde::Serializable::serialize(const Circuit::BlackBoxOp::Keccakf1600 &obj, Serializer &serializer) { - serde::Serializable::serialize(obj.message, serializer); - serde::Serializable::serialize(obj.output, serializer); +void serde::Serializable::serialize(const Circuit::BlackBoxFuncCall::BigIntToLeBytes &obj, Serializer &serializer) { + serde::Serializable::serialize(obj.input, serializer); + serde::Serializable::serialize(obj.outputs, serializer); } template <> template -Circuit::BlackBoxOp::Keccakf1600 serde::Deserializable::deserialize(Deserializer &deserializer) { - Circuit::BlackBoxOp::Keccakf1600 obj; - obj.message = serde::Deserializable::deserialize(deserializer); - obj.output = serde::Deserializable::deserialize(deserializer); +Circuit::BlackBoxFuncCall::BigIntToLeBytes serde::Deserializable::deserialize(Deserializer &deserializer) { + Circuit::BlackBoxFuncCall::BigIntToLeBytes obj; + obj.input = serde::Deserializable::deserialize(deserializer); + obj.outputs = serde::Deserializable::deserialize(deserializer); return obj; } namespace Circuit { - inline bool operator==(const BlackBoxOp::EcdsaSecp256k1 &lhs, const BlackBoxOp::EcdsaSecp256k1 &rhs) { - if (!(lhs.hashed_msg == rhs.hashed_msg)) { return false; } - if (!(lhs.public_key_x == rhs.public_key_x)) { return false; } - if (!(lhs.public_key_y == rhs.public_key_y)) { return false; } - if (!(lhs.signature == rhs.signature)) { return false; } - if (!(lhs.result == rhs.result)) { return false; } + inline bool operator==(const BlackBoxFuncCall::Poseidon2Permutation &lhs, const BlackBoxFuncCall::Poseidon2Permutation &rhs) { + if (!(lhs.inputs == rhs.inputs)) { return false; } + if (!(lhs.outputs == rhs.outputs)) { return false; } + if (!(lhs.len == rhs.len)) { return false; } return true; } - inline std::vector BlackBoxOp::EcdsaSecp256k1::bincodeSerialize() const { + inline std::vector BlackBoxFuncCall::Poseidon2Permutation::bincodeSerialize() const { auto serializer = serde::BincodeSerializer(); - serde::Serializable::serialize(*this, serializer); + serde::Serializable::serialize(*this, serializer); return std::move(serializer).bytes(); } - inline BlackBoxOp::EcdsaSecp256k1 BlackBoxOp::EcdsaSecp256k1::bincodeDeserialize(std::vector input) { + inline BlackBoxFuncCall::Poseidon2Permutation BlackBoxFuncCall::Poseidon2Permutation::bincodeDeserialize(std::vector input) { auto deserializer = serde::BincodeDeserializer(input); - auto value = serde::Deserializable::deserialize(deserializer); + auto value = serde::Deserializable::deserialize(deserializer); if (deserializer.get_buffer_offset() < input.size()) { throw serde::deserialization_error("Some input bytes were not read"); } @@ -2746,46 +2852,615 @@ namespace Circuit { template <> template -void serde::Serializable::serialize(const Circuit::BlackBoxOp::EcdsaSecp256k1 &obj, Serializer &serializer) { - serde::Serializable::serialize(obj.hashed_msg, serializer); - serde::Serializable::serialize(obj.public_key_x, serializer); - serde::Serializable::serialize(obj.public_key_y, serializer); - serde::Serializable::serialize(obj.signature, serializer); - serde::Serializable::serialize(obj.result, serializer); +void serde::Serializable::serialize(const Circuit::BlackBoxFuncCall::Poseidon2Permutation &obj, Serializer &serializer) { + serde::Serializable::serialize(obj.inputs, serializer); + serde::Serializable::serialize(obj.outputs, serializer); + serde::Serializable::serialize(obj.len, serializer); } template <> template -Circuit::BlackBoxOp::EcdsaSecp256k1 serde::Deserializable::deserialize(Deserializer &deserializer) { - Circuit::BlackBoxOp::EcdsaSecp256k1 obj; - obj.hashed_msg = serde::Deserializable::deserialize(deserializer); - obj.public_key_x = serde::Deserializable::deserialize(deserializer); - obj.public_key_y = serde::Deserializable::deserialize(deserializer); - obj.signature = serde::Deserializable::deserialize(deserializer); +Circuit::BlackBoxFuncCall::Poseidon2Permutation serde::Deserializable::deserialize(Deserializer &deserializer) { + Circuit::BlackBoxFuncCall::Poseidon2Permutation obj; + obj.inputs = serde::Deserializable::deserialize(deserializer); + obj.outputs = serde::Deserializable::deserialize(deserializer); + obj.len = serde::Deserializable::deserialize(deserializer); + return obj; +} + +namespace Circuit { + + inline bool operator==(const BlackBoxFuncCall::Sha256Compression &lhs, const BlackBoxFuncCall::Sha256Compression &rhs) { + if (!(lhs.inputs == rhs.inputs)) { return false; } + if (!(lhs.hash_values == rhs.hash_values)) { return false; } + if (!(lhs.outputs == rhs.outputs)) { return false; } + return true; + } + + inline std::vector BlackBoxFuncCall::Sha256Compression::bincodeSerialize() const { + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); + } + + inline BlackBoxFuncCall::Sha256Compression BlackBoxFuncCall::Sha256Compression::bincodeDeserialize(std::vector input) { + auto deserializer = serde::BincodeDeserializer(input); + auto value = serde::Deserializable::deserialize(deserializer); + if (deserializer.get_buffer_offset() < input.size()) { + throw serde::deserialization_error("Some input bytes were not read"); + } + return value; + } + +} // end of namespace Circuit + +template <> +template +void serde::Serializable::serialize(const Circuit::BlackBoxFuncCall::Sha256Compression &obj, Serializer &serializer) { + serde::Serializable::serialize(obj.inputs, serializer); + serde::Serializable::serialize(obj.hash_values, serializer); + serde::Serializable::serialize(obj.outputs, serializer); +} + +template <> +template +Circuit::BlackBoxFuncCall::Sha256Compression serde::Deserializable::deserialize(Deserializer &deserializer) { + Circuit::BlackBoxFuncCall::Sha256Compression obj; + obj.inputs = serde::Deserializable::deserialize(deserializer); + obj.hash_values = serde::Deserializable::deserialize(deserializer); + obj.outputs = serde::Deserializable::deserialize(deserializer); + return obj; +} + +namespace Circuit { + + inline bool operator==(const BlackBoxOp &lhs, const BlackBoxOp &rhs) { + if (!(lhs.value == rhs.value)) { return false; } + return true; + } + + inline std::vector BlackBoxOp::bincodeSerialize() const { + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); + } + + inline BlackBoxOp BlackBoxOp::bincodeDeserialize(std::vector input) { + auto deserializer = serde::BincodeDeserializer(input); + auto value = serde::Deserializable::deserialize(deserializer); + if (deserializer.get_buffer_offset() < input.size()) { + throw serde::deserialization_error("Some input bytes were not read"); + } + return value; + } + +} // end of namespace Circuit + +template <> +template +void serde::Serializable::serialize(const Circuit::BlackBoxOp &obj, Serializer &serializer) { + serializer.increase_container_depth(); + serde::Serializable::serialize(obj.value, serializer); + serializer.decrease_container_depth(); +} + +template <> +template +Circuit::BlackBoxOp serde::Deserializable::deserialize(Deserializer &deserializer) { + deserializer.increase_container_depth(); + Circuit::BlackBoxOp obj; + obj.value = serde::Deserializable::deserialize(deserializer); + deserializer.decrease_container_depth(); + return obj; +} + +namespace Circuit { + + inline bool operator==(const BlackBoxOp::Sha256 &lhs, const BlackBoxOp::Sha256 &rhs) { + if (!(lhs.message == rhs.message)) { return false; } + if (!(lhs.output == rhs.output)) { return false; } + return true; + } + + inline std::vector BlackBoxOp::Sha256::bincodeSerialize() const { + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); + } + + inline BlackBoxOp::Sha256 BlackBoxOp::Sha256::bincodeDeserialize(std::vector input) { + auto deserializer = serde::BincodeDeserializer(input); + auto value = serde::Deserializable::deserialize(deserializer); + if (deserializer.get_buffer_offset() < input.size()) { + throw serde::deserialization_error("Some input bytes were not read"); + } + return value; + } + +} // end of namespace Circuit + +template <> +template +void serde::Serializable::serialize(const Circuit::BlackBoxOp::Sha256 &obj, Serializer &serializer) { + serde::Serializable::serialize(obj.message, serializer); + serde::Serializable::serialize(obj.output, serializer); +} + +template <> +template +Circuit::BlackBoxOp::Sha256 serde::Deserializable::deserialize(Deserializer &deserializer) { + Circuit::BlackBoxOp::Sha256 obj; + obj.message = serde::Deserializable::deserialize(deserializer); + obj.output = serde::Deserializable::deserialize(deserializer); + return obj; +} + +namespace Circuit { + + inline bool operator==(const BlackBoxOp::Blake2s &lhs, const BlackBoxOp::Blake2s &rhs) { + if (!(lhs.message == rhs.message)) { return false; } + if (!(lhs.output == rhs.output)) { return false; } + return true; + } + + inline std::vector BlackBoxOp::Blake2s::bincodeSerialize() const { + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); + } + + inline BlackBoxOp::Blake2s BlackBoxOp::Blake2s::bincodeDeserialize(std::vector input) { + auto deserializer = serde::BincodeDeserializer(input); + auto value = serde::Deserializable::deserialize(deserializer); + if (deserializer.get_buffer_offset() < input.size()) { + throw serde::deserialization_error("Some input bytes were not read"); + } + return value; + } + +} // end of namespace Circuit + +template <> +template +void serde::Serializable::serialize(const Circuit::BlackBoxOp::Blake2s &obj, Serializer &serializer) { + serde::Serializable::serialize(obj.message, serializer); + serde::Serializable::serialize(obj.output, serializer); +} + +template <> +template +Circuit::BlackBoxOp::Blake2s serde::Deserializable::deserialize(Deserializer &deserializer) { + Circuit::BlackBoxOp::Blake2s obj; + obj.message = serde::Deserializable::deserialize(deserializer); + obj.output = serde::Deserializable::deserialize(deserializer); + return obj; +} + +namespace Circuit { + + inline bool operator==(const BlackBoxOp::Blake3 &lhs, const BlackBoxOp::Blake3 &rhs) { + if (!(lhs.message == rhs.message)) { return false; } + if (!(lhs.output == rhs.output)) { return false; } + return true; + } + + inline std::vector BlackBoxOp::Blake3::bincodeSerialize() const { + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); + } + + inline BlackBoxOp::Blake3 BlackBoxOp::Blake3::bincodeDeserialize(std::vector input) { + auto deserializer = serde::BincodeDeserializer(input); + auto value = serde::Deserializable::deserialize(deserializer); + if (deserializer.get_buffer_offset() < input.size()) { + throw serde::deserialization_error("Some input bytes were not read"); + } + return value; + } + +} // end of namespace Circuit + +template <> +template +void serde::Serializable::serialize(const Circuit::BlackBoxOp::Blake3 &obj, Serializer &serializer) { + serde::Serializable::serialize(obj.message, serializer); + serde::Serializable::serialize(obj.output, serializer); +} + +template <> +template +Circuit::BlackBoxOp::Blake3 serde::Deserializable::deserialize(Deserializer &deserializer) { + Circuit::BlackBoxOp::Blake3 obj; + obj.message = serde::Deserializable::deserialize(deserializer); + obj.output = serde::Deserializable::deserialize(deserializer); + return obj; +} + +namespace Circuit { + + inline bool operator==(const BlackBoxOp::Keccak256 &lhs, const BlackBoxOp::Keccak256 &rhs) { + if (!(lhs.message == rhs.message)) { return false; } + if (!(lhs.output == rhs.output)) { return false; } + return true; + } + + inline std::vector BlackBoxOp::Keccak256::bincodeSerialize() const { + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); + } + + inline BlackBoxOp::Keccak256 BlackBoxOp::Keccak256::bincodeDeserialize(std::vector input) { + auto deserializer = serde::BincodeDeserializer(input); + auto value = serde::Deserializable::deserialize(deserializer); + if (deserializer.get_buffer_offset() < input.size()) { + throw serde::deserialization_error("Some input bytes were not read"); + } + return value; + } + +} // end of namespace Circuit + +template <> +template +void serde::Serializable::serialize(const Circuit::BlackBoxOp::Keccak256 &obj, Serializer &serializer) { + serde::Serializable::serialize(obj.message, serializer); + serde::Serializable::serialize(obj.output, serializer); +} + +template <> +template +Circuit::BlackBoxOp::Keccak256 serde::Deserializable::deserialize(Deserializer &deserializer) { + Circuit::BlackBoxOp::Keccak256 obj; + obj.message = serde::Deserializable::deserialize(deserializer); + obj.output = serde::Deserializable::deserialize(deserializer); + return obj; +} + +namespace Circuit { + + inline bool operator==(const BlackBoxOp::Keccakf1600 &lhs, const BlackBoxOp::Keccakf1600 &rhs) { + if (!(lhs.message == rhs.message)) { return false; } + if (!(lhs.output == rhs.output)) { return false; } + return true; + } + + inline std::vector BlackBoxOp::Keccakf1600::bincodeSerialize() const { + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); + } + + inline BlackBoxOp::Keccakf1600 BlackBoxOp::Keccakf1600::bincodeDeserialize(std::vector input) { + auto deserializer = serde::BincodeDeserializer(input); + auto value = serde::Deserializable::deserialize(deserializer); + if (deserializer.get_buffer_offset() < input.size()) { + throw serde::deserialization_error("Some input bytes were not read"); + } + return value; + } + +} // end of namespace Circuit + +template <> +template +void serde::Serializable::serialize(const Circuit::BlackBoxOp::Keccakf1600 &obj, Serializer &serializer) { + serde::Serializable::serialize(obj.message, serializer); + serde::Serializable::serialize(obj.output, serializer); +} + +template <> +template +Circuit::BlackBoxOp::Keccakf1600 serde::Deserializable::deserialize(Deserializer &deserializer) { + Circuit::BlackBoxOp::Keccakf1600 obj; + obj.message = serde::Deserializable::deserialize(deserializer); + obj.output = serde::Deserializable::deserialize(deserializer); + return obj; +} + +namespace Circuit { + + inline bool operator==(const BlackBoxOp::EcdsaSecp256k1 &lhs, const BlackBoxOp::EcdsaSecp256k1 &rhs) { + if (!(lhs.hashed_msg == rhs.hashed_msg)) { return false; } + if (!(lhs.public_key_x == rhs.public_key_x)) { return false; } + if (!(lhs.public_key_y == rhs.public_key_y)) { return false; } + if (!(lhs.signature == rhs.signature)) { return false; } + if (!(lhs.result == rhs.result)) { return false; } + return true; + } + + inline std::vector BlackBoxOp::EcdsaSecp256k1::bincodeSerialize() const { + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); + } + + inline BlackBoxOp::EcdsaSecp256k1 BlackBoxOp::EcdsaSecp256k1::bincodeDeserialize(std::vector input) { + auto deserializer = serde::BincodeDeserializer(input); + auto value = serde::Deserializable::deserialize(deserializer); + if (deserializer.get_buffer_offset() < input.size()) { + throw serde::deserialization_error("Some input bytes were not read"); + } + return value; + } + +} // end of namespace Circuit + +template <> +template +void serde::Serializable::serialize(const Circuit::BlackBoxOp::EcdsaSecp256k1 &obj, Serializer &serializer) { + serde::Serializable::serialize(obj.hashed_msg, serializer); + serde::Serializable::serialize(obj.public_key_x, serializer); + serde::Serializable::serialize(obj.public_key_y, serializer); + serde::Serializable::serialize(obj.signature, serializer); + serde::Serializable::serialize(obj.result, serializer); +} + +template <> +template +Circuit::BlackBoxOp::EcdsaSecp256k1 serde::Deserializable::deserialize(Deserializer &deserializer) { + Circuit::BlackBoxOp::EcdsaSecp256k1 obj; + obj.hashed_msg = serde::Deserializable::deserialize(deserializer); + obj.public_key_x = serde::Deserializable::deserialize(deserializer); + obj.public_key_y = serde::Deserializable::deserialize(deserializer); + obj.signature = serde::Deserializable::deserialize(deserializer); + obj.result = serde::Deserializable::deserialize(deserializer); + return obj; +} + +namespace Circuit { + + inline bool operator==(const BlackBoxOp::EcdsaSecp256r1 &lhs, const BlackBoxOp::EcdsaSecp256r1 &rhs) { + if (!(lhs.hashed_msg == rhs.hashed_msg)) { return false; } + if (!(lhs.public_key_x == rhs.public_key_x)) { return false; } + if (!(lhs.public_key_y == rhs.public_key_y)) { return false; } + if (!(lhs.signature == rhs.signature)) { return false; } + if (!(lhs.result == rhs.result)) { return false; } + return true; + } + + inline std::vector BlackBoxOp::EcdsaSecp256r1::bincodeSerialize() const { + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); + } + + inline BlackBoxOp::EcdsaSecp256r1 BlackBoxOp::EcdsaSecp256r1::bincodeDeserialize(std::vector input) { + auto deserializer = serde::BincodeDeserializer(input); + auto value = serde::Deserializable::deserialize(deserializer); + if (deserializer.get_buffer_offset() < input.size()) { + throw serde::deserialization_error("Some input bytes were not read"); + } + return value; + } + +} // end of namespace Circuit + +template <> +template +void serde::Serializable::serialize(const Circuit::BlackBoxOp::EcdsaSecp256r1 &obj, Serializer &serializer) { + serde::Serializable::serialize(obj.hashed_msg, serializer); + serde::Serializable::serialize(obj.public_key_x, serializer); + serde::Serializable::serialize(obj.public_key_y, serializer); + serde::Serializable::serialize(obj.signature, serializer); + serde::Serializable::serialize(obj.result, serializer); +} + +template <> +template +Circuit::BlackBoxOp::EcdsaSecp256r1 serde::Deserializable::deserialize(Deserializer &deserializer) { + Circuit::BlackBoxOp::EcdsaSecp256r1 obj; + obj.hashed_msg = serde::Deserializable::deserialize(deserializer); + obj.public_key_x = serde::Deserializable::deserialize(deserializer); + obj.public_key_y = serde::Deserializable::deserialize(deserializer); + obj.signature = serde::Deserializable::deserialize(deserializer); + obj.result = serde::Deserializable::deserialize(deserializer); + return obj; +} + +namespace Circuit { + + inline bool operator==(const BlackBoxOp::SchnorrVerify &lhs, const BlackBoxOp::SchnorrVerify &rhs) { + if (!(lhs.public_key_x == rhs.public_key_x)) { return false; } + if (!(lhs.public_key_y == rhs.public_key_y)) { return false; } + if (!(lhs.message == rhs.message)) { return false; } + if (!(lhs.signature == rhs.signature)) { return false; } + if (!(lhs.result == rhs.result)) { return false; } + return true; + } + + inline std::vector BlackBoxOp::SchnorrVerify::bincodeSerialize() const { + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); + } + + inline BlackBoxOp::SchnorrVerify BlackBoxOp::SchnorrVerify::bincodeDeserialize(std::vector input) { + auto deserializer = serde::BincodeDeserializer(input); + auto value = serde::Deserializable::deserialize(deserializer); + if (deserializer.get_buffer_offset() < input.size()) { + throw serde::deserialization_error("Some input bytes were not read"); + } + return value; + } + +} // end of namespace Circuit + +template <> +template +void serde::Serializable::serialize(const Circuit::BlackBoxOp::SchnorrVerify &obj, Serializer &serializer) { + serde::Serializable::serialize(obj.public_key_x, serializer); + serde::Serializable::serialize(obj.public_key_y, serializer); + serde::Serializable::serialize(obj.message, serializer); + serde::Serializable::serialize(obj.signature, serializer); + serde::Serializable::serialize(obj.result, serializer); +} + +template <> +template +Circuit::BlackBoxOp::SchnorrVerify serde::Deserializable::deserialize(Deserializer &deserializer) { + Circuit::BlackBoxOp::SchnorrVerify obj; + obj.public_key_x = serde::Deserializable::deserialize(deserializer); + obj.public_key_y = serde::Deserializable::deserialize(deserializer); + obj.message = serde::Deserializable::deserialize(deserializer); + obj.signature = serde::Deserializable::deserialize(deserializer); + obj.result = serde::Deserializable::deserialize(deserializer); + return obj; +} + +namespace Circuit { + + inline bool operator==(const BlackBoxOp::PedersenCommitment &lhs, const BlackBoxOp::PedersenCommitment &rhs) { + if (!(lhs.inputs == rhs.inputs)) { return false; } + if (!(lhs.domain_separator == rhs.domain_separator)) { return false; } + if (!(lhs.output == rhs.output)) { return false; } + return true; + } + + inline std::vector BlackBoxOp::PedersenCommitment::bincodeSerialize() const { + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); + } + + inline BlackBoxOp::PedersenCommitment BlackBoxOp::PedersenCommitment::bincodeDeserialize(std::vector input) { + auto deserializer = serde::BincodeDeserializer(input); + auto value = serde::Deserializable::deserialize(deserializer); + if (deserializer.get_buffer_offset() < input.size()) { + throw serde::deserialization_error("Some input bytes were not read"); + } + return value; + } + +} // end of namespace Circuit + +template <> +template +void serde::Serializable::serialize(const Circuit::BlackBoxOp::PedersenCommitment &obj, Serializer &serializer) { + serde::Serializable::serialize(obj.inputs, serializer); + serde::Serializable::serialize(obj.domain_separator, serializer); + serde::Serializable::serialize(obj.output, serializer); +} + +template <> +template +Circuit::BlackBoxOp::PedersenCommitment serde::Deserializable::deserialize(Deserializer &deserializer) { + Circuit::BlackBoxOp::PedersenCommitment obj; + obj.inputs = serde::Deserializable::deserialize(deserializer); + obj.domain_separator = serde::Deserializable::deserialize(deserializer); + obj.output = serde::Deserializable::deserialize(deserializer); + return obj; +} + +namespace Circuit { + + inline bool operator==(const BlackBoxOp::PedersenHash &lhs, const BlackBoxOp::PedersenHash &rhs) { + if (!(lhs.inputs == rhs.inputs)) { return false; } + if (!(lhs.domain_separator == rhs.domain_separator)) { return false; } + if (!(lhs.output == rhs.output)) { return false; } + return true; + } + + inline std::vector BlackBoxOp::PedersenHash::bincodeSerialize() const { + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); + } + + inline BlackBoxOp::PedersenHash BlackBoxOp::PedersenHash::bincodeDeserialize(std::vector input) { + auto deserializer = serde::BincodeDeserializer(input); + auto value = serde::Deserializable::deserialize(deserializer); + if (deserializer.get_buffer_offset() < input.size()) { + throw serde::deserialization_error("Some input bytes were not read"); + } + return value; + } + +} // end of namespace Circuit + +template <> +template +void serde::Serializable::serialize(const Circuit::BlackBoxOp::PedersenHash &obj, Serializer &serializer) { + serde::Serializable::serialize(obj.inputs, serializer); + serde::Serializable::serialize(obj.domain_separator, serializer); + serde::Serializable::serialize(obj.output, serializer); +} + +template <> +template +Circuit::BlackBoxOp::PedersenHash serde::Deserializable::deserialize(Deserializer &deserializer) { + Circuit::BlackBoxOp::PedersenHash obj; + obj.inputs = serde::Deserializable::deserialize(deserializer); + obj.domain_separator = serde::Deserializable::deserialize(deserializer); + obj.output = serde::Deserializable::deserialize(deserializer); + return obj; +} + +namespace Circuit { + + inline bool operator==(const BlackBoxOp::FixedBaseScalarMul &lhs, const BlackBoxOp::FixedBaseScalarMul &rhs) { + if (!(lhs.low == rhs.low)) { return false; } + if (!(lhs.high == rhs.high)) { return false; } + if (!(lhs.result == rhs.result)) { return false; } + return true; + } + + inline std::vector BlackBoxOp::FixedBaseScalarMul::bincodeSerialize() const { + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); + } + + inline BlackBoxOp::FixedBaseScalarMul BlackBoxOp::FixedBaseScalarMul::bincodeDeserialize(std::vector input) { + auto deserializer = serde::BincodeDeserializer(input); + auto value = serde::Deserializable::deserialize(deserializer); + if (deserializer.get_buffer_offset() < input.size()) { + throw serde::deserialization_error("Some input bytes were not read"); + } + return value; + } + +} // end of namespace Circuit + +template <> +template +void serde::Serializable::serialize(const Circuit::BlackBoxOp::FixedBaseScalarMul &obj, Serializer &serializer) { + serde::Serializable::serialize(obj.low, serializer); + serde::Serializable::serialize(obj.high, serializer); + serde::Serializable::serialize(obj.result, serializer); +} + +template <> +template +Circuit::BlackBoxOp::FixedBaseScalarMul serde::Deserializable::deserialize(Deserializer &deserializer) { + Circuit::BlackBoxOp::FixedBaseScalarMul obj; + obj.low = serde::Deserializable::deserialize(deserializer); + obj.high = serde::Deserializable::deserialize(deserializer); obj.result = serde::Deserializable::deserialize(deserializer); return obj; } namespace Circuit { - inline bool operator==(const BlackBoxOp::EcdsaSecp256r1 &lhs, const BlackBoxOp::EcdsaSecp256r1 &rhs) { - if (!(lhs.hashed_msg == rhs.hashed_msg)) { return false; } - if (!(lhs.public_key_x == rhs.public_key_x)) { return false; } - if (!(lhs.public_key_y == rhs.public_key_y)) { return false; } - if (!(lhs.signature == rhs.signature)) { return false; } + inline bool operator==(const BlackBoxOp::EmbeddedCurveAdd &lhs, const BlackBoxOp::EmbeddedCurveAdd &rhs) { + if (!(lhs.input1_x == rhs.input1_x)) { return false; } + if (!(lhs.input1_y == rhs.input1_y)) { return false; } + if (!(lhs.input2_x == rhs.input2_x)) { return false; } + if (!(lhs.input2_y == rhs.input2_y)) { return false; } if (!(lhs.result == rhs.result)) { return false; } return true; } - inline std::vector BlackBoxOp::EcdsaSecp256r1::bincodeSerialize() const { + inline std::vector BlackBoxOp::EmbeddedCurveAdd::bincodeSerialize() const { auto serializer = serde::BincodeSerializer(); - serde::Serializable::serialize(*this, serializer); + serde::Serializable::serialize(*this, serializer); return std::move(serializer).bytes(); } - inline BlackBoxOp::EcdsaSecp256r1 BlackBoxOp::EcdsaSecp256r1::bincodeDeserialize(std::vector input) { + inline BlackBoxOp::EmbeddedCurveAdd BlackBoxOp::EmbeddedCurveAdd::bincodeDeserialize(std::vector input) { auto deserializer = serde::BincodeDeserializer(input); - auto value = serde::Deserializable::deserialize(deserializer); + auto value = serde::Deserializable::deserialize(deserializer); if (deserializer.get_buffer_offset() < input.size()) { throw serde::deserialization_error("Some input bytes were not read"); } @@ -2796,46 +3471,44 @@ namespace Circuit { template <> template -void serde::Serializable::serialize(const Circuit::BlackBoxOp::EcdsaSecp256r1 &obj, Serializer &serializer) { - serde::Serializable::serialize(obj.hashed_msg, serializer); - serde::Serializable::serialize(obj.public_key_x, serializer); - serde::Serializable::serialize(obj.public_key_y, serializer); - serde::Serializable::serialize(obj.signature, serializer); +void serde::Serializable::serialize(const Circuit::BlackBoxOp::EmbeddedCurveAdd &obj, Serializer &serializer) { + serde::Serializable::serialize(obj.input1_x, serializer); + serde::Serializable::serialize(obj.input1_y, serializer); + serde::Serializable::serialize(obj.input2_x, serializer); + serde::Serializable::serialize(obj.input2_y, serializer); serde::Serializable::serialize(obj.result, serializer); } template <> template -Circuit::BlackBoxOp::EcdsaSecp256r1 serde::Deserializable::deserialize(Deserializer &deserializer) { - Circuit::BlackBoxOp::EcdsaSecp256r1 obj; - obj.hashed_msg = serde::Deserializable::deserialize(deserializer); - obj.public_key_x = serde::Deserializable::deserialize(deserializer); - obj.public_key_y = serde::Deserializable::deserialize(deserializer); - obj.signature = serde::Deserializable::deserialize(deserializer); +Circuit::BlackBoxOp::EmbeddedCurveAdd serde::Deserializable::deserialize(Deserializer &deserializer) { + Circuit::BlackBoxOp::EmbeddedCurveAdd obj; + obj.input1_x = serde::Deserializable::deserialize(deserializer); + obj.input1_y = serde::Deserializable::deserialize(deserializer); + obj.input2_x = serde::Deserializable::deserialize(deserializer); + obj.input2_y = serde::Deserializable::deserialize(deserializer); obj.result = serde::Deserializable::deserialize(deserializer); return obj; } namespace Circuit { - inline bool operator==(const BlackBoxOp::SchnorrVerify &lhs, const BlackBoxOp::SchnorrVerify &rhs) { - if (!(lhs.public_key_x == rhs.public_key_x)) { return false; } - if (!(lhs.public_key_y == rhs.public_key_y)) { return false; } - if (!(lhs.message == rhs.message)) { return false; } - if (!(lhs.signature == rhs.signature)) { return false; } - if (!(lhs.result == rhs.result)) { return false; } + inline bool operator==(const BlackBoxOp::BigIntAdd &lhs, const BlackBoxOp::BigIntAdd &rhs) { + if (!(lhs.lhs == rhs.lhs)) { return false; } + if (!(lhs.rhs == rhs.rhs)) { return false; } + if (!(lhs.output == rhs.output)) { return false; } return true; } - inline std::vector BlackBoxOp::SchnorrVerify::bincodeSerialize() const { + inline std::vector BlackBoxOp::BigIntAdd::bincodeSerialize() const { auto serializer = serde::BincodeSerializer(); - serde::Serializable::serialize(*this, serializer); + serde::Serializable::serialize(*this, serializer); return std::move(serializer).bytes(); } - inline BlackBoxOp::SchnorrVerify BlackBoxOp::SchnorrVerify::bincodeDeserialize(std::vector input) { + inline BlackBoxOp::BigIntAdd BlackBoxOp::BigIntAdd::bincodeDeserialize(std::vector input) { auto deserializer = serde::BincodeDeserializer(input); - auto value = serde::Deserializable::deserialize(deserializer); + auto value = serde::Deserializable::deserialize(deserializer); if (deserializer.get_buffer_offset() < input.size()) { throw serde::deserialization_error("Some input bytes were not read"); } @@ -2846,44 +3519,40 @@ namespace Circuit { template <> template -void serde::Serializable::serialize(const Circuit::BlackBoxOp::SchnorrVerify &obj, Serializer &serializer) { - serde::Serializable::serialize(obj.public_key_x, serializer); - serde::Serializable::serialize(obj.public_key_y, serializer); - serde::Serializable::serialize(obj.message, serializer); - serde::Serializable::serialize(obj.signature, serializer); - serde::Serializable::serialize(obj.result, serializer); +void serde::Serializable::serialize(const Circuit::BlackBoxOp::BigIntAdd &obj, Serializer &serializer) { + serde::Serializable::serialize(obj.lhs, serializer); + serde::Serializable::serialize(obj.rhs, serializer); + serde::Serializable::serialize(obj.output, serializer); } template <> template -Circuit::BlackBoxOp::SchnorrVerify serde::Deserializable::deserialize(Deserializer &deserializer) { - Circuit::BlackBoxOp::SchnorrVerify obj; - obj.public_key_x = serde::Deserializable::deserialize(deserializer); - obj.public_key_y = serde::Deserializable::deserialize(deserializer); - obj.message = serde::Deserializable::deserialize(deserializer); - obj.signature = serde::Deserializable::deserialize(deserializer); - obj.result = serde::Deserializable::deserialize(deserializer); +Circuit::BlackBoxOp::BigIntAdd serde::Deserializable::deserialize(Deserializer &deserializer) { + Circuit::BlackBoxOp::BigIntAdd obj; + obj.lhs = serde::Deserializable::deserialize(deserializer); + obj.rhs = serde::Deserializable::deserialize(deserializer); + obj.output = serde::Deserializable::deserialize(deserializer); return obj; } namespace Circuit { - inline bool operator==(const BlackBoxOp::PedersenCommitment &lhs, const BlackBoxOp::PedersenCommitment &rhs) { - if (!(lhs.inputs == rhs.inputs)) { return false; } - if (!(lhs.domain_separator == rhs.domain_separator)) { return false; } + inline bool operator==(const BlackBoxOp::BigIntNeg &lhs, const BlackBoxOp::BigIntNeg &rhs) { + if (!(lhs.lhs == rhs.lhs)) { return false; } + if (!(lhs.rhs == rhs.rhs)) { return false; } if (!(lhs.output == rhs.output)) { return false; } return true; } - inline std::vector BlackBoxOp::PedersenCommitment::bincodeSerialize() const { + inline std::vector BlackBoxOp::BigIntNeg::bincodeSerialize() const { auto serializer = serde::BincodeSerializer(); - serde::Serializable::serialize(*this, serializer); + serde::Serializable::serialize(*this, serializer); return std::move(serializer).bytes(); } - inline BlackBoxOp::PedersenCommitment BlackBoxOp::PedersenCommitment::bincodeDeserialize(std::vector input) { + inline BlackBoxOp::BigIntNeg BlackBoxOp::BigIntNeg::bincodeDeserialize(std::vector input) { auto deserializer = serde::BincodeDeserializer(input); - auto value = serde::Deserializable::deserialize(deserializer); + auto value = serde::Deserializable::deserialize(deserializer); if (deserializer.get_buffer_offset() < input.size()) { throw serde::deserialization_error("Some input bytes were not read"); } @@ -2894,40 +3563,128 @@ namespace Circuit { template <> template -void serde::Serializable::serialize(const Circuit::BlackBoxOp::PedersenCommitment &obj, Serializer &serializer) { - serde::Serializable::serialize(obj.inputs, serializer); - serde::Serializable::serialize(obj.domain_separator, serializer); +void serde::Serializable::serialize(const Circuit::BlackBoxOp::BigIntNeg &obj, Serializer &serializer) { + serde::Serializable::serialize(obj.lhs, serializer); + serde::Serializable::serialize(obj.rhs, serializer); serde::Serializable::serialize(obj.output, serializer); } template <> template -Circuit::BlackBoxOp::PedersenCommitment serde::Deserializable::deserialize(Deserializer &deserializer) { - Circuit::BlackBoxOp::PedersenCommitment obj; - obj.inputs = serde::Deserializable::deserialize(deserializer); - obj.domain_separator = serde::Deserializable::deserialize(deserializer); +Circuit::BlackBoxOp::BigIntNeg serde::Deserializable::deserialize(Deserializer &deserializer) { + Circuit::BlackBoxOp::BigIntNeg obj; + obj.lhs = serde::Deserializable::deserialize(deserializer); + obj.rhs = serde::Deserializable::deserialize(deserializer); obj.output = serde::Deserializable::deserialize(deserializer); return obj; } namespace Circuit { - inline bool operator==(const BlackBoxOp::PedersenHash &lhs, const BlackBoxOp::PedersenHash &rhs) { + inline bool operator==(const BlackBoxOp::BigIntMul &lhs, const BlackBoxOp::BigIntMul &rhs) { + if (!(lhs.lhs == rhs.lhs)) { return false; } + if (!(lhs.rhs == rhs.rhs)) { return false; } + if (!(lhs.output == rhs.output)) { return false; } + return true; + } + + inline std::vector BlackBoxOp::BigIntMul::bincodeSerialize() const { + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); + } + + inline BlackBoxOp::BigIntMul BlackBoxOp::BigIntMul::bincodeDeserialize(std::vector input) { + auto deserializer = serde::BincodeDeserializer(input); + auto value = serde::Deserializable::deserialize(deserializer); + if (deserializer.get_buffer_offset() < input.size()) { + throw serde::deserialization_error("Some input bytes were not read"); + } + return value; + } + +} // end of namespace Circuit + +template <> +template +void serde::Serializable::serialize(const Circuit::BlackBoxOp::BigIntMul &obj, Serializer &serializer) { + serde::Serializable::serialize(obj.lhs, serializer); + serde::Serializable::serialize(obj.rhs, serializer); + serde::Serializable::serialize(obj.output, serializer); +} + +template <> +template +Circuit::BlackBoxOp::BigIntMul serde::Deserializable::deserialize(Deserializer &deserializer) { + Circuit::BlackBoxOp::BigIntMul obj; + obj.lhs = serde::Deserializable::deserialize(deserializer); + obj.rhs = serde::Deserializable::deserialize(deserializer); + obj.output = serde::Deserializable::deserialize(deserializer); + return obj; +} + +namespace Circuit { + + inline bool operator==(const BlackBoxOp::BigIntDiv &lhs, const BlackBoxOp::BigIntDiv &rhs) { + if (!(lhs.lhs == rhs.lhs)) { return false; } + if (!(lhs.rhs == rhs.rhs)) { return false; } + if (!(lhs.output == rhs.output)) { return false; } + return true; + } + + inline std::vector BlackBoxOp::BigIntDiv::bincodeSerialize() const { + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); + } + + inline BlackBoxOp::BigIntDiv BlackBoxOp::BigIntDiv::bincodeDeserialize(std::vector input) { + auto deserializer = serde::BincodeDeserializer(input); + auto value = serde::Deserializable::deserialize(deserializer); + if (deserializer.get_buffer_offset() < input.size()) { + throw serde::deserialization_error("Some input bytes were not read"); + } + return value; + } + +} // end of namespace Circuit + +template <> +template +void serde::Serializable::serialize(const Circuit::BlackBoxOp::BigIntDiv &obj, Serializer &serializer) { + serde::Serializable::serialize(obj.lhs, serializer); + serde::Serializable::serialize(obj.rhs, serializer); + serde::Serializable::serialize(obj.output, serializer); +} + +template <> +template +Circuit::BlackBoxOp::BigIntDiv serde::Deserializable::deserialize(Deserializer &deserializer) { + Circuit::BlackBoxOp::BigIntDiv obj; + obj.lhs = serde::Deserializable::deserialize(deserializer); + obj.rhs = serde::Deserializable::deserialize(deserializer); + obj.output = serde::Deserializable::deserialize(deserializer); + return obj; +} + +namespace Circuit { + + inline bool operator==(const BlackBoxOp::BigIntFromLeBytes &lhs, const BlackBoxOp::BigIntFromLeBytes &rhs) { if (!(lhs.inputs == rhs.inputs)) { return false; } - if (!(lhs.domain_separator == rhs.domain_separator)) { return false; } + if (!(lhs.modulus == rhs.modulus)) { return false; } if (!(lhs.output == rhs.output)) { return false; } return true; } - inline std::vector BlackBoxOp::PedersenHash::bincodeSerialize() const { + inline std::vector BlackBoxOp::BigIntFromLeBytes::bincodeSerialize() const { auto serializer = serde::BincodeSerializer(); - serde::Serializable::serialize(*this, serializer); + serde::Serializable::serialize(*this, serializer); return std::move(serializer).bytes(); } - inline BlackBoxOp::PedersenHash BlackBoxOp::PedersenHash::bincodeDeserialize(std::vector input) { + inline BlackBoxOp::BigIntFromLeBytes BlackBoxOp::BigIntFromLeBytes::bincodeDeserialize(std::vector input) { auto deserializer = serde::BincodeDeserializer(input); - auto value = serde::Deserializable::deserialize(deserializer); + auto value = serde::Deserializable::deserialize(deserializer); if (deserializer.get_buffer_offset() < input.size()) { throw serde::deserialization_error("Some input bytes were not read"); } @@ -2938,40 +3695,39 @@ namespace Circuit { template <> template -void serde::Serializable::serialize(const Circuit::BlackBoxOp::PedersenHash &obj, Serializer &serializer) { +void serde::Serializable::serialize(const Circuit::BlackBoxOp::BigIntFromLeBytes &obj, Serializer &serializer) { serde::Serializable::serialize(obj.inputs, serializer); - serde::Serializable::serialize(obj.domain_separator, serializer); + serde::Serializable::serialize(obj.modulus, serializer); serde::Serializable::serialize(obj.output, serializer); } template <> template -Circuit::BlackBoxOp::PedersenHash serde::Deserializable::deserialize(Deserializer &deserializer) { - Circuit::BlackBoxOp::PedersenHash obj; +Circuit::BlackBoxOp::BigIntFromLeBytes serde::Deserializable::deserialize(Deserializer &deserializer) { + Circuit::BlackBoxOp::BigIntFromLeBytes obj; obj.inputs = serde::Deserializable::deserialize(deserializer); - obj.domain_separator = serde::Deserializable::deserialize(deserializer); + obj.modulus = serde::Deserializable::deserialize(deserializer); obj.output = serde::Deserializable::deserialize(deserializer); return obj; } namespace Circuit { - inline bool operator==(const BlackBoxOp::FixedBaseScalarMul &lhs, const BlackBoxOp::FixedBaseScalarMul &rhs) { - if (!(lhs.low == rhs.low)) { return false; } - if (!(lhs.high == rhs.high)) { return false; } - if (!(lhs.result == rhs.result)) { return false; } + inline bool operator==(const BlackBoxOp::BigIntToLeBytes &lhs, const BlackBoxOp::BigIntToLeBytes &rhs) { + if (!(lhs.input == rhs.input)) { return false; } + if (!(lhs.output == rhs.output)) { return false; } return true; } - inline std::vector BlackBoxOp::FixedBaseScalarMul::bincodeSerialize() const { + inline std::vector BlackBoxOp::BigIntToLeBytes::bincodeSerialize() const { auto serializer = serde::BincodeSerializer(); - serde::Serializable::serialize(*this, serializer); + serde::Serializable::serialize(*this, serializer); return std::move(serializer).bytes(); } - inline BlackBoxOp::FixedBaseScalarMul BlackBoxOp::FixedBaseScalarMul::bincodeDeserialize(std::vector input) { + inline BlackBoxOp::BigIntToLeBytes BlackBoxOp::BigIntToLeBytes::bincodeDeserialize(std::vector input) { auto deserializer = serde::BincodeDeserializer(input); - auto value = serde::Deserializable::deserialize(deserializer); + auto value = serde::Deserializable::deserialize(deserializer); if (deserializer.get_buffer_offset() < input.size()) { throw serde::deserialization_error("Some input bytes were not read"); } @@ -2982,42 +3738,38 @@ namespace Circuit { template <> template -void serde::Serializable::serialize(const Circuit::BlackBoxOp::FixedBaseScalarMul &obj, Serializer &serializer) { - serde::Serializable::serialize(obj.low, serializer); - serde::Serializable::serialize(obj.high, serializer); - serde::Serializable::serialize(obj.result, serializer); +void serde::Serializable::serialize(const Circuit::BlackBoxOp::BigIntToLeBytes &obj, Serializer &serializer) { + serde::Serializable::serialize(obj.input, serializer); + serde::Serializable::serialize(obj.output, serializer); } template <> template -Circuit::BlackBoxOp::FixedBaseScalarMul serde::Deserializable::deserialize(Deserializer &deserializer) { - Circuit::BlackBoxOp::FixedBaseScalarMul obj; - obj.low = serde::Deserializable::deserialize(deserializer); - obj.high = serde::Deserializable::deserialize(deserializer); - obj.result = serde::Deserializable::deserialize(deserializer); +Circuit::BlackBoxOp::BigIntToLeBytes serde::Deserializable::deserialize(Deserializer &deserializer) { + Circuit::BlackBoxOp::BigIntToLeBytes obj; + obj.input = serde::Deserializable::deserialize(deserializer); + obj.output = serde::Deserializable::deserialize(deserializer); return obj; } namespace Circuit { - inline bool operator==(const BlackBoxOp::EmbeddedCurveAdd &lhs, const BlackBoxOp::EmbeddedCurveAdd &rhs) { - if (!(lhs.input1_x == rhs.input1_x)) { return false; } - if (!(lhs.input1_y == rhs.input1_y)) { return false; } - if (!(lhs.input2_x == rhs.input2_x)) { return false; } - if (!(lhs.input2_y == rhs.input2_y)) { return false; } - if (!(lhs.result == rhs.result)) { return false; } + inline bool operator==(const BlackBoxOp::Poseidon2Permutation &lhs, const BlackBoxOp::Poseidon2Permutation &rhs) { + if (!(lhs.message == rhs.message)) { return false; } + if (!(lhs.output == rhs.output)) { return false; } + if (!(lhs.len == rhs.len)) { return false; } return true; } - inline std::vector BlackBoxOp::EmbeddedCurveAdd::bincodeSerialize() const { + inline std::vector BlackBoxOp::Poseidon2Permutation::bincodeSerialize() const { auto serializer = serde::BincodeSerializer(); - serde::Serializable::serialize(*this, serializer); + serde::Serializable::serialize(*this, serializer); return std::move(serializer).bytes(); } - inline BlackBoxOp::EmbeddedCurveAdd BlackBoxOp::EmbeddedCurveAdd::bincodeDeserialize(std::vector input) { + inline BlackBoxOp::Poseidon2Permutation BlackBoxOp::Poseidon2Permutation::bincodeDeserialize(std::vector input) { auto deserializer = serde::BincodeDeserializer(input); - auto value = serde::Deserializable::deserialize(deserializer); + auto value = serde::Deserializable::deserialize(deserializer); if (deserializer.get_buffer_offset() < input.size()) { throw serde::deserialization_error("Some input bytes were not read"); } @@ -3028,44 +3780,40 @@ namespace Circuit { template <> template -void serde::Serializable::serialize(const Circuit::BlackBoxOp::EmbeddedCurveAdd &obj, Serializer &serializer) { - serde::Serializable::serialize(obj.input1_x, serializer); - serde::Serializable::serialize(obj.input1_y, serializer); - serde::Serializable::serialize(obj.input2_x, serializer); - serde::Serializable::serialize(obj.input2_y, serializer); - serde::Serializable::serialize(obj.result, serializer); +void serde::Serializable::serialize(const Circuit::BlackBoxOp::Poseidon2Permutation &obj, Serializer &serializer) { + serde::Serializable::serialize(obj.message, serializer); + serde::Serializable::serialize(obj.output, serializer); + serde::Serializable::serialize(obj.len, serializer); } template <> template -Circuit::BlackBoxOp::EmbeddedCurveAdd serde::Deserializable::deserialize(Deserializer &deserializer) { - Circuit::BlackBoxOp::EmbeddedCurveAdd obj; - obj.input1_x = serde::Deserializable::deserialize(deserializer); - obj.input1_y = serde::Deserializable::deserialize(deserializer); - obj.input2_x = serde::Deserializable::deserialize(deserializer); - obj.input2_y = serde::Deserializable::deserialize(deserializer); - obj.result = serde::Deserializable::deserialize(deserializer); +Circuit::BlackBoxOp::Poseidon2Permutation serde::Deserializable::deserialize(Deserializer &deserializer) { + Circuit::BlackBoxOp::Poseidon2Permutation obj; + obj.message = serde::Deserializable::deserialize(deserializer); + obj.output = serde::Deserializable::deserialize(deserializer); + obj.len = serde::Deserializable::deserialize(deserializer); return obj; } namespace Circuit { - inline bool operator==(const BlackBoxOp::EmbeddedCurveDouble &lhs, const BlackBoxOp::EmbeddedCurveDouble &rhs) { - if (!(lhs.input1_x == rhs.input1_x)) { return false; } - if (!(lhs.input1_y == rhs.input1_y)) { return false; } - if (!(lhs.result == rhs.result)) { return false; } + inline bool operator==(const BlackBoxOp::Sha256Compression &lhs, const BlackBoxOp::Sha256Compression &rhs) { + if (!(lhs.input == rhs.input)) { return false; } + if (!(lhs.hash_values == rhs.hash_values)) { return false; } + if (!(lhs.output == rhs.output)) { return false; } return true; } - inline std::vector BlackBoxOp::EmbeddedCurveDouble::bincodeSerialize() const { + inline std::vector BlackBoxOp::Sha256Compression::bincodeSerialize() const { auto serializer = serde::BincodeSerializer(); - serde::Serializable::serialize(*this, serializer); + serde::Serializable::serialize(*this, serializer); return std::move(serializer).bytes(); } - inline BlackBoxOp::EmbeddedCurveDouble BlackBoxOp::EmbeddedCurveDouble::bincodeDeserialize(std::vector input) { + inline BlackBoxOp::Sha256Compression BlackBoxOp::Sha256Compression::bincodeDeserialize(std::vector input) { auto deserializer = serde::BincodeDeserializer(input); - auto value = serde::Deserializable::deserialize(deserializer); + auto value = serde::Deserializable::deserialize(deserializer); if (deserializer.get_buffer_offset() < input.size()) { throw serde::deserialization_error("Some input bytes were not read"); } @@ -3076,19 +3824,19 @@ namespace Circuit { template <> template -void serde::Serializable::serialize(const Circuit::BlackBoxOp::EmbeddedCurveDouble &obj, Serializer &serializer) { - serde::Serializable::serialize(obj.input1_x, serializer); - serde::Serializable::serialize(obj.input1_y, serializer); - serde::Serializable::serialize(obj.result, serializer); +void serde::Serializable::serialize(const Circuit::BlackBoxOp::Sha256Compression &obj, Serializer &serializer) { + serde::Serializable::serialize(obj.input, serializer); + serde::Serializable::serialize(obj.hash_values, serializer); + serde::Serializable::serialize(obj.output, serializer); } template <> template -Circuit::BlackBoxOp::EmbeddedCurveDouble serde::Deserializable::deserialize(Deserializer &deserializer) { - Circuit::BlackBoxOp::EmbeddedCurveDouble obj; - obj.input1_x = serde::Deserializable::deserialize(deserializer); - obj.input1_y = serde::Deserializable::deserialize(deserializer); - obj.result = serde::Deserializable::deserialize(deserializer); +Circuit::BlackBoxOp::Sha256Compression serde::Deserializable::deserialize(Deserializer &deserializer) { + Circuit::BlackBoxOp::Sha256Compression obj; + obj.input = serde::Deserializable::deserialize(deserializer); + obj.hash_values = serde::Deserializable::deserialize(deserializer); + obj.output = serde::Deserializable::deserialize(deserializer); return obj; } diff --git a/acvm-repo/acir/src/circuit/black_box_functions.rs b/acvm-repo/acir/src/circuit/black_box_functions.rs index d1f5560313b..97b4759d350 100644 --- a/acvm-repo/acir/src/circuit/black_box_functions.rs +++ b/acvm-repo/acir/src/circuit/black_box_functions.rs @@ -47,8 +47,22 @@ pub enum BlackBoxFunc { RecursiveAggregation, /// Addition over the embedded curve on which [`FieldElement`][acir_field::FieldElement] is defined. EmbeddedCurveAdd, - /// Point doubling over the embedded curve on which [`FieldElement`][acir_field::FieldElement] is defined. - EmbeddedCurveDouble, + /// BigInt addition + BigIntAdd, + /// BigInt subtraction + BigIntNeg, + /// BigInt multiplication + BigIntMul, + /// BigInt division + BigIntDiv, + /// BigInt from le bytes + BigIntFromLeBytes, + /// BigInt to le bytes + BigIntToLeBytes, + /// Permutation function of Poseidon2 + Poseidon2Permutation, + /// SHA256 compression function + Sha256Compression, } impl std::fmt::Display for BlackBoxFunc { @@ -68,8 +82,7 @@ impl BlackBoxFunc { BlackBoxFunc::PedersenHash => "pedersen_hash", BlackBoxFunc::EcdsaSecp256k1 => "ecdsa_secp256k1", BlackBoxFunc::FixedBaseScalarMul => "fixed_base_scalar_mul", - BlackBoxFunc::EmbeddedCurveAdd => "ec_add", - BlackBoxFunc::EmbeddedCurveDouble => "ec_double", + BlackBoxFunc::EmbeddedCurveAdd => "embedded_curve_add", BlackBoxFunc::AND => "and", BlackBoxFunc::XOR => "xor", BlackBoxFunc::RANGE => "range", @@ -77,8 +90,17 @@ impl BlackBoxFunc { BlackBoxFunc::Keccakf1600 => "keccakf1600", BlackBoxFunc::RecursiveAggregation => "recursive_aggregation", BlackBoxFunc::EcdsaSecp256r1 => "ecdsa_secp256r1", + BlackBoxFunc::BigIntAdd => "bigint_add", + BlackBoxFunc::BigIntNeg => "bigint_neg", + BlackBoxFunc::BigIntMul => "bigint_mul", + BlackBoxFunc::BigIntDiv => "bigint_div", + BlackBoxFunc::BigIntFromLeBytes => "bigint_from_le_bytes", + BlackBoxFunc::BigIntToLeBytes => "bigint_to_le_bytes", + BlackBoxFunc::Poseidon2Permutation => "poseidon2_permutation", + BlackBoxFunc::Sha256Compression => "sha256_compression", } } + pub fn lookup(op_name: &str) -> Option { match op_name { "sha256" => Some(BlackBoxFunc::SHA256), @@ -90,17 +112,25 @@ impl BlackBoxFunc { "ecdsa_secp256k1" => Some(BlackBoxFunc::EcdsaSecp256k1), "ecdsa_secp256r1" => Some(BlackBoxFunc::EcdsaSecp256r1), "fixed_base_scalar_mul" => Some(BlackBoxFunc::FixedBaseScalarMul), - "ec_add" => Some(BlackBoxFunc::EmbeddedCurveAdd), - "ec_double" => Some(BlackBoxFunc::EmbeddedCurveDouble), + "embedded_curve_add" => Some(BlackBoxFunc::EmbeddedCurveAdd), "and" => Some(BlackBoxFunc::AND), "xor" => Some(BlackBoxFunc::XOR), "range" => Some(BlackBoxFunc::RANGE), "keccak256" => Some(BlackBoxFunc::Keccak256), "keccakf1600" => Some(BlackBoxFunc::Keccakf1600), "recursive_aggregation" => Some(BlackBoxFunc::RecursiveAggregation), + "bigint_add" => Some(BlackBoxFunc::BigIntAdd), + "bigint_neg" => Some(BlackBoxFunc::BigIntNeg), + "bigint_mul" => Some(BlackBoxFunc::BigIntMul), + "bigint_div" => Some(BlackBoxFunc::BigIntDiv), + "bigint_from_le_bytes" => Some(BlackBoxFunc::BigIntFromLeBytes), + "bigint_to_le_bytes" => Some(BlackBoxFunc::BigIntToLeBytes), + "poseidon2_permutation" => Some(BlackBoxFunc::Poseidon2Permutation), + "sha256_compression" => Some(BlackBoxFunc::Sha256Compression), _ => None, } } + pub fn is_valid_black_box_func_name(op_name: &str) -> bool { BlackBoxFunc::lookup(op_name).is_some() } diff --git a/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs b/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs index 7ee4e2498a5..ba4964c8912 100644 --- a/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs +++ b/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs @@ -86,11 +86,6 @@ pub enum BlackBoxFuncCall { input2_y: FunctionInput, outputs: (Witness, Witness), }, - EmbeddedCurveDouble { - input_x: FunctionInput, - input_y: FunctionInput, - outputs: (Witness, Witness), - }, Keccak256 { inputs: Vec, outputs: Vec, @@ -120,6 +115,61 @@ pub enum BlackBoxFuncCall { /// key provided to the circuit matches the key produced by the circuit creator key_hash: FunctionInput, }, + BigIntAdd { + lhs: u32, + rhs: u32, + output: u32, + }, + BigIntNeg { + lhs: u32, + rhs: u32, + output: u32, + }, + BigIntMul { + lhs: u32, + rhs: u32, + output: u32, + }, + BigIntDiv { + lhs: u32, + rhs: u32, + output: u32, + }, + BigIntFromLeBytes { + inputs: Vec, + modulus: Vec, + output: u32, + }, + BigIntToLeBytes { + input: u32, + outputs: Vec, + }, + /// Applies the Poseidon2 permutation function to the given state, + /// outputting the permuted state. + Poseidon2Permutation { + /// Input state for the permutation of Poseidon2 + inputs: Vec, + /// Permuted state + outputs: Vec, + /// State length (in number of field elements) + /// It is the length of inputs and outputs vectors + len: u32, + }, + /// Applies the SHA-256 compression function to the input message + /// + /// # Arguments + /// + /// * `inputs` - input message block + /// * `hash_values` - state from the previous compression + /// * `outputs` - result of the input compressed into 256 bits + Sha256Compression { + /// 512 bits of the input message, represented by 16 u32s + inputs: Vec, + /// Vector of 8 u32s used to compress the input + hash_values: Vec, + /// Output of the compression, represented by 8 u32s + outputs: Vec, + }, } impl BlackBoxFuncCall { @@ -138,11 +188,18 @@ impl BlackBoxFuncCall { BlackBoxFuncCall::EcdsaSecp256r1 { .. } => BlackBoxFunc::EcdsaSecp256r1, BlackBoxFuncCall::FixedBaseScalarMul { .. } => BlackBoxFunc::FixedBaseScalarMul, BlackBoxFuncCall::EmbeddedCurveAdd { .. } => BlackBoxFunc::EmbeddedCurveAdd, - BlackBoxFuncCall::EmbeddedCurveDouble { .. } => BlackBoxFunc::EmbeddedCurveDouble, BlackBoxFuncCall::Keccak256 { .. } => BlackBoxFunc::Keccak256, BlackBoxFuncCall::Keccak256VariableLength { .. } => BlackBoxFunc::Keccak256, BlackBoxFuncCall::Keccakf1600 { .. } => BlackBoxFunc::Keccakf1600, BlackBoxFuncCall::RecursiveAggregation { .. } => BlackBoxFunc::RecursiveAggregation, + BlackBoxFuncCall::BigIntAdd { .. } => BlackBoxFunc::BigIntAdd, + BlackBoxFuncCall::BigIntNeg { .. } => BlackBoxFunc::BigIntNeg, + BlackBoxFuncCall::BigIntMul { .. } => BlackBoxFunc::BigIntMul, + BlackBoxFuncCall::BigIntDiv { .. } => BlackBoxFunc::BigIntDiv, + BlackBoxFuncCall::BigIntFromLeBytes { .. } => BlackBoxFunc::BigIntFromLeBytes, + BlackBoxFuncCall::BigIntToLeBytes { .. } => BlackBoxFunc::BigIntToLeBytes, + BlackBoxFuncCall::Poseidon2Permutation { .. } => BlackBoxFunc::Poseidon2Permutation, + BlackBoxFuncCall::Sha256Compression { .. } => BlackBoxFunc::Sha256Compression, } } @@ -158,17 +215,22 @@ impl BlackBoxFuncCall { | BlackBoxFuncCall::Keccak256 { inputs, .. } | BlackBoxFuncCall::Keccakf1600 { inputs, .. } | BlackBoxFuncCall::PedersenCommitment { inputs, .. } - | BlackBoxFuncCall::PedersenHash { inputs, .. } => inputs.to_vec(), + | BlackBoxFuncCall::PedersenHash { inputs, .. } + | BlackBoxFuncCall::BigIntFromLeBytes { inputs, .. } + | BlackBoxFuncCall::Poseidon2Permutation { inputs, .. } + | BlackBoxFuncCall::Sha256Compression { inputs, .. } => inputs.to_vec(), BlackBoxFuncCall::AND { lhs, rhs, .. } | BlackBoxFuncCall::XOR { lhs, rhs, .. } => { vec![*lhs, *rhs] } + BlackBoxFuncCall::BigIntAdd { .. } + | BlackBoxFuncCall::BigIntNeg { .. } + | BlackBoxFuncCall::BigIntMul { .. } + | BlackBoxFuncCall::BigIntDiv { .. } + | BlackBoxFuncCall::BigIntToLeBytes { .. } => Vec::new(), BlackBoxFuncCall::FixedBaseScalarMul { low, high, .. } => vec![*low, *high], BlackBoxFuncCall::EmbeddedCurveAdd { input1_x, input1_y, input2_x, input2_y, .. } => vec![*input1_x, *input1_y, *input2_x, *input2_y], - BlackBoxFuncCall::EmbeddedCurveDouble { input_x, input_y, .. } => { - vec![*input_x, *input_y] - } BlackBoxFuncCall::RANGE { input } => vec![*input], BlackBoxFuncCall::SchnorrVerify { public_key_x, @@ -249,7 +311,10 @@ impl BlackBoxFuncCall { | BlackBoxFuncCall::Blake2s { outputs, .. } | BlackBoxFuncCall::Blake3 { outputs, .. } | BlackBoxFuncCall::Keccak256 { outputs, .. } - | BlackBoxFuncCall::Keccakf1600 { outputs, .. } => outputs.to_vec(), + | BlackBoxFuncCall::Keccakf1600 { outputs, .. } + | BlackBoxFuncCall::Keccak256VariableLength { outputs, .. } + | BlackBoxFuncCall::Poseidon2Permutation { outputs, .. } + | BlackBoxFuncCall::Sha256Compression { outputs, .. } => outputs.to_vec(), BlackBoxFuncCall::AND { output, .. } | BlackBoxFuncCall::XOR { output, .. } | BlackBoxFuncCall::SchnorrVerify { output, .. } @@ -258,12 +323,17 @@ impl BlackBoxFuncCall { | BlackBoxFuncCall::EcdsaSecp256r1 { output, .. } => vec![*output], BlackBoxFuncCall::FixedBaseScalarMul { outputs, .. } | BlackBoxFuncCall::PedersenCommitment { outputs, .. } - | BlackBoxFuncCall::EmbeddedCurveAdd { outputs, .. } - | BlackBoxFuncCall::EmbeddedCurveDouble { outputs, .. } => vec![outputs.0, outputs.1], - BlackBoxFuncCall::RANGE { .. } | BlackBoxFuncCall::RecursiveAggregation { .. } => { + | BlackBoxFuncCall::EmbeddedCurveAdd { outputs, .. } => vec![outputs.0, outputs.1], + BlackBoxFuncCall::RANGE { .. } + | BlackBoxFuncCall::RecursiveAggregation { .. } + | BlackBoxFuncCall::BigIntFromLeBytes { .. } + | BlackBoxFuncCall::BigIntAdd { .. } + | BlackBoxFuncCall::BigIntNeg { .. } + | BlackBoxFuncCall::BigIntMul { .. } + | BlackBoxFuncCall::BigIntDiv { .. } => { vec![] } - BlackBoxFuncCall::Keccak256VariableLength { outputs, .. } => outputs.to_vec(), + BlackBoxFuncCall::BigIntToLeBytes { outputs, .. } => outputs.to_vec(), } } } diff --git a/acvm-repo/acvm/src/pwg/blackbox/fixed_base_scalar_mul.rs b/acvm-repo/acvm/src/pwg/blackbox/fixed_base_scalar_mul.rs index 582ed56584b..c5bfd1d5646 100644 --- a/acvm-repo/acvm/src/pwg/blackbox/fixed_base_scalar_mul.rs +++ b/acvm-repo/acvm/src/pwg/blackbox/fixed_base_scalar_mul.rs @@ -23,3 +23,24 @@ pub(super) fn fixed_base_scalar_mul( Ok(()) } + +pub(super) fn embedded_curve_add( + backend: &impl BlackBoxFunctionSolver, + initial_witness: &mut WitnessMap, + input1_x: FunctionInput, + input1_y: FunctionInput, + input2_x: FunctionInput, + input2_y: FunctionInput, + outputs: (Witness, Witness), +) -> Result<(), OpcodeResolutionError> { + let input1_x = witness_to_value(initial_witness, input1_x.witness)?; + let input1_y = witness_to_value(initial_witness, input1_y.witness)?; + let input2_x = witness_to_value(initial_witness, input2_x.witness)?; + let input2_y = witness_to_value(initial_witness, input2_y.witness)?; + let (res_x, res_y) = backend.ec_add(input1_x, input1_y, input2_x, input2_y)?; + + insert_value(&outputs.0, res_x, initial_witness)?; + insert_value(&outputs.1, res_y, initial_witness)?; + + Ok(()) +} diff --git a/acvm-repo/acvm/src/pwg/blackbox/mod.rs b/acvm-repo/acvm/src/pwg/blackbox/mod.rs index 5eea234885c..0f026cd274a 100644 --- a/acvm-repo/acvm/src/pwg/blackbox/mod.rs +++ b/acvm-repo/acvm/src/pwg/blackbox/mod.rs @@ -17,7 +17,7 @@ mod pedersen; mod range; mod signature; -use fixed_base_scalar_mul::fixed_base_scalar_mul; +use fixed_base_scalar_mul::{embedded_curve_add, fixed_base_scalar_mul}; // Hash functions should eventually be exposed for external consumers. use hash::solve_generic_256_hash_opcode; use logic::{and, xor}; @@ -177,13 +177,26 @@ pub(crate) fn solve( BlackBoxFuncCall::FixedBaseScalarMul { low, high, outputs } => { fixed_base_scalar_mul(backend, initial_witness, *low, *high, *outputs) } - BlackBoxFuncCall::EmbeddedCurveAdd { .. } => { - todo!(); - } - BlackBoxFuncCall::EmbeddedCurveDouble { .. } => { - todo!(); + BlackBoxFuncCall::EmbeddedCurveAdd { input1_x, input1_y, input2_x, input2_y, outputs } => { + embedded_curve_add( + backend, + initial_witness, + *input1_x, + *input1_y, + *input2_x, + *input2_y, + *outputs, + ) } // Recursive aggregation will be entirely handled by the backend and is not solved by the ACVM BlackBoxFuncCall::RecursiveAggregation { .. } => Ok(()), + BlackBoxFuncCall::BigIntAdd { .. } => todo!(), + BlackBoxFuncCall::BigIntNeg { .. } => todo!(), + BlackBoxFuncCall::BigIntMul { .. } => todo!(), + BlackBoxFuncCall::BigIntDiv { .. } => todo!(), + BlackBoxFuncCall::BigIntFromLeBytes { .. } => todo!(), + BlackBoxFuncCall::BigIntToLeBytes { .. } => todo!(), + BlackBoxFuncCall::Poseidon2Permutation { .. } => todo!(), + BlackBoxFuncCall::Sha256Compression { .. } => todo!(), } } diff --git a/acvm-repo/blackbox_solver/src/curve_specific_solver.rs b/acvm-repo/blackbox_solver/src/curve_specific_solver.rs index 82941e91d61..2234710dec0 100644 --- a/acvm-repo/blackbox_solver/src/curve_specific_solver.rs +++ b/acvm-repo/blackbox_solver/src/curve_specific_solver.rs @@ -36,11 +36,6 @@ pub trait BlackBoxFunctionSolver { input2_x: &FieldElement, input2_y: &FieldElement, ) -> Result<(FieldElement, FieldElement), BlackBoxResolutionError>; - fn ec_double( - &self, - input_x: &FieldElement, - input_x: &FieldElement, - ) -> Result<(FieldElement, FieldElement), BlackBoxResolutionError>; } pub struct StubbedBlackBoxSolver; @@ -94,11 +89,4 @@ impl BlackBoxFunctionSolver for StubbedBlackBoxSolver { ) -> Result<(FieldElement, FieldElement), BlackBoxResolutionError> { Err(Self::fail(BlackBoxFunc::EmbeddedCurveAdd)) } - fn ec_double( - &self, - _input_x: &FieldElement, - _input_y: &FieldElement, - ) -> Result<(FieldElement, FieldElement), BlackBoxResolutionError> { - Err(Self::fail(BlackBoxFunc::EmbeddedCurveDouble)) - } } diff --git a/acvm-repo/bn254_blackbox_solver/src/fixed_base_scalar_mul.rs b/acvm-repo/bn254_blackbox_solver/src/fixed_base_scalar_mul.rs index 7f004de0fe9..5e68c7d4030 100644 --- a/acvm-repo/bn254_blackbox_solver/src/fixed_base_scalar_mul.rs +++ b/acvm-repo/bn254_blackbox_solver/src/fixed_base_scalar_mul.rs @@ -47,6 +47,26 @@ pub fn fixed_base_scalar_mul( } } +pub fn embedded_curve_add( + input1_x: FieldElement, + input1_y: FieldElement, + input2_x: FieldElement, + input2_y: FieldElement, +) -> Result<(FieldElement, FieldElement), BlackBoxResolutionError> { + let mut point1 = grumpkin::SWAffine::new(input1_x.into_repr(), input1_y.into_repr()); + let point2 = grumpkin::SWAffine::new(input2_x.into_repr(), input2_y.into_repr()); + let res = point1 + point2; + point1 = res.into(); + if let Some((res_x, res_y)) = point1.xy() { + Ok((FieldElement::from_repr(*res_x), FieldElement::from_repr(*res_y))) + } else { + Err(BlackBoxResolutionError::Failed( + BlackBoxFunc::EmbeddedCurveAdd, + "Point is not on curve".to_string(), + )) + } +} + #[cfg(test)] mod grumpkin_fixed_base_scalar_mul { use ark_ff::BigInteger; diff --git a/acvm-repo/bn254_blackbox_solver/src/lib.rs b/acvm-repo/bn254_blackbox_solver/src/lib.rs index 92c45e93dea..13aa956f9e1 100644 --- a/acvm-repo/bn254_blackbox_solver/src/lib.rs +++ b/acvm-repo/bn254_blackbox_solver/src/lib.rs @@ -8,7 +8,7 @@ use acvm_blackbox_solver::{BlackBoxFunctionSolver, BlackBoxResolutionError}; mod fixed_base_scalar_mul; mod wasm; -pub use fixed_base_scalar_mul::fixed_base_scalar_mul; +pub use fixed_base_scalar_mul::{embedded_curve_add, fixed_base_scalar_mul}; use wasm::Barretenberg; use self::wasm::{Pedersen, SchnorrSig}; @@ -90,19 +90,11 @@ impl BlackBoxFunctionSolver for Bn254BlackBoxSolver { fn ec_add( &self, - _input1_x: &FieldElement, - _input1_y: &FieldElement, - _input2_x: &FieldElement, - _input2_y: &FieldElement, + input1_x: &FieldElement, + input1_y: &FieldElement, + input2_x: &FieldElement, + input2_y: &FieldElement, ) -> Result<(FieldElement, FieldElement), BlackBoxResolutionError> { - todo!(); - } - - fn ec_double( - &self, - _input_x: &FieldElement, - _input_y: &FieldElement, - ) -> Result<(FieldElement, FieldElement), BlackBoxResolutionError> { - todo!(); + embedded_curve_add(*input1_x, *input1_y, *input2_x, *input2_y) } } diff --git a/acvm-repo/brillig/src/black_box.rs b/acvm-repo/brillig/src/black_box.rs index c007e78b785..22fac6f3ba3 100644 --- a/acvm-repo/brillig/src/black_box.rs +++ b/acvm-repo/brillig/src/black_box.rs @@ -6,15 +6,30 @@ use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] pub enum BlackBoxOp { /// Calculates the SHA256 hash of the inputs. - Sha256 { message: HeapVector, output: HeapArray }, + Sha256 { + message: HeapVector, + output: HeapArray, + }, /// Calculates the Blake2s hash of the inputs. - Blake2s { message: HeapVector, output: HeapArray }, + Blake2s { + message: HeapVector, + output: HeapArray, + }, /// Calculates the Blake3 hash of the inputs. - Blake3 { message: HeapVector, output: HeapArray }, + Blake3 { + message: HeapVector, + output: HeapArray, + }, /// Calculates the Keccak256 hash of the inputs. - Keccak256 { message: HeapVector, output: HeapArray }, + Keccak256 { + message: HeapVector, + output: HeapArray, + }, /// Keccak Permutation function of 1600 width - Keccakf1600 { message: HeapVector, output: HeapArray }, + Keccakf1600 { + message: HeapVector, + output: HeapArray, + }, /// Verifies a ECDSA signature over the secp256k1 curve. EcdsaSecp256k1 { hashed_msg: HeapVector, @@ -40,11 +55,23 @@ pub enum BlackBoxOp { result: RegisterIndex, }, /// Calculates a Pedersen commitment to the inputs. - PedersenCommitment { inputs: HeapVector, domain_separator: RegisterIndex, output: HeapArray }, + PedersenCommitment { + inputs: HeapVector, + domain_separator: RegisterIndex, + output: HeapArray, + }, /// Calculates a Pedersen hash to the inputs. - PedersenHash { inputs: HeapVector, domain_separator: RegisterIndex, output: RegisterIndex }, + PedersenHash { + inputs: HeapVector, + domain_separator: RegisterIndex, + output: RegisterIndex, + }, /// Performs scalar multiplication over the embedded curve. - FixedBaseScalarMul { low: RegisterIndex, high: RegisterIndex, result: HeapArray }, + FixedBaseScalarMul { + low: RegisterIndex, + high: RegisterIndex, + result: HeapArray, + }, /// Performs addition over the embedded curve. EmbeddedCurveAdd { input1_x: RegisterIndex, @@ -53,6 +80,43 @@ pub enum BlackBoxOp { input2_y: RegisterIndex, result: HeapArray, }, - /// Performs point doubling over the embedded curve. - EmbeddedCurveDouble { input1_x: RegisterIndex, input1_y: RegisterIndex, result: HeapArray }, + BigIntAdd { + lhs: RegisterIndex, + rhs: RegisterIndex, + output: RegisterIndex, + }, + BigIntNeg { + lhs: RegisterIndex, + rhs: RegisterIndex, + output: RegisterIndex, + }, + BigIntMul { + lhs: RegisterIndex, + rhs: RegisterIndex, + output: RegisterIndex, + }, + BigIntDiv { + lhs: RegisterIndex, + rhs: RegisterIndex, + output: RegisterIndex, + }, + BigIntFromLeBytes { + inputs: HeapVector, + modulus: HeapVector, + output: RegisterIndex, + }, + BigIntToLeBytes { + input: RegisterIndex, + output: HeapVector, + }, + Poseidon2Permutation { + message: HeapVector, + output: HeapArray, + len: RegisterIndex, + }, + Sha256Compression { + input: HeapVector, + hash_values: HeapVector, + output: HeapArray, + }, } diff --git a/acvm-repo/brillig_vm/src/black_box.rs b/acvm-repo/brillig_vm/src/black_box.rs index 463038509e1..e9c25200c47 100644 --- a/acvm-repo/brillig_vm/src/black_box.rs +++ b/acvm-repo/brillig_vm/src/black_box.rs @@ -165,13 +165,6 @@ pub(crate) fn evaluate_black_box( memory.write_slice(registers.get(result.pointer).to_usize(), &[x.into(), y.into()]); Ok(()) } - BlackBoxOp::EmbeddedCurveDouble { input1_x, input1_y, result } => { - let input1_x = registers.get(*input1_x).to_field(); - let input1_y = registers.get(*input1_y).to_field(); - let (x, y) = solver.ec_double(&input1_x, &input1_y)?; - memory.write_slice(registers.get(result.pointer).to_usize(), &[x.into(), y.into()]); - Ok(()) - } BlackBoxOp::PedersenCommitment { inputs, domain_separator, output } => { let inputs: Vec = read_heap_vector(memory, registers, inputs).iter().map(|x| x.to_field()).collect(); @@ -200,6 +193,14 @@ pub(crate) fn evaluate_black_box( registers.set(*output, hash.into()); Ok(()) } + BlackBoxOp::BigIntAdd { .. } => todo!(), + BlackBoxOp::BigIntNeg { .. } => todo!(), + BlackBoxOp::BigIntMul { .. } => todo!(), + BlackBoxOp::BigIntDiv { .. } => todo!(), + BlackBoxOp::BigIntFromLeBytes { .. } => todo!(), + BlackBoxOp::BigIntToLeBytes { .. } => todo!(), + BlackBoxOp::Poseidon2Permutation { .. } => todo!(), + BlackBoxOp::Sha256Compression { .. } => todo!(), } } @@ -217,7 +218,14 @@ fn black_box_function_from_op(op: &BlackBoxOp) -> BlackBoxFunc { BlackBoxOp::PedersenHash { .. } => BlackBoxFunc::PedersenHash, BlackBoxOp::FixedBaseScalarMul { .. } => BlackBoxFunc::FixedBaseScalarMul, BlackBoxOp::EmbeddedCurveAdd { .. } => BlackBoxFunc::EmbeddedCurveAdd, - BlackBoxOp::EmbeddedCurveDouble { .. } => BlackBoxFunc::EmbeddedCurveDouble, + BlackBoxOp::BigIntAdd { .. } => BlackBoxFunc::BigIntAdd, + BlackBoxOp::BigIntNeg { .. } => BlackBoxFunc::BigIntNeg, + BlackBoxOp::BigIntMul { .. } => BlackBoxFunc::BigIntMul, + BlackBoxOp::BigIntDiv { .. } => BlackBoxFunc::BigIntDiv, + BlackBoxOp::BigIntFromLeBytes { .. } => BlackBoxFunc::BigIntFromLeBytes, + BlackBoxOp::BigIntToLeBytes { .. } => BlackBoxFunc::BigIntToLeBytes, + BlackBoxOp::Poseidon2Permutation { .. } => BlackBoxFunc::Poseidon2Permutation, + BlackBoxOp::Sha256Compression { .. } => BlackBoxFunc::Sha256Compression, } } diff --git a/acvm-repo/brillig_vm/src/lib.rs b/acvm-repo/brillig_vm/src/lib.rs index 00c20a704da..0c258ab34d6 100644 --- a/acvm-repo/brillig_vm/src/lib.rs +++ b/acvm-repo/brillig_vm/src/lib.rs @@ -460,13 +460,6 @@ impl BlackBoxFunctionSolver for DummyBlackBoxSolver { ) -> Result<(FieldElement, FieldElement), BlackBoxResolutionError> { Ok((5_u128.into(), 6_u128.into())) } - fn ec_double( - &self, - _input1_x: &FieldElement, - _input1_y: &FieldElement, - ) -> Result<(FieldElement, FieldElement), BlackBoxResolutionError> { - Ok((7_u128.into(), 8_u128.into())) - } } #[cfg(test)] diff --git a/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_black_box.rs b/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_black_box.rs index c081806f4a7..96d80cb8131 100644 --- a/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_black_box.rs +++ b/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_black_box.rs @@ -215,23 +215,6 @@ pub(crate) fn convert_black_box_call( ) } } - BlackBoxFunc::EmbeddedCurveDouble => { - if let ( - [BrilligVariable::Simple(input1_x), BrilligVariable::Simple(input1_y)], - [BrilligVariable::BrilligArray(result_array)], - ) = (function_arguments, function_results) - { - brillig_context.black_box_op_instruction(BlackBoxOp::EmbeddedCurveDouble { - input1_x: *input1_x, - input1_y: *input1_y, - result: result_array.to_heap_array(), - }); - } else { - unreachable!( - "ICE: EmbeddedCurveAdd expects two register arguments and one array result" - ) - } - } BlackBoxFunc::AND => { unreachable!("ICE: `BlackBoxFunc::AND` calls should be transformed into a `BinaryOp`") } @@ -244,6 +227,138 @@ pub(crate) fn convert_black_box_call( BlackBoxFunc::RecursiveAggregation => unimplemented!( "ICE: `BlackBoxFunc::RecursiveAggregation` is not implemented by the Brillig VM" ), + BlackBoxFunc::BigIntAdd => { + if let ( + [BrilligVariable::Simple(lhs), BrilligVariable::Simple(rhs)], + [BrilligVariable::Simple(output)], + ) = (function_arguments, function_results) + { + brillig_context.black_box_op_instruction(BlackBoxOp::BigIntAdd { + lhs: *lhs, + rhs: *rhs, + output: *output, + }); + } else { + unreachable!( + "ICE: EmbeddedCurveAdd expects two register arguments and one array result" + ) + } + } + BlackBoxFunc::BigIntNeg => { + if let ( + [BrilligVariable::Simple(lhs), BrilligVariable::Simple(rhs)], + [BrilligVariable::Simple(output)], + ) = (function_arguments, function_results) + { + brillig_context.black_box_op_instruction(BlackBoxOp::BigIntNeg { + lhs: *lhs, + rhs: *rhs, + output: *output, + }); + } else { + unreachable!( + "ICE: EmbeddedCurveAdd expects two register arguments and one array result" + ) + } + } + BlackBoxFunc::BigIntMul => { + if let ( + [BrilligVariable::Simple(lhs), BrilligVariable::Simple(rhs)], + [BrilligVariable::Simple(output)], + ) = (function_arguments, function_results) + { + brillig_context.black_box_op_instruction(BlackBoxOp::BigIntMul { + lhs: *lhs, + rhs: *rhs, + output: *output, + }); + } else { + unreachable!( + "ICE: EmbeddedCurveAdd expects two register arguments and one array result" + ) + } + } + BlackBoxFunc::BigIntDiv => { + if let ( + [BrilligVariable::Simple(lhs), BrilligVariable::Simple(rhs)], + [BrilligVariable::Simple(output)], + ) = (function_arguments, function_results) + { + brillig_context.black_box_op_instruction(BlackBoxOp::BigIntDiv { + lhs: *lhs, + rhs: *rhs, + output: *output, + }); + } else { + unreachable!( + "ICE: EmbeddedCurveAdd expects two register arguments and one array result" + ) + } + } + BlackBoxFunc::BigIntFromLeBytes => { + if let ([inputs, modulus], [BrilligVariable::Simple(output)]) = + (function_arguments, function_results) + { + let inputs_vector = convert_array_or_vector(brillig_context, inputs, bb_func); + let modulus_vector = convert_array_or_vector(brillig_context, modulus, bb_func); + brillig_context.black_box_op_instruction(BlackBoxOp::BigIntFromLeBytes { + inputs: inputs_vector.to_heap_vector(), + modulus: modulus_vector.to_heap_vector(), + output: *output, + }); + } else { + unreachable!( + "ICE: EmbeddedCurveAdd expects two register arguments and one array result" + ) + } + } + BlackBoxFunc::BigIntToLeBytes => { + if let ( + [BrilligVariable::Simple(input)], + [BrilligVariable::BrilligVector(result_vector)], + ) = (function_arguments, function_results) + { + brillig_context.black_box_op_instruction(BlackBoxOp::BigIntToLeBytes { + input: *input, + output: result_vector.to_heap_vector(), + }); + } else { + unreachable!( + "ICE: EmbeddedCurveAdd expects two register arguments and one array result" + ) + } + } + BlackBoxFunc::Poseidon2Permutation => { + if let ( + [message, BrilligVariable::Simple(state_len)], + [BrilligVariable::BrilligArray(result_array)], + ) = (function_arguments, function_results) + { + let message_vector = convert_array_or_vector(brillig_context, message, bb_func); + brillig_context.black_box_op_instruction(BlackBoxOp::Poseidon2Permutation { + message: message_vector.to_heap_vector(), + output: result_array.to_heap_array(), + len: *state_len, + }); + } else { + unreachable!("ICE: Poseidon2Permutation expects one array argument, a length and one array result") + } + } + BlackBoxFunc::Sha256Compression => { + if let ([message, hash_values], [BrilligVariable::BrilligArray(result_array)]) = + (function_arguments, function_results) + { + let message_vector = convert_array_or_vector(brillig_context, message, bb_func); + let hash_vector = convert_array_or_vector(brillig_context, hash_values, bb_func); + brillig_context.black_box_op_instruction(BlackBoxOp::Sha256Compression { + input: message_vector.to_heap_vector(), + hash_values: hash_vector.to_heap_vector(), + output: result_array.to_heap_array(), + }); + } else { + unreachable!("ICE: Sha256Compression expects two array argument, one array result") + } + } } } diff --git a/compiler/noirc_evaluator/src/brillig/brillig_ir.rs b/compiler/noirc_evaluator/src/brillig/brillig_ir.rs index db3cd501ca0..3e6c3d4d7de 100644 --- a/compiler/noirc_evaluator/src/brillig/brillig_ir.rs +++ b/compiler/noirc_evaluator/src/brillig/brillig_ir.rs @@ -1096,14 +1096,6 @@ pub(crate) mod tests { ) -> Result<(FieldElement, FieldElement), BlackBoxResolutionError> { panic!("Path not trodden by this test") } - - fn ec_double( - &self, - _input_x: &FieldElement, - _input_y: &FieldElement, - ) -> Result<(FieldElement, FieldElement), BlackBoxResolutionError> { - panic!("Path not trodden by this test") - } } pub(crate) fn create_context() -> BrilligContext { diff --git a/compiler/noirc_evaluator/src/brillig/brillig_ir/debug_show.rs b/compiler/noirc_evaluator/src/brillig/brillig_ir/debug_show.rs index dc8c6b6694c..a8563dc9efe 100644 --- a/compiler/noirc_evaluator/src/brillig/brillig_ir/debug_show.rs +++ b/compiler/noirc_evaluator/src/brillig/brillig_ir/debug_show.rs @@ -413,15 +413,6 @@ impl DebugShow { result ); } - BlackBoxOp::EmbeddedCurveDouble { input1_x, input1_y, result } => { - debug_println!( - self.enable_debug_trace, - " EMBEDDED_CURVE_DOUBLE ({} {}) -> {}", - input1_x, - input1_y, - result - ); - } BlackBoxOp::PedersenCommitment { inputs, domain_separator, output } => { debug_println!( self.enable_debug_trace, @@ -457,6 +448,77 @@ impl DebugShow { result ); } + BlackBoxOp::BigIntAdd { lhs, rhs, output } => { + debug_println!( + self.enable_debug_trace, + " BIGINT_ADD {} {} -> {}", + lhs, + rhs, + output + ); + } + BlackBoxOp::BigIntNeg { lhs, rhs, output } => { + debug_println!( + self.enable_debug_trace, + " BIGINT_NEG {} {} -> {}", + lhs, + rhs, + output + ); + } + BlackBoxOp::BigIntMul { lhs, rhs, output } => { + debug_println!( + self.enable_debug_trace, + " BIGINT_MUL {} {} -> {}", + lhs, + rhs, + output + ); + } + BlackBoxOp::BigIntDiv { lhs, rhs, output } => { + debug_println!( + self.enable_debug_trace, + " BIGINT_DIV {} {} -> {}", + lhs, + rhs, + output + ); + } + BlackBoxOp::BigIntFromLeBytes { inputs, modulus, output } => { + debug_println!( + self.enable_debug_trace, + " BIGINT_FROM_LE_BYTES {} {} -> {}", + inputs, + modulus, + output + ); + } + BlackBoxOp::BigIntToLeBytes { input, output } => { + debug_println!( + self.enable_debug_trace, + " BIGINT_TO_LE_BYTES {} -> {}", + input, + output + ); + } + BlackBoxOp::Poseidon2Permutation { message, output, len } => { + debug_println!( + self.enable_debug_trace, + " POSEIDON2_PERMUTATION {} {} -> {}", + message, + len, + output + ); + } + BlackBoxOp::Sha256Compression { input, hash_values, output } => { + debug_println!( + self.enable_debug_trace, + " SHA256COMPRESSION {} {} -> {}", + input, + hash_values, + output + ); + } } } diff --git a/compiler/noirc_evaluator/src/errors.rs b/compiler/noirc_evaluator/src/errors.rs index 2582c48555a..73b6e671bd5 100644 --- a/compiler/noirc_evaluator/src/errors.rs +++ b/compiler/noirc_evaluator/src/errors.rs @@ -44,6 +44,8 @@ pub enum RuntimeError { AssertConstantFailed { call_stack: CallStack }, #[error("Nested slices are not supported")] NestedSlice { call_stack: CallStack }, + #[error("Big Integer modulus do no match")] + BigIntModulus { call_stack: CallStack }, } // We avoid showing the actual lhs and rhs since most of the time they are just 0 @@ -132,7 +134,8 @@ impl RuntimeError { | RuntimeError::AssertConstantFailed { call_stack } | RuntimeError::IntegerOutOfBounds { call_stack, .. } | RuntimeError::UnsupportedIntegerSize { call_stack, .. } - | RuntimeError::NestedSlice { call_stack, .. } => call_stack, + | RuntimeError::NestedSlice { call_stack, .. } + | RuntimeError::BigIntModulus { call_stack, .. } => call_stack, } } } diff --git a/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir.rs b/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir.rs index 96800b22ad0..1ddbae0f339 100644 --- a/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir.rs +++ b/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir.rs @@ -1,3 +1,4 @@ pub(crate) mod acir_variable; +pub(crate) mod big_int; pub(crate) mod generated_acir; pub(crate) mod sort; diff --git a/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs b/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs index e88e92ef76a..a419dac9d93 100644 --- a/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs +++ b/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs @@ -1,3 +1,4 @@ +use super::big_int::BigIntContext; use super::generated_acir::GeneratedAcir; use crate::brillig::brillig_gen::brillig_directive; use crate::brillig::brillig_ir::artifact::GeneratedBrillig; @@ -107,6 +108,9 @@ pub(crate) struct AcirContext { /// then the `acir_ir` will be populated to assert this /// addition. acir_ir: GeneratedAcir, + + /// The BigIntContext, used to generate identifiers for BigIntegers + big_int_ctx: BigIntContext, } impl AcirContext { @@ -1140,10 +1144,10 @@ impl AcirContext { &mut self, name: BlackBoxFunc, mut inputs: Vec, - output_count: usize, + mut output_count: usize, ) -> Result, RuntimeError> { // Separate out any arguments that should be constants - let constants = match name { + let (constant_inputs, constant_outputs) = match name { BlackBoxFunc::PedersenCommitment | BlackBoxFunc::PedersenHash => { // The last argument of pedersen is the domain separator, which must be a constant let domain_var = match inputs.pop() { @@ -1167,23 +1171,140 @@ impl AcirContext { } }; - vec![domain_constant] + (vec![domain_constant], Vec::new()) + } + BlackBoxFunc::Poseidon2Permutation => { + // The last argument is the state length, which must be a constant + let state_len = match inputs.pop() { + Some(state_len) => state_len.into_var()?, + None => { + return Err(RuntimeError::InternalError(InternalError::MissingArg { + name: "poseidon_2_permutation call".to_string(), + arg: "length".to_string(), + call_stack: self.get_call_stack(), + })) + } + }; + + let state_len = match self.vars[&state_len].as_constant() { + Some(state_len) => state_len, + None => { + return Err(RuntimeError::InternalError(InternalError::NotAConstant { + name: "length".to_string(), + call_stack: self.get_call_stack(), + })) + } + }; + + (vec![state_len], Vec::new()) + } + BlackBoxFunc::BigIntAdd + | BlackBoxFunc::BigIntNeg + | BlackBoxFunc::BigIntMul + | BlackBoxFunc::BigIntDiv => { + assert_eq!(inputs.len(), 4, "ICE - bigint operation requires 4 inputs"); + let const_inputs = vecmap(inputs, |i| { + let var = i.into_var()?; + match self.vars[&var].as_constant() { + Some(const_var) => Ok(const_var), + None => Err(RuntimeError::InternalError(InternalError::NotAConstant { + name: "big integer".to_string(), + call_stack: self.get_call_stack(), + })), + } + }); + inputs = Vec::new(); + output_count = 0; + let mut field_inputs = Vec::new(); + for i in const_inputs { + field_inputs.push(i?); + } + if field_inputs[1] != field_inputs[3] { + return Err(RuntimeError::BigIntModulus { call_stack: self.get_call_stack() }); + } + + let result_id = self.big_int_ctx.new_big_int(field_inputs[1]); + ( + vec![field_inputs[0], field_inputs[2]], + vec![result_id.bigint_id(), result_id.modulus_id()], + ) + } + BlackBoxFunc::BigIntToLeBytes => { + let const_inputs = vecmap(inputs, |i| { + let var = i.into_var()?; + match self.vars[&var].as_constant() { + Some(const_var) => Ok(const_var), + None => Err(RuntimeError::InternalError(InternalError::NotAConstant { + name: "big integer".to_string(), + call_stack: self.get_call_stack(), + })), + } + }); + inputs = Vec::new(); + let mut field_inputs = Vec::new(); + for i in const_inputs { + field_inputs.push(i?); + } + let modulus = self.big_int_ctx.modulus(field_inputs[0]); + let bytes_len = ((modulus - BigUint::from(1_u32)).bits() - 1) / 8 + 1; + output_count = bytes_len as usize; + (field_inputs, vec![FieldElement::from(bytes_len as u128)]) + } + BlackBoxFunc::BigIntFromLeBytes => { + let invalid_input = "ICE - bigint operation requires 2 inputs"; + assert_eq!(inputs.len(), 2, "{invalid_input}"); + let mut modulus = Vec::new(); + match inputs.pop().expect(invalid_input) { + AcirValue::Array(values) => { + for value in values { + modulus.push(self.vars[&value.into_var()?].as_constant().ok_or( + RuntimeError::InternalError(InternalError::NotAConstant { + name: "big integer".to_string(), + call_stack: self.get_call_stack(), + }), + )?); + } + } + _ => { + return Err(RuntimeError::InternalError(InternalError::MissingArg { + name: "big_int_from_le_bytes".to_owned(), + arg: "modulus".to_owned(), + call_stack: self.get_call_stack(), + })); + } + } + let big_modulus = BigUint::from_bytes_le(&vecmap(&modulus, |b| b.to_u128() as u8)); + output_count = 0; + + let modulus_id = self.big_int_ctx.get_or_insert_modulus(big_modulus); + let result_id = + self.big_int_ctx.new_big_int(FieldElement::from(modulus_id as u128)); + (modulus, vec![result_id.bigint_id(), result_id.modulus_id()]) } - _ => vec![], + _ => (vec![], vec![]), }; // Convert `AcirVar` to `FunctionInput` let inputs = self.prepare_inputs_for_black_box_func_call(inputs)?; - // Call Black box with `FunctionInput` - let outputs = self.acir_ir.call_black_box(name, &inputs, constants, output_count)?; + let mut results = vecmap(&constant_outputs, |c| self.add_constant(*c)); + let outputs = self.acir_ir.call_black_box( + name, + &inputs, + constant_inputs, + constant_outputs, + output_count, + )?; // Convert `Witness` values which are now constrained to be the output of the // black box function call into `AcirVar`s. // // We do not apply range information on the output of the black box function. // See issue #1439 - Ok(vecmap(&outputs, |witness_index| self.add_data(AcirVarData::Witness(*witness_index)))) + results.extend(vecmap(&outputs, |witness_index| { + self.add_data(AcirVarData::Witness(*witness_index)) + })); + Ok(results) } /// Black box function calls expect their inputs to be in a specific data structure (FunctionInput). diff --git a/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/big_int.rs b/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/big_int.rs new file mode 100644 index 00000000000..c21188a8dbc --- /dev/null +++ b/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/big_int.rs @@ -0,0 +1,57 @@ +use acvm::FieldElement; +use num_bigint::BigUint; + +/// Represents a bigint value in the form (id, modulus) where +/// id is the identifier of the big integer number, and +/// modulus is the identifier of the big integer size +#[derive(Default, Clone, Copy, Debug)] +pub(crate) struct BigIntId { + pub(crate) bigint_id: u32, + pub(crate) modulus_id: u32, +} + +impl BigIntId { + pub(crate) fn bigint_id(&self) -> FieldElement { + FieldElement::from(self.bigint_id as u128) + } + + pub(crate) fn modulus_id(&self) -> FieldElement { + FieldElement::from(self.modulus_id as u128) + } +} + +/// BigIntContext is used to generate identifiers for big integers and their modulus +#[derive(Default, Debug)] +pub(crate) struct BigIntContext { + modulus: Vec, + big_integers: Vec, +} + +impl BigIntContext { + /// Creates a new BigIntId for the given modulus identifier and returns it. + pub(crate) fn new_big_int(&mut self, modulus_id: FieldElement) -> BigIntId { + let id = self.big_integers.len() as u32; + let result = BigIntId { bigint_id: id, modulus_id: modulus_id.to_u128() as u32 }; + self.big_integers.push(result); + result + } + + /// Returns the modulus corresponding to the given modulus index + pub(crate) fn modulus(&self, idx: FieldElement) -> BigUint { + self.modulus[idx.to_u128() as usize].clone() + } + + /// Returns the BigIntId corresponding to the given identifier + pub(crate) fn get(&self, id: FieldElement) -> BigIntId { + self.big_integers[id.to_u128() as usize] + } + + /// Adds a modulus to the context (if it is not already present) + pub(crate) fn get_or_insert_modulus(&mut self, modulus: BigUint) -> u32 { + if let Some(pos) = self.modulus.iter().position(|x| x == &modulus) { + return pos as u32; + } + self.modulus.push(modulus); + (self.modulus.len() - 1) as u32 + } +} diff --git a/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs b/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs index efc64c5286e..b86fc4eeb5f 100644 --- a/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs +++ b/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs @@ -138,7 +138,8 @@ impl GeneratedAcir { &mut self, func_name: BlackBoxFunc, inputs: &[Vec], - constants: Vec, + constant_inputs: Vec, + constant_outputs: Vec, output_count: usize, ) -> Result, InternalError> { let input_count = inputs.iter().fold(0usize, |sum, val| sum + val.len()); @@ -176,12 +177,12 @@ impl GeneratedAcir { BlackBoxFunc::PedersenCommitment => BlackBoxFuncCall::PedersenCommitment { inputs: inputs[0].clone(), outputs: (outputs[0], outputs[1]), - domain_separator: constants[0].to_u128() as u32, + domain_separator: constant_inputs[0].to_u128() as u32, }, BlackBoxFunc::PedersenHash => BlackBoxFuncCall::PedersenHash { inputs: inputs[0].clone(), output: outputs[0], - domain_separator: constants[0].to_u128() as u32, + domain_separator: constant_inputs[0].to_u128() as u32, }, BlackBoxFunc::EcdsaSecp256k1 => { BlackBoxFuncCall::EcdsaSecp256k1 { @@ -219,11 +220,6 @@ impl GeneratedAcir { input2_y: inputs[3][0], outputs: (outputs[0], outputs[1]), }, - BlackBoxFunc::EmbeddedCurveDouble => BlackBoxFuncCall::EmbeddedCurveDouble { - input_x: inputs[0][0], - input_y: inputs[1][0], - outputs: (outputs[0], outputs[1]), - }, BlackBoxFunc::Keccak256 => { let var_message_size = match inputs.to_vec().pop() { Some(var_message_size) => var_message_size[0], @@ -251,6 +247,45 @@ impl GeneratedAcir { public_inputs: inputs[2].clone(), key_hash: inputs[3][0], }, + BlackBoxFunc::BigIntAdd => BlackBoxFuncCall::BigIntAdd { + lhs: constant_inputs[0].to_u128() as u32, + rhs: constant_inputs[1].to_u128() as u32, + output: constant_outputs[0].to_u128() as u32, + }, + BlackBoxFunc::BigIntNeg => BlackBoxFuncCall::BigIntNeg { + lhs: constant_inputs[0].to_u128() as u32, + rhs: constant_inputs[1].to_u128() as u32, + output: constant_outputs[0].to_u128() as u32, + }, + BlackBoxFunc::BigIntMul => BlackBoxFuncCall::BigIntMul { + lhs: constant_inputs[0].to_u128() as u32, + rhs: constant_inputs[1].to_u128() as u32, + output: constant_outputs[0].to_u128() as u32, + }, + BlackBoxFunc::BigIntDiv => BlackBoxFuncCall::BigIntDiv { + lhs: constant_inputs[0].to_u128() as u32, + rhs: constant_inputs[1].to_u128() as u32, + output: constant_outputs[0].to_u128() as u32, + }, + BlackBoxFunc::BigIntFromLeBytes => BlackBoxFuncCall::BigIntFromLeBytes { + inputs: inputs[0].clone(), + modulus: vecmap(constant_inputs, |c| c.to_u128() as u8), + output: constant_outputs[0].to_u128() as u32, + }, + BlackBoxFunc::BigIntToLeBytes => BlackBoxFuncCall::BigIntToLeBytes { + input: constant_inputs[0].to_u128() as u32, + outputs, + }, + BlackBoxFunc::Poseidon2Permutation => BlackBoxFuncCall::Poseidon2Permutation { + inputs: inputs[0].clone(), + outputs, + len: constant_inputs[0].to_u128() as u32, + }, + BlackBoxFunc::Sha256Compression => BlackBoxFuncCall::Sha256Compression { + inputs: inputs[0].clone(), + hash_values: inputs[1].clone(), + outputs, + }, }; self.push_opcode(AcirOpcode::BlackBoxFuncCall(black_box_func_call)); @@ -573,6 +608,7 @@ fn black_box_func_expected_input_size(name: BlackBoxFunc) -> Option { match name { // Bitwise opcodes will take in 2 parameters BlackBoxFunc::AND | BlackBoxFunc::XOR => Some(2), + // All of the hash/cipher methods will take in a // variable number of inputs. BlackBoxFunc::Keccak256 @@ -583,7 +619,11 @@ fn black_box_func_expected_input_size(name: BlackBoxFunc) -> Option { | BlackBoxFunc::PedersenHash => None, BlackBoxFunc::Keccakf1600 => Some(25), + // The permutation takes a fixed number of inputs, but the inputs length depends on the proving system implementation. + BlackBoxFunc::Poseidon2Permutation => None, + // SHA256 compression requires 16 u32s as input message and 8 u32s for the hash state. + BlackBoxFunc::Sha256Compression => Some(24), // Can only apply a range constraint to one // witness at a time. BlackBoxFunc::RANGE => Some(1), @@ -593,15 +633,26 @@ fn black_box_func_expected_input_size(name: BlackBoxFunc) -> Option { BlackBoxFunc::SchnorrVerify | BlackBoxFunc::EcdsaSecp256k1 | BlackBoxFunc::EcdsaSecp256r1 => None, + // Inputs for fixed based scalar multiplication // is the low and high limbs of the scalar BlackBoxFunc::FixedBaseScalarMul => Some(2), + // Recursive aggregation has a variable number of inputs BlackBoxFunc::RecursiveAggregation => None, + // Addition over the embedded curve: input are coordinates (x1,y1) and (x2,y2) of the Grumpkin points BlackBoxFunc::EmbeddedCurveAdd => Some(4), - // Doubling over the embedded curve: input is (x,y) coordinate of the point. - BlackBoxFunc::EmbeddedCurveDouble => Some(2), + + // Big integer operations take in 0 inputs. They use constants for their inputs. + BlackBoxFunc::BigIntAdd + | BlackBoxFunc::BigIntNeg + | BlackBoxFunc::BigIntMul + | BlackBoxFunc::BigIntDiv + | BlackBoxFunc::BigIntToLeBytes => Some(0), + + // FromLeBytes takes a variable array of bytes as input + BlackBoxFunc::BigIntFromLeBytes => None, } } @@ -612,28 +663,47 @@ fn black_box_expected_output_size(name: BlackBoxFunc) -> Option { // Bitwise opcodes will return 1 parameter which is the output // or the operation. BlackBoxFunc::AND | BlackBoxFunc::XOR => Some(1), + // 32 byte hash algorithms BlackBoxFunc::Keccak256 | BlackBoxFunc::SHA256 | BlackBoxFunc::Blake2s | BlackBoxFunc::Blake3 => Some(32), + BlackBoxFunc::Keccakf1600 => Some(25), + // The permutation returns a fixed number of outputs, equals to the inputs length which depends on the proving system implementation. + BlackBoxFunc::Poseidon2Permutation => None, + + BlackBoxFunc::Sha256Compression => Some(8), // Pedersen commitment returns a point BlackBoxFunc::PedersenCommitment => Some(2), + // Pedersen hash returns a field BlackBoxFunc::PedersenHash => Some(1), + // Can only apply a range constraint to one // witness at a time. BlackBoxFunc::RANGE => Some(0), + // Signature verification algorithms will return a boolean BlackBoxFunc::SchnorrVerify | BlackBoxFunc::EcdsaSecp256k1 | BlackBoxFunc::EcdsaSecp256r1 => Some(1), + // Output of operations over the embedded curve // will be 2 field elements representing the point. - BlackBoxFunc::FixedBaseScalarMul - | BlackBoxFunc::EmbeddedCurveAdd - | BlackBoxFunc::EmbeddedCurveDouble => Some(2), + BlackBoxFunc::FixedBaseScalarMul | BlackBoxFunc::EmbeddedCurveAdd => Some(2), + + // Big integer operations return a big integer + BlackBoxFunc::BigIntAdd + | BlackBoxFunc::BigIntNeg + | BlackBoxFunc::BigIntMul + | BlackBoxFunc::BigIntDiv + | BlackBoxFunc::BigIntFromLeBytes => Some(0), + + // ToLeBytes returns a variable array of bytes + BlackBoxFunc::BigIntToLeBytes => None, + // Recursive aggregation has a variable number of outputs BlackBoxFunc::RecursiveAggregation => None, } @@ -690,5 +760,5 @@ fn intrinsics_check_outputs(name: BlackBoxFunc, output_count: usize) { None => return, }; - assert_eq!(expected_num_outputs,output_count,"Tried to call black box function {name} with {output_count} inputs, but this function's definition requires {expected_num_outputs} inputs"); + assert_eq!(expected_num_outputs,output_count,"Tried to call black box function {name} with {output_count} outputs, but this function's definition requires {expected_num_outputs} outputs"); } diff --git a/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs b/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs index d832b8d0fbb..120c5bf25df 100644 --- a/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs +++ b/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs @@ -1541,7 +1541,7 @@ impl Context { let vars = self.acir_context.black_box_function(black_box, inputs, output_count)?; - Ok(Self::convert_vars_to_values(vars, dfg, result_ids)) + Ok(self.convert_vars_to_values(vars, dfg, result_ids)) } Intrinsic::ApplyRangeConstraint => { unreachable!("ICE: `Intrinsic::ApplyRangeConstraint` calls should be transformed into an `Instruction::RangeCheck`"); @@ -1588,7 +1588,7 @@ impl Context { .sort(input_vars, bit_size, self.current_side_effects_enabled_var) .expect("Could not sort"); - Ok(Self::convert_vars_to_values(out_vars, dfg, result_ids)) + Ok(self.convert_vars_to_values(out_vars, dfg, result_ids)) } Intrinsic::ArrayLen => { let len = match self.convert_value(arguments[0], dfg) { @@ -2101,16 +2101,35 @@ impl Context { /// Convert a Vec into a Vec using the given result ids. /// If the type of a result id is an array, several acir vars are collected into /// a single AcirValue::Array of the same length. + /// If the type of a result id is a slice, the slice length must precede it and we can + /// convert to an AcirValue::Array when the length is known (constant). fn convert_vars_to_values( + &self, vars: Vec, dfg: &DataFlowGraph, result_ids: &[ValueId], ) -> Vec { let mut vars = vars.into_iter(); - vecmap(result_ids, |result| { + let mut values: Vec = Vec::new(); + for result in result_ids { let result_type = dfg.type_of_value(*result); - Self::convert_var_type_to_values(&result_type, &mut vars) - }) + if let Type::Slice(elements_type) = result_type { + let error = "ICE - cannot get slice length when converting slice to AcirValue"; + let len = values.last().expect(error).borrow_var().expect(error); + let len = self.acir_context.constant(len).to_u128(); + let mut element_values = im::Vector::new(); + for _ in 0..len { + for element_type in elements_type.iter() { + let element = Self::convert_var_type_to_values(element_type, &mut vars); + element_values.push_back(element); + } + } + values.push(AcirValue::Array(element_values)); + } else { + values.push(Self::convert_var_type_to_values(&result_type, &mut vars)); + } + } + values } /// Recursive helper for convert_vars_to_values. diff --git a/compiler/noirc_evaluator/src/ssa/ir/instruction/call.rs b/compiler/noirc_evaluator/src/ssa/ir/instruction/call.rs index d1991abab37..0178ae9dba1 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/instruction/call.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/instruction/call.rs @@ -417,7 +417,7 @@ fn simplify_black_box_func( _ => SimplifyResult::None, } } - + BlackBoxFunc::Poseidon2Permutation => SimplifyResult::None, //TODO(Guillaume) BlackBoxFunc::EcdsaSecp256k1 => { simplify_signature(dfg, arguments, acvm::blackbox_solver::ecdsa_secp256k1_verify) } @@ -429,13 +429,17 @@ fn simplify_black_box_func( | BlackBoxFunc::SchnorrVerify | BlackBoxFunc::PedersenCommitment | BlackBoxFunc::PedersenHash - | BlackBoxFunc::EmbeddedCurveAdd - | BlackBoxFunc::EmbeddedCurveDouble => { + | BlackBoxFunc::EmbeddedCurveAdd => { // Currently unsolvable here as we rely on an implementation in the backend. SimplifyResult::None } - - BlackBoxFunc::RecursiveAggregation => SimplifyResult::None, + BlackBoxFunc::BigIntAdd + | BlackBoxFunc::BigIntNeg + | BlackBoxFunc::BigIntMul + | BlackBoxFunc::BigIntDiv + | BlackBoxFunc::RecursiveAggregation + | BlackBoxFunc::BigIntFromLeBytes + | BlackBoxFunc::BigIntToLeBytes => SimplifyResult::None, BlackBoxFunc::AND => { unreachable!("ICE: `BlackBoxFunc::AND` calls should be transformed into a `BinaryOp`") @@ -448,6 +452,7 @@ fn simplify_black_box_func( "ICE: `BlackBoxFunc::RANGE` calls should be transformed into a `Instruction::Cast`" ) } + BlackBoxFunc::Sha256Compression => SimplifyResult::None, //TODO(Guillaume) } } diff --git a/noir_stdlib/src/bigint.nr b/noir_stdlib/src/bigint.nr new file mode 100644 index 00000000000..14790f69241 --- /dev/null +++ b/noir_stdlib/src/bigint.nr @@ -0,0 +1,53 @@ +use crate::ops::{Add, Sub, Mul, Div, Rem,}; + +struct BigInt { + pointer: u32, + modulus: u32, +} + +impl BigInt { + #[builtin(bigint_add)] + pub fn bigint_add(_self: Self, _other: BigInt) -> BigInt { + } + #[builtin(bigint_neg)] + pub fn bigint_neg(_self: Self, _other: BigInt) -> BigInt { + } + #[builtin(bigint_mul)] + pub fn bigint_mul(_self: Self, _other: BigInt) -> BigInt { + } + #[builtin(bigint_div)] + pub fn bigint_div(_self: Self, _other: BigInt) -> BigInt { + } + #[builtin(bigint_from_le_bytes)] + pub fn from_le_bytes(_bytes: [u8], _modulus: [u8]) -> BigInt {} + #[builtin(bigint_to_le_bytes)] + pub fn to_le_bytes(_self: Self) -> [u8] {} +} + +impl Add for BigInt { + fn add(self: Self, other: BigInt) -> BigInt { + self.bigint_add(other) + } +} +impl Sub for BigInt { + fn sub(self: Self, other: BigInt) -> BigInt { + self.bigint_neg(other) + } +} +impl Mul for BigInt { + fn mul(self: Self, other: BigInt) -> BigInt { + self.bigint_mul(other) + } +} +impl Div for BigInt { + fn div(self: Self, other: BigInt) -> BigInt { + self.bigint_div(other) + } +} +impl Rem for BigInt { + fn rem(self: Self, other: BigInt) -> BigInt { + let quotient = self.bigint_div(other); + self.bigint_neg(quotient.bigint_mul(other)) + } +} + diff --git a/noir_stdlib/src/hash.nr b/noir_stdlib/src/hash.nr index 09154038f4e..4033e2a5365 100644 --- a/noir_stdlib/src/hash.nr +++ b/noir_stdlib/src/hash.nr @@ -69,3 +69,8 @@ pub fn keccak256(_input: [u8; N], _message_size: u32) -> [u8; 32] // docs:end:keccak256 {} +#[foreign(poseidon2_permutation)] +pub fn poseidon2_permutation(_input: [u8; N], _state_length: u32) -> [u8; N] {} + +#[foreign(sha256_compression)] +pub fn sha256_compression(_input: [u32; 16], _state: [u32; 8]) -> [u32; 8] {} diff --git a/noir_stdlib/src/lib.nr b/noir_stdlib/src/lib.nr index b86834712a6..90aff3c312b 100644 --- a/noir_stdlib/src/lib.nr +++ b/noir_stdlib/src/lib.nr @@ -25,6 +25,7 @@ mod ops; mod default; mod prelude; mod uint128; +// mod bigint; // Oracle calls are required to be wrapped in an unconstrained function // Thus, the only argument to the `println` oracle is expected to always be an ident diff --git a/noir_stdlib/src/scalar_mul.nr b/noir_stdlib/src/scalar_mul.nr index c045e72d400..0e84b4f66fc 100644 --- a/noir_stdlib/src/scalar_mul.nr +++ b/noir_stdlib/src/scalar_mul.nr @@ -1,3 +1,22 @@ +use crate::ops::Add; + +struct EmbeddedCurvePoint { + x: Field, + y: Field, +} + +impl EmbeddedCurvePoint { + fn double(self) -> EmbeddedCurvePoint { + embedded_curve_add(self, self) + } +} + +impl Add for EmbeddedCurvePoint { + fn add(self, other: EmbeddedCurvePoint) -> EmbeddedCurvePoint { + embedded_curve_add(self, other) + } +} + // Computes a fixed base scalar multiplication over the embedded curve. // For bn254, We have Grumpkin and Baby JubJub. // For bls12-381, we have JubJub and Bandersnatch. @@ -12,3 +31,6 @@ pub fn fixed_base_embedded_curve( ) -> [Field; 2] // docs:end:fixed_base_embedded_curve {} + +#[foreign(embedded_curve_add)] +fn embedded_curve_add(_point1: EmbeddedCurvePoint, _point2: EmbeddedCurvePoint) -> EmbeddedCurvePoint {} diff --git a/test_programs/execution_success/scalar_mul/src/main.nr b/test_programs/execution_success/scalar_mul/src/main.nr index 2ddf22cf71e..e20f47907db 100644 --- a/test_programs/execution_success/scalar_mul/src/main.nr +++ b/test_programs/execution_success/scalar_mul/src/main.nr @@ -20,4 +20,12 @@ fn main( let res = std::scalar_mul::fixed_base_embedded_curve(priv_key, 0); assert(res[0] == pub_x); assert(res[1] == pub_y); + let pub_point= std::scalar_mul::EmbeddedCurvePoint { x: pub_x, y: pub_y }; + let g1_y = 17631683881184975370165255887551781615748388533673675138860; + let g1= std::scalar_mul::EmbeddedCurvePoint { x: 1, y: g1_y }; + + let res = pub_point.double(); + let double = g1.add(g1); + + assert(double.x == res.x); } diff --git a/tooling/backend_interface/src/cli/mod.rs b/tooling/backend_interface/src/cli/mod.rs index 3ea65f28103..b4dec859839 100644 --- a/tooling/backend_interface/src/cli/mod.rs +++ b/tooling/backend_interface/src/cli/mod.rs @@ -1,4 +1,4 @@ -// Reference: https://github.com/AztecProtocol/aztec-packages/blob/master/circuits/cpp/barretenberg/cpp/src/barretenberg/bb/main.cpp +// Reference: https://github.com/AztecProtocol/aztec-packages/blob/master/barretenberg/cpp/src/barretenberg/bb/main.cpp mod contract; mod gates; diff --git a/tooling/bb_abstraction_leaks/build.rs b/tooling/bb_abstraction_leaks/build.rs index 18413f87793..6197f52cb4b 100644 --- a/tooling/bb_abstraction_leaks/build.rs +++ b/tooling/bb_abstraction_leaks/build.rs @@ -10,7 +10,7 @@ use const_format::formatcp; const USERNAME: &str = "AztecProtocol"; const REPO: &str = "aztec-packages"; -const VERSION: &str = "0.19.0"; +const VERSION: &str = "0.21.0"; const TAG: &str = formatcp!("aztec-packages-v{}", VERSION); const API_URL: &str = diff --git a/tooling/lsp/src/solver.rs b/tooling/lsp/src/solver.rs index 6217b7ad71f..f001cebaa4d 100644 --- a/tooling/lsp/src/solver.rs +++ b/tooling/lsp/src/solver.rs @@ -49,12 +49,4 @@ impl BlackBoxFunctionSolver for WrapperSolver { ) -> Result<(acvm::FieldElement, acvm::FieldElement), acvm::BlackBoxResolutionError> { self.0.ec_add(input1_x, input1_y, input2_x, input2_y) } - - fn ec_double( - &self, - input_x: &acvm::FieldElement, - input_y: &acvm::FieldElement, - ) -> Result<(acvm::FieldElement, acvm::FieldElement), acvm::BlackBoxResolutionError> { - self.0.ec_double(input_x, input_y) - } } diff --git a/tooling/noir_js_backend_barretenberg/package.json b/tooling/noir_js_backend_barretenberg/package.json index cd2a6354ac4..a0123883efd 100644 --- a/tooling/noir_js_backend_barretenberg/package.json +++ b/tooling/noir_js_backend_barretenberg/package.json @@ -42,7 +42,7 @@ "lint": "NODE_NO_WARNINGS=1 eslint . --ext .ts --ignore-path ./.eslintignore --max-warnings 0" }, "dependencies": { - "@aztec/bb.js": "0.19.0", + "@aztec/bb.js": "0.21.0", "@noir-lang/types": "workspace:*", "fflate": "^0.8.0" }, diff --git a/yarn.lock b/yarn.lock index db3f493bc62..743068f1907 100644 --- a/yarn.lock +++ b/yarn.lock @@ -235,9 +235,9 @@ __metadata: languageName: node linkType: hard -"@aztec/bb.js@npm:0.19.0": - version: 0.19.0 - resolution: "@aztec/bb.js@npm:0.19.0" +"@aztec/bb.js@npm:0.21.0": + version: 0.21.0 + resolution: "@aztec/bb.js@npm:0.21.0" dependencies: comlink: ^4.4.1 commander: ^10.0.1 @@ -245,7 +245,7 @@ __metadata: tslib: ^2.4.0 bin: bb.js: dest/node/main.js - checksum: c78c22c3b8c43e0010a43145f973489aa7da9fcf0b8527884107f1f34ac3ca5f5d4ab087d74ce50cb75d6dbaef88bfc693e23745282faa30b81dc78481c65874 + checksum: a0fb97476f52025f3c31b7a5e890966ac375ed47c5cfd3434f5c3e4265af3c7566a162f37d6c56f394f44bfe4ba67e5002b7c5998ecc4f6abe70e04f5b8abe34 languageName: node linkType: hard @@ -4435,7 +4435,7 @@ __metadata: version: 0.0.0-use.local resolution: "@noir-lang/backend_barretenberg@workspace:tooling/noir_js_backend_barretenberg" dependencies: - "@aztec/bb.js": 0.19.0 + "@aztec/bb.js": 0.21.0 "@noir-lang/types": "workspace:*" "@types/node": ^20.6.2 "@types/prettier": ^3 From f4de6ee0e9675f78522a89b367a14c2a76523b97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Pedro=20Sousa?= Date: Tue, 30 Jan 2024 15:09:58 +0000 Subject: [PATCH 53/70] chore(docs): updating docs to match new recursion interfacee (#4187) # Description This PR documents the new recursion interface. ## Problem\* Resolves #4139 Resolves AztecProtocol/dev-rel#148 ## Summary\* - Removes the usage of `aggregation object` while retaining the mention that recursive proofs are actually aggregation of proofs - Removes the mention to add the size of public inputs to the proof, as they are now separate - Removes some leftover explainer in the `verify_proof` reference ## Additional Context `noir-examples` is actually not working with this new interface, as I'm blocked by a weird issue where proofs give me my dear friend `unreachable` Will debug that next week with @TomAFrench but I think we're good to push the docs for now. --------- Co-authored-by: Cat McGee --- docs/docs/explainers/explainer-recursion.md | 23 +++++---- docs/docs/how_to/how-to-recursion.md | 21 ++++---- docs/docs/noir/standard_library/recursion.md | 48 +++++-------------- .../explainers/explainer-recursion.md | 23 +++++---- .../how_to/how-to-recursion.md | 21 ++++---- .../noir/standard_library/recursion.md | 48 +++++-------------- 6 files changed, 64 insertions(+), 120 deletions(-) diff --git a/docs/docs/explainers/explainer-recursion.md b/docs/docs/explainers/explainer-recursion.md index 8f992ec29fd..18846176ca7 100644 --- a/docs/docs/explainers/explainer-recursion.md +++ b/docs/docs/explainers/explainer-recursion.md @@ -16,12 +16,13 @@ keywords: "Optimizing Computational Resources", "Improving Efficiency", "Verification Key", - "Aggregation Objects", + "Aggregation", "Recursive zkSNARK schemes", "PLONK", "Proving and Verification Keys" ] sidebar_position: 1 +pagination_next: how_to/how-to-recursion --- In programming, we tend to think of recursion as something calling itself. A classic example would be the calculation of the factorial of a number: @@ -64,7 +65,7 @@ So, they use zero-knowledge proofs. Alice tries to guess Bob's number, and Bob w This ZK proof can go on a smart contract, revealing the winner and even giving prizes. However, this means every turn needs to be verified on-chain. This incurs some cost and waiting time that may simply make the game too expensive or time-consuming to be worth it. -As a solution, Alice proposes the following: "what if Bob generates his proof, and instead of sending it on-chain, I verify it *within* my own proof before playing my own turn?". +As a solution, Alice proposes the following: "what if Bob generates his proof, and instead of sending it on-chain, I verify it *within* my own proof before playing my own turn?". She can then generate a proof that she verified his proof, and so on. @@ -116,25 +117,19 @@ As you can see in the [recursion reference](noir/standard_library/recursion.md), - The Verification Key of the circuit that generated the proof - A hash of this verification key, as it's needed for some backends - The public inputs for the proof -- The input aggregation object -It also returns the `output aggregation object`. These aggregation objects can be confusing at times, so let's dive in a little bit. - -### Aggregation objects +:::info Recursive zkSNARK schemes do not necessarily "verify a proof" in the sense that you expect a true or false to be spit out by the verifier. Rather an aggregation object is built over the public inputs. -In the case of PLONK the recursive aggregation object is two G1 points (expressed as 16 witness values). The final verifier (in our case this is most often the smart contract verifier) has to be aware of this aggregation object to execute a pairing and check the validity of these points. - So, taking the example of Alice and Bob and their guessing game: - Alice makes her guess. Her proof is *not* recursive: it doesn't verify any proof within it! It's just a standard `assert(x != y)` circuit -- Bob verifies Alice's proof and makes his own guess. In this circuit, he is verifying a proof, so it needs to output an `aggregation object`: he is generating a recursive proof! -- Alice verifies Bob's *recursive proof*, and uses Bob's `output aggregation object` as the `input aggregation object` in her proof... Which in turn, generates another `output aggregation object`. +- Bob verifies Alice's proof and makes his own guess. In this circuit, he doesn't exactly *prove* the verification of Alice's proof. Instead, he *aggregates* his proof to Alice's proof. The actual verification is done when the full proof is verified, for example when using `nargo verify` or through the verifier smart contract. -One should notice that when Bob generates his first proof, he has no input aggregation object. Because he is not verifying an recursive proof, he has no `input aggregation object`. In this case, he may use zeros instead. +We can imagine recursive proofs a [relay race](https://en.wikipedia.org/wiki/Relay_race). The first runner doesn't have to receive the baton from anyone else, as he/she already starts with it. But when his/her turn is over, the next runner needs to receive it, run a bit more, and pass it along. Even though every runner could theoretically verify the baton mid-run (why not? 🏃🔍), only at the end of the race does the referee verify that the whole race is valid. -We can imagine the `aggregation object` as the baton in a [relay race](https://en.wikipedia.org/wiki/Relay_race). The first runner doesn't have to receive the baton from anyone else, as he/she already starts with it. But when his/her turn is over, the next runner needs to receive it, run a bit more, and pass it along. Even though every runner could theoretically verify the baton mid-run (why not? 🏃🔍), only at the end of the race does the referee verify that the whole race is valid. +::: ## Some architecture @@ -175,3 +170,7 @@ In this example, a regulator could verify that taxes were paid for a specific pu At the time of writing, verifying recursive proofs is surprisingly fast. This is because most of the time is spent on generating the verification key that will be used to generate the next proof. So you are able to cache the verification key and reuse it later. Currently, Noir JS packages don't expose the functionality of loading proving and verification keys, but that feature exists in the underlying `bb.js` package. + +## How can I try it + +Learn more about using recursion in Nargo and NoirJS in the [how-to guide](../how_to/how-to-recursion.md) and see a full example in [noir-examples](https://github.com/noir-lang/noir-examples). diff --git a/docs/docs/how_to/how-to-recursion.md b/docs/docs/how_to/how-to-recursion.md index 39db23f1f3a..f34647a99d5 100644 --- a/docs/docs/how_to/how-to-recursion.md +++ b/docs/docs/how_to/how-to-recursion.md @@ -108,11 +108,7 @@ This call takes the public inputs and the proof, but also the public inputs coun :::info -The `proofAsFields` has a constant size `[Field; 93]`. However, currently the backend doesn't remove the public inputs from the proof when converting it. - -This means that if your `main` circuit has two public inputs, then you should also modify the recursive circuit to accept a proof with the public inputs appended. This means that in our example, since `y` is a public input, our `proofAsFields` is of type `[Field; 94]`. - -Verification keys in Barretenberg are always of size 114. +The `proofAsFields` has a constant size `[Field; 93]` and verification keys in Barretenberg are always `[Field; 114]`. ::: @@ -136,7 +132,6 @@ const recursiveInputs = { proof: proofAsFields, // array of length 93 + size of public inputs publicInputs: [mainInput.y], // using the example above, where `y` is the only public input key_hash: vkHash, - input_aggregation_object: Array(16).fill(0) // this circuit is verifying a non-recursive proof, so there's no input aggregation object: just use zero } const { witness, returnValue } = noir.execute(recursiveInputs) // we're executing the recursive circuit now! @@ -144,7 +139,7 @@ const { proof, publicInputs } = backend.generateFinalProof(witness) const verified = backend.verifyFinalProof({ proof, publicInputs }) ``` -You can obviously chain this proof into another proof. In fact, if you're using recursive proofs, you're probably interested of using them this way! In that case, you should keep in mind the `returnValue`, as it will contain the `input_aggregation_object` for the next proof. +You can obviously chain this proof into another proof. In fact, if you're using recursive proofs, you're probably interested of using them this way! :::tip @@ -152,16 +147,16 @@ Managing circuits and "who does what" can be confusing. To make sure your naming ```js const circuits = { -main: mainJSON, -recursive: recursiveJSON + main: mainJSON, + recursive: recursiveJSON } const backends = { -main: new BarretenbergBackend(circuits.main), -recursive: new BarretenbergBackend(circuits.recursive) + main: new BarretenbergBackend(circuits.main), + recursive: new BarretenbergBackend(circuits.recursive) } const noir_programs = { -main: new Noir(circuits.main, backends.main), -recursive: new Noir(circuits.recursive, backends.recursive) + main: new Noir(circuits.main, backends.main), + recursive: new Noir(circuits.recursive, backends.recursive) } ``` diff --git a/docs/docs/noir/standard_library/recursion.md b/docs/docs/noir/standard_library/recursion.md index 67962082a8f..f252150c8b5 100644 --- a/docs/docs/noir/standard_library/recursion.md +++ b/docs/docs/noir/standard_library/recursion.md @@ -1,16 +1,16 @@ --- title: Recursive Proofs description: Learn about how to write recursive proofs in Noir. -keywords: [recursion, recursive proofs, verification_key, aggregation object, verify_proof] +keywords: [recursion, recursive proofs, verification_key, verify_proof] --- Noir supports recursively verifying proofs, meaning you verify the proof of a Noir program in another Noir program. This enables creating proofs of arbitrary size by doing step-wise verification of smaller components of a large proof. -The `verify_proof` function takes a verification key, proof and public inputs for a zk program, as well as a key hash and an input aggregation object. The key hash is used to check the validity of the verification key and the input aggregation object is required by some proving systems. The `verify_proof` function returns an output aggregation object that can then be fed into future iterations of the proof verification if required. +Read [the explainer on recursion](../../explainers/explainer-recursion.md) to know more about this function and the [guide on how to use it.](../../how_to/how-to-recursion.md) ```rust #[foreign(verify_proof)] -fn verify_proof(_verification_key : [Field], _proof : [Field], _public_input : Field, _key_hash : Field, _input_aggregation_object : [Field]) -> [Field] {} +fn verify_proof(_verification_key : [Field], _proof : [Field], _public_input : Field, _key_hash : Field) {} ``` :::info @@ -26,36 +26,29 @@ use dep::std; fn main( verification_key : [Field; 114], - proof : [Field; 94], + proof : [Field; 93], public_inputs : [Field; 1], key_hash : Field, - input_aggregation_object : [Field; 16], - proof_b : [Field; 94], -) -> pub [Field; 16] { - let output_aggregation_object_a = std::verify_proof( + proof_b : [Field; 93], +) { + std::verify_proof( verification_key.as_slice(), proof.as_slice(), public_inputs.as_slice(), - key_hash, - input_aggregation_object + key_hash ); - let output_aggregation_object = std::verify_proof( + std::verify_proof( verification_key.as_slice(), proof_b.as_slice(), public_inputs.as_slice(), - key_hash, - output_aggregation_object_a + key_hash ); - - let mut output = [0; 16]; - for i in 0..16 { - output[i] = output_aggregation_object[i]; - } - output } ``` +You can see a full example of recursive proofs in [this example recursion demo repo](https://github.com/noir-lang/noir-examples/tree/master/recursion). + ## Parameters ### `verification_key` @@ -68,23 +61,8 @@ The proof for the zk program that is being verified. ### `public_inputs` -These represent the public inputs of the proof we are verifying. They should be checked against in the circuit after construction of a new aggregation state. +These represent the public inputs of the proof we are verifying. ### `key_hash` A key hash is used to check the validity of the verification key. The circuit implementing this opcode can use this hash to ensure that the key provided to the circuit matches the key produced by the circuit creator. - -### `input_aggregation_object` - -An aggregation object is blob of data that the top-level verifier must run some proof system specific algorithm on to complete verification. The size is proof system specific and will be set by the backend integrating this opcode. The input aggregation object is only not `None` when we are verifying a previous recursive aggregation in the current circuit. If this is the first recursive aggregation there is no input aggregation object. It is left to the backend to determine how to handle when there is no input aggregation object. - -## Return value - -### `output_aggregation_object` - -This is the result of a recursive aggregation and is what will be fed into the next verifier. -The next verifier can either perform a final verification (returning true or false) or perform another recursive aggregation where this output aggregation object will be the input aggregation object of the next recursive aggregation. - -## Example - -You can see an example of how to do recursive proofs in [this example recursion demo repo](https://github.com/noir-lang/noir-examples/tree/master/recursion). diff --git a/docs/versioned_docs/version-v0.23.0/explainers/explainer-recursion.md b/docs/versioned_docs/version-v0.23.0/explainers/explainer-recursion.md index 8f992ec29fd..18846176ca7 100644 --- a/docs/versioned_docs/version-v0.23.0/explainers/explainer-recursion.md +++ b/docs/versioned_docs/version-v0.23.0/explainers/explainer-recursion.md @@ -16,12 +16,13 @@ keywords: "Optimizing Computational Resources", "Improving Efficiency", "Verification Key", - "Aggregation Objects", + "Aggregation", "Recursive zkSNARK schemes", "PLONK", "Proving and Verification Keys" ] sidebar_position: 1 +pagination_next: how_to/how-to-recursion --- In programming, we tend to think of recursion as something calling itself. A classic example would be the calculation of the factorial of a number: @@ -64,7 +65,7 @@ So, they use zero-knowledge proofs. Alice tries to guess Bob's number, and Bob w This ZK proof can go on a smart contract, revealing the winner and even giving prizes. However, this means every turn needs to be verified on-chain. This incurs some cost and waiting time that may simply make the game too expensive or time-consuming to be worth it. -As a solution, Alice proposes the following: "what if Bob generates his proof, and instead of sending it on-chain, I verify it *within* my own proof before playing my own turn?". +As a solution, Alice proposes the following: "what if Bob generates his proof, and instead of sending it on-chain, I verify it *within* my own proof before playing my own turn?". She can then generate a proof that she verified his proof, and so on. @@ -116,25 +117,19 @@ As you can see in the [recursion reference](noir/standard_library/recursion.md), - The Verification Key of the circuit that generated the proof - A hash of this verification key, as it's needed for some backends - The public inputs for the proof -- The input aggregation object -It also returns the `output aggregation object`. These aggregation objects can be confusing at times, so let's dive in a little bit. - -### Aggregation objects +:::info Recursive zkSNARK schemes do not necessarily "verify a proof" in the sense that you expect a true or false to be spit out by the verifier. Rather an aggregation object is built over the public inputs. -In the case of PLONK the recursive aggregation object is two G1 points (expressed as 16 witness values). The final verifier (in our case this is most often the smart contract verifier) has to be aware of this aggregation object to execute a pairing and check the validity of these points. - So, taking the example of Alice and Bob and their guessing game: - Alice makes her guess. Her proof is *not* recursive: it doesn't verify any proof within it! It's just a standard `assert(x != y)` circuit -- Bob verifies Alice's proof and makes his own guess. In this circuit, he is verifying a proof, so it needs to output an `aggregation object`: he is generating a recursive proof! -- Alice verifies Bob's *recursive proof*, and uses Bob's `output aggregation object` as the `input aggregation object` in her proof... Which in turn, generates another `output aggregation object`. +- Bob verifies Alice's proof and makes his own guess. In this circuit, he doesn't exactly *prove* the verification of Alice's proof. Instead, he *aggregates* his proof to Alice's proof. The actual verification is done when the full proof is verified, for example when using `nargo verify` or through the verifier smart contract. -One should notice that when Bob generates his first proof, he has no input aggregation object. Because he is not verifying an recursive proof, he has no `input aggregation object`. In this case, he may use zeros instead. +We can imagine recursive proofs a [relay race](https://en.wikipedia.org/wiki/Relay_race). The first runner doesn't have to receive the baton from anyone else, as he/she already starts with it. But when his/her turn is over, the next runner needs to receive it, run a bit more, and pass it along. Even though every runner could theoretically verify the baton mid-run (why not? 🏃🔍), only at the end of the race does the referee verify that the whole race is valid. -We can imagine the `aggregation object` as the baton in a [relay race](https://en.wikipedia.org/wiki/Relay_race). The first runner doesn't have to receive the baton from anyone else, as he/she already starts with it. But when his/her turn is over, the next runner needs to receive it, run a bit more, and pass it along. Even though every runner could theoretically verify the baton mid-run (why not? 🏃🔍), only at the end of the race does the referee verify that the whole race is valid. +::: ## Some architecture @@ -175,3 +170,7 @@ In this example, a regulator could verify that taxes were paid for a specific pu At the time of writing, verifying recursive proofs is surprisingly fast. This is because most of the time is spent on generating the verification key that will be used to generate the next proof. So you are able to cache the verification key and reuse it later. Currently, Noir JS packages don't expose the functionality of loading proving and verification keys, but that feature exists in the underlying `bb.js` package. + +## How can I try it + +Learn more about using recursion in Nargo and NoirJS in the [how-to guide](../how_to/how-to-recursion.md) and see a full example in [noir-examples](https://github.com/noir-lang/noir-examples). diff --git a/docs/versioned_docs/version-v0.23.0/how_to/how-to-recursion.md b/docs/versioned_docs/version-v0.23.0/how_to/how-to-recursion.md index 39db23f1f3a..f34647a99d5 100644 --- a/docs/versioned_docs/version-v0.23.0/how_to/how-to-recursion.md +++ b/docs/versioned_docs/version-v0.23.0/how_to/how-to-recursion.md @@ -108,11 +108,7 @@ This call takes the public inputs and the proof, but also the public inputs coun :::info -The `proofAsFields` has a constant size `[Field; 93]`. However, currently the backend doesn't remove the public inputs from the proof when converting it. - -This means that if your `main` circuit has two public inputs, then you should also modify the recursive circuit to accept a proof with the public inputs appended. This means that in our example, since `y` is a public input, our `proofAsFields` is of type `[Field; 94]`. - -Verification keys in Barretenberg are always of size 114. +The `proofAsFields` has a constant size `[Field; 93]` and verification keys in Barretenberg are always `[Field; 114]`. ::: @@ -136,7 +132,6 @@ const recursiveInputs = { proof: proofAsFields, // array of length 93 + size of public inputs publicInputs: [mainInput.y], // using the example above, where `y` is the only public input key_hash: vkHash, - input_aggregation_object: Array(16).fill(0) // this circuit is verifying a non-recursive proof, so there's no input aggregation object: just use zero } const { witness, returnValue } = noir.execute(recursiveInputs) // we're executing the recursive circuit now! @@ -144,7 +139,7 @@ const { proof, publicInputs } = backend.generateFinalProof(witness) const verified = backend.verifyFinalProof({ proof, publicInputs }) ``` -You can obviously chain this proof into another proof. In fact, if you're using recursive proofs, you're probably interested of using them this way! In that case, you should keep in mind the `returnValue`, as it will contain the `input_aggregation_object` for the next proof. +You can obviously chain this proof into another proof. In fact, if you're using recursive proofs, you're probably interested of using them this way! :::tip @@ -152,16 +147,16 @@ Managing circuits and "who does what" can be confusing. To make sure your naming ```js const circuits = { -main: mainJSON, -recursive: recursiveJSON + main: mainJSON, + recursive: recursiveJSON } const backends = { -main: new BarretenbergBackend(circuits.main), -recursive: new BarretenbergBackend(circuits.recursive) + main: new BarretenbergBackend(circuits.main), + recursive: new BarretenbergBackend(circuits.recursive) } const noir_programs = { -main: new Noir(circuits.main, backends.main), -recursive: new Noir(circuits.recursive, backends.recursive) + main: new Noir(circuits.main, backends.main), + recursive: new Noir(circuits.recursive, backends.recursive) } ``` diff --git a/docs/versioned_docs/version-v0.23.0/noir/standard_library/recursion.md b/docs/versioned_docs/version-v0.23.0/noir/standard_library/recursion.md index 67962082a8f..f252150c8b5 100644 --- a/docs/versioned_docs/version-v0.23.0/noir/standard_library/recursion.md +++ b/docs/versioned_docs/version-v0.23.0/noir/standard_library/recursion.md @@ -1,16 +1,16 @@ --- title: Recursive Proofs description: Learn about how to write recursive proofs in Noir. -keywords: [recursion, recursive proofs, verification_key, aggregation object, verify_proof] +keywords: [recursion, recursive proofs, verification_key, verify_proof] --- Noir supports recursively verifying proofs, meaning you verify the proof of a Noir program in another Noir program. This enables creating proofs of arbitrary size by doing step-wise verification of smaller components of a large proof. -The `verify_proof` function takes a verification key, proof and public inputs for a zk program, as well as a key hash and an input aggregation object. The key hash is used to check the validity of the verification key and the input aggregation object is required by some proving systems. The `verify_proof` function returns an output aggregation object that can then be fed into future iterations of the proof verification if required. +Read [the explainer on recursion](../../explainers/explainer-recursion.md) to know more about this function and the [guide on how to use it.](../../how_to/how-to-recursion.md) ```rust #[foreign(verify_proof)] -fn verify_proof(_verification_key : [Field], _proof : [Field], _public_input : Field, _key_hash : Field, _input_aggregation_object : [Field]) -> [Field] {} +fn verify_proof(_verification_key : [Field], _proof : [Field], _public_input : Field, _key_hash : Field) {} ``` :::info @@ -26,36 +26,29 @@ use dep::std; fn main( verification_key : [Field; 114], - proof : [Field; 94], + proof : [Field; 93], public_inputs : [Field; 1], key_hash : Field, - input_aggregation_object : [Field; 16], - proof_b : [Field; 94], -) -> pub [Field; 16] { - let output_aggregation_object_a = std::verify_proof( + proof_b : [Field; 93], +) { + std::verify_proof( verification_key.as_slice(), proof.as_slice(), public_inputs.as_slice(), - key_hash, - input_aggregation_object + key_hash ); - let output_aggregation_object = std::verify_proof( + std::verify_proof( verification_key.as_slice(), proof_b.as_slice(), public_inputs.as_slice(), - key_hash, - output_aggregation_object_a + key_hash ); - - let mut output = [0; 16]; - for i in 0..16 { - output[i] = output_aggregation_object[i]; - } - output } ``` +You can see a full example of recursive proofs in [this example recursion demo repo](https://github.com/noir-lang/noir-examples/tree/master/recursion). + ## Parameters ### `verification_key` @@ -68,23 +61,8 @@ The proof for the zk program that is being verified. ### `public_inputs` -These represent the public inputs of the proof we are verifying. They should be checked against in the circuit after construction of a new aggregation state. +These represent the public inputs of the proof we are verifying. ### `key_hash` A key hash is used to check the validity of the verification key. The circuit implementing this opcode can use this hash to ensure that the key provided to the circuit matches the key produced by the circuit creator. - -### `input_aggregation_object` - -An aggregation object is blob of data that the top-level verifier must run some proof system specific algorithm on to complete verification. The size is proof system specific and will be set by the backend integrating this opcode. The input aggregation object is only not `None` when we are verifying a previous recursive aggregation in the current circuit. If this is the first recursive aggregation there is no input aggregation object. It is left to the backend to determine how to handle when there is no input aggregation object. - -## Return value - -### `output_aggregation_object` - -This is the result of a recursive aggregation and is what will be fed into the next verifier. -The next verifier can either perform a final verification (returning true or false) or perform another recursive aggregation where this output aggregation object will be the input aggregation object of the next recursive aggregation. - -## Example - -You can see an example of how to do recursive proofs in [this example recursion demo repo](https://github.com/noir-lang/noir-examples/tree/master/recursion). From dac0e87ee3be3446b92bbb12ef4832fd493fcee3 Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Tue, 30 Jan 2024 15:53:11 +0000 Subject: [PATCH 54/70] feat: remove replacement of boolean range opcodes with `AssertZero` opcodes (#4107) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit … # Description ## Problem\* Complement to https://github.com/AztecProtocol/aztec-packages/pull/4164. I'm going to leave this in draft until we've pushed out a release of `bb` containing the optimisation. This optimisation is being moved to be a responsibility of the backend so we shouldn't do it here. ## Summary\* ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- .../compiler/optimizers/redundant_range.rs | 72 +++++++------------ 1 file changed, 26 insertions(+), 46 deletions(-) diff --git a/acvm-repo/acvm/src/compiler/optimizers/redundant_range.rs b/acvm-repo/acvm/src/compiler/optimizers/redundant_range.rs index 5d19f9629ba..ecabd98b3b1 100644 --- a/acvm-repo/acvm/src/compiler/optimizers/redundant_range.rs +++ b/acvm-repo/acvm/src/compiler/optimizers/redundant_range.rs @@ -3,8 +3,7 @@ use acir::{ opcodes::{BlackBoxFuncCall, FunctionInput}, Circuit, Opcode, }, - native_types::{Expression, Witness}, - FieldElement, + native_types::Witness, }; use std::collections::{BTreeMap, HashSet}; @@ -105,9 +104,11 @@ impl RangeOptimizer { let mut new_order_list = Vec::with_capacity(order_list.len()); let mut optimized_opcodes = Vec::with_capacity(self.circuit.opcodes.len()); for (idx, opcode) in self.circuit.opcodes.into_iter().enumerate() { - let (witness, num_bits) = match extract_range_opcode(&opcode) { - Some(range_opcode) => range_opcode, - None => { + let (witness, num_bits) = match &opcode { + Opcode::BlackBoxFuncCall(BlackBoxFuncCall::RANGE { input }) => { + (input.witness, input.num_bits) + } + _ => { // If its not the range opcode, add it to the opcode // list and continue; optimized_opcodes.push(opcode); @@ -131,7 +132,7 @@ impl RangeOptimizer { if is_lowest_bit_size { already_seen_witness.insert(witness); new_order_list.push(order_list[idx]); - optimized_opcodes.push(optimized_range_opcode(witness, num_bits)); + optimized_opcodes.push(opcode); } } @@ -139,36 +140,11 @@ impl RangeOptimizer { } } -/// Extract the range opcode from the `Opcode` enum -/// Returns None, if `Opcode` is not the range opcode. -fn extract_range_opcode(opcode: &Opcode) -> Option<(Witness, u32)> { - match opcode { - Opcode::BlackBoxFuncCall(BlackBoxFuncCall::RANGE { input }) => { - Some((input.witness, input.num_bits)) - } - _ => None, - } -} - -fn optimized_range_opcode(witness: Witness, num_bits: u32) -> Opcode { - if num_bits == 1 { - Opcode::AssertZero(Expression { - mul_terms: vec![(FieldElement::one(), witness, witness)], - linear_combinations: vec![(-FieldElement::one(), witness)], - q_c: FieldElement::zero(), - }) - } else { - Opcode::BlackBoxFuncCall(BlackBoxFuncCall::RANGE { - input: FunctionInput { witness, num_bits }, - }) - } -} - #[cfg(test)] mod tests { use std::collections::BTreeSet; - use crate::compiler::optimizers::redundant_range::{extract_range_opcode, RangeOptimizer}; + use crate::compiler::optimizers::redundant_range::RangeOptimizer; use acir::{ circuit::{ opcodes::{BlackBoxFuncCall, FunctionInput}, @@ -218,11 +194,12 @@ mod tests { let (optimized_circuit, _) = optimizer.replace_redundant_ranges(acir_opcode_positions); assert_eq!(optimized_circuit.opcodes.len(), 1); - let (witness, num_bits) = - extract_range_opcode(&optimized_circuit.opcodes[0]).expect("expected one range opcode"); - - assert_eq!(witness, Witness(1)); - assert_eq!(num_bits, 16); + assert_eq!( + optimized_circuit.opcodes[0], + Opcode::BlackBoxFuncCall(BlackBoxFuncCall::RANGE { + input: FunctionInput { witness: Witness(1), num_bits: 16 } + }) + ); } #[test] @@ -240,15 +217,18 @@ mod tests { let (optimized_circuit, _) = optimizer.replace_redundant_ranges(acir_opcode_positions); assert_eq!(optimized_circuit.opcodes.len(), 2); - let (witness_a, num_bits_a) = - extract_range_opcode(&optimized_circuit.opcodes[0]).expect("expected two range opcode"); - let (witness_b, num_bits_b) = - extract_range_opcode(&optimized_circuit.opcodes[1]).expect("expected two range opcode"); - - assert_eq!(witness_a, Witness(1)); - assert_eq!(witness_b, Witness(2)); - assert_eq!(num_bits_a, 16); - assert_eq!(num_bits_b, 23); + assert_eq!( + optimized_circuit.opcodes[0], + Opcode::BlackBoxFuncCall(BlackBoxFuncCall::RANGE { + input: FunctionInput { witness: Witness(1), num_bits: 16 } + }) + ); + assert_eq!( + optimized_circuit.opcodes[1], + Opcode::BlackBoxFuncCall(BlackBoxFuncCall::RANGE { + input: FunctionInput { witness: Witness(2), num_bits: 23 } + }) + ); } #[test] From 2d93169d0cf54fc36fb61ee9b62d2ce26f36fd7a Mon Sep 17 00:00:00 2001 From: Michael J Klein Date: Tue, 30 Jan 2024 11:48:24 -0500 Subject: [PATCH 55/70] chore: Rename acir_docs.md to README.md (#4208) # Description Makes it easier to find/view ACIR docs markdown file in github ## Problem\* ## Summary\* ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- acvm-repo/acir/{acir_docs.md => README.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename acvm-repo/acir/{acir_docs.md => README.md} (100%) diff --git a/acvm-repo/acir/acir_docs.md b/acvm-repo/acir/README.md similarity index 100% rename from acvm-repo/acir/acir_docs.md rename to acvm-repo/acir/README.md From 8f70e57ded3b8a46388eedf1c0ec83772f88733e Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Tue, 30 Jan 2024 18:06:04 +0000 Subject: [PATCH 56/70] feat: disable unused variable checks on low-level and oracle functions (#4179) # Description ## Problem\* Resolves ## Summary\* Any low-level functions don't have a function implementation in Noir so all inputs will appear unused. We currently prefix these arguments with underscores to silence this but this leaks through into the docs where preferably we'd have non-underscored variables. This also affects any oracle functions which may exist in user code, requiring them to use underscores in the same way which isn't ideal. This PR then disables unused variable checks on any function with the `#[foreign]`, `#[builtin]` or `#[oracle]` attributes. ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- .../src/hir/resolution/resolver.rs | 10 +++++++++- compiler/noirc_frontend/src/lexer/token.rs | 4 ++++ noir_stdlib/src/array.nr | 4 ++-- noir_stdlib/src/ecdsa_secp256k1.nr | 10 +++++----- noir_stdlib/src/ecdsa_secp256r1.nr | 10 +++++----- noir_stdlib/src/field.nr | 10 +++++----- noir_stdlib/src/hash.nr | 16 ++++++++-------- noir_stdlib/src/lib.nr | 10 +++++----- noir_stdlib/src/scalar_mul.nr | 4 ++-- noir_stdlib/src/schnorr.nr | 10 +++++----- noir_stdlib/src/slice.nr | 12 ++++++------ noir_stdlib/src/string.nr | 2 +- noir_stdlib/src/test.nr | 10 +++++----- 13 files changed, 62 insertions(+), 50 deletions(-) diff --git a/compiler/noirc_frontend/src/hir/resolution/resolver.rs b/compiler/noirc_frontend/src/hir/resolution/resolver.rs index df533f6a4ae..f2becc93b79 100644 --- a/compiler/noirc_frontend/src/hir/resolution/resolver.rs +++ b/compiler/noirc_frontend/src/hir/resolution/resolver.rs @@ -191,10 +191,18 @@ impl<'a> Resolver<'a> { self.add_generics(&func.def.generics); self.trait_bounds = func.def.where_clause.clone(); + let is_low_level_or_oracle = func + .attributes() + .function + .as_ref() + .map_or(false, |func| func.is_low_level() || func.is_oracle()); let (hir_func, func_meta) = self.intern_function(func, func_id); let func_scope_tree = self.scopes.end_function(); - self.check_for_unused_variables_in_scope_tree(func_scope_tree); + // The arguments to low-level and oracle functions are always unused so we do not produce warnings for them. + if !is_low_level_or_oracle { + self.check_for_unused_variables_in_scope_tree(func_scope_tree); + } self.trait_bounds.clear(); (hir_func, func_meta, self.errors) diff --git a/compiler/noirc_frontend/src/lexer/token.rs b/compiler/noirc_frontend/src/lexer/token.rs index ab131ccd880..835a0baae3f 100644 --- a/compiler/noirc_frontend/src/lexer/token.rs +++ b/compiler/noirc_frontend/src/lexer/token.rs @@ -562,6 +562,10 @@ impl FunctionAttribute { matches!(self, FunctionAttribute::Foreign(_)) } + pub fn is_oracle(&self) -> bool { + matches!(self, FunctionAttribute::Oracle(_)) + } + pub fn is_low_level(&self) -> bool { matches!(self, FunctionAttribute::Foreign(_) | FunctionAttribute::Builtin(_)) } diff --git a/noir_stdlib/src/array.nr b/noir_stdlib/src/array.nr index bcdf56dd7aa..87cf4167dac 100644 --- a/noir_stdlib/src/array.nr +++ b/noir_stdlib/src/array.nr @@ -3,10 +3,10 @@ // by the methods in the `slice` module impl [T; N] { #[builtin(array_len)] - pub fn len(_self: Self) -> Field {} + pub fn len(self) -> Field {} #[builtin(arraysort)] - pub fn sort(_self: Self) -> Self {} + pub fn sort(self) -> Self {} // Sort with a custom sorting function. pub fn sort_via(mut a: Self, ordering: fn[Env](T, T) -> bool) -> Self { diff --git a/noir_stdlib/src/ecdsa_secp256k1.nr b/noir_stdlib/src/ecdsa_secp256k1.nr index 290ccba27e5..e8d9af2230f 100644 --- a/noir_stdlib/src/ecdsa_secp256k1.nr +++ b/noir_stdlib/src/ecdsa_secp256k1.nr @@ -1,10 +1,10 @@ #[foreign(ecdsa_secp256k1)] // docs:start:ecdsa_secp256k1 pub fn verify_signature( - _public_key_x: [u8; 32], - _public_key_y: [u8; 32], - _signature: [u8; 64], - _message_hash: [u8; N] + public_key_x: [u8; 32], + public_key_y: [u8; 32], + signature: [u8; 64], + message_hash: [u8; N] ) -> bool // docs:end:ecdsa_secp256k1 -{} +{} \ No newline at end of file diff --git a/noir_stdlib/src/ecdsa_secp256r1.nr b/noir_stdlib/src/ecdsa_secp256r1.nr index 390f8ed39d2..9fe932a2f3d 100644 --- a/noir_stdlib/src/ecdsa_secp256r1.nr +++ b/noir_stdlib/src/ecdsa_secp256r1.nr @@ -1,10 +1,10 @@ #[foreign(ecdsa_secp256r1)] // docs:start:ecdsa_secp256r1 pub fn verify_signature( - _public_key_x: [u8; 32], - _public_key_y: [u8; 32], - _signature: [u8; 64], - _message_hash: [u8; N] + public_key_x: [u8; 32], + public_key_y: [u8; 32], + signature: [u8; 64], + message_hash: [u8; N] ) -> bool // docs:end:ecdsa_secp256r1 -{} +{} \ No newline at end of file diff --git a/noir_stdlib/src/field.nr b/noir_stdlib/src/field.nr index fbd76a1e8a2..66fb50119f9 100644 --- a/noir_stdlib/src/field.nr +++ b/noir_stdlib/src/field.nr @@ -13,13 +13,13 @@ impl Field { } #[builtin(to_le_bits)] - fn __to_le_bits(_self: Self, _bit_size: u32) -> [u1] {} + fn __to_le_bits(self, _bit_size: u32) -> [u1] {} #[builtin(to_be_bits)] - fn __to_be_bits(_self: Self, _bit_size: u32) -> [u1] {} + fn __to_be_bits(self, bit_size: u32) -> [u1] {} #[builtin(apply_range_constraint)] - fn __assert_max_bit_size(_self: Self, _bit_size: u32) {} + fn __assert_max_bit_size(self, bit_size: u32) {} pub fn assert_max_bit_size(self: Self, bit_size: u32) { crate::assert_constant(bit_size); @@ -53,10 +53,10 @@ impl Field { // decompose `_self` into a `_result_len` vector over the `_radix` basis // `_radix` must be less than 256 #[builtin(to_le_radix)] - fn __to_le_radix(_self: Self, _radix: u32, _result_len: u32) -> [u8] {} + fn __to_le_radix(self, radix: u32, result_len: u32) -> [u8] {} #[builtin(to_be_radix)] - fn __to_be_radix(_self: Self, _radix: u32, _result_len: u32) -> [u8] {} + fn __to_be_radix(self, radix: u32, result_len: u32) -> [u8] {} // Returns self to the power of the given exponent value. diff --git a/noir_stdlib/src/hash.nr b/noir_stdlib/src/hash.nr index 4033e2a5365..cc864039a90 100644 --- a/noir_stdlib/src/hash.nr +++ b/noir_stdlib/src/hash.nr @@ -3,19 +3,19 @@ mod mimc; #[foreign(sha256)] // docs:start:sha256 -pub fn sha256(_input: [u8; N]) -> [u8; 32] +pub fn sha256(input: [u8; N]) -> [u8; 32] // docs:end:sha256 {} #[foreign(blake2s)] // docs:start:blake2s -pub fn blake2s(_input: [u8; N]) -> [u8; 32] +pub fn blake2s(input: [u8; N]) -> [u8; 32] // docs:end:blake2s {} #[foreign(blake3)] // docs:start:blake3 -pub fn blake3(_input: [u8; N]) -> [u8; 32] +pub fn blake3(input: [u8; N]) -> [u8; 32] // docs:end:blake3 {} @@ -32,7 +32,7 @@ pub fn pedersen_commitment(input: [Field; N]) -> PedersenPoint } #[foreign(pedersen_commitment)] -pub fn __pedersen_commitment_with_separator(_input: [Field; N], _separator: u32) -> [Field; 2] {} +pub fn __pedersen_commitment_with_separator(input: [Field; N], separator: u32) -> [Field; 2] {} pub fn pedersen_commitment_with_separator(input: [Field; N], separator: u32) -> PedersenPoint { let values = __pedersen_commitment_with_separator(input, separator); @@ -47,13 +47,13 @@ pub fn pedersen_hash(input: [Field; N]) -> Field } #[foreign(pedersen_hash)] -pub fn pedersen_hash_with_separator(_input: [Field; N], _separator: u32) -> Field {} +pub fn pedersen_hash_with_separator(input: [Field; N], separator: u32) -> Field {} -pub fn hash_to_field(_input: [Field; N]) -> Field { +pub fn hash_to_field(input: [Field; N]) -> Field { let mut inputs_as_bytes = []; for i in 0..N { - let input_bytes = _input[i].to_le_bytes(32); + let input_bytes = input[i].to_le_bytes(32); for i in 0..32 { inputs_as_bytes = inputs_as_bytes.push_back(input_bytes[i]); } @@ -65,7 +65,7 @@ pub fn hash_to_field(_input: [Field; N]) -> Field { #[foreign(keccak256)] // docs:start:keccak256 -pub fn keccak256(_input: [u8; N], _message_size: u32) -> [u8; 32] +pub fn keccak256(input: [u8; N], message_size: u32) -> [u8; 32] // docs:end:keccak256 {} diff --git a/noir_stdlib/src/lib.nr b/noir_stdlib/src/lib.nr index 90aff3c312b..5165d1ee07b 100644 --- a/noir_stdlib/src/lib.nr +++ b/noir_stdlib/src/lib.nr @@ -30,7 +30,7 @@ mod uint128; // Oracle calls are required to be wrapped in an unconstrained function // Thus, the only argument to the `println` oracle is expected to always be an ident #[oracle(print)] -unconstrained fn print_oracle(_with_newline: bool, _input: T) {} +unconstrained fn print_oracle(with_newline: bool, input: T) {} unconstrained pub fn print(input: T) { print_oracle(false, input); @@ -41,20 +41,20 @@ unconstrained pub fn println(input: T) { } #[foreign(recursive_aggregation)] -pub fn verify_proof(_verification_key: [Field], _proof: [Field], _public_inputs: [Field], _key_hash: Field) {} +pub fn verify_proof(verification_key: [Field], proof: [Field], public_inputs: [Field], key_hash: Field) {} // Asserts that the given value is known at compile-time. // Useful for debugging for-loop bounds. #[builtin(assert_constant)] -pub fn assert_constant(_x: T) {} +pub fn assert_constant(x: T) {} // from_field and as_field are private since they are not valid for every type. // `as` should be the default for users to cast between primitive types, and in the future // traits can be used to work with generic types. #[builtin(from_field)] -fn from_field(_x: Field) -> T {} +fn from_field(x: Field) -> T {} #[builtin(as_field)] -fn as_field(_x: T) -> Field {} +fn as_field(x: T) -> Field {} pub fn wrapping_add(x: T, y: T) -> T { crate::from_field(crate::as_field(x) + crate::as_field(y)) diff --git a/noir_stdlib/src/scalar_mul.nr b/noir_stdlib/src/scalar_mul.nr index 0e84b4f66fc..26378e4839a 100644 --- a/noir_stdlib/src/scalar_mul.nr +++ b/noir_stdlib/src/scalar_mul.nr @@ -26,8 +26,8 @@ impl Add for EmbeddedCurvePoint { #[foreign(fixed_base_scalar_mul)] // docs:start:fixed_base_embedded_curve pub fn fixed_base_embedded_curve( - _low: Field, - _high: Field + low: Field, + high: Field ) -> [Field; 2] // docs:end:fixed_base_embedded_curve {} diff --git a/noir_stdlib/src/schnorr.nr b/noir_stdlib/src/schnorr.nr index 025c3a0f921..33656254550 100644 --- a/noir_stdlib/src/schnorr.nr +++ b/noir_stdlib/src/schnorr.nr @@ -1,10 +1,10 @@ #[foreign(schnorr_verify)] // docs:start:schnorr_verify pub fn verify_signature( - _public_key_x: Field, - _public_key_y: Field, - _signature: [u8; 64], - _message: [u8; N] + public_key_x: Field, + public_key_y: Field, + signature: [u8; 64], + message: [u8; N] ) -> bool // docs:end:schnorr_verify -{} +{} \ No newline at end of file diff --git a/noir_stdlib/src/slice.nr b/noir_stdlib/src/slice.nr index a5a9a38ed53..aa4b73edc1a 100644 --- a/noir_stdlib/src/slice.nr +++ b/noir_stdlib/src/slice.nr @@ -3,34 +3,34 @@ impl [T] { /// new slice with a length one greater than the /// original unmodified slice. #[builtin(slice_push_back)] - pub fn push_back(_self: Self, _elem: T) -> Self { } + pub fn push_back(self, elem: T) -> Self { } /// Push a new element to the front of the slice, returning a /// new slice with a length one greater than the /// original unmodified slice. #[builtin(slice_push_front)] - pub fn push_front(_self: Self, _elem: T) -> Self { } + pub fn push_front(self, elem: T) -> Self { } /// Remove the last element of the slice, returning the /// popped slice and the element in a tuple #[builtin(slice_pop_back)] - pub fn pop_back(_self: Self) -> (Self, T) { } + pub fn pop_back(self) -> (Self, T) { } /// Remove the first element of the slice, returning the /// element and the popped slice in a tuple #[builtin(slice_pop_front)] - pub fn pop_front(_self: Self) -> (T, Self) { } + pub fn pop_front(self) -> (T, Self) { } /// Insert an element at a specified index, shifting all elements /// after it to the right #[builtin(slice_insert)] - pub fn insert(_self: Self, _index: Field, _elem: T) -> Self { } + pub fn insert(self, index: Field, elem: T) -> Self { } /// Remove an element at a specified index, shifting all elements /// after it to the left, returning the altered slice and /// the removed element #[builtin(slice_remove)] - pub fn remove(_self: Self, _index: Field) -> (Self, T) { } + pub fn remove(self, index: Field) -> (Self, T) { } // Append each element of the `other` slice to the end of `self`. // This returns a new slice and leaves both input slices unchanged. diff --git a/noir_stdlib/src/string.nr b/noir_stdlib/src/string.nr index e402abf9ab6..ad6fd19e2de 100644 --- a/noir_stdlib/src/string.nr +++ b/noir_stdlib/src/string.nr @@ -2,7 +2,7 @@ use crate::collections::vec::Vec; impl str { /// Converts the given string into a byte array #[builtin(str_as_bytes)] - pub fn as_bytes(_self: Self) -> [u8; N] { } + pub fn as_bytes(self) -> [u8; N] { } /// return a byte vector of the str content pub fn as_bytes_vec(self: Self) -> Vec { diff --git a/noir_stdlib/src/test.nr b/noir_stdlib/src/test.nr index 47b31f4acea..560cfde741c 100644 --- a/noir_stdlib/src/test.nr +++ b/noir_stdlib/src/test.nr @@ -1,17 +1,17 @@ #[oracle(create_mock)] -unconstrained fn create_mock_oracle(_name: str) -> Field {} +unconstrained fn create_mock_oracle(name: str) -> Field {} #[oracle(set_mock_params)] -unconstrained fn set_mock_params_oracle

(_id: Field, _params: P) {} +unconstrained fn set_mock_params_oracle

(id: Field, params: P) {} #[oracle(set_mock_returns)] -unconstrained fn set_mock_returns_oracle(_id: Field, _returns: R) {} +unconstrained fn set_mock_returns_oracle(id: Field, returns: R) {} #[oracle(set_mock_times)] -unconstrained fn set_mock_times_oracle(_id: Field, _times: u64) {} +unconstrained fn set_mock_times_oracle(id: Field, times: u64) {} #[oracle(clear_mock)] -unconstrained fn clear_mock_oracle(_id: Field) {} +unconstrained fn clear_mock_oracle(id: Field) {} struct OracleMock { id: Field, From 9fb6b092c504d29d7f190952387de66c7e6e570c Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Tue, 30 Jan 2024 18:30:08 +0000 Subject: [PATCH 57/70] fix: prevent declarations of blackbox functions outside of the stdlib (#4177) # Description ## Problem\* Resolves ## Summary\* I found this [semaphore lib which is redeclaring pedersen for some reason](https://github.com/siosw/semaphore-noir/blob/main/circuits/src/identity.nr). Let's ~break it!~ give a nice error message to tell users that they're doing something wrong here. ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- compiler/noirc_frontend/src/hir/resolution/errors.rs | 7 +++++++ compiler/noirc_frontend/src/hir/resolution/resolver.rs | 7 +++++++ compiler/noirc_frontend/src/tests.rs | 2 ++ .../builtin_function_declaration/Nargo.toml | 7 +++++++ .../builtin_function_declaration/src/main.nr | 10 ++++++++++ .../foreign_function_declaration/Nargo.toml | 7 +++++++ .../foreign_function_declaration/src/main.nr | 10 ++++++++++ 7 files changed, 50 insertions(+) create mode 100644 test_programs/compile_failure/builtin_function_declaration/Nargo.toml create mode 100644 test_programs/compile_failure/builtin_function_declaration/src/main.nr create mode 100644 test_programs/compile_failure/foreign_function_declaration/Nargo.toml create mode 100644 test_programs/compile_failure/foreign_function_declaration/src/main.nr diff --git a/compiler/noirc_frontend/src/hir/resolution/errors.rs b/compiler/noirc_frontend/src/hir/resolution/errors.rs index 390807afd17..7bd4de77e84 100644 --- a/compiler/noirc_frontend/src/hir/resolution/errors.rs +++ b/compiler/noirc_frontend/src/hir/resolution/errors.rs @@ -84,6 +84,8 @@ pub enum ResolverError { InvalidTypeForEntryPoint { span: Span }, #[error("Nested slices are not supported")] NestedSlices { span: Span }, + #[error("Usage of the `#[foreign]` or `#[builtin]` function attributes are not allowed outside of the Noir standard library")] + LowLevelFunctionOutsideOfStdlib { ident: Ident }, } impl ResolverError { @@ -311,6 +313,11 @@ impl From for Diagnostic { "Try to use a constant sized array instead".into(), span, ), + ResolverError::LowLevelFunctionOutsideOfStdlib { ident } => Diagnostic::simple_error( + "Definition of low-level function outside of standard library".into(), + "Usage of the `#[foreign]` or `#[builtin]` function attributes are not allowed outside of the Noir standard library".into(), + ident.span(), + ), } } } diff --git a/compiler/noirc_frontend/src/hir/resolution/resolver.rs b/compiler/noirc_frontend/src/hir/resolution/resolver.rs index f2becc93b79..8243b684c8a 100644 --- a/compiler/noirc_frontend/src/hir/resolution/resolver.rs +++ b/compiler/noirc_frontend/src/hir/resolution/resolver.rs @@ -908,6 +908,13 @@ impl<'a> Resolver<'a> { position: PubPosition::ReturnType, }); } + let is_low_level_function = + func.attributes().function.as_ref().map_or(false, |func| func.is_low_level()); + if !self.path_resolver.module_id().krate.is_stdlib() && is_low_level_function { + let error = + ResolverError::LowLevelFunctionOutsideOfStdlib { ident: func.name_ident().clone() }; + self.push_err(error); + } // 'pub' is required on return types for entry point functions if self.is_entry_point_function(func) diff --git a/compiler/noirc_frontend/src/tests.rs b/compiler/noirc_frontend/src/tests.rs index 9ccbddab9ec..a4246a9fe7d 100644 --- a/compiler/noirc_frontend/src/tests.rs +++ b/compiler/noirc_frontend/src/tests.rs @@ -52,10 +52,12 @@ mod test { ) -> (ParsedModule, Context, Vec<(CompilationError, FileId)>) { let root = std::path::Path::new("/"); let fm = FileManager::new(root); + let mut context = Context::new(fm, Default::default()); context.def_interner.populate_dummy_operator_traits(); let root_file_id = FileId::dummy(); let root_crate_id = context.crate_graph.add_crate_root(root_file_id); + let (program, parser_errors) = parse_program(src); let mut errors = vecmap(parser_errors, |e| (e.into(), root_file_id)); remove_experimental_warnings(&mut errors); diff --git a/test_programs/compile_failure/builtin_function_declaration/Nargo.toml b/test_programs/compile_failure/builtin_function_declaration/Nargo.toml new file mode 100644 index 00000000000..3835292a6ba --- /dev/null +++ b/test_programs/compile_failure/builtin_function_declaration/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "builtin_function_declaration" +type = "bin" +authors = [""] +compiler_version = ">=0.23.0" + +[dependencies] diff --git a/test_programs/compile_failure/builtin_function_declaration/src/main.nr b/test_programs/compile_failure/builtin_function_declaration/src/main.nr new file mode 100644 index 00000000000..ed376557371 --- /dev/null +++ b/test_programs/compile_failure/builtin_function_declaration/src/main.nr @@ -0,0 +1,10 @@ +// This test prevents users from trying to create their own builtin functions as these should only exist in the stdlib. + +// This would otherwise be a perfectly valid declaration of the `to_le_bits` builtin function +#[builtin(to_le_bits)] +fn to_le_bits(_x: Field, _bit_size: u32) -> [u1] {} + +fn main(x: Field) -> pub u1 { + let bits = to_le_bits(x, 100); + bits[0] +} diff --git a/test_programs/compile_failure/foreign_function_declaration/Nargo.toml b/test_programs/compile_failure/foreign_function_declaration/Nargo.toml new file mode 100644 index 00000000000..951658d7fb8 --- /dev/null +++ b/test_programs/compile_failure/foreign_function_declaration/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "foreign_function_declaration" +type = "bin" +authors = [""] +compiler_version = ">=0.23.0" + +[dependencies] diff --git a/test_programs/compile_failure/foreign_function_declaration/src/main.nr b/test_programs/compile_failure/foreign_function_declaration/src/main.nr new file mode 100644 index 00000000000..6273067f6a7 --- /dev/null +++ b/test_programs/compile_failure/foreign_function_declaration/src/main.nr @@ -0,0 +1,10 @@ +// This test prevents users from trying to create their own blackbox functions as these should only exist in the stdlib. + +// This would otherwise be a perfectly valid definition of the `pedersen_hash` black box function, +// however executing the circuit results in an unhelpful ICE. +#[foreign(pedersen_hash)] +fn my_pedersen_hash(_input: [Field; N]) -> Field {} + +fn main() -> pub Field { + my_pedersen_hash([1]) +} From 3a908491d649be503df24038fc1eab875d77c8f1 Mon Sep 17 00:00:00 2001 From: joao <22820692+joaolago1113@users.noreply.github.com> Date: Tue, 30 Jan 2024 21:01:40 +0000 Subject: [PATCH 58/70] feat: Improve Error Handling for Cargo in Bootstrap Script (#4211) ### Overview This pull request introduces an improvement to the `bootstrap_native.sh` script. It adds a preliminary check to verify whether Cargo, the Rust package manager, is installed in the environment. This enhancement is aimed at providing clearer error messages to developers setting up the project. ### Changes Made - Added a check in `bootstrap_native.sh` to determine if the `cargo` command is available in the system. - If Cargo is not found, the script now outputs a user-friendly error message: `Cargo is not installed. Please install Cargo and the Rust toolchain.` ### Motivation During the setup process, particularly for new contributors or in environments where Rust is not yet installed, the absence of Cargo could lead to a cryptic error message. By explicitly checking for Cargo and providing a clear error message, we make the setup process more developer-friendly and intuitive. --- scripts/bootstrap_native.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/scripts/bootstrap_native.sh b/scripts/bootstrap_native.sh index 3e0e2ed853a..974f0edcfec 100755 --- a/scripts/bootstrap_native.sh +++ b/scripts/bootstrap_native.sh @@ -12,6 +12,12 @@ else export GIT_COMMIT=$(git rev-parse --verify HEAD) fi +# Check if the 'cargo' command is available in the system +if ! command -v cargo > /dev/null; then + echo "Cargo is not installed. Please install Cargo and the Rust toolchain." + exit 1 +fi + # Build native. if [ -n "${DEBUG:-}" ]; then cargo build From 26e961860709e9c0ab3d1eb561fd39b5bd95a0fb Mon Sep 17 00:00:00 2001 From: Koby Hall <102518238+kobyhallx@users.noreply.github.com> Date: Wed, 31 Jan 2024 08:58:18 +0100 Subject: [PATCH 59/70] fix(lsp): replace panics with errors (#4209) # Description ## Problem\* Resolves lsp panics when contract with #[event] #4203 ## Summary\* Replaces .expect calls with err returns. ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --------- Co-authored-by: jfecher --- aztec_macros/src/lib.rs | 86 ++++++++++++++----- .../src/hir/def_collector/dc_crate.rs | 14 ++- compiler/noirc_frontend/src/lib.rs | 6 +- 3 files changed, 82 insertions(+), 24 deletions(-) diff --git a/aztec_macros/src/lib.rs b/aztec_macros/src/lib.rs index c9adece4eb5..baabd9aa1dc 100644 --- a/aztec_macros/src/lib.rs +++ b/aztec_macros/src/lib.rs @@ -26,8 +26,12 @@ impl MacroProcessor for AztecMacro { transform(ast, crate_id, context) } - fn process_typed_ast(&self, crate_id: &CrateId, context: &mut HirContext) { - transform_hir(crate_id, context) + fn process_typed_ast( + &self, + crate_id: &CrateId, + context: &mut HirContext, + ) -> Result<(), (MacroError, FileId)> { + transform_hir(crate_id, context).map_err(|(err, file_id)| (err.into(), file_id)) } } @@ -41,6 +45,7 @@ pub enum AztecMacroError { ContractHasTooManyFunctions { span: Span }, ContractConstructorMissing { span: Span }, UnsupportedFunctionArgumentType { span: Span, typ: UnresolvedTypeData }, + EventError { span: Span, message: String }, } impl From for MacroError { @@ -71,6 +76,11 @@ impl From for MacroError { secondary_message: None, span: Some(span), }, + AztecMacroError::EventError { span, message } => MacroError { + primary_message: message, + secondary_message: None, + span: Some(span), + }, } } } @@ -237,8 +247,11 @@ fn transform( // /// Completes the Hir with data gathered from type resolution -fn transform_hir(crate_id: &CrateId, context: &mut HirContext) { - transform_events(crate_id, context); +fn transform_hir( + crate_id: &CrateId, + context: &mut HirContext, +) -> Result<(), (AztecMacroError, FileId)> { + transform_events(crate_id, context) } /// Includes an import to the aztec library if it has not been included yet @@ -472,19 +485,30 @@ fn collect_crate_structs(crate_id: &CrateId, context: &HirContext) -> Vec Result<(), (AztecMacroError, FileId)> { let struct_type = interner.get_struct(struct_id); let selector_id = interner - .lookup_method(&Type::Struct(struct_type, vec![]), struct_id, "selector", false) - .expect("Selector method not found"); + .lookup_method(&Type::Struct(struct_type.clone(), vec![]), struct_id, "selector", false) + .ok_or_else(|| { + let error = AztecMacroError::EventError { + span: struct_type.borrow().location.span, + message: "Selector method not found".to_owned(), + }; + (error, struct_type.borrow().location.file) + })?; let selector_function = interner.function(&selector_id); let compute_selector_statement = interner.statement( - selector_function - .block(interner) - .statements() - .first() - .expect("Compute selector statement not found"), + selector_function.block(interner).statements().first().ok_or_else(|| { + let error = AztecMacroError::EventError { + span: struct_type.borrow().location.span, + message: "Compute selector statement not found".to_owned(), + }; + (error, struct_type.borrow().location.file) + })?, ); let compute_selector_expression = match compute_selector_statement { @@ -494,12 +518,21 @@ fn transform_event(struct_id: StructId, interner: &mut NodeInterner) { }, _ => None, } - .expect("Compute selector statement is not a call expression"); - - let first_arg_id = compute_selector_expression - .arguments - .first() - .expect("Missing argument for compute selector"); + .ok_or_else(|| { + let error = AztecMacroError::EventError { + span: struct_type.borrow().location.span, + message: "Compute selector statement is not a call expression".to_owned(), + }; + (error, struct_type.borrow().location.file) + })?; + + let first_arg_id = compute_selector_expression.arguments.first().ok_or_else(|| { + let error = AztecMacroError::EventError { + span: struct_type.borrow().location.span, + message: "Compute selector statement is not a call expression".to_owned(), + }; + (error, struct_type.borrow().location.file) + })?; match interner.expression(first_arg_id) { HirExpression::Literal(HirLiteral::Str(signature)) @@ -518,18 +551,29 @@ fn transform_event(struct_id: StructId, interner: &mut NodeInterner) { selector_literal_id, Type::String(Box::new(Type::Constant(signature.len() as u64))), ); + Ok(()) } - _ => unreachable!("Signature placeholder literal does not match"), + _ => Err(( + AztecMacroError::EventError { + span: struct_type.borrow().location.span, + message: "Signature placeholder literal does not match".to_owned(), + }, + struct_type.borrow().location.file, + )), } } -fn transform_events(crate_id: &CrateId, context: &mut HirContext) { +fn transform_events( + crate_id: &CrateId, + context: &mut HirContext, +) -> Result<(), (AztecMacroError, FileId)> { for struct_id in collect_crate_structs(crate_id, context) { let attributes = context.def_interner.struct_attributes(&struct_id); if attributes.iter().any(|attr| matches!(attr, SecondaryAttribute::Event)) { - transform_event(struct_id, &mut context.def_interner); + transform_event(struct_id, &mut context.def_interner)?; } } + Ok(()) } const SIGNATURE_PLACEHOLDER: &str = "SIGNATURE_PLACEHOLDER"; diff --git a/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs b/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs index a6ab6b1d825..f7441750fc8 100644 --- a/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs +++ b/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs @@ -14,7 +14,7 @@ use crate::hir::resolution::{ use crate::hir::type_check::{type_check_func, TypeCheckError, TypeChecker}; use crate::hir::Context; -use crate::macros_api::MacroProcessor; +use crate::macros_api::{MacroError, MacroProcessor}; use crate::node_interner::{FuncId, NodeInterner, StmtId, StructId, TraitId, TypeAliasId}; use crate::parser::{ParserError, SortedModule}; @@ -155,6 +155,12 @@ impl From for CustomDiagnostic { } } +impl From for CompilationError { + fn from(value: MacroError) -> Self { + CompilationError::DefinitionError(DefCollectorErrorKind::MacroError(value)) + } +} + impl From for CompilationError { fn from(value: ParserError) -> Self { CompilationError::ParseError(value) @@ -359,7 +365,11 @@ impl DefCollector { errors.extend(resolved_globals.errors); for macro_processor in macro_processors { - macro_processor.process_typed_ast(&crate_id, context); + macro_processor.process_typed_ast(&crate_id, context).unwrap_or_else( + |(macro_err, file_id)| { + errors.push((macro_err.into(), file_id)); + }, + ); } errors.extend(type_check_globals(&mut context.def_interner, resolved_globals.globals)); diff --git a/compiler/noirc_frontend/src/lib.rs b/compiler/noirc_frontend/src/lib.rs index 9582b80dcba..b6d4c568334 100644 --- a/compiler/noirc_frontend/src/lib.rs +++ b/compiler/noirc_frontend/src/lib.rs @@ -75,6 +75,10 @@ pub mod macros_api { ) -> Result; /// Function to manipulate the AST after type checking has been completed. /// The AST after type checking has been done is called the HIR. - fn process_typed_ast(&self, crate_id: &CrateId, context: &mut HirContext); + fn process_typed_ast( + &self, + crate_id: &CrateId, + context: &mut HirContext, + ) -> Result<(), (MacroError, FileId)>; } } From 3af2a89826f7d9b6dcd1782b8b38417c64065293 Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Wed, 31 Jan 2024 14:48:06 +0000 Subject: [PATCH 60/70] fix: apply range constraints to return values from unconstrained functions (#4217) # Description ## Problem\* Resolves ## Summary\* Consider the program ```rust unconstrained fn identity(x: u8) -> u8 { x } fn main(x: u8, y: pub Field) { assert(identity(x) as Field == 1000); } ``` From looking at the type information, this program should be unsatisfiable. A `u8` should not be able to contain the value `1000` so the assertion should always fail. If we look at the generated ACIR however we see that the return value of `identity()` doesn't need to be a valid `u8` and so can be set by the prover to be `1000`. ``` BLACKBOX::RANGE [(_0, num_bits: 8)] [ ] BRILLIG: inputs: [Single(Expression { mul_terms: [], linear_combinations: [(1, Witness(0))], q_c: 0 })] outputs: [Simple(Witness(2))] [Mov { destination: RegisterIndex(2), source: RegisterIndex(0) }, Const { destination: RegisterIndex(0), value: Value { inner: 0 } }, Const { destination: RegisterIndex(1), value: Value { inner: 0 } }, Mov { destination: RegisterIndex(2), source: RegisterIndex(2) }, Call { location: 7 }, Mov { destination: RegisterIndex(0), source: RegisterIndex(2) }, Stop, Mov { destination: RegisterIndex(3), source: RegisterIndex(2) }, Mov { destination: RegisterIndex(2), source: RegisterIndex(3) }, Return] EXPR [ (1, _2) -1000 ] ``` This PR modifies ACIR gen so that when inserting a call to a brillig function, we apply range constraints to the return values to ensure that the results provided by the prover must be valid for those types. ## Additional Context Note that we cannot enforce safety for all types which have validity conditions outside of the type system. e.g. If an unconstrained function returns a `U128` then this will not be constrained as its limbs are made up of `Field`s so no constraints will be applied allowing a potentially invalid value to be returned. ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- .../src/ssa/acir_gen/acir_ir/acir_variable.rs | 56 ++++++++++++++----- 1 file changed, 43 insertions(+), 13 deletions(-) diff --git a/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs b/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs index a419dac9d93..5cf70b098f9 100644 --- a/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs +++ b/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs @@ -1441,20 +1441,22 @@ impl AcirContext { inputs: Vec, outputs: Vec, attempt_execution: bool, - ) -> Result, InternalError> { - let b_inputs = try_vecmap(inputs, |i| match i { - AcirValue::Var(var, _) => Ok(BrilligInputs::Single(self.var_to_expression(var)?)), - AcirValue::Array(vars) => { - let mut var_expressions: Vec = Vec::new(); - for var in vars { - self.brillig_array_input(&mut var_expressions, var)?; + ) -> Result, RuntimeError> { + let b_inputs = try_vecmap(inputs, |i| -> Result<_, InternalError> { + match i { + AcirValue::Var(var, _) => Ok(BrilligInputs::Single(self.var_to_expression(var)?)), + AcirValue::Array(vars) => { + let mut var_expressions: Vec = Vec::new(); + for var in vars { + self.brillig_array_input(&mut var_expressions, var)?; + } + Ok(BrilligInputs::Array(var_expressions)) + } + AcirValue::DynamicArray(_) => { + let mut var_expressions = Vec::new(); + self.brillig_array_input(&mut var_expressions, i)?; + Ok(BrilligInputs::Array(var_expressions)) } - Ok(BrilligInputs::Array(var_expressions)) - } - AcirValue::DynamicArray(_) => { - let mut var_expressions = Vec::new(); - self.brillig_array_input(&mut var_expressions, i)?; - Ok(BrilligInputs::Array(var_expressions)) } })?; @@ -1489,6 +1491,34 @@ impl AcirContext { let predicate = self.var_to_expression(predicate)?; self.acir_ir.brillig(Some(predicate), generated_brillig, b_inputs, b_outputs); + fn range_constraint_value( + context: &mut AcirContext, + value: &AcirValue, + ) -> Result<(), RuntimeError> { + match value { + AcirValue::Var(var, typ) => { + let numeric_type = match typ { + AcirType::NumericType(numeric_type) => numeric_type, + _ => unreachable!("`AcirValue::Var` may only hold primitive values"), + }; + context.range_constrain_var(*var, numeric_type, None)?; + } + AcirValue::Array(values) => { + for value in values { + range_constraint_value(context, value)?; + } + } + AcirValue::DynamicArray(_) => { + unreachable!("Brillig opcodes cannot return dynamic arrays") + } + } + Ok(()) + } + + for output_var in &outputs_var { + range_constraint_value(self, output_var)?; + } + Ok(outputs_var) } From 0e2a552bfb13e3521802cc2b4b7eb7362818d19c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Pedro=20Sousa?= Date: Thu, 1 Feb 2024 13:26:26 +0000 Subject: [PATCH 61/70] chore(docs): XOR typo in docs (#4223) closes #4222 --- docs/docs/noir/concepts/unconstrained.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/noir/concepts/unconstrained.md b/docs/docs/noir/concepts/unconstrained.md index 6b3424f7993..89d12c1c971 100644 --- a/docs/docs/noir/concepts/unconstrained.md +++ b/docs/docs/noir/concepts/unconstrained.md @@ -40,7 +40,7 @@ Total ACIR opcodes generated for language PLONKCSat { width: 3 }: 91 Backend circuit size: 3619 ``` -A lot of the operations in this function are optimized away by the compiler (all the bit-shifts turn into divisions by constants). However we can save a bunch of gates by casting to u8 a bit earlier. This automatically truncates the bit-shifted value to fit in a u8 which allows us to remove the XOR against 0xff. This saves us ~480 gates in total. +A lot of the operations in this function are optimized away by the compiler (all the bit-shifts turn into divisions by constants). However we can save a bunch of gates by casting to u8 a bit earlier. This automatically truncates the bit-shifted value to fit in a u8 which allows us to remove the AND against 0xff. This saves us ~480 gates in total. ```rust fn main(num: u72) -> pub [u8; 8] { From c284e01bfe20ceae4414dc123624b5cbb8b66d09 Mon Sep 17 00:00:00 2001 From: Maxim Vezenov Date: Thu, 1 Feb 2024 13:37:03 +0000 Subject: [PATCH 62/70] feat: Evaluation of dynamic assert messages (#4101) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Description ## Problem\* Resolves #3113 ## Summary\* The first major change is a new MacroProcessor that generates an oracle and the respective unconstrained oracle wrapper for resolving assert message expressions. This was done as to prevent exposing the resolve assert message funcs in the stdlib directly. Before an assertion with a dynamic assert message we perform a foreign call out to the user with the format-string and the values to be formatted. The user must then return what the assert message should look like. This is then cached on by nargo when executing the ACVM and should the next opcode fail to execute then this error message will be returned to the user. We now require end-users (people running ACVM) to format their own assert messages. Example output for `assert_msg_runtime` test: Screenshot 2024-01-23 at 4 07 18 PM Assert message still work in the stdlib as expected: Screenshot 2024-01-23 at 4 43 47 PM Output for debug logs when putting `assert(x == y, struct_string);` on line 48 immediately following `std::println(struct_string);`: Screenshot 2024-01-23 at 4 47 55 PM ## Additional Context ## Documentation\* Check one: - [ ] No documentation needed. - [x] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --------- Co-authored-by: Tom French <15848336+TomAFrench@users.noreply.github.com> Co-authored-by: Tom French --- Cargo.lock | 9 ++ Cargo.toml | 3 + acvm-repo/acir/src/circuit/mod.rs | 4 + acvm-repo/brillig/src/foreign_call.rs | 2 +- acvm-repo/brillig_vm/src/lib.rs | 2 +- compiler/noirc_driver/Cargo.toml | 1 + compiler/noirc_driver/src/lib.rs | 10 +- .../src/brillig/brillig_gen/brillig_block.rs | 33 ++++- .../noirc_evaluator/src/ssa/acir_gen/mod.rs | 130 ++++++++++++------ .../src/ssa/function_builder/mod.rs | 4 +- .../noirc_evaluator/src/ssa/ir/instruction.rs | 45 +++++- .../src/ssa/ir/instruction/constrain.rs | 14 +- .../noirc_evaluator/src/ssa/ir/printer.rs | 40 +++++- .../src/ssa/opt/bubble_up_constrains.rs | 8 +- .../src/ssa/opt/defunctionalize.rs | 35 ++++- .../src/ssa/ssa_gen/context.rs | 16 ++- .../noirc_evaluator/src/ssa/ssa_gen/mod.rs | 57 +++++++- compiler/noirc_frontend/src/ast/statement.rs | 2 +- .../src/hir/resolution/resolver.rs | 46 ++++++- .../noirc_frontend/src/hir/type_check/stmt.rs | 3 + compiler/noirc_frontend/src/hir_def/stmt.rs | 2 +- compiler/noirc_frontend/src/lib.rs | 2 +- .../src/monomorphization/ast.rs | 2 +- .../src/monomorphization/mod.rs | 9 +- compiler/noirc_frontend/src/parser/parser.rs | 53 +++---- compiler/noirc_printable_type/src/lib.rs | 3 + docs/docs/noir/concepts/assert.md | 20 ++- noirc_macros/Cargo.toml | 14 ++ noirc_macros/src/lib.rs | 61 ++++++++ .../assert_msg_runtime/Nargo.toml | 7 + .../assert_msg_runtime/src/main.nr | 7 + .../brillig_assert_msg_runtime/Nargo.toml | 7 + .../brillig_assert_msg_runtime/src/main.nr | 10 ++ .../method_call_regression/Nargo.toml | 2 +- .../trait_static_methods/Nargo.toml | 2 +- .../brillig_assert/src/main.nr | 4 +- .../execution_success/debug_logs/src/main.nr | 7 + tooling/debugger/src/context.rs | 4 + tooling/nargo/src/ops/execute.rs | 27 +++- tooling/nargo/src/ops/foreign_calls.rs | 112 ++++++++++++--- tooling/nargo_fmt/src/visitor/stmt.rs | 3 +- tooling/noir_js/src/witness_generation.ts | 6 + tooling/noir_js/test/node/execute.test.ts | 15 ++ .../assert_lt/src/main.nr | 4 + .../assert_lt/target/assert_lt.json | 2 +- .../assert_msg_runtime/Nargo.toml | 7 + .../assert_msg_runtime/src/main.nr | 6 + .../target/assert_msg_runtime.json | 1 + 48 files changed, 701 insertions(+), 162 deletions(-) create mode 100644 noirc_macros/Cargo.toml create mode 100644 noirc_macros/src/lib.rs create mode 100644 test_programs/compile_failure/assert_msg_runtime/Nargo.toml create mode 100644 test_programs/compile_failure/assert_msg_runtime/src/main.nr create mode 100644 test_programs/compile_failure/brillig_assert_msg_runtime/Nargo.toml create mode 100644 test_programs/compile_failure/brillig_assert_msg_runtime/src/main.nr create mode 100644 tooling/noir_js/test/noir_compiled_examples/assert_msg_runtime/Nargo.toml create mode 100644 tooling/noir_js/test/noir_compiled_examples/assert_msg_runtime/src/main.nr create mode 100644 tooling/noir_js/test/noir_compiled_examples/assert_msg_runtime/target/assert_msg_runtime.json diff --git a/Cargo.lock b/Cargo.lock index 93f1d25fc76..1585d81d6e1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2931,6 +2931,7 @@ dependencies = [ "noirc_errors", "noirc_evaluator", "noirc_frontend", + "noirc_macros", "rust-embed", "serde", "tracing", @@ -2993,6 +2994,14 @@ dependencies = [ "tracing", ] +[[package]] +name = "noirc_macros" +version = "0.23.0" +dependencies = [ + "iter-extended", + "noirc_frontend", +] + [[package]] name = "noirc_printable_type" version = "0.23.0" diff --git a/Cargo.toml b/Cargo.toml index 5dfff3dbb5d..2ba97e906b1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,10 @@ [workspace] members = [ + # Macros crates for metaprogramming "aztec_macros", + "noirc_macros", + # Compiler crates "compiler/noirc_evaluator", "compiler/noirc_frontend", "compiler/noirc_errors", diff --git a/acvm-repo/acir/src/circuit/mod.rs b/acvm-repo/acir/src/circuit/mod.rs index b248b30b1d9..dcb09d429eb 100644 --- a/acvm-repo/acir/src/circuit/mod.rs +++ b/acvm-repo/acir/src/circuit/mod.rs @@ -38,6 +38,10 @@ pub struct Circuit { // Note: This should be a BTreeMap, but serde-reflect is creating invalid // c++ code at the moment when it is, due to OpcodeLocation needing a comparison // implementation which is never generated. + // + // TODO: These are only used for constraints that are explicitly created during code generation (such as index out of bounds on slices) + // TODO: We should move towards having all the checks being evaluated in the same manner + // TODO: as runtime assert messages specified by the user. This will also be a breaking change as the `Circuit` structure will change. pub assert_messages: Vec<(OpcodeLocation, String)>, } diff --git a/acvm-repo/brillig/src/foreign_call.rs b/acvm-repo/brillig/src/foreign_call.rs index 1359d7d604d..3f124a9a0a7 100644 --- a/acvm-repo/brillig/src/foreign_call.rs +++ b/acvm-repo/brillig/src/foreign_call.rs @@ -37,7 +37,7 @@ impl ForeignCallParam { } /// Represents the full output of a [foreign call][crate::Opcode::ForeignCall]. -#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Clone)] +#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Clone, Default)] pub struct ForeignCallResult { /// Resolved output values of the foreign call. pub values: Vec, diff --git a/acvm-repo/brillig_vm/src/lib.rs b/acvm-repo/brillig_vm/src/lib.rs index 0c258ab34d6..38a562e65a1 100644 --- a/acvm-repo/brillig_vm/src/lib.rs +++ b/acvm-repo/brillig_vm/src/lib.rs @@ -242,7 +242,7 @@ impl<'a, B: BlackBoxFunctionSolver> VM<'a, B> { self.registers.set(*value_index, *value); } _ => unreachable!( - "Function result size does not match brillig bytecode (expected 1 result)" + "Function result size does not match brillig bytecode. Expected 1 result but got {output:?}" ), }, RegisterOrMemory::HeapArray(HeapArray { pointer: pointer_index, size }) => { diff --git a/compiler/noirc_driver/Cargo.toml b/compiler/noirc_driver/Cargo.toml index eb9650e8aec..d9b240101d8 100644 --- a/compiler/noirc_driver/Cargo.toml +++ b/compiler/noirc_driver/Cargo.toml @@ -25,3 +25,4 @@ rust-embed.workspace = true tracing.workspace = true aztec_macros = { path = "../../aztec_macros" } +noirc_macros = { path = "../../noirc_macros" } diff --git a/compiler/noirc_driver/src/lib.rs b/compiler/noirc_driver/src/lib.rs index 6fd69f8b576..25d4229048e 100644 --- a/compiler/noirc_driver/src/lib.rs +++ b/compiler/noirc_driver/src/lib.rs @@ -76,7 +76,7 @@ pub struct CompileOptions { #[arg(long, hide = true)] pub only_acir: bool, - /// Disables the builtin macros being used in the compiler + /// Disables the builtin Aztec macros being used in the compiler #[arg(long, hide = true)] pub disable_macros: bool, @@ -191,9 +191,12 @@ pub fn check_crate( disable_macros: bool, ) -> CompilationResult<()> { let macros: Vec<&dyn MacroProcessor> = if disable_macros { - vec![] + vec![&noirc_macros::AssertMessageMacro as &dyn MacroProcessor] } else { - vec![&aztec_macros::AztecMacro as &dyn MacroProcessor] + vec![ + &aztec_macros::AztecMacro as &dyn MacroProcessor, + &noirc_macros::AssertMessageMacro as &dyn MacroProcessor, + ] }; let mut errors = vec![]; @@ -244,6 +247,7 @@ pub fn compile_main( let compiled_program = compile_no_check(context, options, main, cached_program, options.force_compile) .map_err(FileDiagnostic::from)?; + let compilation_warnings = vecmap(compiled_program.warnings.clone(), FileDiagnostic::from); if options.deny_warnings && !compilation_warnings.is_empty() { return Err(compilation_warnings); diff --git a/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs b/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs index b084042981b..632add74e6d 100644 --- a/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs +++ b/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs @@ -3,6 +3,7 @@ use crate::brillig::brillig_ir::{ BrilligBinaryOp, BrilligContext, BRILLIG_INTEGER_ARITHMETIC_BIT_SIZE, }; use crate::ssa::ir::dfg::CallStack; +use crate::ssa::ir::instruction::ConstrainError; use crate::ssa::ir::{ basic_block::{BasicBlock, BasicBlockId}, dfg::DataFlowGraph, @@ -265,7 +266,30 @@ impl<'block> BrilligBlock<'block> { condition, ); - self.brillig_context.constrain_instruction(condition, assert_message.clone()); + let assert_message = if let Some(error) = assert_message { + match error.as_ref() { + ConstrainError::Static(string) => Some(string.clone()), + ConstrainError::Dynamic(call_instruction) => { + let Instruction::Call { func, arguments } = call_instruction else { + unreachable!("expected a call instruction") + }; + + let Value::Function(func_id) = &dfg[*func] else { + unreachable!("expected a function value") + }; + + self.convert_ssa_function_call(*func_id, arguments, dfg, &[]); + + // Dynamic assert messages are handled in the generated function call. + // We then don't need to attach one to the constrain instruction. + None + } + } + } else { + None + }; + + self.brillig_context.constrain_instruction(condition, assert_message); self.brillig_context.deallocate_register(condition); } Instruction::Allocate => { @@ -369,7 +393,8 @@ impl<'block> BrilligBlock<'block> { } } Value::Function(func_id) => { - self.convert_ssa_function_call(*func_id, arguments, dfg, instruction_id); + let result_ids = dfg.instruction_results(instruction_id); + self.convert_ssa_function_call(*func_id, arguments, dfg, result_ids); } Value::Intrinsic(Intrinsic::BlackBox(bb_func)) => { // Slices are represented as a tuple of (length, slice contents). @@ -638,7 +663,7 @@ impl<'block> BrilligBlock<'block> { func_id: FunctionId, arguments: &[ValueId], dfg: &DataFlowGraph, - instruction_id: InstructionId, + result_ids: &[ValueId], ) { // Convert the arguments to registers casting those to the types of the receiving function let argument_registers: Vec = arguments @@ -646,8 +671,6 @@ impl<'block> BrilligBlock<'block> { .flat_map(|argument_id| self.convert_ssa_value(*argument_id, dfg).extract_registers()) .collect(); - let result_ids = dfg.instruction_results(instruction_id); - // Create label for the function that will be called let label_of_function_to_call = FunctionContext::function_id_to_function_label(func_id); diff --git a/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs b/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs index 120c5bf25df..5d067737930 100644 --- a/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs +++ b/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs @@ -7,6 +7,7 @@ use std::fmt::Debug; use self::acir_ir::acir_variable::{AcirContext, AcirType, AcirVar}; use super::function_builder::data_bus::DataBus; use super::ir::dfg::CallStack; +use super::ir::instruction::ConstrainError; use super::{ ir::{ dfg::DataFlowGraph, @@ -413,15 +414,94 @@ impl Context { let lhs = self.convert_numeric_value(*lhs, dfg)?; let rhs = self.convert_numeric_value(*rhs, dfg)?; - self.acir_context.assert_eq_var(lhs, rhs, assert_message.clone())?; + let assert_message = if let Some(error) = assert_message { + match error.as_ref() { + ConstrainError::Static(string) => Some(string.clone()), + ConstrainError::Dynamic(call_instruction) => { + self.convert_ssa_call(call_instruction, dfg, ssa, brillig, &[])?; + None + } + } + } else { + None + }; + + self.acir_context.assert_eq_var(lhs, rhs, assert_message)?; } Instruction::Cast(value_id, _) => { let acir_var = self.convert_numeric_value(*value_id, dfg)?; self.define_result_var(dfg, instruction_id, acir_var); } - Instruction::Call { func, arguments } => { + Instruction::Call { .. } => { let result_ids = dfg.instruction_results(instruction_id); - match &dfg[*func] { + warnings.extend(self.convert_ssa_call( + instruction, + dfg, + ssa, + brillig, + result_ids, + )?); + } + Instruction::Not(value_id) => { + let (acir_var, typ) = match self.convert_value(*value_id, dfg) { + AcirValue::Var(acir_var, typ) => (acir_var, typ), + _ => unreachable!("NOT is only applied to numerics"), + }; + let result_acir_var = self.acir_context.not_var(acir_var, typ)?; + self.define_result_var(dfg, instruction_id, result_acir_var); + } + Instruction::Truncate { value, bit_size, max_bit_size } => { + let result_acir_var = + self.convert_ssa_truncate(*value, *bit_size, *max_bit_size, dfg)?; + self.define_result_var(dfg, instruction_id, result_acir_var); + } + Instruction::EnableSideEffects { condition } => { + let acir_var = self.convert_numeric_value(*condition, dfg)?; + self.current_side_effects_enabled_var = acir_var; + } + Instruction::ArrayGet { .. } | Instruction::ArraySet { .. } => { + self.handle_array_operation(instruction_id, dfg, last_array_uses)?; + } + Instruction::Allocate => { + unreachable!("Expected all allocate instructions to be removed before acir_gen") + } + Instruction::Store { .. } => { + unreachable!("Expected all store instructions to be removed before acir_gen") + } + Instruction::Load { .. } => { + unreachable!("Expected all load instructions to be removed before acir_gen") + } + Instruction::IncrementRc { .. } => { + // Do nothing. Only Brillig needs to worry about reference counted arrays + } + Instruction::RangeCheck { value, max_bit_size, assert_message } => { + let acir_var = self.convert_numeric_value(*value, dfg)?; + self.acir_context.range_constrain_var( + acir_var, + &NumericType::Unsigned { bit_size: *max_bit_size }, + assert_message.clone(), + )?; + } + } + + self.acir_context.set_call_stack(CallStack::new()); + Ok(warnings) + } + + fn convert_ssa_call( + &mut self, + instruction: &Instruction, + dfg: &DataFlowGraph, + ssa: &Ssa, + brillig: &Brillig, + result_ids: &[ValueId], + ) -> Result, RuntimeError> { + let mut warnings = Vec::new(); + + match instruction { + Instruction::Call { func, arguments } => { + let function_value = &dfg[*func]; + match function_value { Value::Function(id) => { let func = &ssa.functions[id]; match func.runtime() { @@ -495,51 +575,11 @@ impl Context { Value::ForeignFunction(_) => unreachable!( "All `oracle` methods should be wrapped in an unconstrained fn" ), - _ => unreachable!("expected calling a function"), + _ => unreachable!("expected calling a function but got {function_value:?}"), } } - Instruction::Not(value_id) => { - let (acir_var, typ) = match self.convert_value(*value_id, dfg) { - AcirValue::Var(acir_var, typ) => (acir_var, typ), - _ => unreachable!("NOT is only applied to numerics"), - }; - let result_acir_var = self.acir_context.not_var(acir_var, typ)?; - self.define_result_var(dfg, instruction_id, result_acir_var); - } - Instruction::Truncate { value, bit_size, max_bit_size } => { - let result_acir_var = - self.convert_ssa_truncate(*value, *bit_size, *max_bit_size, dfg)?; - self.define_result_var(dfg, instruction_id, result_acir_var); - } - Instruction::EnableSideEffects { condition } => { - let acir_var = self.convert_numeric_value(*condition, dfg)?; - self.current_side_effects_enabled_var = acir_var; - } - Instruction::ArrayGet { .. } | Instruction::ArraySet { .. } => { - self.handle_array_operation(instruction_id, dfg, last_array_uses)?; - } - Instruction::Allocate => { - unreachable!("Expected all allocate instructions to be removed before acir_gen") - } - Instruction::Store { .. } => { - unreachable!("Expected all store instructions to be removed before acir_gen") - } - Instruction::Load { .. } => { - unreachable!("Expected all load instructions to be removed before acir_gen") - } - Instruction::IncrementRc { .. } => { - // Do nothing. Only Brillig needs to worry about reference counted arrays - } - Instruction::RangeCheck { value, max_bit_size, assert_message } => { - let acir_var = self.convert_numeric_value(*value, dfg)?; - self.acir_context.range_constrain_var( - acir_var, - &NumericType::Unsigned { bit_size: *max_bit_size }, - assert_message.clone(), - )?; - } + _ => unreachable!("expected calling a call instruction"), } - self.acir_context.set_call_stack(CallStack::new()); Ok(warnings) } diff --git a/compiler/noirc_evaluator/src/ssa/function_builder/mod.rs b/compiler/noirc_evaluator/src/ssa/function_builder/mod.rs index 44be423be10..1cac0aa67ed 100644 --- a/compiler/noirc_evaluator/src/ssa/function_builder/mod.rs +++ b/compiler/noirc_evaluator/src/ssa/function_builder/mod.rs @@ -18,7 +18,7 @@ use super::{ basic_block::BasicBlock, dfg::{CallStack, InsertInstructionResult}, function::RuntimeType, - instruction::{Endian, InstructionId, Intrinsic}, + instruction::{ConstrainError, Endian, InstructionId, Intrinsic}, types::NumericType, }, ssa_gen::Ssa, @@ -250,7 +250,7 @@ impl FunctionBuilder { &mut self, lhs: ValueId, rhs: ValueId, - assert_message: Option, + assert_message: Option>, ) { self.insert_instruction(Instruction::Constrain(lhs, rhs, assert_message), None); } diff --git a/compiler/noirc_evaluator/src/ssa/ir/instruction.rs b/compiler/noirc_evaluator/src/ssa/ir/instruction.rs index 331a02a6974..59f88fe99eb 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/instruction.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/instruction.rs @@ -157,7 +157,7 @@ pub(crate) enum Instruction { Truncate { value: ValueId, bit_size: u32, max_bit_size: u32 }, /// Constrains two values to be equal to one another. - Constrain(ValueId, ValueId, Option), + Constrain(ValueId, ValueId, Option>), /// Range constrain `value` to `max_bit_size` RangeCheck { value: ValueId, max_bit_size: u32, assert_message: Option }, @@ -326,7 +326,17 @@ impl Instruction { max_bit_size: *max_bit_size, }, Instruction::Constrain(lhs, rhs, assert_message) => { - Instruction::Constrain(f(*lhs), f(*rhs), assert_message.clone()) + // Must map the `lhs` and `rhs` first as the value `f` is moved with the closure + let lhs = f(*lhs); + let rhs = f(*rhs); + let assert_message = assert_message.as_ref().map(|error| match error.as_ref() { + ConstrainError::Dynamic(call_instr) => { + let new_instr = call_instr.map_values(f); + Box::new(ConstrainError::Dynamic(new_instr)) + } + _ => error.clone(), + }); + Instruction::Constrain(lhs, rhs, assert_message) } Instruction::Call { func, arguments } => Instruction::Call { func: f(*func), @@ -376,9 +386,14 @@ impl Instruction { | Instruction::Load { address: value } => { f(*value); } - Instruction::Constrain(lhs, rhs, _) => { + Instruction::Constrain(lhs, rhs, assert_error) => { f(*lhs); f(*rhs); + if let Some(error) = assert_error.as_ref() { + if let ConstrainError::Dynamic(call_instr) = error.as_ref() { + call_instr.for_each_value(f); + } + } } Instruction::Store { address, value } => { @@ -441,7 +456,7 @@ impl Instruction { } } Instruction::Constrain(lhs, rhs, msg) => { - let constraints = decompose_constrain(*lhs, *rhs, msg.clone(), dfg); + let constraints = decompose_constrain(*lhs, *rhs, msg, dfg); if constraints.is_empty() { Remove } else { @@ -551,6 +566,28 @@ impl Instruction { } } +#[derive(Debug, PartialEq, Eq, Hash, Clone)] +pub(crate) enum ConstrainError { + // These are errors which have been hardcoded during SSA gen + Static(String), + // These are errors which come from runtime expressions specified by a Noir program + // We store an `Instruction` as we want this Instruction to be atomic in SSA with + // a constrain instruction, and leave codegen of this instruction to lower level passes. + Dynamic(Instruction), +} + +impl From for ConstrainError { + fn from(value: String) -> Self { + ConstrainError::Static(value) + } +} + +impl From for Box { + fn from(value: String) -> Self { + Box::new(value.into()) + } +} + /// The possible return values for Instruction::return_types pub(crate) enum InstructionResultType { /// The result type of this instruction matches that of this operand diff --git a/compiler/noirc_evaluator/src/ssa/ir/instruction/constrain.rs b/compiler/noirc_evaluator/src/ssa/ir/instruction/constrain.rs index 7fb0970c834..0ae0f8f2892 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/instruction/constrain.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/instruction/constrain.rs @@ -1,13 +1,13 @@ use acvm::FieldElement; -use super::{Binary, BinaryOp, DataFlowGraph, Instruction, Type, Value, ValueId}; +use super::{Binary, BinaryOp, ConstrainError, DataFlowGraph, Instruction, Type, Value, ValueId}; /// Try to decompose this constrain instruction. This constraint will be broken down such that it instead constrains /// all the values which are used to compute the values which were being constrained. pub(super) fn decompose_constrain( lhs: ValueId, rhs: ValueId, - msg: Option, + msg: &Option>, dfg: &mut DataFlowGraph, ) -> Vec { let lhs = dfg.resolve(lhs); @@ -39,7 +39,7 @@ pub(super) fn decompose_constrain( // Note that this doesn't remove the value `v2` as it may be used in other instructions, but it // will likely be removed through dead instruction elimination. - vec![Instruction::Constrain(lhs, rhs, msg)] + vec![Instruction::Constrain(lhs, rhs, msg.clone())] } Instruction::Binary(Binary { lhs, rhs, operator: BinaryOp::Mul }) @@ -64,7 +64,7 @@ pub(super) fn decompose_constrain( let one = dfg.make_constant(one, Type::bool()); [ - decompose_constrain(lhs, one, msg.clone(), dfg), + decompose_constrain(lhs, one, msg, dfg), decompose_constrain(rhs, one, msg, dfg), ] .concat() @@ -92,7 +92,7 @@ pub(super) fn decompose_constrain( let zero = dfg.make_constant(zero, dfg.type_of_value(lhs)); [ - decompose_constrain(lhs, zero, msg.clone(), dfg), + decompose_constrain(lhs, zero, msg, dfg), decompose_constrain(rhs, zero, msg, dfg), ] .concat() @@ -116,11 +116,11 @@ pub(super) fn decompose_constrain( decompose_constrain(value, reversed_constant, msg, dfg) } - _ => vec![Instruction::Constrain(lhs, rhs, msg)], + _ => vec![Instruction::Constrain(lhs, rhs, msg.clone())], } } - _ => vec![Instruction::Constrain(lhs, rhs, msg)], + _ => vec![Instruction::Constrain(lhs, rhs, msg.clone())], } } } diff --git a/compiler/noirc_evaluator/src/ssa/ir/printer.rs b/compiler/noirc_evaluator/src/ssa/ir/printer.rs index 2899b987c1d..9bd43fab1ff 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/printer.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/printer.rs @@ -9,7 +9,7 @@ use iter_extended::vecmap; use super::{ basic_block::BasicBlockId, function::Function, - instruction::{Instruction, InstructionId, TerminatorInstruction}, + instruction::{ConstrainError, Instruction, InstructionId, TerminatorInstruction}, value::ValueId, }; @@ -133,9 +133,17 @@ pub(crate) fn display_instruction( write!(f, "{} = ", value_list(function, results))?; } + display_instruction_inner(function, &function.dfg[instruction], f) +} + +fn display_instruction_inner( + function: &Function, + instruction: &Instruction, + f: &mut Formatter, +) -> Result { let show = |id| value(function, id); - match &function.dfg[instruction] { + match instruction { Instruction::Binary(binary) => { writeln!(f, "{} {}, {}", binary.operator, show(binary.lhs), show(binary.rhs)) } @@ -145,10 +153,15 @@ pub(crate) fn display_instruction( let value = show(*value); writeln!(f, "truncate {value} to {bit_size} bits, max_bit_size: {max_bit_size}",) } - Instruction::Constrain(lhs, rhs, message) => match message { - Some(message) => writeln!(f, "constrain {} == {} '{message}'", show(*lhs), show(*rhs)), - None => writeln!(f, "constrain {} == {}", show(*lhs), show(*rhs)), - }, + Instruction::Constrain(lhs, rhs, error) => { + write!(f, "constrain {} == {}", show(*lhs), show(*rhs))?; + if let Some(error) = error { + write!(f, " ")?; + display_constrain_error(function, error, f) + } else { + writeln!(f) + } + } Instruction::Call { func, arguments } => { writeln!(f, "call {}({})", show(*func), value_list(function, arguments)) } @@ -180,3 +193,18 @@ pub(crate) fn display_instruction( } } } + +fn display_constrain_error( + function: &Function, + error: &ConstrainError, + f: &mut Formatter, +) -> Result { + match error { + ConstrainError::Static(assert_message_string) => { + writeln!(f, "{assert_message_string:?}") + } + ConstrainError::Dynamic(assert_message_call) => { + display_instruction_inner(function, assert_message_call, f) + } + } +} diff --git a/compiler/noirc_evaluator/src/ssa/opt/bubble_up_constrains.rs b/compiler/noirc_evaluator/src/ssa/opt/bubble_up_constrains.rs index 8a903cbd87b..b737c51d145 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/bubble_up_constrains.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/bubble_up_constrains.rs @@ -109,11 +109,11 @@ mod test { let v1 = builder.insert_binary(v0, BinaryOp::Add, one); let v2 = builder.insert_binary(v1, BinaryOp::Add, one); - builder.insert_constrain(v0, one, Some("With message".to_string())); + builder.insert_constrain(v0, one, Some("With message".to_string().into())); builder.insert_constrain(v2, three, None); builder.insert_constrain(v0, one, None); builder.insert_constrain(v1, two, None); - builder.insert_constrain(v1, two, Some("With message".to_string())); + builder.insert_constrain(v1, two, Some("With message".to_string().into())); builder.terminate_with_return(vec![]); let ssa = builder.finish(); @@ -137,11 +137,11 @@ mod test { assert_eq!(block.instructions().len(), 7); let expected_instructions = vec![ - Instruction::Constrain(v0, one, Some("With message".to_string())), + Instruction::Constrain(v0, one, Some("With message".to_string().into())), Instruction::Constrain(v0, one, None), Instruction::Binary(Binary { lhs: v0, rhs: one, operator: BinaryOp::Add }), Instruction::Constrain(v1, two, None), - Instruction::Constrain(v1, two, Some("With message".to_string())), + Instruction::Constrain(v1, two, Some("With message".to_string().into())), Instruction::Binary(Binary { lhs: v1, rhs: one, operator: BinaryOp::Add }), Instruction::Constrain(v2, three, None), ]; diff --git a/compiler/noirc_evaluator/src/ssa/opt/defunctionalize.rs b/compiler/noirc_evaluator/src/ssa/opt/defunctionalize.rs index b7f154397a6..1f09a132132 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/defunctionalize.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/defunctionalize.rs @@ -14,7 +14,7 @@ use crate::ssa::{ ir::{ basic_block::BasicBlockId, function::{Function, FunctionId, RuntimeType, Signature}, - instruction::{BinaryOp, Instruction}, + instruction::{BinaryOp, ConstrainError, Instruction}, types::{NumericType, Type}, value::{Value, ValueId}, }, @@ -86,9 +86,22 @@ impl DefunctionalizationContext { let instruction = func.dfg[instruction_id].clone(); let mut replacement_instruction = None; // Operate on call instructions - let (target_func_id, mut arguments) = match instruction { + let (target_func_id, arguments) = match &instruction { Instruction::Call { func: target_func_id, arguments } => { - (target_func_id, arguments) + (*target_func_id, arguments) + } + // Constrain instruction potentially hold a call instruction themselves + // thus we need to account for them. + Instruction::Constrain(_, _, Some(constrain_error)) => { + if let ConstrainError::Dynamic(Instruction::Call { + func: target_func_id, + arguments, + }) = constrain_error.as_ref() + { + (*target_func_id, arguments) + } else { + continue; + } } _ => continue, }; @@ -96,6 +109,7 @@ impl DefunctionalizationContext { match func.dfg[target_func_id] { // If the target is a function used as value Value::Param { .. } | Value::Instruction { .. } => { + let mut arguments = arguments.clone(); let results = func.dfg.instruction_results(instruction_id); let signature = Signature { params: vecmap(&arguments, |param| func.dfg.type_of_value(*param)), @@ -120,7 +134,20 @@ impl DefunctionalizationContext { } _ => {} } - if let Some(new_instruction) = replacement_instruction { + if let Some(mut new_instruction) = replacement_instruction { + if let Instruction::Constrain(lhs, rhs, constrain_error_call) = instruction { + let new_error_call = if let Some(error) = constrain_error_call { + match error.as_ref() { + ConstrainError::Dynamic(_) => { + Some(Box::new(ConstrainError::Dynamic(new_instruction))) + } + _ => None, + } + } else { + None + }; + new_instruction = Instruction::Constrain(lhs, rhs, new_error_call); + } func.dfg[instruction_id] = new_instruction; } } diff --git a/compiler/noirc_evaluator/src/ssa/ssa_gen/context.rs b/compiler/noirc_evaluator/src/ssa/ssa_gen/context.rs index 0e155776545..adf68bacba4 100644 --- a/compiler/noirc_evaluator/src/ssa/ssa_gen/context.rs +++ b/compiler/noirc_evaluator/src/ssa/ssa_gen/context.rs @@ -435,7 +435,7 @@ impl<'a> FunctionContext<'a> { self.builder.set_location(location).insert_constrain( sign, one, - Some("attempt to bit-shift with overflow".to_string()), + Some("attempt to bit-shift with overflow".to_owned().into()), ); } @@ -446,7 +446,7 @@ impl<'a> FunctionContext<'a> { self.builder.set_location(location).insert_constrain( overflow, one, - Some("attempt to bit-shift with overflow".to_owned()), + Some("attempt to bit-shift with overflow".to_owned().into()), ); self.builder.insert_truncate(result, bit_size, bit_size + 1) } @@ -498,8 +498,11 @@ impl<'a> FunctionContext<'a> { let sign_diff = self.builder.insert_binary(result_sign, BinaryOp::Eq, lhs_sign); let sign_diff_with_predicate = self.builder.insert_binary(sign_diff, BinaryOp::Mul, same_sign); - let overflow_check = - Instruction::Constrain(sign_diff_with_predicate, same_sign, Some(message)); + let overflow_check = Instruction::Constrain( + sign_diff_with_predicate, + same_sign, + Some(message.into()), + ); self.builder.set_location(location).insert_instruction(overflow_check, None); } BinaryOpKind::Multiply => { @@ -509,11 +512,10 @@ impl<'a> FunctionContext<'a> { let rhs_abs = self.absolute_value_helper(rhs, rhs_sign, bit_size); let product_field = self.builder.insert_binary(lhs_abs, BinaryOp::Mul, rhs_abs); // It must not already overflow the bit_size - let message = "attempt to multiply with overflow".to_string(); self.builder.set_location(location).insert_range_check( product_field, bit_size, - Some(message.clone()), + Some("attempt to multiply with overflow".to_string()), ); let product = self.builder.insert_cast(product_field, Type::unsigned(bit_size)); @@ -530,7 +532,7 @@ impl<'a> FunctionContext<'a> { self.builder.set_location(location).insert_constrain( product_overflow_check, one, - Some(message), + Some(message.into()), ); } _ => unreachable!("operator {} should not overflow", operator), diff --git a/compiler/noirc_evaluator/src/ssa/ssa_gen/mod.rs b/compiler/noirc_evaluator/src/ssa/ssa_gen/mod.rs index 9d9635fed34..0efc73fb85b 100644 --- a/compiler/noirc_evaluator/src/ssa/ssa_gen/mod.rs +++ b/compiler/noirc_evaluator/src/ssa/ssa_gen/mod.rs @@ -13,7 +13,7 @@ use noirc_frontend::{ }; use crate::{ - errors::RuntimeError, + errors::{InternalError, RuntimeError}, ssa::{ function_builder::data_bus::DataBusBuilder, ir::{instruction::Intrinsic, types::NumericType}, @@ -29,7 +29,7 @@ use super::{ function_builder::data_bus::DataBus, ir::{ function::RuntimeType, - instruction::{BinaryOp, TerminatorInstruction}, + instruction::{BinaryOp, ConstrainError, Instruction, TerminatorInstruction}, types::Type, value::ValueId, }, @@ -141,7 +141,7 @@ impl<'a> FunctionContext<'a> { Expression::Call(call) => self.codegen_call(call), Expression::Let(let_expr) => self.codegen_let(let_expr), Expression::Constrain(expr, location, assert_message) => { - self.codegen_constrain(expr, *location, assert_message.clone()) + self.codegen_constrain(expr, *location, assert_message) } Expression::Assign(assign) => self.codegen_assign(assign), Expression::Semi(semi) => self.codegen_semi(semi), @@ -438,10 +438,11 @@ impl<'a> FunctionContext<'a> { let is_offset_out_of_bounds = self.builder.insert_binary(index, BinaryOp::Lt, array_len); let true_const = self.builder.numeric_constant(true, Type::bool()); + self.builder.insert_constrain( is_offset_out_of_bounds, true_const, - Some("Index out of bounds".to_owned()), + Some(Box::new("Index out of bounds".to_owned().into())), ); } @@ -665,15 +666,59 @@ impl<'a> FunctionContext<'a> { &mut self, expr: &Expression, location: Location, - assert_message: Option, + assert_message: &Option>, ) -> Result { let expr = self.codegen_non_tuple_expression(expr)?; let true_literal = self.builder.numeric_constant(true, Type::bool()); - self.builder.set_location(location).insert_constrain(expr, true_literal, assert_message); + + // Set the location here for any errors that may occur when we codegen the assert message + self.builder.set_location(location); + + let assert_message = self.codegen_constrain_error(assert_message)?; + + self.builder.insert_constrain(expr, true_literal, assert_message); Ok(Self::unit_value()) } + // This method does not necessary codegen the full assert message expression, thus it does not + // return a `Values` object. Instead we check the internals of the expression to make sure + // we have an `Expression::Call` as expected. An `Instruction::Call` is then constructed but not + // inserted to the SSA as we want that instruction to be atomic in SSA with a constrain instruction. + fn codegen_constrain_error( + &mut self, + assert_message: &Option>, + ) -> Result>, RuntimeError> { + let Some(assert_message_expr) = assert_message else { + return Ok(None) + }; + + let ast::Expression::Call(call) = assert_message_expr.as_ref() else { + return Err(InternalError::Unexpected { + expected: "Expected a call expression".to_owned(), + found: "Instead found {expr:?}".to_owned(), + call_stack: self.builder.get_call_stack(), + } + .into()); + }; + + let func = self.codegen_non_tuple_expression(&call.func)?; + let mut arguments = Vec::with_capacity(call.arguments.len()); + + for argument in &call.arguments { + let mut values = self.codegen_expression(argument)?.into_value_list(self); + arguments.append(&mut values); + } + + // If an array is passed as an argument we increase its reference count + for argument in &arguments { + self.builder.increment_array_reference_count(*argument); + } + + let instr = Instruction::Call { func, arguments }; + Ok(Some(Box::new(ConstrainError::Dynamic(instr)))) + } + fn codegen_assign(&mut self, assign: &ast::Assign) -> Result { let lhs = self.extract_current_value(&assign.lvalue)?; let rhs = self.codegen_expression(&assign.expression)?; diff --git a/compiler/noirc_frontend/src/ast/statement.rs b/compiler/noirc_frontend/src/ast/statement.rs index 73b1f68778d..a2c29a8c52e 100644 --- a/compiler/noirc_frontend/src/ast/statement.rs +++ b/compiler/noirc_frontend/src/ast/statement.rs @@ -416,7 +416,7 @@ pub enum LValue { } #[derive(Debug, PartialEq, Eq, Clone)] -pub struct ConstrainStatement(pub Expression, pub Option, pub ConstrainKind); +pub struct ConstrainStatement(pub Expression, pub Option, pub ConstrainKind); #[derive(Debug, PartialEq, Eq, Clone, Copy)] pub enum ConstrainKind { diff --git a/compiler/noirc_frontend/src/hir/resolution/resolver.rs b/compiler/noirc_frontend/src/hir/resolution/resolver.rs index 8243b684c8a..7b876244601 100644 --- a/compiler/noirc_frontend/src/hir/resolution/resolver.rs +++ b/compiler/noirc_frontend/src/hir/resolution/resolver.rs @@ -1133,9 +1133,16 @@ impl<'a> Resolver<'a> { }) } StatementKind::Constrain(constrain_stmt) => { + let span = constrain_stmt.0.span; + let assert_msg_call_expr_id = + self.resolve_assert_message(constrain_stmt.1, span, constrain_stmt.0.clone()); let expr_id = self.resolve_expression(constrain_stmt.0); - let assert_message = constrain_stmt.1; - HirStatement::Constrain(HirConstrainStatement(expr_id, self.file, assert_message)) + + HirStatement::Constrain(HirConstrainStatement( + expr_id, + self.file, + assert_msg_call_expr_id, + )) } StatementKind::Expression(expr) => { HirStatement::Expression(self.resolve_expression(expr)) @@ -1184,6 +1191,41 @@ impl<'a> Resolver<'a> { } } + fn resolve_assert_message( + &mut self, + assert_message_expr: Option, + span: Span, + condition: Expression, + ) -> Option { + let mut assert_msg_call_args = if let Some(assert_message_expr) = assert_message_expr { + vec![assert_message_expr.clone()] + } else { + return None; + }; + assert_msg_call_args.push(condition); + + let is_in_stdlib = self.path_resolver.module_id().krate.is_stdlib(); + let assert_msg_call_path = if is_in_stdlib { + ExpressionKind::Variable(Path { + segments: vec![Ident::from("resolve_assert_message")], + kind: PathKind::Crate, + span, + }) + } else { + ExpressionKind::Variable(Path { + segments: vec![Ident::from("std"), Ident::from("resolve_assert_message")], + kind: PathKind::Dep, + span, + }) + }; + let assert_msg_call_expr = Expression::call( + Expression { kind: assert_msg_call_path, span }, + assert_msg_call_args, + span, + ); + Some(self.resolve_expression(assert_msg_call_expr)) + } + pub fn intern_stmt(&mut self, stmt: StatementKind) -> StmtId { let hir_stmt = self.resolve_stmt(stmt); self.interner.push_stmt(hir_stmt) diff --git a/compiler/noirc_frontend/src/hir/type_check/stmt.rs b/compiler/noirc_frontend/src/hir/type_check/stmt.rs index fd8ae62d34e..a38a16a6580 100644 --- a/compiler/noirc_frontend/src/hir/type_check/stmt.rs +++ b/compiler/noirc_frontend/src/hir/type_check/stmt.rs @@ -303,6 +303,9 @@ impl<'interner> TypeChecker<'interner> { let expr_type = self.check_expression(&stmt.0); let expr_span = self.interner.expr_span(&stmt.0); + // Must type check the assertion message expression so that we instantiate bindings + stmt.2.map(|assert_msg_expr| self.check_expression(&assert_msg_expr)); + self.unify(&expr_type, &Type::Bool, || TypeCheckError::TypeMismatch { expr_typ: expr_type.to_string(), expected_typ: Type::Bool.to_string(), diff --git a/compiler/noirc_frontend/src/hir_def/stmt.rs b/compiler/noirc_frontend/src/hir_def/stmt.rs index 34c9302c251..4d946690151 100644 --- a/compiler/noirc_frontend/src/hir_def/stmt.rs +++ b/compiler/noirc_frontend/src/hir_def/stmt.rs @@ -55,7 +55,7 @@ pub struct HirAssignStatement { /// originates from. This is used later in the SSA pass to issue /// an error if a constrain is found to be always false. #[derive(Debug, Clone)] -pub struct HirConstrainStatement(pub ExprId, pub FileId, pub Option); +pub struct HirConstrainStatement(pub ExprId, pub FileId, pub Option); #[derive(Debug, Clone, Hash)] pub enum HirPattern { diff --git a/compiler/noirc_frontend/src/lib.rs b/compiler/noirc_frontend/src/lib.rs index b6d4c568334..b14cb632f81 100644 --- a/compiler/noirc_frontend/src/lib.rs +++ b/compiler/noirc_frontend/src/lib.rs @@ -48,7 +48,7 @@ pub mod macros_api { pub use crate::hir_def::expr::{HirExpression, HirLiteral}; pub use crate::hir_def::stmt::HirStatement; pub use crate::node_interner::{NodeInterner, StructId}; - pub use crate::parser::SortedModule; + pub use crate::parser::{parse_program, SortedModule}; pub use crate::token::SecondaryAttribute; pub use crate::hir::def_map::ModuleDefId; diff --git a/compiler/noirc_frontend/src/monomorphization/ast.rs b/compiler/noirc_frontend/src/monomorphization/ast.rs index 42a618e7d77..5172eabde46 100644 --- a/compiler/noirc_frontend/src/monomorphization/ast.rs +++ b/compiler/noirc_frontend/src/monomorphization/ast.rs @@ -31,7 +31,7 @@ pub enum Expression { ExtractTupleField(Box, usize), Call(Call), Let(Let), - Constrain(Box, Location, Option), + Constrain(Box, Location, Option>), Assign(Assign), Semi(Box), } diff --git a/compiler/noirc_frontend/src/monomorphization/mod.rs b/compiler/noirc_frontend/src/monomorphization/mod.rs index 67b246a02ce..663731d462c 100644 --- a/compiler/noirc_frontend/src/monomorphization/mod.rs +++ b/compiler/noirc_frontend/src/monomorphization/mod.rs @@ -479,7 +479,9 @@ impl<'interner> Monomorphizer<'interner> { HirStatement::Constrain(constrain) => { let expr = self.expr(constrain.0); let location = self.interner.expr_location(&constrain.0); - ast::Expression::Constrain(Box::new(expr), location, constrain.2) + let assert_message = + constrain.2.map(|assert_msg_expr| Box::new(self.expr(assert_msg_expr))); + ast::Expression::Constrain(Box::new(expr), location, assert_message) } HirStatement::Assign(assign) => self.assign(assign), HirStatement::For(for_loop) => { @@ -929,6 +931,9 @@ impl<'interner> Monomorphizer<'interner> { // The first argument to the `print` oracle is a bool, indicating a newline to be inserted at the end of the input // The second argument is expected to always be an ident self.append_printable_type_info(&hir_arguments[1], &mut arguments); + } else if name.as_str() == "assert_message" { + // The first argument to the `assert_message` oracle is the expression passed as a mesage to an `assert` or `assert_eq` statement + self.append_printable_type_info(&hir_arguments[0], &mut arguments); } } } @@ -1024,7 +1029,7 @@ impl<'interner> Monomorphizer<'interner> { // The caller needs information as to whether it is handling a format string or a single type arguments.push(ast::Expression::Literal(ast::Literal::Bool(is_fmt_str))); } - _ => unreachable!("logging expr {:?} is not supported", arguments[0]), + _ => unreachable!("logging expr {:?} is not supported", hir_argument), } } diff --git a/compiler/noirc_frontend/src/parser/parser.rs b/compiler/noirc_frontend/src/parser/parser.rs index f82ce95c718..1bdb276d4fb 100644 --- a/compiler/noirc_frontend/src/parser/parser.rs +++ b/compiler/noirc_frontend/src/parser/parser.rs @@ -832,23 +832,10 @@ where ignore_then_commit(keyword(Keyword::Assert), parenthesized(argument_parser)) .labelled(ParsingRuleLabel::Statement) - .validate(|expressions, span, emit| { + .validate(|expressions, span, _| { let condition = expressions.get(0).unwrap_or(&Expression::error(span)).clone(); - let mut message_str = None; - - if let Some(message) = expressions.get(1) { - if let ExpressionKind::Literal(Literal::Str(message)) = &message.kind { - message_str = Some(message.clone()); - } else { - emit(ParserError::with_reason(ParserErrorReason::AssertMessageNotString, span)); - } - } - - StatementKind::Constrain(ConstrainStatement( - condition, - message_str, - ConstrainKind::Assert, - )) + let message = expressions.get(1).cloned(); + StatementKind::Constrain(ConstrainStatement(condition, message, ConstrainKind::Assert)) }) } @@ -861,7 +848,7 @@ where ignore_then_commit(keyword(Keyword::AssertEq), parenthesized(argument_parser)) .labelled(ParsingRuleLabel::Statement) - .validate(|exprs: Vec, span, emit| { + .validate(|exprs: Vec, span, _| { let predicate = Expression::new( ExpressionKind::Infix(Box::new(InfixExpression { lhs: exprs.get(0).unwrap_or(&Expression::error(span)).clone(), @@ -870,18 +857,10 @@ where })), span, ); - let mut message_str = None; - - if let Some(message) = exprs.get(2) { - if let ExpressionKind::Literal(Literal::Str(message)) = &message.kind { - message_str = Some(message.clone()); - } else { - emit(ParserError::with_reason(ParserErrorReason::AssertMessageNotString, span)); - } - } + let message = exprs.get(2).cloned(); StatementKind::Constrain(ConstrainStatement( predicate, - message_str, + message, ConstrainKind::AssertEq, )) }) @@ -2092,7 +2071,13 @@ mod test { match parse_with(assertion(expression()), "assert(x == y, \"assertion message\")").unwrap() { StatementKind::Constrain(ConstrainStatement(_, message, _)) => { - assert_eq!(message, Some("assertion message".to_owned())); + let message = message.unwrap(); + match message.kind { + ExpressionKind::Literal(Literal::Str(message_string)) => { + assert_eq!(message_string, "assertion message".to_owned()); + } + _ => unreachable!(), + } } _ => unreachable!(), } @@ -2116,7 +2101,13 @@ mod test { .unwrap() { StatementKind::Constrain(ConstrainStatement(_, message, _)) => { - assert_eq!(message, Some("assertion message".to_owned())); + let message = message.unwrap(); + match message.kind { + ExpressionKind::Literal(Literal::Str(message_string)) => { + assert_eq!(message_string, "assertion message".to_owned()); + } + _ => unreachable!(), + } } _ => unreachable!(), } @@ -2483,7 +2474,7 @@ mod test { Case { source: "assert(x == x, x)", expect: "constrain (plain::x == plain::x)", - errors: 1, + errors: 0, }, Case { source: "assert_eq(x,)", expect: "constrain (Error == Error)", errors: 1 }, Case { @@ -2494,7 +2485,7 @@ mod test { Case { source: "assert_eq(x, x, x)", expect: "constrain (plain::x == plain::x)", - errors: 1, + errors: 0, }, ]; diff --git a/compiler/noirc_printable_type/src/lib.rs b/compiler/noirc_printable_type/src/lib.rs index 18f2fe0a873..eb206f0af3d 100644 --- a/compiler/noirc_printable_type/src/lib.rs +++ b/compiler/noirc_printable_type/src/lib.rs @@ -69,6 +69,9 @@ pub enum ForeignCallError { #[error("Failed calling external resolver. {0}")] ExternalResolverError(#[from] jsonrpc::Error), + + #[error("Assert message resolved after an unsatisified constrain. {0}")] + ResolvedAssertMessage(String), } impl TryFrom<&[ForeignCallParam]> for PrintableValueDisplay { diff --git a/docs/docs/noir/concepts/assert.md b/docs/docs/noir/concepts/assert.md index c5f9aff139c..bcff613a695 100644 --- a/docs/docs/noir/concepts/assert.md +++ b/docs/docs/noir/concepts/assert.md @@ -18,10 +18,28 @@ fn main(x : Field, y : Field) { } ``` +> Assertions only work for predicate operations, such as `==`. If there's any ambiguity on the operation, the program will fail to compile. For example, it is unclear if `assert(x + y)` would check for `x + y == 0` or simply would return `true`. + You can optionally provide a message to be logged when the assertion fails: ```rust assert(x == y, "x and y are not equal"); ``` -> Assertions only work for predicate operations, such as `==`. If there's any ambiguity on the operation, the program will fail to compile. For example, it is unclear if `assert(x + y)` would check for `x + y == 0` or simply would return `true`. +Aside string literals, the optional message can be a format string or any other type supported as input for Noir's [print](../standard_library/logging.md) functions. This feature lets you incorporate runtime variables into your failed assertion logs: + +```rust +assert(x == y, f"Expected x == y, but got {x} == {y}"); +``` + +Using a variable as an assertion message directly: + +```rust +struct myStruct { + myField: Field +} + +let s = myStruct { myField: y }; +assert(s.myField == x, s); +``` + diff --git a/noirc_macros/Cargo.toml b/noirc_macros/Cargo.toml new file mode 100644 index 00000000000..699e6b01cae --- /dev/null +++ b/noirc_macros/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "noirc_macros" +version.workspace = true +authors.workspace = true +edition.workspace = true +rust-version.workspace = true +license.workspace = true +repository.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +noirc_frontend.workspace = true +iter-extended.workspace = true \ No newline at end of file diff --git a/noirc_macros/src/lib.rs b/noirc_macros/src/lib.rs new file mode 100644 index 00000000000..4337214d69f --- /dev/null +++ b/noirc_macros/src/lib.rs @@ -0,0 +1,61 @@ +use noirc_frontend::macros_api::parse_program; +use noirc_frontend::macros_api::HirContext; +use noirc_frontend::macros_api::SortedModule; +use noirc_frontend::macros_api::{CrateId, FileId}; +use noirc_frontend::macros_api::{MacroError, MacroProcessor}; + +pub struct AssertMessageMacro; + +impl MacroProcessor for AssertMessageMacro { + fn process_untyped_ast( + &self, + ast: SortedModule, + crate_id: &CrateId, + _context: &HirContext, + ) -> Result { + transform(ast, crate_id) + } + + // This macro does not need to process any information after name resolution + fn process_typed_ast( + &self, + _crate_id: &CrateId, + _context: &mut HirContext, + ) -> Result<(), (MacroError, FileId)> { + Ok(()) + } +} + +fn transform(ast: SortedModule, crate_id: &CrateId) -> Result { + let ast = add_resolve_assert_message_funcs(ast, crate_id)?; + + Ok(ast) +} + +fn add_resolve_assert_message_funcs( + mut ast: SortedModule, + crate_id: &CrateId, +) -> Result { + if !crate_id.is_stdlib() { + return Ok(ast); + } + let assert_message_oracles = " + #[oracle(assert_message)] + unconstrained fn assert_message_oracle(_input: T) {} + unconstrained pub fn resolve_assert_message(input: T, condition: bool) { + if !condition { + assert_message_oracle(input); + } + }"; + + let (assert_msg_funcs_ast, errors) = parse_program(assert_message_oracles); + assert_eq!(errors.len(), 0, "Failed to parse Noir macro code. This is either a bug in the compiler or the Noir macro code"); + + let assert_msg_funcs_ast = assert_msg_funcs_ast.into_sorted(); + + for func in assert_msg_funcs_ast.functions { + ast.functions.push(func) + } + + Ok(ast) +} diff --git a/test_programs/compile_failure/assert_msg_runtime/Nargo.toml b/test_programs/compile_failure/assert_msg_runtime/Nargo.toml new file mode 100644 index 00000000000..765f632ff74 --- /dev/null +++ b/test_programs/compile_failure/assert_msg_runtime/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "assert_msg_runtime" +type = "bin" +authors = [""] +compiler_version = ">=0.23.0" + +[dependencies] \ No newline at end of file diff --git a/test_programs/compile_failure/assert_msg_runtime/src/main.nr b/test_programs/compile_failure/assert_msg_runtime/src/main.nr new file mode 100644 index 00000000000..bec3082550a --- /dev/null +++ b/test_programs/compile_failure/assert_msg_runtime/src/main.nr @@ -0,0 +1,7 @@ +fn main(x: Field, y: pub Field) { + assert(x != y, f"Expected x != y, but got both equal {x}"); + assert(x != y); + let z = x + y; + assert(z != y, f"Expected z != y, but got both equal {z}"); + assert_eq(x, y, f"Expected x == y, but x is {x} and y is {y}"); +} \ No newline at end of file diff --git a/test_programs/compile_failure/brillig_assert_msg_runtime/Nargo.toml b/test_programs/compile_failure/brillig_assert_msg_runtime/Nargo.toml new file mode 100644 index 00000000000..00f97b7273a --- /dev/null +++ b/test_programs/compile_failure/brillig_assert_msg_runtime/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "brillig_assert_msg_runtime" +type = "bin" +authors = [""] +compiler_version = ">=0.23.0" + +[dependencies] \ No newline at end of file diff --git a/test_programs/compile_failure/brillig_assert_msg_runtime/src/main.nr b/test_programs/compile_failure/brillig_assert_msg_runtime/src/main.nr new file mode 100644 index 00000000000..428b2006363 --- /dev/null +++ b/test_programs/compile_failure/brillig_assert_msg_runtime/src/main.nr @@ -0,0 +1,10 @@ +fn main(x: Field) { + assert(1 == conditional(x)); +} + +unconstrained fn conditional(x: Field) -> Field { + let z = x as u8 + 20; + assert_eq(z, 25, f"Expected 25 but got {z}"); + assert(x == 10, f"Expected x to equal 10, but got {x}"); + 1 +} \ No newline at end of file diff --git a/test_programs/compile_success_empty/method_call_regression/Nargo.toml b/test_programs/compile_success_empty/method_call_regression/Nargo.toml index 92c9b942008..09f95590aad 100644 --- a/test_programs/compile_success_empty/method_call_regression/Nargo.toml +++ b/test_programs/compile_success_empty/method_call_regression/Nargo.toml @@ -1,5 +1,5 @@ [package] -name = "short" +name = "method_call_regression" type = "bin" authors = [""] compiler_version = ">=0.19.4" diff --git a/test_programs/compile_success_empty/trait_static_methods/Nargo.toml b/test_programs/compile_success_empty/trait_static_methods/Nargo.toml index 71c541ccd4f..ea30031b9a5 100644 --- a/test_programs/compile_success_empty/trait_static_methods/Nargo.toml +++ b/test_programs/compile_success_empty/trait_static_methods/Nargo.toml @@ -1,5 +1,5 @@ [package] -name = "trait_self" +name = "trait_static_methods" type = "bin" authors = [""] diff --git a/test_programs/execution_success/brillig_assert/src/main.nr b/test_programs/execution_success/brillig_assert/src/main.nr index 91e4cebd9d3..16fe7b29061 100644 --- a/test_programs/execution_success/brillig_assert/src/main.nr +++ b/test_programs/execution_success/brillig_assert/src/main.nr @@ -6,7 +6,7 @@ fn main(x: Field) { } unconstrained fn conditional(x: bool) -> Field { - assert(x, "x is false"); - assert_eq(x, true, "x is false"); + assert(x, f"Expected x to be false but got {x}"); + assert_eq(x, true, f"Expected x to be false but got {x}"); 1 } diff --git a/test_programs/execution_success/debug_logs/src/main.nr b/test_programs/execution_success/debug_logs/src/main.nr index 52c910065c1..b640e4f5f0c 100644 --- a/test_programs/execution_success/debug_logs/src/main.nr +++ b/test_programs/execution_success/debug_logs/src/main.nr @@ -3,8 +3,15 @@ use dep::std; fn main(x: Field, y: pub Field) { let string = "i: {i}, j: {j}"; std::println(string); + + // TODO: fmtstr cannot be printed + // let fmt_str: fmtstr<14, (Field, Field)> = f"i: {x}, j: {y}"; + // let fmt_fmt_str = f"fmtstr: {fmt_str}, i: {x}"; + // std::println(fmt_fmt_str); + // A `fmtstr` lets you easily perform string interpolation. let fmt_str: fmtstr<14, (Field, Field)> = f"i: {x}, j: {y}"; + let fmt_str = string_identity(fmt_str); std::println(fmt_str); diff --git a/tooling/debugger/src/context.rs b/tooling/debugger/src/context.rs index 12b55708b15..ab807c65a46 100644 --- a/tooling/debugger/src/context.rs +++ b/tooling/debugger/src/context.rs @@ -1,5 +1,6 @@ use acvm::acir::circuit::{Circuit, Opcode, OpcodeLocation}; use acvm::acir::native_types::{Witness, WitnessMap}; +use acvm::brillig_vm::brillig::ForeignCallResult; use acvm::brillig_vm::{brillig::Value, Registers}; use acvm::pwg::{ ACVMStatus, BrilligSolver, BrilligSolverStatus, ForeignCallWaitInfo, StepResult, ACVM, @@ -224,6 +225,9 @@ impl<'a, B: BlackBoxFunctionSolver> DebugContext<'a, B> { let foreign_call_result = self.foreign_call_executor.execute(&foreign_call); match foreign_call_result { Ok(foreign_call_result) => { + let foreign_call_result = foreign_call_result + .get_brillig_output() + .unwrap_or(ForeignCallResult::default()); if let Some(mut solver) = self.brillig_solver.take() { solver.resolve_pending_foreign_call(foreign_call_result); self.brillig_solver = Some(solver); diff --git a/tooling/nargo/src/ops/execute.rs b/tooling/nargo/src/ops/execute.rs index 4fc7f7b599f..370393fea09 100644 --- a/tooling/nargo/src/ops/execute.rs +++ b/tooling/nargo/src/ops/execute.rs @@ -1,3 +1,4 @@ +use acvm::brillig_vm::brillig::ForeignCallResult; use acvm::pwg::{ACVMStatus, ErrorLocation, OpcodeResolutionError, ACVM}; use acvm::BlackBoxFunctionSolver; use acvm::{acir::circuit::Circuit, acir::native_types::WitnessMap}; @@ -5,7 +6,7 @@ use acvm::{acir::circuit::Circuit, acir::native_types::WitnessMap}; use crate::errors::ExecutionError; use crate::NargoError; -use super::foreign_calls::ForeignCallExecutor; +use super::foreign_calls::{ForeignCallExecutor, NargoForeignCallResult}; #[tracing::instrument(level = "trace", skip_all)] pub fn execute_circuit( @@ -16,6 +17,8 @@ pub fn execute_circuit( ) -> Result { let mut acvm = ACVM::new(blackbox_solver, &circuit.opcodes, initial_witness); + // This message should be resolved by a nargo foreign call only when we have an unsatisfied assertion. + let mut assert_message: Option = None; loop { let solver_status = acvm.solve(); @@ -37,7 +40,13 @@ pub fn execute_circuit( return Err(NargoError::ExecutionError(match call_stack { Some(call_stack) => { - if let Some(assert_message) = circuit.get_assert_message( + // First check whether we have a runtime assertion message that should be resolved on an ACVM failure + // If we do not have a runtime assertion message, we should check whether the circuit has any hardcoded + // messages associated with a specific `OpcodeLocation`. + // Otherwise return the provided opcode resolution error. + if let Some(assert_message) = assert_message { + ExecutionError::AssertionFailed(assert_message.to_owned(), call_stack) + } else if let Some(assert_message) = circuit.get_assert_message( *call_stack.last().expect("Call stacks should not be empty"), ) { ExecutionError::AssertionFailed(assert_message.to_owned(), call_stack) @@ -50,7 +59,19 @@ pub fn execute_circuit( } ACVMStatus::RequiresForeignCall(foreign_call) => { let foreign_call_result = foreign_call_executor.execute(&foreign_call)?; - acvm.resolve_pending_foreign_call(foreign_call_result); + match foreign_call_result { + NargoForeignCallResult::BrilligOutput(foreign_call_result) => { + acvm.resolve_pending_foreign_call(foreign_call_result); + } + NargoForeignCallResult::ResolvedAssertMessage(message) => { + if assert_message.is_some() { + unreachable!("Resolving an assert message should happen only once as the VM should have failed"); + } + assert_message = Some(message); + + acvm.resolve_pending_foreign_call(ForeignCallResult::default()); + } + } } } } diff --git a/tooling/nargo/src/ops/foreign_calls.rs b/tooling/nargo/src/ops/foreign_calls.rs index e3a3174f8dc..f600b3047fc 100644 --- a/tooling/nargo/src/ops/foreign_calls.rs +++ b/tooling/nargo/src/ops/foreign_calls.rs @@ -9,13 +9,69 @@ pub trait ForeignCallExecutor { fn execute( &mut self, foreign_call: &ForeignCallWaitInfo, - ) -> Result; + ) -> Result; +} + +#[derive(Debug, PartialEq, Eq, Clone)] +pub enum NargoForeignCallResult { + BrilligOutput(ForeignCallResult), + ResolvedAssertMessage(String), +} + +impl NargoForeignCallResult { + pub fn get_assert_message(self) -> Option { + match self { + Self::ResolvedAssertMessage(msg) => Some(msg), + _ => None, + } + } + + pub fn get_brillig_output(self) -> Option { + match self { + Self::BrilligOutput(foreign_call_result) => Some(foreign_call_result), + _ => None, + } + } +} + +impl From for NargoForeignCallResult { + fn from(value: ForeignCallResult) -> Self { + Self::BrilligOutput(value) + } +} + +impl From for NargoForeignCallResult { + fn from(value: String) -> Self { + Self::ResolvedAssertMessage(value) + } +} + +impl From for NargoForeignCallResult { + fn from(value: Value) -> Self { + let foreign_call_result: ForeignCallResult = value.into(); + foreign_call_result.into() + } +} + +impl From> for NargoForeignCallResult { + fn from(values: Vec) -> Self { + let foreign_call_result: ForeignCallResult = values.into(); + foreign_call_result.into() + } +} + +impl From> for NargoForeignCallResult { + fn from(values: Vec) -> Self { + let foreign_call_result: ForeignCallResult = values.into(); + foreign_call_result.into() + } } /// This enumeration represents the Brillig foreign calls that are natively supported by nargo. /// After resolution of a foreign call, nargo will restart execution of the ACVM pub(crate) enum ForeignCall { Print, + AssertMessage, CreateMock, SetMockParams, SetMockReturns, @@ -33,6 +89,7 @@ impl ForeignCall { pub(crate) fn name(&self) -> &'static str { match self { ForeignCall::Print => "print", + ForeignCall::AssertMessage => "assert_message", ForeignCall::CreateMock => "create_mock", ForeignCall::SetMockParams => "set_mock_params", ForeignCall::SetMockReturns => "set_mock_returns", @@ -44,6 +101,7 @@ impl ForeignCall { pub(crate) fn lookup(op_name: &str) -> Option { match op_name { "print" => Some(ForeignCall::Print), + "assert_message" => Some(ForeignCall::AssertMessage), "create_mock" => Some(ForeignCall::CreateMock), "set_mock_params" => Some(ForeignCall::SetMockParams), "set_mock_returns" => Some(ForeignCall::SetMockReturns), @@ -134,29 +192,49 @@ impl DefaultForeignCallExecutor { fn execute_print(foreign_call_inputs: &[ForeignCallParam]) -> Result<(), ForeignCallError> { let skip_newline = foreign_call_inputs[0].unwrap_value().is_zero(); - let display_values: PrintableValueDisplay = foreign_call_inputs - .split_first() - .ok_or(ForeignCallError::MissingForeignCallInputs)? - .1 - .try_into()?; - print!("{display_values}{}", if skip_newline { "" } else { "\n" }); + + let foreign_call_inputs = + foreign_call_inputs.split_first().ok_or(ForeignCallError::MissingForeignCallInputs)?.1; + let display_string = Self::format_printable_value(foreign_call_inputs, skip_newline)?; + + print!("{display_string}"); + Ok(()) } + + fn execute_assert_message( + foreign_call_inputs: &[ForeignCallParam], + ) -> Result { + let display_string = Self::format_printable_value(foreign_call_inputs, true)?; + Ok(display_string.into()) + } + + fn format_printable_value( + foreign_call_inputs: &[ForeignCallParam], + skip_newline: bool, + ) -> Result { + let display_values: PrintableValueDisplay = foreign_call_inputs.try_into()?; + + let result = format!("{display_values}{}", if skip_newline { "" } else { "\n" }); + + Ok(result) + } } impl ForeignCallExecutor for DefaultForeignCallExecutor { fn execute( &mut self, foreign_call: &ForeignCallWaitInfo, - ) -> Result { + ) -> Result { let foreign_call_name = foreign_call.function.as_str(); match ForeignCall::lookup(foreign_call_name) { Some(ForeignCall::Print) => { if self.show_output { Self::execute_print(&foreign_call.inputs)?; } - Ok(ForeignCallResult { values: vec![] }) + Ok(ForeignCallResult::default().into()) } + Some(ForeignCall::AssertMessage) => Self::execute_assert_message(&foreign_call.inputs), Some(ForeignCall::CreateMock) => { let mock_oracle_name = Self::parse_string(&foreign_call.inputs[0]); assert!(ForeignCall::lookup(&mock_oracle_name).is_none()); @@ -164,7 +242,7 @@ impl ForeignCallExecutor for DefaultForeignCallExecutor { self.mocked_responses.push(MockedCall::new(id, mock_oracle_name)); self.last_mock_id += 1; - Ok(ForeignCallResult { values: vec![Value::from(id).into()] }) + Ok(Value::from(id).into()) } Some(ForeignCall::SetMockParams) => { let (id, params) = Self::extract_mock_id(&foreign_call.inputs)?; @@ -172,7 +250,7 @@ impl ForeignCallExecutor for DefaultForeignCallExecutor { .unwrap_or_else(|| panic!("Unknown mock id {}", id)) .params = Some(params.to_vec()); - Ok(ForeignCallResult { values: vec![] }) + Ok(ForeignCallResult::default().into()) } Some(ForeignCall::SetMockReturns) => { let (id, params) = Self::extract_mock_id(&foreign_call.inputs)?; @@ -180,7 +258,7 @@ impl ForeignCallExecutor for DefaultForeignCallExecutor { .unwrap_or_else(|| panic!("Unknown mock id {}", id)) .result = ForeignCallResult { values: params.to_vec() }; - Ok(ForeignCallResult { values: vec![] }) + Ok(ForeignCallResult::default().into()) } Some(ForeignCall::SetMockTimes) => { let (id, params) = Self::extract_mock_id(&foreign_call.inputs)?; @@ -194,12 +272,12 @@ impl ForeignCallExecutor for DefaultForeignCallExecutor { .unwrap_or_else(|| panic!("Unknown mock id {}", id)) .times_left = Some(times); - Ok(ForeignCallResult { values: vec![] }) + Ok(ForeignCallResult::default().into()) } Some(ForeignCall::ClearMock) => { let (id, _) = Self::extract_mock_id(&foreign_call.inputs)?; self.mocked_responses.retain(|response| response.id != id); - Ok(ForeignCallResult { values: vec![] }) + Ok(ForeignCallResult::default().into()) } None => { let mock_response_position = self @@ -222,7 +300,7 @@ impl ForeignCallExecutor for DefaultForeignCallExecutor { } } - Ok(ForeignCallResult { values: result }) + Ok(result.into()) } (None, Some(external_resolver)) => { let encoded_params: Vec<_> = @@ -235,7 +313,7 @@ impl ForeignCallExecutor for DefaultForeignCallExecutor { let parsed_response: ForeignCallResult = response.result()?; - Ok(parsed_response) + Ok(parsed_response.into()) } (None, None) => panic!("Unknown foreign call {}", foreign_call_name), } @@ -312,7 +390,7 @@ mod tests { }; let result = executor.execute(&foreign_call); - assert_eq!(result.unwrap(), ForeignCallResult { values: foreign_call.inputs }); + assert_eq!(result.unwrap(), ForeignCallResult { values: foreign_call.inputs }.into()); server.close(); } diff --git a/tooling/nargo_fmt/src/visitor/stmt.rs b/tooling/nargo_fmt/src/visitor/stmt.rs index 800a8656ef3..cfe5acb21a7 100644 --- a/tooling/nargo_fmt/src/visitor/stmt.rs +++ b/tooling/nargo_fmt/src/visitor/stmt.rs @@ -38,8 +38,7 @@ impl super::FmtVisitor<'_> { nested_shape.indent.block_indent(self.config); - let message = - message.map_or(String::new(), |message| format!(", \"{message}\"")); + let message = message.map_or(String::new(), |message| format!(", {message}")); let (callee, args) = match kind { ConstrainKind::Assert => { diff --git a/tooling/noir_js/src/witness_generation.ts b/tooling/noir_js/src/witness_generation.ts index 1f233422061..cef1d817d9b 100644 --- a/tooling/noir_js/src/witness_generation.ts +++ b/tooling/noir_js/src/witness_generation.ts @@ -26,6 +26,12 @@ const defaultForeignCallHandler: ForeignCallHandler = async (name: string, args: // // If a user needs to print values then they should provide a custom foreign call handler. return []; + } else if (name == 'assert_message') { + // By default we do not do anything for `assert_message` foreign calls due to a need for formatting, + // however we provide an empty response in order to not halt execution. + // + // If a user needs to use dynamic assertion messages then they should provide a custom foreign call handler. + return []; } throw Error(`Unexpected oracle during execution: ${name}(${args.join(', ')})`); }; diff --git a/tooling/noir_js/test/node/execute.test.ts b/tooling/noir_js/test/node/execute.test.ts index bfaf80882ab..491bcb0dfc4 100644 --- a/tooling/noir_js/test/node/execute.test.ts +++ b/tooling/noir_js/test/node/execute.test.ts @@ -1,9 +1,11 @@ import assert_lt_json from '../noir_compiled_examples/assert_lt/target/assert_lt.json' assert { type: 'json' }; +import assert_msg_json from '../noir_compiled_examples/assert_msg_runtime/target/assert_msg_runtime.json' assert { type: 'json' }; import { Noir } from '@noir-lang/noir_js'; import { CompiledCircuit } from '@noir-lang/types'; import { expect } from 'chai'; const assert_lt_program = assert_lt_json as CompiledCircuit; +const assert_msg_runtime = assert_msg_json as CompiledCircuit; it('returns the return value of the circuit', async () => { const inputs = { @@ -14,3 +16,16 @@ it('returns the return value of the circuit', async () => { expect(returnValue).to.be.eq('0x05'); }); + +it('circuit with a dynamic assert message should fail on an assert failure not the foreign call handler', async () => { + const inputs = { + x: '10', + y: '5', + }; + try { + await new Noir(assert_msg_runtime).execute(inputs); + } catch (error) { + const knownError = error as Error; + expect(knownError.message).to.equal('Circuit execution failed: Error: Cannot satisfy constraint'); + } +}); diff --git a/tooling/noir_js/test/noir_compiled_examples/assert_lt/src/main.nr b/tooling/noir_js/test/noir_compiled_examples/assert_lt/src/main.nr index 693e7285736..a9aaae5f2f7 100644 --- a/tooling/noir_js/test/noir_compiled_examples/assert_lt/src/main.nr +++ b/tooling/noir_js/test/noir_compiled_examples/assert_lt/src/main.nr @@ -4,6 +4,10 @@ fn main(x: u64, y: pub u64) -> pub u64 { // We include a println statement to show that noirJS will ignore this and continue execution std::println("foo"); + // A dynamic assertion message is used to show that noirJS will ignore the call and continue execution + // The assertion passes and thus the foreign call for resolving an assertion message should not be called. + assert(x < y, f"Expected x < y but got {x} < {y}"); + assert(x < y); x + y } diff --git a/tooling/noir_js/test/noir_compiled_examples/assert_lt/target/assert_lt.json b/tooling/noir_js/test/noir_compiled_examples/assert_lt/target/assert_lt.json index 5b511cdc140..027df0b39d9 100644 --- a/tooling/noir_js/test/noir_compiled_examples/assert_lt/target/assert_lt.json +++ b/tooling/noir_js/test/noir_compiled_examples/assert_lt/target/assert_lt.json @@ -1 +1 @@ -{"noir_version":"0.20.0+010fdb69616f47fc0a9f252a65a903316d3cbe80","hash":17538653710107541030,"backend":"acvm-backend-barretenberg","abi":{"parameters":[{"name":"x","type":{"kind":"integer","sign":"unsigned","width":64},"visibility":"private"},{"name":"y","type":{"kind":"integer","sign":"unsigned","width":64},"visibility":"public"}],"param_witnesses":{"x":[{"start":1,"end":2}],"y":[{"start":2,"end":3}]},"return_type":{"abi_type":{"kind":"integer","sign":"unsigned","width":64},"visibility":"public"},"return_witnesses":[5]},"bytecode":"H4sIAAAAAAAA/9Wa627aMBiGHcKhBBLOR+0Hl+Ak5PQP9U6gBK3SNqoqWm9kFzzMYu2DujhbPjvFEkrsJu/7vJ+TFDAtQkiH/GnG6VXLtxvQr+V9Mx/jx5pE3Db5lpZqYahI96Ba91e+bee1g60J6objS90mehbqN8nfuUbSpLAeNVAjXg++bZxeD/m+k9esjlyz6+t3A/p1MFfYvkyzharpPrXzmsFmXPU3YL8F8jUV5HvA1aRMs42qGe2YhgVqwuvH2Tvg721QLwu5Xgbw5Lq8bynz9Tye8Vb+joCjozF/R5lveJ7/riR/V8DR1Zi/q8w3TJiGLclvCzhsjfltZb5hyjQcSX5HwOFozO8o8w3XTKMnyd8TcPQ05od8RVmtilnxff0t0+hL8vcFHH2N+SFfUVarYlZ838hnGgNJ/oGAY6Ax/0CZb3R+rgwl+YcCjqHG/ENlvtH5fdVIkn8k4BhpzA/5irJ274jVrpgV3zeMmMZYkn8s4BhrzA/5irJaFbPi+3pPTGMiyT8RcEw05od8RVmtilnxfcPzXE0l+acCjqnG/FNlvmHANGaS/DMBx0xjfshXlNW+I9bRHbEOKmbF9w1jpjGX5J8LOOYa80O+oqzWHbH2KmbF9/XPnwUXkvwLAcdCY/6FMt9ozzSWkvxLAcdSY/4l8MVet3gAmV9en39kHKAOYPg+X2xlzQRjXOALOIeDtsj7hR60qpnk/eolAWNYPgbQ8k/fTK7TyEtd391SL9nFAV0HuzB2YzeIg70X+34ar+Mo2SURTdy1n7qHIPEPuVjt/7nc6wFBdDRtWFe46tgAE18D44/geLgCb4A5eQTniI4xPtBpgzF+vkMUXljQHEvTJJc/T+C6ZS8oE4+R8kmtk8vlWELwfxKg6qYqq9VErOet+v0jJ73idE3EzHXEeS1Rv5sPuM9839yaZ1quXdwntFxzMe+TBsF/7nDNj/6B8P0GuXz4848R/B3INsvS7y/ZKjuutvv96u05+7o6/kxfD9+Ob78Bhjydn08mAAA="} \ No newline at end of file +{"noir_version":"0.23.0+2dc4805116123ecde584fe0f2cd280de817d3915","hash":17955244824623030861,"abi":{"parameters":[{"name":"x","type":{"kind":"integer","sign":"unsigned","width":64},"visibility":"private"},{"name":"y","type":{"kind":"integer","sign":"unsigned","width":64},"visibility":"public"}],"param_witnesses":{"x":[{"start":0,"end":1}],"y":[{"start":1,"end":2}]},"return_type":{"abi_type":{"kind":"integer","sign":"unsigned","width":64},"visibility":"public"},"return_witnesses":[4]},"bytecode":"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","debug_symbols":"ndvNilVHFIbhezljCftbq/auqr6VkIEkBgTREJ1J33sSYjLQ/uE8Mx180OhLD55d6+vtw6df3355/+nj59vD11vdHn7+evv8x9uP//zt85e3f365PeRcb27vPv7295/mfHxz+/39h3e3h1GPv7y59VODcexvg5Hx3WDcOzjvHVz3Dua9g3XvYD85mP/9s47V3w1y3Luon578qeqY3ybV5/+TWv9O9v2Tp3+yOerbZl7zx01gU7Bp2AzYnLC5YDNhs2Cz798UdFDQQUEHBR0UdFDQQUEHBR0UdFDQQUMHDR00dNDQQUMHDR00dNDQQUMHDR0M6GBABwM6GNDBgA4GdDCggwEdDOhgQAcndHBCByd0cEIHJ3RwQgcndHBCByd0cEIHF3RwQQcXdHBBBxd0cEEHF3RwQQcXdHBBBxM6mNDBhA4mdDChgwkdTOhgQgcTOpjQwYIOFnSwoIMFHSzoYEEHCzpY0MGCDhZ0sKGDDR1s6GBDBxs62NDBhg42dLChgw0d5BBIOkSSDqGkQyzpEEw6RJMO4aRDPOkQUDqkCKNFKYJwkXSReJF8kYCRhJGIUYwxgowp0mYpQpwxAo0RaYxQY8QaI9gY0cYIN0a8MU0fIKQIIceIOUbQMaKOEXaMuGMEHiPyGKHHDPomJUWIPuZ+fpzPfMp66ePkfOZT1subOmAT2Dz5//rSZ9D5zCemVzYDNidsLthM2CzY7Ps3T//Of2UT2EAHDR00dNDQQUMHDR00dNDQwYAOBnQwoIMBHQzoYEAHAzoY0MGADgZ0cEIHJ3RwQgcndHBCByd0cEIHJ3RwQgcndHBBBxd0cEEHF3RwQQcXdHBBBxd0cEEHF3QwoYMJHUzoYEIHEzqY0MGEDiZ0MKGDCR0s6GBBBws6WNDBgg4WdLCggwUdLOhgQQcbOtjQwYYONnSwoYMNHWzoYEMHGzrY0MEzn5heG0VGJaOW0ZDRKaNLRlNGS0ZSRKSISBGRIiJFRIqIFBEpIlJEpIhIESVFlBQhzBhxxgg0RqQxQo0Ra4xgY0QbI9wY8cYIOEbEMUKOEXOMoGNEHSPsGHHHCDxG5DFCjxF7jOBjRB8j/BjxxwhARgQyQpARg4wgZEQhIwwZccgIREYkMkKREYuMYGREIyMcGfHICEhGRDJCkhGTjKBkRCUjLBlxyQhMRmQyQpMRm4zgZEQnIzwZ8ckIUEaEMkKUEaOMIGVEKSNMGXHKCFRGpDJClRGrjGBlRCsjXBnxyghYRsQyQpYRsywxyxKzLDHLErMsMcsSsywxyxKzLDHLErMsMcsSsywxyxKzLDHLErMsMcsSsywxyxKzLDHLErMsehpJbyPpcSS9jqTnkfQ+kh5IilmWmGWJWVbTY1kpQsyyxCxLzLLELEvMssQsS8yyxCxLzLIGvZ+WIsQsS8yyxCxLzLLELEvMssQsS8yyxCxLzLLELEvMssQsS8yyxCxLzLLELEvMssQsS8yyLrqykCLELEvMssQsS8yyxCxLzLLELEvMssQsa9LhjRQhZlliliVmWWKWJWZZYpYlZlliliVmWYtusaQIMcsSsywxyxKzLDHLErMsMcsSsywxy9p0nkf3eXKgJ2bZYpYtZtlili1m2WKWLWbZYpYtZtmhk00pQsyyxSxbzLLFLFvMssUsW8yyxSxbzLKLrnilCDHLFrNsMcsWs2wxyxazbLrqprNuuuu2w24pgk676babjrvpupvOu8UsW8yyxSxbzLIH3fpLEWKWLWbZYpZ9r1k+Pv4F","file_map":{"28":{"source":"mod hash;\nmod array;\nmod slice;\nmod merkle;\nmod schnorr;\nmod ecdsa_secp256k1;\nmod ecdsa_secp256r1;\nmod eddsa;\nmod grumpkin_scalar;\nmod grumpkin_scalar_mul;\nmod scalar_mul;\nmod sha256;\nmod sha512;\nmod field;\nmod ec;\nmod unsafe;\nmod collections;\nmod compat;\nmod convert;\nmod option;\nmod string;\nmod test;\nmod cmp;\nmod ops;\nmod default;\nmod prelude;\nmod uint128;\n// mod bigint;\n\n// Oracle calls are required to be wrapped in an unconstrained function\n// Thus, the only argument to the `println` oracle is expected to always be an ident\n#[oracle(print)]\nunconstrained fn print_oracle(with_newline: bool, input: T) {}\n\nunconstrained pub fn print(input: T) {\n print_oracle(false, input);\n}\n\nunconstrained pub fn println(input: T) {\n print_oracle(true, input);\n}\n\n#[foreign(recursive_aggregation)]\npub fn verify_proof(verification_key: [Field], proof: [Field], public_inputs: [Field], key_hash: Field) {}\n\n// Asserts that the given value is known at compile-time.\n// Useful for debugging for-loop bounds.\n#[builtin(assert_constant)]\npub fn assert_constant(x: T) {}\n// from_field and as_field are private since they are not valid for every type.\n// `as` should be the default for users to cast between primitive types, and in the future\n// traits can be used to work with generic types.\n#[builtin(from_field)]\nfn from_field(x: Field) -> T {}\n\n#[builtin(as_field)]\nfn as_field(x: T) -> Field {}\n\npub fn wrapping_add(x: T, y: T) -> T {\n crate::from_field(crate::as_field(x) + crate::as_field(y))\n}\n\npub fn wrapping_sub(x: T, y: T) -> T {\n //340282366920938463463374607431768211456 is 2^128, it is used to avoid underflow\n crate::from_field(crate::as_field(x) + 340282366920938463463374607431768211456 - crate::as_field(y))\n}\n\npub fn wrapping_mul(x: T, y: T) -> T {\n crate::from_field(crate::as_field(x) * crate::as_field(y))\n}\n","path":"std/lib.nr"},"42":{"source":"use dep::std;\n\nfn main(x: u64, y: pub u64) -> pub u64 {\n // We include a println statement to show that noirJS will ignore this and continue execution\n std::println(\"foo\");\n\n // A dynamic assertion message is used to show that noirJS will ignore the call and continue execution\n // The assertion passes and thus the foreign call for resolving an assertion message should not be called.\n assert(x < y, f\"Expected x < y but got {x} < {y}\");\n\n assert(x < y);\n x + y\n}\n","path":"/mnt/user-data/maxim/noir/tooling/noir_js/test/noir_compiled_examples/assert_lt/src/main.nr"}}} \ No newline at end of file diff --git a/tooling/noir_js/test/noir_compiled_examples/assert_msg_runtime/Nargo.toml b/tooling/noir_js/test/noir_compiled_examples/assert_msg_runtime/Nargo.toml new file mode 100644 index 00000000000..765f632ff74 --- /dev/null +++ b/tooling/noir_js/test/noir_compiled_examples/assert_msg_runtime/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "assert_msg_runtime" +type = "bin" +authors = [""] +compiler_version = ">=0.23.0" + +[dependencies] \ No newline at end of file diff --git a/tooling/noir_js/test/noir_compiled_examples/assert_msg_runtime/src/main.nr b/tooling/noir_js/test/noir_compiled_examples/assert_msg_runtime/src/main.nr new file mode 100644 index 00000000000..40e447cad02 --- /dev/null +++ b/tooling/noir_js/test/noir_compiled_examples/assert_msg_runtime/src/main.nr @@ -0,0 +1,6 @@ +fn main(x: u64, y: pub u64) { + // A dynamic assertion message is used to show that noirJS will ignore the call and continue execution + // We need this assertion to fail as the `assert_message` oracle in Noir is only called + // upon a failing condition in an assert. + assert(x < y, f"Expected x < y but got {x} < {y}"); +} diff --git a/tooling/noir_js/test/noir_compiled_examples/assert_msg_runtime/target/assert_msg_runtime.json b/tooling/noir_js/test/noir_compiled_examples/assert_msg_runtime/target/assert_msg_runtime.json new file mode 100644 index 00000000000..300e9a06e13 --- /dev/null +++ b/tooling/noir_js/test/noir_compiled_examples/assert_msg_runtime/target/assert_msg_runtime.json @@ -0,0 +1 @@ +{"noir_version":"0.23.0+2dc4805116123ecde584fe0f2cd280de817d3915","hash":8331765605233675558,"abi":{"parameters":[{"name":"x","type":{"kind":"integer","sign":"unsigned","width":64},"visibility":"private"},{"name":"y","type":{"kind":"integer","sign":"unsigned","width":64},"visibility":"public"}],"param_witnesses":{"x":[{"start":0,"end":1}],"y":[{"start":1,"end":2}]},"return_type":null,"return_witnesses":[]},"bytecode":"H4sIAAAAAAAA/+2c2W6bQBSGwVviJBi870si9Z4dfFflQRrZDelVb+q+vxqWUU/wNEPrM0OPlJEsYDDnfP/PsHgG3NY07VrLi/76aRTzn8GyXiw3wXpY4DZpsS8rDozl2aHvJ5GbOJ5zsN39MQ5sPziGsRM7QRw8u7HnJbEfR/vjPrL3ju8lzkuw916KYPq/cznlCo50tNgNjp+p323Ovmm9fh7B93Uw1UGMR7AN7zv6H+J0OSw9sP5S8WdmMHFNEFMDJmDmgrEwG9elsVp4Gu33/PtLTrvE6TQQNTcR9+sF/p0djOUDb6fxCw67H8iJG8WS4tpy4oaSfAg9ST74xHyQxOtKag+y2q8sXu8rMX/3tHhDV5IPss6/xI63MJIU9+XD34z3KCmurOv8My1/yZ1/ZbUHSef18/aAF9t+c27XcWM7iLFsmZy6pobz0t9tDeR9k5anAjLtfGhrb0un+GB6nea5KvmT1rHOsAaoYx0iTVB3U8y3AKOGyujaHQ29jdldoK0N9DRLOrpA2xWoY9tcgzq4DZuybW5ALquY7xXbdHG1ZccP7MzUQQ7G0wTfGRXTVOcX/bf+awlczF8Wt1nysQO8wsnrBrA9a8AXrcTCyg1gwd43acxb3JjZ8XGHGjO/JhvAE+bfLZiy9XfALwPZLx3kZHHZsiEtr5tdh3sC/T0OR0+h/p60vGG2/02BfpPDYSrUb0rLG2b3jpZAv8XhsBTqt6TlDZM0Rl+gv8/h6CvU35eWN+8jHAj0DzgcA4X6IV9VVqNmVvy83iGNMRToH3I4hgr1Q76qrEbNrPh58z7GkUD/iMMxUqgf8lVltWpmxc8bZeNFY4H+MYdjrFA/5KvKatbMip8377OeCPRPOBwThfohX1VWq2ZW/Lz5uOZUoH/K4Zgq1A/5qrL2CbGahFitmlnx8+ZjVjOB/hmHY6ZQP+SryjohxDomxFq3r/h5o6yPaS7QP+dwzBXqh3xVWY2aWfHzutmY6kKgf8HhWCjUD/mqsho1s+LnjbJ74aVA/5LDsVSoH/JVZTUJsfYJsU5rZsXPG2bPwqwE+lccjpVC/ZCvKqtBiHVQMyt+Xi9MY6wF+tccjrVC/Wtpeb3sd8tGoH/D4dgo1L+Rljd/9mkr0L/lcGwV6t+CvDvUvPmzBDBvWt57lmAn0YM05j1uzOx5qQfAz7Teg2W2Ho77PyBr00FOFpctQ76qrAYh1h4hVpMQq0WItU+IldKxNSDESsnXISFWSueBESFWSteCMSFWSu11QoiV0jX24z5LDuuUECulY4vS+ZWSrzNCrJTuX+eEWCn5uiDESukaS+nehdI1dkmI9aPfRQ7rihDrmhDrpmZWCeMlTjr+xfrrD6dT8uPn0/fkdDp8SxgJfLu6UczvAGkLzMM3vjtgOzbK9gnU3ZbqNKAOvsl7pUn8yzoYUy/F/o9er7d1DueZKa/lFybuFpAIUgAA"} \ No newline at end of file From 8e042f2cbcc8a698aa45241aedbb0131b4acdc46 Mon Sep 17 00:00:00 2001 From: Maxim Vezenov Date: Thu, 1 Feb 2024 15:40:40 +0000 Subject: [PATCH 63/70] feat: Option expect method (#4219) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Description ## Problem\* https://github.com/noir-lang/noir/pull/4101 resolves https://github.com/noir-lang/noir/issues/3113 which was preventing an expect function on our Option struct. ## Summary\* This adds an `expect` method and a test inside of `compile_failure`. Here is the example for the test under `compile_failure/option_expect`: Screenshot 2024-01-31 at 11 12 51 AM ## Additional Context ## Documentation\* Check one: - [ ] No documentation needed. - [x] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --------- Co-authored-by: Tom French <15848336+TomAFrench@users.noreply.github.com> Co-authored-by: Tom French --- compiler/noirc_frontend/src/monomorphization/mod.rs | 4 ++-- docs/docs/noir/standard_library/options.md | 4 ++++ noir_stdlib/src/option.nr | 6 ++++++ .../compile_failure/assert_msg_runtime/Prover.toml | 2 ++ .../brillig_assert_msg_runtime/Prover.toml | 1 + test_programs/compile_failure/option_expect/Nargo.toml | 7 +++++++ test_programs/compile_failure/option_expect/src/main.nr | 8 ++++++++ .../compile_failure/option_expect_bad_input/Nargo.toml | 7 +++++++ .../compile_failure/option_expect_bad_input/src/main.nr | 6 ++++++ test_programs/compile_success_empty/option/src/main.nr | 4 ++-- 10 files changed, 45 insertions(+), 4 deletions(-) create mode 100644 test_programs/compile_failure/assert_msg_runtime/Prover.toml create mode 100644 test_programs/compile_failure/brillig_assert_msg_runtime/Prover.toml create mode 100644 test_programs/compile_failure/option_expect/Nargo.toml create mode 100644 test_programs/compile_failure/option_expect/src/main.nr create mode 100644 test_programs/compile_failure/option_expect_bad_input/Nargo.toml create mode 100644 test_programs/compile_failure/option_expect_bad_input/src/main.nr diff --git a/compiler/noirc_frontend/src/monomorphization/mod.rs b/compiler/noirc_frontend/src/monomorphization/mod.rs index 663731d462c..7e06b94ca5a 100644 --- a/compiler/noirc_frontend/src/monomorphization/mod.rs +++ b/compiler/noirc_frontend/src/monomorphization/mod.rs @@ -1038,10 +1038,10 @@ impl<'interner> Monomorphizer<'interner> { // since they cannot be passed from ACIR into Brillig if let HirType::Array(size, _) = typ { if let HirType::NotConstant = **size { - unreachable!("println does not support slices. Convert the slice to an array before passing it to println"); + unreachable!("println and format strings do not support slices. Convert the slice to an array before passing it to println"); } } else if matches!(typ, HirType::MutableReference(_)) { - unreachable!("println does not support mutable references."); + unreachable!("println and format strings do not support mutable references."); } let printable_type: PrintableType = typ.into(); diff --git a/docs/docs/noir/standard_library/options.md b/docs/docs/noir/standard_library/options.md index 970c9cfbf11..a1bd4e1de5f 100644 --- a/docs/docs/noir/standard_library/options.md +++ b/docs/docs/noir/standard_library/options.md @@ -56,6 +56,10 @@ Returns the wrapped value if `self.is_some()`. Otherwise, returns the given defa Returns the wrapped value if `self.is_some()`. Otherwise, calls the given function to return a default value. +### expect + +Asserts `self.is_some()` with a provided custom message and returns the contained `Some` value. The custom message is expected to be a format string. + ### map If self is `Some(x)`, this returns `Some(f(x))`. Otherwise, this returns `None`. diff --git a/noir_stdlib/src/option.nr b/noir_stdlib/src/option.nr index 137d57f33db..cab95731d05 100644 --- a/noir_stdlib/src/option.nr +++ b/noir_stdlib/src/option.nr @@ -56,6 +56,12 @@ impl Option { } } + /// Asserts `self.is_some()` with a provided custom message and returns the contained `Some` value + fn expect(self, message: fmtstr) -> T { + assert(self.is_some(), message); + self._value + } + /// If self is `Some(x)`, this returns `Some(f(x))`. Otherwise, this returns `None`. pub fn map(self, f: fn[Env](T) -> U) -> Option { if self._is_some { diff --git a/test_programs/compile_failure/assert_msg_runtime/Prover.toml b/test_programs/compile_failure/assert_msg_runtime/Prover.toml new file mode 100644 index 00000000000..f28f2f8cc48 --- /dev/null +++ b/test_programs/compile_failure/assert_msg_runtime/Prover.toml @@ -0,0 +1,2 @@ +x = "5" +y = "10" diff --git a/test_programs/compile_failure/brillig_assert_msg_runtime/Prover.toml b/test_programs/compile_failure/brillig_assert_msg_runtime/Prover.toml new file mode 100644 index 00000000000..0e5dfd5638d --- /dev/null +++ b/test_programs/compile_failure/brillig_assert_msg_runtime/Prover.toml @@ -0,0 +1 @@ +x = "5" diff --git a/test_programs/compile_failure/option_expect/Nargo.toml b/test_programs/compile_failure/option_expect/Nargo.toml new file mode 100644 index 00000000000..1ee1215ff71 --- /dev/null +++ b/test_programs/compile_failure/option_expect/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "option_expect" +type = "bin" +authors = [""] +compiler_version = ">=0.23.0" + +[dependencies] \ No newline at end of file diff --git a/test_programs/compile_failure/option_expect/src/main.nr b/test_programs/compile_failure/option_expect/src/main.nr new file mode 100644 index 00000000000..439ce4f386e --- /dev/null +++ b/test_programs/compile_failure/option_expect/src/main.nr @@ -0,0 +1,8 @@ +fn main() { + let inner_value = 3; + let none = Option::none(); + let some = Option::some(inner_value); + + assert(some.expect(f"Should have the value {inner_value}") == 3); + assert(none.expect(f"Should have the value {inner_value}") == 3); +} diff --git a/test_programs/compile_failure/option_expect_bad_input/Nargo.toml b/test_programs/compile_failure/option_expect_bad_input/Nargo.toml new file mode 100644 index 00000000000..0555681e188 --- /dev/null +++ b/test_programs/compile_failure/option_expect_bad_input/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "option_expect_bad_input" +type = "bin" +authors = [""] +compiler_version = ">=0.23.0" + +[dependencies] \ No newline at end of file diff --git a/test_programs/compile_failure/option_expect_bad_input/src/main.nr b/test_programs/compile_failure/option_expect_bad_input/src/main.nr new file mode 100644 index 00000000000..cc93e767975 --- /dev/null +++ b/test_programs/compile_failure/option_expect_bad_input/src/main.nr @@ -0,0 +1,6 @@ +fn main() { + let inner_value = 3; + let some = Option::some(inner_value); + + assert(some.expect("Should have the value {inner_value}") == 3); +} diff --git a/test_programs/compile_success_empty/option/src/main.nr b/test_programs/compile_success_empty/option/src/main.nr index 1f879bd375f..989c8f65bf4 100644 --- a/test_programs/compile_success_empty/option/src/main.nr +++ b/test_programs/compile_success_empty/option/src/main.nr @@ -1,5 +1,3 @@ -use dep::std::option::Option; - fn main() { let ten = 10; // giving this a name, to ensure that the Option functions work with closures let none = Option::none(); @@ -22,6 +20,8 @@ fn main() { assert(some.map(|x| x * 2).unwrap() == 6); assert(some.map(|x| x * ten).unwrap() == 30); + assert(some.expect(f"Should have a value") == 3); + assert(none.map_or(0, |x| x * 2) == 0); assert(some.map_or(0, |x| x * 2) == 6); assert(none.map_or(0, |x| x * ten) == 0); From 593916bb61fb926730a34519b1429a8d035e10b6 Mon Sep 17 00:00:00 2001 From: guipublic <47281315+guipublic@users.noreply.github.com> Date: Thu, 1 Feb 2024 16:56:06 +0100 Subject: [PATCH 64/70] fix: from field with constant values (#4226) # Description ## Problem\* Resolves a small issue when trying to cast a constant value from a field element. ## Summary\* We were trying to do a modulo 2^{254} which does not fit in u128 ## Additional Context ## Documentation\* Check one: - [X] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [X ] I have tested the changes locally. - [ X] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- compiler/noirc_evaluator/src/ssa/ir/instruction.rs | 3 +++ test_programs/execution_success/u128/src/main.nr | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/compiler/noirc_evaluator/src/ssa/ir/instruction.rs b/compiler/noirc_evaluator/src/ssa/ir/instruction.rs index 59f88fe99eb..fa5bc0f6697 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/instruction.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/instruction.rs @@ -490,6 +490,9 @@ impl Instruction { None } Instruction::Truncate { value, bit_size, max_bit_size } => { + if bit_size == max_bit_size { + return SimplifiedTo(*value); + } if let Some((numeric_constant, typ)) = dfg.get_numeric_constant_with_type(*value) { let integer_modulus = 2_u128.pow(*bit_size); let truncated = numeric_constant.to_u128() % integer_modulus; diff --git a/test_programs/execution_success/u128/src/main.nr b/test_programs/execution_success/u128/src/main.nr index 4c734f3a8f9..dc586408795 100644 --- a/test_programs/execution_success/u128/src/main.nr +++ b/test_programs/execution_success/u128/src/main.nr @@ -39,6 +39,6 @@ fn main(mut x: u32, y: u32, z: u32, big_int: U128, hexa: str<7>) { assert(shift >> small_int == small_int); assert(shift >> U128::from_integer(127) == U128::from_integer(0)); assert(shift << U128::from_integer(127) == U128::from_integer(0)); - + assert(U128::from_integer(3).to_integer() == 3); } From 96a74bb7a047c066f1bd53b7ac72af625345fcae Mon Sep 17 00:00:00 2001 From: Maxim Vezenov Date: Thu, 1 Feb 2024 16:22:06 +0000 Subject: [PATCH 65/70] chore(docs): Updates following `is_recursive` flag removal (#4199) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Description ## Problem\* Followup to https://github.com/noir-lang/noir/pull/4187 for resolving #4139 ## Summary\* We no longer need to distinguish between `generateIntermediateProof` and `generateFinalProof`. This will go into effect once https://github.com/AztecProtocol/aztec-packages/pull/4221 is merged and released. ## Additional Context ## Documentation\* Check one: - [ ] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [ ] I have tested the changes locally. - [ ] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --------- Co-authored-by: José Pedro Sousa Co-authored-by: Cat McGee --- docs/docs/how_to/how-to-recursion.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/docs/how_to/how-to-recursion.md b/docs/docs/how_to/how-to-recursion.md index f34647a99d5..4c45bb87ae2 100644 --- a/docs/docs/how_to/how-to-recursion.md +++ b/docs/docs/how_to/how-to-recursion.md @@ -42,9 +42,9 @@ In short: ::: -In a standard recursive app, you're also dealing with at least two circuits. For the purpose of this guide, we will assume these two: +In a standard recursive app, you're also dealing with at least two circuits. For the purpose of this guide, we will assume the following: -- `main`: a circuit of type `assert(x != y)` +- `main`: a circuit of type `assert(x != y)`, where `main` is marked with a `#[recursive]` attribute. This attribute states that the backend should generate proofs that are friendly for verification within another circuit. - `recursive`: a circuit that verifies `main` For a full example on how recursive proofs work, please refer to the [noir-examples](https://github.com/noir-lang/noir-examples) repository. We will *not* be using it as a reference for this guide. @@ -77,7 +77,7 @@ const { witness } = noir.execute(input) With this witness, you are now able to generate the intermediate proof for the main circuit: ```js -const { proof, publicInputs } = await backend.generateIntermediateProof(witness) +const { proof, publicInputs } = await backend.generateProof(witness) ``` :::warning @@ -95,13 +95,13 @@ With this in mind, it becomes clear that our intermediate proof is the one *mean Optionally, you are able to verify the intermediate proof: ```js -const verified = await backend.verifyIntermediateProof({ proof, publicInputs }) +const verified = await backend.verifyProof({ proof, publicInputs }) ``` -This can be useful to make sure our intermediate proof was correctly generated. But the real goal is to do it within another circuit. For that, we need to generate the intermediate artifacts: +This can be useful to make sure our intermediate proof was correctly generated. But the real goal is to do it within another circuit. For that, we need to generate recursive proof artifacts that will be passed to the circuit that is verifying the proof we just generated. Instead of passing the proof and verification key as a byte array, we pass them as fields which makes it cheaper to verify in a circuit: ```js -const { proofAsFields, vkAsFields, vkHash } = await backend.generateIntermediateProofArtifacts( { publicInputs, proof }, publicInputsCount) +const { proofAsFields, vkAsFields, vkHash } = await backend.generateRecursiveProofArtifacts( { publicInputs, proof }, publicInputsCount) ``` This call takes the public inputs and the proof, but also the public inputs count. While this is easily retrievable by simply counting the `publicInputs` length, the backend interface doesn't currently abstract it away. @@ -135,8 +135,8 @@ const recursiveInputs = { } const { witness, returnValue } = noir.execute(recursiveInputs) // we're executing the recursive circuit now! -const { proof, publicInputs } = backend.generateFinalProof(witness) -const verified = backend.verifyFinalProof({ proof, publicInputs }) +const { proof, publicInputs } = backend.generateProof(witness) +const verified = backend.verifyProof({ proof, publicInputs }) ``` You can obviously chain this proof into another proof. In fact, if you're using recursive proofs, you're probably interested of using them this way! @@ -165,15 +165,15 @@ This allows you to neatly call exactly the method you want without conflicting n ```js // Alice runs this 👇 const { witness: mainWitness } = await noir_programs.main.execute(input) -const proof = await backends.main.generateIntermediateProof(mainWitness) +const proof = await backends.main.generateProof(mainWitness) // Bob runs this 👇 -const verified = await backends.main.verifyIntermediateProof(proof) -const { proofAsFields, vkAsFields, vkHash } = await backends.main.generateIntermediateProofArtifacts( +const verified = await backends.main.verifyProof(proof) +const { proofAsFields, vkAsFields, vkHash } = await backends.main.generateRecursiveProofArtifacts( proof, numPublicInputs, ); -const recursiveProof = await noir_programs.recursive.generateFinalProof(recursiveInputs) +const recursiveProof = await noir_programs.recursive.generateProof(recursiveInputs) ``` ::: From 4467ea9e285ec810f45052e469ac2c1f9903a7d3 Mon Sep 17 00:00:00 2001 From: Michael J Klein Date: Thu, 1 Feb 2024 16:46:49 -0500 Subject: [PATCH 66/70] chore: add test for missing lambda closure environment (#2120) (#4212) # Description This issue has been resolved, presumably by github.com/noir-lang/noir/pull/2457, but this test no longer appears to be in the repo so re-adding it to prevent regressions. ## Problem\* Resolves #2120 ## Summary\* This just adds a test. ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- .../missing_closure_env/Nargo.toml | 7 +++++++ .../missing_closure_env/Prover.toml | 1 + .../missing_closure_env/src/main.nr | 16 ++++++++++++++++ 3 files changed, 24 insertions(+) create mode 100644 test_programs/execution_success/missing_closure_env/Nargo.toml create mode 100644 test_programs/execution_success/missing_closure_env/Prover.toml create mode 100644 test_programs/execution_success/missing_closure_env/src/main.nr diff --git a/test_programs/execution_success/missing_closure_env/Nargo.toml b/test_programs/execution_success/missing_closure_env/Nargo.toml new file mode 100644 index 00000000000..284e61b1144 --- /dev/null +++ b/test_programs/execution_success/missing_closure_env/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "missing_closure_env" +type = "bin" +authors = [""] +compiler_version = ">=0.23.0" + +[dependencies] \ No newline at end of file diff --git a/test_programs/execution_success/missing_closure_env/Prover.toml b/test_programs/execution_success/missing_closure_env/Prover.toml new file mode 100644 index 00000000000..2d76abaa89f --- /dev/null +++ b/test_programs/execution_success/missing_closure_env/Prover.toml @@ -0,0 +1 @@ +x = 42 diff --git a/test_programs/execution_success/missing_closure_env/src/main.nr b/test_programs/execution_success/missing_closure_env/src/main.nr new file mode 100644 index 00000000000..0bc99b0671c --- /dev/null +++ b/test_programs/execution_success/missing_closure_env/src/main.nr @@ -0,0 +1,16 @@ +fn main(x: Field) { + let x1 = &mut 42; + let set_x1 = |y| { *x1 = y; }; + + assert(*x1 == 42); + set_x1(44); + assert(*x1 == 44); + set_x1(*x1); + assert(*x1 == 44); + assert(x == 42); +} + +#[test] +fn test_main() { + main(42); +} From d646243b2e8deff64d4d7dfe379d9caeba81c3b5 Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Fri, 2 Feb 2024 10:55:26 +0000 Subject: [PATCH 67/70] feat: remove predicate from `sort` intrinsic function (#4228) # Description ## Problem\* Resolves ## Summary\* This PR removes the predicate from `AcirContext.sort()`. I'm not sure why this exists as we should always be able to perform a sorting on an array of values. We also list `Intrinsic::Sort` as having no side effects so it doesn't make sense for us to be using the side effects predicate here. ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- .../src/ssa/acir_gen/acir_ir/acir_variable.rs | 18 ++++-------------- .../noirc_evaluator/src/ssa/acir_gen/mod.rs | 5 +---- 2 files changed, 5 insertions(+), 18 deletions(-) diff --git a/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs b/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs index 5cf70b098f9..13d1ad707c2 100644 --- a/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs +++ b/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs @@ -1649,7 +1649,6 @@ impl AcirContext { &mut self, inputs: Vec, bit_size: u32, - predicate: AcirVar, ) -> Result, RuntimeError> { let len = inputs.len(); // Convert the inputs into expressions @@ -1666,25 +1665,16 @@ impl AcirContext { self.acir_ir.permutation(&inputs_expr, &output_expr)?; // Enforce the outputs to be sorted + let true_var = self.add_constant(true); for i in 0..(outputs_var.len() - 1) { - self.less_than_constrain(outputs_var[i], outputs_var[i + 1], bit_size, predicate)?; + let less_than_next_element = + self.more_than_eq_var(outputs_var[i + 1], outputs_var[i], bit_size)?; + self.assert_eq_var(less_than_next_element, true_var, None)?; } Ok(outputs_var) } - /// Constrain lhs to be less than rhs - fn less_than_constrain( - &mut self, - lhs: AcirVar, - rhs: AcirVar, - bit_size: u32, - predicate: AcirVar, - ) -> Result<(), RuntimeError> { - let lhs_less_than_rhs = self.more_than_eq_var(rhs, lhs, bit_size)?; - self.maybe_eq_predicate(lhs_less_than_rhs, predicate) - } - /// Returns a Variable that is constrained to be the result of reading /// from the memory `block_id` at the given `index`. pub(crate) fn read_from_memory( diff --git a/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs b/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs index 5d067737930..211506a6d15 100644 --- a/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs +++ b/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs @@ -1623,10 +1623,7 @@ impl Context { } } // Generate the sorted output variables - let out_vars = self - .acir_context - .sort(input_vars, bit_size, self.current_side_effects_enabled_var) - .expect("Could not sort"); + let out_vars = self.acir_context.sort(input_vars, bit_size)?; Ok(self.convert_vars_to_values(out_vars, dfg, result_ids)) } From 0ffc38bc8e91291c21cad3682ef77250e3c1e237 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Rodr=C3=ADguez?= Date: Fri, 2 Feb 2024 14:26:07 +0100 Subject: [PATCH 68/70] feat: Add warnings for usage of restricted bit sizes (#4234) # Description ## Problem\* Breaking change warning for [#4162](https://github.com/noir-lang/noir/issues/4162) ## Summary\* ## Additional Context ## Documentation\* Check one: - [ ] No documentation needed. - [ ] Documentation included in this PR. - [x] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- compiler/noirc_frontend/src/parser/errors.rs | 9 ++++ compiler/noirc_frontend/src/parser/parser.rs | 15 ++++++- noir_stdlib/src/cmp.nr | 26 ----------- noir_stdlib/src/convert.nr | 9 ---- noir_stdlib/src/default.nr | 2 - noir_stdlib/src/ops.nr | 20 --------- .../brillig_cast/src/main.nr | 26 ++++------- .../brillig_modulo/src/main.nr | 8 ++-- .../execution_success/5_over/src/main.nr | 4 +- .../bit_shifts_comptime/src/main.nr | 2 +- .../src/main.nr | 8 ++-- .../execution_success/regression/src/main.nr | 43 ++++++++++++++----- 12 files changed, 76 insertions(+), 96 deletions(-) diff --git a/compiler/noirc_frontend/src/parser/errors.rs b/compiler/noirc_frontend/src/parser/errors.rs index 5c869ff4719..9158c68db72 100644 --- a/compiler/noirc_frontend/src/parser/errors.rs +++ b/compiler/noirc_frontend/src/parser/errors.rs @@ -40,6 +40,8 @@ pub enum ParserErrorReason { NoFunctionAttributesAllowedOnStruct, #[error("Assert statements can only accept string literals")] AssertMessageNotString, + #[error("Integer bit size {0} won't be supported")] + DeprecatedBitSize(u32), #[error("{0}")] Lexer(LexerErrorKind), } @@ -130,6 +132,8 @@ impl std::fmt::Display for ParserError { } } +pub(crate) static ALLOWED_INTEGER_BIT_SIZES: &[u32] = &[1, 8, 32, 64]; + impl From for Diagnostic { fn from(error: ParserError) -> Diagnostic { match error.reason { @@ -145,6 +149,11 @@ impl From for Diagnostic { "The 'comptime' keyword has been deprecated. It can be removed without affecting your program".into(), error.span, ), + ParserErrorReason::DeprecatedBitSize(bit_size) => Diagnostic::simple_warning( + format!("Use of deprecated bit size {}", bit_size), + format!("Bit sizes for integers will be restricted to {}", ALLOWED_INTEGER_BIT_SIZES.iter().map(|n| n.to_string()).collect::>().join(", ")), + error.span, + ), ParserErrorReason::ExperimentalFeature(_) => Diagnostic::simple_warning( reason.to_string(), "".into(), diff --git a/compiler/noirc_frontend/src/parser/parser.rs b/compiler/noirc_frontend/src/parser/parser.rs index 1bdb276d4fb..1f41a29dd4f 100644 --- a/compiler/noirc_frontend/src/parser/parser.rs +++ b/compiler/noirc_frontend/src/parser/parser.rs @@ -23,6 +23,7 @@ //! prevent other parsers from being tried afterward since there is no longer an error. Thus, they should //! be limited to cases like the above `fn` example where it is clear we shouldn't back out of the //! current parser to try alternative parsers in a `choice` expression. +use super::errors::ALLOWED_INTEGER_BIT_SIZES; use super::{ foldl_with_span, labels::ParsingRuleLabel, parameter_name_recovery, parameter_recovery, parenthesized, then_commit, then_commit_ignore, top_level_statement_recovery, ExprParser, @@ -35,7 +36,7 @@ use crate::ast::{ }; use crate::lexer::Lexer; use crate::parser::{force, ignore_then_commit, statement_recovery}; -use crate::token::{Attribute, Attributes, Keyword, SecondaryAttribute, Token, TokenKind}; +use crate::token::{Attribute, Attributes, IntType, Keyword, SecondaryAttribute, Token, TokenKind}; use crate::{ BinaryOp, BinaryOpKind, BlockExpression, ConstrainKind, ConstrainStatement, Distinctness, ForLoopStatement, ForRange, FunctionDefinition, FunctionReturnType, FunctionVisibility, Ident, @@ -1092,6 +1093,18 @@ fn int_type() -> impl NoirParser { Err(ParserError::expected_label(ParsingRuleLabel::IntegerType, unexpected, span)) } })) + .validate(|int_type, span, emit| { + let bit_size = match int_type.1 { + IntType::Signed(bit_size) | IntType::Unsigned(bit_size) => bit_size, + }; + if !ALLOWED_INTEGER_BIT_SIZES.contains(&bit_size) { + emit(ParserError::with_reason( + ParserErrorReason::DeprecatedBitSize(bit_size), + span, + )); + } + int_type + }) .map_with_span(|(_, token), span| UnresolvedTypeData::from_int_token(token).with_span(span)) } diff --git a/noir_stdlib/src/cmp.nr b/noir_stdlib/src/cmp.nr index b3de3e2658e..38316e5d6a8 100644 --- a/noir_stdlib/src/cmp.nr +++ b/noir_stdlib/src/cmp.nr @@ -8,12 +8,10 @@ impl Eq for Field { fn eq(self, other: Field) -> bool { self == other } } impl Eq for u1 { fn eq(self, other: u1) -> bool { self == other } } impl Eq for u8 { fn eq(self, other: u8) -> bool { self == other } } -impl Eq for u16 { fn eq(self, other: u16) -> bool { self == other } } impl Eq for u32 { fn eq(self, other: u32) -> bool { self == other } } impl Eq for u64 { fn eq(self, other: u64) -> bool { self == other } } impl Eq for i8 { fn eq(self, other: i8) -> bool { self == other } } -impl Eq for i16 { fn eq(self, other: i16) -> bool { self == other } } impl Eq for i32 { fn eq(self, other: i32) -> bool { self == other } } impl Eq for i64 { fn eq(self, other: i64) -> bool { self == other } } @@ -111,18 +109,6 @@ impl Ord for u8 { } } -impl Ord for u16 { - fn cmp(self, other: u16) -> Ordering { - if self < other { - Ordering::less() - } else if self > other { - Ordering::greater() - } else { - Ordering::equal() - } - } -} - impl Ord for u32 { fn cmp(self, other: u32) -> Ordering { if self < other { @@ -159,18 +145,6 @@ impl Ord for i8 { } } -impl Ord for i16 { - fn cmp(self, other: i16) -> Ordering { - if self < other { - Ordering::less() - } else if self > other { - Ordering::greater() - } else { - Ordering::equal() - } - } -} - impl Ord for i32 { fn cmp(self, other: i32) -> Ordering { if self < other { diff --git a/noir_stdlib/src/convert.nr b/noir_stdlib/src/convert.nr index 814f63f1cde..00ac0a0fd8c 100644 --- a/noir_stdlib/src/convert.nr +++ b/noir_stdlib/src/convert.nr @@ -24,37 +24,28 @@ impl Into for U where T: From { // docs:start:from-impls // Unsigned integers -impl From for u16 { fn from(value: u8) -> u16 { value as u16 } } impl From for u32 { fn from(value: u8) -> u32 { value as u32 } } -impl From for u32 { fn from(value: u16) -> u32 { value as u32 } } impl From for u64 { fn from(value: u8) -> u64 { value as u64 } } -impl From for u64 { fn from(value: u16) -> u64 { value as u64 } } impl From for u64 { fn from(value: u32) -> u64 { value as u64 } } impl From for Field { fn from(value: u8) -> Field { value as Field } } -impl From for Field { fn from(value: u16) -> Field { value as Field } } impl From for Field { fn from(value: u32) -> Field { value as Field } } impl From for Field { fn from(value: u64) -> Field { value as Field } } // Signed integers -impl From for i16 { fn from(value: i8) -> i16 { value as i16 } } impl From for i32 { fn from(value: i8) -> i32 { value as i32 } } -impl From for i32 { fn from(value: i16) -> i32 { value as i32 } } impl From for i64 { fn from(value: i8) -> i64 { value as i64 } } -impl From for i64 { fn from(value: i16) -> i64 { value as i64 } } impl From for i64 { fn from(value: i32) -> i64 { value as i64 } } // Booleans impl From for u8 { fn from(value: bool) -> u8 { value as u8 } } -impl From for u16 { fn from(value: bool) -> u16 { value as u16 } } impl From for u32 { fn from(value: bool) -> u32 { value as u32 } } impl From for u64 { fn from(value: bool) -> u64 { value as u64 } } impl From for i8 { fn from(value: bool) -> i8 { value as i8 } } -impl From for i16 { fn from(value: bool) -> i16 { value as i16 } } impl From for i32 { fn from(value: bool) -> i32 { value as i32 } } impl From for i64 { fn from(value: bool) -> i64 { value as i64 } } impl From for Field { fn from(value: bool) -> Field { value as Field } } diff --git a/noir_stdlib/src/default.nr b/noir_stdlib/src/default.nr index ba6412a834f..32c4f3f3b48 100644 --- a/noir_stdlib/src/default.nr +++ b/noir_stdlib/src/default.nr @@ -7,12 +7,10 @@ trait Default { impl Default for Field { fn default() -> Field { 0 } } impl Default for u8 { fn default() -> u8 { 0 } } -impl Default for u16 { fn default() -> u16 { 0 } } impl Default for u32 { fn default() -> u32 { 0 } } impl Default for u64 { fn default() -> u64 { 0 } } impl Default for i8 { fn default() -> i8 { 0 } } -impl Default for i16 { fn default() -> i16 { 0 } } impl Default for i32 { fn default() -> i32 { 0 } } impl Default for i64 { fn default() -> i64 { 0 } } diff --git a/noir_stdlib/src/ops.nr b/noir_stdlib/src/ops.nr index 50386290b8e..e561265629e 100644 --- a/noir_stdlib/src/ops.nr +++ b/noir_stdlib/src/ops.nr @@ -7,12 +7,10 @@ trait Add { impl Add for Field { fn add(self, other: Field) -> Field { self + other } } impl Add for u8 { fn add(self, other: u8) -> u8 { self + other } } -impl Add for u16 { fn add(self, other: u16) -> u16 { self + other } } impl Add for u32 { fn add(self, other: u32) -> u32 { self + other } } impl Add for u64 { fn add(self, other: u64) -> u64 { self + other } } impl Add for i8 { fn add(self, other: i8) -> i8 { self + other } } -impl Add for i16 { fn add(self, other: i16) -> i16 { self + other } } impl Add for i32 { fn add(self, other: i32) -> i32 { self + other } } impl Add for i64 { fn add(self, other: i64) -> i64 { self + other } } @@ -25,12 +23,10 @@ trait Sub { impl Sub for Field { fn sub(self, other: Field) -> Field { self - other } } impl Sub for u8 { fn sub(self, other: u8) -> u8 { self - other } } -impl Sub for u16 { fn sub(self, other: u16) -> u16 { self - other } } impl Sub for u32 { fn sub(self, other: u32) -> u32 { self - other } } impl Sub for u64 { fn sub(self, other: u64) -> u64 { self - other } } impl Sub for i8 { fn sub(self, other: i8) -> i8 { self - other } } -impl Sub for i16 { fn sub(self, other: i16) -> i16 { self - other } } impl Sub for i32 { fn sub(self, other: i32) -> i32 { self - other } } impl Sub for i64 { fn sub(self, other: i64) -> i64 { self - other } } @@ -43,12 +39,10 @@ trait Mul { impl Mul for Field { fn mul(self, other: Field) -> Field { self * other } } impl Mul for u8 { fn mul(self, other: u8) -> u8 { self * other } } -impl Mul for u16 { fn mul(self, other: u16) -> u16 { self * other } } impl Mul for u32 { fn mul(self, other: u32) -> u32 { self * other } } impl Mul for u64 { fn mul(self, other: u64) -> u64 { self * other } } impl Mul for i8 { fn mul(self, other: i8) -> i8 { self * other } } -impl Mul for i16 { fn mul(self, other: i16) -> i16 { self * other } } impl Mul for i32 { fn mul(self, other: i32) -> i32 { self * other } } impl Mul for i64 { fn mul(self, other: i64) -> i64 { self * other } } @@ -61,12 +55,10 @@ trait Div { impl Div for Field { fn div(self, other: Field) -> Field { self / other } } impl Div for u8 { fn div(self, other: u8) -> u8 { self / other } } -impl Div for u16 { fn div(self, other: u16) -> u16 { self / other } } impl Div for u32 { fn div(self, other: u32) -> u32 { self / other } } impl Div for u64 { fn div(self, other: u64) -> u64 { self / other } } impl Div for i8 { fn div(self, other: i8) -> i8 { self / other } } -impl Div for i16 { fn div(self, other: i16) -> i16 { self / other } } impl Div for i32 { fn div(self, other: i32) -> i32 { self / other } } impl Div for i64 { fn div(self, other: i64) -> i64 { self / other } } @@ -77,12 +69,10 @@ trait Rem{ // docs:end:rem-trait impl Rem for u8 { fn rem(self, other: u8) -> u8 { self % other } } -impl Rem for u16 { fn rem(self, other: u16) -> u16 { self % other } } impl Rem for u32 { fn rem(self, other: u32) -> u32 { self % other } } impl Rem for u64 { fn rem(self, other: u64) -> u64 { self % other } } impl Rem for i8 { fn rem(self, other: i8) -> i8 { self % other } } -impl Rem for i16 { fn rem(self, other: i16) -> i16 { self % other } } impl Rem for i32 { fn rem(self, other: i32) -> i32 { self % other } } impl Rem for i64 { fn rem(self, other: i64) -> i64 { self % other } } @@ -95,12 +85,10 @@ trait BitOr { impl BitOr for bool { fn bitor(self, other: bool) -> bool { self | other } } impl BitOr for u8 { fn bitor(self, other: u8) -> u8 { self | other } } -impl BitOr for u16 { fn bitor(self, other: u16) -> u16 { self | other } } impl BitOr for u32 { fn bitor(self, other: u32) -> u32 { self | other } } impl BitOr for u64 { fn bitor(self, other: u64) -> u64 { self | other } } impl BitOr for i8 { fn bitor(self, other: i8) -> i8 { self | other } } -impl BitOr for i16 { fn bitor(self, other: i16) -> i16 { self | other } } impl BitOr for i32 { fn bitor(self, other: i32) -> i32 { self | other } } impl BitOr for i64 { fn bitor(self, other: i64) -> i64 { self | other } } @@ -113,12 +101,10 @@ trait BitAnd { impl BitAnd for bool { fn bitand(self, other: bool) -> bool { self & other } } impl BitAnd for u8 { fn bitand(self, other: u8) -> u8 { self & other } } -impl BitAnd for u16 { fn bitand(self, other: u16) -> u16 { self & other } } impl BitAnd for u32 { fn bitand(self, other: u32) -> u32 { self & other } } impl BitAnd for u64 { fn bitand(self, other: u64) -> u64 { self & other } } impl BitAnd for i8 { fn bitand(self, other: i8) -> i8 { self & other } } -impl BitAnd for i16 { fn bitand(self, other: i16) -> i16 { self & other } } impl BitAnd for i32 { fn bitand(self, other: i32) -> i32 { self & other } } impl BitAnd for i64 { fn bitand(self, other: i64) -> i64 { self & other } } @@ -131,12 +117,10 @@ trait BitXor { impl BitXor for bool { fn bitxor(self, other: bool) -> bool { self ^ other } } impl BitXor for u8 { fn bitxor(self, other: u8) -> u8 { self ^ other } } -impl BitXor for u16 { fn bitxor(self, other: u16) -> u16 { self ^ other } } impl BitXor for u32 { fn bitxor(self, other: u32) -> u32 { self ^ other } } impl BitXor for u64 { fn bitxor(self, other: u64) -> u64 { self ^ other } } impl BitXor for i8 { fn bitxor(self, other: i8) -> i8 { self ^ other } } -impl BitXor for i16 { fn bitxor(self, other: i16) -> i16 { self ^ other } } impl BitXor for i32 { fn bitxor(self, other: i32) -> i32 { self ^ other } } impl BitXor for i64 { fn bitxor(self, other: i64) -> i64 { self ^ other } } @@ -147,13 +131,11 @@ trait Shl { // docs:end:shl-trait impl Shl for u8 { fn shl(self, other: u8) -> u8 { self << other } } -impl Shl for u16 { fn shl(self, other: u16) -> u16 { self << other } } impl Shl for u32 { fn shl(self, other: u32) -> u32 { self << other } } impl Shl for u64 { fn shl(self, other: u64) -> u64 { self << other } } // Bit shifting is not currently supported for signed integer types // impl Shl for i8 { fn shl(self, other: i8) -> i8 { self << other } } -// impl Shl for i16 { fn shl(self, other: i16) -> i16 { self << other } } // impl Shl for i32 { fn shl(self, other: i32) -> i32 { self << other } } // impl Shl for i64 { fn shl(self, other: i64) -> i64 { self << other } } @@ -164,12 +146,10 @@ trait Shr { // docs:end:shr-trait impl Shr for u8 { fn shr(self, other: u8) -> u8 { self >> other } } -impl Shr for u16 { fn shr(self, other: u16) -> u16 { self >> other } } impl Shr for u32 { fn shr(self, other: u32) -> u32 { self >> other } } impl Shr for u64 { fn shr(self, other: u64) -> u64 { self >> other } } // Bit shifting is not currently supported for signed integer types // impl Shr for i8 { fn shr(self, other: i8) -> i8 { self >> other } } -// impl Shr for i16 { fn shr(self, other: i16) -> i16 { self >> other } } // impl Shr for i32 { fn shr(self, other: i32) -> i32 { self >> other } } // impl Shr for i64 { fn shr(self, other: i64) -> i64 { self >> other } } diff --git a/test_programs/compile_success_empty/brillig_cast/src/main.nr b/test_programs/compile_success_empty/brillig_cast/src/main.nr index 3ba29b52982..ecb832468ba 100644 --- a/test_programs/compile_success_empty/brillig_cast/src/main.nr +++ b/test_programs/compile_success_empty/brillig_cast/src/main.nr @@ -17,33 +17,25 @@ unconstrained fn bool_casts() { unconstrained fn field_casts() { assert(5 as u8 as Field == 5); - assert(16 as u4 as Field == 0); + assert(256 as u8 as Field == 0); } unconstrained fn uint_casts() { - let x: u32 = 100; - assert(x as u2 == 0); - assert(x as u4 == 4); - assert(x as u6 == 36); - assert(x as u8 == 100); - assert(x as u64 == 100); - assert(x as u126 == 100); + let x: u32 = 300; + assert(x as u8 == 44); + assert(x as u32 == 300); + assert(x as u64 == 300); } unconstrained fn int_casts() { - let x: i32 = 100; - assert(x as i2 == 0); - assert(x as i4 == 4); - assert(x as i6 == -28 as i6); - assert(x as i8 == 100); - assert(x as i8 == 100); - assert(x as i8 == 100); + let x: i32 = 456; + assert(x as i8 == -56 as i8); + assert(x as i64 == 456); } unconstrained fn mixed_casts() { assert(100 as u32 as i32 as u32 == 100); - assert(13 as u4 as i2 as u32 == 1); - assert(15 as u4 as i2 as u32 == 3); + assert(257 as u8 as u32 == 1); assert(1 as u8 as bool == true); assert(true as i8 == 1); } diff --git a/test_programs/compile_success_empty/brillig_modulo/src/main.nr b/test_programs/compile_success_empty/brillig_modulo/src/main.nr index ed0353b101a..195ed31fb08 100644 --- a/test_programs/compile_success_empty/brillig_modulo/src/main.nr +++ b/test_programs/compile_success_empty/brillig_modulo/src/main.nr @@ -7,9 +7,9 @@ fn main() { assert(signed_modulo(5, 3) == 2); assert(signed_modulo(2, 3) == 2); - let minus_two: i4 = -2; // 14 - let minus_three: i4 = -3; // 13 - let minus_five: i4 = -5; // 11 + let minus_two: i8 = -2; // 254 + let minus_three: i8 = -3; // 253 + let minus_five: i8 = -5; // 251 // (5 / -3) * -3 + 2 = -1 * -3 + 2 = 3 + 2 = 5 assert(signed_modulo(5, minus_three) == 2); // (-5 / 3) * 3 - 2 = -1 * 3 - 2 = -3 - 2 = -5 @@ -22,6 +22,6 @@ unconstrained fn modulo(x: u32, y: u32) -> u32 { x % y } -unconstrained fn signed_modulo(x: i4, y: i4) -> i4 { +unconstrained fn signed_modulo(x: i8, y: i8) -> i8 { x % y } diff --git a/test_programs/execution_success/5_over/src/main.nr b/test_programs/execution_success/5_over/src/main.nr index f24ff06cb2a..313d580a8d1 100644 --- a/test_programs/execution_success/5_over/src/main.nr +++ b/test_programs/execution_success/5_over/src/main.nr @@ -5,6 +5,6 @@ fn main(mut x: u32, y: u32) { x = std::wrapping_mul(x,x); assert(y == x); - let c: u3 = 2; - assert(c > x as u3); + let c: u1 = 0; + assert(x as u1 > c); } diff --git a/test_programs/execution_success/bit_shifts_comptime/src/main.nr b/test_programs/execution_success/bit_shifts_comptime/src/main.nr index 9bb1028173d..9184b5bd5e6 100644 --- a/test_programs/execution_success/bit_shifts_comptime/src/main.nr +++ b/test_programs/execution_success/bit_shifts_comptime/src/main.nr @@ -14,7 +14,7 @@ fn main(x: u64) { //regression for 3481 assert(x << 63 == 0); - assert_eq((1 as u56) << (32 as u56), 0x0100000000); + assert_eq((1 as u64) << (32 as u64), 0x0100000000); } fn regression_2250() { diff --git a/test_programs/execution_success/conditional_regression_underflow/src/main.nr b/test_programs/execution_success/conditional_regression_underflow/src/main.nr index a101af32505..aaf3754a20f 100644 --- a/test_programs/execution_success/conditional_regression_underflow/src/main.nr +++ b/test_programs/execution_success/conditional_regression_underflow/src/main.nr @@ -1,12 +1,12 @@ // Regression test for https://github.com/noir-lang/noir/issues/3493 -fn main(x: u4) { +fn main(x: u8) { if x == 10 { - x + 15; + x + 255; } if x == 9 { - x << 3; + x << 7; } - if x == 8 { + if x == 128 { x * 3; } if x == 7 { diff --git a/test_programs/execution_success/regression/src/main.nr b/test_programs/execution_success/regression/src/main.nr index 08112d4c616..c70e2e75fa8 100644 --- a/test_programs/execution_success/regression/src/main.nr +++ b/test_programs/execution_success/regression/src/main.nr @@ -1,29 +1,49 @@ global NIBBLE_LENGTH: Field = 16; -fn compact_decode(input: [u8; N], length: Field) -> ([u4; NIBBLE_LENGTH], Field) { +struct U4 { + inner: u8, +} + +impl U4 { + fn zero() -> U4 { + U4 { inner: 0 } + } + + fn from_u8(x: u8) -> U4 { + U4 { inner: x % 16 } + } +} + +impl Eq for U4 { + fn eq(self, other: Self) -> bool { + self.inner == other.inner + } +} + +fn compact_decode(input: [u8; N], length: Field) -> ([U4; NIBBLE_LENGTH], Field) { assert(2 * input.len() as u64 <= NIBBLE_LENGTH as u64); assert(length as u64 <= input.len() as u64); - let mut nibble = [0 as u4; NIBBLE_LENGTH]; + let mut nibble = [U4::zero(); NIBBLE_LENGTH]; - let first_nibble = (input[0] >> 4) as u4; - let parity = first_nibble as u1; + let first_nibble = U4::from_u8(input[0] >> 4); + let parity = first_nibble.inner as u1; if parity == 1 { - nibble[0] = (input[0] & 0x0f) as u4; + nibble[0] = U4::from_u8(input[0] & 0x0f); for i in 1..input.len() { if i as u64 < length as u64 { let x = input[i]; - nibble[2*i - 1] = (x >> 4) as u4; - nibble[2*i] = (x & 0x0f) as u4; + nibble[2*i - 1] = U4::from_u8(x >> 4); + nibble[2*i] = U4::from_u8(x & 0x0f); } } } else { for i in 0..2 { if (i as u64) < length as u64 - 1 { let x = input[i + 1]; - nibble[2*i] = (x >> 4) as u4; - nibble[2*i + 1] = (x & 0x0f) as u4; + nibble[2*i] = U4::from_u8(x >> 4); + nibble[2*i + 1] = U4::from_u8(x & 0x0f); } } } @@ -78,7 +98,10 @@ fn main(x: [u8; 5], z: Field) { //Issue 1144 let (nib, len) = compact_decode(x, z); assert(len == 5); - assert([nib[0], nib[1], nib[2], nib[3], nib[4]] == [15, 1, 12, 11, 8]); + assert( + [nib[0], nib[1], nib[2], nib[3], nib[4]] + == [U4::from_u8(15), U4::from_u8(1), U4::from_u8(12), U4::from_u8(11), U4::from_u8(8)] + ); // Issue 1169 let val1 = [ 0xb8, 0x8f, 0x61, 0xe6, 0xfb, 0xda, 0x83, 0xfb, 0xff, 0xfa, 0xbe, 0x36, 0x41, 0x12, 0x13, From afcb385daa572f990178eda51faf10dc20acd2d0 Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Fri, 2 Feb 2024 14:15:18 +0000 Subject: [PATCH 69/70] chore: automatically recompile `noir_js` test case programs (#4236) # Description ## Problem\* [CI is currently failing in master](https://github.com/noir-lang/noir/actions/runs/7755136791/job/21150220295) due to the new testcase added in #4101 not being added to the docker test flow. ## Summary\* This PR adds a compilation step to `yarn test` which recompiles all of the test programs with the currently installed version of nargo. This is similar to what we're doing in `noir_codegen`. ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- .github/scripts/noir-js-test.sh | 4 +--- .github/workflows/test-js-packages.yml | 16 +++++++++++++++- scripts/nargo_compile_noir_js_assert_lt.sh | 4 ---- tooling/noir_js/.gitignore | 2 -- tooling/noir_js/package.json | 3 ++- tooling/noir_js/scripts/compile_test_programs.sh | 5 +++++ .../assert_lt/target/assert_lt.json | 1 - .../target/assert_msg_runtime.json | 1 - 8 files changed, 23 insertions(+), 13 deletions(-) delete mode 100755 scripts/nargo_compile_noir_js_assert_lt.sh create mode 100755 tooling/noir_js/scripts/compile_test_programs.sh delete mode 100644 tooling/noir_js/test/noir_compiled_examples/assert_lt/target/assert_lt.json delete mode 100644 tooling/noir_js/test/noir_compiled_examples/assert_msg_runtime/target/assert_msg_runtime.json diff --git a/.github/scripts/noir-js-test.sh b/.github/scripts/noir-js-test.sh index b5fe34038fe..72458d8de6a 100755 --- a/.github/scripts/noir-js-test.sh +++ b/.github/scripts/noir-js-test.sh @@ -1,6 +1,4 @@ #!/bin/bash set -eu -./scripts/nargo_compile_noir_js_assert_lt.sh -rm -rf /usr/src/noir/tooling/noir_js/test/noir_compiled_examples/assert_lt/target/debug_assert_lt.json -yarn workspace @noir-lang/noir_js test \ No newline at end of file +yarn workspace @noir-lang/noir_js test diff --git a/.github/workflows/test-js-packages.yml b/.github/workflows/test-js-packages.yml index addc9ce3d83..036c582eaa4 100644 --- a/.github/workflows/test-js-packages.yml +++ b/.github/workflows/test-js-packages.yml @@ -247,7 +247,7 @@ jobs: yarn workspace @noir-lang/backend_barretenberg test test-noir-js: - needs: [build-acvm-js, build-noirc-abi] + needs: [build-nargo, build-acvm-js, build-noirc-abi] name: Noir JS runs-on: ubuntu-latest timeout-minutes: 30 @@ -256,6 +256,12 @@ jobs: - name: Checkout uses: actions/checkout@v4 + - name: Download nargo binary + uses: actions/download-artifact@v3 + with: + name: nargo + path: ./nargo + - name: Download artifact uses: actions/download-artifact@v3 with: @@ -268,6 +274,14 @@ jobs: name: noirc_abi_wasm path: ./tooling/noirc_abi_wasm + - name: Set nargo on PATH + run: | + nargo_binary="${{ github.workspace }}/nargo/nargo" + chmod +x $nargo_binary + echo "$(dirname $nargo_binary)" >> $GITHUB_PATH + export PATH="$PATH:$(dirname $nargo_binary)" + nargo -V + - name: Install Yarn dependencies uses: ./.github/actions/setup diff --git a/scripts/nargo_compile_noir_js_assert_lt.sh b/scripts/nargo_compile_noir_js_assert_lt.sh deleted file mode 100755 index 636ae59b996..00000000000 --- a/scripts/nargo_compile_noir_js_assert_lt.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash - -cd ./tooling/noir_js/test/noir_compiled_examples/assert_lt -nargo compile \ No newline at end of file diff --git a/tooling/noir_js/.gitignore b/tooling/noir_js/.gitignore index 5b57ba1708d..a55d1794141 100644 --- a/tooling/noir_js/.gitignore +++ b/tooling/noir_js/.gitignore @@ -1,3 +1 @@ crs - -!test/noir_compiled_examples/*/target diff --git a/tooling/noir_js/package.json b/tooling/noir_js/package.json index 356909a1e35..5f83a03019b 100644 --- a/tooling/noir_js/package.json +++ b/tooling/noir_js/package.json @@ -37,7 +37,8 @@ "scripts": { "dev": "tsc-multi --watch", "build": "tsc-multi", - "test": "yarn test:node:esm && yarn test:node:cjs", + "test": "yarn test:compile_program && yarn test:node:esm && yarn test:node:cjs", + "test:compile_program": "./scripts/compile_test_programs.sh", "test:node:esm": "mocha --timeout 25000 --exit --config ./.mocharc.json", "test:node:cjs": "mocha --timeout 25000 --exit --config ./.mocharc.cjs.json", "prettier": "prettier 'src/**/*.ts'", diff --git a/tooling/noir_js/scripts/compile_test_programs.sh b/tooling/noir_js/scripts/compile_test_programs.sh new file mode 100755 index 00000000000..5257aaae696 --- /dev/null +++ b/tooling/noir_js/scripts/compile_test_programs.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +rm -rf ./test/noir_compiled_examples/**/target +nargo --program-dir ./test/noir_compiled_examples/assert_lt compile --force +nargo --program-dir ./test/noir_compiled_examples/assert_msg_runtime compile --force diff --git a/tooling/noir_js/test/noir_compiled_examples/assert_lt/target/assert_lt.json b/tooling/noir_js/test/noir_compiled_examples/assert_lt/target/assert_lt.json deleted file mode 100644 index 027df0b39d9..00000000000 --- a/tooling/noir_js/test/noir_compiled_examples/assert_lt/target/assert_lt.json +++ /dev/null @@ -1 +0,0 @@ -{"noir_version":"0.23.0+2dc4805116123ecde584fe0f2cd280de817d3915","hash":17955244824623030861,"abi":{"parameters":[{"name":"x","type":{"kind":"integer","sign":"unsigned","width":64},"visibility":"private"},{"name":"y","type":{"kind":"integer","sign":"unsigned","width":64},"visibility":"public"}],"param_witnesses":{"x":[{"start":0,"end":1}],"y":[{"start":1,"end":2}]},"return_type":{"abi_type":{"kind":"integer","sign":"unsigned","width":64},"visibility":"public"},"return_witnesses":[4]},"bytecode":"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","debug_symbols":"ndvNilVHFIbhezljCftbq/auqr6VkIEkBgTREJ1J33sSYjLQ/uE8Mx180OhLD55d6+vtw6df3355/+nj59vD11vdHn7+evv8x9uP//zt85e3f365PeRcb27vPv7295/mfHxz+/39h3e3h1GPv7y59VODcexvg5Hx3WDcOzjvHVz3Dua9g3XvYD85mP/9s47V3w1y3Luon578qeqY3ybV5/+TWv9O9v2Tp3+yOerbZl7zx01gU7Bp2AzYnLC5YDNhs2Cz798UdFDQQUEHBR0UdFDQQUEHBR0UdFDQQUMHDR00dNDQQUMHDR00dNDQQUMHDR0M6GBABwM6GNDBgA4GdDCggwEdDOhgQAcndHBCByd0cEIHJ3RwQgcndHBCByd0cEIHF3RwQQcXdHBBBxd0cEEHF3RwQQcXdHBBBxM6mNDBhA4mdDChgwkdTOhgQgcTOpjQwYIOFnSwoIMFHSzoYEEHCzpY0MGCDhZ0sKGDDR1s6GBDBxs62NDBhg42dLChgw0d5BBIOkSSDqGkQyzpEEw6RJMO4aRDPOkQUDqkCKNFKYJwkXSReJF8kYCRhJGIUYwxgowp0mYpQpwxAo0RaYxQY8QaI9gY0cYIN0a8MU0fIKQIIceIOUbQMaKOEXaMuGMEHiPyGKHHDPomJUWIPuZ+fpzPfMp66ePkfOZT1subOmAT2Dz5//rSZ9D5zCemVzYDNidsLthM2CzY7Ps3T//Of2UT2EAHDR00dNDQQUMHDR00dNDQwYAOBnQwoIMBHQzoYEAHAzoY0MGADgZ0cEIHJ3RwQgcndHBCByd0cEIHJ3RwQgcndHBBBxd0cEEHF3RwQQcXdHBBBxd0cEEHF3QwoYMJHUzoYEIHEzqY0MGEDiZ0MKGDCR0s6GBBBws6WNDBgg4WdLCggwUdLOhgQQcbOtjQwYYONnSwoYMNHWzoYEMHGzrY0MEzn5heG0VGJaOW0ZDRKaNLRlNGS0ZSRKSISBGRIiJFRIqIFBEpIlJEpIhIESVFlBQhzBhxxgg0RqQxQo0Ra4xgY0QbI9wY8cYIOEbEMUKOEXOMoGNEHSPsGHHHCDxG5DFCjxF7jOBjRB8j/BjxxwhARgQyQpARg4wgZEQhIwwZccgIREYkMkKREYuMYGREIyMcGfHICEhGRDJCkhGTjKBkRCUjLBlxyQhMRmQyQpMRm4zgZEQnIzwZ8ckIUEaEMkKUEaOMIGVEKSNMGXHKCFRGpDJClRGrjGBlRCsjXBnxyghYRsQyQpYRsywxyxKzLDHLErMsMcsSsywxyxKzLDHLErMsMcsSsywxyxKzLDHLErMsMcsSsywxyxKzLDHLErMsehpJbyPpcSS9jqTnkfQ+kh5IilmWmGWJWVbTY1kpQsyyxCxLzLLELEvMssQsS8yyxCxLzLIGvZ+WIsQsS8yyxCxLzLLELEvMssQsS8yyxCxLzLLELEvMssQsS8yyxCxLzLLELEvMssQsS8yyLrqykCLELEvMssQsS8yyxCxLzLLELEvMssQsa9LhjRQhZlliliVmWWKWJWZZYpYlZlliliVmWYtusaQIMcsSsywxyxKzLDHLErMsMcsSsywxy9p0nkf3eXKgJ2bZYpYtZtlili1m2WKWLWbZYpYtZtmhk00pQsyyxSxbzLLFLFvMssUsW8yyxSxbzLKLrnilCDHLFrNsMcsWs2wxyxazbLrqprNuuuu2w24pgk676babjrvpupvOu8UsW8yyxSxbzLIH3fpLEWKWLWbZYpZ9r1k+Pv4F","file_map":{"28":{"source":"mod hash;\nmod array;\nmod slice;\nmod merkle;\nmod schnorr;\nmod ecdsa_secp256k1;\nmod ecdsa_secp256r1;\nmod eddsa;\nmod grumpkin_scalar;\nmod grumpkin_scalar_mul;\nmod scalar_mul;\nmod sha256;\nmod sha512;\nmod field;\nmod ec;\nmod unsafe;\nmod collections;\nmod compat;\nmod convert;\nmod option;\nmod string;\nmod test;\nmod cmp;\nmod ops;\nmod default;\nmod prelude;\nmod uint128;\n// mod bigint;\n\n// Oracle calls are required to be wrapped in an unconstrained function\n// Thus, the only argument to the `println` oracle is expected to always be an ident\n#[oracle(print)]\nunconstrained fn print_oracle(with_newline: bool, input: T) {}\n\nunconstrained pub fn print(input: T) {\n print_oracle(false, input);\n}\n\nunconstrained pub fn println(input: T) {\n print_oracle(true, input);\n}\n\n#[foreign(recursive_aggregation)]\npub fn verify_proof(verification_key: [Field], proof: [Field], public_inputs: [Field], key_hash: Field) {}\n\n// Asserts that the given value is known at compile-time.\n// Useful for debugging for-loop bounds.\n#[builtin(assert_constant)]\npub fn assert_constant(x: T) {}\n// from_field and as_field are private since they are not valid for every type.\n// `as` should be the default for users to cast between primitive types, and in the future\n// traits can be used to work with generic types.\n#[builtin(from_field)]\nfn from_field(x: Field) -> T {}\n\n#[builtin(as_field)]\nfn as_field(x: T) -> Field {}\n\npub fn wrapping_add(x: T, y: T) -> T {\n crate::from_field(crate::as_field(x) + crate::as_field(y))\n}\n\npub fn wrapping_sub(x: T, y: T) -> T {\n //340282366920938463463374607431768211456 is 2^128, it is used to avoid underflow\n crate::from_field(crate::as_field(x) + 340282366920938463463374607431768211456 - crate::as_field(y))\n}\n\npub fn wrapping_mul(x: T, y: T) -> T {\n crate::from_field(crate::as_field(x) * crate::as_field(y))\n}\n","path":"std/lib.nr"},"42":{"source":"use dep::std;\n\nfn main(x: u64, y: pub u64) -> pub u64 {\n // We include a println statement to show that noirJS will ignore this and continue execution\n std::println(\"foo\");\n\n // A dynamic assertion message is used to show that noirJS will ignore the call and continue execution\n // The assertion passes and thus the foreign call for resolving an assertion message should not be called.\n assert(x < y, f\"Expected x < y but got {x} < {y}\");\n\n assert(x < y);\n x + y\n}\n","path":"/mnt/user-data/maxim/noir/tooling/noir_js/test/noir_compiled_examples/assert_lt/src/main.nr"}}} \ No newline at end of file diff --git a/tooling/noir_js/test/noir_compiled_examples/assert_msg_runtime/target/assert_msg_runtime.json b/tooling/noir_js/test/noir_compiled_examples/assert_msg_runtime/target/assert_msg_runtime.json deleted file mode 100644 index 300e9a06e13..00000000000 --- a/tooling/noir_js/test/noir_compiled_examples/assert_msg_runtime/target/assert_msg_runtime.json +++ /dev/null @@ -1 +0,0 @@ -{"noir_version":"0.23.0+2dc4805116123ecde584fe0f2cd280de817d3915","hash":8331765605233675558,"abi":{"parameters":[{"name":"x","type":{"kind":"integer","sign":"unsigned","width":64},"visibility":"private"},{"name":"y","type":{"kind":"integer","sign":"unsigned","width":64},"visibility":"public"}],"param_witnesses":{"x":[{"start":0,"end":1}],"y":[{"start":1,"end":2}]},"return_type":null,"return_witnesses":[]},"bytecode":"H4sIAAAAAAAA/+2c2W6bQBSGwVviJBi870si9Z4dfFflQRrZDelVb+q+vxqWUU/wNEPrM0OPlJEsYDDnfP/PsHgG3NY07VrLi/76aRTzn8GyXiw3wXpY4DZpsS8rDozl2aHvJ5GbOJ5zsN39MQ5sPziGsRM7QRw8u7HnJbEfR/vjPrL3ju8lzkuw916KYPq/cznlCo50tNgNjp+p323Ovmm9fh7B93Uw1UGMR7AN7zv6H+J0OSw9sP5S8WdmMHFNEFMDJmDmgrEwG9elsVp4Gu33/PtLTrvE6TQQNTcR9+sF/p0djOUDb6fxCw67H8iJG8WS4tpy4oaSfAg9ST74xHyQxOtKag+y2q8sXu8rMX/3tHhDV5IPss6/xI63MJIU9+XD34z3KCmurOv8My1/yZ1/ZbUHSef18/aAF9t+c27XcWM7iLFsmZy6pobz0t9tDeR9k5anAjLtfGhrb0un+GB6nea5KvmT1rHOsAaoYx0iTVB3U8y3AKOGyujaHQ29jdldoK0N9DRLOrpA2xWoY9tcgzq4DZuybW5ALquY7xXbdHG1ZccP7MzUQQ7G0wTfGRXTVOcX/bf+awlczF8Wt1nysQO8wsnrBrA9a8AXrcTCyg1gwd43acxb3JjZ8XGHGjO/JhvAE+bfLZiy9XfALwPZLx3kZHHZsiEtr5tdh3sC/T0OR0+h/p60vGG2/02BfpPDYSrUb0rLG2b3jpZAv8XhsBTqt6TlDZM0Rl+gv8/h6CvU35eWN+8jHAj0DzgcA4X6IV9VVqNmVvy83iGNMRToH3I4hgr1Q76qrEbNrPh58z7GkUD/iMMxUqgf8lVltWpmxc8bZeNFY4H+MYdjrFA/5KvKatbMip8377OeCPRPOBwThfohX1VWq2ZW/Lz5uOZUoH/K4Zgq1A/5qrL2CbGahFitmlnx8+ZjVjOB/hmHY6ZQP+SryjohxDomxFq3r/h5o6yPaS7QP+dwzBXqh3xVWY2aWfHzutmY6kKgf8HhWCjUD/mqsho1s+LnjbJ74aVA/5LDsVSoH/JVZTUJsfYJsU5rZsXPG2bPwqwE+lccjpVC/ZCvKqtBiHVQMyt+Xi9MY6wF+tccjrVC/Wtpeb3sd8tGoH/D4dgo1L+Rljd/9mkr0L/lcGwV6t+CvDvUvPmzBDBvWt57lmAn0YM05j1uzOx5qQfAz7Teg2W2Ho77PyBr00FOFpctQ76qrAYh1h4hVpMQq0WItU+IldKxNSDESsnXISFWSueBESFWSteCMSFWSu11QoiV0jX24z5LDuuUECulY4vS+ZWSrzNCrJTuX+eEWCn5uiDESukaS+nehdI1dkmI9aPfRQ7rihDrmhDrpmZWCeMlTjr+xfrrD6dT8uPn0/fkdDp8SxgJfLu6UczvAGkLzMM3vjtgOzbK9gnU3ZbqNKAOvsl7pUn8yzoYUy/F/o9er7d1DueZKa/lFybuFpAIUgAA"} \ No newline at end of file From b3ddf10a2cbb80e88821baf7d76c478c3b98b3ea Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Fri, 2 Feb 2024 16:31:23 +0000 Subject: [PATCH 70/70] fix: allow performing bitwise NOT on unsigned integers (#4229) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Description ## Problem\* Resolves ## Summary\* Currently running `bit_not` results in the output ``` $ nargo info --show-ssa error: u8 cannot be used in a unary operation ┌─ /home/tom/Programming/aztec/noir/test_programs/execution_success/bit_not/src/main.nr:3:30 │ 3 │ let not_four_as_u8: u8 = !four_as_u8; │ ----------- │ error: u32 cannot be used in a unary operation ┌─ /home/tom/Programming/aztec/noir/test_programs/execution_success/bit_not/src/main.nr:6:32 │ 6 │ let not_four_as_u32: u32 = !four_as_u32; │ ------------ │ ``` We're unable to perform bitwise nots for unsigned integers (signed is fine). This PR loosens the check being applied in `lint_overflowing_uint` so that it only errors for using an unary `-`. ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- compiler/noirc_frontend/src/hir/type_check/stmt.rs | 13 ++++++++++--- test_programs/execution_success/bit_not/Nargo.toml | 7 +++++++ test_programs/execution_success/bit_not/Prover.toml | 1 + test_programs/execution_success/bit_not/src/main.nr | 8 ++++++++ 4 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 test_programs/execution_success/bit_not/Nargo.toml create mode 100644 test_programs/execution_success/bit_not/Prover.toml create mode 100644 test_programs/execution_success/bit_not/src/main.nr diff --git a/compiler/noirc_frontend/src/hir/type_check/stmt.rs b/compiler/noirc_frontend/src/hir/type_check/stmt.rs index a38a16a6580..76bd064bf83 100644 --- a/compiler/noirc_frontend/src/hir/type_check/stmt.rs +++ b/compiler/noirc_frontend/src/hir/type_check/stmt.rs @@ -8,6 +8,7 @@ use crate::hir_def::stmt::{ }; use crate::hir_def::types::Type; use crate::node_interner::{DefinitionId, ExprId, StmtId}; +use crate::UnaryOp; use super::errors::{Source, TypeCheckError}; use super::TypeChecker; @@ -361,9 +362,15 @@ impl<'interner> TypeChecker<'interner> { }; }; } - HirExpression::Prefix(_) => self - .errors - .push(TypeCheckError::InvalidUnaryOp { kind: annotated_type.to_string(), span }), + HirExpression::Prefix(expr) => { + self.lint_overflowing_uint(&expr.rhs, annotated_type); + if matches!(expr.operator, UnaryOp::Minus) { + self.errors.push(TypeCheckError::InvalidUnaryOp { + kind: "annotated_type".to_string(), + span, + }); + } + } HirExpression::Infix(expr) => { self.lint_overflowing_uint(&expr.lhs, annotated_type); self.lint_overflowing_uint(&expr.rhs, annotated_type); diff --git a/test_programs/execution_success/bit_not/Nargo.toml b/test_programs/execution_success/bit_not/Nargo.toml new file mode 100644 index 00000000000..e89a338595b --- /dev/null +++ b/test_programs/execution_success/bit_not/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "bit_not" +type = "bin" +authors = [""] +compiler_version = ">=0.23.0" + +[dependencies] diff --git a/test_programs/execution_success/bit_not/Prover.toml b/test_programs/execution_success/bit_not/Prover.toml new file mode 100644 index 00000000000..b4bcbcec177 --- /dev/null +++ b/test_programs/execution_success/bit_not/Prover.toml @@ -0,0 +1 @@ +four_as_u32 = 4 diff --git a/test_programs/execution_success/bit_not/src/main.nr b/test_programs/execution_success/bit_not/src/main.nr new file mode 100644 index 00000000000..30b78d330ce --- /dev/null +++ b/test_programs/execution_success/bit_not/src/main.nr @@ -0,0 +1,8 @@ +fn main(four_as_u32: u32) { + let four_as_u8: u8 = 4; + let not_four_as_u8: u8 = !four_as_u8; + assert_eq(not_four_as_u8, 251); + + let not_four_as_u32: u32 = !four_as_u32; + assert_eq(not_four_as_u32, 4294967291); +}