three.hoon 60 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047
  1. /= ztd-two /common/ztd/two
  2. => ztd-two
  3. ~% %misc-lib ..lift ~
  4. :: misc-lib
  5. |%
  6. :: +flec: reflect a noun, i.e. switch head and tail
  7. ++ flec
  8. |* *
  9. ?@ +< +<
  10. +<+^+<-
  11. ::
  12. ++ lib-u32
  13. ~% %lib-u32 + ~
  14. :: Unsigned 32-bit Arithmetic
  15. |%
  16. +$ u32 @udthirtytwo
  17. ++ bex32 ^~((bex 32)) :: 4.294.967.296
  18. ++ max32 ^~((dec (bex 32))) :: 4.294.967.295
  19. ::
  20. :: +is-u32: is atom a u32?
  21. ++ is-u32
  22. ~/ %is-u32
  23. |= a=@
  24. ^- ?
  25. (lth a bex32)
  26. ::
  27. :: +belt-to-u32: decompose a belt to u32s
  28. ++ belt-to-u32s
  29. ~/ %btu32s
  30. |= sam=belt
  31. ^- [lo=u32 hi=u32]
  32. ?> (lth sam p) ::NOTE: in flib and jutes, this is bex64 instead of goldilocks prime?
  33. :: ?> (lth sam (bex 64))
  34. (flec (dvr sam bex32))
  35. ::
  36. ++ belt-from-u32s
  37. ~/ %bfu32s
  38. |= [lo=u32 hi=u32]
  39. ^- belt
  40. ?> ?&((is-u32 lo) (is-u32 hi))
  41. (add lo (mul bex32 hi))
  42. ::
  43. :: +u32-add: a + b = lo + (2^32)*car
  44. ++ u32-add
  45. |= [a=u32 b=u32]
  46. ^- [lo=u32 car=u32]
  47. ?> ?&((is-u32 a) (is-u32 b))
  48. (flec (dvr (badd a b) (bex 32)))
  49. ::
  50. :: +u32-sub: a - b = -(2^32)*bor + com
  51. ::
  52. :: If a>b, then a-b=c is interpreable as an ordinary u32. But if a<b, you
  53. :: can imagine we "borrow" 2^32 to add to `a` before we subtract so we can
  54. :: represent the difference as an ordinary u32. Equivalently we're just
  55. :: adding 2^32 to any negative answer, i.e. we're doing arithmetic mod 2^32.
  56. ++ u32-sub
  57. |= [a=u32 b=u32]
  58. :: com=complement (i.e. 2's-complement), bor=borrow
  59. ^- [com=u32 bor=u32]
  60. ?> ?&((is-u32 a) (is-u32 b))
  61. [(~(dif fo (bex 32)) a b) ?:((lth a b) 1 0)]
  62. ::
  63. :: +u32-lth: [a b] --> 0/1 according to a < b T/F
  64. ++ u32-lth
  65. ~/ %u32-lth
  66. |= [a=u32 b=u32]
  67. ^- ?
  68. ?> ?&((is-u32 a) (is-u32 b))
  69. (lth a b)
  70. ::
  71. :: +u32-mul: a*b = lo + (2^32)*hi
  72. ++ u32-mul
  73. ~/ %u32-mul
  74. |= [a=u32 b=u32]
  75. ^- [lo=u32 hi=u32]
  76. ?> ?&((is-u32 a) (is-u32 b))
  77. (flec (dvr (bmul a b) bex32))
  78. ::
  79. :: +u32-dvr: a = qot*b + rem, rem < b
  80. ++ u32-dvr
  81. ~/ %u32-dvr
  82. |= [a=u32 b=u32]
  83. ^- [qot=u32 rem=u32]
  84. ?> ?&((is-u32 a) (is-u32 b))
  85. (dvr a b)
  86. ::
  87. :: +u32-div: a / b = c such that a - b*c < b
  88. ++ u32-div
  89. ~/ %u32-div
  90. |= [a=u32 b=u32]
  91. ^- u32
  92. ?> ?&((is-u32 a) (is-u32 b))
  93. qot:(u32-dvr a b)
  94. ::
  95. :: +u32-mod: a - b*(a / b)
  96. ++ u32-mod
  97. ~/ %u32-mod
  98. |= [a=u32 b=u32]
  99. ^- u32
  100. ?> ?&((is-u32 a) (is-u32 b))
  101. rem:(u32-dvr a b)
  102. --
  103. ::
  104. ++ bignum :: /lib/bignum
  105. ~% %bignum + ~
  106. |%
  107. ++ l32 lib-u32
  108. ++ u32 u32:l32
  109. :: mirrors bignum from flib
  110. :: 32 bits = 2^5 bits => bloq size of 5
  111. +$ bignum
  112. :: LSB order (based on result of rip)
  113. :: empty array is 0
  114. [%bn p=(list u32)]
  115. ::
  116. ++ validate
  117. |= bn=bignum
  118. (levy p.bn is-u32:l32)
  119. ::
  120. :: +p: Goldilocks prime, written in bignum form
  121. ::
  122. :: least significant bit first, so:
  123. :: p = 2^64-2^32+1 = 2^32(2^32 - 1) + 1
  124. ++ p
  125. ^- bignum
  126. [%bn ~[1 4.294.967.295]]
  127. ::
  128. :: +p2: p^2
  129. ++ p2
  130. ^- bignum
  131. [%bn ~[1 4.294.967.294 2 4.294.967.294]]
  132. ::
  133. :: +p3: p^3
  134. ++ p3
  135. ^- bignum
  136. [%bn ~[1 4.294.967.293 5 4.294.967.289 5 4.294.967.293]]
  137. ::
  138. ++ chunk
  139. ~/ %chunk
  140. |= a=@
  141. ^- bignum
  142. [%bn (rip-correct 5 a)]
  143. ::
  144. ++ merge
  145. ~/ %merge
  146. |= b=bignum
  147. ^- @
  148. :: fock always turns unchunked bignums into chunked case
  149. (rep 5 p.b)
  150. ::
  151. ++ valid
  152. :: are all elements of the list valid big int chunks, i.e., less than u32.max_val
  153. ~/ %valid
  154. |= b=bignum
  155. ^- ?
  156. (levy p.b |=(c=@ (lth c (bex 32))))
  157. -- ::bignum
  158. ::
  159. ++ shape :: /lib/shape
  160. ~% %shape ..shape ~
  161. =, mp-to-mega
  162. |%
  163. :: +dyck: produce the Dyck word describing the shape of a tree
  164. ++ dyck
  165. ~/ %dyck
  166. |= t=*
  167. %- flop
  168. ^- (list @)
  169. =| vec=(list @)
  170. |-
  171. ?@ t vec
  172. $(t +.t, vec [1 $(t -.t, vec [0 vec])])
  173. ::
  174. :: +grow: grow the tree with given shape and leaves
  175. ++ grow
  176. ~/ %grow
  177. |= [shape=(list @) leaves=(list @)]
  178. ^- *
  179. ?> ?&(=((lent shape) (mul 2 (dec (lent leaves)))) (valid-shape shape))
  180. ?~ shape
  181. ?> ?=([@ ~] leaves)
  182. i.leaves
  183. =/ lr-shape (left-right-shape shape)
  184. =/ split-idx (shape-size -:lr-shape)
  185. =/ split-leaves (split split-idx leaves)
  186. :- (grow -:lr-shape -:split-leaves)
  187. (grow +:lr-shape +:split-leaves)
  188. ::
  189. :: +shape-size: size of the tree in #leaves described by a given Dyck word
  190. ++ shape-size
  191. ~/ %shape-size
  192. |= shape=(list @)
  193. ^- @
  194. (add 1 (div (lent shape) 2))
  195. ::
  196. ++ leaf-sequence
  197. ~/ %leaf-sequence
  198. |= t=*
  199. %- flop
  200. ^- (list @)
  201. =| vec=(list @)
  202. |-
  203. ?@ t t^vec
  204. $(t +.t, vec $(t -.t))
  205. ::
  206. ++ num-of-leaves
  207. ~/ %num-of-leaves
  208. |= t=*
  209. ?@ t 1
  210. %+ add
  211. (num-of-leaves -:t)
  212. (num-of-leaves +:t)
  213. ::
  214. :: +left-right-shape: extract left and right tree shapes from given tree shape
  215. ++ left-right-shape
  216. ~/ %left-right-shape
  217. |= shape=(list @)
  218. ^- [(list @) (list @)]
  219. ?> (valid-shape shape)
  220. ?: =((lent shape) 0)
  221. ~| "Empty tree has no left subtree."
  222. !!
  223. =. shape (slag 1 shape)
  224. =/ stack-height 1
  225. =| lefsh=(list @)
  226. |-
  227. ?: =(stack-height 0)
  228. ?< ?=(~ lefsh)
  229. [(flop t.lefsh) shape]
  230. ?< ?=(~ shape)
  231. ?: =(i.shape 0)
  232. $(lefsh [i.shape lefsh], shape t.shape, stack-height +(stack-height))
  233. $(lefsh [i.shape lefsh], shape t.shape, stack-height (dec stack-height))
  234. ::
  235. ++ axis-to-axes
  236. ~/ %axis-to-axes
  237. |= axi=@
  238. ^- (list @)
  239. =| lis=(list @)
  240. |-
  241. ?: =(1 axi) lis
  242. =/ hav (dvr axi 2)
  243. $(axi p.hav, lis [?:(=(q.hav 0) 2 3) lis])
  244. ::
  245. :: +valid-shape: computes whether a given vector is a valid tree shape
  246. ++ valid-shape
  247. ~/ %valid-shape
  248. |= shape=(list @)
  249. ^- ?
  250. =/ stack-height 0
  251. |-
  252. ?: ?=(~ shape)
  253. ?: =(stack-height 0)
  254. %.y
  255. %.n
  256. ?> ?|(=(i.shape 0) =(i.shape 1))
  257. ?: =(i.shape 0)
  258. $(shape t.shape, stack-height +(stack-height))
  259. ?: =(stack-height 0)
  260. %.n
  261. $(shape t.shape, stack-height (dec stack-height))
  262. ::
  263. :: +split: split ~[a_1 ... a_n] into [~[a)1 ... a_{idx -1}] ~[a_{idx} ... a_n]]
  264. ++ split
  265. ~/ %split
  266. |= [idx=@ lis=(list @)]
  267. ^- [(list @) (list @)]
  268. ~| "Index argument must be less than list length."
  269. ?> (lth idx (lent lis))
  270. =| lef=(list @)
  271. =/ i 0
  272. |-
  273. ?: =(i idx)
  274. [(flop lef) lis]
  275. ?< ?=(~ lis)
  276. $(lef [i.lis lef], lis t.lis, i +(i))
  277. ::
  278. ++ shape-axis-to-index
  279. ~/ %shape-axis-to-index
  280. |= [tre=* axis=@]
  281. ^- [dyck-index=@ leaf-index=@]
  282. =/ axes (axis-to-axes axis)
  283. =/ shape (dyck tre)
  284. =/ dyck-index 0
  285. =/ leaf-index 0
  286. |-
  287. ?~ axes
  288. [dyck-index leaf-index]
  289. =/ lr-shape (left-right-shape shape)
  290. ?: =(i.axes 2)
  291. $(axes t.axes, shape -.lr-shape)
  292. ?> =(i.axes 3)
  293. %_ $
  294. axes t.axes
  295. shape +.lr-shape
  296. dyck-index (add dyck-index (lent -.lr-shape))
  297. leaf-index (add leaf-index (shape-size -.lr-shape))
  298. ==
  299. ::
  300. :: +path-to-axis: binary directions to input axis
  301. ++ path-to-axis
  302. |= axis=belt
  303. ^- (list belt)
  304. (slag 1 (flop (rip 0 axis)))
  305. ::
  306. :: +ion-eval: eval first arg as poly at alpha
  307. ::
  308. :: First arg is a polynomial, read high powers to low from L to R.
  309. :: In practice this poly is a dyck word or leaf vector.
  310. ++ ion-eval
  311. |= [word-vec=(list belt) alpha=belt]
  312. ^- belt
  313. %+ roll word-vec
  314. |= [coeff=_f0 acc=_f0]
  315. ^- belt
  316. (badd (bmul alpha acc) coeff)
  317. ::
  318. ++ ion-eval-symbolic
  319. |= [word-vec=(list mp-mega) alpha=mp-mega]
  320. ^- mp-mega
  321. %+ roll word-vec
  322. |= [coeff=mp-mega acc=mp-mega]
  323. ^- mp-mega
  324. (mpadd (mpmul alpha acc) coeff)
  325. -- ::shape
  326. ::
  327. ++ tip5 :: lib/tip5
  328. ~% %tip5-lib ..tip5 ~
  329. |_ num-rounds=_7
  330. +| %user-types
  331. +$ noun-digest [belt belt belt belt belt]
  332. +$ ten-cell [noun-digest noun-digest]
  333. ::
  334. ++ digest-dyck-word
  335. ^- (list @)
  336. ~[0 1 0 1 0 1 0 1]
  337. ++ ten-cell-dyck-word
  338. ^~ ^- (list @)
  339. (weld [0 digest-dyck-word] [1 digest-dyck-word])
  340. ::
  341. :: a sponge-tuple is a 16-tuple of belts; relevant for hash5.hoon
  342. ++ sponge-tuple-dyck-word
  343. ^~ ^- (list @)
  344. (zing (reap (dec state-size) ~[0 1]))
  345. ::
  346. +| %user-funcs
  347. ::
  348. :: +hash-ten-cell
  349. ++ hash-ten-cell
  350. ~/ %hash-ten-cell
  351. |= =ten-cell
  352. ^- noun-digest
  353. =- ?> ?=(noun-digest -) -
  354. %- list-to-tuple
  355. %- hash-10
  356. %- leaf-sequence:shape
  357. ten-cell
  358. ::
  359. :: +hash-leaf
  360. ++ hash-leaf
  361. |= leaf=belt
  362. ^- noun-digest
  363. :: ?> (based leaf) commented out because its performed in +hash-varlen
  364. (hash-belts-list ~[leaf])
  365. ::
  366. :: $hashable: a DSL for hashing anything
  367. +$ hashable
  368. $~ [%leaf p=*]
  369. $^ [p=hashable q=hashable]
  370. $% [%leaf p=*]
  371. [%hash p=noun-digest]
  372. [%list p=(list hashable)]
  373. [%mary p=mary]
  374. ==
  375. ::
  376. :: +hash-hashable
  377. ++ hash-hashable
  378. ~/ %hash-hashable
  379. |= h=hashable
  380. ^- noun-digest
  381. ?: ?=(%hash -.h)
  382. p.h
  383. ?: ?=(%leaf -.h)
  384. (hash-noun-varlen p.h)
  385. ?: ?=(%list -.h)
  386. (hash-noun-varlen (turn p.h hash-hashable))
  387. ?: ?=(%mary -.h)
  388. %- hash-hashable
  389. :- leaf+step.p.h
  390. :- leaf+len.array.p.h
  391. hash+(hash-belts-list (bpoly-to-list array:(~(change-step ave p.h) 1)))
  392. %- hash-ten-cell
  393. [$(h p.h) $(h q.h)]
  394. ::
  395. ++ hashable-noun-digests
  396. |= lis=(list noun-digest)
  397. ^- hashable
  398. list+(turn lis |=(nd=noun-digest hash+nd))
  399. ::
  400. ++ hashable-bpoly
  401. |= bp=bpoly
  402. ^- hashable
  403. mary+`mary`[%1 bp]
  404. ::
  405. ++ hashable-felt
  406. |= f=felt
  407. ^- hashable
  408. (hashable-bpoly [3 f])
  409. ::
  410. ++ hashable-fpoly
  411. |= fp=fpoly
  412. ^- hashable
  413. mary+`mary`[%3 fp]
  414. ::
  415. ++ hashable-mary
  416. |= =mary
  417. ^- hashable
  418. mary+mary
  419. ::
  420. :: +hash-noun-varlen
  421. ++ hash-noun-varlen
  422. ~/ %hash-noun-varlen
  423. |= n=*
  424. ^- noun-digest
  425. =/ leaf=(list @) (leaf-sequence:shape n)
  426. =/ dyck=(list @) (dyck:shape n)
  427. =/ size (lent leaf)
  428. (hash-belts-list [size (weld leaf dyck)])
  429. ::
  430. :: +hash-felt
  431. ++ hash-felt
  432. ~/ %hash-felt
  433. |= =felt
  434. ^- noun-digest:tip5
  435. =/ felt-tuple=[@ @ @ @ @]
  436. ;; [@ @ @ @ @]
  437. %- list-to-tuple
  438. (weld (felt-to-list felt) ~[0 0])
  439. (hash-ten-cell felt-tuple [0 0 0 0 0])
  440. ::
  441. ::
  442. ++ hash-belts-list
  443. ~/ %hash-belts-list
  444. |= belts=(list belt)
  445. ^- noun-digest:tip5
  446. =- ?> ?=(noun-digest -) -
  447. %- list-to-tuple
  448. (hash-varlen belts)
  449. ::
  450. :: +hash-pairs
  451. ++ hash-pairs
  452. ~/ %hash-pairs
  453. |= lis=(list (list @))
  454. ^- (list (list @))
  455. |^
  456. %+ turn
  457. (indices (lent lis))
  458. |= b=@
  459. ?: =(+(b) (lent lis))
  460. (snag b lis)
  461. (hash-10:tip5 (weld (snag b lis) (snag +(b) lis)))
  462. ::
  463. :: TODO: there is probably a more clean way to generate indices.
  464. ++ indices
  465. |= n=@
  466. ^- (list @)
  467. ?< =(n 0)
  468. =/ i 0
  469. |-
  470. ?: (gte i n)
  471. ~
  472. [i $(i (add 2 i))]
  473. --
  474. ::
  475. :: +snag-as-digest
  476. ::
  477. :: Retrieve the i-th entry of the mary return it as a tip5 hash digest.
  478. :: Assumes that each entry of the mary is a single hash encoded in base 64.
  479. ::
  480. ++ snag-as-digest
  481. ~/ %snag-as-digest
  482. |= [m=mary i=@]
  483. ^- noun-digest:tip5
  484. ?> =(5 step.m)
  485. =/ buf (~(snag ave m) i)
  486. :* (cut 6 [0 1] buf)
  487. (cut 6 [1 1] buf)
  488. (cut 6 [2 1] buf)
  489. (cut 6 [3 1] buf)
  490. (cut 6 [4 1] buf)
  491. ==
  492. ::
  493. :: +list-to-digest
  494. ++ list-to-digest
  495. ~/ %list-to-digest
  496. |= lis=(list @)
  497. ^- noun-digest:tip5
  498. ?> =(5 (lent lis))
  499. :* (snag 0 lis)
  500. (snag 1 lis)
  501. (snag 2 lis)
  502. (snag 3 lis)
  503. (snag 4 lis)
  504. ==
  505. ::
  506. :: +atom-to-digest
  507. ::
  508. :: Converts hex buffer into base-p representation
  509. ++ atom-to-digest
  510. ~/ %atom-to-digest
  511. |= buffer=@ux
  512. ^- noun-digest:tip5
  513. =/ [q=@ a=@] (dvr buffer p)
  514. =/ [q=@ b=@] (dvr q p)
  515. =/ [q=@ c=@] (dvr q p)
  516. =/ [e=@ d=@] (dvr q p)
  517. [a b c d e]
  518. ::
  519. :: +digest-to-atom
  520. ::
  521. :: Returns a hexadecimal representation of the hash.
  522. :: We treat the tip-5 hash as a base-p number.
  523. ++ digest-to-atom
  524. ~/ %digest-to-atom
  525. |= [a=belt b=belt c=belt d=belt e=belt]
  526. ^- @ux
  527. =/ p2 (mul p p)
  528. =/ p3 (mul p2 p)
  529. =/ p4 (mul p3 p)
  530. ;: add
  531. a
  532. (mul p b)
  533. (mul p2 c)
  534. (mul p3 d)
  535. (mul p4 e)
  536. ==
  537. ::
  538. +| %dev-types
  539. +$ digest (list melt) :: length = digest-length
  540. +$ state (list melt) :: length = state-size
  541. +$ domain ?(%variable %fixed)
  542. +$ tip5-state (list melt)
  543. ::
  544. +| %dev-constants
  545. ++ digest-length 5
  546. ++ state-size 16
  547. ++ num-split-and-lookup 4
  548. ++ capacity 6
  549. ++ rate 10
  550. ++ max-tip5-atom (digest-to-atom [(dec p) (dec p) (dec p) (dec p) (dec p)])
  551. ::
  552. ++ state-dyck-word
  553. ^~ ^- (list @)
  554. (zing (reap state-size ~[0 1]))
  555. ::
  556. :: +lookup-table: represents the map x -> (x+1)^3 - 1 (mod 257) on {0, ..., 255}
  557. ::
  558. :: Used on the first 4 state elements in the S-box layer of each round of Tip5
  559. ++ lookup-table
  560. ^- (list @)
  561. :~ 0 7 26 63 124 215 85 254 214 228 45 185 140 173 33 240
  562. 29 177 176 32 8 110 87 202 204 99 150 106 230 14 235 128
  563. 213 239 212 138 23 130 208 6 44 71 93 116 146 189 251 81
  564. 199 97 38 28 73 179 95 84 152 48 35 119 49 88 242 3
  565. 148 169 72 120 62 161 166 83 175 191 137 19 100 129 112 55
  566. 221 102 218 61 151 237 68 164 17 147 46 234 203 216 22 141
  567. 65 57 123 12 244 54 219 231 96 77 180 154 5 253 133 165
  568. 98 195 205 134 245 30 9 188 59 142 186 197 181 144 92 31
  569. 224 163 111 74 58 69 113 196 67 246 225 10 121 50 60 157
  570. 90 122 2 250 101 75 178 159 24 36 201 11 243 132 198 190
  571. 114 233 39 52 21 209 108 238 91 187 18 104 194 37 153 34
  572. 200 143 126 155 236 118 64 80 172 89 94 193 135 183 86 107
  573. 252 13 167 206 136 220 207 103 171 160 76 182 227 217 158 56
  574. 174 4 66 109 139 162 184 211 249 47 125 232 117 43 16 42
  575. 127 20 241 25 149 105 156 51 53 168 145 247 223 79 78 226
  576. 15 222 82 115 70 210 27 41 1 170 40 131 192 229 248 255
  577. ==
  578. ::
  579. :: +round-constants: 5 length=16 vectors added to the state in the final layer each round
  580. ++ round-constants
  581. :: notice melt and montify: these are in Montgomery representation
  582. ^- (list melt)
  583. %- turn :_ montify
  584. ?> ?|(=(num-rounds 5) =(num-rounds 7))
  585. ?: =(num-rounds 5)
  586. :: length = 5 * state-size = 80
  587. :~
  588. :: 1st round constants
  589. 13.630.775.303.355.457.758 16.896.927.574.093.233.874
  590. 10.379.449.653.650.130.495 1.965.408.364.413.093.495
  591. 15.232.538.947.090.185.111 15.892.634.398.091.747.074
  592. 3.989.134.140.024.871.768 2.851.411.912.127.730.865
  593. 8.709.136.439.293.758.776 3.694.858.669.662.939.734
  594. 12.692.440.244.315.327.141 10.722.316.166.358.076.749
  595. 12.745.429.320.441.639.448 17.932.424.223.723.990.421
  596. 7.558.102.534.867.937.463 15.551.047.435.855.531.404
  597. :: 2nd round constants
  598. 17.532.528.648.579.384.106 5.216.785.850.422.679.555
  599. 15.418.071.332.095.031.847 11.921.929.762.955.146.258
  600. 9.738.718.993.677.019.874 3.464.580.399.432.997.147
  601. 13.408.434.769.117.164.050 264.428.218.649.616.431
  602. 4.436.247.869.008.081.381 4.063.129.435.850.804.221
  603. 2.865.073.155.741.120.117 5.749.834.437.609.765.994
  604. 6.804.196.764.189.408.435 17.060.469.201.292.988.508
  605. 9.475.383.556.737.206.708 12.876.344.085.611.465.020
  606. :: 3rd round constants
  607. 13.835.756.199.368.269.249 1.648.753.455.944.344.172
  608. 9.836.124.473.569.258.483 12.867.641.597.107.932.229
  609. 11.254.152.636.692.960.595 16.550.832.737.139.861.108
  610. 11.861.573.970.480.733.262 1.256.660.473.588.673.495
  611. 13.879.506.000.676.455.136 10.564.103.842.682.358.721
  612. 16.142.842.524.796.397.521 3.287.098.591.948.630.584
  613. 685.911.471.061.284.805 5.285.298.776.918.878.023
  614. 18.310.953.571.768.047.354 3.142.266.350.630.002.035
  615. :: 4th round constants
  616. 549.990.724.933.663.297 4.901.984.846.118.077.401
  617. 11.458.643.033.696.775.769 8.706.785.264.119.212.710
  618. 12.521.758.138.015.724.072 11.877.914.062.416.978.196
  619. 11.333.318.251.134.523.752 3.933.899.631.278.608.623
  620. 16.635.128.972.021.157.924 10.291.337.173.108.950.450
  621. 4.142.107.155.024.199.350 16.973.934.533.787.743.537
  622. 11.068.111.539.125.175.221 17.546.769.694.830.203.606
  623. 5.315.217.744.825.068.993 4.609.594.252.909.613.081
  624. :: 5th round constants
  625. 3.350.107.164.315.270.407 17.715.942.834.299.349.177
  626. 9.600.609.149.219.873.996 12.894.357.635.820.003.949
  627. 4.597.649.658.040.514.631 7.735.563.950.920.491.847
  628. 1.663.379.455.870.887.181 13.889.298.103.638.829.706
  629. 7.375.530.351.220.884.434 3.502.022.433.285.269.151
  630. 9.231.805.330.431.056.952 9.252.272.755.288.523.725
  631. 10.014.268.662.326.746.219 15.565.031.632.950.843.234
  632. 1.209.725.273.521.819.323 6.024.642.864.597.845.108
  633. ==
  634. ::
  635. :: length = 7 * state-size = 112
  636. :~
  637. :: 1st round constants
  638. 1.332.676.891.236.936.200 16.607.633.045.354.064.669
  639. 12.746.538.998.793.080.786 15.240.351.333.789.289.931
  640. 10.333.439.796.058.208.418 986.873.372.968.378.050
  641. 153.505.017.314.310.505 703.086.547.770.691.416
  642. 8.522.628.845.961.587.962 1.727.254.290.898.686.320
  643. 199.492.491.401.196.126 2.969.174.933.639.985.366
  644. 1.607.536.590.362.293.391 16.971.515.075.282.501.568
  645. 15.401.316.942.841.283.351 14.178.982.151.025.681.389
  646. :: 2nd round constants
  647. 2.916.963.588.744.282.587 5.474.267.501.391.258.599
  648. 5.350.367.839.445.462.659 7.436.373.192.934.779.388
  649. 12.563.531.800.071.493.891 12.265.318.129.758.141.428
  650. 6.524.649.031.155.262.053 1.388.069.597.090.660.214
  651. 3.049.665.785.814.990.091 5.225.141.380.721.656.276
  652. 10.399.487.208.361.035.835 6.576.713.996.114.457.203
  653. 12.913.805.829.885.867.278 10.299.910.245.954.679.423
  654. 12.980.779.960.345.402.499 593.670.858.850.716.490
  655. :: 3rd round constants
  656. 12.184.128.243.723.146.967 1.315.341.360.419.235.257
  657. 9.107.195.871.057.030.023 4.354.141.752.578.294.067
  658. 8.824.457.881.527.486.794 14.811.586.928.506.712.910
  659. 7.768.837.314.956.434.138 2.807.636.171.572.954.860
  660. 9.487.703.495.117.094.125 13.452.575.580.428.891.895
  661. 14.689.488.045.617.615.844 16.144.091.782.672.017.853
  662. 15.471.922.440.568.867.245 17.295.382.518.415.944.107
  663. 15.054.306.047.726.632.486 5.708.955.503.115.886.019
  664. :: 4th round constants
  665. 9.596.017.237.020.520.842 16.520.851.172.964.236.909
  666. 8.513.472.793.890.943.175 8.503.326.067.026.609.602
  667. 9.402.483.918.549.940.854 8.614.816.312.698.982.446
  668. 7.744.830.563.717.871.780 14.419.404.818.700.162.041
  669. 8.090.742.384.565.069.824 15.547.662.568.163.517.559
  670. 17.314.710.073.626.307.254 10.008.393.716.631.058.961
  671. 14.480.243.402.290.327.574 13.569.194.973.291.808.551
  672. 10.573.516.815.088.946.209 15.120.483.436.559.336.219
  673. :: 5th round constants
  674. 3.515.151.310.595.301.563 1.095.382.462.248.757.907
  675. 5.323.307.938.514.209.350 14.204.542.692.543.834.582
  676. 12.448.773.944.668.684.656 13.967.843.398.310.696.452
  677. 14.838.288.394.107.326.806 13.718.313.940.616.442.191
  678. 15.032.565.440.414.177.483 13.769.903.572.116.157.488
  679. 17.074.377.440.395.071.208 16.931.086.385.239.297.738
  680. 8.723.550.055.169.003.617 590.842.605.971.518.043
  681. 16.642.348.030.861.036.090 10.708.719.298.241.282.592
  682. :: 6th round constants
  683. 12.766.914.315.707.517.909 11.780.889.552.403.245.587
  684. 113.183.285.481.780.712 9.019.899.125.655.375.514
  685. 3.300.264.967.390.964.820 12.802.381.622.653.377.935
  686. 891.063.765.000.023.873 15.939.045.541.699.412.539
  687. 3.240.223.189.948.727.743 4.087.221.142.360.949.772
  688. 10.980.466.041.788.253.952 18.199.914.337.033.135.244
  689. 7.168.108.392.363.190.150 16.860.278.046.098.150.740
  690. 13.088.202.265.571.714.855 4.712.275.036.097.525.581
  691. :: 7th round constants
  692. 16.338.034.078.141.228.133 1.455.012.125.527.134.274
  693. 5.024.057.780.895.012.002 9.289.161.311.673.217.186
  694. 9.401.110.072.402.537.104 11.919.498.251.456.187.748
  695. 4.173.156.070.774.045.271 15.647.643.457.869.530.627
  696. 15.642.078.237.964.257.476 1.405.048.341.078.324.037
  697. 3.059.193.199.283.698.832 1.605.012.781.983.592.984
  698. 7.134.876.918.849.821.827 5.796.994.175.286.958.720
  699. 7.251.651.436.095.127.661 4.565.856.221.886.323.991
  700. ==
  701. ::
  702. :: +mds-matrix-first-column: the mds matrix is determined by any column
  703. ++ mds-matrix-first-column
  704. :: length = state-size = 16
  705. ^- (list belt)
  706. :~ 61.402 1.108 28.750 33.823 7.454 43.244 53.865 12.034
  707. 56.951 27.521 41.351 40.901 12.021 59.689 26.798 17.845
  708. ==
  709. ::
  710. ++ mds-first-column-fft
  711. ^- (list belt)
  712. :~ 524.757 12.925.608.463.476.951.657
  713. 15.523.111.717.718.611.263 16.532.524.212.944.612.299
  714. 7.588.283.897.142.562.168 15.572.835.691.259.601.621
  715. 2.891.241.344.421.052.990 4.554.321.248.572.910.116
  716. 52.427 3.009.663.708.287.279.710
  717. 15.424.499.013.074.857.791 4.457.503.309.926.164.732
  718. 10.858.460.172.271.996.281 243.395.401.255.089.650
  719. 3.054.636.063.615.042.110 16.491.124.241.935.763.107
  720. ==
  721. ::
  722. :: list of rows
  723. ++ mds-matrix
  724. ^~
  725. ^- (list (list belt))
  726. |^
  727. ^~((gen-circulant-matrix mds-matrix-first-column))
  728. ::
  729. :: +gen-circulant-matrix: use first column to produce mds-matrix
  730. ::
  731. :: The first row of mds is a cyclic rotation of the flop of the
  732. :: first column, and successive rows are obtained by more cyclic
  733. :: rotations.
  734. ++ gen-circulant-matrix
  735. |= first-column=(list @)
  736. ^- (list (list @))
  737. %+ spun (range (lent first-column))
  738. |= [i=@ acc=_(flop first-column)]
  739. [(rotate acc) (rotate acc)]
  740. ::
  741. :: +rotate: cyclic vector rotation
  742. ++ rotate
  743. |= lst=(list @)
  744. ^- (list @)
  745. [(rear lst) (snip lst)]
  746. --
  747. ::
  748. ++ primitive-16-roots
  749. ^- (list belt)
  750. :~ 4.096 :: o (o=2^12; 2 is a primitive 192nd rou, & 192=12*16)
  751. 68.719.476.736 :: o^3
  752. 1.152.921.504.606.846.976 :: o^5
  753. 4.503.599.626.321.920 :: o^7
  754. 18.446.744.069.414.580.225 :: o^9
  755. 18.446.744.000.695.107.585 :: o^11
  756. 17.293.822.564.807.737.345 :: o^13
  757. 18.442.240.469.788.262.401 :: o^15
  758. ==
  759. ::
  760. ++ layer-two-twiddles
  761. ^~ ^- (map belt (list belt))
  762. %- ~(gas by *(map belt (list belt)))
  763. %+ turn primitive-16-roots
  764. |= r=belt
  765. =/ fourth-rou (bpow r (div 16 4))
  766. :- r (turn (range 2) |=(i=@ (bpow fourth-rou i)))
  767. ::
  768. ++ layer-three-twiddles
  769. ^~ ^- (map belt (list belt))
  770. %- ~(gas by *(map belt (list belt)))
  771. %+ turn primitive-16-roots
  772. |= r=belt
  773. =/ eighth-rou (bpow r (div 16 8))
  774. :- r (turn (range 4) |=(i=@ (bpow eighth-rou i)))
  775. ::
  776. ++ layer-four-twiddles
  777. ^~ ^- (map belt (list belt))
  778. %- ~(gas by *(map belt (list belt)))
  779. %+ turn primitive-16-roots
  780. |= r=belt
  781. :- r (turn (range 8) |=(i=@ (bpow r i)))
  782. ::
  783. ::
  784. :: For the cognoscenti:
  785. ::
  786. :: The formal mathematical specification of Tip5 involves conversion to
  787. :: and from Montgomery representation in the S-box layer of each round.
  788. :: In practice it is inefficient to do this, so the MDS and round constants
  789. :: layers are done in Montgomery representation. This demands that the
  790. :: round constants be given in Montgomery representation, but, confusingly
  791. :: enough, does not demand the same of the MDS matrix constants, for the
  792. :: simple reason that ordinary multiplication of melt a' (whose underlying
  793. :: belt is a) and belt b yields (ab)'; this owes to the fact that
  794. :: "Montification" is multiplication by 2^64 mod p = 2^32 - 1. Basically,
  795. :: we "stay in Montgomery space" if we multiply a melt and a belt.
  796. ::
  797. :: This manifests clearly in +hash-10, where the input is montified and
  798. :: the output is demontified before being returned.
  799. +| %dev-funcs
  800. ++ init-tip5-state
  801. |= =domain
  802. ^- tip5-state
  803. ?- domain
  804. %variable
  805. ^~((reap state-size 0))
  806. ::
  807. %fixed
  808. ^~((weld (reap rate 0) (reap capacity (montify 1))))
  809. ==
  810. ::
  811. :: +offset-fermat-cube-map: generates and can be used to test lookup-table
  812. ++ offset-fermat-cube-map
  813. |= x=@
  814. ^- @
  815. ?> (lth x 256)
  816. =/ xx +(x)
  817. %- mod :_ 257
  818. (add :(mul xx xx xx) 256)
  819. ::
  820. :: +split-and-lookup: splits b into bytes, applies offset-fermat-cube-map to each, & recombines bytes
  821. ++ split-and-lookup
  822. |= m=melt
  823. ^- melt
  824. :: split
  825. =/ bytes=(list @) (weld (rip 3 m) (reap (sub 8 (lent (rip 3 m))) 0))
  826. :: lookup=offset-fermat-cube
  827. =. bytes (turn bytes |=(byte=@ (snag byte lookup-table)))
  828. :: recombine
  829. (can 3 (zip-up (reap 8 1) bytes))
  830. ::
  831. :: +cyclomul16-fft: fft of f and g, hadamard multiply result, then ifft.
  832. ::
  833. :: This is different than polynomial multiplication of f and g bc output length equals input lengths.
  834. :: In fact, it is polynomial multiplication modulo the cyclotomic polynomial X^16 - 1. (Not obvious.)
  835. ++ cyclomul16-fft
  836. |= [f=(list belt) g=(list belt)]
  837. ^- (list belt)
  838. ?> ?&(=((lent f) state-size) =((lent g) state-size))
  839. =/ [fx=fpoly gx=fpoly] [(lift-to-fpoly f) (lift-to-fpoly g)]
  840. %- turn :_ drop
  841. %- fpoly-to-list
  842. (fp-ifft (~(zip fop (fp-fft fx)) (fp-fft gx) fmul))
  843. ::
  844. :: +fft-16-w-root:
  845. ++ fft-16-w-root
  846. ~/ %fft-16-w-root
  847. |= [bp=(list belt) r=belt]
  848. ^- (list belt)
  849. |^
  850. =/ current-layer=(list (list belt))
  851. %- turn :_ interpolate-linear
  852. (zip-up (scag 8 bp) (slag 8 bp))
  853. =. current-layer
  854. %+ turn (zip-up (scag 4 current-layer) (slag 4 current-layer))
  855. (cury interpolate-next (~(got by layer-two-twiddles) r))
  856. =/ current-layer
  857. %+ turn (zip-up (scag 2 current-layer) (slag 2 current-layer))
  858. (cury interpolate-next (~(got by layer-three-twiddles) r))
  859. %- interpolate-next
  860. :+ (~(got by layer-four-twiddles) r)
  861. (snag 0 current-layer) (snag 1 current-layer)
  862. ::
  863. ++ interpolate-linear
  864. |= [b=belt c=belt]
  865. ~[(badd b c) (bsub b c)]
  866. ::
  867. ++ interpolate-next
  868. |= [twids=(list belt) dft1=(list belt) dft2=(list belt)]
  869. ^- (list belt)
  870. =/ right (zip dft2 twids bmul)
  871. %+ weld
  872. (zip dft1 right badd)
  873. (zip dft1 right bsub)
  874. --
  875. ::
  876. ++ fft-16
  877. ~/ %fft-16
  878. |= bp=(list belt)
  879. (fft-16-w-root bp 4.096)
  880. ::
  881. ++ ifft-16
  882. ~/ %ifft-16
  883. |= evals=(list belt)
  884. ^- (list belt)
  885. %- turn :_ |=(=belt (bmul belt 17.293.822.565.076.172.801))
  886. (fft-16-w-root evals 18.442.240.469.788.262.401)
  887. ::
  888. :: +mds-cyclomul: applies the mds matrix as a linear transformation to state
  889. :: w/o doing matrix multiplication
  890. ++ mds-cyclomul
  891. ~/ %mds-cyclomul
  892. |= =state
  893. ^- ^state
  894. %- ifft-16
  895. (zip mds-first-column-fft (fft-16 state) bmul)
  896. ::
  897. :: +mds-cyclomul-m: applies the mds matrix as a linear transformation to state
  898. :: doing matrix multiplication.
  899. ++ mds-cyclomul-m
  900. ~/ %mds-cyclomul-m
  901. |= v=(list @)
  902. ^- (list @)
  903. %+ turn
  904. mds-matrix
  905. |= row=(list @)
  906. (mod (inner-product row v) p)
  907. ::
  908. ++ inner-product
  909. ~/ %inner-product
  910. |= [l=(list @) t=(list @)]
  911. ^- belt
  912. %^ zip-roll l t
  913. |= [[a=@ b=@] res=@]
  914. (add res (mul a b))
  915. ::
  916. :: +sbox-layer: applies fermat map to first 4 elements and 7th-power map to remainder
  917. ++ sbox-layer
  918. ~/ %sbox-layer
  919. |= =state
  920. ^- (list melt)
  921. ?> =((lent state) state-size)
  922. %+ weld
  923. (turn (scag num-split-and-lookup state) split-and-lookup)
  924. %+ turn (slag num-split-and-lookup state)
  925. :: computes b^7 in 4 base field multiplications
  926. ::
  927. :: Note that we are able to replace montiplys with
  928. :: bmuls due to the fact that R^3 = 1 mod p. Thus:
  929. :: m^7 = R^7*b^7
  930. :: = (R^3)^2*R*b^7
  931. :: = R*b^7 mod p
  932. |= m=melt
  933. ^- melt
  934. =/ sq (bmul m m)
  935. =/ qu (bmul sq sq)
  936. :(bmul m sq qu)
  937. ::
  938. :: +round: one round has three components; sbox, linear (mds), add round constants
  939. ++ round
  940. ~/ %round
  941. |= [sponge=tip5-state round-index=@]
  942. ^- tip5-state
  943. =. sponge (mds-cyclomul-m (sbox-layer sponge))
  944. %^ zip sponge (range state-size)
  945. |= [b=belt i=@]
  946. (badd b (snag (add (mul round-index state-size) i) round-constants))
  947. ::
  948. :: +permutation: applies rounds iteratively, num-rounds times
  949. ++ permutation
  950. ~/ %permutation
  951. |= sponge=tip5-state
  952. ^- tip5-state
  953. %+ roll (range num-rounds)
  954. |= [round-index=@ acc=_sponge]
  955. (round acc round-index)
  956. ::
  957. :: +trace: a record of the tip5-state's evolution during permutation
  958. ++ trace
  959. ~/ %trace
  960. |= sponge=tip5-state
  961. ^- (list tip5-state)
  962. :- sponge
  963. %+ spun (range num-rounds)
  964. |= [i=@ sp=_sponge]
  965. [(round sp i) (round sp i)]
  966. ::
  967. :: +hash-10: hash list of 10 belts into a list of 5 belts
  968. ++ hash-10
  969. ~/ %hash-10
  970. |= input=(list belt)
  971. :: output length is 5
  972. ^- (list belt)
  973. ?> =((lent input) rate)
  974. ?> (levy input based)
  975. =. input (turn input montify)
  976. =/ sponge (init-tip5-state %fixed)
  977. =. sponge (permutation (weld input (slag rate sponge)))
  978. (turn (scag digest-length sponge) mont-reduction)
  979. ::
  980. :: +hash-varlen: hash a list of belts, but in practice only a single belt
  981. ::
  982. :: you might think this is the function for hashing lists of belts,
  983. :: but you'd be wrong. +hash-varlen is part of the tip5 spec, so
  984. :: we need to have it. but because hoon is structurally typed, the
  985. :: type system cannot distinguish between a list ~[1 2 3] and a tuple
  986. :: [1 2 3 0]. unfortunately, +hash-noun of [1 2 3 0] is different from
  987. :: +hash-varlen of ~[1 2 3]. having identical nouns of belts with different
  988. :: hashes would be catastrophic.
  989. ::
  990. :: the two tip5 primitives are +hash-varlen and +hash-ten-cell.
  991. :: +hash-ten-cell can't be used on a single atom, so we must use
  992. :: +hash-varlen on it. +hash-ten-cell is only to be used to combine two
  993. :: hashes. so +hash-noun works out to be: +hash-varlen on every belt
  994. :: atom, and +hash-ten-cell on every cell.
  995. ::
  996. :: we also make use of +hash-varlen for hashing marys. see +hash-mary
  997. :: for more information
  998. ++ hash-varlen
  999. ~/ %hash-varlen
  1000. |= input=(list belt)
  1001. ^- (list belt)
  1002. =/ spo (new:sponge)
  1003. =. spo (absorb:spo input)
  1004. =^ output spo
  1005. (squeeze:spo)
  1006. (scag digest-length output)
  1007. ::
  1008. ++ sponge
  1009. ~% %sponge +> ~
  1010. |_ sponge=tip5-state
  1011. ++ new
  1012. |. ^+ +.$
  1013. =. sponge (init-tip5-state %variable)
  1014. +.$
  1015. ::
  1016. ++ absorb
  1017. ~/ %absorb
  1018. |= input=(list belt)
  1019. ^+ +>.$
  1020. =* rng +>.$
  1021. |^
  1022. :: assert that input is made of base field elements
  1023. ?> (levy input based)
  1024. =/ [q=@ r=@] (dvr (lent input) rate)
  1025. :: pad input with ~[1 0 ... 0] to be a multiple of rate
  1026. =. input (weld input [1 (reap (dec (sub rate r)) 0)])
  1027. :: bring input into montgomery space
  1028. =. input (turn input montify)
  1029. |-
  1030. =. sponge (absorb-rate (scag rate input))
  1031. ?: =(q 0)
  1032. rng
  1033. $(q (dec q), input (slag rate input))
  1034. ::
  1035. ++ absorb-rate
  1036. |= input=(list belt)
  1037. ^+ sponge
  1038. ?> =((lent input) rate)
  1039. =. sponge (weld input (slag rate sponge))
  1040. $:permute
  1041. --
  1042. ::
  1043. ++ permute
  1044. ~% %permute + ~
  1045. |. ^+ sponge
  1046. (permutation sponge)
  1047. ::
  1048. ++ squeeze
  1049. ~% %squeeze + ~
  1050. |. ^+ [*(list belt) +.$]
  1051. =* rng +.$
  1052. :: squeeze out the full rate and bring out of montgomery space
  1053. =/ output (turn (scag rate sponge) mont-reduction)
  1054. =. sponge $:permute
  1055. [output rng]
  1056. --
  1057. ::
  1058. :: +list-to-tuple: strips ~ from a list and yields a tuple
  1059. ::
  1060. :: hash-10 returns a length=5 list and this function is useful
  1061. :: for converting it to a tuple
  1062. ++ list-to-tuple
  1063. ~/ %list-to-tuple
  1064. |= lis=(list @)
  1065. :: address of [a_{k-1} ~] (final nontrivial tail of list)
  1066. =+ (dec (bex (lent lis)))
  1067. .* lis
  1068. [10 [- [0 (mul 2 -)]] [0 1]]
  1069. ::
  1070. :: +tog: Tip5 Sponge PRNG
  1071. ::
  1072. ++ tog
  1073. ~% %tog +> ~
  1074. |_ spo=tip5-state
  1075. ::
  1076. ++ new
  1077. |= sponge-state=tip5-state
  1078. ~(. tog sponge-state)
  1079. ::
  1080. ++ belts
  1081. ~/ %belts
  1082. |= n=@
  1083. ^+ [*(list belt) +>.$]
  1084. =* rng +>.$
  1085. =/ sponge ~(. sponge spo)
  1086. =/ [q=@ r=@] (dvr n rate)
  1087. =| output=(list belt)
  1088. |-
  1089. =^ out sponge
  1090. (squeeze:sponge)
  1091. =. spo sponge:sponge
  1092. ?: =(q 0)
  1093. [(weld output (scag r out)) rng]
  1094. $(q (dec q), output (weld output out))
  1095. ::
  1096. ++ felt
  1097. ~% %felt + ~
  1098. |. ^+ [*^felt +.$]
  1099. =^ felt-list +.$ (felts 1)
  1100. [(head felt-list) +.$]
  1101. ::
  1102. ++ felts
  1103. ~/ %felts
  1104. |= n=@
  1105. ^+ [*(list ^felt) +>.$]
  1106. =* outer +>.$
  1107. =^ lis-belts +>.$ (belts (mul n 3))
  1108. =| ret=(list ^felt)
  1109. =/ i 0
  1110. |-
  1111. ?: =(i n)
  1112. [(flop ret) outer]
  1113. =/ f=^felt (frep (scag 3 lis-belts))
  1114. $(ret [f ret], lis-belts (slag 3 lis-belts), i +(i))
  1115. ::
  1116. ++ index
  1117. ~/ %index
  1118. |= size=@
  1119. ^+ [*@ +>.$]
  1120. =^ belt-list +>.$ (belts 1)
  1121. [(mod (head belt-list) size) +>.$]
  1122. ::
  1123. ++ indices
  1124. ~/ %indices
  1125. |= [n=@ size=@ reduced-size=@]
  1126. ^+ [*(list @) +>.$]
  1127. =* rng +>.$
  1128. ~| "cannot sample more indices than available in last codeword"
  1129. ?> (lte n reduced-size)
  1130. =| indices=(list @)
  1131. =| reduced-indices=(list @)
  1132. |-
  1133. ?: (gte (lent indices) n)
  1134. [(flop indices) rng]
  1135. =^ index rng (index size)
  1136. =/ reduced-index (mod index reduced-size)
  1137. ?^ (find reduced-index^~ reduced-indices)
  1138. $
  1139. ?^ (find index^~ indices) $
  1140. %_ $
  1141. indices [index indices]
  1142. reduced-indices [reduced-index reduced-indices]
  1143. ==
  1144. --
  1145. ::
  1146. ++ test-tip5
  1147. |%
  1148. ::
  1149. ++ lookup-table-test
  1150. ^- ?
  1151. ?> =((lent lookup-table) 256)
  1152. %+ levy (range 256)
  1153. |= i=@
  1154. =((snag i lookup-table) (offset-fermat-cube-map i))
  1155. ::
  1156. ++ fermat-cube-map-is-permutation
  1157. ^- ?
  1158. =((range 256) (sort lookup-table lth))
  1159. ::
  1160. :: needs Blake3 hash function; I've painstakingly checked our list against the one in Neptune's code
  1161. ++ round-constants-test
  1162. ^- ?
  1163. !!
  1164. ::
  1165. :: +reduce-mod-cyclotomic: reduce f mod X^n-1
  1166. ++ reduce-mod-cyclotomic
  1167. |= [f=(list belt) n=@]
  1168. ^- (list belt)
  1169. =. f (weld f (reap (sub n (mod (lent f) n)) 0))
  1170. =/ result (reap n 0)
  1171. |-
  1172. ?~ f
  1173. result
  1174. =/ f-lst `(list belt)`f
  1175. %_ $
  1176. f (slag n f-lst)
  1177. result (zip (scag n f-lst) result badd)
  1178. ==
  1179. ::
  1180. ++ cyclomul-is-bpmul-mod-cyclotomic-test
  1181. |= [f=(list belt) g=(list belt)]
  1182. ^- ?
  1183. ?> ?&((lte (lent f) 16) (lte (lent g) 16))
  1184. =. f (weld f (reap (sub 16 (lent f)) 0))
  1185. =. g (weld g (reap (sub 16 (lent g)) 0))
  1186. =/ prod=(list belt) (bpoly-to-list (bpmul (init-bpoly f) (init-bpoly g)))
  1187. =. prod (weld prod (reap (sub 32 (lent prod)) 0))
  1188. .= (cyclomul16-fft f g)
  1189. (zip (scag 16 prod) (slag 16 prod) badd)
  1190. ::
  1191. ++ matrix-vector-product
  1192. |= [matrix=(list (list belt)) vector=(list belt)]
  1193. ^- (list belt)
  1194. %+ turn matrix
  1195. :: dot product
  1196. |= row=(list belt)
  1197. ^- belt
  1198. %+ roll (zip-up row vector)
  1199. |= [[entry=belt component=belt] acc=belt]
  1200. ^- belt
  1201. (badd acc (bmul entry component))
  1202. ::
  1203. ++ mds-cyclomul-test
  1204. |= input=(list belt)
  1205. ^- ?
  1206. ?> =((lent input) 16)
  1207. =((mds-cyclomul input) (matrix-vector-product mds-matrix input))
  1208. ::
  1209. ++ test-hash10-0
  1210. =/ expected=(list belt)
  1211. :~ 941.080.798.860.502.477
  1212. 5.295.886.365.985.465.639
  1213. 14.728.839.126.885.177.993
  1214. 10.358.449.902.914.633.406
  1215. 14.220.746.792.122.877.272
  1216. ==
  1217. =/ got (hash-10 (reap 10 0))
  1218. (zip-up expected got)
  1219. ::
  1220. ++ hash10-test-vectors
  1221. ^- ?
  1222. =/ input=(list belt) (reap rate 0)
  1223. =+ %+ roll (range 6)
  1224. |= [i=@ in=_input]
  1225. =/ out (hash-10 in)
  1226. :(weld (scag i in) out (reap (sub 5 i) 0))
  1227. =/ digest (hash-10 -)
  1228. =/ final=(list belt)
  1229. :~ 10.869.784.347.448.351.760
  1230. 1.853.783.032.222.938.415
  1231. 6.856.460.589.287.344.822
  1232. 17.178.399.545.409.290.325
  1233. 7.650.660.984.651.717.733
  1234. ==
  1235. =/ expected-got=(list [belt belt]) (zip-up final digest)
  1236. ~& expected-got
  1237. (levy expected-got |=([a=belt b=belt] =(a b)))
  1238. ::
  1239. :: comment out the jet hint on hash-varlen before running this test
  1240. ++ test-hash-varlen
  1241. |= [num=@ seed=@]
  1242. ^- ?
  1243. |^
  1244. =| counter=@
  1245. |-
  1246. ?: =(counter num) %.y
  1247. =/ [tv=(list belt) new-seed=@]
  1248. %^ spin (range counter) seed
  1249. |= [i=@ sd=belt]
  1250. =- -^-
  1251. (badd (bmul sd sd) 1)
  1252. ?. =((hash-varlen tv) (old-hash-varlen tv))
  1253. ~& fail-on+tv %.n
  1254. $(counter +(counter), seed new-seed)
  1255. ::
  1256. ++ old-hash-varlen
  1257. |= input=(list belt)
  1258. =/ [q=@ r=@] (dvr (lent input) rate)
  1259. :: append ~[1 0 ... 0] to input
  1260. =. input (turn (weld input [1 (reap (dec (sub rate r)) 0)]) montify)
  1261. =/ sponge (init-tip5-state %variable)
  1262. =- (turn (scag digest-length sp) mont-reduction)
  1263. %+ roll (gulf 0 q)
  1264. |= [i=@ [sp=_sponge in=_input]]
  1265. :_ (slag rate in)
  1266. (permutation (weld (scag rate in) (slag rate sp)))
  1267. --
  1268. --
  1269. --
  1270. ::
  1271. :: TODO: needs to be audited and thoroughly tested
  1272. ++ cheetah
  1273. ~% %cheetah ..cheetah ~
  1274. :: degree-six extension of F_p is cheetah curve's base field
  1275. |%
  1276. :: f6lt: element of F_p[x]/(x^6 - 7)
  1277. +$ f6lt [a0=belt a1=belt a2=belt a3=belt a4=belt a5=belt]
  1278. ++ f6lt-based
  1279. |= f=f6lt
  1280. =+ [a=belt b=belt c=belt d=belt e=belt f=belt]=f
  1281. ?& (based a)
  1282. (based b)
  1283. (based c)
  1284. (based d)
  1285. (based e)
  1286. (based f)
  1287. ==
  1288. ++ f6lt-dyck-word
  1289. ^- (list @)
  1290. ~[0 1 0 1 0 1 0 1 0 1]
  1291. ++ f6lt-cell-dyck-word
  1292. ^~ ^- (list @)
  1293. (weld [0 f6lt-dyck-word] [1 f6lt-dyck-word])
  1294. ++ f6lt-triple-dyck-word
  1295. ^~ ^- (list @)
  1296. :(weld [0 f6lt-dyck-word] [1 [0 f6lt-dyck-word]] [1 f6lt-dyck-word])
  1297. ++ f6lt-triple-cell-dyck-word
  1298. ^~ ^- (list @)
  1299. (weld [0 f6lt-triple-dyck-word] [1 f6lt-triple-dyck-word])
  1300. ++ f6-zero `f6lt`[0 0 0 0 0 0]
  1301. ++ f6-one `f6lt`[1 0 0 0 0 0]
  1302. ::
  1303. ++ f6lt-to-list
  1304. |= f=f6lt
  1305. ^- (list belt)
  1306. ~[a0.f a1.f a2.f a3.f a4.f a5.f]
  1307. ::
  1308. ++ list-to-f6lt
  1309. |= lis=(list belt)
  1310. ^- f6lt
  1311. ?> =((lent lis) 6)
  1312. :: 63 = axis of [a_5 ~] in ~[a0 ... a_5]
  1313. :: 126 = axis of a_5 in ~[a0 ... a_5]
  1314. :: replace axis 63 (=[a_5 ~]) of *[lis [0 1]]=lis with *[lis [0 126]]=a_5
  1315. =/ n
  1316. .* lis
  1317. [10 [63 [0 126]] [0 1]]
  1318. ?> ?=(f6lt n) n
  1319. ::
  1320. ++ f6-add
  1321. |= [f1=f6lt f2=f6lt]
  1322. ^- f6lt
  1323. :* (badd a0.f1 a0.f2)
  1324. (badd a1.f1 a1.f2)
  1325. (badd a2.f1 a2.f2)
  1326. (badd a3.f1 a3.f2)
  1327. (badd a4.f1 a4.f2)
  1328. (badd a5.f1 a5.f2)
  1329. ==
  1330. ::
  1331. ++ f6-neg
  1332. |= f=f6lt
  1333. ^- f6lt
  1334. :* (bneg a0.f)
  1335. (bneg a1.f)
  1336. (bneg a2.f)
  1337. (bneg a3.f)
  1338. (bneg a4.f)
  1339. (bneg a5.f)
  1340. ==
  1341. ::
  1342. ++ f6-sub
  1343. |= [f1=f6lt f2=f6lt]
  1344. ^- f6lt
  1345. (f6-add f1 (f6-neg f2))
  1346. ::
  1347. ++ f6-scal
  1348. |= [c=belt f=f6lt]
  1349. ^- f6lt
  1350. :* (bmul c a0.f)
  1351. (bmul c a1.f)
  1352. (bmul c a2.f)
  1353. (bmul c a3.f)
  1354. (bmul c a4.f)
  1355. (bmul c a5.f)
  1356. ==
  1357. ::
  1358. :: +karat3: mults 2 quadratic polys w only 6 bmuls (vs naive 9)
  1359. ++ karat3
  1360. |= [[a0=belt a1=belt a2=belt] [b0=belt b1=belt b2=belt]]
  1361. ^- [c0=belt c1=belt c2=belt c3=belt c4=belt]
  1362. =/ [m0=belt m1=belt m2=belt]
  1363. [(bmul a0 b0) (bmul a1 b1) (bmul a2 b2)]
  1364. :* m0
  1365. (bsub (bmul (badd a0 a1) (badd b0 b1)) (badd m0 m1))
  1366. (badd (bsub (bmul (badd a0 a2) (badd b0 b2)) (badd m0 m2)) m1)
  1367. (bsub (bmul (badd a1 a2) (badd b1 b2)) (badd m1 m2))
  1368. m2
  1369. ==
  1370. ::
  1371. :: +karat3-square: squares quadratic poly w only 5 bmuls
  1372. ++ karat3-square
  1373. |= [a0=belt a1=belt a2=belt]
  1374. ^- [c0=belt c1=belt c2=belt c3=belt c4=belt]
  1375. =/ [m0=belt m2=belt] [(bmul a0 a0) (bmul a2 a2)]
  1376. =/ [n01=belt n12=belt] [(bmul a0 a1) (bmul a1 a2)]
  1377. =: n01 (badd n01 n01)
  1378. n12 (badd n12 n12)
  1379. ==
  1380. =/ tri2=belt
  1381. =/ tri :(badd a0 a1 a2)
  1382. (bmul tri tri)
  1383. =/ coeff2 (bsub tri2 :(badd m0 m2 n01 n12))
  1384. [m0 n01 coeff2 n12 m2]
  1385. ::
  1386. ++ f6-mul
  1387. |= [f=f6lt g=f6lt]
  1388. ^- f6lt
  1389. =/ f0g0 (karat3 [a0.f a1.f a2.f] [a0.g a1.g a2.g])
  1390. =/ f1g1 (karat3 [a3.f a4.f a5.f] [a3.g a4.g a5.g])
  1391. =/ foil
  1392. %- karat3
  1393. :- [(badd a0.f a3.f) (badd a1.f a4.f) (badd a2.f a5.f)]
  1394. [(badd a0.g a3.g) (badd a1.g a4.g) (badd a2.g a5.g)]
  1395. =/ cross=[c0=belt c1=belt c2=belt c3=belt c4=belt]
  1396. :* (bsub c0.foil (badd c0.f0g0 c0.f1g1))
  1397. (bsub c1.foil (badd c1.f0g0 c1.f1g1))
  1398. (bsub c2.foil (badd c2.f0g0 c2.f1g1))
  1399. (bsub c3.foil (badd c3.f0g0 c3.f1g1))
  1400. (bsub c4.foil (badd c4.f0g0 c4.f1g1))
  1401. ==
  1402. :* (badd c0.f0g0 (bmul 7 (badd c3.cross c0.f1g1)))
  1403. (badd c1.f0g0 (bmul 7 (badd c4.cross c1.f1g1)))
  1404. (badd c2.f0g0 (bmul 7 c2.f1g1))
  1405. :(badd c3.f0g0 c0.cross (bmul 7 c3.f1g1))
  1406. :(badd c4.f0g0 c1.cross (bmul 7 c4.f1g1))
  1407. c2.cross
  1408. ==
  1409. ::
  1410. :: +f6-square: uses karat3-square for more efficiency than (f6-mul f f)
  1411. ++ f6-square
  1412. |= f=f6lt
  1413. ^- f6lt
  1414. =/ lo [a0.f a1.f a2.f]
  1415. =/ hi [a3.f a4.f a5.f]
  1416. =/ lo2 (karat3-square lo)
  1417. =/ hi2 (karat3-square hi)
  1418. =/ folded2 :: (lo + hi)^2
  1419. (karat3-square [(badd a0.f a3.f) (badd a1.f a4.f) (badd a2.f a5.f)])
  1420. =/ cross=[c0=belt c1=belt c2=belt c3=belt c4=belt]
  1421. :* (bsub c0.folded2 (badd c0.lo2 c0.hi2))
  1422. (bsub c1.folded2 (badd c1.lo2 c1.hi2))
  1423. (bsub c2.folded2 (badd c2.lo2 c2.hi2))
  1424. (bsub c3.folded2 (badd c3.lo2 c3.hi2))
  1425. (bsub c4.folded2 (badd c4.lo2 c4.hi2))
  1426. ==
  1427. :* :(badd c0.lo2 (bmul 7 c3.cross) (bmul 7 c0.hi2))
  1428. :(badd c1.lo2 (bmul 7 c4.cross) (bmul 7 c1.hi2))
  1429. (badd c2.lo2 (bmul 7 c2.hi2))
  1430. :(badd c3.lo2 c0.cross (bmul 7 c3.hi2))
  1431. :(badd c4.lo2 c1.cross (bmul 7 c4.hi2))
  1432. c2.cross
  1433. ==
  1434. ::
  1435. ++ f6-pow
  1436. |= [f=f6lt n=@]
  1437. ^- f6lt
  1438. =/ acc=f6lt f6-one
  1439. |-
  1440. ?: =(n 0) acc
  1441. %_ $
  1442. acc ?:(=((end 0 n) 0) acc (f6-mul acc f))
  1443. f (f6-square f)
  1444. n (rsh 0 n)
  1445. ==
  1446. ::
  1447. ++ f6-inv
  1448. |= f=f6lt
  1449. ^- f6lt
  1450. ?: =(f f6-zero)
  1451. ~|('+f6-inv: zero point has no inverse' !!)
  1452. =/ eucl
  1453. %+ bpegcd
  1454. (init-bpoly (f6lt-to-list f))
  1455. (init-bpoly ~[(bneg 7) 0 0 0 0 0 1])
  1456. %- list-to-f6lt
  1457. =+ %- bpoly-to-list
  1458. (bpscal (binv (snag 0 (bpoly-to-list d.eucl))) u.eucl)
  1459. (weld - (reap (sub 6 (lent -)) 0))
  1460. ::
  1461. ++ f6-div
  1462. ~/ %f6-div
  1463. |= [f1=f6lt f2=f6lt]
  1464. ^- f6lt
  1465. (f6-mul f1 (f6-inv f2))
  1466. ::
  1467. :: elliptic cheetah curve operations
  1468. ++ curve
  1469. ~% %curve ..curve ~
  1470. |%
  1471. ++ b `f6lt`[395 1 0 0 0 0]
  1472. ::
  1473. :: +gx: x-coordinate of g in affine coordinates
  1474. ++ gx
  1475. ^- f6lt
  1476. :* 2.754.611.494.552.410.273
  1477. 8.599.518.745.794.843.693
  1478. 10.526.511.002.404.673.680
  1479. 4.830.863.958.577.994.148
  1480. 375.185.138.577.093.320
  1481. 12.938.930.721.685.970.739
  1482. ==
  1483. :: +gy: y-coordinate of g in affine coordinates
  1484. ++ gy
  1485. ^- f6lt
  1486. :* 15.384.029.202.802.550.068
  1487. 2.774.812.795.997.841.935
  1488. 14.375.303.400.746.062.753
  1489. 10.708.493.419.890.101.954
  1490. 13.187.678.623.570.541.764
  1491. 9.990.732.138.772.505.951
  1492. ==
  1493. ::
  1494. :: +g-order: order of g; 255 bits
  1495. ++ g-order
  1496. 0x7af2.599b.3b3f.22d0.563f.bf0f.990a.37b5.327a.a723.3015.7722.d443.623e.aed4.accf
  1497. :: +a-pt: affine coordinates
  1498. ::
  1499. :: If the infinity flag inf if %.n, this is an (x, y) point in the
  1500. :: affine plane, which we identify with the z=1 plane in projective
  1501. :: space. If %.y, this is a point on the projective line
  1502. :: "at infinity," i.e. (x, y) is identified with [x, y, 0] in
  1503. :: projective space. By the projective equivalence relation, this
  1504. :: representation is not unique.
  1505. +$ a-pt [x=f6lt y=f6lt inf=?]
  1506. ::
  1507. :: +a-pt-based: checks if elements in a-pt are in base field.
  1508. ++ a-pt-based
  1509. |= a-pt
  1510. ?& (f6lt-based x)
  1511. (f6lt-based y)
  1512. ==
  1513. ::
  1514. ++ a-pt-dyck-word
  1515. ^~ ^- (list @)
  1516. (snoc (weld [0 f6lt-dyck-word] [1 0 f6lt-dyck-word]) 1)
  1517. ++ a-pt-cell-dyck-word
  1518. ^~ ^- (list @)
  1519. (weld [0 a-pt-dyck-word] [1 a-pt-dyck-word])
  1520. ::
  1521. :: +a-id
  1522. ::
  1523. :: The curve is defined by y^2 = x^3 + x + b over F^6.
  1524. :: To add the point at infinity we interpret these (x, y)
  1525. :: points as [x, y, 1] in P^2 over F^6. In projective [x, y, z]
  1526. :: coordinates the equation is y^2z = x^3 + xz^2 + bz^3. A
  1527. :: point at infinity (z=0), must satisfy x^3=0 so [0, y, 0] (y≠0)
  1528. :: is the only point at infinity on the curve (this is the same
  1529. :: pt for any y by the projective equivalence relation). Thus we
  1530. :: can take [0 1 %.y] as the identity point.
  1531. ::
  1532. :: Note that [0 -1 %.y] also represents the identity point.
  1533. ++ a-id `a-pt`[f6-zero f6-one %.y]
  1534. ++ a-gen
  1535. ^- a-pt
  1536. [gx gy %.n]
  1537. ::
  1538. :: +affine: curve operations in affine coordinates
  1539. ++ affine
  1540. ~% %affine ..affine ~
  1541. |%
  1542. ++ in-g
  1543. |= p=a-pt
  1544. =(a-id (ch-scal g-order p))
  1545. ::
  1546. :: +ch-neg: negate a cheetah point
  1547. ::
  1548. :: In Weierstrass form an elliptic curve has f([x y z]) = [x -y z] symmetry.
  1549. :: The line in the z=constant plane thru p and f(p) is vertical so passes
  1550. :: through O, the point at infinity; thus by the straight line relation for
  1551. :: elliptic curve addition, p + f(p) + O = O i.e. f(p) = -p.
  1552. ++ ch-neg
  1553. |= p=a-pt
  1554. ^- a-pt
  1555. [x.p (f6-neg y.p) inf.p]
  1556. ::
  1557. :: +ch-add: add two cheetah points
  1558. ++ ch-add-unsafe
  1559. |= [p=a-pt q=a-pt]
  1560. ^- a-pt
  1561. =/ slope (f6-div (f6-sub y.p y.q) (f6-sub x.p x.q))
  1562. =/ x-out (f6-sub (f6-square slope) (f6-add x.p x.q))
  1563. :+ x-out
  1564. (f6-sub (f6-mul slope (f6-sub x.p x-out)) y.p)
  1565. %.n
  1566. ::
  1567. ++ ch-add
  1568. |= [p=a-pt q=a-pt]
  1569. ^- a-pt
  1570. ?: inf.p q
  1571. ?: inf.q p
  1572. ?: =(p (ch-neg q)) a-id
  1573. ?: =(p q) (ch-double p)
  1574. (ch-add-unsafe p q)
  1575. ::
  1576. :: +ch-double-unsafe: generic add w/o special case checks
  1577. ++ ch-double-unsafe
  1578. |= p=a-pt
  1579. ^- a-pt
  1580. =/ slope
  1581. %+ f6-div
  1582. (f6-add (f6-scal 3 (f6-square x.p)) f6-one)
  1583. (f6-scal 2 y.p)
  1584. =/ x-out (f6-sub (f6-square slope) (f6-scal 2 x.p))
  1585. :+ x-out
  1586. (f6-sub (f6-mul slope (f6-sub x.p x-out)) y.p)
  1587. %.n
  1588. ::
  1589. :: +ch-double: [2]p, p a cheetah point
  1590. ::
  1591. :: Analog of squaring; fundamental for computing [n]p quickly.
  1592. :: Two special cases: the double of the point at infinity is itself;
  1593. :: and the double of any point with infinite slope is infinite. A
  1594. :: point with infinite slope is any point with y=0 by the equation
  1595. :: dy/dx = (3x^2 + 1)/2y.
  1596. ++ ch-double
  1597. |= p=a-pt
  1598. ^- a-pt
  1599. ?: inf.p a-id
  1600. ?: =(y.p f6-zero) a-id
  1601. (ch-double-unsafe p)
  1602. ::
  1603. :: +ch-scal: compute [n]p, p a cheetah point
  1604. ::
  1605. :: This is the action of Z on cheetah as an abelian group.
  1606. ++ ch-scal
  1607. ~/ %ch-scal
  1608. |= [n=@ p=a-pt]
  1609. ^- a-pt
  1610. =/ acc a-id
  1611. |-
  1612. ?: =(n 0) acc
  1613. %_ $
  1614. acc ?:(=((end 0 n) 0) acc (ch-add acc p))
  1615. n (rsh 0 n)
  1616. p (ch-double p)
  1617. ==
  1618. --
  1619. --
  1620. ::
  1621. ++ schnorr
  1622. ~% %schnorr ..schnorr ~
  1623. |%
  1624. ++ affine
  1625. ~% %affine ..affine ~
  1626. |%
  1627. ++ sign
  1628. ~/ %sign
  1629. |= [sk-as-32-bit-belts=(list belt) m=(list belt)]
  1630. ^- [c=@ux s=@ux]
  1631. ?> =((lent m) 5)
  1632. =/ b-32 (bex 32)
  1633. ?> (levy sk-as-32-bit-belts |=(n=@ (lth n b-32)))
  1634. =/ sk (rep 5 sk-as-32-bit-belts)
  1635. ?< =(sk 0)
  1636. ?> (lth sk g-order:curve)
  1637. =/ pubkey (ch-scal:affine:curve sk a-gen:curve)
  1638. =/ transcript=(list (list belt))
  1639. [(f6lt-to-list x.pubkey) (f6lt-to-list y.pubkey) m ~]
  1640. =/ nonce
  1641. (trunc-g-order (hash-varlen:tip5 (zing transcript)))
  1642. ?< =(nonce 0)
  1643. =/ scalar (ch-scal:affine:curve nonce a-gen:curve)
  1644. =. transcript [(f6lt-to-list x.scalar) (f6lt-to-list y.scalar) transcript]
  1645. =/ chal
  1646. (trunc-g-order (hash-varlen:tip5 (zing transcript)))
  1647. ?< =(chal 0)
  1648. =/ sig
  1649. %+ mod
  1650. (add nonce (mul chal sk))
  1651. g-order:curve
  1652. ?< =(sig 0)
  1653. [chal sig]
  1654. ::
  1655. ++ verify
  1656. ~/ %verify
  1657. |= [pubkey=a-pt:curve m=(list belt) chal=@ux sig=@ux]
  1658. ^- ?
  1659. ?&
  1660. =((lent m) 5) :: m must be a tip5 hash
  1661. (gth chal 0) (lth chal g-order:curve)
  1662. ::
  1663. (gth sig 0) (lth sig g-order:curve)
  1664. ::
  1665. =/ scalar
  1666. %+ ch-add:affine:curve
  1667. (ch-scal:affine:curve sig a-gen:curve)
  1668. (ch-neg:affine:curve (ch-scal:affine:curve chal pubkey))
  1669. ?< =(scalar f6-zero)
  1670. .= chal
  1671. %- trunc-g-order
  1672. %- hash-varlen:tip5
  1673. %- zing
  1674. :~ (f6lt-to-list x.scalar) (f6lt-to-list y.scalar)
  1675. (f6lt-to-list x.pubkey) (f6lt-to-list y.pubkey)
  1676. m
  1677. ==
  1678. ==
  1679. --
  1680. --
  1681. ::
  1682. :: +trunc-g-order: truncates a list of ≥4 belts to a 255-bit number
  1683. ++ trunc-g-order
  1684. |= a=(list belt)
  1685. ^- @
  1686. %+ mod
  1687. ;: add
  1688. (snag 0 a)
  1689. (mul p (snag 1 a))
  1690. :(mul p p (snag 2 a))
  1691. :(mul p p p (snag 3 a))
  1692. ==
  1693. g-order:curve
  1694. ::
  1695. :: +a-pt-to-base58: concatenate a-pt coords
  1696. ::
  1697. :: we treat an a-pt as 12 64-bit atoms (6 for x, 6 for y). we concatenate them as
  1698. :: fixed-width atoms, put a leading 1 in front of it, and then
  1699. :: convert to a base58 cord.
  1700. ::
  1701. :: we crash when inf=%.y since that is for projective coordinates, which does not
  1702. :: have a unique representation and so must be treated differently.
  1703. ++ a-pt-to-base58
  1704. ~/ %a-pt-to-base58
  1705. |= a=a-pt:curve
  1706. ^- cord
  1707. ?: inf.a !!
  1708. (crip (en-base58 (ser-a-pt a)))
  1709. ::
  1710. ++ ser-a-pt
  1711. ~/ %ser-a-pt
  1712. |= a=a-pt:curve
  1713. ^- @ux
  1714. ?> &((in-g:affine:curve a) !=(a-id:curve p))
  1715. ?: inf.a !!
  1716. %+ rep 6 :: 64 bit atoms
  1717. :~ a0.x.a a1.x.a a2.x.a a3.x.a a4.x.a a5.x.a
  1718. a0.y.a a1.y.a a2.y.a a3.y.a a4.y.a a5.y.a
  1719. 1 :: the leading 1
  1720. ==
  1721. ::
  1722. ++ de-a-pt
  1723. ~/ %de-a-pt
  1724. |= a=@ux
  1725. ^- a-pt:curve
  1726. |^
  1727. =/ pt-list=(list @) (rip-correct 6 a)
  1728. =/ x=f6lt (conv (scag 6 pt-list))
  1729. =/ y=f6lt (conv (scag 6 (oust [0 6] pt-list)))
  1730. ::
  1731. :: We assume the point we are provided is not projective
  1732. :: and set inf to %.n. This will be true so long
  1733. :: as `a` was encoded using ser-a-pt. This also means that a-pt
  1734. :: will never be the identity point, so we skip the check.
  1735. =/ =a-pt:curve [x y %.n]
  1736. ?> (in-g:affine:curve a-pt)
  1737. a-pt
  1738. ++ conv
  1739. |= n=(list @)
  1740. ^- f6lt
  1741. :* (snag 0 n) (snag 1 n) (snag 2 n)
  1742. (snag 3 n) (snag 4 n) (snag 5 n)
  1743. ==
  1744. --
  1745. ++ base58-to-a-pt
  1746. ~/ %base58-to-a-pt
  1747. |= a=cord
  1748. ^- a-pt:curve
  1749. (de-a-pt (de-base58 (trip a)))
  1750. ::
  1751. ::
  1752. ::
  1753. :: +belt-schnorr: a wrapper for Schnorr signatures that works only with belts
  1754. :: TODO: audit this around how rip and rep are used
  1755. ++ belt-schnorr
  1756. |%
  1757. +$ t8 [@ux @ux @ux @ux @ux @ux @ux @ux] :: 8-tuple of belts
  1758. +$ sk t8
  1759. +$ sig t8
  1760. +$ chal t8
  1761. ::
  1762. ++ based
  1763. |= =t8
  1764. ^- ?
  1765. =+ [a=@ux b=@ux c=@ux d=@ux e=@ux f=@ux g=@ux h=@ux]=t8
  1766. ?& (^based a)
  1767. (^based b)
  1768. (^based c)
  1769. (^based d)
  1770. (^based e)
  1771. (^based f)
  1772. (^based g)
  1773. (^based h)
  1774. ==
  1775. ::
  1776. ::
  1777. ++ atom-to-t8
  1778. |= a=@ux
  1779. ^- t8
  1780. =/ ripped=(list @) (rip-correct 5 a)
  1781. :: most of the time, .rippped will be 8 @, but if it has enough leading
  1782. :: zeroes then it won't. +rip reverses the endianness, so we put the
  1783. :: leading zeroes at the end.
  1784. =/ length-dif=@ (sub 8 (lent ripped))
  1785. =. ripped (weld ripped (reap length-dif 0))
  1786. ;;(t8 (list-to-tuple:tip5 (rip-correct 5 a)))
  1787. ::
  1788. ++ t8-to-atom
  1789. |= t=t8
  1790. ^- @ux
  1791. (rap 5 (leaf-sequence:shape t))
  1792. ::
  1793. ++ t8-to-list
  1794. |= t=t8
  1795. ^- (list belt)
  1796. (leaf-sequence:shape t)
  1797. ::
  1798. ++ affine
  1799. |%
  1800. ++ sign
  1801. |= [=sk m=(list belt)]
  1802. ^- [c=chal s=sig]
  1803. =/ [c=@ux s=@ux]
  1804. (sign:affine:schnorr (t8-to-list sk) m)
  1805. [(atom-to-t8 c) (atom-to-t8 s)]
  1806. ::
  1807. ++ verify
  1808. |= [pk=a-pt:curve m=(list belt) =chal =sig]
  1809. ^- ?
  1810. %- verify:affine:schnorr
  1811. :* pk m
  1812. (t8-to-atom chal)
  1813. (t8-to-atom sig)
  1814. ==
  1815. -- ::+affine
  1816. -- ::+belt-schnorr
  1817. -- ::+cheetah
  1818. ::
  1819. ++ merkle :: /lib/merkle
  1820. ~% %merkle ..merkle ~
  1821. |%
  1822. +| %types
  1823. :: TODO: switch merk over to this type once tip5 changes are finalized
  1824. ++ other-merk
  1825. |$ node
  1826. $: h=noun-digest:tip5
  1827. $@ ~
  1828. (pair (merk node) (merk node))
  1829. ==
  1830. ++ merk
  1831. |$ [node]
  1832. $~ [%leaf *noun-digest:tip5 ~]
  1833. $% [%leaf h=noun-digest:tip5 ~]
  1834. [%tree h=noun-digest:tip5 t=(pair (merk node) (merk node))]
  1835. ==
  1836. +$ vector (list @) :: replace with bitvector
  1837. +$ merk-proof [root=noun-digest:tip5 path=(list noun-digest:tip5)]
  1838. +$ merk-heap [h=noun-digest:tip5 m=mary]
  1839. ++ mee
  1840. |$ [node]
  1841. $~ [%leaf *node]
  1842. $% [%leaf n=node]
  1843. [%tree l=(mee node) r=(mee node)]
  1844. ==
  1845. ::
  1846. +| %work
  1847. ++ build-merk
  1848. ~/ %build-merk
  1849. |= m=mary
  1850. ^- (pair @ (merk mary))
  1851. =/ [h=@ n=(mee mary)] (list-to-balanced-tree m)
  1852. :- h
  1853. |-
  1854. ?: ?=([%leaf *] n)
  1855. [%leaf (hash-hashable:tip5 (hashable-mary:tip5 n.n)) ~]
  1856. =/ l=(merk mary) $(n l.n)
  1857. =/ r=(merk mary) $(n r.n)
  1858. [%tree (hash-ten-cell:tip5 h.l h.r) l r]
  1859. ::
  1860. ++ build-merk-heap
  1861. ~/ %build-merk-heap-hoon
  1862. |= m=mary
  1863. (do-build-merk-heap +<)
  1864. ::
  1865. ++ do-build-merk-heap
  1866. ~/ %build-merk-heap
  1867. |= m=mary
  1868. ^- [depth=@ heap=merk-heap]
  1869. |^
  1870. =/ heap-mary (heapify-mary m)
  1871. :- (xeb len.array.m)
  1872. [(snag-as-digest:tip5 heap-mary 0) heap-mary]
  1873. ::
  1874. :: +heapify-mary
  1875. :: Take a mary of felts, merklize it, and return it as a heap
  1876. ++ heapify-mary
  1877. |= m=mary
  1878. ^- mary
  1879. =/ size (dec (bex (xeb len.array.m)))
  1880. =/ high-bit (lsh [6 (mul size 5)] 1)
  1881. :: make leaves
  1882. =/ res=(list (list @))
  1883. %+ turn
  1884. (range len.array.m)
  1885. |= i=@
  1886. =/ t (~(snag-as-fpoly ave m) i)
  1887. (leaf-sequence:shape (hash-hashable:tip5 (hashable-fpoly:tip5 t)))
  1888. :+ 5
  1889. size
  1890. %+ add
  1891. high-bit
  1892. %+ rep 6
  1893. %- zing
  1894. ^- (list (list @))
  1895. =/ curr res
  1896. |-
  1897. ?: =((lent curr) 1)
  1898. res
  1899. =/ pairs (hash-pairs:tip5 curr)
  1900. %= $
  1901. res (weld pairs res)
  1902. curr pairs
  1903. ==
  1904. --
  1905. ::
  1906. ++ bp-build-merk-heap
  1907. ~/ %bp-build-merk-heap-hoon
  1908. |= m=mary
  1909. ^- (pair @ merk-heap)
  1910. (do-bp-build-merk-heap +<)
  1911. ::
  1912. ++ do-bp-build-merk-heap
  1913. ~/ %bp-build-merk-heap
  1914. |= m=mary
  1915. ^- (pair @ merk-heap)
  1916. |^
  1917. =/ heap-mary (heapify-mary m)
  1918. :- (xeb len.array.m)
  1919. [(snag-as-digest:tip5 heap-mary 0) heap-mary]
  1920. ::
  1921. :: +heapify-mary
  1922. :: Take a mary of belts, merklize it, and return it as a heap
  1923. ++ heapify-mary
  1924. |= m=mary
  1925. ^- mary
  1926. =/ size (dec (bex (xeb len.array.m)))
  1927. =/ high-bit (lsh [6 (mul size 5)] 1)
  1928. :: make leaves
  1929. =/ res=(list (list @))
  1930. %+ turn
  1931. (range len.array.m)
  1932. |= i=@
  1933. =/ t (~(snag-as-bpoly ave m) i)
  1934. (leaf-sequence:shape (hash-hashable:tip5 (hashable-bpoly:tip5 t)))
  1935. :+ 5
  1936. size
  1937. %+ add
  1938. high-bit
  1939. %+ rep 6
  1940. %- zing
  1941. ^- (list (list @))
  1942. =/ curr res
  1943. |-
  1944. ?: =((lent curr) 1)
  1945. res
  1946. =/ pairs (hash-pairs:tip5 curr)
  1947. %= $
  1948. res (weld pairs res)
  1949. curr pairs
  1950. ==
  1951. --
  1952. ::
  1953. ++ index-to-axis
  1954. ~/ %index-to-axis
  1955. |= [h=@ i=@]
  1956. ^- axis
  1957. =/ min (bex (dec h))
  1958. (add min i)
  1959. ::
  1960. ++ list-to-balanced-merk
  1961. ~/ %list-to-balanced-merk
  1962. |= lis=mary
  1963. ^- (pair @ (merk mary))
  1964. (build-merk lis)
  1965. ::
  1966. ++ list-to-balanced-tree
  1967. ~/ %list-to-balanced-tree
  1968. |= lis=mary
  1969. ^- [h=@ t=(mee mary)]
  1970. :- (xeb len.array.lis)
  1971. |-
  1972. ?> !=(0 len.array.lis)
  1973. =/ len len.array.lis
  1974. ?: =(1 len)
  1975. [%leaf (~(change-step ave [step.lis 1 (~(snag ave lis) 0)]) 3)]
  1976. ?: =(2 len)
  1977. :+ %tree
  1978. [%leaf (~(change-step ave [step.lis 1 (~(snag ave lis) 0)]) 3)]
  1979. [%leaf (~(change-step ave [step.lis 1 (~(snag ave lis) 1)]) 3)]
  1980. =/ l=(mee mary)
  1981. ?: =((mod len 2) 0)
  1982. $(lis (~(scag ave lis) (div len 2)))
  1983. $(lis (~(scag ave lis) +((div len 2))))
  1984. =/ r=(mee mary)
  1985. ?: =((mod len 2) 0)
  1986. $(lis (~(slag ave lis) (div len 2)))
  1987. $(lis (~(slag ave lis) +((div len 2))))
  1988. [%tree l r]
  1989. ::
  1990. ++ build-merk-proof
  1991. ~/ %build-merk-proof
  1992. |= [merk=merk-heap axis=@]
  1993. ^- merk-proof
  1994. ?: =(0 axis) !!
  1995. :- h.merk
  1996. ?: =(1 axis) ~
  1997. ::
  1998. :: Convert axis to heap index by decrementing
  1999. =. axis (dec axis)
  2000. ^- (list noun-digest:tip5)
  2001. |-
  2002. ?: =(0 axis)
  2003. ~
  2004. =/ parent (div (dec axis) 2)
  2005. =/ sibling
  2006. ?: =(1 (mod axis 2))
  2007. (add axis 1)
  2008. (sub axis 1)
  2009. [(snag-as-digest:tip5 m.merk sibling) $(axis parent)]
  2010. ::
  2011. ++ snag-as-merk-proof
  2012. |= [i=@ root=noun-digest:tip5 merk=mary]
  2013. ^- merk-proof
  2014. =/ mary-pat=mary (~(snag-as-mary ave merk) i)
  2015. =/ pat (~(change-step ave mary-pat) 5)
  2016. =/ merk-path=(list noun-digest:tip5)
  2017. %+ turn (range len.array.pat)
  2018. |= i=@
  2019. (snag-as-digest:tip5 pat i)
  2020. [root merk-path]
  2021. ::
  2022. +$ merk-data [leaf=noun-digest:tip5 axis=@ p=merk-proof]
  2023. ++ verify-merk-proof
  2024. ~/ %verify-merk-proof
  2025. |= [leaf=noun-digest:tip5 axis=@ merk-proof]
  2026. ^- ?
  2027. ?: =(0 axis) %.n
  2028. |-
  2029. ?: =(1 axis)
  2030. &(=(root leaf) ?=(~ path))
  2031. ?~ path %.n
  2032. =* sib i.path
  2033. ::
  2034. :: axis=2 when your parent is the root and you are the left child
  2035. ?: =(2 axis)
  2036. &(=(root (hash-ten-cell:tip5 leaf sib)) ?=(~ t.path))
  2037. ::
  2038. :: axis=3 when your parent is the root and you are the right child
  2039. ?: =(3 axis)
  2040. &(=(root (hash-ten-cell:tip5 sib leaf)) ?=(~ t.path))
  2041. ?: =((mod axis 2) 0)
  2042. $(axis (div axis 2), leaf (hash-ten-cell:tip5 leaf sib), path t.path)
  2043. $(axis (div (dec axis) 2), leaf (hash-ten-cell:tip5 sib leaf), path t.path)
  2044. ::
  2045. --
  2046. --