Merge pull request #1264 from Zokrates/optimize-js-lib
Optimize js library size
This commit is contained in:
commit
478b555371
20 changed files with 8414 additions and 379 deletions
|
@ -119,11 +119,13 @@ jobs:
|
|||
- setup-sccache
|
||||
- restore-sccache-cache
|
||||
- run:
|
||||
name: Check format
|
||||
command: cargo fmt --all -- --check
|
||||
- run:
|
||||
name: Run clippy
|
||||
command: cargo clippy -- -D warnings
|
||||
name: Install headless chrome dependencies
|
||||
command: |
|
||||
apt-get update && apt-get install -yq \
|
||||
ca-certificates fonts-liberation libasound2 libatk-bridge2.0-0 libatk1.0-0 libc6 libcairo2 libcups2 \
|
||||
libdbus-1-3 libexpat1 libfontconfig1 libgbm1 libgcc1 libglib2.0-0 libgtk-3-0 libnspr4 libnss3 \
|
||||
libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 \
|
||||
libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 lsb-release wget xdg-utils
|
||||
- run:
|
||||
name: Run tests
|
||||
no_output_timeout: "30m"
|
||||
|
|
6
Cargo.lock
generated
6
Cargo.lock
generated
|
@ -1270,9 +1270,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.7"
|
||||
version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6"
|
||||
checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"js-sys",
|
||||
|
@ -3258,6 +3258,7 @@ name = "zokrates_js"
|
|||
version = "1.1.4"
|
||||
dependencies = [
|
||||
"console_error_panic_hook",
|
||||
"getrandom",
|
||||
"indexmap",
|
||||
"js-sys",
|
||||
"json",
|
||||
|
@ -3344,6 +3345,7 @@ dependencies = [
|
|||
name = "zokrates_test"
|
||||
version = "0.2.0"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
|
|
1
changelogs/unreleased/1264-dark64
Normal file
1
changelogs/unreleased/1264-dark64
Normal file
|
@ -0,0 +1 @@
|
|||
Optimize `zokrates-js` library size
|
|
@ -15,8 +15,8 @@ zokrates_proof_systems = { version = "0.1", path = "../zokrates_proof_systems",
|
|||
bellman = { package = "bellman_ce", version = "^0.3", default-features = false }
|
||||
pairing = { package = "pairing_ce", version = "^0.21" }
|
||||
phase2 = { git = "https://github.com/Zokrates/phase2", default-features = false }
|
||||
rand_0_4 = { version = "0.4", package = "rand" }#
|
||||
getrandom = { version = "0.2", features = ["js", "wasm-bindgen"] }
|
||||
rand_0_4 = { version = "0.4", package = "rand" }
|
||||
getrandom = { version = "0.2.8" }
|
||||
hex = "0.4.2"
|
||||
|
||||
[dev-dependencies]
|
||||
|
|
|
@ -8,113 +8,135 @@ npm install zokrates-js
|
|||
|
||||
## Importing
|
||||
|
||||
##### Bundlers
|
||||
**Note:** As this library uses a model where the wasm module itself is natively an ES module, you will need a bundler of some form.
|
||||
Currently the only known bundler known to be fully compatible with `zokrates-js` is [Webpack](https://webpack.js.org/) (`experiments.syncWebAssembly` must be enabled).
|
||||
The choice of this default was done to reflect the trends of the JS ecosystem.
|
||||
#### ES modules
|
||||
|
||||
```js
|
||||
import { initialize } from 'zokrates-js';
|
||||
import { initialize } from "zokrates-js";
|
||||
```
|
||||
|
||||
##### Node
|
||||
#### CommonJS
|
||||
|
||||
```js
|
||||
const { initialize } = require('zokrates-js')
|
||||
let { initialize } = await import("zokrates-js");
|
||||
```
|
||||
|
||||
#### CDN
|
||||
|
||||
```html
|
||||
<script src="https://unpkg.com/zokrates-js@latest/umd.min.js"></script>
|
||||
<script>
|
||||
zokrates.initialize().then((zokratesProvider) => {
|
||||
/* ... */
|
||||
});
|
||||
</script>
|
||||
```
|
||||
|
||||
## Example
|
||||
|
||||
```js
|
||||
initialize().then((zokratesProvider) => {
|
||||
const source = "def main(private field a) -> field { return a * a; }";
|
||||
const source = "def main(private field a) -> field { return a * a; }";
|
||||
|
||||
// compilation
|
||||
const artifacts = zokratesProvider.compile(source);
|
||||
// compilation
|
||||
const artifacts = zokratesProvider.compile(source);
|
||||
|
||||
// computation
|
||||
const { witness, output } = zokratesProvider.computeWitness(artifacts, ["2"]);
|
||||
// computation
|
||||
const { witness, output } = zokratesProvider.computeWitness(artifacts, ["2"]);
|
||||
|
||||
// run setup
|
||||
const keypair = zokratesProvider.setup(artifacts.program);
|
||||
// run setup
|
||||
const keypair = zokratesProvider.setup(artifacts.program);
|
||||
|
||||
// generate proof
|
||||
const proof = zokratesProvider.generateProof(artifacts.program, witness, keypair.pk);
|
||||
// generate proof
|
||||
const proof = zokratesProvider.generateProof(
|
||||
artifacts.program,
|
||||
witness,
|
||||
keypair.pk
|
||||
);
|
||||
|
||||
// export solidity verifier
|
||||
const verifier = zokratesProvider.exportSolidityVerifier(keypair.vk);
|
||||
|
||||
// or verify off-chain
|
||||
const isVerified = zokratesProvider.verify(keypair.vk, proof);
|
||||
// export solidity verifier
|
||||
const verifier = zokratesProvider.exportSolidityVerifier(keypair.vk);
|
||||
|
||||
// or verify off-chain
|
||||
const isVerified = zokratesProvider.verify(keypair.vk, proof);
|
||||
});
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
##### initialize()
|
||||
|
||||
Returns an initialized `ZoKratesProvider` as a promise.
|
||||
|
||||
```js
|
||||
initialize().then((zokratesProvider) => {
|
||||
// call api functions here
|
||||
initialize().then((zokratesProvider) => {
|
||||
// call api functions here
|
||||
});
|
||||
```
|
||||
|
||||
Returns: `Promise<ZoKratesProvider>`
|
||||
|
||||
##### withOptions(options)
|
||||
|
||||
Returns a `ZoKratesProvider` configured with given options.
|
||||
|
||||
```js
|
||||
initialize().then((defaultProvider) => {
|
||||
let zokratesProvider = defaultProvider.withOptions({
|
||||
backend: "ark",
|
||||
curve: "bls12_381",
|
||||
scheme: "g16"
|
||||
});
|
||||
// ...
|
||||
initialize().then((defaultProvider) => {
|
||||
let zokratesProvider = defaultProvider.withOptions({
|
||||
backend: "ark",
|
||||
curve: "bls12_381",
|
||||
scheme: "g16",
|
||||
});
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
Options:
|
||||
* `backend` - Backend (options: `ark` | `bellman`, default: `ark`)
|
||||
* `curve` - Elliptic curve (options: `bn128` | `bls12_381` | `bls12_377` | `bw6_761`, default: `bn128`)
|
||||
* `scheme` - Proving scheme (options: `g16` | `gm17` | `marlin`, default: `g16`)
|
||||
|
||||
- `backend` - Backend (options: `ark` | `bellman`, default: `ark`)
|
||||
- `curve` - Elliptic curve (options: `bn128` | `bls12_381` | `bls12_377` | `bw6_761`, default: `bn128`)
|
||||
- `scheme` - Proving scheme (options: `g16` | `gm17` | `marlin`, default: `g16`)
|
||||
|
||||
Returns: `ZoKratesProvider`
|
||||
|
||||
##### compile(source[, options])
|
||||
|
||||
Compiles source code into ZoKrates internal representation of arithmetic circuits.
|
||||
|
||||
Parameters:
|
||||
* `source` - Source code to compile
|
||||
* `options` - Compilation options
|
||||
|
||||
- `source` - Source code to compile
|
||||
- `options` - Compilation options
|
||||
|
||||
Returns: `CompilationArtifacts`
|
||||
|
||||
**Examples:**
|
||||
|
||||
Compilation:
|
||||
|
||||
```js
|
||||
const artifacts = zokratesProvider.compile("def main() { return; }");
|
||||
```
|
||||
|
||||
Compilation with custom options:
|
||||
|
||||
```js
|
||||
const source = "...";
|
||||
const options = {
|
||||
location: "main.zok", // location of the root module
|
||||
resolveCallback: (currentLocation, importLocation) => {
|
||||
console.log(currentLocation + ' is importing ' + importLocation);
|
||||
return {
|
||||
source: "def main() { return; }",
|
||||
location: importLocation
|
||||
};
|
||||
}
|
||||
location: "main.zok", // location of the root module
|
||||
resolveCallback: (currentLocation, importLocation) => {
|
||||
console.log(currentLocation + " is importing " + importLocation);
|
||||
return {
|
||||
source: "def main() { return; }",
|
||||
location: importLocation,
|
||||
};
|
||||
},
|
||||
};
|
||||
const artifacts = zokratesProvider.compile(source, options);
|
||||
```
|
||||
|
||||
**Note:** The `resolveCallback` function is used to resolve dependencies.
|
||||
This callback receives the current module location and the import location of the module which is being imported.
|
||||
The callback must synchronously return either an error, `null` or a valid `ResolverResult` object like shown in the example above.
|
||||
**Note:** The `resolveCallback` function is used to resolve dependencies.
|
||||
This callback receives the current module location and the import location of the module which is being imported.
|
||||
The callback must synchronously return either an error, `null` or a valid `ResolverResult` object like shown in the example above.
|
||||
A simple file system resolver for a node environment can be implemented as follows:
|
||||
|
||||
```js
|
||||
|
@ -129,19 +151,21 @@ const fileSystemResolver = (from, to) => {
|
|||
```
|
||||
|
||||
##### computeWitness(artifacts, args[, options])
|
||||
|
||||
Computes a valid assignment of the variables, which include the results of the computation.
|
||||
|
||||
Parameters:
|
||||
* `artifacts` - Compilation artifacts
|
||||
* `args` - Array of arguments (eg. `["1", "2", true]`)
|
||||
* `options` - Computation options
|
||||
|
||||
- `artifacts` - Compilation artifacts
|
||||
- `args` - Array of arguments (eg. `["1", "2", true]`)
|
||||
- `options` - Computation options
|
||||
|
||||
Returns: `ComputationResult`
|
||||
|
||||
**Example:**
|
||||
|
||||
```js
|
||||
const code = 'def main(private field a) -> field { return a * a; }';
|
||||
const code = "def main(private field a) -> field { return a * a; }";
|
||||
const artifacts = zokratesProvider.compile(code);
|
||||
|
||||
const { witness, output } = zokratesProvider.computeWitness(artifacts, ["2"]);
|
||||
|
@ -151,53 +175,75 @@ console.log(output); // Computation output: "4"
|
|||
```
|
||||
|
||||
##### setup(program)
|
||||
|
||||
Generates a trusted setup for the compiled program.
|
||||
|
||||
Parameters:
|
||||
* `program` - Compiled program
|
||||
|
||||
- `program` - Compiled program
|
||||
|
||||
Returns: `SetupKeypair`
|
||||
|
||||
##### universalSetup(size)
|
||||
|
||||
Performs the universal phase of a trusted setup. Only available for the `marlin` scheme.
|
||||
|
||||
Parameters:
|
||||
* `size` - Size of the trusted setup passed as an exponent. For example, `8` for `2**8`.
|
||||
|
||||
- `size` - Size of the trusted setup passed as an exponent. For example, `8` for `2**8`.
|
||||
|
||||
Returns: `Uint8Array`
|
||||
|
||||
##### setupWithSrs(srs, program)
|
||||
|
||||
Generates a trusted setup with universal public parameters for the compiled program. Only available for `marlin` scheme.
|
||||
|
||||
Parameters:
|
||||
* `srs` - Universal public parameters from the universal setup phase
|
||||
* `program` - Compiled program
|
||||
|
||||
- `srs` - Universal public parameters from the universal setup phase
|
||||
- `program` - Compiled program
|
||||
|
||||
Returns: `SetupKeypair`
|
||||
|
||||
##### generateProof(program, witness, provingKey)
|
||||
|
||||
Generates a proof for a computation of the compiled program.
|
||||
|
||||
Parameters:
|
||||
* `program` - Compiled program
|
||||
* `witness` - Witness (valid assignment of the variables) from the computation result
|
||||
* `provingKey` - Proving key from the setup keypair
|
||||
|
||||
- `program` - Compiled program
|
||||
- `witness` - Witness (valid assignment of the variables) from the computation result
|
||||
- `provingKey` - Proving key from the setup keypair
|
||||
|
||||
Returns: `Proof`
|
||||
|
||||
##### verify(verificationKey, proof)
|
||||
|
||||
Verifies the generated proof.
|
||||
|
||||
Parameters:
|
||||
* `verificationKey` - Verification key from the setup keypair
|
||||
* `proof` - Generated proof
|
||||
|
||||
- `verificationKey` - Verification key from the setup keypair
|
||||
- `proof` - Generated proof
|
||||
|
||||
Returns: `boolean`
|
||||
|
||||
##### exportSolidityVerifier(verificationKey)
|
||||
|
||||
Generates a Solidity contract which contains the generated verification key and a public function to verify proofs of computation of the compiled program.
|
||||
|
||||
Parameters:
|
||||
* `verificationKey` - Verification key from the setup keypair
|
||||
|
||||
- `verificationKey` - Verification key from the setup keypair
|
||||
|
||||
Returns: `string`
|
||||
|
||||
##### utils.formatProof(proof)
|
||||
|
||||
Formats the proof into an array of field elements that are compatible as input to the generated solidity contract
|
||||
|
||||
Parameters:
|
||||
|
||||
- `proof` - Generated proof
|
||||
|
||||
Returns: `array`
|
||||
|
|
6
zokrates_js/.gitignore
vendored
6
zokrates_js/.gitignore
vendored
|
@ -3,6 +3,6 @@ dist
|
|||
target
|
||||
pkg
|
||||
wasm-pack.log
|
||||
stdlib
|
||||
stdlib.js
|
||||
metadata.js
|
||||
metadata.js
|
||||
wasm.js
|
||||
umd.min.js
|
|
@ -26,6 +26,7 @@ zokrates_abi = { path = "../zokrates_abi", default-features = false, features =
|
|||
zokrates_circom = { path = "../zokrates_circom" }
|
||||
console_error_panic_hook = "0.1.6"
|
||||
indexmap = "~1.6.2" # see https://github.com/rustwasm/wasm-bindgen/issues/2770#issuecomment-1041102532
|
||||
getrandom = { version = "0.2.8", features = ["js"] }
|
||||
|
||||
[build-dependencies]
|
||||
json = "0.12.4"
|
||||
|
|
|
@ -40,9 +40,5 @@ fn export_metadata() {
|
|||
.insert("version", config["package"]["version"].as_str().unwrap())
|
||||
.unwrap();
|
||||
|
||||
fs::write(
|
||||
"metadata.js",
|
||||
format!("module.exports = {}", metadata.dump()),
|
||||
)
|
||||
.unwrap();
|
||||
fs::write("metadata.js", format!("export default {}", metadata.dump())).unwrap();
|
||||
}
|
||||
|
|
5
zokrates_js/index-node.js
Normal file
5
zokrates_js/index-node.js
Normal file
|
@ -0,0 +1,5 @@
|
|||
// https://docs.rs/getrandom/0.2.8/getrandom/index.html#nodejs-es-module-support
|
||||
import { webcrypto } from "node:crypto";
|
||||
globalThis.crypto = webcrypto;
|
||||
|
||||
export * from "./index.js";
|
|
@ -1,9 +1,126 @@
|
|||
import lib from "./lib.js";
|
||||
import { inflate } from "pako";
|
||||
import metadata from "./metadata.js";
|
||||
import * as wasmExports from "./wasm.js";
|
||||
|
||||
const initialize = async () => {
|
||||
const pkg = await import("./pkg/index.js");
|
||||
return lib(pkg);
|
||||
await wasmExports.init(inflate);
|
||||
|
||||
const defaultProvider = {
|
||||
compile: (source, compileOptions = {}) => {
|
||||
var {
|
||||
curve = "bn128",
|
||||
location = "main.zok",
|
||||
resolveCallback = () => null,
|
||||
config = {},
|
||||
snarkjs = false,
|
||||
} = compileOptions;
|
||||
|
||||
config = { snarkjs, ...config };
|
||||
|
||||
const ptr = wasmExports.compile(
|
||||
source,
|
||||
location,
|
||||
resolveCallback,
|
||||
config,
|
||||
curve
|
||||
);
|
||||
const result = Object.assign(
|
||||
{
|
||||
program: ptr.program(),
|
||||
abi: ptr.abi(),
|
||||
constraintCount: ptr.constraint_count(),
|
||||
},
|
||||
snarkjs ? { snarkjs: { program: ptr.snarkjs_program() } } : {}
|
||||
);
|
||||
ptr.free();
|
||||
return result;
|
||||
},
|
||||
computeWitness: (input, args, computeOptions = {}) => {
|
||||
const { program, abi } =
|
||||
input instanceof Uint8Array ? { program: input, abi: null } : input;
|
||||
|
||||
const { snarkjs = false, logCallback = console.log } = computeOptions;
|
||||
const ptr = wasmExports.compute_witness(
|
||||
program,
|
||||
abi,
|
||||
JSON.stringify(args),
|
||||
{
|
||||
snarkjs: snarkjs,
|
||||
},
|
||||
logCallback
|
||||
);
|
||||
|
||||
const result = Object.assign(
|
||||
{
|
||||
witness: ptr.witness(),
|
||||
output: ptr.output(),
|
||||
},
|
||||
snarkjs
|
||||
? {
|
||||
snarkjs: {
|
||||
witness: ptr.snarkjs_witness(),
|
||||
},
|
||||
}
|
||||
: {}
|
||||
);
|
||||
|
||||
ptr.free();
|
||||
return result;
|
||||
},
|
||||
setup: (program, options) => {
|
||||
return wasmExports.setup(program, options);
|
||||
},
|
||||
universalSetup: (curve, size) => {
|
||||
return wasmExports.universal_setup(curve, size);
|
||||
},
|
||||
setupWithSrs: (srs, program, options) => {
|
||||
return wasmExports.setup_with_srs(srs, program, options);
|
||||
},
|
||||
generateProof: (program, witness, provingKey, options) => {
|
||||
return wasmExports.generate_proof(program, witness, provingKey, options);
|
||||
},
|
||||
verify: (vk, proof, options) => {
|
||||
return wasmExports.verify(vk, proof, options);
|
||||
},
|
||||
exportSolidityVerifier: (vk) => {
|
||||
return wasmExports.export_solidity_verifier(vk);
|
||||
},
|
||||
utils: {
|
||||
formatProof: (proof) => {
|
||||
return wasmExports.format_proof(proof);
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const withOptions = (options) => {
|
||||
return {
|
||||
withOptions,
|
||||
compile: (source, compileOptions = {}) =>
|
||||
defaultProvider.compile(source, {
|
||||
...compileOptions,
|
||||
curve: options.curve,
|
||||
}),
|
||||
computeWitness: (artifacts, args, computeOptions = {}) =>
|
||||
defaultProvider.computeWitness(artifacts, args, computeOptions),
|
||||
setup: (program) => defaultProvider.setup(program, options),
|
||||
universalSetup: (size) =>
|
||||
defaultProvider.universalSetup(options.curve, size),
|
||||
setupWithSrs: (srs, program) =>
|
||||
defaultProvider.setupWithSrs(srs, program, options),
|
||||
generateProof: (program, witness, provingKey) =>
|
||||
defaultProvider.generateProof(program, witness, provingKey, options),
|
||||
verify: (vk, proof) => defaultProvider.verify(vk, proof, options),
|
||||
exportSolidityVerifier: (vk) =>
|
||||
defaultProvider.exportSolidityVerifier(vk),
|
||||
utils: {
|
||||
formatProof: (proof) => defaultProvider.utils.formatProof(proof),
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
return {
|
||||
...withOptions({ backend: "ark", scheme: "g16", curve: "bn128" }),
|
||||
};
|
||||
};
|
||||
|
||||
export { initialize, metadata };
|
||||
|
|
|
@ -1,112 +0,0 @@
|
|||
module.exports = (pkg) => {
|
||||
const defaultProvider = {
|
||||
compile: (source, compileOptions = {}) => {
|
||||
var {
|
||||
curve = "bn128",
|
||||
location = "main.zok",
|
||||
resolveCallback = () => null,
|
||||
config = {},
|
||||
snarkjs = false,
|
||||
} = compileOptions;
|
||||
|
||||
config = { snarkjs, ...config };
|
||||
|
||||
const ptr = pkg.compile(source, location, resolveCallback, config, curve);
|
||||
const result = Object.assign(
|
||||
{
|
||||
program: ptr.program(),
|
||||
abi: ptr.abi(),
|
||||
constraintCount: ptr.constraint_count(),
|
||||
},
|
||||
snarkjs ? { snarkjs: { program: ptr.snarkjs_program() } } : {}
|
||||
);
|
||||
ptr.free();
|
||||
return result;
|
||||
},
|
||||
computeWitness: (input, args, computeOptions = {}) => {
|
||||
const { program, abi } =
|
||||
input instanceof Uint8Array ? { program: input, abi: null } : input;
|
||||
|
||||
const { snarkjs = false, logCallback = console.log } = computeOptions;
|
||||
const ptr = pkg.compute_witness(
|
||||
program,
|
||||
abi,
|
||||
JSON.stringify(args),
|
||||
{
|
||||
snarkjs: snarkjs,
|
||||
},
|
||||
logCallback
|
||||
);
|
||||
|
||||
const result = Object.assign(
|
||||
{
|
||||
witness: ptr.witness(),
|
||||
output: ptr.output(),
|
||||
},
|
||||
snarkjs
|
||||
? {
|
||||
snarkjs: {
|
||||
witness: ptr.snarkjs_witness(),
|
||||
},
|
||||
}
|
||||
: {}
|
||||
);
|
||||
|
||||
ptr.free();
|
||||
return result;
|
||||
},
|
||||
setup: (program, options) => {
|
||||
return pkg.setup(program, options);
|
||||
},
|
||||
universalSetup: (curve, size) => {
|
||||
return pkg.universal_setup(curve, size);
|
||||
},
|
||||
setupWithSrs: (srs, program, options) => {
|
||||
return pkg.setup_with_srs(srs, program, options);
|
||||
},
|
||||
generateProof: (program, witness, provingKey, options) => {
|
||||
return pkg.generate_proof(program, witness, provingKey, options);
|
||||
},
|
||||
verify: (vk, proof, options) => {
|
||||
return pkg.verify(vk, proof, options);
|
||||
},
|
||||
exportSolidityVerifier: (vk) => {
|
||||
return pkg.export_solidity_verifier(vk);
|
||||
},
|
||||
utils: {
|
||||
formatProof: (proof) => {
|
||||
return pkg.format_proof(proof);
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const withOptions = (options) => {
|
||||
return {
|
||||
withOptions,
|
||||
compile: (source, compileOptions = {}) =>
|
||||
defaultProvider.compile(source, {
|
||||
...compileOptions,
|
||||
curve: options.curve,
|
||||
}),
|
||||
computeWitness: (artifacts, args, computeOptions = {}) =>
|
||||
defaultProvider.computeWitness(artifacts, args, computeOptions),
|
||||
setup: (program) => defaultProvider.setup(program, options),
|
||||
universalSetup: (size) =>
|
||||
defaultProvider.universalSetup(options.curve, size),
|
||||
setupWithSrs: (srs, program) =>
|
||||
defaultProvider.setupWithSrs(srs, program, options),
|
||||
generateProof: (program, witness, provingKey) =>
|
||||
defaultProvider.generateProof(program, witness, provingKey, options),
|
||||
verify: (vk, proof) => defaultProvider.verify(vk, proof, options),
|
||||
exportSolidityVerifier: (vk) =>
|
||||
defaultProvider.exportSolidityVerifier(vk),
|
||||
utils: {
|
||||
formatProof: (proof) => defaultProvider.utils.formatProof(proof),
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
return {
|
||||
...withOptions({ backend: "ark", scheme: "g16", curve: "bn128" }),
|
||||
};
|
||||
};
|
|
@ -1,8 +0,0 @@
|
|||
const lib = require("../lib.js");
|
||||
const metadata = require("../metadata.js");
|
||||
|
||||
const initialize = async () => {
|
||||
return lib(require("./pkg/index.js"));
|
||||
};
|
||||
|
||||
module.exports = { initialize, metadata };
|
8133
zokrates_js/package-lock.json
generated
8133
zokrates_js/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -2,7 +2,7 @@
|
|||
"name": "zokrates-js",
|
||||
"version": "1.1.4",
|
||||
"module": "index.js",
|
||||
"main": "node/index.js",
|
||||
"main": "index-node.js",
|
||||
"description": "JavaScript bindings for ZoKrates",
|
||||
"contributors": [
|
||||
"Darko Macesic <darem966@gmail.com>",
|
||||
|
@ -15,38 +15,46 @@
|
|||
],
|
||||
"license": "GPLv3",
|
||||
"files": [
|
||||
"node",
|
||||
"pkg",
|
||||
"index.js",
|
||||
"index-node.js",
|
||||
"index.d.ts",
|
||||
"lib.js",
|
||||
"metadata.js"
|
||||
"wasm.js",
|
||||
"metadata.js",
|
||||
"umd.min.js"
|
||||
],
|
||||
"types": "index.d.ts",
|
||||
"type": "module",
|
||||
"exports": {
|
||||
"node": "./node/index.js",
|
||||
"node": "./index-node.js",
|
||||
"default": "./index.js"
|
||||
},
|
||||
"scripts": {
|
||||
"wasm-pack": "wasm-pack build --out-name index",
|
||||
"wasm-pack": "wasm-pack build --out-name index --target web",
|
||||
"prebuild": "npm install",
|
||||
"build": "npm run build:bundler && npm run build:node",
|
||||
"build:dev": "npm run build:bundler:dev && npm run build:node:dev",
|
||||
"build:bundler": "rimraf pkg && npm run wasm-pack -- --target bundler --release && npm run clean-pkg",
|
||||
"build:bundler:dev": "rimraf pkg && npm run wasm-pack -- --target bundler --dev && npm run clean-pkg",
|
||||
"build:node": "rimraf node/pkg && npm run wasm-pack -- --target nodejs -d node/pkg --release && npm run clean-node-pkg",
|
||||
"build:node:dev": "rimraf node/pkg && npm run wasm-pack -- --target nodejs -d node/pkg --dev && npm run clean-node-pkg",
|
||||
"clean-pkg": "rimraf pkg/README.md pkg/.gitignore pkg/package.json pkg/*.d.ts",
|
||||
"clean-node-pkg": "rimraf node/pkg/README.md node/pkg/.gitignore node/pkg/package.json node/pkg/*.d.ts",
|
||||
"pretest": "npm run build:node:dev",
|
||||
"build": "npm run wasm-pack -- --release && npm run patch && npm run bundle",
|
||||
"build:dev": "npm run wasm-pack -- --dev && npm run patch && npm run bundle",
|
||||
"pretest": "npm run build:dev",
|
||||
"test": "npm run run-tests",
|
||||
"run-tests": "mocha --timeout 100000 --recursive tests"
|
||||
"run-tests": "mocha --timeout 100000 --recursive tests",
|
||||
"patch": "node patch.js",
|
||||
"bundle": "browserify ./index.js --standalone zokrates -t [ babelify --presets [ @babel/preset-env ] ] | uglifyjs --compress --mangle > umd.min.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"dree": "^2.6.1",
|
||||
"@babel/core": "^7.20.12",
|
||||
"@babel/preset-env": "^7.20.2",
|
||||
"acorn": "^8.8.1",
|
||||
"astring": "^1.8.4",
|
||||
"babelify": "^10.0.0",
|
||||
"browserify": "^17.0.0",
|
||||
"dree": "^3.4.3",
|
||||
"mocha": "^9.2.0",
|
||||
"puppeteer": "^19.6.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"snarkjs": "^0.4.25",
|
||||
"uglify-js": "^3.17.4",
|
||||
"wasm-pack": "^0.10.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"pako": "^2.1.0"
|
||||
}
|
||||
}
|
||||
|
|
75
zokrates_js/patch.js
Normal file
75
zokrates_js/patch.js
Normal file
|
@ -0,0 +1,75 @@
|
|||
import { parse } from "acorn";
|
||||
import { generate } from "astring";
|
||||
import fs from "fs/promises";
|
||||
import pako from "pako";
|
||||
|
||||
(async function () {
|
||||
const packageObject = JSON.parse(
|
||||
await fs.readFile("pkg/package.json", { encoding: "utf-8" })
|
||||
);
|
||||
const wasmPath = packageObject.files.find((file) => file.endsWith(".wasm"));
|
||||
const wasm = await fs.readFile(`pkg/${wasmPath}`);
|
||||
|
||||
const deflated = Buffer.from(pako.deflate(wasm));
|
||||
const wasmBase64 = deflated.toString("base64");
|
||||
|
||||
const init = `export async function init(inflate) {
|
||||
const encoded = '${wasmBase64}';
|
||||
|
||||
let bytes;
|
||||
|
||||
if (typeof Buffer === "function") {
|
||||
bytes = Buffer.from(encoded, "base64");
|
||||
} else if (typeof atob === "function") {
|
||||
const binary = atob(encoded);
|
||||
bytes = new Uint8Array(binary.length);
|
||||
|
||||
for (let i = 0; i < binary.length; i++) {
|
||||
bytes[i] = binary.charCodeAt(i);
|
||||
}
|
||||
} else {
|
||||
throw new Error("Unsupported platform");
|
||||
}
|
||||
|
||||
const imports = getImports();
|
||||
initMemory(imports);
|
||||
|
||||
bytes = inflate(bytes);
|
||||
|
||||
const { instance, module } = await WebAssembly.instantiate(bytes, imports);
|
||||
return finalizeInit(instance, module);
|
||||
}
|
||||
|
||||
export default init;`;
|
||||
|
||||
const generatedSource = await fs.readFile(`pkg/${packageObject.module}`, {
|
||||
encoding: "utf-8",
|
||||
});
|
||||
|
||||
const ast = parse(generatedSource, {
|
||||
ecmaVersion: "latest",
|
||||
sourceType: "module",
|
||||
});
|
||||
|
||||
let body = ast.body.filter((v) => {
|
||||
switch (v.type) {
|
||||
case "FunctionDeclaration":
|
||||
// we don't use these functions so we strip them out
|
||||
return !["load", "init", "initSync"].includes(v.id.name);
|
||||
case "ExportDefaultDeclaration":
|
||||
// we will provide our own default export
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
body.pop(); // removes `export { initSync }`
|
||||
|
||||
const source = generate({
|
||||
...ast,
|
||||
body,
|
||||
});
|
||||
|
||||
await fs.writeFile("wasm.js", source + init);
|
||||
})();
|
|
@ -24,12 +24,6 @@ if [ $NPM_VERSION = $PACKAGE_VERSION ]; then
|
|||
exit 0
|
||||
fi
|
||||
|
||||
# make sure the pkg folder is present
|
||||
if [ ! -d "pkg" ]; then
|
||||
echo "pkg folder is missing"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# publish
|
||||
npm set //registry.npmjs.org/:_authToken=${NPM_TOKEN}
|
||||
npm publish
|
|
@ -1,10 +1,10 @@
|
|||
const assert = require("assert");
|
||||
const path = require("path");
|
||||
const fs = require("fs");
|
||||
const os = require("os");
|
||||
const dree = require("dree");
|
||||
const snarkjs = require("snarkjs");
|
||||
const { initialize, metadata } = require("../node/index.js");
|
||||
import assert from "assert";
|
||||
import path from "path";
|
||||
import fs from "fs";
|
||||
import os from "os";
|
||||
import * as snarkjs from "snarkjs";
|
||||
import dree from "dree";
|
||||
import { initialize, metadata } from "../index-node.js";
|
||||
|
||||
let zokratesProvider;
|
||||
let tmpFolder;
|
||||
|
@ -364,8 +364,8 @@ describe("tests", () => {
|
|||
extensions: ["json"],
|
||||
};
|
||||
|
||||
dree.scan(testsPath, options, function (file) {
|
||||
const test = require(file.path);
|
||||
dree.scan(testsPath, options, async function (file) {
|
||||
const test = JSON.parse(await fs.promises.readFile(file.path));
|
||||
const testName = file.path.substring(testsPath.length + 1);
|
||||
|
||||
if (!ignoreList.some((v) => testName.startsWith(v)))
|
||||
|
|
38
zokrates_js/tests/umd/index.html
Normal file
38
zokrates_js/tests/umd/index.html
Normal file
|
@ -0,0 +1,38 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Test Document</title>
|
||||
</head>
|
||||
<body>
|
||||
<script src="../../umd.min.js"></script>
|
||||
<script>
|
||||
zokrates.initialize().then((zokratesProvider) => {
|
||||
const source = "def main(private field a) -> field { return a * a; }";
|
||||
|
||||
const artifacts = zokratesProvider.compile(source);
|
||||
const { witness, output } = zokratesProvider.computeWitness(artifacts, [
|
||||
"2",
|
||||
]);
|
||||
|
||||
const keypair = zokratesProvider.setup(artifacts.program);
|
||||
|
||||
const proof = zokratesProvider.generateProof(
|
||||
artifacts.program,
|
||||
witness,
|
||||
keypair.pk
|
||||
);
|
||||
|
||||
const isVerified = zokratesProvider.verify(keypair.vk, proof);
|
||||
|
||||
var result = document.createElement("div");
|
||||
result.id = "result";
|
||||
result.innerText = isVerified;
|
||||
|
||||
document.body.appendChild(result);
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
27
zokrates_js/tests/umd/tests.js
Normal file
27
zokrates_js/tests/umd/tests.js
Normal file
|
@ -0,0 +1,27 @@
|
|||
import puppeteer from "puppeteer";
|
||||
import assert from "assert";
|
||||
import path from "path";
|
||||
|
||||
describe("umd web tests", () => {
|
||||
it("verify", async () => {
|
||||
const browser = await puppeteer.launch({
|
||||
headless: true,
|
||||
args: ["--no-sandbox", "--disable-setuid-sandbox"],
|
||||
});
|
||||
const page = await browser.newPage();
|
||||
|
||||
let response = await page.goto(
|
||||
path.dirname(import.meta.url) + "/index.html"
|
||||
);
|
||||
assert(response.ok());
|
||||
|
||||
let element = await page.waitForSelector("#result", {
|
||||
timeout: 30000,
|
||||
visible: true,
|
||||
});
|
||||
let value = await element.evaluate((el) => el.textContent, element);
|
||||
assert.equal(value, "true");
|
||||
|
||||
await browser.close();
|
||||
});
|
||||
});
|
|
@ -21,6 +21,6 @@ typed-arena = "1.4.1"
|
|||
wasm-bindgen-test = "^0.3.0"
|
||||
zokrates_ark = { version = "0.1", path = "../zokrates_ark" }
|
||||
zokrates_proof_systems = { version = "0.1", path = "../zokrates_proof_systems" }
|
||||
|
||||
getrandom = { version = "0.2.8", features = ["js"] }
|
||||
|
||||
[lib]
|
||||
|
|
Loading…
Reference in a new issue