keccak-armv7-neon.S 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946
  1. /* keccak-armv7-neon.S - ARMv7/NEON implementation of Keccak
  2. *
  3. * Copyright (C) 2015 Jussi Kivilinna <jussi.kivilinna@iki.fi>
  4. *
  5. * This file is part of Libgcrypt.
  6. *
  7. * Libgcrypt is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU Lesser General Public License as
  9. * published by the Free Software Foundation; either version 2.1 of
  10. * the License, or (at your option) any later version.
  11. *
  12. * Libgcrypt is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with this program; if not, see <http://www.gnu.org/licenses/>.
  19. */
  20. #include <config.h>
  21. #if defined(HAVE_ARM_ARCH_V6) && defined(__ARMEL__) && \
  22. defined(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS) && \
  23. defined(HAVE_GCC_INLINE_ASM_NEON)
  24. /* Based on public-domain/CC0 implementation from SUPERCOP package
  25. * (keccakc1024/inplace-armv7a-neon/keccak2.s)
  26. *
  27. * Original copyright header follows:
  28. */
  29. @ The Keccak sponge function, designed by Guido Bertoni, Joan Daemen,
  30. @ Michaël Peeters and Gilles Van Assche. For more information, feedback or
  31. @ questions, please refer to our website: http://keccak.noekeon.org/
  32. @
  33. @ Implementation by Ronny Van Keer, hereby denoted as "the implementer".
  34. @
  35. @ To the extent possible under law, the implementer has waived all copyright
  36. @ and related or neighboring rights to the source code in this file.
  37. @ http://creativecommons.org/publicdomain/zero/1.0/
  38. .text
  39. .syntax unified
  40. .fpu neon
  41. .arm
  42. .extern _gcry_keccak_round_consts_64bit;
  43. #ifdef __PIC__
  44. # define GET_DATA_POINTER(reg, name, rtmp) \
  45. ldr reg, 1f; \
  46. ldr rtmp, 2f; \
  47. b 3f; \
  48. 1: .word _GLOBAL_OFFSET_TABLE_-(3f+8); \
  49. 2: .word name(GOT); \
  50. 3: add reg, pc, reg; \
  51. ldr reg, [reg, rtmp];
  52. #else
  53. # define GET_DATA_POINTER(reg, name, rtmp) ldr reg, =name
  54. #endif
  55. @// --- offsets in state
  56. .equ Aba, 0*8
  57. .equ Aga, 1*8
  58. .equ Aka, 2*8
  59. .equ Ama, 3*8
  60. .equ Asa, 4*8
  61. @// --- macros
  62. .macro KeccakThetaRhoPiChiIota argA1, argA2, argA3, argA4, argA5
  63. @Prepare Theta
  64. @Ca = Aba^Aga^Aka^Ama^Asa@
  65. @Ce = Abe^Age^Ake^Ame^Ase@
  66. @Ci = Abi^Agi^Aki^Ami^Asi@
  67. @Co = Abo^Ago^Ako^Amo^Aso@
  68. @Cu = Abu^Agu^Aku^Amu^Asu@
  69. @De = Ca^ROL64(Ci, 1)@
  70. @Di = Ce^ROL64(Co, 1)@
  71. @Do = Ci^ROL64(Cu, 1)@
  72. @Du = Co^ROL64(Ca, 1)@
  73. @Da = Cu^ROL64(Ce, 1)@
  74. veor.64 q4, q6, q7
  75. veor.64 q5, q9, q10
  76. veor.64 d8, d8, d9
  77. veor.64 d10, d10, d11
  78. veor.64 d1, d8, d16
  79. veor.64 d2, d10, d17
  80. veor.64 q4, q11, q12
  81. veor.64 q5, q14, q15
  82. veor.64 d8, d8, d9
  83. veor.64 d10, d10, d11
  84. veor.64 d3, d8, d26
  85. vadd.u64 q4, q1, q1
  86. veor.64 d4, d10, d27
  87. vmov.64 d0, d5
  88. vsri.64 q4, q1, #63
  89. vadd.u64 q5, q2, q2
  90. veor.64 q4, q4, q0
  91. vsri.64 q5, q2, #63
  92. vadd.u64 d7, d1, d1
  93. veor.64 \argA2, \argA2, d8
  94. veor.64 q5, q5, q1
  95. vsri.64 d7, d1, #63
  96. vshl.u64 d1, \argA2, #44
  97. veor.64 \argA3, \argA3, d9
  98. veor.64 d7, d7, d4
  99. @Ba = argA1^Da@
  100. @Be = ROL64((argA2^De), 44)@
  101. @Bi = ROL64((argA3^Di), 43)@
  102. @Bo = ROL64((argA4^Do), 21)@
  103. @Bu = ROL64((argA5^Du), 14)@
  104. @argA2 = Be ^((~Bi)& Bo )@
  105. @argA3 = Bi ^((~Bo)& Bu )@
  106. @argA4 = Bo ^((~Bu)& Ba )@
  107. @argA5 = Bu ^((~Ba)& Be )@
  108. @argA1 = Ba ^((~Be)& Bi )@ argA1 ^= KeccakF1600RoundConstants[i+round]@
  109. vsri.64 d1, \argA2, #64-44
  110. vshl.u64 d2, \argA3, #43
  111. vldr.64 d0, [sp, #\argA1]
  112. veor.64 \argA4, \argA4, d10
  113. vsri.64 d2, \argA3, #64-43
  114. vshl.u64 d3, \argA4, #21
  115. veor.64 \argA5, \argA5, d11
  116. veor.64 d0, d0, d7
  117. vsri.64 d3, \argA4, #64-21
  118. vbic.64 d5, d2, d1
  119. vshl.u64 d4, \argA5, #14
  120. vbic.64 \argA2, d3, d2
  121. vld1.64 d6, [ip]!
  122. veor.64 d5, d0
  123. vsri.64 d4, \argA5, #64-14
  124. veor.64 d5, d6
  125. vbic.64 \argA5, d1, d0
  126. vbic.64 \argA3, d4, d3
  127. vbic.64 \argA4, d0, d4
  128. veor.64 \argA2, d1
  129. vstr.64 d5, [sp, #\argA1]
  130. veor.64 \argA3, d2
  131. veor.64 \argA4, d3
  132. veor.64 \argA5, d4
  133. .endm
  134. .macro KeccakThetaRhoPiChi1 argA1, argA2, argA3, argA4, argA5
  135. @d2 = ROL64((argA1^Da), 3)@
  136. @d3 = ROL64((argA2^De), 45)@
  137. @d4 = ROL64((argA3^Di), 61)@
  138. @d0 = ROL64((argA4^Do), 28)@
  139. @d1 = ROL64((argA5^Du), 20)@
  140. @argA1 = Ba ^((~Be)& Bi )@ Ca ^= argA1@
  141. @argA2 = Be ^((~Bi)& Bo )@
  142. @argA3 = Bi ^((~Bo)& Bu )@
  143. @argA4 = Bo ^((~Bu)& Ba )@
  144. @argA5 = Bu ^((~Ba)& Be )@
  145. veor.64 \argA2, \argA2, d8
  146. veor.64 \argA3, \argA3, d9
  147. vshl.u64 d3, \argA2, #45
  148. vldr.64 d6, [sp, #\argA1]
  149. vshl.u64 d4, \argA3, #61
  150. veor.64 \argA4, \argA4, d10
  151. vsri.64 d3, \argA2, #64-45
  152. veor.64 \argA5, \argA5, d11
  153. vsri.64 d4, \argA3, #64-61
  154. vshl.u64 d0, \argA4, #28
  155. veor.64 d6, d6, d7
  156. vshl.u64 d1, \argA5, #20
  157. vbic.64 \argA3, d4, d3
  158. vsri.64 d0, \argA4, #64-28
  159. vbic.64 \argA4, d0, d4
  160. vshl.u64 d2, d6, #3
  161. vsri.64 d1, \argA5, #64-20
  162. veor.64 \argA4, d3
  163. vsri.64 d2, d6, #64-3
  164. vbic.64 \argA5, d1, d0
  165. vbic.64 d6, d2, d1
  166. vbic.64 \argA2, d3, d2
  167. veor.64 d6, d0
  168. veor.64 \argA2, d1
  169. vstr.64 d6, [sp, #\argA1]
  170. veor.64 \argA3, d2
  171. veor.64 d5, d6
  172. veor.64 \argA5, d4
  173. .endm
  174. .macro KeccakThetaRhoPiChi2 argA1, argA2, argA3, argA4, argA5
  175. @d4 = ROL64((argA1^Da), 18)@
  176. @d0 = ROL64((argA2^De), 1)@
  177. @d1 = ROL64((argA3^Di), 6)@
  178. @d2 = ROL64((argA4^Do), 25)@
  179. @d3 = ROL64((argA5^Du), 8)@
  180. @argA1 = Ba ^((~Be)& Bi )@ Ca ^= argA1@
  181. @argA2 = Be ^((~Bi)& Bo )@
  182. @argA3 = Bi ^((~Bo)& Bu )@
  183. @argA4 = Bo ^((~Bu)& Ba )@
  184. @argA5 = Bu ^((~Ba)& Be )@
  185. veor.64 \argA3, \argA3, d9
  186. veor.64 \argA4, \argA4, d10
  187. vshl.u64 d1, \argA3, #6
  188. vldr.64 d6, [sp, #\argA1]
  189. vshl.u64 d2, \argA4, #25
  190. veor.64 \argA5, \argA5, d11
  191. vsri.64 d1, \argA3, #64-6
  192. veor.64 \argA2, \argA2, d8
  193. vsri.64 d2, \argA4, #64-25
  194. vext.8 d3, \argA5, \argA5, #7
  195. veor.64 d6, d6, d7
  196. vbic.64 \argA3, d2, d1
  197. vadd.u64 d0, \argA2, \argA2
  198. vbic.64 \argA4, d3, d2
  199. vsri.64 d0, \argA2, #64-1
  200. vshl.u64 d4, d6, #18
  201. veor.64 \argA2, d1, \argA4
  202. veor.64 \argA3, d0
  203. vsri.64 d4, d6, #64-18
  204. vstr.64 \argA3, [sp, #\argA1]
  205. veor.64 d5, \argA3
  206. vbic.64 \argA5, d1, d0
  207. vbic.64 \argA3, d4, d3
  208. vbic.64 \argA4, d0, d4
  209. veor.64 \argA3, d2
  210. veor.64 \argA4, d3
  211. veor.64 \argA5, d4
  212. .endm
  213. .macro KeccakThetaRhoPiChi3 argA1, argA2, argA3, argA4, argA5
  214. @d1 = ROL64((argA1^Da), 36)@
  215. @d2 = ROL64((argA2^De), 10)@
  216. @d3 = ROL64((argA3^Di), 15)@
  217. @d4 = ROL64((argA4^Do), 56)@
  218. @d0 = ROL64((argA5^Du), 27)@
  219. @argA1 = Ba ^((~Be)& Bi )@ Ca ^= argA1@
  220. @argA2 = Be ^((~Bi)& Bo )@
  221. @argA3 = Bi ^((~Bo)& Bu )@
  222. @argA4 = Bo ^((~Bu)& Ba )@
  223. @argA5 = Bu ^((~Ba)& Be )@
  224. veor.64 \argA2, \argA2, d8
  225. veor.64 \argA3, \argA3, d9
  226. vshl.u64 d2, \argA2, #10
  227. vldr.64 d6, [sp, #\argA1]
  228. vshl.u64 d3, \argA3, #15
  229. veor.64 \argA4, \argA4, d10
  230. vsri.64 d2, \argA2, #64-10
  231. vsri.64 d3, \argA3, #64-15
  232. veor.64 \argA5, \argA5, d11
  233. vext.8 d4, \argA4, \argA4, #1
  234. vbic.64 \argA2, d3, d2
  235. vshl.u64 d0, \argA5, #27
  236. veor.64 d6, d6, d7
  237. vbic.64 \argA3, d4, d3
  238. vsri.64 d0, \argA5, #64-27
  239. vshl.u64 d1, d6, #36
  240. veor.64 \argA3, d2
  241. vbic.64 \argA4, d0, d4
  242. vsri.64 d1, d6, #64-36
  243. veor.64 \argA4, d3
  244. vbic.64 d6, d2, d1
  245. vbic.64 \argA5, d1, d0
  246. veor.64 d6, d0
  247. veor.64 \argA2, d1
  248. vstr.64 d6, [sp, #\argA1]
  249. veor.64 d5, d6
  250. veor.64 \argA5, d4
  251. .endm
  252. .macro KeccakThetaRhoPiChi4 argA1, argA2, argA3, argA4, argA5
  253. @d3 = ROL64((argA1^Da), 41)@
  254. @d4 = ROL64((argA2^De), 2)@
  255. @d0 = ROL64((argA3^Di), 62)@
  256. @d1 = ROL64((argA4^Do), 55)@
  257. @d2 = ROL64((argA5^Du), 39)@
  258. @argA1 = Ba ^((~Be)& Bi )@ Ca ^= argA1@
  259. @argA2 = Be ^((~Bi)& Bo )@
  260. @argA3 = Bi ^((~Bo)& Bu )@
  261. @argA4 = Bo ^((~Bu)& Ba )@
  262. @argA5 = Bu ^((~Ba)& Be )@
  263. veor.64 \argA2, \argA2, d8
  264. veor.64 \argA3, \argA3, d9
  265. vshl.u64 d4, \argA2, #2
  266. veor.64 \argA5, \argA5, d11
  267. vshl.u64 d0, \argA3, #62
  268. vldr.64 d6, [sp, #\argA1]
  269. vsri.64 d4, \argA2, #64-2
  270. veor.64 \argA4, \argA4, d10
  271. vsri.64 d0, \argA3, #64-62
  272. vshl.u64 d1, \argA4, #55
  273. veor.64 d6, d6, d7
  274. vshl.u64 d2, \argA5, #39
  275. vsri.64 d1, \argA4, #64-55
  276. vbic.64 \argA4, d0, d4
  277. vsri.64 d2, \argA5, #64-39
  278. vbic.64 \argA2, d1, d0
  279. vshl.u64 d3, d6, #41
  280. veor.64 \argA5, d4, \argA2
  281. vbic.64 \argA2, d2, d1
  282. vsri.64 d3, d6, #64-41
  283. veor.64 d6, d0, \argA2
  284. vbic.64 \argA2, d3, d2
  285. vbic.64 \argA3, d4, d3
  286. veor.64 \argA2, d1
  287. vstr.64 d6, [sp, #\argA1]
  288. veor.64 d5, d6
  289. veor.64 \argA3, d2
  290. veor.64 \argA4, d3
  291. .endm
  292. @// --- code
  293. @not callable from C!
  294. .p2align 3
  295. .type KeccakF_armv7a_neon_asm,%function;
  296. KeccakF_armv7a_neon_asm: @
  297. .LroundLoop:
  298. KeccakThetaRhoPiChiIota Aba, d13, d19, d25, d31
  299. KeccakThetaRhoPiChi1 Aka, d15, d21, d22, d28
  300. KeccakThetaRhoPiChi2 Asa, d12, d18, d24, d30
  301. KeccakThetaRhoPiChi3 Aga, d14, d20, d26, d27
  302. KeccakThetaRhoPiChi4 Ama, d16, d17, d23, d29
  303. KeccakThetaRhoPiChiIota Aba, d15, d18, d26, d29
  304. KeccakThetaRhoPiChi1 Asa, d14, d17, d25, d28
  305. KeccakThetaRhoPiChi2 Ama, d13, d21, d24, d27
  306. KeccakThetaRhoPiChi3 Aka, d12, d20, d23, d31
  307. KeccakThetaRhoPiChi4 Aga, d16, d19, d22, d30
  308. KeccakThetaRhoPiChiIota Aba, d14, d21, d23, d30
  309. KeccakThetaRhoPiChi1 Ama, d12, d19, d26, d28
  310. KeccakThetaRhoPiChi2 Aga, d15, d17, d24, d31
  311. KeccakThetaRhoPiChi3 Asa, d13, d20, d22, d29
  312. KeccakThetaRhoPiChi4 Aka, d16, d18, d25, d27
  313. KeccakThetaRhoPiChiIota Aba, d12, d17, d22, d27
  314. KeccakThetaRhoPiChi1 Aga, d13, d18, d23, d28
  315. KeccakThetaRhoPiChi2 Aka, d14, d19, d24, d29
  316. ldr r0, [ip]
  317. KeccakThetaRhoPiChi3 Ama, d15, d20, d25, d30
  318. cmp r0, #0xFFFFFFFF
  319. KeccakThetaRhoPiChi4 Asa, d16, d21, d26, d31
  320. bne .LroundLoop
  321. sub ip, #(8*24)
  322. bx lr
  323. .p2align 2
  324. .ltorg
  325. .size KeccakF_armv7a_neon_asm,.-KeccakF_armv7a_neon_asm;
  326. @//unsigned _gcry_keccak_permute_armv7_neon(u64 *state) callable from C
  327. .p2align 3
  328. .global _gcry_keccak_permute_armv7_neon
  329. .type _gcry_keccak_permute_armv7_neon,%function;
  330. _gcry_keccak_permute_armv7_neon:
  331. push {ip, lr}
  332. vpush {q4-q7}
  333. sub sp,sp, #5*8
  334. vldr.64 d0, [r0, #0*8]
  335. vldr.64 d12, [r0, #1*8]
  336. vldr.64 d17, [r0, #2*8]
  337. vldr.64 d22, [r0, #3*8]
  338. vldr.64 d27, [r0, #4*8]
  339. GET_DATA_POINTER(ip, _gcry_keccak_round_consts_64bit, lr);
  340. vldr.64 d1, [r0, #5*8]
  341. vldr.64 d13, [r0, #6*8]
  342. vldr.64 d18, [r0, #7*8]
  343. vldr.64 d23, [r0, #8*8]
  344. vldr.64 d28, [r0, #9*8]
  345. vldr.64 d2, [r0, #10*8]
  346. vldr.64 d14, [r0, #11*8]
  347. vldr.64 d19, [r0, #12*8]
  348. vldr.64 d24, [r0, #13*8]
  349. vldr.64 d29, [r0, #14*8]
  350. vldr.64 d3, [r0, #15*8]
  351. vldr.64 d15, [r0, #16*8]
  352. vldr.64 d20, [r0, #17*8]
  353. vldr.64 d25, [r0, #18*8]
  354. vldr.64 d30, [r0, #19*8]
  355. vldr.64 d4, [r0, #20*8]
  356. vldr.64 d16, [r0, #21*8]
  357. vldr.64 d21, [r0, #22*8]
  358. vldr.64 d26, [r0, #23*8]
  359. vldr.64 d31, [r0, #24*8]
  360. vstr.64 d0, [sp, #Aba]
  361. vstr.64 d1, [sp, #Aga]
  362. veor.64 q0, q0, q1
  363. vstr.64 d2, [sp, #Aka]
  364. veor.64 d5, d0, d1
  365. vstr.64 d3, [sp, #Ama]
  366. mov r1, r0
  367. vstr.64 d4, [sp, #Asa]
  368. veor.64 d5, d5, d4
  369. bl KeccakF_armv7a_neon_asm
  370. vpop.64 { d0- d4 }
  371. vstr.64 d0, [r1, #0*8]
  372. vstr.64 d12, [r1, #1*8]
  373. vstr.64 d17, [r1, #2*8]
  374. vstr.64 d22, [r1, #3*8]
  375. vstr.64 d27, [r1, #4*8]
  376. vstr.64 d1, [r1, #5*8]
  377. vstr.64 d13, [r1, #6*8]
  378. vstr.64 d18, [r1, #7*8]
  379. vstr.64 d23, [r1, #8*8]
  380. vstr.64 d28, [r1, #9*8]
  381. vstr.64 d2, [r1, #10*8]
  382. vstr.64 d14, [r1, #11*8]
  383. vstr.64 d19, [r1, #12*8]
  384. vstr.64 d24, [r1, #13*8]
  385. vstr.64 d29, [r1, #14*8]
  386. vstr.64 d3, [r1, #15*8]
  387. vstr.64 d15, [r1, #16*8]
  388. vstr.64 d20, [r1, #17*8]
  389. vstr.64 d25, [r1, #18*8]
  390. vstr.64 d30, [r1, #19*8]
  391. vstr.64 d4, [r1, #20*8]
  392. vstr.64 d16, [r1, #21*8]
  393. vstr.64 d21, [r1, #22*8]
  394. vstr.64 d26, [r1, #23*8]
  395. vstr.64 d31, [r1, #24*8]
  396. mov r0, #112
  397. vpop {q4-q7}
  398. pop {ip, pc}
  399. .p2align 2
  400. .ltorg
  401. .size _gcry_keccak_permute_armv7_neon,.-_gcry_keccak_permute_armv7_neon;
  402. @//unsigned _gcry_keccak_absorb_lanes64_armv7_neon(u64 *state, @r4
  403. @ int pos, @r1
  404. @ const byte *lanes, @r2
  405. @ size_t nlanes, @r3
  406. @ int blocklanes) @ r5 callable from C
  407. .p2align 3
  408. .global _gcry_keccak_absorb_lanes64_armv7_neon
  409. .type _gcry_keccak_absorb_lanes64_armv7_neon,%function;
  410. _gcry_keccak_absorb_lanes64_armv7_neon:
  411. cmp r3, #0 @ nlanes == 0
  412. itt eq
  413. moveq r0, #0
  414. bxeq lr
  415. push {r4-r5, ip, lr}
  416. beq .Lout
  417. mov r4, r0
  418. ldr r5, [sp, #(4*4)]
  419. vpush {q4-q7}
  420. @ load state
  421. vldr.64 d0, [r4, #0*8]
  422. vldr.64 d12, [r4, #1*8]
  423. vldr.64 d17, [r4, #2*8]
  424. vldr.64 d22, [r4, #3*8]
  425. vldr.64 d27, [r4, #4*8]
  426. GET_DATA_POINTER(ip, _gcry_keccak_round_consts_64bit, lr);
  427. vldr.64 d1, [r4, #5*8]
  428. vldr.64 d13, [r4, #6*8]
  429. vldr.64 d18, [r4, #7*8]
  430. vldr.64 d23, [r4, #8*8]
  431. vldr.64 d28, [r4, #9*8]
  432. vldr.64 d2, [r4, #10*8]
  433. vldr.64 d14, [r4, #11*8]
  434. vldr.64 d19, [r4, #12*8]
  435. vldr.64 d24, [r4, #13*8]
  436. vldr.64 d29, [r4, #14*8]
  437. vldr.64 d3, [r4, #15*8]
  438. vldr.64 d15, [r4, #16*8]
  439. vldr.64 d20, [r4, #17*8]
  440. vldr.64 d25, [r4, #18*8]
  441. vldr.64 d30, [r4, #19*8]
  442. vldr.64 d4, [r4, #20*8]
  443. vldr.64 d16, [r4, #21*8]
  444. vldr.64 d21, [r4, #22*8]
  445. vldr.64 d26, [r4, #23*8]
  446. vldr.64 d31, [r4, #24*8]
  447. .Lmain_loop:
  448. @ detect absorb mode (full blocks vs lanes)
  449. cmp r1, #0 @ pos != 0
  450. bne .Llanes_loop
  451. .Lmain_loop_pos0:
  452. @ full blocks mode
  453. @ switch (blocksize)
  454. cmp r5, #21
  455. beq .Lfull_block_21
  456. cmp r5, #18
  457. beq .Lfull_block_18
  458. cmp r5, #17
  459. beq .Lfull_block_17
  460. cmp r5, #13
  461. beq .Lfull_block_13
  462. cmp r5, #9
  463. beq .Lfull_block_9
  464. @ unknown blocksize
  465. b .Llanes_loop
  466. .Lfull_block_21:
  467. @ SHAKE128
  468. cmp r3, #21 @ nlanes < blocklanes
  469. blo .Llanes_loop
  470. sub sp,sp, #5*8
  471. vld1.64 {d5-d8}, [r2]!
  472. veor d0, d5
  473. vld1.64 {d9-d11}, [r2]!
  474. veor d12, d6
  475. veor d17, d7
  476. veor d22, d8
  477. vld1.64 {d5-d8}, [r2]!
  478. veor d27, d9
  479. veor d1, d10
  480. veor d13, d11
  481. vld1.64 {d9-d11}, [r2]!
  482. veor d18, d5
  483. veor d23, d6
  484. veor d28, d7
  485. veor d2, d8
  486. vld1.64 {d5-d8}, [r2]!
  487. veor d14, d9
  488. veor d19, d10
  489. veor d24, d11
  490. vld1.64 {d9-d11}, [r2]!
  491. veor d29, d5
  492. veor d3, d6
  493. veor d15, d7
  494. veor d20, d8
  495. veor d25, d9
  496. veor d30, d10
  497. veor d4, d11
  498. vstr.64 d0, [sp, #Aba]
  499. vstr.64 d1, [sp, #Aga]
  500. veor.64 q0, q0, q1
  501. vstr.64 d2, [sp, #Aka]
  502. veor.64 d5, d0, d1
  503. vstr.64 d3, [sp, #Ama]
  504. vstr.64 d4, [sp, #Asa]
  505. veor.64 d5, d5, d4
  506. bl KeccakF_armv7a_neon_asm
  507. subs r3, #21 @ nlanes -= 21
  508. vpop.64 { d0-d4 }
  509. beq .Ldone
  510. b .Lfull_block_21
  511. .Lfull_block_18:
  512. @ SHA3-224
  513. cmp r3, #18 @ nlanes < blocklanes
  514. blo .Llanes_loop
  515. sub sp,sp, #5*8
  516. vld1.64 {d5-d8}, [r2]!
  517. veor d0, d5
  518. vld1.64 {d9-d11}, [r2]!
  519. veor d12, d6
  520. veor d17, d7
  521. veor d22, d8
  522. vld1.64 {d5-d8}, [r2]!
  523. veor d27, d9
  524. veor d1, d10
  525. veor d13, d11
  526. vld1.64 {d9-d11}, [r2]!
  527. veor d18, d5
  528. veor d23, d6
  529. veor d28, d7
  530. veor d2, d8
  531. vld1.64 {d5-d8}, [r2]!
  532. veor d14, d9
  533. veor d19, d10
  534. veor d24, d11
  535. veor d29, d5
  536. veor d3, d6
  537. veor d15, d7
  538. veor d20, d8
  539. vstr.64 d0, [sp, #Aba]
  540. vstr.64 d1, [sp, #Aga]
  541. veor.64 q0, q0, q1
  542. vstr.64 d2, [sp, #Aka]
  543. veor.64 d5, d0, d1
  544. vstr.64 d3, [sp, #Ama]
  545. vstr.64 d4, [sp, #Asa]
  546. veor.64 d5, d5, d4
  547. bl KeccakF_armv7a_neon_asm
  548. subs r3, #18 @ nlanes -= 18
  549. vpop.64 { d0-d4 }
  550. beq .Ldone
  551. b .Lfull_block_18
  552. .Lfull_block_17:
  553. @ SHA3-256 & SHAKE256
  554. cmp r3, #17 @ nlanes < blocklanes
  555. blo .Llanes_loop
  556. sub sp,sp, #5*8
  557. vld1.64 {d5-d8}, [r2]!
  558. veor d0, d5
  559. vld1.64 {d9-d11}, [r2]!
  560. veor d12, d6
  561. veor d17, d7
  562. veor d22, d8
  563. vld1.64 {d5-d8}, [r2]!
  564. veor d27, d9
  565. veor d1, d10
  566. veor d13, d11
  567. vld1.64 {d9-d11}, [r2]!
  568. veor d18, d5
  569. veor d23, d6
  570. veor d28, d7
  571. veor d2, d8
  572. vld1.64 {d5-d7}, [r2]!
  573. veor d14, d9
  574. veor d19, d10
  575. veor d24, d11
  576. veor d29, d5
  577. veor d3, d6
  578. veor d15, d7
  579. vstr.64 d0, [sp, #Aba]
  580. vstr.64 d1, [sp, #Aga]
  581. veor.64 q0, q0, q1
  582. vstr.64 d2, [sp, #Aka]
  583. veor.64 d5, d0, d1
  584. vstr.64 d3, [sp, #Ama]
  585. vstr.64 d4, [sp, #Asa]
  586. veor.64 d5, d5, d4
  587. bl KeccakF_armv7a_neon_asm
  588. subs r3, #17 @ nlanes -= 17
  589. vpop.64 { d0-d4 }
  590. beq .Ldone
  591. b .Lfull_block_17
  592. .Lfull_block_13:
  593. @ SHA3-384
  594. cmp r3, #13 @ nlanes < blocklanes
  595. blo .Llanes_loop
  596. sub sp,sp, #5*8
  597. vld1.64 {d5-d8}, [r2]!
  598. veor d0, d5
  599. vld1.64 {d9-d11}, [r2]!
  600. veor d12, d6
  601. veor d17, d7
  602. veor d22, d8
  603. vld1.64 {d5-d8}, [r2]!
  604. veor d27, d9
  605. veor d1, d10
  606. veor d13, d11
  607. vld1.64 {d9-d10}, [r2]!
  608. veor d18, d5
  609. veor d23, d6
  610. veor d28, d7
  611. veor d2, d8
  612. veor d14, d9
  613. veor d19, d10
  614. vstr.64 d0, [sp, #Aba]
  615. vstr.64 d1, [sp, #Aga]
  616. veor.64 q0, q0, q1
  617. vstr.64 d2, [sp, #Aka]
  618. veor.64 d5, d0, d1
  619. vstr.64 d3, [sp, #Ama]
  620. vstr.64 d4, [sp, #Asa]
  621. veor.64 d5, d5, d4
  622. bl KeccakF_armv7a_neon_asm
  623. subs r3, #13 @ nlanes -= 13
  624. vpop.64 { d0-d4 }
  625. beq .Ldone
  626. b .Lfull_block_13
  627. .Lfull_block_9:
  628. @ SHA3-512
  629. cmp r3, #9 @ nlanes < blocklanes
  630. blo .Llanes_loop
  631. sub sp,sp, #5*8
  632. vld1.64 {d5-d8}, [r2]!
  633. veor d0, d5
  634. vld1.64 {d9-d11}, [r2]!
  635. veor d12, d6
  636. veor d17, d7
  637. veor d22, d8
  638. vld1.64 {d5-d6}, [r2]!
  639. veor d27, d9
  640. veor d1, d10
  641. veor d13, d11
  642. veor d18, d5
  643. veor d23, d6
  644. vstr.64 d0, [sp, #Aba]
  645. vstr.64 d1, [sp, #Aga]
  646. veor.64 q0, q0, q1
  647. vstr.64 d2, [sp, #Aka]
  648. veor.64 d5, d0, d1
  649. vstr.64 d3, [sp, #Ama]
  650. vstr.64 d4, [sp, #Asa]
  651. veor.64 d5, d5, d4
  652. bl KeccakF_armv7a_neon_asm
  653. subs r3, #9 @ nlanes -= 9
  654. vpop.64 { d0-d4 }
  655. beq .Ldone
  656. b .Lfull_block_9
  657. .Llanes_loop:
  658. @ per-lane mode
  659. @ switch (pos)
  660. ldrb r0, [pc, r1]
  661. add pc, pc, r0, lsl #2
  662. .Lswitch_table:
  663. .byte (.Llane0-.Lswitch_table-4)/4
  664. .byte (.Llane1-.Lswitch_table-4)/4
  665. .byte (.Llane2-.Lswitch_table-4)/4
  666. .byte (.Llane3-.Lswitch_table-4)/4
  667. .byte (.Llane4-.Lswitch_table-4)/4
  668. .byte (.Llane5-.Lswitch_table-4)/4
  669. .byte (.Llane6-.Lswitch_table-4)/4
  670. .byte (.Llane7-.Lswitch_table-4)/4
  671. .byte (.Llane8-.Lswitch_table-4)/4
  672. .byte (.Llane9-.Lswitch_table-4)/4
  673. .byte (.Llane10-.Lswitch_table-4)/4
  674. .byte (.Llane11-.Lswitch_table-4)/4
  675. .byte (.Llane12-.Lswitch_table-4)/4
  676. .byte (.Llane13-.Lswitch_table-4)/4
  677. .byte (.Llane14-.Lswitch_table-4)/4
  678. .byte (.Llane15-.Lswitch_table-4)/4
  679. .byte (.Llane16-.Lswitch_table-4)/4
  680. .byte (.Llane17-.Lswitch_table-4)/4
  681. .byte (.Llane18-.Lswitch_table-4)/4
  682. .byte (.Llane19-.Lswitch_table-4)/4
  683. .byte (.Llane20-.Lswitch_table-4)/4
  684. .byte (.Llane21-.Lswitch_table-4)/4
  685. .byte (.Llane22-.Lswitch_table-4)/4
  686. .byte (.Llane23-.Lswitch_table-4)/4
  687. .byte (.Llane24-.Lswitch_table-4)/4
  688. .p2align 2
  689. #define ABSORB_LANE(label, vreg) \
  690. label: \
  691. add r1, #1; \
  692. vld1.64 d5, [r2]!; \
  693. cmp r1, r5; /* pos == blocklanes */ \
  694. veor vreg, vreg, d5; \
  695. beq .Llanes_permute; \
  696. subs r3, #1; \
  697. beq .Ldone;
  698. ABSORB_LANE(.Llane0, d0)
  699. ABSORB_LANE(.Llane1, d12)
  700. ABSORB_LANE(.Llane2, d17)
  701. ABSORB_LANE(.Llane3, d22)
  702. ABSORB_LANE(.Llane4, d27)
  703. ABSORB_LANE(.Llane5, d1)
  704. ABSORB_LANE(.Llane6, d13)
  705. ABSORB_LANE(.Llane7, d18)
  706. ABSORB_LANE(.Llane8, d23)
  707. ABSORB_LANE(.Llane9, d28)
  708. ABSORB_LANE(.Llane10, d2)
  709. ABSORB_LANE(.Llane11, d14)
  710. ABSORB_LANE(.Llane12, d19)
  711. ABSORB_LANE(.Llane13, d24)
  712. ABSORB_LANE(.Llane14, d29)
  713. ABSORB_LANE(.Llane15, d3)
  714. ABSORB_LANE(.Llane16, d15)
  715. ABSORB_LANE(.Llane17, d20)
  716. ABSORB_LANE(.Llane18, d25)
  717. ABSORB_LANE(.Llane19, d30)
  718. ABSORB_LANE(.Llane20, d4)
  719. ABSORB_LANE(.Llane21, d16)
  720. ABSORB_LANE(.Llane22, d21)
  721. ABSORB_LANE(.Llane23, d26)
  722. ABSORB_LANE(.Llane24, d31)
  723. b .Llanes_loop
  724. .Llanes_permute:
  725. sub sp,sp, #5*8
  726. vstr.64 d0, [sp, #Aba]
  727. vstr.64 d1, [sp, #Aga]
  728. veor.64 q0, q0, q1
  729. vstr.64 d2, [sp, #Aka]
  730. veor.64 d5, d0, d1
  731. vstr.64 d3, [sp, #Ama]
  732. vstr.64 d4, [sp, #Asa]
  733. veor.64 d5, d5, d4
  734. bl KeccakF_armv7a_neon_asm
  735. mov r1, #0 @ pos <= 0
  736. subs r3, #1
  737. vpop.64 { d0-d4 }
  738. beq .Ldone
  739. b .Lmain_loop_pos0
  740. .Ldone:
  741. @ save state
  742. vstr.64 d0, [r4, #0*8]
  743. vstr.64 d12, [r4, #1*8]
  744. vstr.64 d17, [r4, #2*8]
  745. vstr.64 d22, [r4, #3*8]
  746. vstr.64 d27, [r4, #4*8]
  747. vstr.64 d1, [r4, #5*8]
  748. vstr.64 d13, [r4, #6*8]
  749. vstr.64 d18, [r4, #7*8]
  750. vstr.64 d23, [r4, #8*8]
  751. vstr.64 d28, [r4, #9*8]
  752. vstr.64 d2, [r4, #10*8]
  753. vstr.64 d14, [r4, #11*8]
  754. vstr.64 d19, [r4, #12*8]
  755. vstr.64 d24, [r4, #13*8]
  756. vstr.64 d29, [r4, #14*8]
  757. vstr.64 d3, [r4, #15*8]
  758. vstr.64 d15, [r4, #16*8]
  759. vstr.64 d20, [r4, #17*8]
  760. vstr.64 d25, [r4, #18*8]
  761. vstr.64 d30, [r4, #19*8]
  762. vstr.64 d4, [r4, #20*8]
  763. vstr.64 d16, [r4, #21*8]
  764. vstr.64 d21, [r4, #22*8]
  765. vstr.64 d26, [r4, #23*8]
  766. vstr.64 d31, [r4, #24*8]
  767. mov r0, #120
  768. vpop {q4-q7}
  769. .Lout:
  770. pop {r4-r5, ip, pc}
  771. .p2align 2
  772. .ltorg
  773. .size _gcry_keccak_absorb_lanes64_armv7_neon,.-_gcry_keccak_absorb_lanes64_armv7_neon;
  774. #endif