Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions src/bindings/crypto/bindings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@ import { verifierIndexConversion } 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 { napiOraclesConversion } from './bindings/napi-conversion-oracles.js';
import { srs } from './bindings/srs.js';
import { srs as napiSrs } from './napi-srs.js';
import { FpVectorBindings, FqVectorBindings } from './bindings/vector.js';
import { napiConversionCore } from './napi-conversion-core.js';
import { napiProofConversion } from './napi-conversion-proof.js';
import { napiOraclesConversion } from './bindings/napi-conversion-oracles.js';
import { napiVerifierIndexConversion } from './napi-conversion-verifier-index.js';
import type * as napiNamespace from '../compiled/node_bindings/plonk_wasm.cjs';

export { RustConversion, Wasm, Napi, createNativeRustConversion, getRustConversion };
Expand Down Expand Up @@ -90,10 +91,11 @@ function buildWasmConversion(wasm: Wasm) {
function createNativeRustConversion(napi: any) {
let core = napiConversionCore(napi);
let proof = napiProofConversion(napi, core);
let verif = napiVerifierIndexConversion(napi, core);
let oracles = napiOraclesConversion(napi);
return {
fp: { ...core.fp, ...proof.fp, ...oracles.fp },
fq: { ...core.fq, ...proof.fq, ...oracles.fq },
fp: { ...core.fp, ...proof.fp, ...verif.fp, ...oracles.fp },
fq: { ...core.fq, ...proof.fq, ...verif.fq, ...oracles.fq },
};
}

Expand Down
2 changes: 1 addition & 1 deletion src/bindings/crypto/bindings/srs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ function srsPerField(f: 'fp' | 'fq', wasm: Wasm, conversion: RustConversion) {
let maybeLagrangeCommitment = (srs: WasmSrs, domain_size: number, i: number) => {
try {
console.log(3);
console.log('srs', srs);
console.log('srs wasm', srs);
let bytes = (wasm as any)[`caml_${f}_srs_to_bytes_external`](srs);
console.log('bytes', bytes);
let wasmSrs = undefined;
Expand Down
25 changes: 7 additions & 18 deletions src/bindings/crypto/napi-conversion-core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,15 +70,13 @@ function napiConversionCore(napi: any) {
};

return {
fp: { ...fpCore },
fp: {
...fpCore,
},
fq: {
...fqCore,
shiftsFromRust: (s: any) => {
let shifts = [s.s0, s.s1, s.s2, s.s3, s.s4, s.s5, s.s6];
return [0, ...shifts.map(fieldFromRust)];
},
},
...shared,
},
...shared,
};
}

Expand Down Expand Up @@ -182,22 +180,13 @@ function conversionCorePerField({ makeAffine, PolyComm }: NapiClasses) {
return new PolyCommClass(unshifted as unknown, undefined);
};

/* const polyCommFromRust = (polyComm: NapiPolyComm): PolyComm => {
const polyCommFromRust = (polyComm: any): any => {
if (polyComm == null) return undefined;
console.log('polyComm', polyComm);
const rustUnshifted = asArrayLike<NapiAffine>(polyComm.unshifted, 'polyComm.unshifted');
console.log('rustUnshifted', rustUnshifted);
const mlUnshifted = rustUnshifted.map(affineFromRust);
return [0, [0, ...mlUnshifted]];
}; */
const polyCommFromRust = (polyComm: any): any => {
let rustUnshifted = polyComm.unshifted;
console.log('rustUnshifted', rustUnshifted);
let mlUnshifted = mapFromUintArray(rustUnshifted, (ptr) => {
console.log('ptr', ptr);
/* return affineFromRust(wrap(ptr, CommitmentCurve));
*/
});
return [0, [0, ...mlUnshifted]];
};

const polyCommsToRust = ([, ...comms]: MlArray<PolyComm>): NapiPolyComm[] =>
Expand Down
2 changes: 0 additions & 2 deletions src/bindings/crypto/napi-conversion-proof.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,6 @@ function proofConversionPerField(
}
return new LookupTable(id, wasmData);
}



return {
proofToRust([, public_evals, proof]: ProofWithPublic): NapiProverProof {
Expand Down
280 changes: 280 additions & 0 deletions src/bindings/crypto/napi-conversion-verifier-index.ts
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file is definitely a mouthful

I would probably look into code generation at around this point, maybe theres something we can make work here?

the as any truly makes me worry

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah that's true. I would love to get type-safety here the same way the Wasm side does admit wasm-like types. I don't know what we can do at compile time though given that the backend is settled at runtime 🤔

Original file line number Diff line number Diff line change
@@ -0,0 +1,280 @@
import { MlArray, MlBool, MlOption } from '../../lib/ml/base.js';
import type * as napiNamespace from '../compiled/node_bindings/plonk_wasm.cjs';
import type {
WasmFpDomain,
WasmFpLookupSelectors,
WasmFpLookupVerifierIndex,
WasmFpPlonkVerificationEvals,
WasmFpPlonkVerifierIndex,
WasmFpShifts,
WasmFqDomain,
WasmFqLookupSelectors,
WasmFqLookupVerifierIndex,
WasmFqPlonkVerificationEvals,
WasmFqPlonkVerifierIndex,
WasmFqShifts,
LookupInfo as WasmLookupInfo,
} from '../compiled/node_bindings/plonk_wasm.cjs';
import { fieldFromRust, fieldToRust } from './bindings/conversion-base.js';
import { ConversionCore, ConversionCores } from './napi-conversion-core.js';
import { Domain, Field, PolyComm, VerificationEvals, VerifierIndex } from './bindings/kimchi-types.js';
import { Lookup, LookupInfo, LookupSelectors } from './bindings/lookup.js';

export { napiVerifierIndexConversion };

type napi = typeof napiNamespace;

type NapiDomain = WasmFpDomain | WasmFqDomain;
type NapiVerificationEvals = WasmFpPlonkVerificationEvals | WasmFqPlonkVerificationEvals;
type NapiShifts = WasmFpShifts | WasmFqShifts;
type NapiVerifierIndex = WasmFpPlonkVerifierIndex | WasmFqPlonkVerifierIndex;
type NapiLookupVerifierIndex = WasmFpLookupVerifierIndex | WasmFqLookupVerifierIndex;
type NapiLookupSelector = WasmFpLookupSelectors | WasmFqLookupSelectors;

type NapiClasses = {
Domain: typeof WasmFpDomain | typeof WasmFqDomain;
VerificationEvals: typeof WasmFpPlonkVerificationEvals | typeof WasmFqPlonkVerificationEvals;
Shifts: typeof WasmFpShifts | typeof WasmFqShifts;
VerifierIndex: typeof WasmFpPlonkVerifierIndex | typeof WasmFqPlonkVerifierIndex;
LookupVerifierIndex: typeof WasmFpLookupVerifierIndex | typeof WasmFqLookupVerifierIndex;
LookupSelector: typeof WasmFpLookupSelectors | typeof WasmFqLookupSelectors;
};

function napiVerifierIndexConversion(napi: any, core: ConversionCores) {
return {
fp: verifierIndexConversionPerField(napi, core.fp, {
Domain: napi.WasmFpDomain,
VerificationEvals: napi.WasmFpPlonkVerificationEvals,
Shifts: napi.WasmFpShifts,
VerifierIndex: napi.WasmFpPlonkVerifierIndex,
LookupVerifierIndex: napi.WasmFpLookupVerifierIndex,
LookupSelector: napi.WasmFpLookupSelectors,
}),
fq: verifierIndexConversionPerField(napi, core.fq, {
Domain: napi.WasmFqDomain,
VerificationEvals: napi.WasmFqPlonkVerificationEvals,
Shifts: napi.WasmFqShifts,
VerifierIndex: napi.WasmFqPlonkVerifierIndex,
LookupVerifierIndex: napi.WasmFqLookupVerifierIndex,
LookupSelector: napi.WasmFqLookupSelectors,
}),
};
}

function verifierIndexConversionPerField(
napi: any,
core: ConversionCore,
{
Domain,
VerificationEvals,
Shifts,
VerifierIndex,
LookupVerifierIndex,
LookupSelector,
}: NapiClasses
) {
function domainToRust([, logSizeOfGroup, groupGen]: Domain): NapiDomain {
return new Domain(logSizeOfGroup, fieldToRust(groupGen));
}
function domainFromRust(domain: NapiDomain): Domain {
return [0, domain.log_size_of_group, fieldFromRust(domain.group_gen)];
}

function verificationEvalsToRust(evals: VerificationEvals): NapiVerificationEvals {
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);
return new VerificationEvals(
sigmaComm as any,
coefficientsComm as any,
genericComm as any,
psmComm as any,
completeAddComm as any,
mulComm as any,
emulComm as any,
endomulScalarComm as any,
xorComm as any,
rangeCheck0Comm as any,
rangeCheck1Comm as any,
foreignFieldAddComm as any,
foreignFieldMulComm as any,
rotComm as any
);
}
function verificationEvalsFromRust(evals: NapiVerificationEvals): 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>): NapiLookupVerifierIndex {
let [
,
joint_lookup_used,
lookup_table,
selectors,
table_ids,
lookup_info,
runtime_tables_selector,
] = lookup;
return new LookupVerifierIndex(
MlBool.from(joint_lookup_used),
core.polyCommsToRust(lookup_table) as any,
lookupSelectorsToRust(selectors),
MlOption.mapFrom(table_ids, core.polyCommToRust) as any,
lookupInfoToRust(lookup_info),
MlOption.mapFrom(runtime_tables_selector, core.polyCommToRust) as any
);
}
function lookupVerifierIndexFromRust(lookup: NapiLookupVerifierIndex): 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>): NapiLookupSelector {
return new LookupSelector(
MlOption.mapFrom(xor, core.polyCommToRust) as any,
MlOption.mapFrom(lookup, core.polyCommToRust) as any,
MlOption.mapFrom(range_check, core.polyCommToRust) as any,
MlOption.mapFrom(ffmul, core.polyCommToRust) as any
);
}
function lookupSelectorsFromRust(selector: NapiLookupSelector): 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): WasmLookupInfo {
let [, patterns, joint_lookup_used, uses_runtime_tables] = features;
let [, xor, lookup, range_check, foreign_field_mul] = patterns;
let napiPatterns = new napi.LookupPatterns(
MlBool.from(xor),
MlBool.from(lookup),
MlBool.from(range_check),
MlBool.from(foreign_field_mul)
);
let napiFeatures = new napi.LookupFeatures(
napiPatterns,
MlBool.from(joint_lookup_used),
MlBool.from(uses_runtime_tables)
);
return new napi.LookupInfo(maxPerRow, maxJointSize, napiFeatures);
}
function lookupInfoFromRust(info: WasmLookupInfo): 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>): NapiShifts {
let s = shifts.map((s) => fieldToRust(s));
return new Shifts(s[0], s[1], s[2], s[3], s[4], s[5], s[6]);
},
shiftsFromRust(s: NapiShifts): 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];
return new VerifierIndex(
domain,
maxPolySize,
nPublic,
prevChallenges,
srs,
evals,
shifts,
lookupIndex,
zkRows
);
},
verifierIndexFromRust(vk: NapiVerifierIndex): VerifierIndex {
console.log('vk from rust', vk);
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;
}
Loading
Loading