prover.hoon 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507
  1. /= compute-table /common/table/prover/compute
  2. /= memory-table /common/table/prover/memory
  3. /= * /common/zeke
  4. /= nock-common /common/nock-common
  5. ::
  6. ::TODO shouldn't need all of this but its useful to keep here for now
  7. ::while we're figuring out how to turn all tables off or on in general
  8. => :* stark-engine
  9. nock-common=nock-common
  10. compute-table=compute-table
  11. memory-table=memory-table
  12. ==
  13. ~% %stark-prover ..stark-engine-jet-hook ~
  14. |%
  15. +$ prove-result (each =proof err=prove-err)
  16. +$ prove-err $%([%too-big heights=(list @)])
  17. +$ prover-output [=proof deep-codeword=fpoly]
  18. :: +prove: prove the Nock computation [s f]
  19. ::
  20. ::
  21. :: .override: an optional list of which tables should be computed and constraints
  22. :: checked. this is for debugging use only, it should always be ~ in production.
  23. :: to use it for debugging, pass in the same list of tables to both +prove
  24. :: and +verify. these are the tables that will be computed - all others will
  25. :: be ignored. you do not need to worry about sorting it in the correct order, that
  26. :: happens automatically.
  27. ++ prove
  28. ~/ %prove
  29. |= $: header=noun-digest:tip5
  30. nonce=noun-digest:tip5
  31. pow-len=@
  32. override=(unit (list term))
  33. ==
  34. ^- prove-result
  35. =/ [s=* f=*] (puzzle-nock header nonce pow-len)
  36. =/ [prod=* return=fock-return] (fink:fock [s f])
  37. (generate-proof header nonce pow-len s f prod return override)
  38. ::
  39. :: generate-proof is the main body of the prover.
  40. ++ generate-proof
  41. |= $: header=noun-digest:tip5
  42. nonce=noun-digest:tip5
  43. pow-len=@
  44. s=*
  45. f=*
  46. prod=*
  47. return=fock-return
  48. override=(unit (list term))
  49. ==
  50. ^- prove-result
  51. =| =proof :: the proof stream
  52. =. proof (~(push proof-stream proof) [%puzzle header nonce pow-len prod])
  53. ::
  54. :: build tables
  55. ::~& %building-tables
  56. =/ tables=(list table-dat)
  57. (build-table-dats return override)
  58. ::
  59. :: check that the tables have correct base width. Comment this out for production.
  60. ::?: %+ levy tables
  61. :: |= t=table-dat
  62. :: !=(step.p.p.t base-width.p.t)
  63. :: ~& %widths-mismatch
  64. :: ~|("prove: mismatch between table full widths and actual widths" !!)
  65. ::
  66. =/ num-tables (lent tables)
  67. =. table-names (turn tables |=(t=table-dat name.p.t))
  68. =/ heights=(list @)
  69. %+ turn tables
  70. |= t=table-dat
  71. =/ len len.array.p.p.t
  72. ?:(=(len 0) 0 (bex (xeb (dec len))))
  73. ::~& heights+heights
  74. ::
  75. =. proof (~(push proof-stream proof) [%heights heights])
  76. =/ pre=preprocess-0 prep.stark-config
  77. ::
  78. :: remove preprocess data for unused tables
  79. =. pre
  80. (remove-unused-constraints:nock-common pre table-names override)
  81. =/ clc ~(. calc heights cd.pre)
  82. =* num-colinearity-tests=@ num-colinearity-tests:fri:clc
  83. =* fri-domain-len=@ init-domain-len:fri:clc
  84. ::
  85. :: convert the base columns to marys, this is a temporary preprocessing step until
  86. :: we change the table struct to contain a mary rather than a (list fpoly)
  87. ::
  88. :: think of each mary as a list of the table's rows
  89. =/ [base-marys=(list mary) width=@]
  90. %^ spin tables
  91. 0
  92. |=([t=table-dat width=@] [p.p.t (add width base-width.p.t)])
  93. =/ base=codeword-commitments
  94. (compute-codeword-commitments base-marys fri-domain-len width)
  95. =. proof (~(push proof-stream proof) [%m-root h.q.merk-heap.base])
  96. ::
  97. :: generate first round of randomness
  98. =/ rng ~(prover-fiat-shamir proof-stream proof)
  99. ::
  100. :: get coefficients for table extensions, extend tables
  101. :: round one challenges: a, b, c, ..., α
  102. =^ chals-rd1=(list belt) rng (belts:rng num-chals-rd1:chal)
  103. ::
  104. :: extension columns: list or mary? probably should be a list
  105. ::
  106. :: build extension columns
  107. =/ table-exts=(list table-mary)
  108. %+ turn tables
  109. |= t=table-dat
  110. ^- table-mary
  111. (extend:q.t p.t chals-rd1 return)
  112. =. tables
  113. %+ turn
  114. (zip-up tables table-exts)
  115. |= [t=table-dat ext=table-mary]
  116. ^- table-dat
  117. :_ [q.t r.t]
  118. (weld-exts:tlib p.t ext)
  119. ::
  120. :: check that the tables have correct num of ext cols. Comment this out for production.
  121. ::
  122. ::?: %+ levy (zip-up tables table-exts)
  123. :: |= [table=table-dat ext=table-mary]
  124. :: !=(step.p.ext ext-width.p.table)
  125. :: ::~& %widths-mismatch
  126. :: ~|("prove: mismatch between table ext widths and actual ext widths" !!)
  127. ::~& %ext-cols
  128. ::
  129. :: convert the ext columns to marys
  130. ::
  131. :: think of each mary as a list of the table's rows
  132. =/ [ext-marys=(list mary) width=@]
  133. %^ spin table-exts
  134. 0
  135. |=([t=table-mary width=@] [p.t (add width ext-width.t)])
  136. ::
  137. =/ ext=codeword-commitments
  138. (compute-codeword-commitments ext-marys fri-domain-len width)
  139. =. proof (~(push proof-stream proof) [%m-root h.q.merk-heap.ext])
  140. ::
  141. :: reseed the rng
  142. =. rng ~(prover-fiat-shamir proof-stream proof)
  143. ::
  144. :: get coefficients for table extensions, extend tables
  145. :: round two challenges: β, z
  146. =^ chals-rd2=(list belt) rng (belts:rng num-chals-rd2:chal)
  147. =/ challenges (weld chals-rd1 chals-rd2)
  148. =/ chal-map=(map @ belt)
  149. (make-challenge-map:chal challenges s f)
  150. ::
  151. :: build mega-extension columns
  152. =/ table-mega-exts
  153. %+ turn tables
  154. |= t=table-dat
  155. ^- table-mary
  156. (mega-extend:q.t p.t (weld chals-rd1 chals-rd2) return)
  157. ::~& %tables-built
  158. =. tables
  159. %+ turn (zip-up tables table-mega-exts)
  160. |= [t=table-dat mega-ext=table-mary]
  161. ^- table-dat
  162. :_ [q.t r.t]
  163. (weld-exts:tlib p.t mega-ext)
  164. ::
  165. :: check that the tables have correct num of ext cols. Comment this out for production.
  166. :: ::~& >> %check-mega-ext-cols
  167. ::?: %+ levy (zip-up tables table-mega-exts)
  168. :: |= [table=table-dat mext=table-mary]
  169. :: !=(step.p.mext mega-ext-width.p.table)
  170. :: ::~& %widths-mismatch
  171. :: ~|("prove: mismatch between table ext widths and actual ext widths" !!)
  172. ::
  173. :: convert the mega-ext columns to marys
  174. ::
  175. :: think of each mary as a list of the table's rows
  176. =/ [mega-ext-marys=(list mary) width=@]
  177. %^ spin table-mega-exts
  178. 0
  179. |= [t=table-mary width=@]
  180. [p.t (add width mega-ext-width.t)]
  181. =/ mega-ext=codeword-commitments
  182. (compute-codeword-commitments mega-ext-marys fri-domain-len width)
  183. =. proof (~(push proof-stream proof) [%m-root h.q.merk-heap.mega-ext])
  184. ::
  185. :: get terminal values for use in permutation/evaluation arguments
  186. =/ dyn-map=(map @ bpoly)
  187. %- ~(gas by *(map @ bpoly))
  188. %+ iturn tables
  189. |= [i=@ t=table-dat]
  190. [i (terminal:q.t p.t)]
  191. ::
  192. :: weld terminals from each table together
  193. =/ terminals=bpoly
  194. %+ roll (range (lent tables))
  195. |= [i=@ acc=bpoly]
  196. (~(weld bop acc) (~(got by dyn-map) i))
  197. ::
  198. =. proof (~(push proof-stream proof) terms+terminals)
  199. ::
  200. :: reseed the rng
  201. =. rng ~(prover-fiat-shamir proof-stream proof)
  202. ::
  203. ::
  204. ::
  205. :: This chunk of code plugs all the rows into the constraints to check if they really do
  206. :: evaluate to 0. Verifying the proof also checks this and is much faster, but this code
  207. :: is useful if you are debugging constraints. Keep it commented out unless you need it.
  208. :: It should never be run in production.
  209. ::
  210. ::?> %+ levy (zip-up (range (lent tables)) tables)
  211. :: |= [i=@ t=table-dat]
  212. :: %- (test:zkvm-debug p.t s f)
  213. :: [challenges (~(got by dyn-map) i) r.t]
  214. ::~& %passed-tests
  215. ::
  216. =/ num-constraints=@
  217. %+ roll (range num-tables)
  218. |= [i=@ acc=@]
  219. =/ cs (~(got by count-map.pre) i)
  220. ;: add
  221. acc
  222. boundary.cs
  223. row.cs
  224. transition.cs
  225. terminal.cs
  226. ==
  227. ::
  228. :: compute weights used in linear combination of composition polynomial
  229. =^ comp-weights=bpoly rng
  230. =^ belt-list rng (belts:rng (mul 2 num-constraints))
  231. [(init-bpoly belt-list) rng]
  232. ::
  233. =/ total-cols=@
  234. %+ roll tables
  235. |= [[p=table-mary *] sum=@]
  236. (add sum step:p.p)
  237. ::
  238. :: The constraints take variables for a full row plus the following row. So to evaluate them
  239. :: the trace polys are not enough. We need to compose each trace poly with f(X)=g*X to create
  240. :: polys that will give the value of the following row. Then we weld these second-row polys
  241. :: to the original polys to get the double trace polys. These can then be used to compose with
  242. :: the constraints and evaluate at the DEEP challenge later on.
  243. ::~& %transposing-table
  244. :: TODO: we already transposed the tables when we interpolated the polynomials and we should
  245. :: just reuse that. But that requires changing the interface to the interpolation functions.
  246. =/ marys=(list table-mary)
  247. %+ turn tables
  248. |=(t=table-dat p.t)
  249. =/ transposed-tables=(list mary)
  250. %+ turn marys
  251. |= =table-mary
  252. (transpose-bpolys p.table-mary)
  253. ::
  254. ::~& %composing-trace-polys
  255. :: each mary is a list of a table's columns, interpolated to polys
  256. =/ trace-polys
  257. %+ turn (zip-up polys.base (zip-up polys.ext polys.mega-ext))
  258. |= [bm=mary em=mary mem=mary]
  259. ^- mary
  260. (~(weld ave bm) (~(weld ave em) mem))
  261. =/ second-row-trace-polys=(list mary)
  262. %+ turn transposed-tables
  263. |= polys=mary
  264. %- zing-bpolys
  265. %+ turn (range len.array.polys)
  266. |= i=@
  267. =/ bp=bpoly (~(snag-as-bpoly ave polys) i)
  268. (bp-ifft (bp-shift-by-unity bp 1))
  269. ::
  270. ::~& %appending-first-and-second-row-trace-polys
  271. ::
  272. =/ tworow-trace-polys=(list mary)
  273. %^ zip
  274. trace-polys
  275. second-row-trace-polys
  276. |= [t-poly=mary s-poly=mary]
  277. (~(weld ave t-poly) s-poly)
  278. ::
  279. ::
  280. :: Compute trace and tworow-trace polynomials in eval form over a 4*d root of unity
  281. :: (where d is the lowest power of 2 greater than the max degree of the constraints)
  282. ::~& %extending-trace-polys
  283. ::
  284. :: TODO: Save these variables in the preprocess step
  285. =/ max-constraint-degree (get-max-constraint-degree cd.pre)
  286. =/ ntt-len
  287. %- bex %- xeb %- dec
  288. (get-max-constraint-degree cd.pre)
  289. =/ max-height=@
  290. %- bex %- xeb %- dec
  291. (roll heights max)
  292. =/ tworow-trace-polys-eval=(list bpoly)
  293. %+ iturn tworow-trace-polys
  294. |= [i=@ polys=mary]
  295. (precompute-ntts polys max-height ntt-len)
  296. ::
  297. :: compute the Composition Polynomial
  298. :: This polynomial composes the trace polynomials with the constraints, takes quotients
  299. :: over the rows where the constraint should be zero, adjusts the degree so they all
  300. :: have the same maximal degree, and combines them into one big random linear combination.
  301. =/ composition-chals=(map @ bpoly)
  302. %- ~(gas by *(map @ bpoly))
  303. =- -<
  304. %+ roll (range num-tables)
  305. |= [i=@ acc=(list [@ bpoly]) num=@]
  306. =/ cs (~(got by count-map.pre) i)
  307. =/ num-constraints=@
  308. ;: add
  309. boundary.cs
  310. row.cs
  311. transition.cs
  312. terminal.cs
  313. ==
  314. :_ (add num (mul 2 num-constraints))
  315. [[i (~(swag bop comp-weights) num (mul 2 num-constraints))] acc]
  316. ::
  317. =/ omicrons-belt
  318. %+ turn tables
  319. |= [t=table-mary *]
  320. ~(omicron quot t)
  321. =/ omicrons-bpoly=bpoly (init-bpoly omicrons-belt)
  322. =/ omicrons-fpoly=fpoly
  323. (init-fpoly (turn omicrons-belt lift))
  324. ::~& %computing-composition-poly
  325. =/ composition-poly=bpoly
  326. %- compute-composition-poly
  327. :* omicrons-bpoly
  328. heights
  329. tworow-trace-polys-eval
  330. constraint-map.pre
  331. count-map.pre
  332. composition-chals
  333. chal-map
  334. dyn-map
  335. ==
  336. ::
  337. :: decompose composition polynomial into one polynomial for each degree of the
  338. :: constraints. If the max degree of the constraints is D, then this will produce
  339. :: D polynomials each of degree table-height.
  340. ::~& %decomposing-composition-poly
  341. =/ num-composition-pieces (get-max-constraint-degree cd.pre)
  342. ::
  343. =/ composition-pieces=(list bpoly)
  344. (bp-decompose composition-poly num-composition-pieces)
  345. ::
  346. :: turn composition pieces into codewords
  347. ::~& %computing-composition-codewords
  348. =/ composition-codewords=mary
  349. %- zing-bpolys
  350. %+ turn composition-pieces
  351. |= poly=bpoly
  352. (bp-coseword poly g fri-domain-len)
  353. =/ composition-codeword-array=mary
  354. (transpose-bpolys composition-codewords)
  355. =/ composition-merk=(pair @ merk-heap:merkle)
  356. (bp-build-merk-heap:merkle composition-codeword-array)
  357. =. proof
  358. (~(push proof-stream proof) [%comp-m h.q.composition-merk num-composition-pieces])
  359. ::
  360. :: reseed the rng
  361. =. rng ~(prover-fiat-shamir proof-stream proof)
  362. ::
  363. :: compute DEEP challenge point from extension field
  364. =^ deep-challenge=felt rng
  365. =^ deep-candidate rng $:felt:rng
  366. =/ n fri-domain-len:clc
  367. =/ exp-offset (lift (bpow generator:stark-engine n))
  368. |-
  369. =/ exp-deep-can (fpow deep-candidate n)
  370. ?. ?|(=(exp-deep-can f1) =(exp-deep-can exp-offset))
  371. [deep-candidate rng]
  372. =^ felt rng $:felt:rng
  373. $(deep-candidate felt)
  374. ::~& %evaluating-trace-at-deep-challenge
  375. ::
  376. :: trace-evaluations: list of evaluations of interpolated column polys and
  377. :: shifted column polys at deep point, grouped in order by tables
  378. =/ trace-evaluations=fpoly
  379. %- init-fpoly
  380. %- zing
  381. %+ turn tworow-trace-polys
  382. |= polys=mary
  383. %+ turn (range len.array.polys)
  384. |= i=@
  385. =/ b=bpoly (~(snag-as-bpoly ave polys) i)
  386. (bpeval-lift b deep-challenge)
  387. ::
  388. ::~& %evaluating-pieces-at-deep-challenge
  389. =/ composition-pieces-fpoly (turn composition-pieces bpoly-to-fpoly)
  390. =/ composition-piece-evaluations=fpoly
  391. =/ c (fpow deep-challenge num-composition-pieces)
  392. %- init-fpoly
  393. %+ turn composition-pieces-fpoly
  394. |=(poly=fpoly (fpeval poly c))
  395. ::
  396. =. proof
  397. (~(push proof-stream proof) [%evals trace-evaluations])
  398. =. proof
  399. (~(push proof-stream proof) [%evals composition-piece-evaluations])
  400. ::
  401. :: reseed the rng
  402. =. rng ~(prover-fiat-shamir proof-stream proof)
  403. ::
  404. :: compute weights used in linear combination of deep polynomial. These
  405. :: are from the extension field.
  406. =^ deep-weights=fpoly rng
  407. =^ felt-list rng
  408. %- felts:rng
  409. (add (mul 2 total-cols) max-constraint-degree)
  410. [(init-fpoly felt-list) rng]
  411. ::~& %computing-deep-poly
  412. =/ deep-poly=fpoly
  413. %- compute-deep
  414. :* trace-polys
  415. trace-evaluations
  416. composition-pieces-fpoly
  417. composition-piece-evaluations
  418. deep-weights
  419. omicrons-fpoly
  420. deep-challenge
  421. ==
  422. ::
  423. :: create DEEP codeword and push to proof
  424. ::~& %computing-deep-codeword
  425. =/ deep-codeword=fpoly
  426. (coseword deep-poly (lift g) fri-domain-len)
  427. ::
  428. =^ fri-indices=(list @) proof
  429. (prove:fri:clc deep-codeword proof)
  430. ::
  431. ::
  432. ::~& %opening-codewords
  433. =. proof
  434. %^ zip-roll (range num-spot-checks) fri-indices
  435. |= [[i=@ idx=@] proof=_proof]
  436. ::
  437. :: base trace codewords
  438. =/ elem=mary
  439. (~(change-step ave (~(snag-as-mary ave codewords.base) idx)) 1)
  440. =/ axis (index-to-axis:merkle p.merk-heap.base idx)
  441. =/ opening=merk-proof:merkle
  442. (build-merk-proof:merkle q.merk-heap.base axis)
  443. =. proof
  444. %- ~(push proof-stream proof)
  445. m-pathbf+[(tail elem) path.opening]
  446. ::
  447. :: ext trace codewords
  448. =. elem
  449. (~(change-step ave (~(snag-as-mary ave codewords.ext) idx)) 1)
  450. =. axis (index-to-axis:merkle p.merk-heap.ext idx)
  451. =. opening
  452. (build-merk-proof:merkle q.merk-heap.ext axis)
  453. =. proof
  454. %- ~(push proof-stream proof)
  455. m-pathbf+[(tail elem) path.opening]
  456. ::
  457. :: mega-ext trace codewords
  458. =. elem
  459. (~(change-step ave (~(snag-as-mary ave codewords.mega-ext) idx)) 1)
  460. =. axis (index-to-axis:merkle p.merk-heap.mega-ext idx)
  461. =. opening
  462. (build-merk-proof:merkle q.merk-heap.mega-ext axis)
  463. =. proof
  464. %- ~(push proof-stream proof)
  465. m-pathbf+[(tail elem) path.opening]
  466. ::
  467. :: piece codewords
  468. =. elem
  469. (~(change-step ave (~(snag-as-mary ave composition-codeword-array) idx)) 1)
  470. =. axis (index-to-axis:merkle p.composition-merk idx)
  471. =. opening (build-merk-proof:merkle q.composition-merk axis)
  472. %- ~(push proof-stream proof)
  473. m-pathbf+[(tail elem) path.opening]
  474. ::
  475. ::~& %finished-proof
  476. [%& objects.proof ~ 0]
  477. ::
  478. ::
  479. ++ build-table-dats
  480. ::~/ %build-table-dats
  481. |= [return=fock-return override=(unit (list term))]
  482. ^- (list table-dat)
  483. %- sort
  484. :_ td-order
  485. %+ turn ?~ override :: check to see if we only want to use certain tables
  486. gen-table-names:nock-common
  487. u.override
  488. |= name=term
  489. =/ t-funcs
  490. ~| "table-funcs do not exist for {<name>}"
  491. (~(got by table-funcs-map) name)
  492. =/ v-funcs
  493. ~| "verifier-funcs do not exist for {<name>}"
  494. (~(got by all-verifier-funcs-map:nock-common) name)
  495. =/ tm=table-mary (build:t-funcs return)
  496. [(pad:t-funcs tm) t-funcs v-funcs]
  497. ::
  498. ++ table-funcs-map
  499. ~+
  500. ^- (map term table-funcs)
  501. %- ~(gas by *(map term table-funcs))
  502. :~ :- name:static:common:compute-table
  503. funcs:compute-table
  504. :- name:static:common:memory-table
  505. funcs:memory-table
  506. ==
  507. --