diff --git a/src/bindings/crypto/bindings-napi.ts b/src/bindings/crypto/bindings-napi.ts new file mode 100644 index 000000000..824e31e18 --- /dev/null +++ b/src/bindings/crypto/bindings-napi.ts @@ -0,0 +1,31 @@ +import { fieldsFromRustFlat, fieldsToRustFlat } from './bindings/conversion-base.js'; + +export { bindingsNapi }; + +function bindingsNapi(napi: any) { + return { + fp: { + vectorToRust: (fields: any) => { + console.log('values going in ', fields); + let res = fieldsToRustFlat(fields); + console.log('values going out ', res); + return res; + }, + vectorFromRust: fieldsFromRustFlat, + }, + fq: { + vectorToRust: (fields: any) => { + console.log('values going in ', fields); + let res = fieldsToRustFlat(fields); + console.log('values going out ', res); + return res; + }, + vectorFromRust: (fieldBytes: any) => { + console.log('values going in ', fieldBytes); + let res = fieldsFromRustFlat(fieldBytes); + console.log('values going out ', res); + return res; + }, + }, + }; +} diff --git a/src/bindings/crypto/bindings.ts b/src/bindings/crypto/bindings.ts index 8e9fcb35f..a616c8b3a 100644 --- a/src/bindings/crypto/bindings.ts +++ b/src/bindings/crypto/bindings.ts @@ -16,8 +16,19 @@ import { verifierIndexConversion } from './bindings/conversion-verifier-index.js import { oraclesConversion } from './bindings/conversion-oracles.js'; import { jsEnvironment } from './bindings/env.js'; import { srs } from './bindings/srs.js'; +import { bindingsNapi } from './bindings-napi.js'; -export { getRustConversion, RustConversion, Wasm }; +export { getRustConversion, RustConversion, Wasm, createNativeRustConversion }; + + +/* TODO: Uncomment in phase 2 of conversion layer +import { conversionCore as conversionCoreNative } from './native/conversion-core.js'; +import { fieldsFromRustFlat as fieldsFromRustFlatNative, fieldsToRustFlat as fieldsToRustFlatNative } from './native/conversion-base.js'; +import { proofConversion as proofConversionNative } from './native/conversion-proof.js'; +import { verifierIndexConversion as verifierIndexConversionNative } from './native/conversion-verifier-index.js'; +import { oraclesConversion as oraclesConversionNative } from './native/conversion-oracles.js'; + +export { getRustConversion, type RustConversion, type NativeConversion, type Wasm };*/ const tsBindings = { jsEnvironment, @@ -31,6 +42,12 @@ const tsBindings = { ...FpVectorBindings, ...FqVectorBindings, rustConversion: createRustConversion, + nativeRustConversion: createNativeRustConversion, + /* TODO: Uncomment in phase 2 of conversion layer + srs: (wasm: Wasm) => { + const bundle = getConversionBundle(wasm); + return bundle.srsFactory(wasm, bundle.conversion); + },*/ srs: (wasm: Wasm) => srs(wasm, getRustConversion(wasm)), }; @@ -39,7 +56,17 @@ const tsBindings = { type Wasm = typeof wasmNamespace; +type RustConversion = ReturnType; + +function getRustConversion(wasm: Wasm): RustConversion { + return createRustConversion(wasm); +} + function createRustConversion(wasm: Wasm) { + return buildWasmConversion(wasm); +} + +function buildWasmConversion(wasm: Wasm) { let core = conversionCore(wasm); let verifierIndex = verifierIndexConversion(wasm, core); let oracles = oraclesConversion(wasm); @@ -55,10 +82,68 @@ function createRustConversion(wasm: Wasm) { }; } -type RustConversion = ReturnType; +function createNativeRustConversion(napi: any) { + return bindingsNapi(napi); +} + +/* TODO: Uncomment in phase 2 of conversion layer + +function shouldUseNativeConversion(wasm: Wasm): boolean { + const marker = (wasm as any).__kimchi_use_native; + const globalMarker = + typeof globalThis !== 'undefined' && + (globalThis as any).__kimchi_use_native; + return Boolean(marker || globalMarker); +} + +function createRustConversion(wasm: Wasm): RustConversion { + return shouldUseNativeConversion(wasm) + ? createNativeConversion(wasm) + : createWasmConversion(wasm); +} + +function createWasmConversion(wasm: Wasm) { + const core = conversionCore(wasm); + const verifierIndex = verifierIndexConversion(wasm, core); + const oracles = oraclesConversion(wasm); + const proof = proofConversion(wasm, core); + + return { + fp: { ...core.fp, ...verifierIndex.fp, ...oracles.fp, ...proof.fp }, + fq: { ...core.fq, ...verifierIndex.fq, ...oracles.fq, ...proof.fq }, + fieldsToRustFlat, + fieldsFromRustFlat, + wireToRust: core.wireToRust, + mapMlArrayToRustVector: core.mapMlArrayToRustVector, + }; +} + +type RustConversion = ReturnType; + +function createNativeConversion(wasm: Wasm) { + const core = conversionCoreNative(wasm); + const verifierIndex = verifierIndexConversionNative(wasm, core); + const oracles = oraclesConversionNative(wasm); + const proof = proofConversionNative(wasm, core); + + return { + fp: { ...core.fp, ...verifierIndex.fp, ...oracles.fp, ...proof.fp }, + fq: { ...core.fq, ...verifierIndex.fq, ...oracles.fq, ...proof.fq }, + fieldsToRustFlatNative, + fieldsFromRustFlatNative, + wireToRust: core.wireToRust, + mapMlArrayToRustVector: core.mapMlArrayToRustVector, + }; +} -let rustConversion: RustConversion | undefined; +type ConversionBundle = + | { conversion: WasmConversion; srsFactory: typeof srs } + | { conversion: NativeConversion; srsFactory: typeof srsNative }; -function getRustConversion(wasm: Wasm) { - return rustConversion ?? (rustConversion = createRustConversion(wasm)); +function getConversionBundle(wasm: Wasm): ConversionBundle { + if (shouldUseNativeConversion(wasm)) { + return { conversion: createNativeConversion(wasm), srsFactory: srsNative }; + } + return { conversion: createWasmConversion(wasm), srsFactory: srs }; } +*/ diff --git a/src/bindings/scripts/build-o1js-node-artifacts.sh b/src/bindings/scripts/build-o1js-node-artifacts.sh index 045a8d992..4c2698afe 100755 --- a/src/bindings/scripts/build-o1js-node-artifacts.sh +++ b/src/bindings/scripts/build-o1js-node-artifacts.sh @@ -51,6 +51,10 @@ run_cmd cp "${MINA_PATH}"/src/config.mlh "src" run_cmd cp -r "${MINA_PATH}"/src/config "src/config" ok "Mina config files copied" +info "Building Kimchi native bindings for Node.js..." +run_cmd dune b "${KIMCHI_BINDINGS}"/js/native +ok "Kimchi native bindings built" + info "Building Kimchi bindings for Node.js..." run_cmd dune b "${KIMCHI_BINDINGS}"/js/node_js ok "Kimchi bindings built" @@ -96,6 +100,14 @@ run_cmd mkdir -p "${BINDINGS_PATH}" run_cmd chmod -R 777 "${BINDINGS_PATH}" ok "Output directory prepared" +info "Preparing native bindings directory..." +run_cmd mkdir -p src/bindings/compiled/native +ok "Native bindings directory prepared" + +info "Copying N-API bindings..." +run_cmd cp _build/default/"${KIMCHI_BINDINGS}"/js/native/plonk_napi* "${BINDINGS_PATH}" +ok "N-API bindings copied" + info "Copying WASM bindings..." run_cmd cp _build/default/"${KIMCHI_BINDINGS}"/js/node_js/plonk_wasm* "${BINDINGS_PATH}" run_cmd mv -f "${BINDINGS_PATH}"/plonk_wasm.js "${BINDINGS_PATH}"/plonk_wasm.cjs @@ -114,6 +126,11 @@ fi run_cmd mv -f "${BINDINGS_PATH}"/o1js_node.bc.js "${BINDINGS_PATH}"/o1js_node.bc.cjs ok "Node.js bindings copied" +info "Copying native bindings..." +run_cmd cp _build/default/"${KIMCHI_BINDINGS}"/js/native/plonk_napi.node src/bindings/compiled/native/ +run_cmd chmod 777 src/bindings/compiled/native/plonk_napi.node +ok "Native bindings copied" + info "Updating WASM references in bindings..." run_cmd sed -i 's/plonk_wasm.js/plonk_wasm.cjs/' "${BINDINGS_PATH}"/o1js_node.bc.cjs ok "WASM references updated" diff --git a/src/build/copy-to-dist.js b/src/build/copy-to-dist.js index d2786c858..6a3db7a1b 100644 --- a/src/build/copy-to-dist.js +++ b/src/build/copy-to-dist.js @@ -5,6 +5,7 @@ await copyFromTo( [ 'src/bindings.d.ts', 'src/bindings/compiled/_node_bindings', + 'src/bindings/compiled/native', 'src/bindings/compiled/node_bindings/plonk_wasm.d.cts', ], 'src/', diff --git a/src/mina b/src/mina index 569e99c95..fa807948b 160000 --- a/src/mina +++ b/src/mina @@ -1 +1 @@ -Subproject commit 569e99c95834841d64858644c5d80ac7e63d0157 +Subproject commit fa807948b4298eabff9ecf79418068e58415bc91