-
Notifications
You must be signed in to change notification settings - Fork 166
(o1js) Native Prover with Napi - Verifier Index
#2658
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
querolita
wants to merge
7
commits into
querolita/napi-proof
Choose a base branch
from
querolita/napi-vindex
base: querolita/napi-proof
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
c5a5da4
bindings: first version of verifier index conversion
querolita e25896e
submodule: update mina
querolita 550855a
bindings: use native conversion for prover keys
querolita 199e872
bindings: logs for srs functions for debugging
querolita a987a9c
bindings: update polyCommFromRust
querolita aeefc4d
bindings: refactor verifier index
querolita c8cbc54
submodule: update mina
querolita File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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; | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
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 anytruly makes me worryThere was a problem hiding this comment.
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 🤔