prover.hoon 17 KB

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