From 03c311e3b979c0759de0e3ae95e27620006bc331 Mon Sep 17 00:00:00 2001 From: Gregor Date: Mon, 8 Jan 2024 17:59:02 +0100 Subject: [PATCH 1/7] start creating a low-level snarky intf --- ocaml/lib/snarky_bindings.ml | 52 +++++++++++++++++++++++++++++++++++ ocaml/lib/snarky_bindings.mli | 16 +++++++++++ 2 files changed, 68 insertions(+) diff --git a/ocaml/lib/snarky_bindings.ml b/ocaml/lib/snarky_bindings.ml index 8877cf35..2fd2b8c6 100644 --- a/ocaml/lib/snarky_bindings.ml +++ b/ocaml/lib/snarky_bindings.ml @@ -30,11 +30,50 @@ let exists (size_in_fields : int) (compute : unit -> Field.Constant.t array) = let exists_var (compute : unit -> Field.Constant.t) = Impl.exists Field.typ ~compute +module Low_level = struct + let make_state num_inputs eval_constraints with_witness = + let input = Impl.Low_level.field_vec () in + let next_auxiliary = ref num_inputs in + let aux = Impl.Low_level.field_vec () in + let system = Backend.R1CS_constraint_system.create () in + let state = + Impl.Low_level.make_state ~num_inputs ~input ~next_auxiliary ~aux ~system + ~eval_constraints ~with_witness () + in + (state, input, aux, system) + + let get_state () = !Impl.Low_level.state + + let set_state state = Impl.Low_level.set_state state + + let field_vec () = Impl.Low_level.field_vec () +end + module Run = struct let as_prover = Impl.as_prover let in_prover_block () = As_prover.in_prover_block () |> Js.bool + (* TODO recreate this in JS *) + let run_circuit num_inputs eval_constraints with_witness (f : unit -> unit) = + let open Impl.Low_level in + let input = field_vec () in + let next_auxiliary = ref num_inputs in + let aux = field_vec () in + let system = Backend.R1CS_constraint_system.create () in + let state' = + make_state ~num_inputs ~input ~next_auxiliary ~aux ~system + ~eval_constraints ~with_witness () + in + set_state state' ; + try + let result = mark_active f in + set_state (Snarky_backendless.Run_state.set_is_running !state true) ; + result + with exn -> + set_state (Snarky_backendless.Run_state.set_is_running !state false) ; + Util.raise_exn exn + let run_and_check (f : unit -> unit) = try Impl.run_and_check_exn (fun () -> @@ -491,6 +530,17 @@ let snarky = method existsVar = exists_var + val lowLevel = + object%js + method makeState = Low_level.make_state + + method getState = Low_level.get_state + + method setState = Low_level.set_state + + method fieldVec = Low_level.field_vec + end + val run = let open Run in object%js @@ -502,6 +552,8 @@ let snarky = method runUnchecked = run_unchecked + method runCircuit = run_circuit + method constraintSystem = constraint_system end diff --git a/ocaml/lib/snarky_bindings.mli b/ocaml/lib/snarky_bindings.mli index a1621a28..c4d1a117 100644 --- a/ocaml/lib/snarky_bindings.mli +++ b/ocaml/lib/snarky_bindings.mli @@ -13,6 +13,21 @@ end val snarky : < exists : (int -> (unit -> field array) -> Field.t array) Js.meth ; existsVar : ((unit -> field) -> Field.t) Js.meth + ; lowLevel : + < fieldVec : (unit -> Impl.Low_level.field_vec) Js.meth + ; getState : (unit -> Impl.Low_level.state) Js.meth + ; makeState : + ( int + -> bool + -> bool + -> Impl.Low_level.state + * Impl.Low_level.field_vec + * Impl.Low_level.field_vec + * Backend.R1CS_constraint_system.t ) + Js.meth + ; setState : (Impl.Low_level.state -> unit) Js.meth > + Js.t + Js.readonly_prop ; run : < asProver : ((unit -> unit) -> unit) Js.meth ; constraintSystem : @@ -23,6 +38,7 @@ val snarky : Js.t ) Js.meth ; inProverBlock : (unit -> bool Js.t) Js.readonly_prop + ; runCircuit : (int -> bool -> bool -> (unit -> unit) -> unit) Js.meth ; runAndCheck : ((unit -> unit) -> unit) Js.meth ; runUnchecked : ((unit -> unit) -> unit) Js.meth > Js.t From c80b433416681d1d7f7a2bc44247840bb5d89f24 Mon Sep 17 00:00:00 2001 From: Gregor Date: Mon, 8 Jan 2024 22:13:08 +0100 Subject: [PATCH 2/7] add log constraint --- js/snarky-class-spec.js | 4 ++++ ocaml/lib/snarky_bindings.ml | 9 +++++---- ocaml/lib/snarky_bindings.mli | 20 +++++++++++++++++++- 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/js/snarky-class-spec.js b/js/snarky-class-spec.js index 64308c9d..b8c2ff19 100644 --- a/js/snarky-class-spec.js +++ b/js/snarky-class-spec.js @@ -32,6 +32,10 @@ export default [ name: 'poseidon', type: 'object', }, + { + name: 'lowLevel', + type: 'object', + }, ], }, { diff --git a/ocaml/lib/snarky_bindings.ml b/ocaml/lib/snarky_bindings.ml index 2fd2b8c6..a5407138 100644 --- a/ocaml/lib/snarky_bindings.ml +++ b/ocaml/lib/snarky_bindings.ml @@ -31,14 +31,14 @@ let exists_var (compute : unit -> Field.Constant.t) = Impl.exists Field.typ ~compute module Low_level = struct - let make_state num_inputs eval_constraints with_witness = + let make_state num_inputs eval_constraints with_witness log_constraint = let input = Impl.Low_level.field_vec () in let next_auxiliary = ref num_inputs in let aux = Impl.Low_level.field_vec () in let system = Backend.R1CS_constraint_system.create () in let state = Impl.Low_level.make_state ~num_inputs ~input ~next_auxiliary ~aux ~system - ~eval_constraints ~with_witness () + ~eval_constraints ~with_witness ~log_constraint () in (state, input, aux, system) @@ -55,7 +55,8 @@ module Run = struct let in_prover_block () = As_prover.in_prover_block () |> Js.bool (* TODO recreate this in JS *) - let run_circuit num_inputs eval_constraints with_witness (f : unit -> unit) = + let run_circuit num_inputs eval_constraints with_witness log_constraint + (f : unit -> unit) = let open Impl.Low_level in let input = field_vec () in let next_auxiliary = ref num_inputs in @@ -63,7 +64,7 @@ module Run = struct let system = Backend.R1CS_constraint_system.create () in let state' = make_state ~num_inputs ~input ~next_auxiliary ~aux ~system - ~eval_constraints ~with_witness () + ~eval_constraints ~with_witness ~log_constraint () in set_state state' ; try diff --git a/ocaml/lib/snarky_bindings.mli b/ocaml/lib/snarky_bindings.mli index c4d1a117..124d98b8 100644 --- a/ocaml/lib/snarky_bindings.mli +++ b/ocaml/lib/snarky_bindings.mli @@ -20,6 +20,12 @@ val snarky : ( int -> bool -> bool + -> ( ?at_label_boundary:[ `End | `Start ] * string + -> ( field Snarky_backendless.Cvar.t + , field ) + Snarky_backendless.Constraint.basic_with_annotation + option + -> unit ) -> Impl.Low_level.state * Impl.Low_level.field_vec * Impl.Low_level.field_vec @@ -38,7 +44,19 @@ val snarky : Js.t ) Js.meth ; inProverBlock : (unit -> bool Js.t) Js.readonly_prop - ; runCircuit : (int -> bool -> bool -> (unit -> unit) -> unit) Js.meth + ; runCircuit : + ( int + -> bool + -> bool + -> ( ?at_label_boundary:[ `End | `Start ] * string + -> ( field Snarky_backendless.Cvar.t + , field ) + Snarky_backendless.Constraint.basic_with_annotation + option + -> unit ) + -> (unit -> unit) + -> unit ) + Js.meth ; runAndCheck : ((unit -> unit) -> unit) Js.meth ; runUnchecked : ((unit -> unit) -> unit) Js.meth > Js.t From 3c2a3b646767b374d466022ededf81ae455d8110 Mon Sep 17 00:00:00 2001 From: Gregor Date: Tue, 9 Jan 2024 08:49:17 +0100 Subject: [PATCH 3/7] iterate, simplify low-level intf --- crypto/bindings/vector.ts | 2 ++ ocaml/lib/snarky_bindings.ml | 45 +++++++++++++++-------------------- ocaml/lib/snarky_bindings.mli | 15 ++++++------ 3 files changed, 29 insertions(+), 33 deletions(-) diff --git a/crypto/bindings/vector.ts b/crypto/bindings/vector.ts index e3c1aa37..ed44657d 100644 --- a/crypto/bindings/vector.ts +++ b/crypto/bindings/vector.ts @@ -7,6 +7,8 @@ import { withPrefix } from './util.js'; export { FpVectorBindings, FqVectorBindings }; +export { FieldVector }; + type FieldVector = MlArray; const FieldVectorBindings = { diff --git a/ocaml/lib/snarky_bindings.ml b/ocaml/lib/snarky_bindings.ml index a5407138..9b64a2de 100644 --- a/ocaml/lib/snarky_bindings.ml +++ b/ocaml/lib/snarky_bindings.ml @@ -31,22 +31,20 @@ let exists_var (compute : unit -> Field.Constant.t) = Impl.exists Field.typ ~compute module Low_level = struct - let make_state num_inputs eval_constraints with_witness log_constraint = - let input = Impl.Low_level.field_vec () in + let state = Impl.Low_level.state + + let set_state state = Impl.Low_level.set_state state + + let create_state num_inputs eval_constraints with_witness log_constraint = + let input = Field.Constant.Vector.create () in let next_auxiliary = ref num_inputs in - let aux = Impl.Low_level.field_vec () in + let aux = Field.Constant.Vector.create () in let system = Backend.R1CS_constraint_system.create () in let state = Impl.Low_level.make_state ~num_inputs ~input ~next_auxiliary ~aux ~system - ~eval_constraints ~with_witness ~log_constraint () + ~eval_constraints ~with_witness ?log_constraint () in (state, input, aux, system) - - let get_state () = !Impl.Low_level.state - - let set_state state = Impl.Low_level.set_state state - - let field_vec () = Impl.Low_level.field_vec () end module Run = struct @@ -57,22 +55,19 @@ module Run = struct (* TODO recreate this in JS *) let run_circuit num_inputs eval_constraints with_witness log_constraint (f : unit -> unit) = - let open Impl.Low_level in - let input = field_vec () in - let next_auxiliary = ref num_inputs in - let aux = field_vec () in - let system = Backend.R1CS_constraint_system.create () in - let state' = - make_state ~num_inputs ~input ~next_auxiliary ~aux ~system - ~eval_constraints ~with_witness ~log_constraint () + let state', _, _, _ = + Low_level.create_state num_inputs eval_constraints with_witness + log_constraint in - set_state state' ; + Low_level.set_state state' ; try - let result = mark_active f in - set_state (Snarky_backendless.Run_state.set_is_running !state true) ; + let result = Impl.Low_level.mark_active f in + Low_level.( + set_state (Snarky_backendless.Run_state.set_is_running !state true)) ; result with exn -> - set_state (Snarky_backendless.Run_state.set_is_running !state false) ; + Low_level.( + set_state (Snarky_backendless.Run_state.set_is_running !state false)) ; Util.raise_exn exn let run_and_check (f : unit -> unit) = @@ -533,13 +528,11 @@ let snarky = val lowLevel = object%js - method makeState = Low_level.make_state - - method getState = Low_level.get_state + val state = Low_level.state method setState = Low_level.set_state - method fieldVec = Low_level.field_vec + method createState = Low_level.create_state end val run = diff --git a/ocaml/lib/snarky_bindings.mli b/ocaml/lib/snarky_bindings.mli index 124d98b8..1550fdea 100644 --- a/ocaml/lib/snarky_bindings.mli +++ b/ocaml/lib/snarky_bindings.mli @@ -14,21 +14,21 @@ val snarky : < exists : (int -> (unit -> field array) -> Field.t array) Js.meth ; existsVar : ((unit -> field) -> Field.t) Js.meth ; lowLevel : - < fieldVec : (unit -> Impl.Low_level.field_vec) Js.meth - ; getState : (unit -> Impl.Low_level.state) Js.meth - ; makeState : + < state : Impl.Low_level.state ref Js.readonly_prop + ; createState : ( int -> bool -> bool -> ( ?at_label_boundary:[ `End | `Start ] * string -> ( field Snarky_backendless.Cvar.t , field ) - Snarky_backendless.Constraint.basic_with_annotation + Snarky_backendless.Constraint.t option -> unit ) + option -> Impl.Low_level.state - * Impl.Low_level.field_vec - * Impl.Low_level.field_vec + * Field.Constant.Vector.t + * Field.Constant.Vector.t * Backend.R1CS_constraint_system.t ) Js.meth ; setState : (Impl.Low_level.state -> unit) Js.meth > @@ -51,9 +51,10 @@ val snarky : -> ( ?at_label_boundary:[ `End | `Start ] * string -> ( field Snarky_backendless.Cvar.t , field ) - Snarky_backendless.Constraint.basic_with_annotation + Snarky_backendless.Constraint.t option -> unit ) + option -> (unit -> unit) -> unit ) Js.meth From 166682eda0e7660faedcf4c604fe3f5c52f9cf0d Mon Sep 17 00:00:00 2001 From: Gregor Date: Wed, 10 Jan 2024 10:07:27 +0100 Subject: [PATCH 4/7] iterate on api --- ocaml/lib/snarky_bindings.ml | 29 ++++++++++++++++++----------- ocaml/lib/snarky_bindings.mli | 3 ++- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/ocaml/lib/snarky_bindings.ml b/ocaml/lib/snarky_bindings.ml index 9b64a2de..9b68e2b9 100644 --- a/ocaml/lib/snarky_bindings.ml +++ b/ocaml/lib/snarky_bindings.ml @@ -33,8 +33,6 @@ let exists_var (compute : unit -> Field.Constant.t) = module Low_level = struct let state = Impl.Low_level.state - let set_state state = Impl.Low_level.set_state state - let create_state num_inputs eval_constraints with_witness log_constraint = let input = Field.Constant.Vector.create () in let next_auxiliary = ref num_inputs in @@ -45,6 +43,11 @@ module Low_level = struct ~eval_constraints ~with_witness ?log_constraint () in (state, input, aux, system) + + let push_active_counter () = Impl.Low_level.push_active_counter () + + let reset_active_counter counters = + Impl.Low_level.reset_active_counter counters end module Run = struct @@ -55,19 +58,21 @@ module Run = struct (* TODO recreate this in JS *) let run_circuit num_inputs eval_constraints with_witness log_constraint (f : unit -> unit) = - let state', _, _, _ = + let state, _, _, _ = Low_level.create_state num_inputs eval_constraints with_witness log_constraint in - Low_level.set_state state' ; + let old_state = !Low_level.state in + Low_level.state := state ; + let counters = Impl.Low_level.push_active_counter () in try - let result = Impl.Low_level.mark_active f in - Low_level.( - set_state (Snarky_backendless.Run_state.set_is_running !state true)) ; + let result = f () in + Impl.Low_level.reset_active_counter counters ; + Low_level.state := old_state ; result with exn -> - Low_level.( - set_state (Snarky_backendless.Run_state.set_is_running !state false)) ; + Impl.Low_level.reset_active_counter counters ; + Low_level.state := old_state ; Util.raise_exn exn let run_and_check (f : unit -> unit) = @@ -530,9 +535,11 @@ let snarky = object%js val state = Low_level.state - method setState = Low_level.set_state - method createState = Low_level.create_state + + method pushActiveCounter = Low_level.push_active_counter + + method resetActiveCounter = Low_level.reset_active_counter end val run = diff --git a/ocaml/lib/snarky_bindings.mli b/ocaml/lib/snarky_bindings.mli index 1550fdea..bc4df487 100644 --- a/ocaml/lib/snarky_bindings.mli +++ b/ocaml/lib/snarky_bindings.mli @@ -31,7 +31,8 @@ val snarky : * Field.Constant.Vector.t * Backend.R1CS_constraint_system.t ) Js.meth - ; setState : (Impl.Low_level.state -> unit) Js.meth > + ; pushActiveCounter : (unit -> int list) Js.meth + ; resetActiveCounter : (int list -> unit) Js.meth > Js.t Js.readonly_prop ; run : From b9ffe8460595d41c4db20998951bbd6bbb03a711 Mon Sep 17 00:00:00 2001 From: Gregor Date: Wed, 10 Jan 2024 13:19:03 +0100 Subject: [PATCH 5/7] expose functions to get cs info --- ocaml/lib/snarky_bindings.ml | 19 +++++++++++++++++++ ocaml/lib/snarky_bindings.mli | 9 ++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/ocaml/lib/snarky_bindings.ml b/ocaml/lib/snarky_bindings.ml index 9b68e2b9..15a4170b 100644 --- a/ocaml/lib/snarky_bindings.ml +++ b/ocaml/lib/snarky_bindings.ml @@ -48,6 +48,16 @@ module Low_level = struct let reset_active_counter counters = Impl.Low_level.reset_active_counter counters + + module Constraint_system = struct + let get_rows cs = Backend.R1CS_constraint_system.get_rows_len cs + + let digest cs = + Backend.R1CS_constraint_system.digest cs |> Md5.to_hex |> Js.string + + let to_json cs = + Backend.R1CS_constraint_system.to_json cs |> Js.string |> Util.json_parse + end end module Run = struct @@ -540,6 +550,15 @@ let snarky = method pushActiveCounter = Low_level.push_active_counter method resetActiveCounter = Low_level.reset_active_counter + + val constraintSystem = + object%js + method getRows = Low_level.Constraint_system.get_rows + + method digest = Low_level.Constraint_system.digest + + method toJson = Low_level.Constraint_system.to_json + end end val run = diff --git a/ocaml/lib/snarky_bindings.mli b/ocaml/lib/snarky_bindings.mli index bc4df487..d16792ed 100644 --- a/ocaml/lib/snarky_bindings.mli +++ b/ocaml/lib/snarky_bindings.mli @@ -32,7 +32,14 @@ val snarky : * Backend.R1CS_constraint_system.t ) Js.meth ; pushActiveCounter : (unit -> int list) Js.meth - ; resetActiveCounter : (int list -> unit) Js.meth > + ; resetActiveCounter : (int list -> unit) Js.meth + ; constraintSystem : + < getRows : (Backend.R1CS_constraint_system.t -> int) Js.meth + ; digest : + (Backend.R1CS_constraint_system.t -> Js.js_string Js.t) Js.meth + ; toJson : (Backend.R1CS_constraint_system.t -> 'a) Js.meth > + Js.t + Js.readonly_prop > Js.t Js.readonly_prop ; run : From 9f851339d3895f04c1704009751b4e068cc08f62 Mon Sep 17 00:00:00 2001 From: Gregor Date: Wed, 10 Jan 2024 13:58:40 +0100 Subject: [PATCH 6/7] fix for jsoo weirdness --- ocaml/lib/snarky_bindings.ml | 2 +- ocaml/lib/snarky_bindings.mli | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ocaml/lib/snarky_bindings.ml b/ocaml/lib/snarky_bindings.ml index 15a4170b..f1529413 100644 --- a/ocaml/lib/snarky_bindings.ml +++ b/ocaml/lib/snarky_bindings.ml @@ -547,7 +547,7 @@ let snarky = method createState = Low_level.create_state - method pushActiveCounter = Low_level.push_active_counter + val pushActiveCounter = Low_level.push_active_counter method resetActiveCounter = Low_level.reset_active_counter diff --git a/ocaml/lib/snarky_bindings.mli b/ocaml/lib/snarky_bindings.mli index d16792ed..75fcdd7f 100644 --- a/ocaml/lib/snarky_bindings.mli +++ b/ocaml/lib/snarky_bindings.mli @@ -31,7 +31,7 @@ val snarky : * Field.Constant.Vector.t * Backend.R1CS_constraint_system.t ) Js.meth - ; pushActiveCounter : (unit -> int list) Js.meth + ; pushActiveCounter : (unit -> int list) Js.readonly_prop ; resetActiveCounter : (int list -> unit) Js.meth ; constraintSystem : < getRows : (Backend.R1CS_constraint_system.t -> int) Js.meth From 9830a955642adf97a09719570c13272d264b2eac Mon Sep 17 00:00:00 2001 From: Gregor Date: Wed, 17 Jan 2024 11:11:20 +0100 Subject: [PATCH 7/7] remove unused api addition --- ocaml/lib/snarky_bindings.ml | 22 ---------------------- ocaml/lib/snarky_bindings.mli | 14 -------------- 2 files changed, 36 deletions(-) diff --git a/ocaml/lib/snarky_bindings.ml b/ocaml/lib/snarky_bindings.ml index f1529413..f7643595 100644 --- a/ocaml/lib/snarky_bindings.ml +++ b/ocaml/lib/snarky_bindings.ml @@ -65,26 +65,6 @@ module Run = struct let in_prover_block () = As_prover.in_prover_block () |> Js.bool - (* TODO recreate this in JS *) - let run_circuit num_inputs eval_constraints with_witness log_constraint - (f : unit -> unit) = - let state, _, _, _ = - Low_level.create_state num_inputs eval_constraints with_witness - log_constraint - in - let old_state = !Low_level.state in - Low_level.state := state ; - let counters = Impl.Low_level.push_active_counter () in - try - let result = f () in - Impl.Low_level.reset_active_counter counters ; - Low_level.state := old_state ; - result - with exn -> - Impl.Low_level.reset_active_counter counters ; - Low_level.state := old_state ; - Util.raise_exn exn - let run_and_check (f : unit -> unit) = try Impl.run_and_check_exn (fun () -> @@ -572,8 +552,6 @@ let snarky = method runUnchecked = run_unchecked - method runCircuit = run_circuit - method constraintSystem = constraint_system end diff --git a/ocaml/lib/snarky_bindings.mli b/ocaml/lib/snarky_bindings.mli index 75fcdd7f..263cec67 100644 --- a/ocaml/lib/snarky_bindings.mli +++ b/ocaml/lib/snarky_bindings.mli @@ -52,20 +52,6 @@ val snarky : Js.t ) Js.meth ; inProverBlock : (unit -> bool Js.t) Js.readonly_prop - ; runCircuit : - ( int - -> bool - -> bool - -> ( ?at_label_boundary:[ `End | `Start ] * string - -> ( field Snarky_backendless.Cvar.t - , field ) - Snarky_backendless.Constraint.t - option - -> unit ) - option - -> (unit -> unit) - -> unit ) - Js.meth ; runAndCheck : ((unit -> unit) -> unit) Js.meth ; runUnchecked : ((unit -> unit) -> unit) Js.meth > Js.t