o1js
Version:
TypeScript framework for zk-SNARKs and zkApps
286 lines (275 loc) • 9.95 kB
text/typescript
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;
}