diff --git a/src/lib/crypto/kimchi_bindings/js/bindings/oracles.js b/src/lib/crypto/kimchi_bindings/js/bindings/oracles.js index 1411fd73613e..ecd57b9f4861 100644 --- a/src/lib/crypto/kimchi_bindings/js/bindings/oracles.js +++ b/src/lib/crypto/kimchi_bindings/js/bindings/oracles.js @@ -1,6 +1,4 @@ -/* global plonk_wasm, tsRustConversion, - - */ +/* global plonk_wasm, tsRustConversion,*/ // Provides: fp_oracles_create // Requires: plonk_wasm, tsRustConversion @@ -75,31 +73,3 @@ function caml_pasta_fp_poseidon_params_create() { function caml_pasta_fq_poseidon_params_create() { return [0]; } - -// Provides: caml_pasta_fp_poseidon_block_cipher -// Requires: plonk_wasm, tsRustConversion, tsRustConversion -function caml_pasta_fp_poseidon_block_cipher(_fake_params, fp_vector) { - // 1. get permuted field vector from rust - var wasm_flat_vector = plonk_wasm.caml_pasta_fp_poseidon_block_cipher( - tsRustConversion.fp.vectorToRust(fp_vector) - ); - var new_fp_vector = tsRustConversion.fp.vectorFromRust(wasm_flat_vector); - // 2. write back modified field vector to original one - new_fp_vector.forEach(function (a, i) { - fp_vector[i] = a; - }); -} - -// Provides: caml_pasta_fq_poseidon_block_cipher -// Requires: plonk_wasm, tsRustConversion, tsRustConversion -function caml_pasta_fq_poseidon_block_cipher(_fake_params, fq_vector) { - // 1. get permuted field vector from rust - var wasm_flat_vector = plonk_wasm.caml_pasta_fq_poseidon_block_cipher( - tsRustConversion.fq.vectorToRust(fq_vector) - ); - var new_fq_vector = tsRustConversion.fq.vectorFromRust(wasm_flat_vector); - // 2. write back modified field vector to original one - new_fq_vector.forEach(function (a, i) { - fq_vector[i] = a; - }); -} diff --git a/src/lib/crypto/kimchi_bindings/js/bindings/util.js b/src/lib/crypto/kimchi_bindings/js/bindings/util.js index 8ada833be869..4f1edf7873b8 100644 --- a/src/lib/crypto/kimchi_bindings/js/bindings/util.js +++ b/src/lib/crypto/kimchi_bindings/js/bindings/util.js @@ -1,6 +1,6 @@ /* global UInt64, caml_int64_of_int32, caml_create_bytes, caml_bytes_unsafe_set, caml_bytes_unsafe_get, caml_ml_bytes_length, - plonk_wasm + plonk_wasm, getTsBindings */ // Provides: tsBindings diff --git a/src/lib/crypto/kimchi_bindings/js/dune b/src/lib/crypto/kimchi_bindings/js/dune index 7c0eb98fe09b..8aa5a3511f3b 100644 --- a/src/lib/crypto/kimchi_bindings/js/dune +++ b/src/lib/crypto/kimchi_bindings/js/dune @@ -14,7 +14,10 @@ bindings/prover-index.js bindings/util.js bindings/srs.js - bindings/verifier-index.js)) + bindings/verifier-index.js + native/native-overrides/oracles.js + native/native-overrides/util.js + )) (instrumentation (backend bisect_ppx)) (preprocess diff --git a/src/lib/crypto/kimchi_bindings/js/native/build.sh b/src/lib/crypto/kimchi_bindings/js/native/build.sh new file mode 100644 index 000000000000..bb3688b83198 --- /dev/null +++ b/src/lib/crypto/kimchi_bindings/js/native/build.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) +CURRENT_DIRECTORY="${SCRIPT_DIR}" +PROOF_SYSTEMS_ROOT=$(cd "${SCRIPT_DIR}/../../../proof-systems" && pwd) +PLONK_NAPI_ROOT="${PROOF_SYSTEMS_ROOT}/plonk-napi" + +TARGET_ROOT="${CARGO_TARGET_DIR:-"${PROOF_SYSTEMS_ROOT}/target"}" +export CARGO_TARGET_DIR="${TARGET_ROOT}" + +cargo build \ + --manifest-path "${PLONK_NAPI_ROOT}/Cargo.toml" \ + --release + +case "$(uname -s)" in + Darwin*) LIB_NAME="libplonk_napi.dylib" ;; + MINGW*|MSYS*|CYGWIN*) LIB_NAME="plonk_napi.dll" ;; + *) LIB_NAME="libplonk_napi.so" ;; + esac + +ARTIFACT="${TARGET_ROOT}/release/${LIB_NAME}" + +if [[ ! -f "${ARTIFACT}" ]]; then + echo "Failed to locate plonk-napi artifact at ${ARTIFACT}" >&2 + exit 1 +fi + +rm -f "${CURRENT_DIRECTORY}/plonk_napi.node" +cp "${ARTIFACT}" "${CURRENT_DIRECTORY}/plonk_napi.node" diff --git a/src/lib/crypto/kimchi_bindings/js/native/dune b/src/lib/crypto/kimchi_bindings/js/native/dune new file mode 100644 index 000000000000..b830cadd6dbe --- /dev/null +++ b/src/lib/crypto/kimchi_bindings/js/native/dune @@ -0,0 +1,29 @@ +(library + (name native_backend) + (public_name bindings_js.native_backend) + (js_of_ocaml + (flags + (:include flags.sexp)) + (javascript_files native_backend.js)) + (instrumentation + (backend bisect_ppx)) + (preprocess + (pps ppx_version js_of_ocaml-ppx))) + +(rule + (targets + plonk_napi.node + flags.sexp) + (deps + build.sh + ../../dune-build-root + (source_tree ../../../proof-systems)) + (locks /cargo-lock) + (action + (progn + (setenv + CARGO_TARGET_DIR + "%{read:../../dune-build-root}/cargo_kimchi_native" + (run bash build.sh)) + (write-file flags.sexp "()")))) + \ No newline at end of file diff --git a/src/lib/crypto/kimchi_bindings/js/native/native-overrides/oracles.js b/src/lib/crypto/kimchi_bindings/js/native/native-overrides/oracles.js new file mode 100644 index 000000000000..2b8e8cabb235 --- /dev/null +++ b/src/lib/crypto/kimchi_bindings/js/native/native-overrides/oracles.js @@ -0,0 +1,38 @@ +/* global plonk_wasm, tsRustConversionNative,*/ + + +// Provides: caml_pasta_fq_poseidon_block_cipher +// Requires: plonk_wasm, tsRustConversionNative +function caml_pasta_fq_poseidon_block_cipher(_fake_params, fq_vector) { + + console.log("overriding the old wasm caml_pasta_fq_poseidon_block_cipher, now using the native one") + + // 1. get permuted field vector from rust + var wasm_flat_vector = plonk_wasm.caml_pasta_fq_poseidon_block_cipher( + tsRustConversionNative.fq.vectorToRust(fq_vector) + ); + var new_fq_vector = tsRustConversionNative.fq.vectorFromRust(wasm_flat_vector); + // 2. write back modified field vector to original one + new_fq_vector.forEach(function (a, i) { + fq_vector[i] = a; + }); +} + + +// Provides: caml_pasta_fp_poseidon_block_cipher +// Requires: plonk_wasm, tsRustConversionNative +function caml_pasta_fp_poseidon_block_cipher(_fake_params, fp_vector) { + + console.log("overriding the old wasm caml_pasta_fp_poseidon_block_cipher, now using the native one") + + + // 1. get permuted field vector from rust + var wasm_flat_vector = plonk_wasm.caml_pasta_fp_poseidon_block_cipher( + tsRustConversionNative.fp.vectorToRust(fp_vector) + ); + var new_fp_vector = tsRustConversionNative.fp.vectorFromRust(wasm_flat_vector); + // 2. write back modified field vector to original one + new_fp_vector.forEach(function (a, i) { + fp_vector[i] = a; + }); +} diff --git a/src/lib/crypto/kimchi_bindings/js/native/native-overrides/util.js b/src/lib/crypto/kimchi_bindings/js/native/native-overrides/util.js new file mode 100644 index 000000000000..139fa4a3bb4d --- /dev/null +++ b/src/lib/crypto/kimchi_bindings/js/native/native-overrides/util.js @@ -0,0 +1,6 @@ +/* global plonk_wasm, tsRustConversionNative, getTsBindings, tsBindings */ + + +// Provides: tsRustConversionNative +// Requires: tsBindings, plonk_wasm, getTsBindings +var tsRustConversionNative = tsBindings.nativeRustConversion(plonk_wasm); \ No newline at end of file diff --git a/src/lib/crypto/kimchi_bindings/js/native/native_backend.js b/src/lib/crypto/kimchi_bindings/js/native/native_backend.js new file mode 100644 index 000000000000..718a4fa2b507 --- /dev/null +++ b/src/lib/crypto/kimchi_bindings/js/native/native_backend.js @@ -0,0 +1,4 @@ +// Provides: plonk_napi +var plonk_napi = require('./plonk_napi.node'); + +module.exports = plonk_napi; diff --git a/src/lib/crypto/kimchi_bindings/js/node_js/node_backend.js b/src/lib/crypto/kimchi_bindings/js/node_js/node_backend.js index 76e22cc82b25..32cc494ab906 100644 --- a/src/lib/crypto/kimchi_bindings/js/node_js/node_backend.js +++ b/src/lib/crypto/kimchi_bindings/js/node_js/node_backend.js @@ -1,2 +1,27 @@ // Provides: plonk_wasm var plonk_wasm = require('./plonk_wasm.js'); +var native = null; +try { + native = require('../native/plonk_napi.node'); +} catch (e) { + // native not available, keep WASM +} + +function snakeToCamel(name) { + return name.replace(/_([a-z])/g, function (_match, ch) { + return ch.toUpperCase(); + }); +} + +function override(functionName) { + if (!native) return; + var camel = snakeToCamel(functionName); + var impl = native[functionName] || native[camel]; + if (typeof impl === 'function') { + plonk_wasm[functionName] = impl; + } +} + +// Overwrite only the functions that are already available in native +override('caml_pasta_fp_poseidon_block_cipher'); +override('caml_pasta_fq_poseidon_block_cipher'); diff --git a/src/lib/crypto/kimchi_bindings/stubs/kimchi_bindings.ml b/src/lib/crypto/kimchi_bindings/stubs/kimchi_bindings.ml index 062a57691ca1..8e2e05126c9a 100644 --- a/src/lib/crypto/kimchi_bindings/stubs/kimchi_bindings.ml +++ b/src/lib/crypto/kimchi_bindings/stubs/kimchi_bindings.ml @@ -215,7 +215,8 @@ module Protocol = struct -> SRS.Fp.t -> bool -> t - = "caml_pasta_fp_plonk_index_create_bytecode" "caml_pasta_fp_plonk_index_create" + = "caml_pasta_fp_plonk_index_create_bytecode" + "caml_pasta_fp_plonk_index_create" external max_degree : t -> int = "caml_pasta_fp_plonk_index_max_degree" @@ -250,7 +251,8 @@ module Protocol = struct -> SRS.Fq.t -> bool -> t - = "caml_pasta_fq_plonk_index_create_bytecode" "caml_pasta_fq_plonk_index_create" + = "caml_pasta_fq_plonk_index_create_bytecode" + "caml_pasta_fq_plonk_index_create" external max_degree : t -> int = "caml_pasta_fq_plonk_index_max_degree" diff --git a/src/lib/crypto/proof-systems b/src/lib/crypto/proof-systems index ff424faac612..2a07e99eb6cb 160000 --- a/src/lib/crypto/proof-systems +++ b/src/lib/crypto/proof-systems @@ -1 +1 @@ -Subproject commit ff424faac6121ba0cead4adc28ca45c9cdc5ca46 +Subproject commit 2a07e99eb6cbef041a5fa918e3c4638659ac5734 diff --git a/src/lib/pickles/plonk_checks/scalars.ml b/src/lib/pickles/plonk_checks/scalars.ml index 17383baa0b4f..0ebaff44ae78 100644 --- a/src/lib/pickles/plonk_checks/scalars.ml +++ b/src/lib/pickles/plonk_checks/scalars.ml @@ -2831,8 +2831,7 @@ module Tick : S = struct + if_feature ( LookupPattern RangeCheck , (fun () -> - cell (var (LookupKindIndex RangeCheck, Curr)) - ) + cell (var (LookupKindIndex RangeCheck, Curr)) ) , fun () -> field "0x0000000000000000000000000000000000000000000000000000000000000000" @@ -2842,8 +2841,7 @@ module Tick : S = struct , (fun () -> cell (var - (LookupKindIndex ForeignFieldMul, Curr) ) - ) + (LookupKindIndex ForeignFieldMul, Curr) ) ) , fun () -> field "0x0000000000000000000000000000000000000000000000000000000000000000"