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