886 lines
22 KiB
Raku
Executable File
886 lines
22 KiB
Raku
Executable File
#!/usr/bin/env perl
|
|
# Copyright 2017-2020 The OpenSSL Project Authors. All Rights Reserved.
|
|
#
|
|
# Licensed under the OpenSSL license (the "License"). You may not use
|
|
# this file except in compliance with the License. You can obtain a copy
|
|
# in the file LICENSE in the source distribution or at
|
|
# https://www.openssl.org/source/license.html
|
|
#
|
|
# ====================================================================
|
|
# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
|
|
# project. The module is, however, dual licensed under OpenSSL and
|
|
# CRYPTOGAMS licenses depending on where you obtain it. For further
|
|
# details see http://www.openssl.org/~appro/cryptogams/.
|
|
# ====================================================================
|
|
#
|
|
# [ABI- and endian-neutral] Keccak-1600 for C64x.
|
|
#
|
|
# June 2017.
|
|
#
|
|
# This is straightforward KECCAK_1X_ALT variant (see sha/keccak1600.c)
|
|
# with bit interleaving. 64-bit values are simply split between A- and
|
|
# B-files, with A-file holding least significant halves. This works
|
|
# out perfectly, because all operations including cross-communications
|
|
# [in rotate operations] are always complementary. Performance is
|
|
# [incredible for a 32-bit processor] 10.9 cycles per processed byte
|
|
# for r=1088, which corresponds to SHA3-256. This is >15x faster than
|
|
# compiler-generated KECCAK_1X_ALT code, and >10x than other variants.
|
|
# On average processor ends up issuing ~4.5 instructions per cycle...
|
|
|
|
my @A = map([ $_, ($_+1), ($_+2), ($_+3), ($_+4) ], (5,10,16,21,26));
|
|
$A[1][4] = 31; # B14 is reserved, A14 is used as iota[]
|
|
($A[3][0],$A[4][1]) = ($A[4][1],$A[3][0]);
|
|
my @C = (0..4,$A[3][0],$A[4][0]);
|
|
my $iotas = "A14";
|
|
|
|
my @rhotates = ([ 0, 1, 62, 28, 27 ],
|
|
[ 36, 44, 6, 55, 20 ],
|
|
[ 3, 10, 43, 25, 39 ],
|
|
[ 41, 45, 15, 21, 8 ],
|
|
[ 18, 2, 61, 56, 14 ]);
|
|
|
|
sub ROL64 {
|
|
my ($src,$rot,$dst,$p) = @_;
|
|
|
|
if ($rot&1) {
|
|
$code.=<<___;
|
|
$p ROTL B$src,$rot/2+1,A$dst
|
|
|| ROTL A$src,$rot/2, B$dst
|
|
___
|
|
} else {
|
|
$code.=<<___;
|
|
$p ROTL A$src,$rot/2,A$dst
|
|
|| ROTL B$src,$rot/2,B$dst
|
|
___
|
|
}
|
|
}
|
|
|
|
########################################################################
|
|
# Stack frame layout
|
|
#
|
|
# SP--->+------+------+
|
|
# | | |
|
|
# +1--->+------+------+<- -9 below 4 slots are used by KeccakF1600_int
|
|
# | | |
|
|
# +2--->+------+------+<- -8
|
|
# | | |
|
|
# +3--->+------+------+<- -7
|
|
# | A2 | A3 | A3:A2 are preserved by KeccakF1600_int
|
|
# +4--->+------+------+<- -6
|
|
# | B2 | B3 | B3:B2 are preserved by KeccakF1600_int
|
|
# +5--->+------+------+<- -5 below is ABI-compliant layout
|
|
# | A10 | A11 |
|
|
# +6--->+------+------+<- -4
|
|
# | A12 | A13 |
|
|
# +7--->+------+------+<- -3
|
|
# | A14 | B3 |
|
|
# +8--->+------+------+<- -2
|
|
# | B10 | B11 |
|
|
# +9--->+------+------+<- -1
|
|
# | B12 | B13 |
|
|
# +------+------+<---FP
|
|
# | A15 |
|
|
# +------+--
|
|
|
|
$code.=<<___;
|
|
.text
|
|
|
|
.if .ASSEMBLER_VERSION<7000000
|
|
.asg 0,__TI_EABI__
|
|
.endif
|
|
.if __TI_EABI__
|
|
.nocmp
|
|
.asg KeccakF1600,_KeccakF1600
|
|
.asg SHA3_absorb,_SHA3_absorb
|
|
.asg SHA3_squeeze,_SHA3_squeeze
|
|
.endif
|
|
|
|
.asg B3,RA
|
|
.asg A15,FP
|
|
.asg B15,SP
|
|
|
|
.align 32
|
|
_KeccakF1600_int:
|
|
.asmfunc
|
|
STDW A3:A2,*FP[-7]
|
|
|| STDW B3:B2,*SP[4]
|
|
_KeccakF1600_cheat:
|
|
.if __TI_EABI__
|
|
ADDKPC _KeccakF1600_int,B0
|
|
|| MVKL \$PCR_OFFSET(iotas,_KeccakF1600_int),$iotas
|
|
MVKH \$PCR_OFFSET(iotas,_KeccakF1600_int),$iotas
|
|
.else
|
|
ADDKPC _KeccakF1600_int,B0
|
|
|| MVKL (iotas-_KeccakF1600_int),$iotas
|
|
MVKH (iotas-_KeccakF1600_int),$iotas
|
|
.endif
|
|
ADD B0,$iotas,$iotas
|
|
loop?:
|
|
XOR A$A[0][2],A$A[1][2],A$C[2] ; Theta
|
|
|| XOR B$A[0][2],B$A[1][2],B$C[2]
|
|
|| XOR A$A[0][3],A$A[1][3],A$C[3]
|
|
|| XOR B$A[0][3],B$A[1][3],B$C[3]
|
|
|| XOR A$A[0][0],A$A[1][0],A$C[0]
|
|
|| XOR B$A[0][0],B$A[1][0],B$C[0]
|
|
XOR A$A[2][2],A$C[2],A$C[2]
|
|
|| XOR B$A[2][2],B$C[2],B$C[2]
|
|
|| XOR A$A[2][3],A$C[3],A$C[3]
|
|
|| XOR B$A[2][3],B$C[3],B$C[3]
|
|
|| XOR A$A[2][0],A$C[0],A$C[0]
|
|
|| XOR B$A[2][0],B$C[0],B$C[0]
|
|
XOR A$A[3][2],A$C[2],A$C[2]
|
|
|| XOR B$A[3][2],B$C[2],B$C[2]
|
|
|| XOR A$A[3][3],A$C[3],A$C[3]
|
|
|| XOR B$A[3][3],B$C[3],B$C[3]
|
|
|| XOR A$A[3][0],A$C[0],A$C[0]
|
|
|| XOR B$A[3][0],B$C[0],B$C[0]
|
|
XOR A$A[4][2],A$C[2],A$C[2]
|
|
|| XOR B$A[4][2],B$C[2],B$C[2]
|
|
|| XOR A$A[4][3],A$C[3],A$C[3]
|
|
|| XOR B$A[4][3],B$C[3],B$C[3]
|
|
|| XOR A$A[4][0],A$C[0],A$C[0]
|
|
|| XOR B$A[4][0],B$C[0],B$C[0]
|
|
XOR A$A[0][4],A$A[1][4],A$C[4]
|
|
|| XOR B$A[0][4],B$A[1][4],B$C[4]
|
|
|| XOR A$A[0][1],A$A[1][1],A$C[1]
|
|
|| XOR B$A[0][1],B$A[1][1],B$C[1]
|
|
|| STDW A$A[3][0]:A$A[4][0],*SP[1] ; offload some data
|
|
STDW B$A[3][0]:B$A[4][0],*SP[2]
|
|
|| XOR A$A[2][4],A$C[4],A$C[4]
|
|
|| XOR B$A[2][4],B$C[4],B$C[4]
|
|
|| XOR A$A[2][1],A$C[1],A$C[1]
|
|
|| XOR B$A[2][1],B$C[1],B$C[1]
|
|
|| ROTL B$C[2],1,A$C[5] ; ROL64(C[2],1)
|
|
|| ROTL A$C[2],0,B$C[5]
|
|
XOR A$A[3][4],A$C[4],A$C[4]
|
|
|| XOR B$A[3][4],B$C[4],B$C[4]
|
|
|| XOR A$A[3][1],A$C[1],A$C[1]
|
|
|| XOR B$A[3][1],B$C[1],B$C[1]
|
|
|| ROTL B$C[3],1,A$C[6] ; ROL64(C[3],1)
|
|
|| ROTL A$C[3],0,B$C[6]
|
|
XOR A$A[4][4],A$C[4],A$C[4]
|
|
|| XOR B$A[4][4],B$C[4],B$C[4]
|
|
|| XOR A$A[4][1],A$C[1],A$C[1]
|
|
|| XOR B$A[4][1],B$C[1],B$C[1]
|
|
|| XOR A$C[0],A$C[5],A$C[5] ; C[0] ^ ROL64(C[2],1)
|
|
|| XOR B$C[0],B$C[5],B$C[5]
|
|
XOR A$C[5],A$A[0][1],A$A[0][1]
|
|
|| XOR B$C[5],B$A[0][1],B$A[0][1]
|
|
|| XOR A$C[5],A$A[1][1],A$A[1][1]
|
|
|| XOR B$C[5],B$A[1][1],B$A[1][1]
|
|
|| XOR A$C[5],A$A[2][1],A$A[2][1]
|
|
|| XOR B$C[5],B$A[2][1],B$A[2][1]
|
|
XOR A$C[5],A$A[3][1],A$A[3][1]
|
|
|| XOR B$C[5],B$A[3][1],B$A[3][1]
|
|
|| XOR A$C[5],A$A[4][1],A$A[4][1]
|
|
|| XOR B$C[5],B$A[4][1],B$A[4][1]
|
|
|| ROTL B$C[4],1,A$C[5] ; ROL64(C[4],1)
|
|
|| ROTL A$C[4],0,B$C[5]
|
|
|| XOR A$C[1],A$C[6],A$C[6] ; C[1] ^ ROL64(C[3],1)
|
|
|| XOR B$C[1],B$C[6],B$C[6]
|
|
XOR A$C[6],A$A[0][2],A$A[0][2]
|
|
|| XOR B$C[6],B$A[0][2],B$A[0][2]
|
|
|| XOR A$C[6],A$A[1][2],A$A[1][2]
|
|
|| XOR B$C[6],B$A[1][2],B$A[1][2]
|
|
|| XOR A$C[6],A$A[2][2],A$A[2][2]
|
|
|| XOR B$C[6],B$A[2][2],B$A[2][2]
|
|
|| ROTL B$C[1],1,A$C[1] ; ROL64(C[1],1)
|
|
|| ROTL A$C[1],0,B$C[1]
|
|
XOR A$C[6],A$A[3][2],A$A[3][2]
|
|
|| XOR B$C[6],B$A[3][2],B$A[3][2]
|
|
|| XOR A$C[6],A$A[4][2],A$A[4][2]
|
|
|| XOR B$C[6],B$A[4][2],B$A[4][2]
|
|
|| ROTL B$C[0],1,A$C[6] ; ROL64(C[0],1)
|
|
|| ROTL A$C[0],0,B$C[6]
|
|
|| XOR A$C[5],A$C[2],A$C[2] ; C[2] ^= ROL64(C[4],1)
|
|
|| XOR B$C[5],B$C[2],B$C[2]
|
|
XOR A$C[2],A$A[0][3],A$A[0][3]
|
|
|| XOR B$C[2],B$A[0][3],B$A[0][3]
|
|
|| XOR A$C[2],A$A[1][3],A$A[1][3]
|
|
|| XOR B$C[2],B$A[1][3],B$A[1][3]
|
|
|| XOR A$C[2],A$A[2][3],A$A[2][3]
|
|
|| XOR B$C[2],B$A[2][3],B$A[2][3]
|
|
XOR A$C[6],A$C[3],A$C[3] ; C[3] ^= ROL64(C[0],1)
|
|
|| XOR B$C[6],B$C[3],B$C[3]
|
|
|| LDDW *FP[-9],A$A[3][0]:A$A[4][0] ; restore offloaded data
|
|
|| LDDW *SP[2],B$A[3][0]:B$A[4][0]
|
|
|| XOR A$C[2],A$A[3][3],A$A[3][3]
|
|
|| XOR B$C[2],B$A[3][3],B$A[3][3]
|
|
XOR A$C[2],A$A[4][3],A$A[4][3]
|
|
|| XOR B$C[2],B$A[4][3],B$A[4][3]
|
|
|| XOR A$C[3],A$A[0][4],A$A[0][4]
|
|
|| XOR B$C[3],B$A[0][4],B$A[0][4]
|
|
|| XOR A$C[3],A$A[1][4],A$A[1][4]
|
|
|| XOR B$C[3],B$A[1][4],B$A[1][4]
|
|
XOR A$C[3],A$A[2][4],A$A[2][4]
|
|
|| XOR B$C[3],B$A[2][4],B$A[2][4]
|
|
|| XOR A$C[3],A$A[3][4],A$A[3][4]
|
|
|| XOR B$C[3],B$A[3][4],B$A[3][4]
|
|
|| XOR A$C[3],A$A[4][4],A$A[4][4]
|
|
|| XOR B$C[3],B$A[4][4],B$A[4][4]
|
|
XOR A$C[1],A$C[4],A$C[4] ; C[4] ^= ROL64(C[1],1)
|
|
|| XOR B$C[1],B$C[4],B$C[4]
|
|
|| MV A$A[0][1],A$C[1] ; Rho+Pi, "early start"
|
|
|| MV B$A[0][1],B$C[1]
|
|
___
|
|
&ROL64 ($A[1][1],$rhotates[1][1],$A[0][1],"||");
|
|
$code.=<<___;
|
|
XOR A$C[4],A$A[0][0],A$A[0][0]
|
|
|| XOR B$C[4],B$A[0][0],B$A[0][0]
|
|
|| XOR A$C[4],A$A[1][0],A$A[1][0]
|
|
|| XOR B$C[4],B$A[1][0],B$A[1][0]
|
|
|| MV A$A[0][3],A$C[3]
|
|
|| MV B$A[0][3],B$C[3]
|
|
___
|
|
&ROL64 ($A[3][3],$rhotates[3][3],$A[0][3],"||");
|
|
$code.=<<___;
|
|
XOR A$C[4],A$A[2][0],A$A[2][0]
|
|
|| XOR B$C[4],B$A[2][0],B$A[2][0]
|
|
|| XOR A$C[4],A$A[3][0],A$A[3][0]
|
|
|| XOR B$C[4],B$A[3][0],B$A[3][0]
|
|
|| MV A$A[0][2],A$C[2]
|
|
|| MV B$A[0][2],B$C[2]
|
|
___
|
|
&ROL64 ($A[2][2],$rhotates[2][2],$A[0][2],"||");
|
|
$code.=<<___;
|
|
XOR A$C[4],A$A[4][0],A$A[4][0]
|
|
|| XOR B$C[4],B$A[4][0],B$A[4][0]
|
|
|| MV A$A[0][4],A$C[4]
|
|
|| MV B$A[0][4],B$C[4]
|
|
___
|
|
&ROL64 ($A[4][4],$rhotates[4][4],$A[0][4],"||");
|
|
|
|
&ROL64 ($A[1][4],$rhotates[1][4],$A[1][1]);
|
|
$code.=<<___;
|
|
|| LDW *${iotas}++[2],A$C[0]
|
|
___
|
|
&ROL64 ($A[2][3],$rhotates[2][3],$A[2][2]);
|
|
$code.=<<___;
|
|
|| LDW *${iotas}[-1],B$C[0]
|
|
___
|
|
&ROL64 ($A[3][2],$rhotates[3][2],$A[3][3]);
|
|
&ROL64 ($A[4][1],$rhotates[4][1],$A[4][4]);
|
|
|
|
&ROL64 ($A[4][2],$rhotates[4][2],$A[1][4]);
|
|
&ROL64 ($A[3][4],$rhotates[3][4],$A[2][3]);
|
|
&ROL64 ($A[2][1],$rhotates[2][1],$A[3][2]);
|
|
&ROL64 ($A[1][3],$rhotates[1][3],$A[4][1]);
|
|
|
|
&ROL64 ($A[2][4],$rhotates[2][4],$A[4][2]);
|
|
&ROL64 ($A[4][3],$rhotates[4][3],$A[3][4]);
|
|
&ROL64 ($A[1][2],$rhotates[1][2],$A[2][1]);
|
|
&ROL64 ($A[3][1],$rhotates[3][1],$A[1][3]);
|
|
|
|
&ROL64 ($A[4][0],$rhotates[4][0],$A[2][4]);
|
|
&ROL64 ($A[3][0],$rhotates[3][0],$A[4][3]);
|
|
&ROL64 ($A[2][0],$rhotates[2][0],$A[1][2]);
|
|
&ROL64 ($A[1][0],$rhotates[1][0],$A[3][1]);
|
|
|
|
#&ROL64 ($C[3], $rhotates[0][3],$A[1][0]); # moved below
|
|
&ROL64 ($C[1], $rhotates[0][1],$A[2][0]);
|
|
&ROL64 ($C[4], $rhotates[0][4],$A[3][0]);
|
|
&ROL64 ($C[2], $rhotates[0][2],$A[4][0]);
|
|
$code.=<<___;
|
|
|| ANDN A$A[0][2],A$A[0][1],A$C[4] ; Chi+Iota
|
|
|| ANDN B$A[0][2],B$A[0][1],B$C[4]
|
|
|| ANDN A$A[0][3],A$A[0][2],A$C[1]
|
|
|| ANDN B$A[0][3],B$A[0][2],B$C[1]
|
|
|| ANDN A$A[0][4],A$A[0][3],A$C[2]
|
|
|| ANDN B$A[0][4],B$A[0][3],B$C[2]
|
|
___
|
|
&ROL64 ($C[3], $rhotates[0][3],$A[1][0]);
|
|
$code.=<<___;
|
|
|| ANDN A$A[0][0],A$A[0][4],A$C[3]
|
|
|| ANDN B$A[0][0],B$A[0][4],B$C[3]
|
|
|| XOR A$C[4],A$A[0][0],A$A[0][0]
|
|
|| XOR B$C[4],B$A[0][0],B$A[0][0]
|
|
|| ANDN A$A[0][1],A$A[0][0],A$C[4]
|
|
|| ANDN B$A[0][1],B$A[0][0],B$C[4]
|
|
XOR A$C[1],A$A[0][1],A$A[0][1]
|
|
|| XOR B$C[1],B$A[0][1],B$A[0][1]
|
|
|| XOR A$C[2],A$A[0][2],A$A[0][2]
|
|
|| XOR B$C[2],B$A[0][2],B$A[0][2]
|
|
|| XOR A$C[3],A$A[0][3],A$A[0][3]
|
|
|| XOR B$C[3],B$A[0][3],B$A[0][3]
|
|
XOR A$C[4],A$A[0][4],A$A[0][4]
|
|
|| XOR B$C[4],B$A[0][4],B$A[0][4]
|
|
|| XOR A$C[0],A$A[0][0],A$A[0][0] ; A[0][0] ^= iotas[i++];
|
|
|| XOR B$C[0],B$A[0][0],B$A[0][0]
|
|
|| EXTU $iotas,24,24,A0 ; A0 is A$C[0], as we done?
|
|
|
|
ANDN A$A[1][2],A$A[1][1],A$C[4]
|
|
|| ANDN B$A[1][2],B$A[1][1],B$C[4]
|
|
|| ANDN A$A[1][3],A$A[1][2],A$C[1]
|
|
|| ANDN B$A[1][3],B$A[1][2],B$C[1]
|
|
|| ANDN A$A[1][4],A$A[1][3],A$C[2]
|
|
|| ANDN B$A[1][4],B$A[1][3],B$C[2]
|
|
ANDN A$A[1][0],A$A[1][4],A$C[3]
|
|
|| ANDN B$A[1][0],B$A[1][4],B$C[3]
|
|
|| XOR A$C[4],A$A[1][0],A$A[1][0]
|
|
|| XOR B$C[4],B$A[1][0],B$A[1][0]
|
|
|| ANDN A$A[1][1],A$A[1][0],A$C[4]
|
|
|| ANDN B$A[1][1],B$A[1][0],B$C[4]
|
|
XOR A$C[1],A$A[1][1],A$A[1][1]
|
|
|| XOR B$C[1],B$A[1][1],B$A[1][1]
|
|
|| XOR A$C[2],A$A[1][2],A$A[1][2]
|
|
|| XOR B$C[2],B$A[1][2],B$A[1][2]
|
|
|| XOR A$C[3],A$A[1][3],A$A[1][3]
|
|
|| XOR B$C[3],B$A[1][3],B$A[1][3]
|
|
XOR A$C[4],A$A[1][4],A$A[1][4]
|
|
|| XOR B$C[4],B$A[1][4],B$A[1][4]
|
|
|
|
|| ANDN A$A[2][2],A$A[2][1],A$C[4]
|
|
|| ANDN B$A[2][2],B$A[2][1],B$C[4]
|
|
|| ANDN A$A[2][3],A$A[2][2],A$C[1]
|
|
|| ANDN B$A[2][3],B$A[2][2],B$C[1]
|
|
ANDN A$A[2][4],A$A[2][3],A$C[2]
|
|
|| ANDN B$A[2][4],B$A[2][3],B$C[2]
|
|
|| ANDN A$A[2][0],A$A[2][4],A$C[3]
|
|
|| ANDN B$A[2][0],B$A[2][4],B$C[3]
|
|
|| XOR A$C[4],A$A[2][0],A$A[2][0]
|
|
|| XOR B$C[4],B$A[2][0],B$A[2][0]
|
|
ANDN A$A[2][1],A$A[2][0],A$C[4]
|
|
|| ANDN B$A[2][1],B$A[2][0],B$C[4]
|
|
|| XOR A$C[1],A$A[2][1],A$A[2][1]
|
|
|| XOR B$C[1],B$A[2][1],B$A[2][1]
|
|
|| XOR A$C[2],A$A[2][2],A$A[2][2]
|
|
|| XOR B$C[2],B$A[2][2],B$A[2][2]
|
|
XOR A$C[3],A$A[2][3],A$A[2][3]
|
|
|| XOR B$C[3],B$A[2][3],B$A[2][3]
|
|
|| XOR A$C[4],A$A[2][4],A$A[2][4]
|
|
|| XOR B$C[4],B$A[2][4],B$A[2][4]
|
|
|
|
ANDN A$A[3][2],A$A[3][1],A$C[4]
|
|
|| ANDN B$A[3][2],B$A[3][1],B$C[4]
|
|
|| ANDN A$A[3][3],A$A[3][2],A$C[1]
|
|
|| ANDN B$A[3][3],B$A[3][2],B$C[1]
|
|
|| ANDN A$A[3][4],A$A[3][3],A$C[2]
|
|
|| ANDN B$A[3][4],B$A[3][3],B$C[2]
|
|
ANDN A$A[3][0],A$A[3][4],A$C[3]
|
|
|| ANDN B$A[3][0],B$A[3][4],B$C[3]
|
|
|| XOR A$C[4],A$A[3][0],A$A[3][0]
|
|
|| XOR B$C[4],B$A[3][0],B$A[3][0]
|
|
|| ANDN A$A[3][1],A$A[3][0],A$C[4]
|
|
|| ANDN B$A[3][1],B$A[3][0],B$C[4]
|
|
XOR A$C[1],A$A[3][1],A$A[3][1]
|
|
|| XOR B$C[1],B$A[3][1],B$A[3][1]
|
|
|| XOR A$C[2],A$A[3][2],A$A[3][2]
|
|
|| XOR B$C[2],B$A[3][2],B$A[3][2]
|
|
|| XOR A$C[3],A$A[3][3],A$A[3][3]
|
|
||[A0] BNOP loop?
|
|
XOR B$C[3],B$A[3][3],B$A[3][3]
|
|
|| XOR A$C[4],A$A[3][4],A$A[3][4]
|
|
|| XOR B$C[4],B$A[3][4],B$A[3][4]
|
|
||[!A0] LDDW *FP[-7],A3:A2
|
|
||[!A0] LDDW *SP[4], RA:B2
|
|
|
|
ANDN A$A[4][2],A$A[4][1],A$C[4]
|
|
|| ANDN B$A[4][2],B$A[4][1],B$C[4]
|
|
|| ANDN A$A[4][3],A$A[4][2],A$C[1]
|
|
|| ANDN B$A[4][3],B$A[4][2],B$C[1]
|
|
|| ANDN A$A[4][4],A$A[4][3],A$C[2]
|
|
|| ANDN B$A[4][4],B$A[4][3],B$C[2]
|
|
ANDN A$A[4][0],A$A[4][4],A$C[3]
|
|
|| ANDN B$A[4][0],B$A[4][4],B$C[3]
|
|
|| XOR A$C[4],A$A[4][0],A$A[4][0]
|
|
|| XOR B$C[4],B$A[4][0],B$A[4][0]
|
|
|| ANDN A$A[4][1],A$A[4][0],A$C[4]
|
|
|| ANDN B$A[4][1],B$A[4][0],B$C[4]
|
|
XOR A$C[1],A$A[4][1],A$A[4][1]
|
|
|| XOR B$C[1],B$A[4][1],B$A[4][1]
|
|
|| XOR A$C[2],A$A[4][2],A$A[4][2]
|
|
|| XOR B$C[2],B$A[4][2],B$A[4][2]
|
|
|| XOR A$C[3],A$A[4][3],A$A[4][3]
|
|
|| XOR B$C[3],B$A[4][3],B$A[4][3]
|
|
XOR A$C[4],A$A[4][4],A$A[4][4]
|
|
|| XOR B$C[4],B$A[4][4],B$A[4][4]
|
|
;;===== branch to loop? is taken here
|
|
|
|
BNOP RA,5
|
|
.endasmfunc
|
|
|
|
.newblock
|
|
.global _KeccakF1600
|
|
.align 32
|
|
_KeccakF1600:
|
|
.asmfunc stack_usage(80)
|
|
STW FP,*SP--(80) ; save frame pointer
|
|
|| MV SP,FP
|
|
STDW B13:B12,*SP[9]
|
|
|| STDW A13:A12,*FP[-4]
|
|
STDW B11:B10,*SP[8]
|
|
|| STDW A11:A10,*FP[-5]
|
|
STW RA, *SP[15]
|
|
|| STW A14,*FP[-6]
|
|
|| MV A4,A2
|
|
|| ADD 4,A4,B2
|
|
|
|
LDW *A2++[2],A$A[0][0] ; load A[5][5]
|
|
|| LDW *B2++[2],B$A[0][0]
|
|
LDW *A2++[2],A$A[0][1]
|
|
|| LDW *B2++[2],B$A[0][1]
|
|
LDW *A2++[2],A$A[0][2]
|
|
|| LDW *B2++[2],B$A[0][2]
|
|
LDW *A2++[2],A$A[0][3]
|
|
|| LDW *B2++[2],B$A[0][3]
|
|
LDW *A2++[2],A$A[0][4]
|
|
|| LDW *B2++[2],B$A[0][4]
|
|
|
|
LDW *A2++[2],A$A[1][0]
|
|
|| LDW *B2++[2],B$A[1][0]
|
|
LDW *A2++[2],A$A[1][1]
|
|
|| LDW *B2++[2],B$A[1][1]
|
|
LDW *A2++[2],A$A[1][2]
|
|
|| LDW *B2++[2],B$A[1][2]
|
|
LDW *A2++[2],A$A[1][3]
|
|
|| LDW *B2++[2],B$A[1][3]
|
|
LDW *A2++[2],A$A[1][4]
|
|
|| LDW *B2++[2],B$A[1][4]
|
|
|
|
LDW *A2++[2],A$A[2][0]
|
|
|| LDW *B2++[2],B$A[2][0]
|
|
LDW *A2++[2],A$A[2][1]
|
|
|| LDW *B2++[2],B$A[2][1]
|
|
LDW *A2++[2],A$A[2][2]
|
|
|| LDW *B2++[2],B$A[2][2]
|
|
LDW *A2++[2],A$A[2][3]
|
|
|| LDW *B2++[2],B$A[2][3]
|
|
LDW *A2++[2],A$A[2][4]
|
|
|| LDW *B2++[2],B$A[2][4]
|
|
|
|
LDW *A2++[2],A$A[3][0]
|
|
|| LDW *B2++[2],B$A[3][0]
|
|
LDW *A2++[2],A$A[3][1]
|
|
|| LDW *B2++[2],B$A[3][1]
|
|
LDW *A2++[2],A$A[3][2]
|
|
|| LDW *B2++[2],B$A[3][2]
|
|
LDW *A2++[2],A$A[3][3]
|
|
|| LDW *B2++[2],B$A[3][3]
|
|
LDW *A2++[2],A$A[3][4]
|
|
|| LDW *B2++[2],B$A[3][4]
|
|
|| BNOP _KeccakF1600_int
|
|
|
|
ADDKPC ret?,RA
|
|
|| LDW *A2++[2],A$A[4][0]
|
|
|| LDW *B2++[2],B$A[4][0]
|
|
LDW *A2++[2],A$A[4][1]
|
|
|| LDW *B2++[2],B$A[4][1]
|
|
LDW *A2++[2],A$A[4][2]
|
|
|| LDW *B2++[2],B$A[4][2]
|
|
LDW *A2++[2],A$A[4][3]
|
|
|| LDW *B2++[2],B$A[4][3]
|
|
LDW *A2,A$A[4][4]
|
|
|| LDW *B2,B$A[4][4]
|
|
|| ADDK -192,A2 ; rewind
|
|
|| ADDK -192,B2
|
|
|
|
.align 16
|
|
ret?:
|
|
STW A$A[0][0],*A2++[2] ; store A[5][5]
|
|
|| STW B$A[0][0],*B2++[2]
|
|
STW A$A[0][1],*A2++[2]
|
|
|| STW B$A[0][1],*B2++[2]
|
|
STW A$A[0][2],*A2++[2]
|
|
|| STW B$A[0][2],*B2++[2]
|
|
STW A$A[0][3],*A2++[2]
|
|
|| STW B$A[0][3],*B2++[2]
|
|
STW A$A[0][4],*A2++[2]
|
|
|| STW B$A[0][4],*B2++[2]
|
|
|
|
STW A$A[1][0],*A2++[2]
|
|
|| STW B$A[1][0],*B2++[2]
|
|
STW A$A[1][1],*A2++[2]
|
|
|| STW B$A[1][1],*B2++[2]
|
|
STW A$A[1][2],*A2++[2]
|
|
|| STW B$A[1][2],*B2++[2]
|
|
STW A$A[1][3],*A2++[2]
|
|
|| STW B$A[1][3],*B2++[2]
|
|
STW A$A[1][4],*A2++[2]
|
|
|| STW B$A[1][4],*B2++[2]
|
|
|
|
STW A$A[2][0],*A2++[2]
|
|
|| STW B$A[2][0],*B2++[2]
|
|
STW A$A[2][1],*A2++[2]
|
|
|| STW B$A[2][1],*B2++[2]
|
|
STW A$A[2][2],*A2++[2]
|
|
|| STW B$A[2][2],*B2++[2]
|
|
STW A$A[2][3],*A2++[2]
|
|
|| STW B$A[2][3],*B2++[2]
|
|
STW A$A[2][4],*A2++[2]
|
|
|| STW B$A[2][4],*B2++[2]
|
|
|
|
STW A$A[3][0],*A2++[2]
|
|
|| STW B$A[3][0],*B2++[2]
|
|
STW A$A[3][1],*A2++[2]
|
|
|| STW B$A[3][1],*B2++[2]
|
|
STW A$A[3][2],*A2++[2]
|
|
|| STW B$A[3][2],*B2++[2]
|
|
STW A$A[3][3],*A2++[2]
|
|
|| STW B$A[3][3],*B2++[2]
|
|
STW A$A[3][4],*A2++[2]
|
|
|| STW B$A[3][4],*B2++[2]
|
|
|
|
LDW *SP[15],RA
|
|
|| LDW *FP[-6],A14
|
|
|
|
STW A$A[4][0],*A2++[2]
|
|
|| STW B$A[4][0],*B2++[2]
|
|
STW A$A[4][1],*A2++[2]
|
|
|| STW B$A[4][1],*B2++[2]
|
|
STW A$A[4][2],*A2++[2]
|
|
|| STW B$A[4][2],*B2++[2]
|
|
STW A$A[4][3],*A2++[2]
|
|
|| STW B$A[4][3],*B2++[2]
|
|
STW A$A[4][4],*A2
|
|
|| STW B$A[4][4],*B2
|
|
|| ADDK -192,A2 ; rewind
|
|
|
|
MV A2,A4 ; return original A4
|
|
|| LDDW *SP[8], B11:B10
|
|
|| LDDW *FP[-5],A11:A10
|
|
LDDW *SP[9], B13:B12
|
|
|| LDDW *FP[-4],A13:A12
|
|
|| BNOP RA
|
|
LDW *++SP(80),FP ; restore frame pointer
|
|
NOP 4 ; wait till FP is committed
|
|
.endasmfunc
|
|
|
|
.newblock
|
|
.asg B2,BSZ
|
|
.asg A2,INP
|
|
.asg A3,LEN
|
|
.global _SHA3_absorb
|
|
.align 32
|
|
_SHA3_absorb:
|
|
.asmfunc stack_usage(80)
|
|
STW FP,*SP--(80) ; save frame pointer
|
|
|| MV SP,FP
|
|
STDW B13:B12,*SP[9]
|
|
|| STDW A13:A12,*FP[-4]
|
|
STDW B11:B10,*SP[8]
|
|
|| STDW A11:A10,*FP[-5]
|
|
STW RA, *SP[15]
|
|
|| STW A14,*FP[-6]
|
|
|
|
STW A4,*SP[1] ; save A[][]
|
|
|| MV B4,INP ; reassign arguments
|
|
|| MV A6,LEN
|
|
|| MV B6,BSZ
|
|
|| ADD 4,A4,B4
|
|
|
|
LDW *A4++[2],A$A[0][0] ; load A[5][5]
|
|
|| LDW *B4++[2],B$A[0][0]
|
|
LDW *A4++[2],A$A[0][1]
|
|
|| LDW *B4++[2],B$A[0][1]
|
|
LDW *A4++[2],A$A[0][2]
|
|
|| LDW *B4++[2],B$A[0][2]
|
|
LDW *A4++[2],A$A[0][3]
|
|
|| LDW *B4++[2],B$A[0][3]
|
|
LDW *A4++[2],A$A[0][4]
|
|
|| LDW *B4++[2],B$A[0][4]
|
|
|
|
LDW *A4++[2],A$A[1][0]
|
|
|| LDW *B4++[2],B$A[1][0]
|
|
LDW *A4++[2],A$A[1][1]
|
|
|| LDW *B4++[2],B$A[1][1]
|
|
LDW *A4++[2],A$A[1][2]
|
|
|| LDW *B4++[2],B$A[1][2]
|
|
LDW *A4++[2],A$A[1][3]
|
|
|| LDW *B4++[2],B$A[1][3]
|
|
LDW *A4++[2],A$A[1][4]
|
|
|| LDW *B4++[2],B$A[1][4]
|
|
|
|
LDW *A4++[2],A$A[2][0]
|
|
|| LDW *B4++[2],B$A[2][0]
|
|
LDW *A4++[2],A$A[2][1]
|
|
|| LDW *B4++[2],B$A[2][1]
|
|
LDW *A4++[2],A$A[2][2]
|
|
|| LDW *B4++[2],B$A[2][2]
|
|
LDW *A4++[2],A$A[2][3]
|
|
|| LDW *B4++[2],B$A[2][3]
|
|
LDW *A4++[2],A$A[2][4]
|
|
|| LDW *B4++[2],B$A[2][4]
|
|
|
|
LDW *A4++[2],A$A[3][0]
|
|
|| LDW *B4++[2],B$A[3][0]
|
|
LDW *A4++[2],A$A[3][1]
|
|
|| LDW *B4++[2],B$A[3][1]
|
|
LDW *A4++[2],A$A[3][2]
|
|
|| LDW *B4++[2],B$A[3][2]
|
|
LDW *A4++[2],A$A[3][3]
|
|
|| LDW *B4++[2],B$A[3][3]
|
|
LDW *A4++[2],A$A[3][4]
|
|
|| LDW *B4++[2],B$A[3][4]
|
|
|
|
LDW *A4++[2],A$A[4][0]
|
|
|| LDW *B4++[2],B$A[4][0]
|
|
LDW *A4++[2],A$A[4][1]
|
|
|| LDW *B4++[2],B$A[4][1]
|
|
LDW *A4++[2],A$A[4][2]
|
|
|| LDW *B4++[2],B$A[4][2]
|
|
LDW *A4++[2],A$A[4][3]
|
|
|| LDW *B4++[2],B$A[4][3]
|
|
LDW *A4,A$A[4][4]
|
|
|| LDW *B4,B$A[4][4]
|
|
|| ADDKPC loop?,RA
|
|
STDW RA:BSZ,*SP[4]
|
|
|
|
loop?:
|
|
CMPLTU LEN,BSZ,A0 ; len < bsz?
|
|
|| SHRU BSZ,3,BSZ
|
|
[A0] BNOP ret?
|
|
||[A0] ZERO BSZ
|
|
||[A0] LDW *SP[1],A2 ; pull A[][]
|
|
[BSZ] LDNDW *INP++,A1:A0
|
|
||[BSZ] SUB LEN,8,LEN
|
|
||[BSZ] SUB BSZ,1,BSZ
|
|
NOP 4
|
|
___
|
|
for ($y = 0; $y < 5; $y++) {
|
|
for ($x = 0; $x < ($y<4 ? 5 : 4); $x++) {
|
|
$code.=<<___;
|
|
.if .BIG_ENDIAN
|
|
SWAP2 A0,A1
|
|
|| SWAP2 A1,A0
|
|
SWAP4 A0,A0
|
|
SWAP4 A1,A1
|
|
||[!BSZ]BNOP _KeccakF1600_cheat
|
|
||[!BSZ]STDW LEN:INP,*SP[3]
|
|
|| DEAL A0,A0
|
|
.else
|
|
[!BSZ]BNOP _KeccakF1600_cheat
|
|
||[!BSZ]STDW LEN:INP,*SP[3]
|
|
|| DEAL A0,A0
|
|
.endif
|
|
[BSZ] LDNDW *INP++,A1:A0
|
|
|| DEAL A1,A1
|
|
[BSZ] SUB LEN,8,LEN
|
|
||[BSZ] SUB BSZ,1,BSZ
|
|
PACK2 A1,A0,A0
|
|
|| PACKH2 A1,A0,A1
|
|
XOR A0,A$A[$y][$x],A$A[$y][$x]
|
|
XOR A1,B$A[$y][$x],B$A[$y][$x]
|
|
___
|
|
}
|
|
}
|
|
$code.=<<___;
|
|
.if .BIG_ENDIAN
|
|
SWAP2 A0,A1
|
|
|| SWAP2 A1,A0
|
|
SWAP4 A0,A0
|
|
SWAP4 A1,A1
|
|
.endif
|
|
BNOP _KeccakF1600_cheat
|
|
|| STDW LEN:INP,*SP[3]
|
|
|| DEAL A0,A0
|
|
DEAL A1,A1
|
|
NOP
|
|
PACK2 A1,A0,A0
|
|
|| PACKH2 A1,A0,A1
|
|
XOR A0,A$A[4][4],A$A[4][4]
|
|
XOR A1,B$A[4][4],B$A[4][4]
|
|
|
|
.align 16
|
|
ret?:
|
|
MV LEN,A4 ; return value
|
|
|| ADD 4,A2,B2
|
|
|
|
STW A$A[0][0],*A2++[2] ; store A[5][5]
|
|
|| STW B$A[0][0],*B2++[2]
|
|
STW A$A[0][1],*A2++[2]
|
|
|| STW B$A[0][1],*B2++[2]
|
|
STW A$A[0][2],*A2++[2]
|
|
|| STW B$A[0][2],*B2++[2]
|
|
STW A$A[0][3],*A2++[2]
|
|
|| STW B$A[0][3],*B2++[2]
|
|
STW A$A[0][4],*A2++[2]
|
|
|| STW B$A[0][4],*B2++[2]
|
|
|
|
STW A$A[1][0],*A2++[2]
|
|
|| STW B$A[1][0],*B2++[2]
|
|
STW A$A[1][1],*A2++[2]
|
|
|| STW B$A[1][1],*B2++[2]
|
|
STW A$A[1][2],*A2++[2]
|
|
|| STW B$A[1][2],*B2++[2]
|
|
STW A$A[1][3],*A2++[2]
|
|
|| STW B$A[1][3],*B2++[2]
|
|
STW A$A[1][4],*A2++[2]
|
|
|| STW B$A[1][4],*B2++[2]
|
|
|
|
STW A$A[2][0],*A2++[2]
|
|
|| STW B$A[2][0],*B2++[2]
|
|
STW A$A[2][1],*A2++[2]
|
|
|| STW B$A[2][1],*B2++[2]
|
|
STW A$A[2][2],*A2++[2]
|
|
|| STW B$A[2][2],*B2++[2]
|
|
STW A$A[2][3],*A2++[2]
|
|
|| STW B$A[2][3],*B2++[2]
|
|
STW A$A[2][4],*A2++[2]
|
|
|| STW B$A[2][4],*B2++[2]
|
|
|
|
LDW *SP[15],RA
|
|
|| LDW *FP[-6],A14
|
|
|
|
STW A$A[3][0],*A2++[2]
|
|
|| STW B$A[3][0],*B2++[2]
|
|
STW A$A[3][1],*A2++[2]
|
|
|| STW B$A[3][1],*B2++[2]
|
|
STW A$A[3][2],*A2++[2]
|
|
|| STW B$A[3][2],*B2++[2]
|
|
STW A$A[3][3],*A2++[2]
|
|
|| STW B$A[3][3],*B2++[2]
|
|
STW A$A[3][4],*A2++[2]
|
|
|| STW B$A[3][4],*B2++[2]
|
|
|
|
LDDW *SP[8], B11:B10
|
|
|| LDDW *FP[-5],A11:A10
|
|
LDDW *SP[9], B13:B12
|
|
|| LDDW *FP[-4],A13:A12
|
|
BNOP RA
|
|
|| LDW *++SP(80),FP ; restore frame pointer
|
|
|
|
STW A$A[4][0],*A2++[2]
|
|
|| STW B$A[4][0],*B2++[2]
|
|
STW A$A[4][1],*A2++[2]
|
|
|| STW B$A[4][1],*B2++[2]
|
|
STW A$A[4][2],*A2++[2]
|
|
|| STW B$A[4][2],*B2++[2]
|
|
STW A$A[4][3],*A2++[2]
|
|
|| STW B$A[4][3],*B2++[2]
|
|
STW A$A[4][4],*A2++[2]
|
|
|| STW B$A[4][4],*B2++[2]
|
|
.endasmfunc
|
|
|
|
.newblock
|
|
.global _SHA3_squeeze
|
|
.asg A12,OUT
|
|
.asg A13,LEN
|
|
.asg A14,BSZ
|
|
.align 32
|
|
_SHA3_squeeze:
|
|
.asmfunc stack_usage(24)
|
|
STW FP,*SP--(24) ; save frame pointer
|
|
|| MV SP,FP
|
|
STW RA, *SP[5]
|
|
|| STW A14,*FP[-2]
|
|
STDW A13:A12,*FP[-2]
|
|
|| MV B4,OUT ; reassign arguments
|
|
MV A6,LEN
|
|
|| MV B6,BSZ
|
|
|
|
loop?:
|
|
LDW *SP[5],RA ; reload RA
|
|
|| SHRU BSZ,3,A1
|
|
|| MV A4,A8
|
|
|| ADD 4,A4,B8
|
|
block?:
|
|
CMPLTU LEN,8,A0 ; len < 8?
|
|
[A0] BNOP tail?
|
|
LDW *A8++[2],A9
|
|
|| LDW *B8++[2],B9
|
|
|| SUB LEN,8,LEN ; len -= 8
|
|
MV LEN,A0
|
|
|| SUB A1,1,A1 ; bsz--
|
|
|| NOP 4
|
|
.if .BIG_ENDIAN
|
|
SWAP4 A9,A9
|
|
|| SWAP4 B9,B9
|
|
SWAP2 A9,A9
|
|
|| SWAP2 B9,B9
|
|
.endif
|
|
[!A0] BNOP ret?
|
|
||[!A0] ZERO A1
|
|
PACK2 B9,A9,B7
|
|
||[A1] BNOP block?
|
|
PACKH2 B9,A9,B9
|
|
|| SHFL B7,B7
|
|
SHFL B9,B9
|
|
STNW B7,*OUT++
|
|
STNW B9,*OUT++
|
|
NOP
|
|
|
|
BNOP _KeccakF1600,4
|
|
ADDKPC loop?,RA
|
|
|
|
.align 16
|
|
tail?:
|
|
.if .BIG_ENDIAN
|
|
SWAP4 A9,A9
|
|
|| SWAP4 B9,B9
|
|
SWAP2 A9,A9
|
|
|| SWAP2 B9,B9
|
|
.endif
|
|
PACK2 B9,A9,B7
|
|
PACKH2 B9,A9,B9
|
|
|| SHFL B7,B7
|
|
SHFL B9,B9
|
|
|
|
STB B7,*OUT++
|
|
|| SHRU B7,8,B7
|
|
|| ADD LEN,7,A0
|
|
[A0] STB B7,*OUT++
|
|
||[A0] SHRU B7,8,B7
|
|
||[A0] SUB A0,1,A0
|
|
[A0] STB B7,*OUT++
|
|
||[A0] SHRU B7,8,B7
|
|
||[A0] SUB A0,1,A0
|
|
[A0] STB B7,*OUT++
|
|
||[A0] SUB A0,1,A0
|
|
[A0] STB B9,*OUT++
|
|
||[A0] SHRU B9,8,B9
|
|
||[A0] SUB A0,1,A0
|
|
[A0] STB B9,*OUT++
|
|
||[A0] SHRU B9,8,B9
|
|
||[A0] SUB A0,1,A0
|
|
[A0] STB B9,*OUT++
|
|
|
|
ret?:
|
|
LDDW *FP[-2],A13:A12
|
|
BNOP RA
|
|
|| LDW *FP[-2],A14
|
|
LDW *++SP(24),FP ; restore frame pointer
|
|
NOP 4 ; wait till FP is committed
|
|
.endasmfunc
|
|
|
|
.if __TI_EABI__
|
|
.sect ".text:sha_asm.const"
|
|
.else
|
|
.sect ".const:sha_asm"
|
|
.endif
|
|
.align 256
|
|
.uword 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
|
iotas:
|
|
.uword 0x00000001, 0x00000000
|
|
.uword 0x00000000, 0x00000089
|
|
.uword 0x00000000, 0x8000008b
|
|
.uword 0x00000000, 0x80008080
|
|
.uword 0x00000001, 0x0000008b
|
|
.uword 0x00000001, 0x00008000
|
|
.uword 0x00000001, 0x80008088
|
|
.uword 0x00000001, 0x80000082
|
|
.uword 0x00000000, 0x0000000b
|
|
.uword 0x00000000, 0x0000000a
|
|
.uword 0x00000001, 0x00008082
|
|
.uword 0x00000000, 0x00008003
|
|
.uword 0x00000001, 0x0000808b
|
|
.uword 0x00000001, 0x8000000b
|
|
.uword 0x00000001, 0x8000008a
|
|
.uword 0x00000001, 0x80000081
|
|
.uword 0x00000000, 0x80000081
|
|
.uword 0x00000000, 0x80000008
|
|
.uword 0x00000000, 0x00000083
|
|
.uword 0x00000000, 0x80008003
|
|
.uword 0x00000001, 0x80008088
|
|
.uword 0x00000000, 0x80000088
|
|
.uword 0x00000001, 0x00008000
|
|
.uword 0x00000000, 0x80008082
|
|
|
|
.cstring "Keccak-1600 absorb and squeeze for C64x, CRYPTOGAMS by <appro\@openssl.org>"
|
|
.align 4
|
|
___
|
|
|
|
$output=pop;
|
|
open STDOUT,">$output";
|
|
print $code;
|
|
close STDOUT or die "error closing STDOUT: $!";
|