UNPKG

o1js

Version:

TypeScript framework for zk-SNARKs and zkApps

118 lines (101 loc) 4.69 kB
/** * This file contains bindings for JSOO written in TS and integrated with our normal code base. * It is exposed to JSOO by populating a global variable with an object. * It gets imported as the first thing in ../../bindings.js so that the global variable is ready by the time JSOO code gets executed. */ import type * as rustNamespace from '../compiled/node_bindings/kimchi_wasm.cjs'; import { prefixHashes, prefixHashesLegacy } from '../crypto/constants.js'; import { Bigint256Bindings } from './bindings/bigint256.js'; import { fieldsFromRustFlat, fieldsToRustFlat } from './bindings/conversion-base.js'; import { conversionCore as wasmConversionCore } from './bindings/conversion-core.js'; import { oraclesConversion as wasmOraclesConversion } from './bindings/conversion-oracles.js'; import { proofConversion as wasmProofConversion } from './bindings/conversion-proof.js'; import { verifierIndexConversion as wasmVerifierIndexConversion } from './bindings/conversion-verifier-index.js'; import { PallasBindings, VestaBindings } from './bindings/curve.js'; import { jsEnvironment } from './bindings/env.js'; import { FpBindings, FqBindings } from './bindings/field.js'; import { FpVectorBindings, FqVectorBindings } from './bindings/vector.js'; import { srs as wasmSrs } from './bindings/srs.js'; import { srs as napiSrs } from './native/napi-srs.js'; import { napiConversionCore } from './native/napi-conversion-core.js'; import { napiProofConversion } from './native/napi-conversion-proof.js'; import { napiVerifierIndexConversion } from './native/napi-conversion-verifier-index.js'; import { napiOraclesConversion } from './native/napi-conversion-oracles.js'; export { Napi, Wasm, RustConversion, getRustConversion }; const tsBindings = { jsEnvironment, prefixHashes, prefixHashesLegacy, ...Bigint256Bindings, ...FpBindings, ...FqBindings, ...VestaBindings, ...PallasBindings, ...FpVectorBindings, ...FqVectorBindings, rustConversion: (rust: Rust) => getConversionBundle(rust).conversion, srs: (rust: Rust) => getConversionBundle(rust).srs, }; // this is put in a global variable so that mina/src/lib/crypto/kimchi_bindings/js/bindings.js finds it (globalThis as any).__snarkyTsBindings = tsBindings; type Rust = typeof rustNamespace; type Wasm = Rust; type Napi = Rust; type BackendKind = 'wasm' | 'native'; // Whether or not native backend is in use function getKimchiBackend(rust: Rust): BackendKind { const backend = (rust as any).__kimchi_backend ?? (globalThis as any)?.__kimchi_backend; return backend === 'native' ? 'native' : 'wasm'; } type WasmConversion = ReturnType<typeof buildWasmRustConversion>; type NapiConversion = ReturnType<typeof buildNapiRustConversion>; type RustConversion<B extends BackendKind = BackendKind> = B extends 'wasm' ? WasmConversion : NapiConversion; function getRustConversion(rust: Rust): RustConversion { return getKimchiBackend(rust) === 'wasm' ? buildWasmRustConversion(rust) : buildNapiRustConversion(rust); } function buildWasmRustConversion(wasm: Rust) { let core = wasmConversionCore(wasm); let proof = wasmProofConversion(wasm, core); let oracles = wasmOraclesConversion(wasm); let verifierIndex = wasmVerifierIndexConversion(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, }; } function buildNapiRustConversion(napi: Rust) { let core = napiConversionCore(napi); let proof = napiProofConversion(napi, core); let oracles = napiOraclesConversion(napi); let verifierIndex = napiVerifierIndexConversion(napi, core); return { fp: { ...core.fp, ...proof.fp, ...verifierIndex.fp, ...oracles.fp }, fq: { ...core.fq, ...proof.fq, ...verifierIndex.fq, ...oracles.fq }, fieldsToRustFlat, fieldsFromRustFlat, wireToRust: core.wireToRust, mapMlArrayToRustVector: core.mapMlArrayToRustVector, }; } type ConversionBundle<B extends BackendKind> = { kind: B; rust: Rust; conversion: RustConversion<B>; srs: B extends 'wasm' ? ReturnType<typeof wasmSrs> : ReturnType<typeof napiSrs>; }; function getConversionBundle(rust: Rust): ConversionBundle<BackendKind> { if (getKimchiBackend(rust) === 'wasm') { const conversion = buildWasmRustConversion(rust); return { kind: 'wasm', rust, conversion, srs: wasmSrs(rust, conversion) }; } const conversion = buildNapiRustConversion(rust); return { kind: 'native', rust, conversion, srs: napiSrs(rust, conversion) }; }