Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
250abd9
2.5.1
actions-user May 27, 2025
98dd1e7
Update CHANGELOG for new version v2.5.1
actions-user May 27, 2025
eda7a99
Merge branch 'main' into release/v2.5.1
Trivo25 May 30, 2025
7b51ea0
Update CHANGELOG.md
Trivo25 May 30, 2025
6b3f268
fix changelog
Trivo25 May 30, 2025
447d346
bump version
Trivo25 May 30, 2025
23bd2e9
correct commit hash in changelog
Trivo25 May 30, 2025
1d00b61
auto update npmDepsHash
Trivo25 May 30, 2025
ee4c6c6
minor change to start CI
Trivo25 May 30, 2025
ec8af40
Merge branch 'release/v2.5.1' of https://github.com/o1-labs/o1js into…
Trivo25 May 30, 2025
2351596
bindings: pass signature kind as parameter
querolita May 30, 2025
80f1dea
remove caml_bigint_256_print
Trivo25 May 31, 2025
65671f6
remove caml_bigint_256_to_string
Trivo25 May 31, 2025
8bf28a6
get rid of equivalentRecord for Fp bindings
Trivo25 May 31, 2025
83802dd
get rid of equivalentRecord for Fq bindings
Trivo25 May 31, 2025
c0a005b
Omit instead of remove
Trivo25 May 31, 2025
4da6926
include bindings in prettier
Trivo25 May 31, 2025
c44208c
ignore compile artefacts
Trivo25 May 31, 2025
d742d81
format with new prettier included files
Trivo25 May 31, 2025
19b27cf
Merge pull request #2242 from o1-labs/florian/fix-bindings-test-remov…
querolita Jun 1, 2025
6b6d8b9
Merge pull request #2237 from o1-labs/release/v2.5.1
Trivo25 Jun 2, 2025
edfd391
Merge pull request #2241 from o1-labs/querolita/bump-mina-compatible-…
querolita Jun 2, 2025
b26d0db
Merge branch 'main' into florian/prettier-for-bindings
Trivo25 Jun 3, 2025
c39f24e
Merge pull request #2243 from o1-labs/florian/prettier-for-bindings
Trivo25 Jun 3, 2025
0f51b6f
Merge branch 'main' into brian/update-develop
Geometer1729 Jun 5, 2025
dcc87d8
update mina
Geometer1729 Jun 5, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ benchmark/
dist/
node_modules/
o1js-reference/
src/bindings/
src/bindings/mina-transaction/gen/
src/bindings/compiled/
src/mina/
**/*.d.ts
10 changes: 5 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,16 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
_Security_ in case of vulnerabilities.
-->

## [Unreleased](https://github.com/o1-labs/o1js/compare/4e23a60...HEAD)
## [Unreleased](https://github.com/o1-labs/o1js/compare/3eef10d...HEAD)

## [2.6.0](https://github.com/o1-labs/o1js/compare/4e23a60...3eef10d) - 2025-05-30

### Added

- [PR! 1905](https://github.com/o1-labs/o1js/pull/1905) API support for circuit chunking
- still requires memory optimizations to be fully functional, and
- proof-systems version still needs to be updated to include [this commit](https://github.com/o1-labs/proof-systems/pull/3222/commits/8c37c293f8159eed3676964ba47fc5dc0ae6ea1e)
- that fixed the zero knowledge rows mismatch across Kimchi WASM bindings
- proof-systems version still needs to be updated to include [this commit](https://github.com/o1-labs/proof-systems/pull/3222/commits/8c37c293f8159eed3676964ba47fc5dc0ae6ea1e)
- [PR !1848](https://github.com/o1-labs/o1js/pull/1848) Dynamic array provable type

## [2.5.0](https://github.com/o1-labs/o1js/compare/6ff7f8470a...4e23a60)

Expand All @@ -32,8 +34,6 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm

### Added

- [PR !1848](https://github.com/o1-labs/o1js/pull/1848) Dynamic array provable type

- [PR !2076](https://github.com/o1-labs/o1js/pull/2076)
- o1js-bindings is no longer a submodule (same directory structure)
- compiled artifacts are now gitignored
Expand Down
1 change: 0 additions & 1 deletion README-nix.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ On macos the first time you run this command, you can expect it to take hours (o
Then, you will observe that the current devshell becomes a Nix shell with the right
configuration for `o1js` and `mina`.


From within the shell, you can build o1js and update the bindings.

```console
Expand Down
2 changes: 1 addition & 1 deletion npmDepsHash
Original file line number Diff line number Diff line change
@@ -1 +1 @@
sha256-m3NmZHhCuQxDpYHmB3sRLvitqu2bzbnNaAKY2KOCSIM=
sha256-BbQaG1unSH42VqtTjETCpm7lU29C1DskfXAJbYBvO5A=
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "o1js",
"description": "TypeScript framework for zk-SNARKs and zkApps",
"version": "2.5.0",
"version": "2.6.0",
"license": "Apache-2.0",
"homepage": "https://github.com/o1-labs/o1js/",
"repository": {
Expand Down Expand Up @@ -54,7 +54,7 @@
"build:wasm": "./src/bindings/scripts/update-wasm-and-types.sh",
"build:web": "rimraf ./dist/web && node src/build/build-web.js",
"build:examples": "npm run build && rimraf ./dist/examples && npx tsc -p tsconfig.examples.json && npx tsc -p benchmark/tsconfig.json",
"checkForBindings" : "test -d ./src/bindings/compiled || npm run build:bindings-download",
"checkForBindings": "test -d ./src/bindings/compiled || npm run build:bindings-download",
"build:docs": "npx typedoc",
"prepublish:web": "npm run checkForBindings && NODE_ENV=production node src/build/build-web.js",
"prepublish:node": "npm run checkForBindings && node src/build/copy-artifacts.js && rimraf ./dist/node && tsc -p tsconfig.node.json && node src/build/copy-to-dist.js && NODE_ENV=production node src/build/build-node.js",
Expand Down
2 changes: 0 additions & 2 deletions src/bindings/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

This directory collects code required by o1js to bind to lower layers of the proof system and the Mina transaction logic, which are written in Rust and OCaml.


**Directory structure**

- `/compiled` - compiled JS and Wasm artifacts produced by `js_of_ocaml` and `wasm-bindgen` from Rust and OCaml source code. We keep these artifacts in the source tree so that developing on o1js can be done with standard JS tooling and doesn't require setting up the full OCaml/Rust build pipeline.
Expand All @@ -12,4 +11,3 @@ This directory collects code required by o1js to bind to lower layers of the pro
- `/mina-transaction` - TS types and modules that specialize the generic tooling in `/lib` to Mina's zkApp protocol; mostly auto-generated from OCaml.
- `/ocaml` - OCaml library exposing Snarky, Pickles and parts of the Mina transaction logic to JS. Also, OCaml scripts that help auto-generate TypeScript for Mina- and crypto-related types and constants.
- `/scripts` - scripts that build parts of o1js from their OCaml and Rust sources, including the contents of `/compiled` and other generated TS files.

4 changes: 1 addition & 3 deletions src/bindings/crypto/bigint.unit-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,7 @@ test(Random.field, (x) => testBigintRoundtrip(x, fieldSize));
// failure cases
expect(() => bigIntToBytes(256n, 1)).toThrow(/does not fit in 1 bytes/);
expect(() => bigIntToBytes(100_000n, 2)).toThrow(/does not fit in 2 bytes/);
expect(() => bigIntToBytes(4n * Fp.modulus, 32)).toThrow(
/does not fit in 32 bytes/
);
expect(() => bigIntToBytes(4n * Fp.modulus, 32)).toThrow(/does not fit in 32 bytes/);

// parseHexString32

Expand Down
5 changes: 1 addition & 4 deletions src/bindings/crypto/bindings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,7 @@ import { PallasBindings, VestaBindings } from './bindings/curve.js';
import { FpBindings, FqBindings } from './bindings/field.js';
import { FpVectorBindings, FqVectorBindings } from './bindings/vector.js';
import type * as wasmNamespace from '../compiled/node_bindings/plonk_wasm.cjs';
import {
fieldsFromRustFlat,
fieldsToRustFlat,
} from './bindings/conversion-base.js';
import { fieldsFromRustFlat, fieldsToRustFlat } from './bindings/conversion-base.js';
import { proofConversion } from './bindings/conversion-proof.js';
import { conversionCore } from './bindings/conversion-core.js';
import { verifierIndexConversion } from './bindings/conversion-verifier-index.js';
Expand Down
133 changes: 7 additions & 126 deletions src/bindings/crypto/bindings/bindings.unit-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,7 @@ import {
toMlStringAscii,
} from './bigint256.js';
import { wasm } from '../../js/node/node-backend.js';
import {
Spec,
ToSpec,
FromSpec,
defaultAssertEqual,
id,
} from '../../../lib/testing/equivalent.js';
import { Spec, ToSpec, FromSpec, defaultAssertEqual, id } from '../../../lib/testing/equivalent.js';
import { Random } from '../../../lib/testing/property.js';
import {
WasmAffine,
Expand All @@ -35,18 +29,8 @@ import {
import { equivalentRecord } from './test-utils.js';
import { Field, FpBindings, FqBindings } from './field.js';
import { MlBool, MlOption } from '../../../lib/ml/base.js';
import {
OrInfinity,
PallasBindings,
VestaBindings,
toMlOrInfinity,
} from './curve.js';
import {
GroupProjective,
Pallas,
ProjectiveCurve,
Vesta,
} from '../elliptic-curve.js';
import { OrInfinity, PallasBindings, VestaBindings, toMlOrInfinity } from './curve.js';
import { GroupProjective, Pallas, ProjectiveCurve, Vesta } from '../elliptic-curve.js';
import {
WasmGPallas,
WasmGVesta,
Expand Down Expand Up @@ -106,15 +90,13 @@ function option<T, S>(spec: Spec<T, S>): Spec<MlOption<T>, S | undefined> {
};
}

equivalentRecord(Bigint256Bindings, wasm, {
equivalentRecord(Bigint256Bindings as Omit<typeof Bigint256Bindings, "caml_bigint_256_print" | "caml_bigint_256_to_string">, wasm, {
caml_bigint_256_of_numeral: undefined, // TODO
caml_bigint_256_of_decimal_string: { from: [decimalString], to: bigint256 },
caml_bigint_256_num_limbs: { from: [], to: number },
caml_bigint_256_bytes_per_limb: { from: [], to: number },
caml_bigint_256_div: { from: [bigint256, bigint256], to: bigint256 },
caml_bigint_256_compare: { from: [bigint256, bigint256], to: number },
caml_bigint_256_print: undefined, // this would spam the console
caml_bigint_256_to_string: { from: [bigint256], to: decimalString },
caml_bigint_256_test_bit: {
from: [bigint256, numberLessThan(256)],
to: boolean,
Expand All @@ -124,97 +106,8 @@ equivalentRecord(Bigint256Bindings, wasm, {
caml_bigint_256_deep_copy: { from: [bigint256], to: bigint256 },
});

equivalentRecord(
FpBindings as Omit<
typeof FpBindings,
| 'caml_pasta_fp_copy'
| 'caml_pasta_fp_mut_add'
| 'caml_pasta_fp_mut_sub'
| 'caml_pasta_fp_mut_mul'
| 'caml_pasta_fp_mut_square'
>,
wasm,
{
caml_pasta_fp_size_in_bits: { from: [], to: number },
caml_pasta_fp_size: { from: [], to: fp },
caml_pasta_fp_add: { from: [fp, fp], to: fp },
caml_pasta_fp_sub: { from: [fp, fp], to: fp },
caml_pasta_fp_negate: { from: [fp], to: fp },
caml_pasta_fp_mul: { from: [fp, fp], to: fp },
caml_pasta_fp_div: { from: [fp, fp], to: fp },
caml_pasta_fp_inv: { from: [fp], to: option(fp) },
caml_pasta_fp_square: { from: [fp], to: fp },
caml_pasta_fp_is_square: { from: [fp], to: boolean },
caml_pasta_fp_sqrt: { from: [fp], to: option(fp) },
caml_pasta_fp_of_int: { from: [uint31], to: fp },
caml_pasta_fp_to_string: { from: [fp], to: decimalString },
caml_pasta_fp_of_string: { from: [decimalString], to: fp },
caml_pasta_fp_print: undefined, // this would spam the console
// these aren't defined in Rust
// caml_pasta_fp_copy: { from: [fp, fp], to: unit },
// caml_pasta_fp_mut_add: { from: [fp, fp], to: unit },
// caml_pasta_fp_mut_sub: { from: [fp, fp], to: unit },
// caml_pasta_fp_mut_mul: { from: [fp, fp], to: unit },
// caml_pasta_fp_mut_square: { from: [fp], to: unit },
caml_pasta_fp_compare: { from: [fp, fp], to: number },
caml_pasta_fp_equal: { from: [fp, fp], to: boolean },
caml_pasta_fp_random: undefined, // random outputs won't match
caml_pasta_fp_rng: undefined, // random outputs won't match
caml_pasta_fp_to_bigint: { from: [fp], to: bigint256 },
caml_pasta_fp_of_bigint: { from: [bigint256], to: fp },
caml_pasta_fp_two_adic_root_of_unity: { from: [], to: fp },
caml_pasta_fp_domain_generator: { from: [numberLessThan(32)], to: fp },
caml_pasta_fp_to_bytes: undefined, // not implemented
caml_pasta_fp_of_bytes: undefined, // not implemented
caml_pasta_fp_deep_copy: { from: [fp], to: fp },
}
);

equivalentRecord(
FqBindings as Omit<
typeof FqBindings,
| 'caml_pasta_fq_copy'
| 'caml_pasta_fq_mut_add'
| 'caml_pasta_fq_mut_sub'
| 'caml_pasta_fq_mut_mul'
| 'caml_pasta_fq_mut_square'
>,
wasm,
{
caml_pasta_fq_size_in_bits: { from: [], to: number },
caml_pasta_fq_size: { from: [], to: fq },
caml_pasta_fq_add: { from: [fq, fq], to: fq },
caml_pasta_fq_sub: { from: [fq, fq], to: fq },
caml_pasta_fq_negate: { from: [fq], to: fq },
caml_pasta_fq_mul: { from: [fq, fq], to: fq },
caml_pasta_fq_div: { from: [fq, fq], to: fq },
caml_pasta_fq_inv: { from: [fq], to: option(fq) },
caml_pasta_fq_square: { from: [fq], to: fq },
caml_pasta_fq_is_square: { from: [fq], to: boolean },
caml_pasta_fq_sqrt: { from: [fq], to: option(fq) },
caml_pasta_fq_of_int: { from: [uint31], to: fq },
caml_pasta_fq_to_string: { from: [fq], to: decimalString },
caml_pasta_fq_of_string: { from: [decimalString], to: fq },
caml_pasta_fq_print: undefined, // this would spam the console
// these aren't defined in Rust
// caml_pasta_fq_copy: { from: [fq, fq], to: unit },
// caml_pasta_fq_mut_add: { from: [fq, fq], to: unit },
// caml_pasta_fq_mut_sub: { from: [fq, fq], to: unit },
// caml_pasta_fq_mut_mul: { from: [fq, fq], to: unit },
// caml_pasta_fq_mut_square: { from: [fq], to: unit },
caml_pasta_fq_compare: { from: [fq, fq], to: number },
caml_pasta_fq_equal: { from: [fq, fq], to: boolean },
caml_pasta_fq_random: undefined, // random outputs won't match
caml_pasta_fq_rng: undefined, // random outputs won't match
caml_pasta_fq_to_bigint: { from: [fq], to: bigint256 },
caml_pasta_fq_of_bigint: { from: [bigint256], to: fq },
caml_pasta_fq_two_adic_root_of_unity: { from: [], to: fq },
caml_pasta_fq_domain_generator: { from: [numberLessThan(32)], to: fq },
caml_pasta_fq_to_bytes: undefined, // not implemented
caml_pasta_fq_of_bytes: undefined, // not implemented
caml_pasta_fq_deep_copy: { from: [fq], to: fq },
}
);


// elliptic curve

Expand Down Expand Up @@ -280,13 +173,7 @@ function projective<WasmP extends WasmProjective, WasmA extends WasmAffine>(
let randomScaled = Random(() => Curve.scale(Curve.one, Scalar.random()));

return {
rng: Random.oneOf(
Curve.zero,
Curve.one,
randomScaled,
randomScaled,
randomScaled
),
rng: Random.oneOf(Curve.zero, Curve.one, randomScaled, randomScaled, randomScaled),
// excessively expensive to work around limited Rust API - only use for tests
there(p: GroupProjective): WasmP {
let { x, y, infinity } = Curve.toAffine(p);
Expand Down Expand Up @@ -324,13 +211,7 @@ function affine<WasmA extends WasmAffine>(
affineOne: () => WasmA
): Spec<OrInfinity, WasmA> {
let randomScaled = Random(() => Curve.scale(Curve.one, Scalar.random()));
let rngProjective = Random.oneOf(
Curve.zero,
Curve.one,
randomScaled,
randomScaled,
randomScaled
);
let rngProjective = Random.oneOf(Curve.zero, Curve.one, randomScaled, randomScaled, randomScaled);
let rng = Random.map(rngProjective, (p) => toMlOrInfinity(Curve.toAffine(p)));

return {
Expand Down
5 changes: 1 addition & 4 deletions src/bindings/crypto/bindings/conversion-base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,7 @@ function affineFromRust<A extends WasmAffine>(pt: A): OrInfinity {

const tmpBytes = new Uint8Array(32);

function affineToRust<A extends WasmAffine>(
pt: OrInfinity,
makeAffine: () => A
) {
function affineToRust<A extends WasmAffine>(pt: OrInfinity, makeAffine: () => A) {
let res = makeAffine();
if (pt === Infinity) {
res.infinity = true;
Expand Down
26 changes: 6 additions & 20 deletions src/bindings/crypto/bindings/conversion-core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,7 @@ function conversionCorePerField(

gateToRust(gate: Gate) {
let [, typ, [, ...wires], coeffs] = gate;
let rustWires = new wasm.WasmGateWires(
...mapTuple(wires, self.wireToRust)
);
let rustWires = new wasm.WasmGateWires(...mapTuple(wires, self.wireToRust));
let rustCoeffs = fieldsToRustFlat(coeffs);
return new Gate(typ, rustWires, rustCoeffs);
},
Expand All @@ -104,14 +102,10 @@ function conversionCorePerField(
pointFromRust: affineFromRust,

pointsToRust([, ...points]: MlArray<OrInfinity>): Uint32Array {
return mapToUint32Array(points, (point) =>
unwrap(self.pointToRust(point))
);
return mapToUint32Array(points, (point) => unwrap(self.pointToRust(point)));
},
pointsFromRust(points: Uint32Array): MlArray<OrInfinity> {
let arr = mapFromUintArray(points, (ptr) =>
affineFromRust(wrap(ptr, CommitmentCurve))
);
let arr = mapFromUintArray(points, (ptr) => affineFromRust(wrap(ptr, CommitmentCurve)));
return [0, ...arr];
},

Expand All @@ -133,9 +127,7 @@ function conversionCorePerField(
return mapToUint32Array(comms, (c) => unwrap(self.polyCommToRust(c)));
},
polyCommsFromRust(rustComms: Uint32Array): MlArray<PolyComm> {
let comms = mapFromUintArray(rustComms, (ptr) =>
self.polyCommFromRust(wrap(ptr, PolyComm))
);
let comms = mapFromUintArray(rustComms, (ptr) => self.polyCommFromRust(wrap(ptr, PolyComm)));
return [0, ...comms];
},
};
Expand Down Expand Up @@ -176,18 +168,12 @@ function freeOnFinalize<T extends Freeable>(instance: T) {
// directly, but unfortunately the destructor name is some mangled internal
// string generated by wasm_bindgen. For now, this is the best,
// least-brittle way to free once the original class instance gets collected.
let instanceRepresentative = wrap<T>(
(instance as any).__wbg_ptr,
(instance as any).constructor
);
let instanceRepresentative = wrap<T>((instance as any).__wbg_ptr, (instance as any).constructor);
registry.register(instance, instanceRepresentative, instance);
return instance;
}

function mapFromUintArray<T>(
array: Uint32Array | Uint8Array,
map: (i: number) => T
) {
function mapFromUintArray<T>(array: Uint32Array | Uint8Array, map: (i: number) => T) {
let n = array.length;
let result: T[] = Array(n);
for (let i = 0; i < n; i++) {
Expand Down
13 changes: 2 additions & 11 deletions src/bindings/crypto/bindings/conversion-oracles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,7 @@ import type {
} from '../../compiled/node_bindings/plonk_wasm.cjs';
import type * as wasmNamespace from '../../compiled/node_bindings/plonk_wasm.cjs';
import { MlOption } from '../../../lib/ml/base.js';
import {
Field,
Oracles,
RandomOracles,
ScalarChallenge,
} from './kimchi-types.js';
import { Field, Oracles, RandomOracles, ScalarChallenge } from './kimchi-types.js';
import {
fieldFromRust,
fieldToRust,
Expand Down Expand Up @@ -80,11 +75,7 @@ function oraclesConversionPerField({ RandomOracles, Oracles }: WasmClasses) {
let jointCombiner = ro.joint_combiner;
let jointCombinerOption = MlOption<[0, ScalarChallenge, Field]>(
jointCombinerChal &&
jointCombiner && [
0,
[0, fieldFromRust(jointCombinerChal)],
fieldFromRust(jointCombiner),
]
jointCombiner && [0, [0, fieldFromRust(jointCombinerChal)], fieldFromRust(jointCombiner)]
);
let mlRo: RandomOracles = [
0,
Expand Down
Loading
Loading