keccak1600-ppc64.pl 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758
  1. #!/usr/bin/env perl
  2. # Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.
  3. #
  4. # Licensed under the OpenSSL license (the "License"). You may not use
  5. # this file except in compliance with the License. You can obtain a copy
  6. # in the file LICENSE in the source distribution or at
  7. # https://www.openssl.org/source/license.html
  8. #
  9. # ====================================================================
  10. # Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
  11. # project. The module is, however, dual licensed under OpenSSL and
  12. # CRYPTOGAMS licenses depending on where you obtain it. For further
  13. # details see http://www.openssl.org/~appro/cryptogams/.
  14. # ====================================================================
  15. #
  16. # Keccak-1600 for PPC64.
  17. #
  18. # June 2017.
  19. #
  20. # This is straightforward KECCAK_1X_ALT implementation that works on
  21. # *any* PPC64. Then PowerISA 2.07 adds 2x64-bit vector rotate, and
  22. # it's possible to achieve performance better than below, but that is
  23. # naturally option only for POWER8 and successors...
  24. #
  25. ######################################################################
  26. # Numbers are cycles per processed byte.
  27. #
  28. # r=1088(*)
  29. #
  30. # PPC970/G5 14.6/+120%
  31. # POWER7 10.3/+100%
  32. # POWER8 11.5/+85%
  33. # POWER9 9.4/+45%
  34. #
  35. # (*) Corresponds to SHA3-256. Percentage after slash is improvement
  36. # over gcc-4.x-generated KECCAK_1X_ALT code. Newer compilers do
  37. # much better (but watch out for them generating code specific
  38. # to processor they execute on).
  39. $flavour = shift;
  40. if ($flavour =~ /64/) {
  41. $SIZE_T =8;
  42. $LRSAVE =2*$SIZE_T;
  43. $UCMP ="cmpld";
  44. $STU ="stdu";
  45. $POP ="ld";
  46. $PUSH ="std";
  47. } else { die "nonsense $flavour"; }
  48. $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
  49. ( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
  50. ( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or
  51. die "can't locate ppc-xlate.pl";
  52. open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!";
  53. $FRAME=24*$SIZE_T+6*$SIZE_T+32;
  54. $LOCALS=6*$SIZE_T;
  55. $TEMP=$LOCALS+6*$SIZE_T;
  56. my $sp ="r1";
  57. my @A = map([ "r$_", "r".($_+1), "r".($_+2), "r".($_+3), "r".($_+4) ],
  58. (7, 12, 17, 22, 27));
  59. $A[1][1] = "r6"; # r13 is reserved
  60. my @C = map("r$_", (0,3,4,5));
  61. my @rhotates = ([ 0, 1, 62, 28, 27 ],
  62. [ 36, 44, 6, 55, 20 ],
  63. [ 3, 10, 43, 25, 39 ],
  64. [ 41, 45, 15, 21, 8 ],
  65. [ 18, 2, 61, 56, 14 ]);
  66. $code.=<<___;
  67. .text
  68. .type KeccakF1600_int,\@function
  69. .align 5
  70. KeccakF1600_int:
  71. li r0,24
  72. mtctr r0
  73. b .Loop
  74. .align 4
  75. .Loop:
  76. xor $C[0],$A[0][0],$A[1][0] ; Theta
  77. std $A[0][4],`$TEMP+0`($sp)
  78. xor $C[1],$A[0][1],$A[1][1]
  79. std $A[1][4],`$TEMP+8`($sp)
  80. xor $C[2],$A[0][2],$A[1][2]
  81. std $A[2][4],`$TEMP+16`($sp)
  82. xor $C[3],$A[0][3],$A[1][3]
  83. std $A[3][4],`$TEMP+24`($sp)
  84. ___
  85. $C[4]=$A[0][4];
  86. $C[5]=$A[1][4];
  87. $C[6]=$A[2][4];
  88. $C[7]=$A[3][4];
  89. $code.=<<___;
  90. xor $C[4],$A[0][4],$A[1][4]
  91. xor $C[0],$C[0],$A[2][0]
  92. xor $C[1],$C[1],$A[2][1]
  93. xor $C[2],$C[2],$A[2][2]
  94. xor $C[3],$C[3],$A[2][3]
  95. xor $C[4],$C[4],$A[2][4]
  96. xor $C[0],$C[0],$A[3][0]
  97. xor $C[1],$C[1],$A[3][1]
  98. xor $C[2],$C[2],$A[3][2]
  99. xor $C[3],$C[3],$A[3][3]
  100. xor $C[4],$C[4],$A[3][4]
  101. xor $C[0],$C[0],$A[4][0]
  102. xor $C[2],$C[2],$A[4][2]
  103. xor $C[1],$C[1],$A[4][1]
  104. xor $C[3],$C[3],$A[4][3]
  105. rotldi $C[5],$C[2],1
  106. xor $C[4],$C[4],$A[4][4]
  107. rotldi $C[6],$C[3],1
  108. xor $C[5],$C[5],$C[0]
  109. rotldi $C[7],$C[4],1
  110. xor $A[0][1],$A[0][1],$C[5]
  111. xor $A[1][1],$A[1][1],$C[5]
  112. xor $A[2][1],$A[2][1],$C[5]
  113. xor $A[3][1],$A[3][1],$C[5]
  114. xor $A[4][1],$A[4][1],$C[5]
  115. rotldi $C[5],$C[0],1
  116. xor $C[6],$C[6],$C[1]
  117. xor $C[2],$C[2],$C[7]
  118. rotldi $C[7],$C[1],1
  119. xor $C[3],$C[3],$C[5]
  120. xor $C[4],$C[4],$C[7]
  121. xor $C[1], $A[0][2],$C[6] ;mr $C[1],$A[0][2]
  122. xor $A[1][2],$A[1][2],$C[6]
  123. xor $A[2][2],$A[2][2],$C[6]
  124. xor $A[3][2],$A[3][2],$C[6]
  125. xor $A[4][2],$A[4][2],$C[6]
  126. xor $A[0][0],$A[0][0],$C[4]
  127. xor $A[1][0],$A[1][0],$C[4]
  128. xor $A[2][0],$A[2][0],$C[4]
  129. xor $A[3][0],$A[3][0],$C[4]
  130. xor $A[4][0],$A[4][0],$C[4]
  131. ___
  132. $C[4]=undef;
  133. $C[5]=undef;
  134. $C[6]=undef;
  135. $C[7]=undef;
  136. $code.=<<___;
  137. ld $A[0][4],`$TEMP+0`($sp)
  138. xor $C[0], $A[0][3],$C[2] ;mr $C[0],$A[0][3]
  139. ld $A[1][4],`$TEMP+8`($sp)
  140. xor $A[1][3],$A[1][3],$C[2]
  141. ld $A[2][4],`$TEMP+16`($sp)
  142. xor $A[2][3],$A[2][3],$C[2]
  143. ld $A[3][4],`$TEMP+24`($sp)
  144. xor $A[3][3],$A[3][3],$C[2]
  145. xor $A[4][3],$A[4][3],$C[2]
  146. xor $C[2], $A[0][4],$C[3] ;mr $C[2],$A[0][4]
  147. xor $A[1][4],$A[1][4],$C[3]
  148. xor $A[2][4],$A[2][4],$C[3]
  149. xor $A[3][4],$A[3][4],$C[3]
  150. xor $A[4][4],$A[4][4],$C[3]
  151. mr $C[3],$A[0][1] ; Rho+Pi
  152. rotldi $A[0][1],$A[1][1],$rhotates[1][1]
  153. ;mr $C[1],$A[0][2]
  154. rotldi $A[0][2],$A[2][2],$rhotates[2][2]
  155. ;mr $C[0],$A[0][3]
  156. rotldi $A[0][3],$A[3][3],$rhotates[3][3]
  157. ;mr $C[2],$A[0][4]
  158. rotldi $A[0][4],$A[4][4],$rhotates[4][4]
  159. rotldi $A[1][1],$A[1][4],$rhotates[1][4]
  160. rotldi $A[2][2],$A[2][3],$rhotates[2][3]
  161. rotldi $A[3][3],$A[3][2],$rhotates[3][2]
  162. rotldi $A[4][4],$A[4][1],$rhotates[4][1]
  163. rotldi $A[1][4],$A[4][2],$rhotates[4][2]
  164. rotldi $A[2][3],$A[3][4],$rhotates[3][4]
  165. rotldi $A[3][2],$A[2][1],$rhotates[2][1]
  166. rotldi $A[4][1],$A[1][3],$rhotates[1][3]
  167. rotldi $A[4][2],$A[2][4],$rhotates[2][4]
  168. rotldi $A[3][4],$A[4][3],$rhotates[4][3]
  169. rotldi $A[2][1],$A[1][2],$rhotates[1][2]
  170. rotldi $A[1][3],$A[3][1],$rhotates[3][1]
  171. rotldi $A[2][4],$A[4][0],$rhotates[4][0]
  172. rotldi $A[4][3],$A[3][0],$rhotates[3][0]
  173. rotldi $A[1][2],$A[2][0],$rhotates[2][0]
  174. rotldi $A[3][1],$A[1][0],$rhotates[1][0]
  175. rotldi $A[1][0],$C[0],$rhotates[0][3]
  176. rotldi $A[2][0],$C[3],$rhotates[0][1]
  177. rotldi $A[3][0],$C[2],$rhotates[0][4]
  178. rotldi $A[4][0],$C[1],$rhotates[0][2]
  179. andc $C[0],$A[0][2],$A[0][1] ; Chi+Iota
  180. andc $C[1],$A[0][3],$A[0][2]
  181. andc $C[2],$A[0][0],$A[0][4]
  182. andc $C[3],$A[0][1],$A[0][0]
  183. xor $A[0][0],$A[0][0],$C[0]
  184. andc $C[0],$A[0][4],$A[0][3]
  185. xor $A[0][1],$A[0][1],$C[1]
  186. ld $C[1],`$LOCALS+4*$SIZE_T`($sp)
  187. xor $A[0][3],$A[0][3],$C[2]
  188. xor $A[0][4],$A[0][4],$C[3]
  189. xor $A[0][2],$A[0][2],$C[0]
  190. ldu $C[3],8($C[1]) ; Iota[i++]
  191. andc $C[0],$A[1][2],$A[1][1]
  192. std $C[1],`$LOCALS+4*$SIZE_T`($sp)
  193. andc $C[1],$A[1][3],$A[1][2]
  194. andc $C[2],$A[1][0],$A[1][4]
  195. xor $A[0][0],$A[0][0],$C[3] ; A[0][0] ^= Iota
  196. andc $C[3],$A[1][1],$A[1][0]
  197. xor $A[1][0],$A[1][0],$C[0]
  198. andc $C[0],$A[1][4],$A[1][3]
  199. xor $A[1][1],$A[1][1],$C[1]
  200. xor $A[1][3],$A[1][3],$C[2]
  201. xor $A[1][4],$A[1][4],$C[3]
  202. xor $A[1][2],$A[1][2],$C[0]
  203. andc $C[0],$A[2][2],$A[2][1]
  204. andc $C[1],$A[2][3],$A[2][2]
  205. andc $C[2],$A[2][0],$A[2][4]
  206. andc $C[3],$A[2][1],$A[2][0]
  207. xor $A[2][0],$A[2][0],$C[0]
  208. andc $C[0],$A[2][4],$A[2][3]
  209. xor $A[2][1],$A[2][1],$C[1]
  210. xor $A[2][3],$A[2][3],$C[2]
  211. xor $A[2][4],$A[2][4],$C[3]
  212. xor $A[2][2],$A[2][2],$C[0]
  213. andc $C[0],$A[3][2],$A[3][1]
  214. andc $C[1],$A[3][3],$A[3][2]
  215. andc $C[2],$A[3][0],$A[3][4]
  216. andc $C[3],$A[3][1],$A[3][0]
  217. xor $A[3][0],$A[3][0],$C[0]
  218. andc $C[0],$A[3][4],$A[3][3]
  219. xor $A[3][1],$A[3][1],$C[1]
  220. xor $A[3][3],$A[3][3],$C[2]
  221. xor $A[3][4],$A[3][4],$C[3]
  222. xor $A[3][2],$A[3][2],$C[0]
  223. andc $C[0],$A[4][2],$A[4][1]
  224. andc $C[1],$A[4][3],$A[4][2]
  225. andc $C[2],$A[4][0],$A[4][4]
  226. andc $C[3],$A[4][1],$A[4][0]
  227. xor $A[4][0],$A[4][0],$C[0]
  228. andc $C[0],$A[4][4],$A[4][3]
  229. xor $A[4][1],$A[4][1],$C[1]
  230. xor $A[4][3],$A[4][3],$C[2]
  231. xor $A[4][4],$A[4][4],$C[3]
  232. xor $A[4][2],$A[4][2],$C[0]
  233. bdnz .Loop
  234. blr
  235. .long 0
  236. .byte 0,12,0x14,0,0,0,0,0
  237. .size KeccakF1600_int,.-KeccakF1600_int
  238. .type KeccakF1600,\@function
  239. .align 5
  240. KeccakF1600:
  241. $STU $sp,-$FRAME($sp)
  242. mflr r0
  243. $PUSH r14,`$FRAME-$SIZE_T*18`($sp)
  244. $PUSH r15,`$FRAME-$SIZE_T*17`($sp)
  245. $PUSH r16,`$FRAME-$SIZE_T*16`($sp)
  246. $PUSH r17,`$FRAME-$SIZE_T*15`($sp)
  247. $PUSH r18,`$FRAME-$SIZE_T*14`($sp)
  248. $PUSH r19,`$FRAME-$SIZE_T*13`($sp)
  249. $PUSH r20,`$FRAME-$SIZE_T*12`($sp)
  250. $PUSH r21,`$FRAME-$SIZE_T*11`($sp)
  251. $PUSH r22,`$FRAME-$SIZE_T*10`($sp)
  252. $PUSH r23,`$FRAME-$SIZE_T*9`($sp)
  253. $PUSH r24,`$FRAME-$SIZE_T*8`($sp)
  254. $PUSH r25,`$FRAME-$SIZE_T*7`($sp)
  255. $PUSH r26,`$FRAME-$SIZE_T*6`($sp)
  256. $PUSH r27,`$FRAME-$SIZE_T*5`($sp)
  257. $PUSH r28,`$FRAME-$SIZE_T*4`($sp)
  258. $PUSH r29,`$FRAME-$SIZE_T*3`($sp)
  259. $PUSH r30,`$FRAME-$SIZE_T*2`($sp)
  260. $PUSH r31,`$FRAME-$SIZE_T*1`($sp)
  261. $PUSH r0,`$FRAME+$LRSAVE`($sp)
  262. bl PICmeup
  263. subi r12,r12,8 ; prepare for ldu
  264. $PUSH r3,`$LOCALS+0*$SIZE_T`($sp)
  265. ;$PUSH r4,`$LOCALS+1*$SIZE_T`($sp)
  266. ;$PUSH r5,`$LOCALS+2*$SIZE_T`($sp)
  267. ;$PUSH r6,`$LOCALS+3*$SIZE_T`($sp)
  268. $PUSH r12,`$LOCALS+4*$SIZE_T`($sp)
  269. ld $A[0][0],`8*0`(r3) ; load A[5][5]
  270. ld $A[0][1],`8*1`(r3)
  271. ld $A[0][2],`8*2`(r3)
  272. ld $A[0][3],`8*3`(r3)
  273. ld $A[0][4],`8*4`(r3)
  274. ld $A[1][0],`8*5`(r3)
  275. ld $A[1][1],`8*6`(r3)
  276. ld $A[1][2],`8*7`(r3)
  277. ld $A[1][3],`8*8`(r3)
  278. ld $A[1][4],`8*9`(r3)
  279. ld $A[2][0],`8*10`(r3)
  280. ld $A[2][1],`8*11`(r3)
  281. ld $A[2][2],`8*12`(r3)
  282. ld $A[2][3],`8*13`(r3)
  283. ld $A[2][4],`8*14`(r3)
  284. ld $A[3][0],`8*15`(r3)
  285. ld $A[3][1],`8*16`(r3)
  286. ld $A[3][2],`8*17`(r3)
  287. ld $A[3][3],`8*18`(r3)
  288. ld $A[3][4],`8*19`(r3)
  289. ld $A[4][0],`8*20`(r3)
  290. ld $A[4][1],`8*21`(r3)
  291. ld $A[4][2],`8*22`(r3)
  292. ld $A[4][3],`8*23`(r3)
  293. ld $A[4][4],`8*24`(r3)
  294. bl KeccakF1600_int
  295. $POP r3,`$LOCALS+0*$SIZE_T`($sp)
  296. std $A[0][0],`8*0`(r3) ; return A[5][5]
  297. std $A[0][1],`8*1`(r3)
  298. std $A[0][2],`8*2`(r3)
  299. std $A[0][3],`8*3`(r3)
  300. std $A[0][4],`8*4`(r3)
  301. std $A[1][0],`8*5`(r3)
  302. std $A[1][1],`8*6`(r3)
  303. std $A[1][2],`8*7`(r3)
  304. std $A[1][3],`8*8`(r3)
  305. std $A[1][4],`8*9`(r3)
  306. std $A[2][0],`8*10`(r3)
  307. std $A[2][1],`8*11`(r3)
  308. std $A[2][2],`8*12`(r3)
  309. std $A[2][3],`8*13`(r3)
  310. std $A[2][4],`8*14`(r3)
  311. std $A[3][0],`8*15`(r3)
  312. std $A[3][1],`8*16`(r3)
  313. std $A[3][2],`8*17`(r3)
  314. std $A[3][3],`8*18`(r3)
  315. std $A[3][4],`8*19`(r3)
  316. std $A[4][0],`8*20`(r3)
  317. std $A[4][1],`8*21`(r3)
  318. std $A[4][2],`8*22`(r3)
  319. std $A[4][3],`8*23`(r3)
  320. std $A[4][4],`8*24`(r3)
  321. $POP r0,`$FRAME+$LRSAVE`($sp)
  322. $POP r14,`$FRAME-$SIZE_T*18`($sp)
  323. $POP r15,`$FRAME-$SIZE_T*17`($sp)
  324. $POP r16,`$FRAME-$SIZE_T*16`($sp)
  325. $POP r17,`$FRAME-$SIZE_T*15`($sp)
  326. $POP r18,`$FRAME-$SIZE_T*14`($sp)
  327. $POP r19,`$FRAME-$SIZE_T*13`($sp)
  328. $POP r20,`$FRAME-$SIZE_T*12`($sp)
  329. $POP r21,`$FRAME-$SIZE_T*11`($sp)
  330. $POP r22,`$FRAME-$SIZE_T*10`($sp)
  331. $POP r23,`$FRAME-$SIZE_T*9`($sp)
  332. $POP r24,`$FRAME-$SIZE_T*8`($sp)
  333. $POP r25,`$FRAME-$SIZE_T*7`($sp)
  334. $POP r26,`$FRAME-$SIZE_T*6`($sp)
  335. $POP r27,`$FRAME-$SIZE_T*5`($sp)
  336. $POP r28,`$FRAME-$SIZE_T*4`($sp)
  337. $POP r29,`$FRAME-$SIZE_T*3`($sp)
  338. $POP r30,`$FRAME-$SIZE_T*2`($sp)
  339. $POP r31,`$FRAME-$SIZE_T*1`($sp)
  340. mtlr r0
  341. addi $sp,$sp,$FRAME
  342. blr
  343. .long 0
  344. .byte 0,12,4,1,0x80,18,1,0
  345. .long 0
  346. .size KeccakF1600,.-KeccakF1600
  347. .type dword_le_load,\@function
  348. .align 5
  349. dword_le_load:
  350. lbzu r0,1(r3)
  351. lbzu r4,1(r3)
  352. lbzu r5,1(r3)
  353. insrdi r0,r4,8,48
  354. lbzu r4,1(r3)
  355. insrdi r0,r5,8,40
  356. lbzu r5,1(r3)
  357. insrdi r0,r4,8,32
  358. lbzu r4,1(r3)
  359. insrdi r0,r5,8,24
  360. lbzu r5,1(r3)
  361. insrdi r0,r4,8,16
  362. lbzu r4,1(r3)
  363. insrdi r0,r5,8,8
  364. insrdi r0,r4,8,0
  365. blr
  366. .long 0
  367. .byte 0,12,0x14,0,0,0,1,0
  368. .long 0
  369. .size dword_le_load,.-dword_le_load
  370. .globl SHA3_absorb
  371. .type SHA3_absorb,\@function
  372. .align 5
  373. SHA3_absorb:
  374. $STU $sp,-$FRAME($sp)
  375. mflr r0
  376. $PUSH r14,`$FRAME-$SIZE_T*18`($sp)
  377. $PUSH r15,`$FRAME-$SIZE_T*17`($sp)
  378. $PUSH r16,`$FRAME-$SIZE_T*16`($sp)
  379. $PUSH r17,`$FRAME-$SIZE_T*15`($sp)
  380. $PUSH r18,`$FRAME-$SIZE_T*14`($sp)
  381. $PUSH r19,`$FRAME-$SIZE_T*13`($sp)
  382. $PUSH r20,`$FRAME-$SIZE_T*12`($sp)
  383. $PUSH r21,`$FRAME-$SIZE_T*11`($sp)
  384. $PUSH r22,`$FRAME-$SIZE_T*10`($sp)
  385. $PUSH r23,`$FRAME-$SIZE_T*9`($sp)
  386. $PUSH r24,`$FRAME-$SIZE_T*8`($sp)
  387. $PUSH r25,`$FRAME-$SIZE_T*7`($sp)
  388. $PUSH r26,`$FRAME-$SIZE_T*6`($sp)
  389. $PUSH r27,`$FRAME-$SIZE_T*5`($sp)
  390. $PUSH r28,`$FRAME-$SIZE_T*4`($sp)
  391. $PUSH r29,`$FRAME-$SIZE_T*3`($sp)
  392. $PUSH r30,`$FRAME-$SIZE_T*2`($sp)
  393. $PUSH r31,`$FRAME-$SIZE_T*1`($sp)
  394. $PUSH r0,`$FRAME+$LRSAVE`($sp)
  395. bl PICmeup
  396. subi r4,r4,1 ; prepare for lbzu
  397. subi r12,r12,8 ; prepare for ldu
  398. $PUSH r3,`$LOCALS+0*$SIZE_T`($sp) ; save A[][]
  399. $PUSH r4,`$LOCALS+1*$SIZE_T`($sp) ; save inp
  400. $PUSH r5,`$LOCALS+2*$SIZE_T`($sp) ; save len
  401. $PUSH r6,`$LOCALS+3*$SIZE_T`($sp) ; save bsz
  402. mr r0,r6
  403. $PUSH r12,`$LOCALS+4*$SIZE_T`($sp)
  404. ld $A[0][0],`8*0`(r3) ; load A[5][5]
  405. ld $A[0][1],`8*1`(r3)
  406. ld $A[0][2],`8*2`(r3)
  407. ld $A[0][3],`8*3`(r3)
  408. ld $A[0][4],`8*4`(r3)
  409. ld $A[1][0],`8*5`(r3)
  410. ld $A[1][1],`8*6`(r3)
  411. ld $A[1][2],`8*7`(r3)
  412. ld $A[1][3],`8*8`(r3)
  413. ld $A[1][4],`8*9`(r3)
  414. ld $A[2][0],`8*10`(r3)
  415. ld $A[2][1],`8*11`(r3)
  416. ld $A[2][2],`8*12`(r3)
  417. ld $A[2][3],`8*13`(r3)
  418. ld $A[2][4],`8*14`(r3)
  419. ld $A[3][0],`8*15`(r3)
  420. ld $A[3][1],`8*16`(r3)
  421. ld $A[3][2],`8*17`(r3)
  422. ld $A[3][3],`8*18`(r3)
  423. ld $A[3][4],`8*19`(r3)
  424. ld $A[4][0],`8*20`(r3)
  425. ld $A[4][1],`8*21`(r3)
  426. ld $A[4][2],`8*22`(r3)
  427. ld $A[4][3],`8*23`(r3)
  428. ld $A[4][4],`8*24`(r3)
  429. mr r3,r4
  430. mr r4,r5
  431. mr r5,r0
  432. b .Loop_absorb
  433. .align 4
  434. .Loop_absorb:
  435. $UCMP r4,r5 ; len < bsz?
  436. blt .Labsorbed
  437. sub r4,r4,r5 ; len -= bsz
  438. srwi r5,r5,3
  439. $PUSH r4,`$LOCALS+2*$SIZE_T`($sp) ; save len
  440. mtctr r5
  441. bl dword_le_load ; *inp++
  442. xor $A[0][0],$A[0][0],r0
  443. bdz .Lprocess_block
  444. bl dword_le_load ; *inp++
  445. xor $A[0][1],$A[0][1],r0
  446. bdz .Lprocess_block
  447. bl dword_le_load ; *inp++
  448. xor $A[0][2],$A[0][2],r0
  449. bdz .Lprocess_block
  450. bl dword_le_load ; *inp++
  451. xor $A[0][3],$A[0][3],r0
  452. bdz .Lprocess_block
  453. bl dword_le_load ; *inp++
  454. xor $A[0][4],$A[0][4],r0
  455. bdz .Lprocess_block
  456. bl dword_le_load ; *inp++
  457. xor $A[1][0],$A[1][0],r0
  458. bdz .Lprocess_block
  459. bl dword_le_load ; *inp++
  460. xor $A[1][1],$A[1][1],r0
  461. bdz .Lprocess_block
  462. bl dword_le_load ; *inp++
  463. xor $A[1][2],$A[1][2],r0
  464. bdz .Lprocess_block
  465. bl dword_le_load ; *inp++
  466. xor $A[1][3],$A[1][3],r0
  467. bdz .Lprocess_block
  468. bl dword_le_load ; *inp++
  469. xor $A[1][4],$A[1][4],r0
  470. bdz .Lprocess_block
  471. bl dword_le_load ; *inp++
  472. xor $A[2][0],$A[2][0],r0
  473. bdz .Lprocess_block
  474. bl dword_le_load ; *inp++
  475. xor $A[2][1],$A[2][1],r0
  476. bdz .Lprocess_block
  477. bl dword_le_load ; *inp++
  478. xor $A[2][2],$A[2][2],r0
  479. bdz .Lprocess_block
  480. bl dword_le_load ; *inp++
  481. xor $A[2][3],$A[2][3],r0
  482. bdz .Lprocess_block
  483. bl dword_le_load ; *inp++
  484. xor $A[2][4],$A[2][4],r0
  485. bdz .Lprocess_block
  486. bl dword_le_load ; *inp++
  487. xor $A[3][0],$A[3][0],r0
  488. bdz .Lprocess_block
  489. bl dword_le_load ; *inp++
  490. xor $A[3][1],$A[3][1],r0
  491. bdz .Lprocess_block
  492. bl dword_le_load ; *inp++
  493. xor $A[3][2],$A[3][2],r0
  494. bdz .Lprocess_block
  495. bl dword_le_load ; *inp++
  496. xor $A[3][3],$A[3][3],r0
  497. bdz .Lprocess_block
  498. bl dword_le_load ; *inp++
  499. xor $A[3][4],$A[3][4],r0
  500. bdz .Lprocess_block
  501. bl dword_le_load ; *inp++
  502. xor $A[4][0],$A[4][0],r0
  503. bdz .Lprocess_block
  504. bl dword_le_load ; *inp++
  505. xor $A[4][1],$A[4][1],r0
  506. bdz .Lprocess_block
  507. bl dword_le_load ; *inp++
  508. xor $A[4][2],$A[4][2],r0
  509. bdz .Lprocess_block
  510. bl dword_le_load ; *inp++
  511. xor $A[4][3],$A[4][3],r0
  512. bdz .Lprocess_block
  513. bl dword_le_load ; *inp++
  514. xor $A[4][4],$A[4][4],r0
  515. .Lprocess_block:
  516. $PUSH r3,`$LOCALS+1*$SIZE_T`($sp) ; save inp
  517. bl KeccakF1600_int
  518. $POP r0,`$LOCALS+4*$SIZE_T`($sp) ; pull iotas[24]
  519. $POP r5,`$LOCALS+3*$SIZE_T`($sp) ; restore bsz
  520. $POP r4,`$LOCALS+2*$SIZE_T`($sp) ; restore len
  521. $POP r3,`$LOCALS+1*$SIZE_T`($sp) ; restore inp
  522. addic r0,r0,`-8*24` ; rewind iotas
  523. $PUSH r0,`$LOCALS+4*$SIZE_T`($sp)
  524. b .Loop_absorb
  525. .align 4
  526. .Labsorbed:
  527. $POP r3,`$LOCALS+0*$SIZE_T`($sp)
  528. std $A[0][0],`8*0`(r3) ; return A[5][5]
  529. std $A[0][1],`8*1`(r3)
  530. std $A[0][2],`8*2`(r3)
  531. std $A[0][3],`8*3`(r3)
  532. std $A[0][4],`8*4`(r3)
  533. std $A[1][0],`8*5`(r3)
  534. std $A[1][1],`8*6`(r3)
  535. std $A[1][2],`8*7`(r3)
  536. std $A[1][3],`8*8`(r3)
  537. std $A[1][4],`8*9`(r3)
  538. std $A[2][0],`8*10`(r3)
  539. std $A[2][1],`8*11`(r3)
  540. std $A[2][2],`8*12`(r3)
  541. std $A[2][3],`8*13`(r3)
  542. std $A[2][4],`8*14`(r3)
  543. std $A[3][0],`8*15`(r3)
  544. std $A[3][1],`8*16`(r3)
  545. std $A[3][2],`8*17`(r3)
  546. std $A[3][3],`8*18`(r3)
  547. std $A[3][4],`8*19`(r3)
  548. std $A[4][0],`8*20`(r3)
  549. std $A[4][1],`8*21`(r3)
  550. std $A[4][2],`8*22`(r3)
  551. std $A[4][3],`8*23`(r3)
  552. std $A[4][4],`8*24`(r3)
  553. mr r3,r4 ; return value
  554. $POP r0,`$FRAME+$LRSAVE`($sp)
  555. $POP r14,`$FRAME-$SIZE_T*18`($sp)
  556. $POP r15,`$FRAME-$SIZE_T*17`($sp)
  557. $POP r16,`$FRAME-$SIZE_T*16`($sp)
  558. $POP r17,`$FRAME-$SIZE_T*15`($sp)
  559. $POP r18,`$FRAME-$SIZE_T*14`($sp)
  560. $POP r19,`$FRAME-$SIZE_T*13`($sp)
  561. $POP r20,`$FRAME-$SIZE_T*12`($sp)
  562. $POP r21,`$FRAME-$SIZE_T*11`($sp)
  563. $POP r22,`$FRAME-$SIZE_T*10`($sp)
  564. $POP r23,`$FRAME-$SIZE_T*9`($sp)
  565. $POP r24,`$FRAME-$SIZE_T*8`($sp)
  566. $POP r25,`$FRAME-$SIZE_T*7`($sp)
  567. $POP r26,`$FRAME-$SIZE_T*6`($sp)
  568. $POP r27,`$FRAME-$SIZE_T*5`($sp)
  569. $POP r28,`$FRAME-$SIZE_T*4`($sp)
  570. $POP r29,`$FRAME-$SIZE_T*3`($sp)
  571. $POP r30,`$FRAME-$SIZE_T*2`($sp)
  572. $POP r31,`$FRAME-$SIZE_T*1`($sp)
  573. mtlr r0
  574. addi $sp,$sp,$FRAME
  575. blr
  576. .long 0
  577. .byte 0,12,4,1,0x80,18,4,0
  578. .long 0
  579. .size SHA3_absorb,.-SHA3_absorb
  580. ___
  581. {
  582. my ($A_flat,$out,$len,$bsz) = map("r$_",(28..31));
  583. $code.=<<___;
  584. .globl SHA3_squeeze
  585. .type SHA3_squeeze,\@function
  586. .align 5
  587. SHA3_squeeze:
  588. $STU $sp,`-10*$SIZE_T`($sp)
  589. mflr r0
  590. $PUSH r28,`6*$SIZE_T`($sp)
  591. $PUSH r29,`7*$SIZE_T`($sp)
  592. $PUSH r30,`8*$SIZE_T`($sp)
  593. $PUSH r31,`9*$SIZE_T`($sp)
  594. $PUSH r0,`10*$SIZE_T+$LRSAVE`($sp)
  595. mr $A_flat,r3
  596. subi r3,r3,8 ; prepare for ldu
  597. subi $out,r4,1 ; prepare for stbu
  598. mr $len,r5
  599. mr $bsz,r6
  600. b .Loop_squeeze
  601. .align 4
  602. .Loop_squeeze:
  603. ldu r0,8(r3)
  604. ${UCMP}i $len,8
  605. blt .Lsqueeze_tail
  606. stbu r0,1($out)
  607. srdi r0,r0,8
  608. stbu r0,1($out)
  609. srdi r0,r0,8
  610. stbu r0,1($out)
  611. srdi r0,r0,8
  612. stbu r0,1($out)
  613. srdi r0,r0,8
  614. stbu r0,1($out)
  615. srdi r0,r0,8
  616. stbu r0,1($out)
  617. srdi r0,r0,8
  618. stbu r0,1($out)
  619. srdi r0,r0,8
  620. stbu r0,1($out)
  621. subic. $len,$len,8
  622. beq .Lsqueeze_done
  623. subic. r6,r6,8
  624. bgt .Loop_squeeze
  625. mr r3,$A_flat
  626. bl KeccakF1600
  627. subi r3,$A_flat,8 ; prepare for ldu
  628. mr r6,$bsz
  629. b .Loop_squeeze
  630. .align 4
  631. .Lsqueeze_tail:
  632. mtctr $len
  633. .Loop_tail:
  634. stbu r0,1($out)
  635. srdi r0,r0,8
  636. bdnz .Loop_tail
  637. .Lsqueeze_done:
  638. $POP r0,`10*$SIZE_T+$LRSAVE`($sp)
  639. $POP r28,`6*$SIZE_T`($sp)
  640. $POP r29,`7*$SIZE_T`($sp)
  641. $POP r30,`8*$SIZE_T`($sp)
  642. $POP r31,`9*$SIZE_T`($sp)
  643. mtlr r0
  644. addi $sp,$sp,`10*$SIZE_T`
  645. blr
  646. .long 0
  647. .byte 0,12,4,1,0x80,4,4,0
  648. .long 0
  649. .size SHA3_squeeze,.-SHA3_squeeze
  650. ___
  651. }
  652. # Ugly hack here, because PPC assembler syntax seem to vary too
  653. # much from platforms to platform...
  654. $code.=<<___;
  655. .align 6
  656. PICmeup:
  657. mflr r0
  658. bcl 20,31,\$+4
  659. mflr r12 ; vvvvvv "distance" between . and 1st data entry
  660. addi r12,r12,`64-8`
  661. mtlr r0
  662. blr
  663. .long 0
  664. .byte 0,12,0x14,0,0,0,0,0
  665. .space `64-9*4`
  666. .type iotas,\@object
  667. iotas:
  668. .quad 0x0000000000000001
  669. .quad 0x0000000000008082
  670. .quad 0x800000000000808a
  671. .quad 0x8000000080008000
  672. .quad 0x000000000000808b
  673. .quad 0x0000000080000001
  674. .quad 0x8000000080008081
  675. .quad 0x8000000000008009
  676. .quad 0x000000000000008a
  677. .quad 0x0000000000000088
  678. .quad 0x0000000080008009
  679. .quad 0x000000008000000a
  680. .quad 0x000000008000808b
  681. .quad 0x800000000000008b
  682. .quad 0x8000000000008089
  683. .quad 0x8000000000008003
  684. .quad 0x8000000000008002
  685. .quad 0x8000000000000080
  686. .quad 0x000000000000800a
  687. .quad 0x800000008000000a
  688. .quad 0x8000000080008081
  689. .quad 0x8000000000008080
  690. .quad 0x0000000080000001
  691. .quad 0x8000000080008008
  692. .size iotas,.-iotas
  693. .asciz "Keccak-1600 absorb and squeeze for PPC64, CRYPTOGAMS by <appro\@openssl.org>"
  694. ___
  695. $code =~ s/\`([^\`]*)\`/eval $1/gem;
  696. print $code;
  697. close STDOUT;