1#!/usr/bin/env perl 2# Copyright 2017-2020 The OpenSSL Project Authors. All Rights Reserved. 3# 4# Licensed under the Apache License 2.0 (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# [ABI- and endian-neutral] Keccak-1600 for C64x. 17# 18# June 2017. 19# 20# This is straightforward KECCAK_1X_ALT variant (see sha/keccak1600.c) 21# with bit interleaving. 64-bit values are simply split between A- and 22# B-files, with A-file holding least significant halves. This works 23# out perfectly, because all operations including cross-communications 24# [in rotate operations] are always complementary. Performance is 25# [incredible for a 32-bit processor] 10.9 cycles per processed byte 26# for r=1088, which corresponds to SHA3-256. This is >15x faster than 27# compiler-generated KECCAK_1X_ALT code, and >10x than other variants. 28# On average processor ends up issuing ~4.5 instructions per cycle... 29 30my @A = map([ $_, ($_+1), ($_+2), ($_+3), ($_+4) ], (5,10,16,21,26)); 31 $A[1][4] = 31; # B14 is reserved, A14 is used as iota[] 32 ($A[3][0],$A[4][1]) = ($A[4][1],$A[3][0]); 33my @C = (0..4,$A[3][0],$A[4][0]); 34my $iotas = "A14"; 35 36my @rhotates = ([ 0, 1, 62, 28, 27 ], 37 [ 36, 44, 6, 55, 20 ], 38 [ 3, 10, 43, 25, 39 ], 39 [ 41, 45, 15, 21, 8 ], 40 [ 18, 2, 61, 56, 14 ]); 41 42sub ROL64 { 43 my ($src,$rot,$dst,$p) = @_; 44 45 if ($rot&1) { 46$code.=<<___; 47$p ROTL B$src,$rot/2+1,A$dst 48|| ROTL A$src,$rot/2, B$dst 49___ 50 } else { 51$code.=<<___; 52$p ROTL A$src,$rot/2,A$dst 53|| ROTL B$src,$rot/2,B$dst 54___ 55 } 56} 57 58######################################################################## 59# Stack frame layout 60# 61# SP--->+------+------+ 62# | | | 63# +1--->+------+------+<- -9 below 4 slots are used by KeccakF1600_int 64# | | | 65# +2--->+------+------+<- -8 66# | | | 67# +3--->+------+------+<- -7 68# | A2 | A3 | A3:A2 are preserved by KeccakF1600_int 69# +4--->+------+------+<- -6 70# | B2 | B3 | B3:B2 are preserved by KeccakF1600_int 71# +5--->+------+------+<- -5 below is ABI-compliant layout 72# | A10 | A11 | 73# +6--->+------+------+<- -4 74# | A12 | A13 | 75# +7--->+------+------+<- -3 76# | A14 | B3 | 77# +8--->+------+------+<- -2 78# | B10 | B11 | 79# +9--->+------+------+<- -1 80# | B12 | B13 | 81# +------+------+<---FP 82# | A15 | 83# +------+-- 84 85$code.=<<___; 86 .text 87 88 .if .ASSEMBLER_VERSION<7000000 89 .asg 0,__TI_EABI__ 90 .endif 91 .if __TI_EABI__ 92 .nocmp 93 .asg KeccakF1600,_KeccakF1600 94 .asg SHA3_absorb,_SHA3_absorb 95 .asg SHA3_squeeze,_SHA3_squeeze 96 .endif 97 98 .asg B3,RA 99 .asg A15,FP 100 .asg B15,SP 101 102 .align 32 103_KeccakF1600_int: 104 .asmfunc 105 STDW A3:A2,*FP[-7] 106|| STDW B3:B2,*SP[4] 107_KeccakF1600_cheat: 108 .if __TI_EABI__ 109 ADDKPC _KeccakF1600_int,B0 110|| MVKL \$PCR_OFFSET(iotas,_KeccakF1600_int),$iotas 111 MVKH \$PCR_OFFSET(iotas,_KeccakF1600_int),$iotas 112 .else 113 ADDKPC _KeccakF1600_int,B0 114|| MVKL (iotas-_KeccakF1600_int),$iotas 115 MVKH (iotas-_KeccakF1600_int),$iotas 116 .endif 117 ADD B0,$iotas,$iotas 118loop?: 119 XOR A$A[0][2],A$A[1][2],A$C[2] ; Theta 120|| XOR B$A[0][2],B$A[1][2],B$C[2] 121|| XOR A$A[0][3],A$A[1][3],A$C[3] 122|| XOR B$A[0][3],B$A[1][3],B$C[3] 123|| XOR A$A[0][0],A$A[1][0],A$C[0] 124|| XOR B$A[0][0],B$A[1][0],B$C[0] 125 XOR A$A[2][2],A$C[2],A$C[2] 126|| XOR B$A[2][2],B$C[2],B$C[2] 127|| XOR A$A[2][3],A$C[3],A$C[3] 128|| XOR B$A[2][3],B$C[3],B$C[3] 129|| XOR A$A[2][0],A$C[0],A$C[0] 130|| XOR B$A[2][0],B$C[0],B$C[0] 131 XOR A$A[3][2],A$C[2],A$C[2] 132|| XOR B$A[3][2],B$C[2],B$C[2] 133|| XOR A$A[3][3],A$C[3],A$C[3] 134|| XOR B$A[3][3],B$C[3],B$C[3] 135|| XOR A$A[3][0],A$C[0],A$C[0] 136|| XOR B$A[3][0],B$C[0],B$C[0] 137 XOR A$A[4][2],A$C[2],A$C[2] 138|| XOR B$A[4][2],B$C[2],B$C[2] 139|| XOR A$A[4][3],A$C[3],A$C[3] 140|| XOR B$A[4][3],B$C[3],B$C[3] 141|| XOR A$A[4][0],A$C[0],A$C[0] 142|| XOR B$A[4][0],B$C[0],B$C[0] 143 XOR A$A[0][4],A$A[1][4],A$C[4] 144|| XOR B$A[0][4],B$A[1][4],B$C[4] 145|| XOR A$A[0][1],A$A[1][1],A$C[1] 146|| XOR B$A[0][1],B$A[1][1],B$C[1] 147|| STDW A$A[3][0]:A$A[4][0],*SP[1] ; offload some data 148 STDW B$A[3][0]:B$A[4][0],*SP[2] 149|| XOR A$A[2][4],A$C[4],A$C[4] 150|| XOR B$A[2][4],B$C[4],B$C[4] 151|| XOR A$A[2][1],A$C[1],A$C[1] 152|| XOR B$A[2][1],B$C[1],B$C[1] 153|| ROTL B$C[2],1,A$C[5] ; ROL64(C[2],1) 154|| ROTL A$C[2],0,B$C[5] 155 XOR A$A[3][4],A$C[4],A$C[4] 156|| XOR B$A[3][4],B$C[4],B$C[4] 157|| XOR A$A[3][1],A$C[1],A$C[1] 158|| XOR B$A[3][1],B$C[1],B$C[1] 159|| ROTL B$C[3],1,A$C[6] ; ROL64(C[3],1) 160|| ROTL A$C[3],0,B$C[6] 161 XOR A$A[4][4],A$C[4],A$C[4] 162|| XOR B$A[4][4],B$C[4],B$C[4] 163|| XOR A$A[4][1],A$C[1],A$C[1] 164|| XOR B$A[4][1],B$C[1],B$C[1] 165|| XOR A$C[0],A$C[5],A$C[5] ; C[0] ^ ROL64(C[2],1) 166|| XOR B$C[0],B$C[5],B$C[5] 167 XOR A$C[5],A$A[0][1],A$A[0][1] 168|| XOR B$C[5],B$A[0][1],B$A[0][1] 169|| XOR A$C[5],A$A[1][1],A$A[1][1] 170|| XOR B$C[5],B$A[1][1],B$A[1][1] 171|| XOR A$C[5],A$A[2][1],A$A[2][1] 172|| XOR B$C[5],B$A[2][1],B$A[2][1] 173 XOR A$C[5],A$A[3][1],A$A[3][1] 174|| XOR B$C[5],B$A[3][1],B$A[3][1] 175|| XOR A$C[5],A$A[4][1],A$A[4][1] 176|| XOR B$C[5],B$A[4][1],B$A[4][1] 177|| ROTL B$C[4],1,A$C[5] ; ROL64(C[4],1) 178|| ROTL A$C[4],0,B$C[5] 179|| XOR A$C[1],A$C[6],A$C[6] ; C[1] ^ ROL64(C[3],1) 180|| XOR B$C[1],B$C[6],B$C[6] 181 XOR A$C[6],A$A[0][2],A$A[0][2] 182|| XOR B$C[6],B$A[0][2],B$A[0][2] 183|| XOR A$C[6],A$A[1][2],A$A[1][2] 184|| XOR B$C[6],B$A[1][2],B$A[1][2] 185|| XOR A$C[6],A$A[2][2],A$A[2][2] 186|| XOR B$C[6],B$A[2][2],B$A[2][2] 187|| ROTL B$C[1],1,A$C[1] ; ROL64(C[1],1) 188|| ROTL A$C[1],0,B$C[1] 189 XOR A$C[6],A$A[3][2],A$A[3][2] 190|| XOR B$C[6],B$A[3][2],B$A[3][2] 191|| XOR A$C[6],A$A[4][2],A$A[4][2] 192|| XOR B$C[6],B$A[4][2],B$A[4][2] 193|| ROTL B$C[0],1,A$C[6] ; ROL64(C[0],1) 194|| ROTL A$C[0],0,B$C[6] 195|| XOR A$C[5],A$C[2],A$C[2] ; C[2] ^= ROL64(C[4],1) 196|| XOR B$C[5],B$C[2],B$C[2] 197 XOR A$C[2],A$A[0][3],A$A[0][3] 198|| XOR B$C[2],B$A[0][3],B$A[0][3] 199|| XOR A$C[2],A$A[1][3],A$A[1][3] 200|| XOR B$C[2],B$A[1][3],B$A[1][3] 201|| XOR A$C[2],A$A[2][3],A$A[2][3] 202|| XOR B$C[2],B$A[2][3],B$A[2][3] 203 XOR A$C[6],A$C[3],A$C[3] ; C[3] ^= ROL64(C[0],1) 204|| XOR B$C[6],B$C[3],B$C[3] 205|| LDDW *FP[-9],A$A[3][0]:A$A[4][0] ; restore offloaded data 206|| LDDW *SP[2],B$A[3][0]:B$A[4][0] 207|| XOR A$C[2],A$A[3][3],A$A[3][3] 208|| XOR B$C[2],B$A[3][3],B$A[3][3] 209 XOR A$C[2],A$A[4][3],A$A[4][3] 210|| XOR B$C[2],B$A[4][3],B$A[4][3] 211|| XOR A$C[3],A$A[0][4],A$A[0][4] 212|| XOR B$C[3],B$A[0][4],B$A[0][4] 213|| XOR A$C[3],A$A[1][4],A$A[1][4] 214|| XOR B$C[3],B$A[1][4],B$A[1][4] 215 XOR A$C[3],A$A[2][4],A$A[2][4] 216|| XOR B$C[3],B$A[2][4],B$A[2][4] 217|| XOR A$C[3],A$A[3][4],A$A[3][4] 218|| XOR B$C[3],B$A[3][4],B$A[3][4] 219|| XOR A$C[3],A$A[4][4],A$A[4][4] 220|| XOR B$C[3],B$A[4][4],B$A[4][4] 221 XOR A$C[1],A$C[4],A$C[4] ; C[4] ^= ROL64(C[1],1) 222|| XOR B$C[1],B$C[4],B$C[4] 223|| MV A$A[0][1],A$C[1] ; Rho+Pi, "early start" 224|| MV B$A[0][1],B$C[1] 225___ 226 &ROL64 ($A[1][1],$rhotates[1][1],$A[0][1],"||"); 227$code.=<<___; 228 XOR A$C[4],A$A[0][0],A$A[0][0] 229|| XOR B$C[4],B$A[0][0],B$A[0][0] 230|| XOR A$C[4],A$A[1][0],A$A[1][0] 231|| XOR B$C[4],B$A[1][0],B$A[1][0] 232|| MV A$A[0][3],A$C[3] 233|| MV B$A[0][3],B$C[3] 234___ 235 &ROL64 ($A[3][3],$rhotates[3][3],$A[0][3],"||"); 236$code.=<<___; 237 XOR A$C[4],A$A[2][0],A$A[2][0] 238|| XOR B$C[4],B$A[2][0],B$A[2][0] 239|| XOR A$C[4],A$A[3][0],A$A[3][0] 240|| XOR B$C[4],B$A[3][0],B$A[3][0] 241|| MV A$A[0][2],A$C[2] 242|| MV B$A[0][2],B$C[2] 243___ 244 &ROL64 ($A[2][2],$rhotates[2][2],$A[0][2],"||"); 245$code.=<<___; 246 XOR A$C[4],A$A[4][0],A$A[4][0] 247|| XOR B$C[4],B$A[4][0],B$A[4][0] 248|| MV A$A[0][4],A$C[4] 249|| MV B$A[0][4],B$C[4] 250___ 251 &ROL64 ($A[4][4],$rhotates[4][4],$A[0][4],"||"); 252 253 &ROL64 ($A[1][4],$rhotates[1][4],$A[1][1]); 254$code.=<<___; 255|| LDW *${iotas}++[2],A$C[0] 256___ 257 &ROL64 ($A[2][3],$rhotates[2][3],$A[2][2]); 258$code.=<<___; 259|| LDW *${iotas}[-1],B$C[0] 260___ 261 &ROL64 ($A[3][2],$rhotates[3][2],$A[3][3]); 262 &ROL64 ($A[4][1],$rhotates[4][1],$A[4][4]); 263 264 &ROL64 ($A[4][2],$rhotates[4][2],$A[1][4]); 265 &ROL64 ($A[3][4],$rhotates[3][4],$A[2][3]); 266 &ROL64 ($A[2][1],$rhotates[2][1],$A[3][2]); 267 &ROL64 ($A[1][3],$rhotates[1][3],$A[4][1]); 268 269 &ROL64 ($A[2][4],$rhotates[2][4],$A[4][2]); 270 &ROL64 ($A[4][3],$rhotates[4][3],$A[3][4]); 271 &ROL64 ($A[1][2],$rhotates[1][2],$A[2][1]); 272 &ROL64 ($A[3][1],$rhotates[3][1],$A[1][3]); 273 274 &ROL64 ($A[4][0],$rhotates[4][0],$A[2][4]); 275 &ROL64 ($A[3][0],$rhotates[3][0],$A[4][3]); 276 &ROL64 ($A[2][0],$rhotates[2][0],$A[1][2]); 277 &ROL64 ($A[1][0],$rhotates[1][0],$A[3][1]); 278 279 #&ROL64 ($C[3], $rhotates[0][3],$A[1][0]); # moved below 280 &ROL64 ($C[1], $rhotates[0][1],$A[2][0]); 281 &ROL64 ($C[4], $rhotates[0][4],$A[3][0]); 282 &ROL64 ($C[2], $rhotates[0][2],$A[4][0]); 283$code.=<<___; 284|| ANDN A$A[0][2],A$A[0][1],A$C[4] ; Chi+Iota 285|| ANDN B$A[0][2],B$A[0][1],B$C[4] 286|| ANDN A$A[0][3],A$A[0][2],A$C[1] 287|| ANDN B$A[0][3],B$A[0][2],B$C[1] 288|| ANDN A$A[0][4],A$A[0][3],A$C[2] 289|| ANDN B$A[0][4],B$A[0][3],B$C[2] 290___ 291 &ROL64 ($C[3], $rhotates[0][3],$A[1][0]); 292$code.=<<___; 293|| ANDN A$A[0][0],A$A[0][4],A$C[3] 294|| ANDN B$A[0][0],B$A[0][4],B$C[3] 295|| XOR A$C[4],A$A[0][0],A$A[0][0] 296|| XOR B$C[4],B$A[0][0],B$A[0][0] 297|| ANDN A$A[0][1],A$A[0][0],A$C[4] 298|| ANDN B$A[0][1],B$A[0][0],B$C[4] 299 XOR A$C[1],A$A[0][1],A$A[0][1] 300|| XOR B$C[1],B$A[0][1],B$A[0][1] 301|| XOR A$C[2],A$A[0][2],A$A[0][2] 302|| XOR B$C[2],B$A[0][2],B$A[0][2] 303|| XOR A$C[3],A$A[0][3],A$A[0][3] 304|| XOR B$C[3],B$A[0][3],B$A[0][3] 305 XOR A$C[4],A$A[0][4],A$A[0][4] 306|| XOR B$C[4],B$A[0][4],B$A[0][4] 307|| XOR A$C[0],A$A[0][0],A$A[0][0] ; A[0][0] ^= iotas[i++]; 308|| XOR B$C[0],B$A[0][0],B$A[0][0] 309|| EXTU $iotas,24,24,A0 ; A0 is A$C[0], as we done? 310 311 ANDN A$A[1][2],A$A[1][1],A$C[4] 312|| ANDN B$A[1][2],B$A[1][1],B$C[4] 313|| ANDN A$A[1][3],A$A[1][2],A$C[1] 314|| ANDN B$A[1][3],B$A[1][2],B$C[1] 315|| ANDN A$A[1][4],A$A[1][3],A$C[2] 316|| ANDN B$A[1][4],B$A[1][3],B$C[2] 317 ANDN A$A[1][0],A$A[1][4],A$C[3] 318|| ANDN B$A[1][0],B$A[1][4],B$C[3] 319|| XOR A$C[4],A$A[1][0],A$A[1][0] 320|| XOR B$C[4],B$A[1][0],B$A[1][0] 321|| ANDN A$A[1][1],A$A[1][0],A$C[4] 322|| ANDN B$A[1][1],B$A[1][0],B$C[4] 323 XOR A$C[1],A$A[1][1],A$A[1][1] 324|| XOR B$C[1],B$A[1][1],B$A[1][1] 325|| XOR A$C[2],A$A[1][2],A$A[1][2] 326|| XOR B$C[2],B$A[1][2],B$A[1][2] 327|| XOR A$C[3],A$A[1][3],A$A[1][3] 328|| XOR B$C[3],B$A[1][3],B$A[1][3] 329 XOR A$C[4],A$A[1][4],A$A[1][4] 330|| XOR B$C[4],B$A[1][4],B$A[1][4] 331 332|| ANDN A$A[2][2],A$A[2][1],A$C[4] 333|| ANDN B$A[2][2],B$A[2][1],B$C[4] 334|| ANDN A$A[2][3],A$A[2][2],A$C[1] 335|| ANDN B$A[2][3],B$A[2][2],B$C[1] 336 ANDN A$A[2][4],A$A[2][3],A$C[2] 337|| ANDN B$A[2][4],B$A[2][3],B$C[2] 338|| ANDN A$A[2][0],A$A[2][4],A$C[3] 339|| ANDN B$A[2][0],B$A[2][4],B$C[3] 340|| XOR A$C[4],A$A[2][0],A$A[2][0] 341|| XOR B$C[4],B$A[2][0],B$A[2][0] 342 ANDN A$A[2][1],A$A[2][0],A$C[4] 343|| ANDN B$A[2][1],B$A[2][0],B$C[4] 344|| XOR A$C[1],A$A[2][1],A$A[2][1] 345|| XOR B$C[1],B$A[2][1],B$A[2][1] 346|| XOR A$C[2],A$A[2][2],A$A[2][2] 347|| XOR B$C[2],B$A[2][2],B$A[2][2] 348 XOR A$C[3],A$A[2][3],A$A[2][3] 349|| XOR B$C[3],B$A[2][3],B$A[2][3] 350|| XOR A$C[4],A$A[2][4],A$A[2][4] 351|| XOR B$C[4],B$A[2][4],B$A[2][4] 352 353 ANDN A$A[3][2],A$A[3][1],A$C[4] 354|| ANDN B$A[3][2],B$A[3][1],B$C[4] 355|| ANDN A$A[3][3],A$A[3][2],A$C[1] 356|| ANDN B$A[3][3],B$A[3][2],B$C[1] 357|| ANDN A$A[3][4],A$A[3][3],A$C[2] 358|| ANDN B$A[3][4],B$A[3][3],B$C[2] 359 ANDN A$A[3][0],A$A[3][4],A$C[3] 360|| ANDN B$A[3][0],B$A[3][4],B$C[3] 361|| XOR A$C[4],A$A[3][0],A$A[3][0] 362|| XOR B$C[4],B$A[3][0],B$A[3][0] 363|| ANDN A$A[3][1],A$A[3][0],A$C[4] 364|| ANDN B$A[3][1],B$A[3][0],B$C[4] 365 XOR A$C[1],A$A[3][1],A$A[3][1] 366|| XOR B$C[1],B$A[3][1],B$A[3][1] 367|| XOR A$C[2],A$A[3][2],A$A[3][2] 368|| XOR B$C[2],B$A[3][2],B$A[3][2] 369|| XOR A$C[3],A$A[3][3],A$A[3][3] 370||[A0] BNOP loop? 371 XOR B$C[3],B$A[3][3],B$A[3][3] 372|| XOR A$C[4],A$A[3][4],A$A[3][4] 373|| XOR B$C[4],B$A[3][4],B$A[3][4] 374||[!A0] LDDW *FP[-7],A3:A2 375||[!A0] LDDW *SP[4], RA:B2 376 377 ANDN A$A[4][2],A$A[4][1],A$C[4] 378|| ANDN B$A[4][2],B$A[4][1],B$C[4] 379|| ANDN A$A[4][3],A$A[4][2],A$C[1] 380|| ANDN B$A[4][3],B$A[4][2],B$C[1] 381|| ANDN A$A[4][4],A$A[4][3],A$C[2] 382|| ANDN B$A[4][4],B$A[4][3],B$C[2] 383 ANDN A$A[4][0],A$A[4][4],A$C[3] 384|| ANDN B$A[4][0],B$A[4][4],B$C[3] 385|| XOR A$C[4],A$A[4][0],A$A[4][0] 386|| XOR B$C[4],B$A[4][0],B$A[4][0] 387|| ANDN A$A[4][1],A$A[4][0],A$C[4] 388|| ANDN B$A[4][1],B$A[4][0],B$C[4] 389 XOR A$C[1],A$A[4][1],A$A[4][1] 390|| XOR B$C[1],B$A[4][1],B$A[4][1] 391|| XOR A$C[2],A$A[4][2],A$A[4][2] 392|| XOR B$C[2],B$A[4][2],B$A[4][2] 393|| XOR A$C[3],A$A[4][3],A$A[4][3] 394|| XOR B$C[3],B$A[4][3],B$A[4][3] 395 XOR A$C[4],A$A[4][4],A$A[4][4] 396|| XOR B$C[4],B$A[4][4],B$A[4][4] 397;;===== branch to loop? is taken here 398 399 BNOP RA,5 400 .endasmfunc 401 402 .newblock 403 .global _KeccakF1600 404 .align 32 405_KeccakF1600: 406 .asmfunc stack_usage(80) 407 STW FP,*SP--(80) ; save frame pointer 408|| MV SP,FP 409 STDW B13:B12,*SP[9] 410|| STDW A13:A12,*FP[-4] 411 STDW B11:B10,*SP[8] 412|| STDW A11:A10,*FP[-5] 413 STW RA, *SP[15] 414|| STW A14,*FP[-6] 415|| MV A4,A2 416|| ADD 4,A4,B2 417 418 LDW *A2++[2],A$A[0][0] ; load A[5][5] 419|| LDW *B2++[2],B$A[0][0] 420 LDW *A2++[2],A$A[0][1] 421|| LDW *B2++[2],B$A[0][1] 422 LDW *A2++[2],A$A[0][2] 423|| LDW *B2++[2],B$A[0][2] 424 LDW *A2++[2],A$A[0][3] 425|| LDW *B2++[2],B$A[0][3] 426 LDW *A2++[2],A$A[0][4] 427|| LDW *B2++[2],B$A[0][4] 428 429 LDW *A2++[2],A$A[1][0] 430|| LDW *B2++[2],B$A[1][0] 431 LDW *A2++[2],A$A[1][1] 432|| LDW *B2++[2],B$A[1][1] 433 LDW *A2++[2],A$A[1][2] 434|| LDW *B2++[2],B$A[1][2] 435 LDW *A2++[2],A$A[1][3] 436|| LDW *B2++[2],B$A[1][3] 437 LDW *A2++[2],A$A[1][4] 438|| LDW *B2++[2],B$A[1][4] 439 440 LDW *A2++[2],A$A[2][0] 441|| LDW *B2++[2],B$A[2][0] 442 LDW *A2++[2],A$A[2][1] 443|| LDW *B2++[2],B$A[2][1] 444 LDW *A2++[2],A$A[2][2] 445|| LDW *B2++[2],B$A[2][2] 446 LDW *A2++[2],A$A[2][3] 447|| LDW *B2++[2],B$A[2][3] 448 LDW *A2++[2],A$A[2][4] 449|| LDW *B2++[2],B$A[2][4] 450 451 LDW *A2++[2],A$A[3][0] 452|| LDW *B2++[2],B$A[3][0] 453 LDW *A2++[2],A$A[3][1] 454|| LDW *B2++[2],B$A[3][1] 455 LDW *A2++[2],A$A[3][2] 456|| LDW *B2++[2],B$A[3][2] 457 LDW *A2++[2],A$A[3][3] 458|| LDW *B2++[2],B$A[3][3] 459 LDW *A2++[2],A$A[3][4] 460|| LDW *B2++[2],B$A[3][4] 461|| BNOP _KeccakF1600_int 462 463 ADDKPC ret?,RA 464|| LDW *A2++[2],A$A[4][0] 465|| LDW *B2++[2],B$A[4][0] 466 LDW *A2++[2],A$A[4][1] 467|| LDW *B2++[2],B$A[4][1] 468 LDW *A2++[2],A$A[4][2] 469|| LDW *B2++[2],B$A[4][2] 470 LDW *A2++[2],A$A[4][3] 471|| LDW *B2++[2],B$A[4][3] 472 LDW *A2,A$A[4][4] 473|| LDW *B2,B$A[4][4] 474|| ADDK -192,A2 ; rewind 475|| ADDK -192,B2 476 477 .align 16 478ret?: 479 STW A$A[0][0],*A2++[2] ; store A[5][5] 480|| STW B$A[0][0],*B2++[2] 481 STW A$A[0][1],*A2++[2] 482|| STW B$A[0][1],*B2++[2] 483 STW A$A[0][2],*A2++[2] 484|| STW B$A[0][2],*B2++[2] 485 STW A$A[0][3],*A2++[2] 486|| STW B$A[0][3],*B2++[2] 487 STW A$A[0][4],*A2++[2] 488|| STW B$A[0][4],*B2++[2] 489 490 STW A$A[1][0],*A2++[2] 491|| STW B$A[1][0],*B2++[2] 492 STW A$A[1][1],*A2++[2] 493|| STW B$A[1][1],*B2++[2] 494 STW A$A[1][2],*A2++[2] 495|| STW B$A[1][2],*B2++[2] 496 STW A$A[1][3],*A2++[2] 497|| STW B$A[1][3],*B2++[2] 498 STW A$A[1][4],*A2++[2] 499|| STW B$A[1][4],*B2++[2] 500 501 STW A$A[2][0],*A2++[2] 502|| STW B$A[2][0],*B2++[2] 503 STW A$A[2][1],*A2++[2] 504|| STW B$A[2][1],*B2++[2] 505 STW A$A[2][2],*A2++[2] 506|| STW B$A[2][2],*B2++[2] 507 STW A$A[2][3],*A2++[2] 508|| STW B$A[2][3],*B2++[2] 509 STW A$A[2][4],*A2++[2] 510|| STW B$A[2][4],*B2++[2] 511 512 STW A$A[3][0],*A2++[2] 513|| STW B$A[3][0],*B2++[2] 514 STW A$A[3][1],*A2++[2] 515|| STW B$A[3][1],*B2++[2] 516 STW A$A[3][2],*A2++[2] 517|| STW B$A[3][2],*B2++[2] 518 STW A$A[3][3],*A2++[2] 519|| STW B$A[3][3],*B2++[2] 520 STW A$A[3][4],*A2++[2] 521|| STW B$A[3][4],*B2++[2] 522 523 LDW *SP[15],RA 524|| LDW *FP[-6],A14 525 526 STW A$A[4][0],*A2++[2] 527|| STW B$A[4][0],*B2++[2] 528 STW A$A[4][1],*A2++[2] 529|| STW B$A[4][1],*B2++[2] 530 STW A$A[4][2],*A2++[2] 531|| STW B$A[4][2],*B2++[2] 532 STW A$A[4][3],*A2++[2] 533|| STW B$A[4][3],*B2++[2] 534 STW A$A[4][4],*A2 535|| STW B$A[4][4],*B2 536|| ADDK -192,A2 ; rewind 537 538 MV A2,A4 ; return original A4 539|| LDDW *SP[8], B11:B10 540|| LDDW *FP[-5],A11:A10 541 LDDW *SP[9], B13:B12 542|| LDDW *FP[-4],A13:A12 543|| BNOP RA 544 LDW *++SP(80),FP ; restore frame pointer 545 NOP 4 ; wait till FP is committed 546 .endasmfunc 547 548 .newblock 549 .asg B2,BSZ 550 .asg A2,INP 551 .asg A3,LEN 552 .global _SHA3_absorb 553 .align 32 554_SHA3_absorb: 555 .asmfunc stack_usage(80) 556 STW FP,*SP--(80) ; save frame pointer 557|| MV SP,FP 558 STDW B13:B12,*SP[9] 559|| STDW A13:A12,*FP[-4] 560 STDW B11:B10,*SP[8] 561|| STDW A11:A10,*FP[-5] 562 STW RA, *SP[15] 563|| STW A14,*FP[-6] 564 565 STW A4,*SP[1] ; save A[][] 566|| MV B4,INP ; reassign arguments 567|| MV A6,LEN 568|| MV B6,BSZ 569|| ADD 4,A4,B4 570 571 LDW *A4++[2],A$A[0][0] ; load A[5][5] 572|| LDW *B4++[2],B$A[0][0] 573 LDW *A4++[2],A$A[0][1] 574|| LDW *B4++[2],B$A[0][1] 575 LDW *A4++[2],A$A[0][2] 576|| LDW *B4++[2],B$A[0][2] 577 LDW *A4++[2],A$A[0][3] 578|| LDW *B4++[2],B$A[0][3] 579 LDW *A4++[2],A$A[0][4] 580|| LDW *B4++[2],B$A[0][4] 581 582 LDW *A4++[2],A$A[1][0] 583|| LDW *B4++[2],B$A[1][0] 584 LDW *A4++[2],A$A[1][1] 585|| LDW *B4++[2],B$A[1][1] 586 LDW *A4++[2],A$A[1][2] 587|| LDW *B4++[2],B$A[1][2] 588 LDW *A4++[2],A$A[1][3] 589|| LDW *B4++[2],B$A[1][3] 590 LDW *A4++[2],A$A[1][4] 591|| LDW *B4++[2],B$A[1][4] 592 593 LDW *A4++[2],A$A[2][0] 594|| LDW *B4++[2],B$A[2][0] 595 LDW *A4++[2],A$A[2][1] 596|| LDW *B4++[2],B$A[2][1] 597 LDW *A4++[2],A$A[2][2] 598|| LDW *B4++[2],B$A[2][2] 599 LDW *A4++[2],A$A[2][3] 600|| LDW *B4++[2],B$A[2][3] 601 LDW *A4++[2],A$A[2][4] 602|| LDW *B4++[2],B$A[2][4] 603 604 LDW *A4++[2],A$A[3][0] 605|| LDW *B4++[2],B$A[3][0] 606 LDW *A4++[2],A$A[3][1] 607|| LDW *B4++[2],B$A[3][1] 608 LDW *A4++[2],A$A[3][2] 609|| LDW *B4++[2],B$A[3][2] 610 LDW *A4++[2],A$A[3][3] 611|| LDW *B4++[2],B$A[3][3] 612 LDW *A4++[2],A$A[3][4] 613|| LDW *B4++[2],B$A[3][4] 614 615 LDW *A4++[2],A$A[4][0] 616|| LDW *B4++[2],B$A[4][0] 617 LDW *A4++[2],A$A[4][1] 618|| LDW *B4++[2],B$A[4][1] 619 LDW *A4++[2],A$A[4][2] 620|| LDW *B4++[2],B$A[4][2] 621 LDW *A4++[2],A$A[4][3] 622|| LDW *B4++[2],B$A[4][3] 623 LDW *A4,A$A[4][4] 624|| LDW *B4,B$A[4][4] 625|| ADDKPC loop?,RA 626 STDW RA:BSZ,*SP[4] 627 628loop?: 629 CMPLTU LEN,BSZ,A0 ; len < bsz? 630|| SHRU BSZ,3,BSZ 631 [A0] BNOP ret? 632||[A0] ZERO BSZ 633||[A0] LDW *SP[1],A2 ; pull A[][] 634 [BSZ] LDNDW *INP++,A1:A0 635||[BSZ] SUB LEN,8,LEN 636||[BSZ] SUB BSZ,1,BSZ 637 NOP 4 638___ 639for ($y = 0; $y < 5; $y++) { 640 for ($x = 0; $x < ($y<4 ? 5 : 4); $x++) { 641$code.=<<___; 642 .if .BIG_ENDIAN 643 SWAP2 A0,A1 644|| SWAP2 A1,A0 645 SWAP4 A0,A0 646 SWAP4 A1,A1 647||[!BSZ]BNOP _KeccakF1600_cheat 648||[!BSZ]STDW LEN:INP,*SP[3] 649|| DEAL A0,A0 650 .else 651 [!BSZ]BNOP _KeccakF1600_cheat 652||[!BSZ]STDW LEN:INP,*SP[3] 653|| DEAL A0,A0 654 .endif 655 [BSZ] LDNDW *INP++,A1:A0 656|| DEAL A1,A1 657 [BSZ] SUB LEN,8,LEN 658||[BSZ] SUB BSZ,1,BSZ 659 PACK2 A1,A0,A0 660|| PACKH2 A1,A0,A1 661 XOR A0,A$A[$y][$x],A$A[$y][$x] 662 XOR A1,B$A[$y][$x],B$A[$y][$x] 663___ 664 } 665} 666$code.=<<___; 667 .if .BIG_ENDIAN 668 SWAP2 A0,A1 669|| SWAP2 A1,A0 670 SWAP4 A0,A0 671 SWAP4 A1,A1 672 .endif 673 BNOP _KeccakF1600_cheat 674|| STDW LEN:INP,*SP[3] 675|| DEAL A0,A0 676 DEAL A1,A1 677 NOP 678 PACK2 A1,A0,A0 679|| PACKH2 A1,A0,A1 680 XOR A0,A$A[4][4],A$A[4][4] 681 XOR A1,B$A[4][4],B$A[4][4] 682 683 .align 16 684ret?: 685 MV LEN,A4 ; return value 686|| ADD 4,A2,B2 687 688 STW A$A[0][0],*A2++[2] ; store A[5][5] 689|| STW B$A[0][0],*B2++[2] 690 STW A$A[0][1],*A2++[2] 691|| STW B$A[0][1],*B2++[2] 692 STW A$A[0][2],*A2++[2] 693|| STW B$A[0][2],*B2++[2] 694 STW A$A[0][3],*A2++[2] 695|| STW B$A[0][3],*B2++[2] 696 STW A$A[0][4],*A2++[2] 697|| STW B$A[0][4],*B2++[2] 698 699 STW A$A[1][0],*A2++[2] 700|| STW B$A[1][0],*B2++[2] 701 STW A$A[1][1],*A2++[2] 702|| STW B$A[1][1],*B2++[2] 703 STW A$A[1][2],*A2++[2] 704|| STW B$A[1][2],*B2++[2] 705 STW A$A[1][3],*A2++[2] 706|| STW B$A[1][3],*B2++[2] 707 STW A$A[1][4],*A2++[2] 708|| STW B$A[1][4],*B2++[2] 709 710 STW A$A[2][0],*A2++[2] 711|| STW B$A[2][0],*B2++[2] 712 STW A$A[2][1],*A2++[2] 713|| STW B$A[2][1],*B2++[2] 714 STW A$A[2][2],*A2++[2] 715|| STW B$A[2][2],*B2++[2] 716 STW A$A[2][3],*A2++[2] 717|| STW B$A[2][3],*B2++[2] 718 STW A$A[2][4],*A2++[2] 719|| STW B$A[2][4],*B2++[2] 720 721 LDW *SP[15],RA 722|| LDW *FP[-6],A14 723 724 STW A$A[3][0],*A2++[2] 725|| STW B$A[3][0],*B2++[2] 726 STW A$A[3][1],*A2++[2] 727|| STW B$A[3][1],*B2++[2] 728 STW A$A[3][2],*A2++[2] 729|| STW B$A[3][2],*B2++[2] 730 STW A$A[3][3],*A2++[2] 731|| STW B$A[3][3],*B2++[2] 732 STW A$A[3][4],*A2++[2] 733|| STW B$A[3][4],*B2++[2] 734 735 LDDW *SP[8], B11:B10 736|| LDDW *FP[-5],A11:A10 737 LDDW *SP[9], B13:B12 738|| LDDW *FP[-4],A13:A12 739 BNOP RA 740|| LDW *++SP(80),FP ; restore frame pointer 741 742 STW A$A[4][0],*A2++[2] 743|| STW B$A[4][0],*B2++[2] 744 STW A$A[4][1],*A2++[2] 745|| STW B$A[4][1],*B2++[2] 746 STW A$A[4][2],*A2++[2] 747|| STW B$A[4][2],*B2++[2] 748 STW A$A[4][3],*A2++[2] 749|| STW B$A[4][3],*B2++[2] 750 STW A$A[4][4],*A2++[2] 751|| STW B$A[4][4],*B2++[2] 752 .endasmfunc 753 754 .newblock 755 .global _SHA3_squeeze 756 .asg A12,OUT 757 .asg A13,LEN 758 .asg A14,BSZ 759 .align 32 760_SHA3_squeeze: 761 .asmfunc stack_usage(24) 762 STW FP,*SP--(24) ; save frame pointer 763|| MV SP,FP 764 STW RA, *SP[5] 765|| STW A14,*FP[-2] 766 STDW A13:A12,*FP[-2] 767|| MV B4,OUT ; reassign arguments 768 MV A6,LEN 769|| MV B6,BSZ 770 771loop?: 772 LDW *SP[5],RA ; reload RA 773|| SHRU BSZ,3,A1 774|| MV A4,A8 775|| ADD 4,A4,B8 776block?: 777 CMPLTU LEN,8,A0 ; len < 8? 778 [A0] BNOP tail? 779 LDW *A8++[2],A9 780|| LDW *B8++[2],B9 781|| SUB LEN,8,LEN ; len -= 8 782 MV LEN,A0 783|| SUB A1,1,A1 ; bsz-- 784|| NOP 4 785 .if .BIG_ENDIAN 786 SWAP4 A9,A9 787|| SWAP4 B9,B9 788 SWAP2 A9,A9 789|| SWAP2 B9,B9 790 .endif 791 [!A0] BNOP ret? 792||[!A0] ZERO A1 793 PACK2 B9,A9,B7 794||[A1] BNOP block? 795 PACKH2 B9,A9,B9 796|| SHFL B7,B7 797 SHFL B9,B9 798 STNW B7,*OUT++ 799 STNW B9,*OUT++ 800 NOP 801 802 BNOP _KeccakF1600,4 803 ADDKPC loop?,RA 804 805 .align 16 806tail?: 807 .if .BIG_ENDIAN 808 SWAP4 A9,A9 809|| SWAP4 B9,B9 810 SWAP2 A9,A9 811|| SWAP2 B9,B9 812 .endif 813 PACK2 B9,A9,B7 814 PACKH2 B9,A9,B9 815|| SHFL B7,B7 816 SHFL B9,B9 817 818 STB B7,*OUT++ 819|| SHRU B7,8,B7 820|| ADD LEN,7,A0 821 [A0] STB B7,*OUT++ 822||[A0] SHRU B7,8,B7 823||[A0] SUB A0,1,A0 824 [A0] STB B7,*OUT++ 825||[A0] SHRU B7,8,B7 826||[A0] SUB A0,1,A0 827 [A0] STB B7,*OUT++ 828||[A0] SUB A0,1,A0 829 [A0] STB B9,*OUT++ 830||[A0] SHRU B9,8,B9 831||[A0] SUB A0,1,A0 832 [A0] STB B9,*OUT++ 833||[A0] SHRU B9,8,B9 834||[A0] SUB A0,1,A0 835 [A0] STB B9,*OUT++ 836 837ret?: 838 LDDW *FP[-2],A13:A12 839 BNOP RA 840|| LDW *FP[-2],A14 841 LDW *++SP(24),FP ; restore frame pointer 842 NOP 4 ; wait till FP is committed 843 .endasmfunc 844 845 .if __TI_EABI__ 846 .sect ".text:sha_asm.const" 847 .else 848 .sect ".const:sha_asm" 849 .endif 850 .align 256 851 .uword 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 852iotas: 853 .uword 0x00000001, 0x00000000 854 .uword 0x00000000, 0x00000089 855 .uword 0x00000000, 0x8000008b 856 .uword 0x00000000, 0x80008080 857 .uword 0x00000001, 0x0000008b 858 .uword 0x00000001, 0x00008000 859 .uword 0x00000001, 0x80008088 860 .uword 0x00000001, 0x80000082 861 .uword 0x00000000, 0x0000000b 862 .uword 0x00000000, 0x0000000a 863 .uword 0x00000001, 0x00008082 864 .uword 0x00000000, 0x00008003 865 .uword 0x00000001, 0x0000808b 866 .uword 0x00000001, 0x8000000b 867 .uword 0x00000001, 0x8000008a 868 .uword 0x00000001, 0x80000081 869 .uword 0x00000000, 0x80000081 870 .uword 0x00000000, 0x80000008 871 .uword 0x00000000, 0x00000083 872 .uword 0x00000000, 0x80008003 873 .uword 0x00000001, 0x80008088 874 .uword 0x00000000, 0x80000088 875 .uword 0x00000001, 0x00008000 876 .uword 0x00000000, 0x80008082 877 878 .cstring "Keccak-1600 absorb and squeeze for C64x, CRYPTOGAMS by <appro\@openssl.org>" 879 .align 4 880___ 881 882$output=pop and open STDOUT,">$output"; 883print $code; 884close STDOUT or die "error closing STDOUT: $!"; 885