From 98725e6946ed76ac002dc17b6fee7982327baf2e Mon Sep 17 00:00:00 2001 From: erhant Date: Fri, 25 Oct 2024 22:48:53 +0300 Subject: [PATCH] example: Bun + SHA256 (#102) * added bun example * add cmdline docs * added witness test * add path check to workflows --- .eslintrc.json | 3 +- .github/workflows/tests.yml | 10 ++ README.md | 2 +- examples/bun-sha256/.gitignore | 122 ++++++++++++++++++ examples/bun-sha256/.vscode/extensions.json | 3 + examples/bun-sha256/.vscode/settings.json | 3 + examples/bun-sha256/README.md | 37 ++++++ examples/bun-sha256/bun.lockb | Bin 0 -> 38543 bytes examples/bun-sha256/circomkit.json | 6 + examples/bun-sha256/circuits.json | 7 + .../bun-sha256/circuits/main/sha256_32.circom | 6 + examples/bun-sha256/circuits/sha256.circom | 42 ++++++ .../bun-sha256/inputs/sha256_32/default.json | 6 + examples/bun-sha256/package.json | 19 +++ examples/bun-sha256/src/index.ts | 37 ++++++ examples/bun-sha256/tests/sha256.test.ts | 54 ++++++++ examples/bun-sha256/tsconfig.json | 26 ++++ 17 files changed, 381 insertions(+), 2 deletions(-) create mode 100644 examples/bun-sha256/.gitignore create mode 100644 examples/bun-sha256/.vscode/extensions.json create mode 100644 examples/bun-sha256/.vscode/settings.json create mode 100644 examples/bun-sha256/README.md create mode 100755 examples/bun-sha256/bun.lockb create mode 100644 examples/bun-sha256/circomkit.json create mode 100644 examples/bun-sha256/circuits.json create mode 100644 examples/bun-sha256/circuits/main/sha256_32.circom create mode 100644 examples/bun-sha256/circuits/sha256.circom create mode 100644 examples/bun-sha256/inputs/sha256_32/default.json create mode 100644 examples/bun-sha256/package.json create mode 100644 examples/bun-sha256/src/index.ts create mode 100644 examples/bun-sha256/tests/sha256.test.ts create mode 100644 examples/bun-sha256/tsconfig.json diff --git a/.eslintrc.json b/.eslintrc.json index 8adee7a..875f9eb 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -32,7 +32,8 @@ "dist", ".vscode", ".github", - "jest.config.js" + "jest.config.js", + "examples" ], "overrides": [ { diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 9b9b242..eaa2d0c 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -4,6 +4,16 @@ on: push: branches: - main + paths: + # Source files + - 'src/**' + - 'tests/**' + # Configurations + - 'circomkit.json' + - 'hardhat.config.ts' + - 'jest.config.js' + # workflow itself + - '.github/workflows/tests.yml' jobs: test: diff --git a/README.md b/README.md index 3b7e0fc..ad2504a 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ You can see available commands with: npx circomkit help ``` -You can check out examples at the [circomkit-examples](https://github.com/erhant/circomkit-examples) repository. +You can check out examples at the [circomkit-examples](https://github.com/erhant/circomkit-examples) repository, or within the [examples](./examples/) directory here. ### Command Line Interface diff --git a/examples/bun-sha256/.gitignore b/examples/bun-sha256/.gitignore new file mode 100644 index 0000000..6b58145 --- /dev/null +++ b/examples/bun-sha256/.gitignore @@ -0,0 +1,122 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# TypeScript v1 declaration files +typings/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env +.env.test + +# parcel-bundler cache (https://parceljs.org/) +.cache + +# Next.js build output +.next + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and *not* Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +# builds +build +dist + +# circuit-specific powers of tau are ignored +*.ptau +# universal ptaus not ignored +!ptau/* +# temporary ptaus are ignored +tmp.ptau + +# is this still a thing lol +.DS_Store + +# ignore auto generated test circuits +circuits/test +ptau diff --git a/examples/bun-sha256/.vscode/extensions.json b/examples/bun-sha256/.vscode/extensions.json new file mode 100644 index 0000000..5fc8eb4 --- /dev/null +++ b/examples/bun-sha256/.vscode/extensions.json @@ -0,0 +1,3 @@ +{ + "recommendations": ["iden3.circom", "oven.bun-vscode"] +} diff --git a/examples/bun-sha256/.vscode/settings.json b/examples/bun-sha256/.vscode/settings.json new file mode 100644 index 0000000..963048a --- /dev/null +++ b/examples/bun-sha256/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "jestrunner.jestCommand": "bun test" +} diff --git a/examples/bun-sha256/README.md b/examples/bun-sha256/README.md new file mode 100644 index 0000000..e3b49bc --- /dev/null +++ b/examples/bun-sha256/README.md @@ -0,0 +1,37 @@ +# Circomkit with Bun + +In this example, we use [Bun](https://bun.sh/) with the [SHA256](https://en.wikipedia.org/wiki/SHA-2) circuit. + +## Installation + +Simply do: + +```sh +bun install +``` + +## Usage + +You can see an example within [`src/index.ts`](./src/index.ts). Run it with: + +```sh +bun start +``` + +For the CLI, you can test the entire flow as follows: + +1. Compile circuit: `bunx circomkit compile sha256_32` +2. Prove with default input: `bunx circomkit prove sha256_32 default` +3. Verify the proof: `bunx circomkit verify sha256_32 default` +4. Create contract: `bunx circomkit contract sha256_32` +5. Create calldata: `bunx circomkit calldata sha256_32 default` + +Notice that we use `bunx` instead of `npx` to use Bun! + +## Testing + +Run tests with: + +```sh +bun test +``` diff --git a/examples/bun-sha256/bun.lockb b/examples/bun-sha256/bun.lockb new file mode 100755 index 0000000000000000000000000000000000000000..8caf48cb022823e3e766ecacc13c0e9bf2b70fc2 GIT binary patch literal 38543 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 literal 0 HcmV?d00001 diff --git a/examples/bun-sha256/circomkit.json b/examples/bun-sha256/circomkit.json new file mode 100644 index 0000000..ded4944 --- /dev/null +++ b/examples/bun-sha256/circomkit.json @@ -0,0 +1,6 @@ +{ + "version": "2.1.2", + "protocol": "groth16", + "curve": "bn128", + "verbose": true +} diff --git a/examples/bun-sha256/circuits.json b/examples/bun-sha256/circuits.json new file mode 100644 index 0000000..9c5678d --- /dev/null +++ b/examples/bun-sha256/circuits.json @@ -0,0 +1,7 @@ +{ + "sha256_32": { + "file": "sha256", + "template": "Sha256Bytes", + "params": [32] + } +} diff --git a/examples/bun-sha256/circuits/main/sha256_32.circom b/examples/bun-sha256/circuits/main/sha256_32.circom new file mode 100644 index 0000000..480112e --- /dev/null +++ b/examples/bun-sha256/circuits/main/sha256_32.circom @@ -0,0 +1,6 @@ +// auto-generated by circomkit +pragma circom 2.1.2; + +include "../sha256.circom"; + +component main = Sha256Bytes(32); diff --git a/examples/bun-sha256/circuits/sha256.circom b/examples/bun-sha256/circuits/sha256.circom new file mode 100644 index 0000000..155b872 --- /dev/null +++ b/examples/bun-sha256/circuits/sha256.circom @@ -0,0 +1,42 @@ +pragma circom 2.0.0; + +include "circomlib/circuits/sha256/sha256.circom"; +include "circomlib/circuits/bitify.circom"; + +/** + * Wrapper around SHA256 to support bytes as input instead of bits + * @param N The number of input bytes + * @input in The input bytes + * @output out The SHA256 output of the n input bytes, in bytes + * + * SOURCE: https://github.com/celer-network/zk-benchmark/blob/main/circom/circuits/sha256/sha256_bytes.circom + */ +template Sha256Bytes(N) { + signal input in[N]; + signal output out[32]; + + // convert input bytes to bits + component byte_to_bits[N]; + for (var i = 0; i < N; i++) { + byte_to_bits[i] = Num2Bits(8); + byte_to_bits[i].in <== in[i]; + } + + // sha256 over bits + component sha256 = Sha256(N*8); + for (var i = 0; i < N; i++) { + for (var j = 0; j < 8; j++) { + sha256.in[i*8+j] <== byte_to_bits[i].out[7-j]; + } + } + + // convert output bytes to bits + component bits_to_bytes[32]; + for (var i = 0; i < 32; i++) { + bits_to_bytes[i] = Bits2Num(8); + for (var j = 0; j < 8; j++) { + bits_to_bytes[i].in[7-j] <== sha256.out[i*8+j]; + } + out[i] <== bits_to_bytes[i].out; + } +} diff --git a/examples/bun-sha256/inputs/sha256_32/default.json b/examples/bun-sha256/inputs/sha256_32/default.json new file mode 100644 index 0000000..8c463ad --- /dev/null +++ b/examples/bun-sha256/inputs/sha256_32/default.json @@ -0,0 +1,6 @@ +{ + "in": [ + 116, 111, 100, 97, 121, 32, 105, 115, 32, 97, 32, 103, 111, 111, 100, 32, 100, 97, 121, 44, 32, 110, 111, 116, 32, + 101, 118, 101, 114, 121, 100, 97 + ] +} diff --git a/examples/bun-sha256/package.json b/examples/bun-sha256/package.json new file mode 100644 index 0000000..16ca2d2 --- /dev/null +++ b/examples/bun-sha256/package.json @@ -0,0 +1,19 @@ +{ + "description": "Circomkit examples", + "scripts": { + "start": "bun run ./src/index.ts", + "test": "bun test" + }, + "dependencies": { + "circomkit": "^0.3.0", + "circomlib": "^2.0.5" + }, + "devDependencies": { + "@types/bun": "latest", + "typescript": "^5.1.3" + }, + "prettier": { + "printWidth": 120, + "singleQuote": true + } +} diff --git a/examples/bun-sha256/src/index.ts b/examples/bun-sha256/src/index.ts new file mode 100644 index 0000000..399ae17 --- /dev/null +++ b/examples/bun-sha256/src/index.ts @@ -0,0 +1,37 @@ +import { createHash } from 'crypto'; +import { Circomkit } from 'circomkit'; + +const PREIMAGE = Buffer.from('bunsbunsbunsbunsbuns'); +const PREIMAGE_BYTES = PREIMAGE.toJSON().data; + +// digest and its byte array +const DIGEST = createHash('sha256').update(new Uint8Array(PREIMAGE)).digest('hex'); +const DIGEST_BYTES = Buffer.from(DIGEST, 'hex').toJSON().data; + +const circomkit = new Circomkit({ + inspect: false, +}); +const circuitName = `sha256_${PREIMAGE_BYTES.length}`; + +console.info('Building circuit...'); +const buildPath = await circomkit.compile(circuitName, { + file: 'sha256', + template: 'Sha256Bytes', + params: [PREIMAGE_BYTES.length], +}); +console.info(`Compiled circuit to ${buildPath}`); + +console.info('Creating a witness...'); +const witnessPath = await circomkit.witness(circuitName, 'bunsbuns', { + in: PREIMAGE_BYTES, +}); +console.info(`Witness created at ${witnessPath}`); + +// https://github.com/oven-sh/bun/issues/11005 +// https://github.com/iden3/snarkjs/pull/490 +console.log('Cant prove with Bun yet!'); +// console.info('Running prover...'); +// const proofPath = await circomkit.prove(circuitName, 'bunsbuns', { +// in: PREIMAGE_BYTES, +// }); +// console.info('Done!'); diff --git a/examples/bun-sha256/tests/sha256.test.ts b/examples/bun-sha256/tests/sha256.test.ts new file mode 100644 index 0000000..a4c4f45 --- /dev/null +++ b/examples/bun-sha256/tests/sha256.test.ts @@ -0,0 +1,54 @@ +import { describe, it, beforeAll } from 'bun:test'; +import { WitnessTester } from 'circomkit'; +import { createHash } from 'crypto'; +import { Circomkit } from 'circomkit'; + +const circomkit = new Circomkit({ verbose: false }); + +describe('sha256', () => { + let circuit: WitnessTester<['in'], ['out']>; + + // number of bytes for the sha256 input + const NUM_BYTES = 36; + + // preimage and its byte array + const PREIMAGE = Buffer.from('today is a good day, not everyday is'); + const PREIMAGE_BYTES = PREIMAGE.toJSON().data; + + // digest and its byte array + const DIGEST = createHash('sha256').update(new Uint8Array(PREIMAGE)).digest('hex'); + const DIGEST_BYTES = Buffer.from(DIGEST, 'hex').toJSON().data; + + // circuit signals + const INPUT = { in: PREIMAGE_BYTES }; + const OUTPUT = { out: DIGEST_BYTES }; + + beforeAll(async () => { + circuit = await circomkit.WitnessTester(`sha256_${NUM_BYTES}`, { + file: 'sha256', + template: 'Sha256Bytes', + params: [NUM_BYTES], + }); + }); + + it('should compute hash correctly', async () => { + await circuit.expectPass(INPUT, OUTPUT); + }); + + it('should pass on correct witness', async () => { + const witness = await circuit.calculateWitness(INPUT); + await circuit.expectConstraintPass(witness); + }); + + it('should fail on fake witness', async () => { + const witness = await circuit.calculateWitness(INPUT); + const badWitness = await circuit.editWitness(witness, { + 'main.sha256.sha256compression[0].sigmaPlus[38].sigma0.out[1]': BigInt(1234), + 'main.sha256.sha256compression[0].sigmaPlus[38].sigma0.out[2]': BigInt(1234), + 'main.sha256.sha256compression[0].sigmaPlus[38].sigma0.out[3]': BigInt(1234), + 'main.sha256.sha256compression[0].sigmaPlus[38].sigma0.out[4]': BigInt(1234), + 'main.sha256.sha256compression[0].sigmaPlus[38].sigma0.out[5]': BigInt(1234), + }); + await circuit.expectConstraintFail(badWitness); + }); +}); diff --git a/examples/bun-sha256/tsconfig.json b/examples/bun-sha256/tsconfig.json new file mode 100644 index 0000000..fd521c7 --- /dev/null +++ b/examples/bun-sha256/tsconfig.json @@ -0,0 +1,26 @@ +{ + "compilerOptions": { + // Enable latest features + "lib": ["ESNext"], + "target": "ESNext", + "module": "ESNext", + "moduleDetection": "force", + "allowJs": true, + + // Bundler mode + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "noEmit": true, + + // Best practices + "strict": true, + "skipLibCheck": true, + "noFallthroughCasesInSwitch": true, + + // Some stricter flags (disabled by default) + "noUnusedLocals": false, + "noUnusedParameters": false, + "noPropertyAccessFromIndexSignature": false + } +}