From 6823523ed817878278d52d2c109f8ea1278b2dac Mon Sep 17 00:00:00 2001 From: James Zaki Date: Tue, 2 Apr 2024 16:40:08 +0100 Subject: [PATCH 01/17] Initial Noir ts commit --- .gitignore | 3 + README.md | 1 + circuits/recurse/Nargo.toml | 8 + circuits/recurse/export/main.json | 1 + circuits/recurse/export/main_call.json | 1 + circuits/recurse/src/lib.nr | 21 ++ circuits/simple/Nargo.toml | 7 + circuits/simple/export/not_equal.json | 1 + circuits/simple/export/not_odd.json | 1 + circuits/simple/src/lib.nr | 22 ++ main.ts | 11 + package.json | 21 ++ tsconfig.json | 109 ++++++ yarn.lock | 497 +++++++++++++++++++++++++ 14 files changed, 704 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 circuits/recurse/Nargo.toml create mode 100644 circuits/recurse/export/main.json create mode 100644 circuits/recurse/export/main_call.json create mode 100644 circuits/recurse/src/lib.nr create mode 100644 circuits/simple/Nargo.toml create mode 100644 circuits/simple/export/not_equal.json create mode 100644 circuits/simple/export/not_odd.json create mode 100644 circuits/simple/src/lib.nr create mode 100644 main.ts create mode 100644 package.json create mode 100644 tsconfig.json create mode 100644 yarn.lock diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..49c30e9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +node_modules +build +codegen \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..685528f --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# Noir recursion diff --git a/circuits/recurse/Nargo.toml b/circuits/recurse/Nargo.toml new file mode 100644 index 0000000..ab6e185 --- /dev/null +++ b/circuits/recurse/Nargo.toml @@ -0,0 +1,8 @@ +[package] +name = "recurse" +type = "lib" +authors = [""] +compiler_version = ">=0.26.0" + +[dependencies] +simple = { path = "../simple" } \ No newline at end of file diff --git a/circuits/recurse/export/main.json b/circuits/recurse/export/main.json new file mode 100644 index 0000000..c285ba2 --- /dev/null +++ b/circuits/recurse/export/main.json @@ -0,0 +1 @@ +{"noir_version":"0.26.0+c46b164ce56e6a8f81255fb17eb6539bd040f336","hash":12993080274337799997,"abi":{"parameters":[{"name":"x","type":{"kind":"field"},"visibility":"private"},{"name":"y","type":{"kind":"field"},"visibility":"private"}],"param_witnesses":{"x":[{"start":0,"end":1}],"y":[{"start":1,"end":2}]},"return_type":{"abi_type":{"kind":"boolean"},"visibility":"public"},"return_witnesses":[25]},"bytecode":"H4sIAAAAAAAA/+1X207jMBCdNN3QUGDJsrD0A/Z9nHve+JWmJP//tI8LNThoGowqkTNVK9VS5CiX4zM3e05A72O1vf66+3B7zejzCNz85GaeNgwQiz10MdiGWfpiJnwUufvI8176TP7zMno3zIH4/0X84/sm+AJn6eGReJ4FNBpPbuZpwwzG2uufMN4avhitGYLXllgZl3neVWlnMrPmtGnrgvOiLWtTm6IuntM6y7o6r6umbSpuTJ51pi+arOvtYDMDYPWOWEg6ST4D+w9p83wHa/vtOs3LruCyq5u6a6q+qHiz7vvnivNNy22bl5yZrG+rlNu02S7bdMXGvPEKyZOwhN+M5jgslnx/uMuOyMN/GKHnfiG++0/YWpFrjbkkHp5qm4YER2HOndPRuBHhikTL7ggfIy9XxMYYKeBeELaQ7cZoMWM6XGekdWiA8yKVvhgO+Ji+1xnFo3fDLDujmPZ3Rj6co+mMrJMuhPExfX0SoNaWyTStM+r7BeEKNcbZyIcqzIBOoDBHkuXSzbYIzpJl5KrBWOskKVksMW3JIpNpqmS5JFxhLkknydGSBWnzFZ2eZLnCYe1Ilms6S5a9ZDSCea2Ae0PHLVms3Tf4GKlIlqXjisb9SdhCthutxTykZNE6NMB5sSNZbt1sN4+zZNkdH52RdZKULAnpSxaZTFMlyy3hCjUhnSQfd0ZIaTUV6xcwrpo2J0CsOyWbQ7DNyJoLgLx+43jxobppJGfJ957O3fReMhrBvFfAfaDj7qat3Q/4GKlwtQfLHeG76T90Goc0Mpce6bjr0cbkUSHWK3CsZccfeO5X4hm9Ao/vA4c8IwAA","debug_symbols":"tdfRCoJAEAXQf5lnH9wZ3V39lehhKwNBLNKCEP89F7WC1kDkvjns3AMiF9yOqsvRteWlbijvKKZ811FzdbWfmtbdWsqVshEV9Wl4Et1HdC6rgvLE9NHvKifvVfVZtf0+IgW0GWgL0E6Adgq0NdA2QNsC7QzZne3FlNDqiCskzkhckHi4nEk2J7TZ8EFTJK6RuEHiFolnQJxjJK6QOCNxQeLbG7pcf06RuEbiBokvNJTDuE9kaxMS7pKNpwTH8v8FtJo2v+nxZ07haMbRgqPDHTISpn0iXZcYhoe7le5QFf6O4c/u9XG+cgxj+7yOJ/0L","file_map":{"47":{"source":"use dep::std;\nuse dep::simple;\n\n// #[recursive]\n#[export]\nfn main(x: Field, y: Field) -> pub bool {\n let mut res = simple::not_odd(x);\n res &= simple::not_odd(y);\n res &= simple::not_equal(x, y);\n res\n}\n\n#[test]\nfn test_not_equal() {\n assert(main(2, 4));\n // Uncomment to make test fail\n // assert(not_equal(1, 1));\n}\n","path":"/home/jz/Documents/code/aztec/recurseNoirTS/circuits/recurse/src/lib.nr"},"48":{"source":"#[export]\npub fn not_equal(x: Field, y: Field) -> bool {\n x != y\n}\n\n#[export]\npub fn not_odd(x: Field) -> bool {\n !(((x as u8) & 1) as bool)\n}\n\n#[test]\nfn test_not_equal() {\n assert(not_equal(1, 2));\n // Uncomment to make test fail\n // assert(not_equal(1, 1));\n}\n\nfn test_not_odd() {\n assert(not_odd(2));\n // Uncomment to make test fail\n // assert(not_equal(1, 1));\n}\n","path":"/home/jz/Documents/code/aztec/recurseNoirTS/circuits/simple/src/lib.nr"}}} \ No newline at end of file diff --git a/circuits/recurse/export/main_call.json b/circuits/recurse/export/main_call.json new file mode 100644 index 0000000..ba2fcbb --- /dev/null +++ b/circuits/recurse/export/main_call.json @@ -0,0 +1 @@ +{"noir_version":"0.26.0+c46b164ce56e6a8f81255fb17eb6539bd040f336","hash":11451067821145455187,"abi":{"parameters":[{"name":"x","type":{"kind":"field"},"visibility":"private"},{"name":"y","type":{"kind":"field"},"visibility":"private"}],"param_witnesses":{"x":[{"start":0,"end":1}],"y":[{"start":1,"end":2}]},"return_type":{"abi_type":{"kind":"boolean"},"visibility":"private"},"return_witnesses":[25]},"bytecode":"H4sIAAAAAAAA/+1X207jMBCdNN3QUGDJsrD0A/Z9nHve+JWmJP//tI8LNThoGowqkTNVK9VS5CiX4zM3e05A72O1vf66+3B7zejzCNz85GaeNgwQiz10MdiGWfpiJnwUufvI8176TP7zMno3zIH4/0X84/sm+AJn6eGReJ4FNBpPbuZpwwzG2uufMN4avhitGYLXllgZl3neVWlnMrPmtGnrgvOiLWtTm6IuntM6y7o6r6umbSpuTJ51pi+arOvtYDMDYPWOWEg6ST4D+w9p83wHa/vtOs3LruCyq5u6a6q+qHiz7vvnivNNy22bl5yZrG+rlNu02S7bdMXGvPEKyZOwhN+M5jgslnx/uMuOyMN/GKHnfiG++0/YWpFrjbkkHp5qm4YER2HOndPRuBHhikTL7ggfIy9XxMYYKeBeELaQ7cZoMWM6XGekdWiA8yKVvhgO+Ji+1xnFo3fDLDujmPZ3Rj6co+mMrJMuhPExfX0SoNaWyTStM+r7BeEKNcbZyIcqzIBOoDBHkuXSzbYIzpJl5KrBWOskKVksMW3JIpNpqmS5JFxhLkknydGSBWnzFZ2eZLnCYe1Ilms6S5a9ZDSCea2Ae0PHLVms3Tf4GKlIlqXjisb9SdhCthutxTykZNE6NMB5sSNZbt1sN4+zZNkdH52RdZKULAnpSxaZTFMlyy3hCjUhnSQfd0ZIaTUV6xcwrpo2J0CsOyWbQ7DNyJoLgLx+43jxobppJGfJ957O3fReMhrBvFfAfaDj7qat3Q/4GKlwtQfLHeG76T90Goc0Mpce6bjr0cbkUSHWK3CsZccfeO5X4hm9Ao/vA4c8IwAA","debug_symbols":"tdffCoIwFAbwdznXXrhz3B99lehilYEgFmlBiO+eo4ywFYh8dzvsnB+M8cHWU33a+646NS0VPaVUbHpqz74JVdv5S0eFSiWhsjmMK1ZDQseqLqnI7JB8t3I2tcpHqxu2CSmgzUBbgHYGtDXQNkDbAm0HtHNkdtYH890qZo4rJM5IXJB4PJzyviXNKy5UI3GDxC0Sd0g8B+KcInGFxBmJCxJfn9Df8WeNxA0St0g8nlC2cTxM5EsnJJ4lo6cJ5/4fwKhXp7Hzx5zC0YyjBUfHM6RdnA4TetnEWNz8pfK7ugx/jLB3bfbTl2Msu/v5uTM8AA==","file_map":{"47":{"source":"use dep::std;\nuse dep::simple;\n\n#[export]\nfn main_call(x: Field, y: Field) -> bool {\n let mut res = simple::not_odd(x);\n res &= simple::not_odd(y);\n res &= simple::not_equal(x, y);\n res\n}\n\n// #[recursive]\n// #[export]\n// fn main(x: Field, y: Field) -> pub bool {}\n\n#[test]\nfn test_not_equal() {\n assert(main_call(2, 4));\n // Uncomment to make test fail\n // assert(not_equal(1, 1));\n}\n","path":"/home/jz/Documents/code/aztec/recurseNoirTS/circuits/recurse/src/lib.nr"},"48":{"source":"#[export]\npub fn not_equal(x: Field, y: Field) -> bool {\n x != y\n}\n\n#[export]\npub fn not_odd(x: Field) -> bool {\n !(((x as u8) & 1) as bool)\n}\n\n#[test]\nfn test_not_equal() {\n assert(not_equal(1, 2));\n // Uncomment to make test fail\n // assert(not_equal(1, 1));\n}\n\nfn test_not_odd() {\n assert(not_odd(2));\n // Uncomment to make test fail\n // assert(not_equal(1, 1));\n}\n","path":"/home/jz/Documents/code/aztec/recurseNoirTS/circuits/simple/src/lib.nr"}}} \ No newline at end of file diff --git a/circuits/recurse/src/lib.nr b/circuits/recurse/src/lib.nr new file mode 100644 index 0000000..f2ce0f8 --- /dev/null +++ b/circuits/recurse/src/lib.nr @@ -0,0 +1,21 @@ +use dep::std; +use dep::simple; + +#[export] +fn main_call(x: Field, y: Field) -> bool { + let mut res = simple::not_odd(x); + res &= simple::not_odd(y); + res &= simple::not_equal(x, y); + res +} + +// #[recursive] +// #[export] +// fn main(x: Field, y: Field) -> pub bool {} + +#[test] +fn test_not_equal() { + assert(main_call(2, 4)); + // Uncomment to make test fail + // assert(not_equal(1, 1)); +} diff --git a/circuits/simple/Nargo.toml b/circuits/simple/Nargo.toml new file mode 100644 index 0000000..e0f7635 --- /dev/null +++ b/circuits/simple/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "simple" +type = "lib" +authors = [""] +compiler_version = ">=0.26.0" + +[dependencies] \ No newline at end of file diff --git a/circuits/simple/export/not_equal.json b/circuits/simple/export/not_equal.json new file mode 100644 index 0000000..541f9e6 --- /dev/null +++ b/circuits/simple/export/not_equal.json @@ -0,0 +1 @@ +{"noir_version":"0.26.0+c46b164ce56e6a8f81255fb17eb6539bd040f336","hash":17779628616883538135,"abi":{"parameters":[{"name":"x","type":{"kind":"field"},"visibility":"private"},{"name":"y","type":{"kind":"field"},"visibility":"private"}],"param_witnesses":{"x":[{"start":0,"end":1}],"y":[{"start":1,"end":2}]},"return_type":{"abi_type":{"kind":"boolean"},"visibility":"private"},"return_witnesses":[5]},"bytecode":"H4sIAAAAAAAA/7VUSQ7DIAwMJKl67U9slmBu+UpRyf9fUFVVqEQdbpiRkH2wzHjGoKYTazkcc4l7iRY253IwGS0+wcREHpxPGyGhJ/8yZG0mRyGmGCCisxkPH+0BJ+pe0AdUgry0HC/4aqYaWiqmJfQBJTkr5vlvF24N/nUdz+9V3VtwVn4v5/Jo8Lx4sAuSGWHmPKDvMsk+3hFzL/IeQdVy0qx3rw6Smq7Ce6mruVUj//vkPwR1AkL+BQAA","debug_symbols":"lY9NCoAgGETvMmsX/VHgVaLFlxkIoqIWhHj3lOgA7uYxb/MStBUUlTUBPKEDXxOCI1MpRPIRfO4ZpDnKWDLDqbQEn5a8MfRt+tCmjy16gZu8ol3LWlK/y4g/rGB83PfkFw==","file_map":{"47":{"source":"#[export]\npub fn not_equal(x: Field, y: Field) -> bool {\n x != y\n}\n\n#[export]\npub fn not_odd(x: Field) -> bool {\n !(((x as u8) & 1) as bool)\n}\n\n#[test]\nfn test_not_equal() {\n assert(not_equal(1, 2));\n // Uncomment to make test fail\n // assert(not_equal(1, 1));\n}\n\nfn test_not_odd() {\n assert(not_odd(2));\n // Uncomment to make test fail\n // assert(not_equal(1, 1));\n}\n","path":"/home/jz/Documents/code/aztec/recurseNoirTS/circuits/simple/src/lib.nr"}}} \ No newline at end of file diff --git a/circuits/simple/export/not_odd.json b/circuits/simple/export/not_odd.json new file mode 100644 index 0000000..8c93ab7 --- /dev/null +++ b/circuits/simple/export/not_odd.json @@ -0,0 +1 @@ +{"noir_version":"0.26.0+c46b164ce56e6a8f81255fb17eb6539bd040f336","hash":15860874175066265550,"abi":{"parameters":[{"name":"x","type":{"kind":"field"},"visibility":"private"}],"param_witnesses":{"x":[{"start":0,"end":1}]},"return_type":{"abi_type":{"kind":"boolean"},"visibility":"private"},"return_witnesses":[9]},"bytecode":"H4sIAAAAAAAA/81WzW7DIAx2wpIm2mHqm5i/ALe+Smnh/U87rktWIrGMatJiplpCpoR+/mxscAN3GefxluZsHi38lCbpU9K4TzghFhbo0mBzxLYQg2WtT/M++94WYtZmcb0VsJoN7i37T2lP8wDntcDjWFhrYCOnpHGf8NXZRb9nzi9j2NhkxLZzLImTUsGIwCU/o3DealTaT5Zbrq2+CitlsMoa551Bx5UMPGonQ1zk7sderJiItVAnydsKZ0flM/uGNe89CzUFjVOwzgZnojZ4Ocd4NaguHr1XE0ouozcCvXCzWRf0hX/xYlBIWKC/jBgdFuZ8X+bRpXlf4L8KK8yHbN8H0NZKbmvL5VjgWe3SyMGpMFkKPDVuB3RFUsvvjv6MilwpLsauAm4PtIW8vvRLh/RfnVGtR4M4L0Qei0PSA/ytMxo331add0Yj/N4ZlXCepjM6pLH+HuDxS0BlO0+mfZ1RjAegK9QB6iT5tjOi5LkXayQ812LCZmt5IcAnVgpzjegNAAA=","debug_symbols":"ldLNCsIwEATgd9lzDubHVvMq4mGtEQIhLU0UJOTdTRA9FHqY2w7Ld5opFOaJs59jIlvoQPZSKC0ce0qZ10xWKiPIxXu7tKyCHj44smasV0ESBQoFGgUGBUcUDCgYUXBCwRkubqdq/RfDVkhYKFhoTLTw4tXzLbi+3/57xuk35xbze/l+6gc=","file_map":{"47":{"source":"#[export]\npub fn not_equal(x: Field, y: Field) -> bool {\n x != y\n}\n\n#[export]\npub fn not_odd(x: Field) -> bool {\n !(((x as u8) & 1) as bool)\n}\n\n#[test]\nfn test_not_equal() {\n assert(not_equal(1, 2));\n // Uncomment to make test fail\n // assert(not_equal(1, 1));\n}\n\nfn test_not_odd() {\n assert(not_odd(2));\n // Uncomment to make test fail\n // assert(not_equal(1, 1));\n}\n","path":"/home/jz/Documents/code/aztec/recurseNoirTS/circuits/simple/src/lib.nr"}}} \ No newline at end of file diff --git a/circuits/simple/src/lib.nr b/circuits/simple/src/lib.nr new file mode 100644 index 0000000..9027a2f --- /dev/null +++ b/circuits/simple/src/lib.nr @@ -0,0 +1,22 @@ +#[export] +pub fn not_equal(x: Field, y: Field) -> bool { + x != y +} + +#[export] +pub fn not_odd(x: Field) -> bool { + !(((x as u8) & 1) as bool) +} + +#[test] +fn test_not_equal() { + assert(not_equal(1, 2)); + // Uncomment to make test fail + // assert(not_equal(1, 1)); +} + +fn test_not_odd() { + assert(not_odd(2)); + // Uncomment to make test fail + // assert(not_equal(1, 1)); +} diff --git a/main.ts b/main.ts new file mode 100644 index 0000000..581cfd7 --- /dev/null +++ b/main.ts @@ -0,0 +1,11 @@ +import { CompiledCircuit } from '@noir-lang/types'; +import { not_equal, not_odd, main_call, main } from './codegen'; +import { setTimeout } from "timers/promises"; + + +async function start() { + let res = await main_call("02", "04"); + console.log(res); +} + +start(); diff --git a/package.json b/package.json new file mode 100644 index 0000000..3a2e03a --- /dev/null +++ b/package.json @@ -0,0 +1,21 @@ +{ + "license": "UNLICENSED", + "scripts": { + "clean": "rm -rf build", + "compile": "yarn clean && tsc", + "start": "node build/main.js", + "clean:codegen": "rm -rf codegen", + "export:simple": "nargo export --program-dir=./circuits/simple", + "export:recurse": "nargo export --program-dir=./circuits/recurse", + "export:all": "yarn clean:codegen && yarn export:simple && yarn export:recurse", + "codegen": "yarn noir-codegen ./circuits/**/export/*.json", + "compile:all": "yarn export:all && yarn codegen && yarn compile" + }, + "devDependencies": { + "@noir-lang/backend_barretenberg": "^0.26.0", + "@noir-lang/noir_codegen": "^0.26.0", + "@noir-lang/noir_js": "^0.26.0", + "@types/node": "^20.12.2", + "typescript": "^5.4.3" + } +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..31428b3 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,109 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig to read more about this file */ + + /* Projects */ + // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ + // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ + // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ + // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ + // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ + // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ + + /* Language and Environment */ + "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + "lib": ["ES6"], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + // "jsx": "preserve", /* Specify what JSX code is generated. */ + // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ + // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ + // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ + // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ + // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ + // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ + // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ + // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ + // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ + + /* Modules */ + "module": "commonjs", /* Specify what module code is generated. */ + // "rootDir": "./", /* Specify the root folder within your source files. */ + // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ + // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ + // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ + // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ + // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ + // "types": [], /* Specify type package names to be included without being referenced in a source file. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ + // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ + // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ + // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ + // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ + "resolveJsonModule": true, /* Enable importing .json files. */ + // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ + // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ + + /* JavaScript Support */ + "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ + // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ + // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ + + /* Emit */ + // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + // "declarationMap": true, /* Create sourcemaps for d.ts files. */ + // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ + // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ + // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ + // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ + "outDir": "./build", /* Specify an output folder for all emitted files. */ + // "removeComments": true, /* Disable emitting comments. */ + // "noEmit": true, /* Disable emitting files from a compilation. */ + // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ + // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ + // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ + // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ + // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ + // "newLine": "crlf", /* Set the newline character for emitting files. */ + // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ + // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ + // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ + // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ + // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ + // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ + + /* Interop Constraints */ + // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ + // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ + // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ + "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ + // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ + "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ + + /* Type Checking */ + "strict": true, /* Enable all strict type-checking options. */ + "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ + // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ + // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ + // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ + // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ + // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ + // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ + // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ + // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ + // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ + // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ + // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ + // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ + // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ + // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ + // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ + // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ + + /* Completeness */ + // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */ + } +} diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..e2b25d4 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,497 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@aztec/bb.js@0.30.1": + version "0.30.1" + resolved "https://registry.yarnpkg.com/@aztec/bb.js/-/bb.js-0.30.1.tgz#32d7667ffab730aefa8ba5ec514d5c068d535ab5" + integrity sha512-HmBjU87LECD3RagU22IH/qDEbzKMK24seCS+W5KYAQj6MXDDKWUrin969K9tdop72uwE/TkKR4pBd8rY9JpNqg== + dependencies: + comlink "^4.4.1" + commander "^10.0.1" + debug "^4.3.4" + tslib "^2.4.0" + +"@isaacs/cliui@^8.0.2": + version "8.0.2" + resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" + integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== + dependencies: + string-width "^5.1.2" + string-width-cjs "npm:string-width@^4.2.0" + strip-ansi "^7.0.1" + strip-ansi-cjs "npm:strip-ansi@^6.0.1" + wrap-ansi "^8.1.0" + wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" + +"@noir-lang/acvm_js@0.42.0": + version "0.42.0" + resolved "https://registry.yarnpkg.com/@noir-lang/acvm_js/-/acvm_js-0.42.0.tgz#a14be995daac989f47987e1d268e79fa3f07cfe0" + integrity sha512-yyTTzPo5fKzsxPL+midEnd52GZXiZLAmBqy7xsILRivdEaaHKXOYGSQWh2slWEfBvv/PcBk89XINydGTqSpeWA== + +"@noir-lang/backend_barretenberg@^0.26.0": + version "0.26.0" + resolved "https://registry.yarnpkg.com/@noir-lang/backend_barretenberg/-/backend_barretenberg-0.26.0.tgz#030d854ad622ccccc933012d9f335ef4cacfe194" + integrity sha512-64iRlAL+p9fx1BIk+1ZlNBGFS/y99AumdSbXIVAJzBO30wJ2eoR4hy5YLjLBw+ncFUHXpek7/JZ5aZbzXv4KAg== + dependencies: + "@aztec/bb.js" "0.30.1" + "@noir-lang/types" "0.26.0" + fflate "^0.8.0" + +"@noir-lang/noir_codegen@^0.26.0": + version "0.26.0" + resolved "https://registry.yarnpkg.com/@noir-lang/noir_codegen/-/noir_codegen-0.26.0.tgz#13e43189327fbed1899b0d7aaee036ab0d2ef8b2" + integrity sha512-8NIpVQYgXRqz5Fl4u7+V2SQpi2WiGgRbXGY2M4CJpf3XIRlktOh9wDqon5AstBwowzYY/zA0SDnofTy4XVLxKQ== + dependencies: + "@noir-lang/types" "0.26.0" + glob "^10.3.10" + ts-command-line-args "^2.5.1" + +"@noir-lang/noir_js@^0.26.0": + version "0.26.0" + resolved "https://registry.yarnpkg.com/@noir-lang/noir_js/-/noir_js-0.26.0.tgz#94da60d6b284b34c1663c0d73999765a63de252f" + integrity sha512-6G/Hg6UXxCeQIyBMLeBn/UFgVQDFY00nn4hUlKFeVZ4YkHoimEq+Fx1wXSlDXoJmCts0RaGvDKPDbqY4iT1MrA== + dependencies: + "@noir-lang/acvm_js" "0.42.0" + "@noir-lang/noirc_abi" "0.26.0" + "@noir-lang/types" "0.26.0" + +"@noir-lang/noirc_abi@0.26.0": + version "0.26.0" + resolved "https://registry.yarnpkg.com/@noir-lang/noirc_abi/-/noirc_abi-0.26.0.tgz#5052ab7a55228cc04d77cebf8753ea42636963ff" + integrity sha512-VRbySH2TNNAXH1JvPgPm/UKuL7ijooa4UaSuqBauytvzwGsYMPv2oKErp6fSSFm22eVPIGE992IOrRbTdYgMQQ== + dependencies: + "@noir-lang/types" "0.26.0" + +"@noir-lang/types@0.26.0": + version "0.26.0" + resolved "https://registry.yarnpkg.com/@noir-lang/types/-/types-0.26.0.tgz#81a1b7bb683d2f96be49f728c801594d3972a30b" + integrity sha512-xD2mJXbqFAxz0NTdILqTbiR3UhkPF8oO35QkUY6MzkUwz+NnLgJaAqaDWPLeWx8mrqhJQdo3fCdQ6XBsaubklA== + +"@pkgjs/parseargs@^0.11.0": + version "0.11.0" + resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" + integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== + +"@types/node@^20.12.2": + version "20.12.2" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.12.2.tgz#9facdd11102f38b21b4ebedd9d7999663343d72e" + integrity sha512-zQ0NYO87hyN6Xrclcqp7f8ZbXNbRfoGWNcMvHTPQp9UUrwI0mI7XBz+cu7/W6/VClYo2g63B0cjull/srU7LgQ== + dependencies: + undici-types "~5.26.4" + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-regex@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" + integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +ansi-styles@^6.1.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" + integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== + +array-back@^3.0.1, array-back@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/array-back/-/array-back-3.1.0.tgz#b8859d7a508871c9a7b2cf42f99428f65e96bfb0" + integrity sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q== + +array-back@^4.0.1, array-back@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/array-back/-/array-back-4.0.2.tgz#8004e999a6274586beeb27342168652fdb89fa1e" + integrity sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg== + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + +chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^4.1.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +comlink@^4.4.1: + version "4.4.1" + resolved "https://registry.yarnpkg.com/comlink/-/comlink-4.4.1.tgz#e568b8e86410b809e8600eb2cf40c189371ef981" + integrity sha512-+1dlx0aY5Jo1vHy/tSsIGpSkN4tS9rZSW8FIhG0JH/crs9wwweswIo/POr451r7bZww3hFbPAKnTpimzL/mm4Q== + +command-line-args@^5.1.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/command-line-args/-/command-line-args-5.2.1.tgz#c44c32e437a57d7c51157696893c5909e9cec42e" + integrity sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg== + dependencies: + array-back "^3.1.0" + find-replace "^3.0.0" + lodash.camelcase "^4.3.0" + typical "^4.0.0" + +command-line-usage@^6.1.0: + version "6.1.3" + resolved "https://registry.yarnpkg.com/command-line-usage/-/command-line-usage-6.1.3.tgz#428fa5acde6a838779dfa30e44686f4b6761d957" + integrity sha512-sH5ZSPr+7UStsloltmDh7Ce5fb8XPlHyoPzTpyyMuYCtervL65+ubVZ6Q61cFtFl62UyJlc8/JwERRbAFPUqgw== + dependencies: + array-back "^4.0.2" + chalk "^2.4.2" + table-layout "^1.0.2" + typical "^5.2.0" + +commander@^10.0.1: + version "10.0.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.1.tgz#881ee46b4f77d1c1dccc5823433aa39b022cbe06" + integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug== + +cross-spawn@^7.0.0: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +debug@^4.3.4: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +deep-extend@~0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + +eastasianwidth@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" + integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +emoji-regex@^9.2.2: + version "9.2.2" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" + integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== + +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== + +fflate@^0.8.0: + version "0.8.2" + resolved "https://registry.yarnpkg.com/fflate/-/fflate-0.8.2.tgz#fc8631f5347812ad6028bbe4a2308b2792aa1dea" + integrity sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A== + +find-replace@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-replace/-/find-replace-3.0.0.tgz#3e7e23d3b05167a76f770c9fbd5258b0def68c38" + integrity sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ== + dependencies: + array-back "^3.0.1" + +foreground-child@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.1.1.tgz#1d173e776d75d2772fed08efe4a0de1ea1b12d0d" + integrity sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg== + dependencies: + cross-spawn "^7.0.0" + signal-exit "^4.0.1" + +glob@^10.3.10: + version "10.3.12" + resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.12.tgz#3a65c363c2e9998d220338e88a5f6ac97302960b" + integrity sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg== + dependencies: + foreground-child "^3.1.0" + jackspeak "^2.3.6" + minimatch "^9.0.1" + minipass "^7.0.4" + path-scurry "^1.10.2" + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +jackspeak@^2.3.6: + version "2.3.6" + resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-2.3.6.tgz#647ecc472238aee4b06ac0e461acc21a8c505ca8" + integrity sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ== + dependencies: + "@isaacs/cliui" "^8.0.2" + optionalDependencies: + "@pkgjs/parseargs" "^0.11.0" + +lodash.camelcase@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" + integrity sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA== + +lru-cache@^10.2.0: + version "10.2.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.2.0.tgz#0bd445ca57363465900f4d1f9bd8db343a4d95c3" + integrity sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q== + +minimatch@^9.0.1: + version "9.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.4.tgz#8e49c731d1749cbec05050ee5145147b32496a51" + integrity sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw== + dependencies: + brace-expansion "^2.0.1" + +"minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.0.4: + version "7.0.4" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.0.4.tgz#dbce03740f50a4786ba994c1fb908844d27b038c" + integrity sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ== + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-scurry@^1.10.2: + version "1.10.2" + resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.10.2.tgz#8f6357eb1239d5fa1da8b9f70e9c080675458ba7" + integrity sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA== + dependencies: + lru-cache "^10.2.0" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + +reduce-flatten@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/reduce-flatten/-/reduce-flatten-2.0.0.tgz#734fd84e65f375d7ca4465c69798c25c9d10ae27" + integrity sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w== + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +signal-exit@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" + integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== + +string-format@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/string-format/-/string-format-2.0.0.tgz#f2df2e7097440d3b65de31b6d40d54c96eaffb9b" + integrity sha512-bbEs3scLeYNXLecRRuk6uJxdXUSj6le/8rNPHChIJTn2V79aXVTR1EH2OH5zLKKoz0V02fOUKZZcw01pLUShZA== + +"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0: + name string-width-cjs + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string-width@^5.0.1, string-width@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" + integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== + dependencies: + eastasianwidth "^0.2.0" + emoji-regex "^9.2.2" + strip-ansi "^7.0.1" + +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: + name strip-ansi-cjs + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@^7.0.1: + version "7.1.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" + integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== + dependencies: + ansi-regex "^6.0.1" + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +table-layout@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/table-layout/-/table-layout-1.0.2.tgz#c4038a1853b0136d63365a734b6931cf4fad4a04" + integrity sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A== + dependencies: + array-back "^4.0.1" + deep-extend "~0.6.0" + typical "^5.2.0" + wordwrapjs "^4.0.0" + +ts-command-line-args@^2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/ts-command-line-args/-/ts-command-line-args-2.5.1.tgz#e64456b580d1d4f6d948824c274cf6fa5f45f7f0" + integrity sha512-H69ZwTw3rFHb5WYpQya40YAX2/w7Ut75uUECbgBIsLmM+BNuYnxsltfyyLMxy6sEeKxgijLTnQtLd0nKd6+IYw== + dependencies: + chalk "^4.1.0" + command-line-args "^5.1.1" + command-line-usage "^6.1.0" + string-format "^2.0.0" + +tslib@^2.4.0: + version "2.6.2" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" + integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== + +typescript@^5.4.3: + version "5.4.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.4.3.tgz#5c6fedd4c87bee01cd7a528a30145521f8e0feff" + integrity sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg== + +typical@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/typical/-/typical-4.0.0.tgz#cbeaff3b9d7ae1e2bbfaf5a4e6f11eccfde94fc4" + integrity sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw== + +typical@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/typical/-/typical-5.2.0.tgz#4daaac4f2b5315460804f0acf6cb69c52bb93066" + integrity sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg== + +undici-types@~5.26.4: + version "5.26.5" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" + integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +wordwrapjs@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/wordwrapjs/-/wordwrapjs-4.0.1.tgz#d9790bccfb110a0fc7836b5ebce0937b37a8b98f" + integrity sha512-kKlNACbvHrkpIw6oPeYDSmdCTu2hdMHoyXLTcUKala++lx5Y+wjJ/e474Jqv5abnVmwxw08DiTuHmw69lJGksA== + dependencies: + reduce-flatten "^2.0.0" + typical "^5.2.0" + +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrap-ansi@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" + integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== + dependencies: + ansi-styles "^6.1.0" + string-width "^5.0.1" + strip-ansi "^7.0.1" From 6ede541281290dcff86ca37d48bdfa1cd17ef69e Mon Sep 17 00:00:00 2001 From: James Zaki Date: Fri, 5 Apr 2024 11:52:47 +0100 Subject: [PATCH 02/17] Update recursive proof example WIP --- circuits/{simple => not_odd}/Nargo.toml | 2 +- circuits/not_odd/src/main.nr | 30 +++++++++++++++++++ circuits/recurse/Nargo.toml | 1 - circuits/recurse/export/main.json | 1 - circuits/recurse/export/main_call.json | 1 - circuits/recurse/src/lib.nr | 35 ++++++++++++----------- circuits/simple/export/not_equal.json | 1 - circuits/simple/export/not_odd.json | 1 - circuits/simple/src/lib.nr | 22 -------------- main.ts | 38 +++++++++++++++++++++++-- package.json | 3 +- yarn.lock | 13 +++++++++ 12 files changed, 100 insertions(+), 48 deletions(-) rename circuits/{simple => not_odd}/Nargo.toml (86%) create mode 100644 circuits/not_odd/src/main.nr delete mode 100644 circuits/recurse/export/main.json delete mode 100644 circuits/recurse/export/main_call.json delete mode 100644 circuits/simple/export/not_equal.json delete mode 100644 circuits/simple/export/not_odd.json delete mode 100644 circuits/simple/src/lib.nr diff --git a/circuits/simple/Nargo.toml b/circuits/not_odd/Nargo.toml similarity index 86% rename from circuits/simple/Nargo.toml rename to circuits/not_odd/Nargo.toml index e0f7635..738a67d 100644 --- a/circuits/simple/Nargo.toml +++ b/circuits/not_odd/Nargo.toml @@ -1,6 +1,6 @@ [package] name = "simple" -type = "lib" +type = "bin" authors = [""] compiler_version = ">=0.26.0" diff --git a/circuits/not_odd/src/main.nr b/circuits/not_odd/src/main.nr new file mode 100644 index 0000000..5324842 --- /dev/null +++ b/circuits/not_odd/src/main.nr @@ -0,0 +1,30 @@ +#[recursive] +fn main(n: Field) -> pub u8 { + // not_odd(n); + n as u8 +} + +// fn main(x: Field, y: Field) -> pub bool { +// not_odd(x) & not_odd(y) & not_equal(x, y); +// } + +fn not_equal(x: Field, y: Field) -> bool { + x != y +} + +fn not_odd(n: Field) -> bool { + (n as u8) & 1 == 0 +} + +#[test] +fn test_not_equal() { + assert(not_equal(1, 2)); + // Uncomment to make test fail + // assert(not_equal(1, 1)); +} + +fn test_not_odd() { + assert(not_odd(2)); + // Uncomment to make test fail + // assert(not_odd(1)); +} diff --git a/circuits/recurse/Nargo.toml b/circuits/recurse/Nargo.toml index ab6e185..f2185a5 100644 --- a/circuits/recurse/Nargo.toml +++ b/circuits/recurse/Nargo.toml @@ -5,4 +5,3 @@ authors = [""] compiler_version = ">=0.26.0" [dependencies] -simple = { path = "../simple" } \ No newline at end of file diff --git a/circuits/recurse/export/main.json b/circuits/recurse/export/main.json deleted file mode 100644 index c285ba2..0000000 --- a/circuits/recurse/export/main.json +++ /dev/null @@ -1 +0,0 @@ -{"noir_version":"0.26.0+c46b164ce56e6a8f81255fb17eb6539bd040f336","hash":12993080274337799997,"abi":{"parameters":[{"name":"x","type":{"kind":"field"},"visibility":"private"},{"name":"y","type":{"kind":"field"},"visibility":"private"}],"param_witnesses":{"x":[{"start":0,"end":1}],"y":[{"start":1,"end":2}]},"return_type":{"abi_type":{"kind":"boolean"},"visibility":"public"},"return_witnesses":[25]},"bytecode":"H4sIAAAAAAAA/+1X207jMBCdNN3QUGDJsrD0A/Z9nHve+JWmJP//tI8LNThoGowqkTNVK9VS5CiX4zM3e05A72O1vf66+3B7zejzCNz85GaeNgwQiz10MdiGWfpiJnwUufvI8176TP7zMno3zIH4/0X84/sm+AJn6eGReJ4FNBpPbuZpwwzG2uufMN4avhitGYLXllgZl3neVWlnMrPmtGnrgvOiLWtTm6IuntM6y7o6r6umbSpuTJ51pi+arOvtYDMDYPWOWEg6ST4D+w9p83wHa/vtOs3LruCyq5u6a6q+qHiz7vvnivNNy22bl5yZrG+rlNu02S7bdMXGvPEKyZOwhN+M5jgslnx/uMuOyMN/GKHnfiG++0/YWpFrjbkkHp5qm4YER2HOndPRuBHhikTL7ggfIy9XxMYYKeBeELaQ7cZoMWM6XGekdWiA8yKVvhgO+Ji+1xnFo3fDLDujmPZ3Rj6co+mMrJMuhPExfX0SoNaWyTStM+r7BeEKNcbZyIcqzIBOoDBHkuXSzbYIzpJl5KrBWOskKVksMW3JIpNpqmS5JFxhLkknydGSBWnzFZ2eZLnCYe1Ilms6S5a9ZDSCea2Ae0PHLVms3Tf4GKlIlqXjisb9SdhCthutxTykZNE6NMB5sSNZbt1sN4+zZNkdH52RdZKULAnpSxaZTFMlyy3hCjUhnSQfd0ZIaTUV6xcwrpo2J0CsOyWbQ7DNyJoLgLx+43jxobppJGfJ957O3fReMhrBvFfAfaDj7qat3Q/4GKlwtQfLHeG76T90Goc0Mpce6bjr0cbkUSHWK3CsZccfeO5X4hm9Ao/vA4c8IwAA","debug_symbols":"tdfRCoJAEAXQf5lnH9wZ3V39lehhKwNBLNKCEP89F7WC1kDkvjns3AMiF9yOqsvRteWlbijvKKZ811FzdbWfmtbdWsqVshEV9Wl4Et1HdC6rgvLE9NHvKifvVfVZtf0+IgW0GWgL0E6Adgq0NdA2QNsC7QzZne3FlNDqiCskzkhckHi4nEk2J7TZ8EFTJK6RuEHiFolnQJxjJK6QOCNxQeLbG7pcf06RuEbiBokvNJTDuE9kaxMS7pKNpwTH8v8FtJo2v+nxZ07haMbRgqPDHTISpn0iXZcYhoe7le5QFf6O4c/u9XG+cgxj+7yOJ/0L","file_map":{"47":{"source":"use dep::std;\nuse dep::simple;\n\n// #[recursive]\n#[export]\nfn main(x: Field, y: Field) -> pub bool {\n let mut res = simple::not_odd(x);\n res &= simple::not_odd(y);\n res &= simple::not_equal(x, y);\n res\n}\n\n#[test]\nfn test_not_equal() {\n assert(main(2, 4));\n // Uncomment to make test fail\n // assert(not_equal(1, 1));\n}\n","path":"/home/jz/Documents/code/aztec/recurseNoirTS/circuits/recurse/src/lib.nr"},"48":{"source":"#[export]\npub fn not_equal(x: Field, y: Field) -> bool {\n x != y\n}\n\n#[export]\npub fn not_odd(x: Field) -> bool {\n !(((x as u8) & 1) as bool)\n}\n\n#[test]\nfn test_not_equal() {\n assert(not_equal(1, 2));\n // Uncomment to make test fail\n // assert(not_equal(1, 1));\n}\n\nfn test_not_odd() {\n assert(not_odd(2));\n // Uncomment to make test fail\n // assert(not_equal(1, 1));\n}\n","path":"/home/jz/Documents/code/aztec/recurseNoirTS/circuits/simple/src/lib.nr"}}} \ No newline at end of file diff --git a/circuits/recurse/export/main_call.json b/circuits/recurse/export/main_call.json deleted file mode 100644 index ba2fcbb..0000000 --- a/circuits/recurse/export/main_call.json +++ /dev/null @@ -1 +0,0 @@ -{"noir_version":"0.26.0+c46b164ce56e6a8f81255fb17eb6539bd040f336","hash":11451067821145455187,"abi":{"parameters":[{"name":"x","type":{"kind":"field"},"visibility":"private"},{"name":"y","type":{"kind":"field"},"visibility":"private"}],"param_witnesses":{"x":[{"start":0,"end":1}],"y":[{"start":1,"end":2}]},"return_type":{"abi_type":{"kind":"boolean"},"visibility":"private"},"return_witnesses":[25]},"bytecode":"H4sIAAAAAAAA/+1X207jMBCdNN3QUGDJsrD0A/Z9nHve+JWmJP//tI8LNThoGowqkTNVK9VS5CiX4zM3e05A72O1vf66+3B7zejzCNz85GaeNgwQiz10MdiGWfpiJnwUufvI8176TP7zMno3zIH4/0X84/sm+AJn6eGReJ4FNBpPbuZpwwzG2uufMN4avhitGYLXllgZl3neVWlnMrPmtGnrgvOiLWtTm6IuntM6y7o6r6umbSpuTJ51pi+arOvtYDMDYPWOWEg6ST4D+w9p83wHa/vtOs3LruCyq5u6a6q+qHiz7vvnivNNy22bl5yZrG+rlNu02S7bdMXGvPEKyZOwhN+M5jgslnx/uMuOyMN/GKHnfiG++0/YWpFrjbkkHp5qm4YER2HOndPRuBHhikTL7ggfIy9XxMYYKeBeELaQ7cZoMWM6XGekdWiA8yKVvhgO+Ji+1xnFo3fDLDujmPZ3Rj6co+mMrJMuhPExfX0SoNaWyTStM+r7BeEKNcbZyIcqzIBOoDBHkuXSzbYIzpJl5KrBWOskKVksMW3JIpNpqmS5JFxhLkknydGSBWnzFZ2eZLnCYe1Ilms6S5a9ZDSCea2Ae0PHLVms3Tf4GKlIlqXjisb9SdhCthutxTykZNE6NMB5sSNZbt1sN4+zZNkdH52RdZKULAnpSxaZTFMlyy3hCjUhnSQfd0ZIaTUV6xcwrpo2J0CsOyWbQ7DNyJoLgLx+43jxobppJGfJ957O3fReMhrBvFfAfaDj7qat3Q/4GKlwtQfLHeG76T90Goc0Mpce6bjr0cbkUSHWK3CsZccfeO5X4hm9Ao/vA4c8IwAA","debug_symbols":"tdffCoIwFAbwdznXXrhz3B99lehilYEgFmlBiO+eo4ywFYh8dzvsnB+M8cHWU33a+646NS0VPaVUbHpqz74JVdv5S0eFSiWhsjmMK1ZDQseqLqnI7JB8t3I2tcpHqxu2CSmgzUBbgHYGtDXQNkDbAm0HtHNkdtYH890qZo4rJM5IXJB4PJzyviXNKy5UI3GDxC0Sd0g8B+KcInGFxBmJCxJfn9Df8WeNxA0St0g8nlC2cTxM5EsnJJ4lo6cJ5/4fwKhXp7Hzx5zC0YyjBUfHM6RdnA4TetnEWNz8pfK7ugx/jLB3bfbTl2Msu/v5uTM8AA==","file_map":{"47":{"source":"use dep::std;\nuse dep::simple;\n\n#[export]\nfn main_call(x: Field, y: Field) -> bool {\n let mut res = simple::not_odd(x);\n res &= simple::not_odd(y);\n res &= simple::not_equal(x, y);\n res\n}\n\n// #[recursive]\n// #[export]\n// fn main(x: Field, y: Field) -> pub bool {}\n\n#[test]\nfn test_not_equal() {\n assert(main_call(2, 4));\n // Uncomment to make test fail\n // assert(not_equal(1, 1));\n}\n","path":"/home/jz/Documents/code/aztec/recurseNoirTS/circuits/recurse/src/lib.nr"},"48":{"source":"#[export]\npub fn not_equal(x: Field, y: Field) -> bool {\n x != y\n}\n\n#[export]\npub fn not_odd(x: Field) -> bool {\n !(((x as u8) & 1) as bool)\n}\n\n#[test]\nfn test_not_equal() {\n assert(not_equal(1, 2));\n // Uncomment to make test fail\n // assert(not_equal(1, 1));\n}\n\nfn test_not_odd() {\n assert(not_odd(2));\n // Uncomment to make test fail\n // assert(not_equal(1, 1));\n}\n","path":"/home/jz/Documents/code/aztec/recurseNoirTS/circuits/simple/src/lib.nr"}}} \ No newline at end of file diff --git a/circuits/recurse/src/lib.nr b/circuits/recurse/src/lib.nr index f2ce0f8..da8e04d 100644 --- a/circuits/recurse/src/lib.nr +++ b/circuits/recurse/src/lib.nr @@ -1,21 +1,24 @@ use dep::std; -use dep::simple; +// use dep::simple; -#[export] -fn main_call(x: Field, y: Field) -> bool { - let mut res = simple::not_odd(x); - res &= simple::not_odd(y); - res &= simple::not_equal(x, y); - res -} - -// #[recursive] // #[export] -// fn main(x: Field, y: Field) -> pub bool {} +// fn main_call(x: Field, y: Field) -> bool { +// let mut res = simple::not_odd(x); +// res &= simple::not_odd(y); +// res &= simple::not_equal(x, y); +// res +// } -#[test] -fn test_not_equal() { - assert(main_call(2, 4)); - // Uncomment to make test fail - // assert(not_equal(1, 1)); +#[export] +fn main(x: Field, y: Field) -> pub bool { + // Hash public inputs together + //TODO: take proofs + x != y } + +// #[test] +// fn test_not_equal() { +// assert(main_call(2, 4)); +// // Uncomment to make test fail +// // assert(not_equal(1, 1)); +// } diff --git a/circuits/simple/export/not_equal.json b/circuits/simple/export/not_equal.json deleted file mode 100644 index 541f9e6..0000000 --- a/circuits/simple/export/not_equal.json +++ /dev/null @@ -1 +0,0 @@ -{"noir_version":"0.26.0+c46b164ce56e6a8f81255fb17eb6539bd040f336","hash":17779628616883538135,"abi":{"parameters":[{"name":"x","type":{"kind":"field"},"visibility":"private"},{"name":"y","type":{"kind":"field"},"visibility":"private"}],"param_witnesses":{"x":[{"start":0,"end":1}],"y":[{"start":1,"end":2}]},"return_type":{"abi_type":{"kind":"boolean"},"visibility":"private"},"return_witnesses":[5]},"bytecode":"H4sIAAAAAAAA/7VUSQ7DIAwMJKl67U9slmBu+UpRyf9fUFVVqEQdbpiRkH2wzHjGoKYTazkcc4l7iRY253IwGS0+wcREHpxPGyGhJ/8yZG0mRyGmGCCisxkPH+0BJ+pe0AdUgry0HC/4aqYaWiqmJfQBJTkr5vlvF24N/nUdz+9V3VtwVn4v5/Jo8Lx4sAuSGWHmPKDvMsk+3hFzL/IeQdVy0qx3rw6Smq7Ce6mruVUj//vkPwR1AkL+BQAA","debug_symbols":"lY9NCoAgGETvMmsX/VHgVaLFlxkIoqIWhHj3lOgA7uYxb/MStBUUlTUBPKEDXxOCI1MpRPIRfO4ZpDnKWDLDqbQEn5a8MfRt+tCmjy16gZu8ol3LWlK/y4g/rGB83PfkFw==","file_map":{"47":{"source":"#[export]\npub fn not_equal(x: Field, y: Field) -> bool {\n x != y\n}\n\n#[export]\npub fn not_odd(x: Field) -> bool {\n !(((x as u8) & 1) as bool)\n}\n\n#[test]\nfn test_not_equal() {\n assert(not_equal(1, 2));\n // Uncomment to make test fail\n // assert(not_equal(1, 1));\n}\n\nfn test_not_odd() {\n assert(not_odd(2));\n // Uncomment to make test fail\n // assert(not_equal(1, 1));\n}\n","path":"/home/jz/Documents/code/aztec/recurseNoirTS/circuits/simple/src/lib.nr"}}} \ No newline at end of file diff --git a/circuits/simple/export/not_odd.json b/circuits/simple/export/not_odd.json deleted file mode 100644 index 8c93ab7..0000000 --- a/circuits/simple/export/not_odd.json +++ /dev/null @@ -1 +0,0 @@ -{"noir_version":"0.26.0+c46b164ce56e6a8f81255fb17eb6539bd040f336","hash":15860874175066265550,"abi":{"parameters":[{"name":"x","type":{"kind":"field"},"visibility":"private"}],"param_witnesses":{"x":[{"start":0,"end":1}]},"return_type":{"abi_type":{"kind":"boolean"},"visibility":"private"},"return_witnesses":[9]},"bytecode":"H4sIAAAAAAAA/81WzW7DIAx2wpIm2mHqm5i/ALe+Smnh/U87rktWIrGMatJiplpCpoR+/mxscAN3GefxluZsHi38lCbpU9K4TzghFhbo0mBzxLYQg2WtT/M++94WYtZmcb0VsJoN7i37T2lP8wDntcDjWFhrYCOnpHGf8NXZRb9nzi9j2NhkxLZzLImTUsGIwCU/o3DealTaT5Zbrq2+CitlsMoa551Bx5UMPGonQ1zk7sderJiItVAnydsKZ0flM/uGNe89CzUFjVOwzgZnojZ4Ocd4NaguHr1XE0ouozcCvXCzWRf0hX/xYlBIWKC/jBgdFuZ8X+bRpXlf4L8KK8yHbN8H0NZKbmvL5VjgWe3SyMGpMFkKPDVuB3RFUsvvjv6MilwpLsauAm4PtIW8vvRLh/RfnVGtR4M4L0Qei0PSA/ytMxo331add0Yj/N4ZlXCepjM6pLH+HuDxS0BlO0+mfZ1RjAegK9QB6iT5tjOi5LkXayQ812LCZmt5IcAnVgpzjegNAAA=","debug_symbols":"ldLNCsIwEATgd9lzDubHVvMq4mGtEQIhLU0UJOTdTRA9FHqY2w7Ld5opFOaJs59jIlvoQPZSKC0ce0qZ10xWKiPIxXu7tKyCHj44smasV0ESBQoFGgUGBUcUDCgYUXBCwRkubqdq/RfDVkhYKFhoTLTw4tXzLbi+3/57xuk35xbze/l+6gc=","file_map":{"47":{"source":"#[export]\npub fn not_equal(x: Field, y: Field) -> bool {\n x != y\n}\n\n#[export]\npub fn not_odd(x: Field) -> bool {\n !(((x as u8) & 1) as bool)\n}\n\n#[test]\nfn test_not_equal() {\n assert(not_equal(1, 2));\n // Uncomment to make test fail\n // assert(not_equal(1, 1));\n}\n\nfn test_not_odd() {\n assert(not_odd(2));\n // Uncomment to make test fail\n // assert(not_equal(1, 1));\n}\n","path":"/home/jz/Documents/code/aztec/recurseNoirTS/circuits/simple/src/lib.nr"}}} \ No newline at end of file diff --git a/circuits/simple/src/lib.nr b/circuits/simple/src/lib.nr deleted file mode 100644 index 9027a2f..0000000 --- a/circuits/simple/src/lib.nr +++ /dev/null @@ -1,22 +0,0 @@ -#[export] -pub fn not_equal(x: Field, y: Field) -> bool { - x != y -} - -#[export] -pub fn not_odd(x: Field) -> bool { - !(((x as u8) & 1) as bool) -} - -#[test] -fn test_not_equal() { - assert(not_equal(1, 2)); - // Uncomment to make test fail - // assert(not_equal(1, 1)); -} - -fn test_not_odd() { - assert(not_odd(2)); - // Uncomment to make test fail - // assert(not_equal(1, 1)); -} diff --git a/main.ts b/main.ts index 581cfd7..f154ed9 100644 --- a/main.ts +++ b/main.ts @@ -1,11 +1,43 @@ import { CompiledCircuit } from '@noir-lang/types'; -import { not_equal, not_odd, main_call, main } from './codegen'; +import { main } from './codegen'; import { setTimeout } from "timers/promises"; +import { Noir } from '@noir-lang/noir_js'; +import { BarretenbergBackend } from '@noir-lang/backend_barretenberg'; +import { join, resolve } from 'path'; +import { compile, createFileManager } from '@noir-lang/noir_wasm'; + +import { ProofData } from '@noir-lang/types'; + +async function getCircuit(name: string) { + const basePath = resolve(join('./circuits', name)); + const fm = createFileManager(basePath); + const compiled = await compile(fm, basePath); + console.log(compiled.program.abi); + if (!('program' in compiled)) { + throw new Error('Compilation failed'); + } + return compiled.program; +} + +const input1 = { n: 2 }; +const input2 = { n: 4 }; async function start() { - let res = await main_call("02", "04"); - console.log(res); + let simpleCircuit: CompiledCircuit = await getCircuit('not_odd'); + let simpleBackend: BarretenbergBackend = new BarretenbergBackend(simpleCircuit, { threads: 8 }); + let simpleNoir: Noir = new Noir(simpleCircuit, simpleBackend); + + const witness1 = (await simpleNoir.execute(input1)).witness; + let proof1: ProofData = await simpleBackend.generateProof(witness1); + + const witness2 = (await simpleNoir.execute(input2)).witness; + let proof2: ProofData = await simpleBackend.generateProof(witness2); + + // let res = await main(/* intermediate proofs */); + // console.log(res); + + simpleBackend.destroy(); } start(); diff --git a/package.json b/package.json index 3a2e03a..7168fb6 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "compile": "yarn clean && tsc", "start": "node build/main.js", "clean:codegen": "rm -rf codegen", - "export:simple": "nargo export --program-dir=./circuits/simple", + "export:simple": "nargo export --program-dir=./circuits/not_odd", "export:recurse": "nargo export --program-dir=./circuits/recurse", "export:all": "yarn clean:codegen && yarn export:simple && yarn export:recurse", "codegen": "yarn noir-codegen ./circuits/**/export/*.json", @@ -15,6 +15,7 @@ "@noir-lang/backend_barretenberg": "^0.26.0", "@noir-lang/noir_codegen": "^0.26.0", "@noir-lang/noir_js": "^0.26.0", + "@noir-lang/noir_wasm": "^0.26.0", "@types/node": "^20.12.2", "typescript": "^5.4.3" } diff --git a/yarn.lock b/yarn.lock index e2b25d4..1742348 100644 --- a/yarn.lock +++ b/yarn.lock @@ -56,6 +56,14 @@ "@noir-lang/noirc_abi" "0.26.0" "@noir-lang/types" "0.26.0" +"@noir-lang/noir_wasm@^0.26.0": + version "0.26.0" + resolved "https://registry.yarnpkg.com/@noir-lang/noir_wasm/-/noir_wasm-0.26.0.tgz#1c634932f53580022998e6811fee6077c47501d1" + integrity sha512-PmVyd/HE0fSxL6UU3XzCwpf9JyoR2Ql6V8odq3LFndosx5/FDWZtpxe1o7aNLdjebK2l4KmGJPN3eMh9JaiRoQ== + dependencies: + "@noir-lang/types" "0.26.0" + pako "^2.1.0" + "@noir-lang/noirc_abi@0.26.0": version "0.26.0" resolved "https://registry.yarnpkg.com/@noir-lang/noirc_abi/-/noirc_abi-0.26.0.tgz#5052ab7a55228cc04d77cebf8753ea42636963ff" @@ -330,6 +338,11 @@ ms@2.1.2: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +pako@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/pako/-/pako-2.1.0.tgz#266cc37f98c7d883545d11335c00fbd4062c9a86" + integrity sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug== + path-key@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" From e52f656d6fb07e9f0a16f4979f32a3758edc8012 Mon Sep 17 00:00:00 2001 From: James Zaki Date: Fri, 5 Apr 2024 12:06:19 +0100 Subject: [PATCH 03/17] Ignore circuit exports --- how-to/recursive-proofs/.gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/how-to/recursive-proofs/.gitignore b/how-to/recursive-proofs/.gitignore index 49c30e9..085144f 100644 --- a/how-to/recursive-proofs/.gitignore +++ b/how-to/recursive-proofs/.gitignore @@ -1,3 +1,4 @@ node_modules build -codegen \ No newline at end of file +codegen +circuits/*/export \ No newline at end of file From 2b36a15bd6014d86bd74d91d15fd3f0a4973e559 Mon Sep 17 00:00:00 2001 From: James Zaki Date: Fri, 5 Apr 2024 12:08:02 +0100 Subject: [PATCH 04/17] add usage instructions --- how-to/recursive-proofs/README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/how-to/recursive-proofs/README.md b/how-to/recursive-proofs/README.md index 685528f..eac2f77 100644 --- a/how-to/recursive-proofs/README.md +++ b/how-to/recursive-proofs/README.md @@ -1 +1,13 @@ # Noir recursion + +## Install dependencies + +`yarn` + +## Compile all the things + +`yarn compile:all` + +## Run main typescript + +`yarn start` From c29b67c56122627c3f718fc68a19984089cbaa19 Mon Sep 17 00:00:00 2001 From: James Zaki Date: Fri, 5 Apr 2024 16:09:52 +0100 Subject: [PATCH 05/17] User intermediate proof in circuit --- .../circuits/not_odd/src/main.nr | 9 ++--- .../circuits/recurse/src/lib.nr | 27 ++++---------- how-to/recursive-proofs/main.ts | 35 +++++++++++++------ 3 files changed, 33 insertions(+), 38 deletions(-) diff --git a/how-to/recursive-proofs/circuits/not_odd/src/main.nr b/how-to/recursive-proofs/circuits/not_odd/src/main.nr index 5324842..63ec619 100644 --- a/how-to/recursive-proofs/circuits/not_odd/src/main.nr +++ b/how-to/recursive-proofs/circuits/not_odd/src/main.nr @@ -1,13 +1,8 @@ #[recursive] -fn main(n: Field) -> pub u8 { - // not_odd(n); - n as u8 +fn main(n: Field) -> pub bool { + not_odd(n) } -// fn main(x: Field, y: Field) -> pub bool { -// not_odd(x) & not_odd(y) & not_equal(x, y); -// } - fn not_equal(x: Field, y: Field) -> bool { x != y } diff --git a/how-to/recursive-proofs/circuits/recurse/src/lib.nr b/how-to/recursive-proofs/circuits/recurse/src/lib.nr index da8e04d..aaa1530 100644 --- a/how-to/recursive-proofs/circuits/recurse/src/lib.nr +++ b/how-to/recursive-proofs/circuits/recurse/src/lib.nr @@ -1,24 +1,11 @@ use dep::std; -// use dep::simple; - -// #[export] -// fn main_call(x: Field, y: Field) -> bool { -// let mut res = simple::not_odd(x); -// res &= simple::not_odd(y); -// res &= simple::not_equal(x, y); -// res -// } #[export] -fn main(x: Field, y: Field) -> pub bool { - // Hash public inputs together - //TODO: take proofs - x != y +fn main(verification_key: [Field; 114], proof: [Field; 93], public_inputs: [Field; 1], key_hash: Field) { + std::verify_proof( + verification_key.as_slice(), + proof.as_slice(), + public_inputs.as_slice(), + key_hash + ); } - -// #[test] -// fn test_not_equal() { -// assert(main_call(2, 4)); -// // Uncomment to make test fail -// // assert(not_equal(1, 1)); -// } diff --git a/how-to/recursive-proofs/main.ts b/how-to/recursive-proofs/main.ts index f154ed9..425efff 100644 --- a/how-to/recursive-proofs/main.ts +++ b/how-to/recursive-proofs/main.ts @@ -13,7 +13,6 @@ async function getCircuit(name: string) { const basePath = resolve(join('./circuits', name)); const fm = createFileManager(basePath); const compiled = await compile(fm, basePath); - console.log(compiled.program.abi); if (!('program' in compiled)) { throw new Error('Compilation failed'); } @@ -23,21 +22,35 @@ async function getCircuit(name: string) { const input1 = { n: 2 }; const input2 = { n: 4 }; +async function fullNoirFromCircuit(circuitName: string): Promise { + const circuit: CompiledCircuit = await getCircuit('not_odd'); + const backend: BarretenbergBackend = new BarretenbergBackend(circuit, { threads: 8 }); + const noir: Noir = new Noir(circuit, backend); + return { circuit, backend, noir }; +} + +type FullNoir = { + circuit: CompiledCircuit, + backend: BarretenbergBackend, + noir: Noir +} + async function start() { - let simpleCircuit: CompiledCircuit = await getCircuit('not_odd'); - let simpleBackend: BarretenbergBackend = new BarretenbergBackend(simpleCircuit, { threads: 8 }); - let simpleNoir: Noir = new Noir(simpleCircuit, simpleBackend); + const simple: FullNoir = await fullNoirFromCircuit('not_odd'); + + const witness1 = (await simple.noir.execute(input1)).witness; + const proof1: ProofData = await simple.backend.generateProof(witness1); - const witness1 = (await simpleNoir.execute(input1)).witness; - let proof1: ProofData = await simpleBackend.generateProof(witness1); + // const witness2 = (await simple.noir.execute(input2)).witness; + // const proof2: ProofData = await simple.backend.generateProof(witness2); - const witness2 = (await simpleNoir.execute(input2)).witness; - let proof2: ProofData = await simpleBackend.generateProof(witness2); + const { proofAsFields, vkAsFields, vkHash } = await simple.backend.generateRecursiveProofArtifacts(proof1, 1); + // console.log({ proofAsFields, vkAsFields, vkHash }); - // let res = await main(/* intermediate proofs */); - // console.log(res); + let res = await main(vkAsFields, proofAsFields, ["7"], vkHash); + console.log(res); - simpleBackend.destroy(); + simple.backend.destroy(); } start(); From 61a9cbba5ef3e0bbc2de884e7bfb120877bf95f9 Mon Sep 17 00:00:00 2001 From: James Zaki Date: Fri, 5 Apr 2024 16:44:28 +0100 Subject: [PATCH 06/17] Test altered proof --- how-to/recursive-proofs/main.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/how-to/recursive-proofs/main.ts b/how-to/recursive-proofs/main.ts index 425efff..28029ba 100644 --- a/how-to/recursive-proofs/main.ts +++ b/how-to/recursive-proofs/main.ts @@ -36,17 +36,26 @@ type FullNoir = { } async function start() { + console.log("Creating Noir from circuit..."); const simple: FullNoir = await fullNoirFromCircuit('not_odd'); + console.log("Executing binary circuit for witness..."); const witness1 = (await simple.noir.execute(input1)).witness; + console.log("Generating intermediate proof..."); const proof1: ProofData = await simple.backend.generateProof(witness1); + if (1) { // mess up proof + console.log("Generating intermediate proof..."); + proof1.proof[0] += 1; + } + // const witness2 = (await simple.noir.execute(input2)).witness; // const proof2: ProofData = await simple.backend.generateProof(witness2); - + console.log("Generating recursive proof artifacts..."); const { proofAsFields, vkAsFields, vkHash } = await simple.backend.generateRecursiveProofArtifacts(proof1, 1); // console.log({ proofAsFields, vkAsFields, vkHash }); + console.log("Executing lib circuit function to verify inner proof"); let res = await main(vkAsFields, proofAsFields, ["7"], vkHash); console.log(res); From ed0371f041f776f470a39d5f5b1492a7679e8cce Mon Sep 17 00:00:00 2001 From: James Zaki Date: Fri, 5 Apr 2024 17:13:42 +0100 Subject: [PATCH 07/17] verify outer proof --- .../circuits/recurse/Nargo.toml | 2 +- .../circuits/recurse/src/{lib.nr => main.nr} | 8 ++- how-to/recursive-proofs/main.ts | 52 +++++++++++++------ how-to/recursive-proofs/package.json | 2 +- 4 files changed, 43 insertions(+), 21 deletions(-) rename how-to/recursive-proofs/circuits/recurse/src/{lib.nr => main.nr} (56%) diff --git a/how-to/recursive-proofs/circuits/recurse/Nargo.toml b/how-to/recursive-proofs/circuits/recurse/Nargo.toml index f2185a5..ce8346c 100644 --- a/how-to/recursive-proofs/circuits/recurse/Nargo.toml +++ b/how-to/recursive-proofs/circuits/recurse/Nargo.toml @@ -1,6 +1,6 @@ [package] name = "recurse" -type = "lib" +type = "bin" authors = [""] compiler_version = ">=0.26.0" diff --git a/how-to/recursive-proofs/circuits/recurse/src/lib.nr b/how-to/recursive-proofs/circuits/recurse/src/main.nr similarity index 56% rename from how-to/recursive-proofs/circuits/recurse/src/lib.nr rename to how-to/recursive-proofs/circuits/recurse/src/main.nr index aaa1530..6dce514 100644 --- a/how-to/recursive-proofs/circuits/recurse/src/lib.nr +++ b/how-to/recursive-proofs/circuits/recurse/src/main.nr @@ -1,7 +1,11 @@ use dep::std; -#[export] -fn main(verification_key: [Field; 114], proof: [Field; 93], public_inputs: [Field; 1], key_hash: Field) { +fn main( + verification_key: [Field; 114], + proof: [Field; 93], + public_inputs: [Field; 1], + key_hash: Field +) { std::verify_proof( verification_key.as_slice(), proof.as_slice(), diff --git a/how-to/recursive-proofs/main.ts b/how-to/recursive-proofs/main.ts index 28029ba..d360441 100644 --- a/how-to/recursive-proofs/main.ts +++ b/how-to/recursive-proofs/main.ts @@ -1,5 +1,5 @@ import { CompiledCircuit } from '@noir-lang/types'; -import { main } from './codegen'; +// import { main } from './codegen'; import { setTimeout } from "timers/promises"; import { Noir } from '@noir-lang/noir_js'; @@ -19,11 +19,8 @@ async function getCircuit(name: string) { return compiled.program; } -const input1 = { n: 2 }; -const input2 = { n: 4 }; - async function fullNoirFromCircuit(circuitName: string): Promise { - const circuit: CompiledCircuit = await getCircuit('not_odd'); + const circuit: CompiledCircuit = await getCircuit(circuitName); const backend: BarretenbergBackend = new BarretenbergBackend(circuit, { threads: 8 }); const noir: Noir = new Noir(circuit, backend); return { circuit, backend, noir }; @@ -36,30 +33,51 @@ type FullNoir = { } async function start() { + // Generate inner proof artifacts console.log("Creating Noir from circuit..."); const simple: FullNoir = await fullNoirFromCircuit('not_odd'); console.log("Executing binary circuit for witness..."); - const witness1 = (await simple.noir.execute(input1)).witness; + const innerInput = { n: 2 }; + const innerWitness = (await simple.noir.execute(innerInput)).witness; console.log("Generating intermediate proof..."); - const proof1: ProofData = await simple.backend.generateProof(witness1); + const innerProof: ProofData = await simple.backend.generateProof(innerWitness); - if (1) { // mess up proof - console.log("Generating intermediate proof..."); - proof1.proof[0] += 1; + if (false) { // mess up proof + console.log("Messing intermediate proof..."); + innerProof.proof[0] += 1; } - // const witness2 = (await simple.noir.execute(input2)).witness; - // const proof2: ProofData = await simple.backend.generateProof(witness2); console.log("Generating recursive proof artifacts..."); - const { proofAsFields, vkAsFields, vkHash } = await simple.backend.generateRecursiveProofArtifacts(proof1, 1); + const { proofAsFields, vkAsFields, vkHash } = await simple.backend.generateRecursiveProofArtifacts(innerProof, 1); // console.log({ proofAsFields, vkAsFields, vkHash }); + simple.backend.destroy(); + + // Generate and verify outer proof + console.log("Creating Noir from circuit..."); + const outer: FullNoir = await fullNoirFromCircuit('recurse'); + console.log("Executing binary circuit for witness..."); + const outerInput = { + verification_key: vkAsFields, + proof: proofAsFields, + public_inputs: ["0"], + key_hash: vkHash + }; + const outerWitness = (await outer.noir.execute( + outerInput + )).witness; - console.log("Executing lib circuit function to verify inner proof"); - let res = await main(vkAsFields, proofAsFields, ["7"], vkHash); - console.log(res); + console.log("Generating outer proof..."); + const outerProof: ProofData = await outer.backend.generateProof(outerWitness); - simple.backend.destroy(); + console.log("Verifying outer proof..."); + console.log(await outer.backend.verifyProof(outerProof)); + + // console.log("Executing lib circuit function to verify inner proof"); + // let res = await main(vkAsFields, proofAsFields, ["7"], vkHash); + // console.log(res); + + outer.backend.destroy(); } start(); diff --git a/how-to/recursive-proofs/package.json b/how-to/recursive-proofs/package.json index 7168fb6..97b5b4d 100644 --- a/how-to/recursive-proofs/package.json +++ b/how-to/recursive-proofs/package.json @@ -8,7 +8,7 @@ "export:simple": "nargo export --program-dir=./circuits/not_odd", "export:recurse": "nargo export --program-dir=./circuits/recurse", "export:all": "yarn clean:codegen && yarn export:simple && yarn export:recurse", - "codegen": "yarn noir-codegen ./circuits/**/export/*.json", + "codegen": "echo 'skipping' || yarn noir-codegen ./circuits/**/export/*.json", "compile:all": "yarn export:all && yarn codegen && yarn compile" }, "devDependencies": { From 53a91e0c08a4a8317810296992ef7dfe9b38c867 Mon Sep 17 00:00:00 2001 From: James Zaki Date: Fri, 5 Apr 2024 17:55:27 +0100 Subject: [PATCH 08/17] Verify two inner proofs (exception) --- .../circuits/recurse/src/main.nr | 13 ++++-- how-to/recursive-proofs/main.ts | 46 ++++++++----------- 2 files changed, 28 insertions(+), 31 deletions(-) diff --git a/how-to/recursive-proofs/circuits/recurse/src/main.nr b/how-to/recursive-proofs/circuits/recurse/src/main.nr index 6dce514..385b6d5 100644 --- a/how-to/recursive-proofs/circuits/recurse/src/main.nr +++ b/how-to/recursive-proofs/circuits/recurse/src/main.nr @@ -2,13 +2,20 @@ use dep::std; fn main( verification_key: [Field; 114], - proof: [Field; 93], public_inputs: [Field; 1], - key_hash: Field + key_hash: Field, + proof1: [Field; 93], + proof2: [Field; 93] ) { std::verify_proof( verification_key.as_slice(), - proof.as_slice(), + proof1.as_slice(), + public_inputs.as_slice(), + key_hash + ); + std::verify_proof( + verification_key.as_slice(), + proof2.as_slice(), public_inputs.as_slice(), key_hash ); diff --git a/how-to/recursive-proofs/main.ts b/how-to/recursive-proofs/main.ts index d360441..40489d0 100644 --- a/how-to/recursive-proofs/main.ts +++ b/how-to/recursive-proofs/main.ts @@ -33,49 +33,39 @@ type FullNoir = { } async function start() { - // Generate inner proof artifacts - console.log("Creating Noir from circuit..."); const simple: FullNoir = await fullNoirFromCircuit('not_odd'); + const outer: FullNoir = await fullNoirFromCircuit('recurse'); - console.log("Executing binary circuit for witness..."); - const innerInput = { n: 2 }; - const innerWitness = (await simple.noir.execute(innerInput)).witness; - console.log("Generating intermediate proof..."); - const innerProof: ProofData = await simple.backend.generateProof(innerWitness); + // Generate inner proof artifacts + console.log("Generating intermediate proof artifacts 1..."); + const innerWitness1 = (await simple.noir.execute({ n: 2 })).witness; + const innerProof1: ProofData = await simple.backend.generateProof(innerWitness1); + const artifacts1 = await simple.backend.generateRecursiveProofArtifacts(innerProof1, 1); - if (false) { // mess up proof - console.log("Messing intermediate proof..."); - innerProof.proof[0] += 1; - } + console.log("Generating intermediate proof artifacts 2..."); + const innerWitness2 = (await simple.noir.execute({ n: 4 })).witness; + const innerProof2: ProofData = await simple.backend.generateProof(innerWitness2); + const artifacts2 = await simple.backend.generateRecursiveProofArtifacts(innerProof2, 1); - console.log("Generating recursive proof artifacts..."); - const { proofAsFields, vkAsFields, vkHash } = await simple.backend.generateRecursiveProofArtifacts(innerProof, 1); - // console.log({ proofAsFields, vkAsFields, vkHash }); simple.backend.destroy(); // Generate and verify outer proof - console.log("Creating Noir from circuit..."); - const outer: FullNoir = await fullNoirFromCircuit('recurse'); - console.log("Executing binary circuit for witness..."); + console.log("Generating outer proof..."); const outerInput = { - verification_key: vkAsFields, - proof: proofAsFields, - public_inputs: ["0"], - key_hash: vkHash + verification_key: artifacts1.vkAsFields, + public_inputs: ["1"], // expect output of inner call to be "true" + key_hash: artifacts1.vkHash, + proof1: artifacts1.proofAsFields, + proof2: artifacts2.proofAsFields }; const outerWitness = (await outer.noir.execute( outerInput )).witness; - - console.log("Generating outer proof..."); const outerProof: ProofData = await outer.backend.generateProof(outerWitness); console.log("Verifying outer proof..."); - console.log(await outer.backend.verifyProof(outerProof)); - - // console.log("Executing lib circuit function to verify inner proof"); - // let res = await main(vkAsFields, proofAsFields, ["7"], vkHash); - // console.log(res); + const res: boolean = await outer.backend.verifyProof(outerProof); + console.log("Verification", res ? "PASSED" : "failed"); outer.backend.destroy(); } From 2558dc98f9dc9f79d318ecad69650bdee14d1550 Mon Sep 17 00:00:00 2001 From: James Zaki Date: Fri, 5 Apr 2024 18:18:17 +0100 Subject: [PATCH 09/17] minor updates to recursive howto script (exception) --- how-to/recursive-proofs/main.ts | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/how-to/recursive-proofs/main.ts b/how-to/recursive-proofs/main.ts index 40489d0..c2305f5 100644 --- a/how-to/recursive-proofs/main.ts +++ b/how-to/recursive-proofs/main.ts @@ -19,9 +19,11 @@ async function getCircuit(name: string) { return compiled.program; } +const cores = 12; + async function fullNoirFromCircuit(circuitName: string): Promise { const circuit: CompiledCircuit = await getCircuit(circuitName); - const backend: BarretenbergBackend = new BarretenbergBackend(circuit, { threads: 8 }); + const backend: BarretenbergBackend = new BarretenbergBackend(circuit, { threads: cores }); const noir: Noir = new Noir(circuit, backend); return { circuit, backend, noir }; } @@ -50,7 +52,6 @@ async function start() { simple.backend.destroy(); // Generate and verify outer proof - console.log("Generating outer proof..."); const outerInput = { verification_key: artifacts1.vkAsFields, public_inputs: ["1"], // expect output of inner call to be "true" @@ -61,11 +62,16 @@ async function start() { const outerWitness = (await outer.noir.execute( outerInput )).witness; - const outerProof: ProofData = await outer.backend.generateProof(outerWitness); - - console.log("Verifying outer proof..."); - const res: boolean = await outer.backend.verifyProof(outerProof); - console.log("Verification", res ? "PASSED" : "failed"); + try { + console.log("Generating outer proof..."); + const outerProof: ProofData = await outer.backend.generateProof(outerWitness); + console.log("Verifying outer proof..."); + const res: boolean = await outer.backend.verifyProof(outerProof); + console.log("Verification", res ? "PASSED" : "failed"); + } + catch (e) { + console.log(e); + } outer.backend.destroy(); } From 8120d965b61323a56b16b8531cc342fb48d49cee Mon Sep 17 00:00:00 2001 From: James Zaki Date: Thu, 11 Apr 2024 15:37:13 +0100 Subject: [PATCH 10/17] Single recursive function (WIP) --- .../circuits/recurse/src/main.nr | 30 +++---- how-to/recursive-proofs/main.ts | 80 +++++++++++-------- 2 files changed, 60 insertions(+), 50 deletions(-) diff --git a/how-to/recursive-proofs/circuits/recurse/src/main.nr b/how-to/recursive-proofs/circuits/recurse/src/main.nr index 385b6d5..14de9a2 100644 --- a/how-to/recursive-proofs/circuits/recurse/src/main.nr +++ b/how-to/recursive-proofs/circuits/recurse/src/main.nr @@ -1,22 +1,22 @@ use dep::std; +// recursive summation +#[recursive] fn main( verification_key: [Field; 114], + proof: [Field; 93], public_inputs: [Field; 1], key_hash: Field, - proof1: [Field; 93], - proof2: [Field; 93] -) { - std::verify_proof( - verification_key.as_slice(), - proof1.as_slice(), - public_inputs.as_slice(), - key_hash - ); - std::verify_proof( - verification_key.as_slice(), - proof2.as_slice(), - public_inputs.as_slice(), - key_hash - ); + sum: Field, + n: Field +) -> pub u64 { + if (key_hash != 0) { + std::verify_proof( + verification_key.as_slice(), + proof.as_slice(), + public_inputs.as_slice(), + key_hash + ); + } + sum as u64 + n as u64 } diff --git a/how-to/recursive-proofs/main.ts b/how-to/recursive-proofs/main.ts index c2305f5..edcdfa7 100644 --- a/how-to/recursive-proofs/main.ts +++ b/how-to/recursive-proofs/main.ts @@ -35,45 +35,55 @@ type FullNoir = { } async function start() { - const simple: FullNoir = await fullNoirFromCircuit('not_odd'); - const outer: FullNoir = await fullNoirFromCircuit('recurse'); + const recursive: FullNoir = await fullNoirFromCircuit('recurse'); - // Generate inner proof artifacts - console.log("Generating intermediate proof artifacts 1..."); - const innerWitness1 = (await simple.noir.execute({ n: 2 })).witness; - const innerProof1: ProofData = await simple.backend.generateProof(innerWitness1); - const artifacts1 = await simple.backend.generateRecursiveProofArtifacts(innerProof1, 1); - - console.log("Generating intermediate proof artifacts 2..."); - const innerWitness2 = (await simple.noir.execute({ n: 4 })).witness; - const innerProof2: ProofData = await simple.backend.generateProof(innerWitness2); - const artifacts2 = await simple.backend.generateRecursiveProofArtifacts(innerProof2, 1); - - simple.backend.destroy(); - - // Generate and verify outer proof - const outerInput = { - verification_key: artifacts1.vkAsFields, - public_inputs: ["1"], // expect output of inner call to be "true" - key_hash: artifacts1.vkHash, - proof1: artifacts1.proofAsFields, - proof2: artifacts2.proofAsFields + // Generate artifacts recursively + let verificationProof = { + verification_key: Array(114).fill("0x00"), + proof: Array(93).fill("0x00"), + public_inputs: ["0x06"], + key_hash: "0x00" as string, // circuit should skip `verify_proof` when key_hash is 0. }; - const outerWitness = (await outer.noir.execute( - outerInput - )).witness; - try { - console.log("Generating outer proof..."); - const outerProof: ProofData = await outer.backend.generateProof(outerWitness); - console.log("Verifying outer proof..."); - const res: boolean = await outer.backend.verifyProof(outerProof); - console.log("Verification", res ? "PASSED" : "failed"); - } - catch (e) { - console.log(e); + let sum = 1; + const nodes = [3, 7]; + for (const [i, n] of nodes.entries()) { + console.log("\n\nExecuting (with key_hash %s, sum %d, n %d)", verificationProof.key_hash, sum, n); + verificationProof.public_inputs = ["4"]; + const { witness, returnValue } = await recursive.noir.execute({ + ...verificationProof, + sum, + n + }); + console.log("RESULT:", returnValue, witness); + sum = Number(returnValue) as number; + console.log("Generating proof data..."); + const pd: ProofData = await recursive.backend.generateProof(witness); + console.log(pd); + if (i < nodes.length - 1) { + console.log("Generating recursive proof artifacts (depth %d)...", i); + ({ + proofAsFields: verificationProof.proof, + vkAsFields: verificationProof.verification_key, + vkHash: verificationProof.key_hash + } = await recursive.backend.generateRecursiveProofArtifacts( + pd, + Number(verificationProof.public_inputs[0]) + )); + } + else { + console.log("Verifying final proof..."); + try { + const res: boolean = await recursive.backend.verifyProof(pd); + console.log("Verification", res ? "PASSED" : "failed"); + } + catch (e) { + console.log(e); + } + + } } - outer.backend.destroy(); + recursive.backend.destroy(); } start(); From 67121cd8a4eb2cbbbc5cde045d11d7af023bde59 Mon Sep 17 00:00:00 2001 From: James Zaki Date: Thu, 11 Apr 2024 16:27:50 +0100 Subject: [PATCH 11/17] Revert "Single recursive function (WIP)" This reverts commit 8120d965b61323a56b16b8531cc342fb48d49cee. --- .../circuits/recurse/src/main.nr | 30 +++---- how-to/recursive-proofs/main.ts | 80 ++++++++----------- 2 files changed, 50 insertions(+), 60 deletions(-) diff --git a/how-to/recursive-proofs/circuits/recurse/src/main.nr b/how-to/recursive-proofs/circuits/recurse/src/main.nr index 14de9a2..385b6d5 100644 --- a/how-to/recursive-proofs/circuits/recurse/src/main.nr +++ b/how-to/recursive-proofs/circuits/recurse/src/main.nr @@ -1,22 +1,22 @@ use dep::std; -// recursive summation -#[recursive] fn main( verification_key: [Field; 114], - proof: [Field; 93], public_inputs: [Field; 1], key_hash: Field, - sum: Field, - n: Field -) -> pub u64 { - if (key_hash != 0) { - std::verify_proof( - verification_key.as_slice(), - proof.as_slice(), - public_inputs.as_slice(), - key_hash - ); - } - sum as u64 + n as u64 + proof1: [Field; 93], + proof2: [Field; 93] +) { + std::verify_proof( + verification_key.as_slice(), + proof1.as_slice(), + public_inputs.as_slice(), + key_hash + ); + std::verify_proof( + verification_key.as_slice(), + proof2.as_slice(), + public_inputs.as_slice(), + key_hash + ); } diff --git a/how-to/recursive-proofs/main.ts b/how-to/recursive-proofs/main.ts index edcdfa7..c2305f5 100644 --- a/how-to/recursive-proofs/main.ts +++ b/how-to/recursive-proofs/main.ts @@ -35,55 +35,45 @@ type FullNoir = { } async function start() { - const recursive: FullNoir = await fullNoirFromCircuit('recurse'); + const simple: FullNoir = await fullNoirFromCircuit('not_odd'); + const outer: FullNoir = await fullNoirFromCircuit('recurse'); - // Generate artifacts recursively - let verificationProof = { - verification_key: Array(114).fill("0x00"), - proof: Array(93).fill("0x00"), - public_inputs: ["0x06"], - key_hash: "0x00" as string, // circuit should skip `verify_proof` when key_hash is 0. - }; - let sum = 1; - const nodes = [3, 7]; - for (const [i, n] of nodes.entries()) { - console.log("\n\nExecuting (with key_hash %s, sum %d, n %d)", verificationProof.key_hash, sum, n); - verificationProof.public_inputs = ["4"]; - const { witness, returnValue } = await recursive.noir.execute({ - ...verificationProof, - sum, - n - }); - console.log("RESULT:", returnValue, witness); - sum = Number(returnValue) as number; - console.log("Generating proof data..."); - const pd: ProofData = await recursive.backend.generateProof(witness); - console.log(pd); - if (i < nodes.length - 1) { - console.log("Generating recursive proof artifacts (depth %d)...", i); - ({ - proofAsFields: verificationProof.proof, - vkAsFields: verificationProof.verification_key, - vkHash: verificationProof.key_hash - } = await recursive.backend.generateRecursiveProofArtifacts( - pd, - Number(verificationProof.public_inputs[0]) - )); - } - else { - console.log("Verifying final proof..."); - try { - const res: boolean = await recursive.backend.verifyProof(pd); - console.log("Verification", res ? "PASSED" : "failed"); - } - catch (e) { - console.log(e); - } + // Generate inner proof artifacts + console.log("Generating intermediate proof artifacts 1..."); + const innerWitness1 = (await simple.noir.execute({ n: 2 })).witness; + const innerProof1: ProofData = await simple.backend.generateProof(innerWitness1); + const artifacts1 = await simple.backend.generateRecursiveProofArtifacts(innerProof1, 1); + + console.log("Generating intermediate proof artifacts 2..."); + const innerWitness2 = (await simple.noir.execute({ n: 4 })).witness; + const innerProof2: ProofData = await simple.backend.generateProof(innerWitness2); + const artifacts2 = await simple.backend.generateRecursiveProofArtifacts(innerProof2, 1); + + simple.backend.destroy(); - } + // Generate and verify outer proof + const outerInput = { + verification_key: artifacts1.vkAsFields, + public_inputs: ["1"], // expect output of inner call to be "true" + key_hash: artifacts1.vkHash, + proof1: artifacts1.proofAsFields, + proof2: artifacts2.proofAsFields + }; + const outerWitness = (await outer.noir.execute( + outerInput + )).witness; + try { + console.log("Generating outer proof..."); + const outerProof: ProofData = await outer.backend.generateProof(outerWitness); + console.log("Verifying outer proof..."); + const res: boolean = await outer.backend.verifyProof(outerProof); + console.log("Verification", res ? "PASSED" : "failed"); + } + catch (e) { + console.log(e); } - recursive.backend.destroy(); + outer.backend.destroy(); } start(); From 2fdeeea858b0abab291c2b0664b4d010fd4257c2 Mon Sep 17 00:00:00 2001 From: James Zaki Date: Fri, 12 Apr 2024 13:31:04 +0100 Subject: [PATCH 12/17] Modify for single nested recursion --- .../circuits/not_odd/src/main.nr | 25 ------ .../circuits/recurse/src/main.nr | 22 ----- .../{recurse => recurseLeaf}/Nargo.toml | 1 + .../circuits/recurseLeaf/src/main.nr | 20 +++++ .../circuits/recurseNode/Nargo.toml | 8 ++ .../circuits/recurseNode/src/main.nr | 17 ++++ .../recursive-proofs/circuits/sum/Nargo.toml | 8 ++ .../recursive-proofs/circuits/sum/src/main.nr | 11 +++ .../circuits/{not_odd => sumLib}/Nargo.toml | 4 +- .../circuits/sumLib/src/lib.nr | 10 +++ how-to/recursive-proofs/main.ts | 85 ++++++++++++------- how-to/recursive-proofs/package.json | 7 +- 12 files changed, 135 insertions(+), 83 deletions(-) delete mode 100644 how-to/recursive-proofs/circuits/not_odd/src/main.nr delete mode 100644 how-to/recursive-proofs/circuits/recurse/src/main.nr rename how-to/recursive-proofs/circuits/{recurse => recurseLeaf}/Nargo.toml (75%) create mode 100644 how-to/recursive-proofs/circuits/recurseLeaf/src/main.nr create mode 100644 how-to/recursive-proofs/circuits/recurseNode/Nargo.toml create mode 100644 how-to/recursive-proofs/circuits/recurseNode/src/main.nr create mode 100644 how-to/recursive-proofs/circuits/sum/Nargo.toml create mode 100644 how-to/recursive-proofs/circuits/sum/src/main.nr rename how-to/recursive-proofs/circuits/{not_odd => sumLib}/Nargo.toml (70%) create mode 100644 how-to/recursive-proofs/circuits/sumLib/src/lib.nr diff --git a/how-to/recursive-proofs/circuits/not_odd/src/main.nr b/how-to/recursive-proofs/circuits/not_odd/src/main.nr deleted file mode 100644 index 63ec619..0000000 --- a/how-to/recursive-proofs/circuits/not_odd/src/main.nr +++ /dev/null @@ -1,25 +0,0 @@ -#[recursive] -fn main(n: Field) -> pub bool { - not_odd(n) -} - -fn not_equal(x: Field, y: Field) -> bool { - x != y -} - -fn not_odd(n: Field) -> bool { - (n as u8) & 1 == 0 -} - -#[test] -fn test_not_equal() { - assert(not_equal(1, 2)); - // Uncomment to make test fail - // assert(not_equal(1, 1)); -} - -fn test_not_odd() { - assert(not_odd(2)); - // Uncomment to make test fail - // assert(not_odd(1)); -} diff --git a/how-to/recursive-proofs/circuits/recurse/src/main.nr b/how-to/recursive-proofs/circuits/recurse/src/main.nr deleted file mode 100644 index 385b6d5..0000000 --- a/how-to/recursive-proofs/circuits/recurse/src/main.nr +++ /dev/null @@ -1,22 +0,0 @@ -use dep::std; - -fn main( - verification_key: [Field; 114], - public_inputs: [Field; 1], - key_hash: Field, - proof1: [Field; 93], - proof2: [Field; 93] -) { - std::verify_proof( - verification_key.as_slice(), - proof1.as_slice(), - public_inputs.as_slice(), - key_hash - ); - std::verify_proof( - verification_key.as_slice(), - proof2.as_slice(), - public_inputs.as_slice(), - key_hash - ); -} diff --git a/how-to/recursive-proofs/circuits/recurse/Nargo.toml b/how-to/recursive-proofs/circuits/recurseLeaf/Nargo.toml similarity index 75% rename from how-to/recursive-proofs/circuits/recurse/Nargo.toml rename to how-to/recursive-proofs/circuits/recurseLeaf/Nargo.toml index ce8346c..8f071fc 100644 --- a/how-to/recursive-proofs/circuits/recurse/Nargo.toml +++ b/how-to/recursive-proofs/circuits/recurseLeaf/Nargo.toml @@ -5,3 +5,4 @@ authors = [""] compiler_version = ">=0.26.0" [dependencies] +sumLib = { path = "../sumLib" } diff --git a/how-to/recursive-proofs/circuits/recurseLeaf/src/main.nr b/how-to/recursive-proofs/circuits/recurseLeaf/src/main.nr new file mode 100644 index 0000000..ff06091 --- /dev/null +++ b/how-to/recursive-proofs/circuits/recurseLeaf/src/main.nr @@ -0,0 +1,20 @@ +use dep::std; +use dep::sumLib::secretSum; + +#[recursive] +fn main( + verification_key: [Field; 114], + public_inputs: pub [Field; 3], + key_hash: Field, + proof: [Field; 93], + num: u64 +) -> pub u64 { + // verify sum so far was computed correctly + std::verify_proof( + verification_key.as_slice(), + proof.as_slice(), + public_inputs.as_slice(), + key_hash + ); + secretSum((public_inputs[2] as u64), num) +} diff --git a/how-to/recursive-proofs/circuits/recurseNode/Nargo.toml b/how-to/recursive-proofs/circuits/recurseNode/Nargo.toml new file mode 100644 index 0000000..8f071fc --- /dev/null +++ b/how-to/recursive-proofs/circuits/recurseNode/Nargo.toml @@ -0,0 +1,8 @@ +[package] +name = "recurse" +type = "bin" +authors = [""] +compiler_version = ">=0.26.0" + +[dependencies] +sumLib = { path = "../sumLib" } diff --git a/how-to/recursive-proofs/circuits/recurseNode/src/main.nr b/how-to/recursive-proofs/circuits/recurseNode/src/main.nr new file mode 100644 index 0000000..109a026 --- /dev/null +++ b/how-to/recursive-proofs/circuits/recurseNode/src/main.nr @@ -0,0 +1,17 @@ +use dep::std; + +fn main( + verification_key: [Field; 114], + public_inputs: pub [Field; 6], + key_hash: Field, + proof: [Field; 109] +) -> pub u64 { + // verify sum was computed correctly + std::verify_proof( + verification_key.as_slice(), + proof.as_slice(), + public_inputs.as_slice(), + key_hash + ); + public_inputs[5] as u64 +} diff --git a/how-to/recursive-proofs/circuits/sum/Nargo.toml b/how-to/recursive-proofs/circuits/sum/Nargo.toml new file mode 100644 index 0000000..4744d35 --- /dev/null +++ b/how-to/recursive-proofs/circuits/sum/Nargo.toml @@ -0,0 +1,8 @@ +[package] +name = "sum" +type = "bin" +authors = [""] +compiler_version = ">=0.26.0" + +[dependencies] +sumLib = { path = "../sumLib" } diff --git a/how-to/recursive-proofs/circuits/sum/src/main.nr b/how-to/recursive-proofs/circuits/sum/src/main.nr new file mode 100644 index 0000000..bea057b --- /dev/null +++ b/how-to/recursive-proofs/circuits/sum/src/main.nr @@ -0,0 +1,11 @@ +use dep::sumLib::secretSum; + +#[recursive] +fn main(a: pub u64, b: pub u64) -> pub u64 { + secretSum(a, b) +} + +#[test] +fn test_not_equal() { + assert(main(1, 3) == 4); +} diff --git a/how-to/recursive-proofs/circuits/not_odd/Nargo.toml b/how-to/recursive-proofs/circuits/sumLib/Nargo.toml similarity index 70% rename from how-to/recursive-proofs/circuits/not_odd/Nargo.toml rename to how-to/recursive-proofs/circuits/sumLib/Nargo.toml index 738a67d..a78466c 100644 --- a/how-to/recursive-proofs/circuits/not_odd/Nargo.toml +++ b/how-to/recursive-proofs/circuits/sumLib/Nargo.toml @@ -1,6 +1,6 @@ [package] -name = "simple" -type = "bin" +name = "sumLib" +type = "lib" authors = [""] compiler_version = ">=0.26.0" diff --git a/how-to/recursive-proofs/circuits/sumLib/src/lib.nr b/how-to/recursive-proofs/circuits/sumLib/src/lib.nr new file mode 100644 index 0000000..329f6c3 --- /dev/null +++ b/how-to/recursive-proofs/circuits/sumLib/src/lib.nr @@ -0,0 +1,10 @@ +pub fn secretSum(a: u64, b: u64) -> u64 { + a + b +} + +#[test] +fn test_sum() { + assert(secretSum(1, 2) == 3); + // Uncomment to make test fail + // assert(secretSum(1, 1) == 3); +} diff --git a/how-to/recursive-proofs/main.ts b/how-to/recursive-proofs/main.ts index c2305f5..044054f 100644 --- a/how-to/recursive-proofs/main.ts +++ b/how-to/recursive-proofs/main.ts @@ -35,45 +35,68 @@ type FullNoir = { } async function start() { - const simple: FullNoir = await fullNoirFromCircuit('not_odd'); - const outer: FullNoir = await fullNoirFromCircuit('recurse'); + const leaf: FullNoir = await fullNoirFromCircuit('sum'); - // Generate inner proof artifacts - console.log("Generating intermediate proof artifacts 1..."); - const innerWitness1 = (await simple.noir.execute({ n: 2 })).witness; - const innerProof1: ProofData = await simple.backend.generateProof(innerWitness1); - const artifacts1 = await simple.backend.generateRecursiveProofArtifacts(innerProof1, 1); + const leafParams = { a: 1, b: 3 }; - console.log("Generating intermediate proof artifacts 2..."); - const innerWitness2 = (await simple.noir.execute({ n: 4 })).witness; - const innerProof2: ProofData = await simple.backend.generateProof(innerWitness2); - const artifacts2 = await simple.backend.generateRecursiveProofArtifacts(innerProof2, 1); + // Generate leaf proof artifacts + let { witness, returnValue } = await leaf.noir.execute(leafParams); + console.log("leaf: %d + %d = ", ...Object.values(leafParams), Number(returnValue).toString()); + const innerProof1: ProofData = await leaf.backend.generateProof(witness); + console.log("Generating intermediate proof artifacts leaf..."); + const artifacts1 = await leaf.backend.generateRecursiveProofArtifacts( + innerProof1, + Object.keys(leafParams).length + 1 + ); - simple.backend.destroy(); - // Generate and verify outer proof - const outerInput = { + let pub_inputs: string[] = [ + ...(Object.values(leafParams).map(a => Number(a).toString())), + Number(returnValue).toString() + ]; + + let recurseLeaf: FullNoir = await fullNoirFromCircuit('recurseLeaf'); + + const a = returnValue; + const b = 5; + + const nodeParams = { verification_key: artifacts1.vkAsFields, - public_inputs: ["1"], // expect output of inner call to be "true" + public_inputs: pub_inputs, key_hash: artifacts1.vkHash, - proof1: artifacts1.proofAsFields, - proof2: artifacts2.proofAsFields + proof: artifacts1.proofAsFields, + num: 5 }; - const outerWitness = (await outer.noir.execute( - outerInput - )).witness; - try { - console.log("Generating outer proof..."); - const outerProof: ProofData = await outer.backend.generateProof(outerWitness); - console.log("Verifying outer proof..."); - const res: boolean = await outer.backend.verifyProof(outerProof); - console.log("Verification", res ? "PASSED" : "failed"); - } - catch (e) { - console.log(e); - } - outer.backend.destroy(); + ({ witness, returnValue } = await recurseLeaf.noir.execute(nodeParams)); + console.log("recurseLeaf: %d + %d = ", a, b, Number(returnValue).toString()); + const innerProof2: ProofData = await recurseLeaf.backend.generateProof(witness); + console.log("Generating intermediate proof artifacts recurseLeaf..."); + const artifacts2 = await recurseLeaf.backend.generateRecursiveProofArtifacts( + innerProof2, + Object.keys(nodeParams).length + 1 + ); + console.log("artifacts2 generated."); + + // Generate and verify outer proof + // const outerParams = { + // verification_key: artifacts2.vkAsFields, + // public_inputs: [...(Object.values(nodeParams)), returnValue], // returns proven sum + // key_hash: artifacts2.vkHash, + // proof: artifacts2.proofAsFields + // }; + + // const recurseNode: FullNoir = await fullNoirFromCircuit('recurseNode'); + // ({ witness, returnValue } = await recurseNode.noir.execute(outerParams)); + // console.log("Generating outer proof..."); + // const outerProof: ProofData = await recurseNode.backend.generateProof(witness); + // console.log("Verifying outer proof..."); + // const res: boolean = await recurseNode.backend.verifyProof(outerProof); + // console.log("Verification", res ? "PASSED" : "failed"); + + // recurseNode.backend.destroy(); + recurseLeaf.backend.destroy(); + leaf.backend.destroy(); } start(); diff --git a/how-to/recursive-proofs/package.json b/how-to/recursive-proofs/package.json index 97b5b4d..12850e3 100644 --- a/how-to/recursive-proofs/package.json +++ b/how-to/recursive-proofs/package.json @@ -5,9 +5,10 @@ "compile": "yarn clean && tsc", "start": "node build/main.js", "clean:codegen": "rm -rf codegen", - "export:simple": "nargo export --program-dir=./circuits/not_odd", - "export:recurse": "nargo export --program-dir=./circuits/recurse", - "export:all": "yarn clean:codegen && yarn export:simple && yarn export:recurse", + "export:leaf": "nargo export --program-dir=./circuits/sum", + "export:recurseLeaf": "nargo export --program-dir=./circuits/recurseLeaf", + "export:recurseNode": "nargo export --program-dir=./circuits/recurseNode", + "export:all": "yarn clean:codegen && yarn export:leaf && yarn export:recurseLeaf && yarn export:recurseNode", "codegen": "echo 'skipping' || yarn noir-codegen ./circuits/**/export/*.json", "compile:all": "yarn export:all && yarn codegen && yarn compile" }, From 969dd83c85a468cfe5810edc418a83325b2f0fcc Mon Sep 17 00:00:00 2001 From: James Zaki Date: Fri, 12 Apr 2024 13:53:10 +0100 Subject: [PATCH 13/17] Add verification before failing recursive generation --- how-to/recursive-proofs/main.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/how-to/recursive-proofs/main.ts b/how-to/recursive-proofs/main.ts index 044054f..3bc69a8 100644 --- a/how-to/recursive-proofs/main.ts +++ b/how-to/recursive-proofs/main.ts @@ -71,6 +71,10 @@ async function start() { ({ witness, returnValue } = await recurseLeaf.noir.execute(nodeParams)); console.log("recurseLeaf: %d + %d = ", a, b, Number(returnValue).toString()); const innerProof2: ProofData = await recurseLeaf.backend.generateProof(witness); + console.log("Verifying intermediate proof recurseLeaf..."); + const res: boolean = await recurseLeaf.backend.verifyProof(innerProof2); + console.log("Verification", res ? "PASSED" : "failed"); + console.log("Generating intermediate proof artifacts recurseLeaf..."); const artifacts2 = await recurseLeaf.backend.generateRecursiveProofArtifacts( innerProof2, From ebb3ed13e1cd7a971a62509556b808b7de6fc0e7 Mon Sep 17 00:00:00 2001 From: James Zaki Date: Fri, 12 Apr 2024 16:07:02 +0100 Subject: [PATCH 14/17] fix public input length with hidden size --- how-to/recursive-proofs/main.ts | 46 ++++++++++++++++----------------- 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/how-to/recursive-proofs/main.ts b/how-to/recursive-proofs/main.ts index 3bc69a8..432ca39 100644 --- a/how-to/recursive-proofs/main.ts +++ b/how-to/recursive-proofs/main.ts @@ -38,6 +38,7 @@ async function start() { const leaf: FullNoir = await fullNoirFromCircuit('sum'); const leafParams = { a: 1, b: 3 }; + let numPubInputs = 2; // Generate leaf proof artifacts let { witness, returnValue } = await leaf.noir.execute(leafParams); @@ -46,12 +47,12 @@ async function start() { console.log("Generating intermediate proof artifacts leaf..."); const artifacts1 = await leaf.backend.generateRecursiveProofArtifacts( innerProof1, - Object.keys(leafParams).length + 1 + numPubInputs + 1 // +1 for public return ); let pub_inputs: string[] = [ - ...(Object.values(leafParams).map(a => Number(a).toString())), + ...(Object.values(leafParams).map(n => Number(n).toString())), Number(returnValue).toString() ]; @@ -62,43 +63,40 @@ async function start() { const nodeParams = { verification_key: artifacts1.vkAsFields, - public_inputs: pub_inputs, + public_inputs: pub_inputs, // public, each counted individually key_hash: artifacts1.vkHash, proof: artifacts1.proofAsFields, num: 5 }; + numPubInputs = pub_inputs.length; ({ witness, returnValue } = await recurseLeaf.noir.execute(nodeParams)); console.log("recurseLeaf: %d + %d = ", a, b, Number(returnValue).toString()); const innerProof2: ProofData = await recurseLeaf.backend.generateProof(witness); - console.log("Verifying intermediate proof recurseLeaf..."); - const res: boolean = await recurseLeaf.backend.verifyProof(innerProof2); - console.log("Verification", res ? "PASSED" : "failed"); - console.log("Generating intermediate proof artifacts recurseLeaf..."); const artifacts2 = await recurseLeaf.backend.generateRecursiveProofArtifacts( innerProof2, - Object.keys(nodeParams).length + 1 + numPubInputs + 1 + 16 // +1 for public return +16 for hidden aggregation object ); console.log("artifacts2 generated."); // Generate and verify outer proof - // const outerParams = { - // verification_key: artifacts2.vkAsFields, - // public_inputs: [...(Object.values(nodeParams)), returnValue], // returns proven sum - // key_hash: artifacts2.vkHash, - // proof: artifacts2.proofAsFields - // }; - - // const recurseNode: FullNoir = await fullNoirFromCircuit('recurseNode'); - // ({ witness, returnValue } = await recurseNode.noir.execute(outerParams)); - // console.log("Generating outer proof..."); - // const outerProof: ProofData = await recurseNode.backend.generateProof(witness); - // console.log("Verifying outer proof..."); - // const res: boolean = await recurseNode.backend.verifyProof(outerProof); - // console.log("Verification", res ? "PASSED" : "failed"); - - // recurseNode.backend.destroy(); + const outerParams = { + verification_key: artifacts2.vkAsFields, + public_inputs: [1, 3, 4, returnValue].map.toString(), // returns proven sum + key_hash: artifacts2.vkHash, + proof: artifacts2.proofAsFields + }; + + const recurseNode: FullNoir = await fullNoirFromCircuit('recurseNode'); + ({ witness, returnValue } = await recurseNode.noir.execute(outerParams)); + console.log("Generating outer proof..."); + const outerProof: ProofData = await recurseNode.backend.generateProof(witness); + console.log("Verifying outer proof..."); + const resNode: boolean = await recurseNode.backend.verifyProof(outerProof); + console.log("Verification", resNode ? "PASSED" : "failed"); + + recurseNode.backend.destroy(); recurseLeaf.backend.destroy(); leaf.backend.destroy(); } From 5c72ded4061a11066d6fe6e718ff5ebf86937605 Mon Sep 17 00:00:00 2001 From: James Zaki Date: Fri, 12 Apr 2024 16:39:35 +0100 Subject: [PATCH 15/17] WIP outer proof --- .../recursive-proofs/circuits/recurseNode/src/main.nr | 4 ++-- how-to/recursive-proofs/main.ts | 10 ++++------ 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/how-to/recursive-proofs/circuits/recurseNode/src/main.nr b/how-to/recursive-proofs/circuits/recurseNode/src/main.nr index 109a026..ae4a922 100644 --- a/how-to/recursive-proofs/circuits/recurseNode/src/main.nr +++ b/how-to/recursive-proofs/circuits/recurseNode/src/main.nr @@ -2,7 +2,7 @@ use dep::std; fn main( verification_key: [Field; 114], - public_inputs: pub [Field; 6], + public_inputs: pub [Field; 2], key_hash: Field, proof: [Field; 109] ) -> pub u64 { @@ -13,5 +13,5 @@ fn main( public_inputs.as_slice(), key_hash ); - public_inputs[5] as u64 + public_inputs[1] as u64 } diff --git a/how-to/recursive-proofs/main.ts b/how-to/recursive-proofs/main.ts index 432ca39..4f820b8 100644 --- a/how-to/recursive-proofs/main.ts +++ b/how-to/recursive-proofs/main.ts @@ -36,6 +36,8 @@ type FullNoir = { async function start() { const leaf: FullNoir = await fullNoirFromCircuit('sum'); + const recurseLeaf: FullNoir = await fullNoirFromCircuit('recurseLeaf'); + const recurseNode: FullNoir = await fullNoirFromCircuit('recurseNode'); const leafParams = { a: 1, b: 3 }; let numPubInputs = 2; @@ -50,14 +52,11 @@ async function start() { numPubInputs + 1 // +1 for public return ); - let pub_inputs: string[] = [ ...(Object.values(leafParams).map(n => Number(n).toString())), Number(returnValue).toString() ]; - let recurseLeaf: FullNoir = await fullNoirFromCircuit('recurseLeaf'); - const a = returnValue; const b = 5; @@ -78,17 +77,16 @@ async function start() { innerProof2, numPubInputs + 1 + 16 // +1 for public return +16 for hidden aggregation object ); - console.log("artifacts2 generated."); // Generate and verify outer proof const outerParams = { verification_key: artifacts2.vkAsFields, - public_inputs: [1, 3, 4, returnValue].map.toString(), // returns proven sum + public_inputs: [pub_inputs.map.toString(), returnValue.toString()], // returns proven sum key_hash: artifacts2.vkHash, proof: artifacts2.proofAsFields }; - const recurseNode: FullNoir = await fullNoirFromCircuit('recurseNode'); + console.log("Executing..."); ({ witness, returnValue } = await recurseNode.noir.execute(outerParams)); console.log("Generating outer proof..."); const outerProof: ProofData = await recurseNode.backend.generateProof(witness); From afa349a1e5ca5807fdfca7c40c7a962a09f565b4 Mon Sep 17 00:00:00 2001 From: James Zaki Date: Fri, 12 Apr 2024 17:04:54 +0100 Subject: [PATCH 16/17] Fix execution errors with outer recursive proof --- how-to/recursive-proofs/circuits/recurseNode/src/main.nr | 6 +++--- how-to/recursive-proofs/main.ts | 6 +++++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/how-to/recursive-proofs/circuits/recurseNode/src/main.nr b/how-to/recursive-proofs/circuits/recurseNode/src/main.nr index ae4a922..4a85918 100644 --- a/how-to/recursive-proofs/circuits/recurseNode/src/main.nr +++ b/how-to/recursive-proofs/circuits/recurseNode/src/main.nr @@ -2,9 +2,9 @@ use dep::std; fn main( verification_key: [Field; 114], - public_inputs: pub [Field; 2], + public_inputs: pub [Field; 5], key_hash: Field, - proof: [Field; 109] + proof: [Field; 93] //109 ) -> pub u64 { // verify sum was computed correctly std::verify_proof( @@ -13,5 +13,5 @@ fn main( public_inputs.as_slice(), key_hash ); - public_inputs[1] as u64 + public_inputs[4] as u64 } diff --git a/how-to/recursive-proofs/main.ts b/how-to/recursive-proofs/main.ts index 4f820b8..c697457 100644 --- a/how-to/recursive-proofs/main.ts +++ b/how-to/recursive-proofs/main.ts @@ -77,11 +77,15 @@ async function start() { innerProof2, numPubInputs + 1 + 16 // +1 for public return +16 for hidden aggregation object ); + console.log("artifacts2.proof length = ", artifacts2.proofAsFields.length); + + pub_inputs.push(returnValue.toString()); // leaf returns sum + pub_inputs.push(returnValue.toString()); // node also coded to return same value // Generate and verify outer proof const outerParams = { verification_key: artifacts2.vkAsFields, - public_inputs: [pub_inputs.map.toString(), returnValue.toString()], // returns proven sum + public_inputs: pub_inputs, key_hash: artifacts2.vkHash, proof: artifacts2.proofAsFields }; From 17805dad499ab4b55e1063b1d72cdc418b434689 Mon Sep 17 00:00:00 2001 From: James Zaki Date: Wed, 17 Apr 2024 14:05:37 +0100 Subject: [PATCH 17/17] Document recursive verification example --- how-to/recursive-proofs/README.md | 24 +++++++++---- .../circuits/recurseNode/src/main.nr | 2 +- how-to/recursive-proofs/main.ts | 34 ++++++++++++++----- 3 files changed, 44 insertions(+), 16 deletions(-) diff --git a/how-to/recursive-proofs/README.md b/how-to/recursive-proofs/README.md index eac2f77..c29cd23 100644 --- a/how-to/recursive-proofs/README.md +++ b/how-to/recursive-proofs/README.md @@ -1,13 +1,23 @@ -# Noir recursion +# A minimal example of nested recursion -## Install dependencies +## About -`yarn` +The code in this project shows recursive verification of Noir functions. -## Compile all the things +The primary function is simply addition, and verifies the re-calculation of one path up a binary tree from two leaf nodes. +A more useful application of this design would be proving the hash of data in a merkle tree (leaf nodes), up to the merkle root. Amortizing the cost of proving each hash per nested call. -`yarn compile:all` +## The circuits +The function doing the calculation, in this case addition, is in the sumLib. It is used in both recursive circuits: `sum` and `recursiveLeaf`. -## Run main typescript +## Verification +Results of a call to `sum` are verified in `recursiveLeaf`, which itself also calls `sum` again. The results of the `recursiveLeaf` call are then verified in `recursiveNode`. -`yarn start` +That is: +- `recursiveNode` verifies `recursiveLeaf` artifacts +- `recursiveLeaf` verifies `sum` artifacts + +## Using this project +- Install dependencies: `yarn` +- Compile all the things: `yarn compile:all` +- Run main typescript: `yarn start` diff --git a/how-to/recursive-proofs/circuits/recurseNode/src/main.nr b/how-to/recursive-proofs/circuits/recurseNode/src/main.nr index 4a85918..792c328 100644 --- a/how-to/recursive-proofs/circuits/recurseNode/src/main.nr +++ b/how-to/recursive-proofs/circuits/recurseNode/src/main.nr @@ -4,7 +4,7 @@ fn main( verification_key: [Field; 114], public_inputs: pub [Field; 5], key_hash: Field, - proof: [Field; 93] //109 + proof: [Field; 93] // 109 bytes were supposed to be required to verify recursive proofs (WIP) ) -> pub u64 { // verify sum was computed correctly std::verify_proof( diff --git a/how-to/recursive-proofs/main.ts b/how-to/recursive-proofs/main.ts index c697457..1a64ae1 100644 --- a/how-to/recursive-proofs/main.ts +++ b/how-to/recursive-proofs/main.ts @@ -9,6 +9,7 @@ import { compile, createFileManager } from '@noir-lang/noir_wasm'; import { ProofData } from '@noir-lang/types'; +// Helper function to get compiled Noir program async function getCircuit(name: string) { const basePath = resolve(join('./circuits', name)); const fm = createFileManager(basePath); @@ -21,6 +22,7 @@ async function getCircuit(name: string) { const cores = 12; +// Helper function to create Noir objects async function fullNoirFromCircuit(circuitName: string): Promise { const circuit: CompiledCircuit = await getCircuit(circuitName); const backend: BarretenbergBackend = new BarretenbergBackend(circuit, { threads: cores }); @@ -28,25 +30,39 @@ async function fullNoirFromCircuit(circuitName: string): Promise { return { circuit, backend, noir }; } +// Type to associate related Noir objects type FullNoir = { circuit: CompiledCircuit, backend: BarretenbergBackend, noir: Noir } +// Calculate example sum of two leaf nodes up left branch +// S3 +// S2 9 +// / \ +// / \ +// S1 4 5 +// / \ / \ +// 1 3 # # + + async function start() { - const leaf: FullNoir = await fullNoirFromCircuit('sum'); - const recurseLeaf: FullNoir = await fullNoirFromCircuit('recurseLeaf'); - const recurseNode: FullNoir = await fullNoirFromCircuit('recurseNode'); + // Create Noir objects for each circuit + const leaf: FullNoir = await fullNoirFromCircuit('sum'); // a + b = c + const recurseLeaf: FullNoir = await fullNoirFromCircuit('recurseLeaf'); // verify l1 + l2 = n1, then sum n1 + n2 + const recurseNode: FullNoir = await fullNoirFromCircuit('recurseNode'); // verify n1 + n2 = root1 + + // Generate leaf proof artifacts (S1, addition of 1 and 3) + // Leaf params of left branch const leafParams = { a: 1, b: 3 }; let numPubInputs = 2; - // Generate leaf proof artifacts let { witness, returnValue } = await leaf.noir.execute(leafParams); console.log("leaf: %d + %d = ", ...Object.values(leafParams), Number(returnValue).toString()); const innerProof1: ProofData = await leaf.backend.generateProof(witness); - console.log("Generating intermediate proof artifacts leaf..."); + console.log("Generating intermediate proof artifacts for leaf calculation..."); const artifacts1 = await leaf.backend.generateRecursiveProofArtifacts( innerProof1, numPubInputs + 1 // +1 for public return @@ -58,8 +74,9 @@ async function start() { ]; const a = returnValue; - const b = 5; + const b = 5; // Sum of leaf branches beneath right node + // Generate node proof artifacts (S2: verify 1+3=4 proof, add 5) const nodeParams = { verification_key: artifacts1.vkAsFields, public_inputs: pub_inputs, // public, each counted individually @@ -82,12 +99,12 @@ async function start() { pub_inputs.push(returnValue.toString()); // leaf returns sum pub_inputs.push(returnValue.toString()); // node also coded to return same value - // Generate and verify outer proof + // Generate outer proof artifacts (S3: verify 4+5=9) const outerParams = { verification_key: artifacts2.vkAsFields, public_inputs: pub_inputs, key_hash: artifacts2.vkHash, - proof: artifacts2.proofAsFields + proof: artifacts2.proofAsFields // the proof size of a function that verifies another proof was expected to be 109 bytes, but was still 93 }; console.log("Executing..."); @@ -98,6 +115,7 @@ async function start() { const resNode: boolean = await recurseNode.backend.verifyProof(outerProof); console.log("Verification", resNode ? "PASSED" : "failed"); + // Cleanup recurseNode.backend.destroy(); recurseLeaf.backend.destroy(); leaf.backend.destroy();