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/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 8877cf35..f7643595 100644 --- a/ocaml/lib/snarky_bindings.ml +++ b/ocaml/lib/snarky_bindings.ml @@ -30,6 +30,36 @@ 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 state = Impl.Low_level.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 = 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 () + 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 + + 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 let as_prover = Impl.as_prover @@ -491,6 +521,26 @@ let snarky = method existsVar = exists_var + val lowLevel = + object%js + val state = Low_level.state + + method createState = Low_level.create_state + + val 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 = let open Run in object%js diff --git a/ocaml/lib/snarky_bindings.mli b/ocaml/lib/snarky_bindings.mli index a1621a28..263cec67 100644 --- a/ocaml/lib/snarky_bindings.mli +++ b/ocaml/lib/snarky_bindings.mli @@ -13,6 +13,35 @@ end val snarky : < exists : (int -> (unit -> field array) -> Field.t array) Js.meth ; existsVar : ((unit -> field) -> Field.t) Js.meth + ; lowLevel : + < 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.t + option + -> unit ) + option + -> Impl.Low_level.state + * Field.Constant.Vector.t + * Field.Constant.Vector.t + * Backend.R1CS_constraint_system.t ) + 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 + ; 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 : < asProver : ((unit -> unit) -> unit) Js.meth ; constraintSystem :