UNPKG

o1js

Version:

TypeScript framework for zk-SNARKs and zkApps

286 lines (275 loc) 9.95 kB
import { MlArray, MlBool, MlOption } from '../../../lib/ml/base.js'; import { fieldFromRust, fieldToRust } from '../bindings/conversion-base.js'; import { Domain, Field, PolyComm, VerificationEvals, VerifierIndex, } from '../bindings/kimchi-types.js'; import { Lookup, LookupInfo, LookupSelectors } from '../bindings/lookup.js'; import { ConversionCore, ConversionCores } from './napi-conversion-core.js'; import type { Napi, NapiDomain, NapiLookupInfoObject, NapiLookupSelectorShape, NapiLookupVerifierIndexShape, NapiShiftsShape, NapiVerificationEvalsShape, NapiVerifierIndex, NapiVerifierIndexClasses, NapiVerifierIndexShape, } from './napi-wrappers.js'; export { napiVerifierIndexConversion }; function napiVerifierIndexConversion(napi: Napi, core: ConversionCores) { return { fp: verifierIndexConversionPerField(core.fp, { Domain: napi.WasmFpDomain, VerificationEvals: napi.WasmFpPlonkVerificationEvals, Shifts: napi.WasmFpShifts, VerifierIndex: napi.WasmFpPlonkVerifierIndex, LookupVerifierIndex: napi.WasmFpLookupVerifierIndex, LookupSelector: napi.WasmFpLookupSelectors, }), fq: verifierIndexConversionPerField(core.fq, { Domain: napi.WasmFqDomain, VerificationEvals: napi.WasmFqPlonkVerificationEvals, Shifts: napi.WasmFqShifts, VerifierIndex: napi.WasmFqPlonkVerifierIndex, LookupVerifierIndex: napi.WasmFqLookupVerifierIndex, LookupSelector: napi.WasmFqLookupSelectors, }), }; } function verifierIndexConversionPerField( core: ConversionCore, { Domain, VerificationEvals, Shifts, VerifierIndex, LookupVerifierIndex, LookupSelector, }: NapiVerifierIndexClasses ) { function domainToRust([, logSizeOfGroup, groupGen]: Domain): NapiDomain { // In the NAPI backend these types are `#[napi(object)]`, i.e. plain JS objects // (not constructable classes). return { log_size_of_group: logSizeOfGroup, group_gen: fieldToRust(groupGen), }; } function domainFromRust(domain: NapiDomain): Domain { return [0, domain.log_size_of_group, fieldFromRust(domain.group_gen)]; } function verificationEvalsToRust(evals: VerificationEvals): NapiVerificationEvalsShape { let sigmaComm = core.polyCommsToRust(evals[1]); let coefficientsComm = core.polyCommsToRust(evals[2]); let genericComm = core.polyCommToRust(evals[3]); let psmComm = core.polyCommToRust(evals[4]); let completeAddComm = core.polyCommToRust(evals[5]); let mulComm = core.polyCommToRust(evals[6]); let emulComm = core.polyCommToRust(evals[7]); let endomulScalarComm = core.polyCommToRust(evals[8]); let xorComm = MlOption.mapFrom(evals[9], core.polyCommToRust); let rangeCheck0Comm = MlOption.mapFrom(evals[10], core.polyCommToRust); let rangeCheck1Comm = MlOption.mapFrom(evals[11], core.polyCommToRust); let foreignFieldAddComm = MlOption.mapFrom(evals[12], core.polyCommToRust); let foreignFieldMulComm = MlOption.mapFrom(evals[13], core.polyCommToRust); let rotComm = MlOption.mapFrom(evals[14], core.polyCommToRust); const evalsObj: NapiVerificationEvalsShape = { sigma_comm: sigmaComm, coefficients_comm: coefficientsComm, generic_comm: genericComm, psm_comm: psmComm, complete_add_comm: completeAddComm, mul_comm: mulComm, emul_comm: emulComm, endomul_scalar_comm: endomulScalarComm, xor_comm: xorComm, range_check0_comm: rangeCheck0Comm, range_check1_comm: rangeCheck1Comm, foreign_field_add_comm: foreignFieldAddComm, foreign_field_mul_comm: foreignFieldMulComm, rot_comm: rotComm, }; return evalsObj; } function verificationEvalsFromRust(evals: NapiVerificationEvalsShape): VerificationEvals { let mlEvals: VerificationEvals = [ 0, core.polyCommsFromRust(evals.sigma_comm), core.polyCommsFromRust(evals.coefficients_comm), core.polyCommFromRust(evals.generic_comm), core.polyCommFromRust(evals.psm_comm), core.polyCommFromRust(evals.complete_add_comm), core.polyCommFromRust(evals.mul_comm), core.polyCommFromRust(evals.emul_comm), core.polyCommFromRust(evals.endomul_scalar_comm), MlOption.mapTo(evals.xor_comm, core.polyCommFromRust), MlOption.mapTo(evals.range_check0_comm, core.polyCommFromRust), MlOption.mapTo(evals.range_check1_comm, core.polyCommFromRust), MlOption.mapTo(evals.foreign_field_add_comm, core.polyCommFromRust), MlOption.mapTo(evals.foreign_field_mul_comm, core.polyCommFromRust), MlOption.mapTo(evals.rot_comm, core.polyCommFromRust), ]; return mlEvals; } function lookupVerifierIndexToRust(lookup: Lookup<PolyComm>): NapiLookupVerifierIndexShape { let [ , joint_lookup_used, lookup_table, selectors, table_ids, lookup_info, runtime_tables_selector, ] = lookup; const lookupObj: NapiLookupVerifierIndexShape = { joint_lookup_used: MlBool.from(joint_lookup_used), lookup_table: core.polyCommsToRust(lookup_table), lookup_selectors: lookupSelectorsToRust(selectors), table_ids: MlOption.mapFrom(table_ids, core.polyCommToRust), lookup_info: lookupInfoToRust(lookup_info), runtime_tables_selector: MlOption.mapFrom(runtime_tables_selector, core.polyCommToRust), }; return lookupObj; } function lookupVerifierIndexFromRust(lookup: NapiLookupVerifierIndexShape): Lookup<PolyComm> { let mlLookup: Lookup<PolyComm> = [ 0, MlBool(lookup.joint_lookup_used), core.polyCommsFromRust(lookup.lookup_table), lookupSelectorsFromRust(lookup.lookup_selectors), MlOption.mapTo(lookup.table_ids, core.polyCommFromRust), lookupInfoFromRust(lookup.lookup_info), MlOption.mapTo(lookup.runtime_tables_selector, core.polyCommFromRust), ]; return mlLookup; } function lookupSelectorsToRust([ , lookup, xor, range_check, ffmul, ]: LookupSelectors<PolyComm>): NapiLookupSelectorShape { const selectorObj: NapiLookupSelectorShape = { xor: MlOption.mapFrom(xor, core.polyCommToRust), lookup: MlOption.mapFrom(lookup, core.polyCommToRust), range_check: MlOption.mapFrom(range_check, core.polyCommToRust), ffmul: MlOption.mapFrom(ffmul, core.polyCommToRust), }; return selectorObj; } function lookupSelectorsFromRust(selector: NapiLookupSelectorShape): LookupSelectors<PolyComm> { let lookup = MlOption.mapTo(selector.lookup, core.polyCommFromRust); let xor = MlOption.mapTo(selector.xor, core.polyCommFromRust); let range_check = MlOption.mapTo(selector.range_check, core.polyCommFromRust); let ffmul = MlOption.mapTo(selector.ffmul, core.polyCommFromRust); return [0, lookup, xor, range_check, ffmul]; } function lookupInfoToRust( [, maxPerRow, maxJointSize, features]: LookupInfo ): NapiLookupInfoObject { let [, patterns, joint_lookup_used, uses_runtime_tables] = features; let [, xor, lookup, range_check, foreign_field_mul] = patterns; return { max_per_row: maxPerRow, max_joint_size: maxJointSize, features: { patterns: { xor: MlBool.from(xor), lookup: MlBool.from(lookup), range_check: MlBool.from(range_check), foreign_field_mul: MlBool.from(foreign_field_mul), }, joint_lookup_used: MlBool.from(joint_lookup_used), uses_runtime_tables: MlBool.from(uses_runtime_tables), }, }; } function lookupInfoFromRust(info: NapiLookupInfoObject): LookupInfo { let features = info.features; let patterns = features.patterns; let mlInfo: LookupInfo = [ 0, info.max_per_row, info.max_joint_size, [ 0, [ 0, MlBool(patterns.xor), MlBool(patterns.lookup), MlBool(patterns.range_check), MlBool(patterns.foreign_field_mul), ], MlBool(features.joint_lookup_used), MlBool(features.uses_runtime_tables), ], ]; return mlInfo; } let self = { shiftsToRust([, ...shifts]: MlArray<Field>): NapiShiftsShape { let s = shifts.map((s) => fieldToRust(s)); const shiftsObj: NapiShiftsShape = { s0: s[0], s1: s[1], s2: s[2], s3: s[3], s4: s[4], s5: s[5], s6: s[6], }; return shiftsObj; }, shiftsFromRust(s: NapiShiftsShape): MlArray<Field> { let shifts = [s.s0, s.s1, s.s2, s.s3, s.s4, s.s5, s.s6]; return [0, ...shifts.map(fieldFromRust)]; }, verifierIndexToRust(vk: VerifierIndex): NapiVerifierIndex { let domain = domainToRust(vk[1]); let maxPolySize = vk[2]; let nPublic = vk[3]; let prevChallenges = vk[4]; let srs = vk[5]; let evals = verificationEvalsToRust(vk[6]); let shifts = self.shiftsToRust(vk[7]); let lookupIndex = MlOption.mapFrom(vk[8], lookupVerifierIndexToRust); let zkRows = vk[9]; const vkObj: NapiVerifierIndexShape = { domain, max_poly_size: maxPolySize, public_: nPublic, prev_challenges: prevChallenges, srs, evals, shifts, lookup_index: lookupIndex, zk_rows: zkRows, }; return vkObj as unknown as NapiVerifierIndex; }, verifierIndexFromRust(vk: NapiVerifierIndex): VerifierIndex { const vk_ = vk as unknown as NapiVerifierIndexShape; let mlVk: VerifierIndex = [ 0, domainFromRust(vk_.domain), vk_.max_poly_size, vk_.public_, vk_.prev_challenges, vk_.srs, verificationEvalsFromRust(vk_.evals), self.shiftsFromRust(vk_.shifts), MlOption.mapTo(vk_.lookup_index, lookupVerifierIndexFromRust), vk_.zk_rows, ]; return mlVk; }, }; return self; }