123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854 |
- #!/usr/bin/env perl
- # Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.
- #
- # Licensed under the Apache License 2.0 (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/.
- # ====================================================================
- #
- # Keccak-1600 for PowerISA 2.07.
- #
- # June 2017.
- #
- # This is straightforward KECCAK_1X_ALT SIMD implementation, but with
- # disjoint Rho and Pi. The module is ABI-bitness- and endian-neutral.
- # POWER8 processor spends 9.8 cycles to process byte out of large
- # buffer for r=1088, which matches SHA3-256. This is 17% better than
- # scalar PPC64 code. It probably should be noted that if POWER8's
- # successor can achieve higher scalar instruction issue rate, then
- # this module will loose... And it does on POWER9 with 12.0 vs. 9.4.
- # $output is the last argument if it looks like a file (it has an extension)
- # $flavour is the first argument if it doesn't look like a file
- $output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef;
- $flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef;
- if ($flavour =~ /64/) {
- $SIZE_T =8;
- $LRSAVE =2*$SIZE_T;
- $UCMP ="cmpld";
- $STU ="stdu";
- $POP ="ld";
- $PUSH ="std";
- } elsif ($flavour =~ /32/) {
- $SIZE_T =4;
- $LRSAVE =$SIZE_T;
- $STU ="stwu";
- $POP ="lwz";
- $PUSH ="stw";
- $UCMP ="cmplw";
- } else { die "nonsense $flavour"; }
- $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
- ( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
- ( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or
- die "can't locate ppc-xlate.pl";
- open STDOUT,"| $^X $xlate $flavour \"$output\""
- or die "can't call $xlate: $!";
- $FRAME=6*$SIZE_T+13*16; # 13*16 is for v20-v31 offload
- my $sp ="r1";
- my $iotas = "r12";
- ########################################################################
- # Register layout:
- #
- # v0 A[0][0] A[1][0]
- # v1 A[0][1] A[1][1]
- # v2 A[0][2] A[1][2]
- # v3 A[0][3] A[1][3]
- # v4 A[0][4] A[1][4]
- #
- # v5 A[2][0] A[3][0]
- # v6 A[2][1] A[3][1]
- # v7 A[2][2] A[3][2]
- # v8 A[2][3] A[3][3]
- # v9 A[2][4] A[3][4]
- #
- # v10 A[4][0] A[4][1]
- # v11 A[4][2] A[4][3]
- # v12 A[4][4] A[4][4]
- #
- # v13..25 rhotates[][]
- # v26..31 volatile
- #
- $code.=<<___;
- .machine "any"
- .text
- .type KeccakF1600_int,\@function
- .align 5
- KeccakF1600_int:
- li r0,24
- mtctr r0
- li r0,0
- b .Loop
- .align 4
- .Loop:
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Theta
- vxor v26,v0, v5 ; A[0..1][0]^A[2..3][0]
- vxor v27,v1, v6 ; A[0..1][1]^A[2..3][1]
- vxor v28,v2, v7 ; A[0..1][2]^A[2..3][2]
- vxor v29,v3, v8 ; A[0..1][3]^A[2..3][3]
- vxor v30,v4, v9 ; A[0..1][4]^A[2..3][4]
- vpermdi v31,v26,v27,0b00 ; A[0][0..1]^A[2][0..1]
- vpermdi v26,v26,v27,0b11 ; A[1][0..1]^A[3][0..1]
- vpermdi v27,v28,v29,0b00 ; A[0][2..3]^A[2][2..3]
- vpermdi v28,v28,v29,0b11 ; A[1][2..3]^A[3][2..3]
- vpermdi v29,v30,v30,0b10 ; A[1..0][4]^A[3..2][4]
- vxor v26,v26,v31 ; C[0..1]
- vxor v27,v27,v28 ; C[2..3]
- vxor v28,v29,v30 ; C[4..4]
- vspltisb v31,1
- vxor v26,v26,v10 ; C[0..1] ^= A[4][0..1]
- vxor v27,v27,v11 ; C[2..3] ^= A[4][2..3]
- vxor v28,v28,v12 ; C[4..4] ^= A[4][4..4], low!
- vrld v29,v26,v31 ; ROL64(C[0..1],1)
- vrld v30,v27,v31 ; ROL64(C[2..3],1)
- vrld v31,v28,v31 ; ROL64(C[4..4],1)
- vpermdi v31,v31,v29,0b10
- vxor v26,v26,v30 ; C[0..1] ^= ROL64(C[2..3],1)
- vxor v27,v27,v31 ; C[2..3] ^= ROL64(C[4..0],1)
- vxor v28,v28,v29 ; C[4..4] ^= ROL64(C[0..1],1), low!
- vpermdi v29,v26,v26,0b00 ; C[0..0]
- vpermdi v30,v28,v26,0b10 ; C[4..0]
- vpermdi v31,v28,v28,0b11 ; C[4..4]
- vxor v1, v1, v29 ; A[0..1][1] ^= C[0..0]
- vxor v6, v6, v29 ; A[2..3][1] ^= C[0..0]
- vxor v10,v10,v30 ; A[4][0..1] ^= C[4..0]
- vxor v0, v0, v31 ; A[0..1][0] ^= C[4..4]
- vxor v5, v5, v31 ; A[2..3][0] ^= C[4..4]
- vpermdi v29,v27,v27,0b00 ; C[2..2]
- vpermdi v30,v26,v26,0b11 ; C[1..1]
- vpermdi v31,v26,v27,0b10 ; C[1..2]
- vxor v3, v3, v29 ; A[0..1][3] ^= C[2..2]
- vxor v8, v8, v29 ; A[2..3][3] ^= C[2..2]
- vxor v2, v2, v30 ; A[0..1][2] ^= C[1..1]
- vxor v7, v7, v30 ; A[2..3][2] ^= C[1..1]
- vxor v11,v11,v31 ; A[4][2..3] ^= C[1..2]
- vpermdi v29,v27,v27,0b11 ; C[3..3]
- vxor v4, v4, v29 ; A[0..1][4] ^= C[3..3]
- vxor v9, v9, v29 ; A[2..3][4] ^= C[3..3]
- vxor v12,v12,v29 ; A[4..4][4] ^= C[3..3]
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Rho
- vrld v26,v0, v13 ; v0
- vrld v1, v1, v14
- vrld v27,v2, v15 ; v2
- vrld v28,v3, v16 ; v3
- vrld v4, v4, v17
- vrld v5, v5, v18
- vrld v6, v6, v19
- vrld v29,v7, v20 ; v7
- vrld v8, v8, v21
- vrld v9, v9, v22
- vrld v10,v10,v23
- vrld v30,v11,v24 ; v11
- vrld v12,v12,v25
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Pi
- vpermdi v0, v26,v28,0b00 ; [0][0] [1][0] < [0][0] [0][3]
- vpermdi v2, v29,v5, 0b00 ; [0][2] [1][2] < [2][2] [2][0]
- vpermdi v11,v9, v5, 0b01 ; [4][2] [4][3] < [2][4] [3][0]
- vpermdi v5, v1, v4, 0b00 ; [2][0] [3][0] < [0][1] [0][4]
- vpermdi v1, v1, v4, 0b11 ; [0][1] [1][1] < [1][1] [1][4]
- vpermdi v3, v8, v6, 0b11 ; [0][3] [1][3] < [3][3] [3][1]
- vpermdi v4, v12,v30,0b10 ; [0][4] [1][4] < [4][4] [4][2]
- vpermdi v7, v8, v6, 0b00 ; [2][2] [3][2] < [2][3] [2][1]
- vpermdi v6, v27,v26,0b11 ; [2][1] [3][1] < [1][2] [1][0]
- vpermdi v8, v9, v29,0b11 ; [2][3] [3][3] < [3][4] [3][2]
- vpermdi v12,v10,v10,0b11 ; [4][4] [4][4] < [4][1] [4][1]
- vpermdi v9, v10,v30,0b01 ; [2][4] [3][4] < [4][0] [4][3]
- vpermdi v10,v27,v28,0b01 ; [4][0] [4][1] < [0][2] [1][3]
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Chi + Iota
- lvx_u v31,$iotas,r0 ; iotas[index]
- addic r0,r0,16 ; index++
- vandc v26,v2, v1 ; (~A[0..1][1] & A[0..1][2])
- vandc v27,v3, v2 ; (~A[0..1][2] & A[0..1][3])
- vandc v28,v4, v3 ; (~A[0..1][3] & A[0..1][4])
- vandc v29,v0, v4 ; (~A[0..1][4] & A[0..1][0])
- vandc v30,v1, v0 ; (~A[0..1][0] & A[0..1][1])
- vxor v0, v0, v26 ; A[0..1][0] ^= (~A[0..1][1] & A[0..1][2])
- vxor v1, v1, v27 ; A[0..1][1] ^= (~A[0..1][2] & A[0..1][3])
- vxor v2, v2, v28 ; A[0..1][2] ^= (~A[0..1][3] & A[0..1][4])
- vxor v3, v3, v29 ; A[0..1][3] ^= (~A[0..1][4] & A[0..1][0])
- vxor v4, v4, v30 ; A[0..1][4] ^= (~A[0..1][0] & A[0..1][1])
- vandc v26,v7, v6 ; (~A[2..3][1] & A[2..3][2])
- vandc v27,v8, v7 ; (~A[2..3][2] & A[2..3][3])
- vandc v28,v9, v8 ; (~A[2..3][3] & A[2..3][4])
- vandc v29,v5, v9 ; (~A[2..3][4] & A[2..3][0])
- vandc v30,v6, v5 ; (~A[2..3][0] & A[2..3][1])
- vxor v5, v5, v26 ; A[2..3][0] ^= (~A[2..3][1] & A[2..3][2])
- vxor v6, v6, v27 ; A[2..3][1] ^= (~A[2..3][2] & A[2..3][3])
- vxor v7, v7, v28 ; A[2..3][2] ^= (~A[2..3][3] & A[2..3][4])
- vxor v8, v8, v29 ; A[2..3][3] ^= (~A[2..3][4] & A[2..3][0])
- vxor v9, v9, v30 ; A[2..3][4] ^= (~A[2..3][0] & A[2..3][1])
- vxor v0, v0, v31 ; A[0][0] ^= iotas[index++]
- vpermdi v26,v10,v11,0b10 ; A[4][1..2]
- vpermdi v27,v12,v10,0b00 ; A[4][4..0]
- vpermdi v28,v11,v12,0b10 ; A[4][3..4]
- vpermdi v29,v10,v10,0b10 ; A[4][1..0]
- vandc v26,v11,v26 ; (~A[4][1..2] & A[4][2..3])
- vandc v27,v27,v28 ; (~A[4][3..4] & A[4][4..0])
- vandc v28,v10,v29 ; (~A[4][1..0] & A[4][0..1])
- vxor v10,v10,v26 ; A[4][0..1] ^= (~A[4][1..2] & A[4][2..3])
- vxor v11,v11,v27 ; A[4][2..3] ^= (~A[4][3..4] & A[4][4..0])
- vxor v12,v12,v28 ; A[4][4..4] ^= (~A[4][0..1] & A[4][1..0])
- bdnz .Loop
- vpermdi v12,v12,v12,0b11 ; broadcast A[4][4]
- blr
- .long 0
- .byte 0,12,0x14,0,0,0,0,0
- .size KeccakF1600_int,.-KeccakF1600_int
- .type KeccakF1600,\@function
- .align 5
- KeccakF1600:
- $STU $sp,-$FRAME($sp)
- li r10,`15+6*$SIZE_T`
- li r11,`31+6*$SIZE_T`
- mflr r8
- mfspr r7, 256 ; save vrsave
- stvx v20,r10,$sp
- addi r10,r10,32
- stvx v21,r11,$sp
- addi r11,r11,32
- stvx v22,r10,$sp
- addi r10,r10,32
- stvx v23,r11,$sp
- addi r11,r11,32
- stvx v24,r10,$sp
- addi r10,r10,32
- stvx v25,r11,$sp
- addi r11,r11,32
- stvx v26,r10,$sp
- addi r10,r10,32
- stvx v27,r11,$sp
- addi r11,r11,32
- stvx v28,r10,$sp
- addi r10,r10,32
- stvx v29,r11,$sp
- addi r11,r11,32
- stvx v30,r10,$sp
- stvx v31,r11,$sp
- stw r7,`$FRAME-4`($sp) ; save vrsave
- li r0, -1
- $PUSH r8,`$FRAME+$LRSAVE`($sp)
- mtspr 256, r0 ; preserve all AltiVec registers
- li r11,16
- lvx_4w v0,0,r3 ; load A[5][5]
- li r10,32
- lvx_4w v1,r11,r3
- addi r11,r11,32
- lvx_4w v2,r10,r3
- addi r10,r10,32
- lvx_4w v3,r11,r3
- addi r11,r11,32
- lvx_4w v4,r10,r3
- addi r10,r10,32
- lvx_4w v5,r11,r3
- addi r11,r11,32
- lvx_4w v6,r10,r3
- addi r10,r10,32
- lvx_4w v7,r11,r3
- addi r11,r11,32
- lvx_4w v8,r10,r3
- addi r10,r10,32
- lvx_4w v9,r11,r3
- addi r11,r11,32
- lvx_4w v10,r10,r3
- addi r10,r10,32
- lvx_4w v11,r11,r3
- lvx_splt v12,r10,r3
- bl PICmeup
- li r11,16
- lvx_u v13,0,r12 ; load rhotates
- li r10,32
- lvx_u v14,r11,r12
- addi r11,r11,32
- lvx_u v15,r10,r12
- addi r10,r10,32
- lvx_u v16,r11,r12
- addi r11,r11,32
- lvx_u v17,r10,r12
- addi r10,r10,32
- lvx_u v18,r11,r12
- addi r11,r11,32
- lvx_u v19,r10,r12
- addi r10,r10,32
- lvx_u v20,r11,r12
- addi r11,r11,32
- lvx_u v21,r10,r12
- addi r10,r10,32
- lvx_u v22,r11,r12
- addi r11,r11,32
- lvx_u v23,r10,r12
- addi r10,r10,32
- lvx_u v24,r11,r12
- lvx_u v25,r10,r12
- addi r12,r12,`16*16` ; points at iotas
- bl KeccakF1600_int
- li r11,16
- stvx_4w v0,0,r3 ; return A[5][5]
- li r10,32
- stvx_4w v1,r11,r3
- addi r11,r11,32
- stvx_4w v2,r10,r3
- addi r10,r10,32
- stvx_4w v3,r11,r3
- addi r11,r11,32
- stvx_4w v4,r10,r3
- addi r10,r10,32
- stvx_4w v5,r11,r3
- addi r11,r11,32
- stvx_4w v6,r10,r3
- addi r10,r10,32
- stvx_4w v7,r11,r3
- addi r11,r11,32
- stvx_4w v8,r10,r3
- addi r10,r10,32
- stvx_4w v9,r11,r3
- addi r11,r11,32
- stvx_4w v10,r10,r3
- addi r10,r10,32
- stvx_4w v11,r11,r3
- stvdx_u v12,r10,r3
- li r10,`15+6*$SIZE_T`
- li r11,`31+6*$SIZE_T`
- mtlr r8
- mtspr 256, r7 ; restore vrsave
- lvx v20,r10,$sp
- addi r10,r10,32
- lvx v21,r11,$sp
- addi r11,r11,32
- lvx v22,r10,$sp
- addi r10,r10,32
- lvx v23,r11,$sp
- addi r11,r11,32
- lvx v24,r10,$sp
- addi r10,r10,32
- lvx v25,r11,$sp
- addi r11,r11,32
- lvx v26,r10,$sp
- addi r10,r10,32
- lvx v27,r11,$sp
- addi r11,r11,32
- lvx v28,r10,$sp
- addi r10,r10,32
- lvx v29,r11,$sp
- addi r11,r11,32
- lvx v30,r10,$sp
- lvx v31,r11,$sp
- addi $sp,$sp,$FRAME
- blr
- .long 0
- .byte 0,12,0x04,1,0x80,0,1,0
- .long 0
- .size KeccakF1600,.-KeccakF1600
- ___
- {
- my ($A_jagged,$inp,$len,$bsz) = map("r$_",(3..6));
- $code.=<<___;
- .globl SHA3_absorb
- .type SHA3_absorb,\@function
- .align 5
- SHA3_absorb:
- $STU $sp,-$FRAME($sp)
- li r10,`15+6*$SIZE_T`
- li r11,`31+6*$SIZE_T`
- mflr r8
- mfspr r7, 256 ; save vrsave
- stvx v20,r10,$sp
- addi r10,r10,32
- stvx v21,r11,$sp
- addi r11,r11,32
- stvx v22,r10,$sp
- addi r10,r10,32
- stvx v23,r11,$sp
- addi r11,r11,32
- stvx v24,r10,$sp
- addi r10,r10,32
- stvx v25,r11,$sp
- addi r11,r11,32
- stvx v26,r10,$sp
- addi r10,r10,32
- stvx v27,r11,$sp
- addi r11,r11,32
- stvx v28,r10,$sp
- addi r10,r10,32
- stvx v29,r11,$sp
- addi r11,r11,32
- stvx v30,r10,$sp
- stvx v31,r11,$sp
- stw r7,`$FRAME-4`($sp) ; save vrsave
- li r0, -1
- $PUSH r8,`$FRAME+$LRSAVE`($sp)
- mtspr 256, r0 ; preserve all AltiVec registers
- li r11,16
- lvx_4w v0,0,$A_jagged ; load A[5][5]
- li r10,32
- lvx_4w v1,r11,$A_jagged
- addi r11,r11,32
- lvx_4w v2,r10,$A_jagged
- addi r10,r10,32
- lvx_4w v3,r11,$A_jagged
- addi r11,r11,32
- lvx_4w v4,r10,$A_jagged
- addi r10,r10,32
- lvx_4w v5,r11,$A_jagged
- addi r11,r11,32
- lvx_4w v6,r10,$A_jagged
- addi r10,r10,32
- lvx_4w v7,r11,$A_jagged
- addi r11,r11,32
- lvx_4w v8,r10,$A_jagged
- addi r10,r10,32
- lvx_4w v9,r11,$A_jagged
- addi r11,r11,32
- lvx_4w v10,r10,$A_jagged
- addi r10,r10,32
- lvx_4w v11,r11,$A_jagged
- lvx_splt v12,r10,$A_jagged
- bl PICmeup
- li r11,16
- lvx_u v13,0,r12 ; load rhotates
- li r10,32
- lvx_u v14,r11,r12
- addi r11,r11,32
- lvx_u v15,r10,r12
- addi r10,r10,32
- lvx_u v16,r11,r12
- addi r11,r11,32
- lvx_u v17,r10,r12
- addi r10,r10,32
- lvx_u v18,r11,r12
- addi r11,r11,32
- lvx_u v19,r10,r12
- addi r10,r10,32
- lvx_u v20,r11,r12
- addi r11,r11,32
- lvx_u v21,r10,r12
- addi r10,r10,32
- lvx_u v22,r11,r12
- addi r11,r11,32
- lvx_u v23,r10,r12
- addi r10,r10,32
- lvx_u v24,r11,r12
- lvx_u v25,r10,r12
- li r10,-32
- li r11,-16
- addi r12,r12,`16*16` ; points at iotas
- b .Loop_absorb
- .align 4
- .Loop_absorb:
- $UCMP $len,$bsz ; len < bsz?
- blt .Labsorbed
- sub $len,$len,$bsz ; len -= bsz
- srwi r0,$bsz,3
- mtctr r0
- lvx_u v30,r10,r12 ; permutation masks
- lvx_u v31,r11,r12
- ?vspltisb v27,7 ; prepare masks for byte swap
- ?vxor v30,v30,v27 ; on big-endian
- ?vxor v31,v31,v27
- vxor v27,v27,v27 ; zero
- lvdx_u v26,0,$inp
- addi $inp,$inp,8
- vperm v26,v26,v27,v30
- vxor v0, v0, v26
- bdz .Lprocess_block
- lvdx_u v26,0,$inp
- addi $inp,$inp,8
- vperm v26,v26,v27,v30
- vxor v1, v1, v26
- bdz .Lprocess_block
- lvdx_u v26,0,$inp
- addi $inp,$inp,8
- vperm v26,v26,v27,v30
- vxor v2, v2, v26
- bdz .Lprocess_block
- lvdx_u v26,0,$inp
- addi $inp,$inp,8
- vperm v26,v26,v27,v30
- vxor v3, v3, v26
- bdz .Lprocess_block
- lvdx_u v26,0,$inp
- addi $inp,$inp,8
- vperm v26,v26,v27,v30
- vxor v4, v4, v26
- bdz .Lprocess_block
- lvdx_u v26,0,$inp
- addi $inp,$inp,8
- vperm v26,v26,v27,v31
- vxor v0, v0, v26
- bdz .Lprocess_block
- lvdx_u v26,0,$inp
- addi $inp,$inp,8
- vperm v26,v26,v27,v31
- vxor v1, v1, v26
- bdz .Lprocess_block
- lvdx_u v26,0,$inp
- addi $inp,$inp,8
- vperm v26,v26,v27,v31
- vxor v2, v2, v26
- bdz .Lprocess_block
- lvdx_u v26,0,$inp
- addi $inp,$inp,8
- vperm v26,v26,v27,v31
- vxor v3, v3, v26
- bdz .Lprocess_block
- lvdx_u v26,0,$inp
- addi $inp,$inp,8
- vperm v26,v26,v27,v31
- vxor v4, v4, v26
- bdz .Lprocess_block
- lvdx_u v26,0,$inp
- addi $inp,$inp,8
- vperm v26,v26,v27,v30
- vxor v5, v5, v26
- bdz .Lprocess_block
- lvdx_u v26,0,$inp
- addi $inp,$inp,8
- vperm v26,v26,v27,v30
- vxor v6, v6, v26
- bdz .Lprocess_block
- lvdx_u v26,0,$inp
- addi $inp,$inp,8
- vperm v26,v26,v27,v30
- vxor v7, v7, v26
- bdz .Lprocess_block
- lvdx_u v26,0,$inp
- addi $inp,$inp,8
- vperm v26,v26,v27,v30
- vxor v8, v8, v26
- bdz .Lprocess_block
- lvdx_u v26,0,$inp
- addi $inp,$inp,8
- vperm v26,v26,v27,v30
- vxor v9, v9, v26
- bdz .Lprocess_block
- lvdx_u v26,0,$inp
- addi $inp,$inp,8
- vperm v26,v26,v27,v31
- vxor v5, v5, v26
- bdz .Lprocess_block
- lvdx_u v26,0,$inp
- addi $inp,$inp,8
- vperm v26,v26,v27,v31
- vxor v6, v6, v26
- bdz .Lprocess_block
- lvdx_u v26,0,$inp
- addi $inp,$inp,8
- vperm v26,v26,v27,v31
- vxor v7, v7, v26
- bdz .Lprocess_block
- lvdx_u v26,0,$inp
- addi $inp,$inp,8
- vperm v26,v26,v27,v31
- vxor v8, v8, v26
- bdz .Lprocess_block
- lvdx_u v26,0,$inp
- addi $inp,$inp,8
- vperm v26,v26,v27,v31
- vxor v9, v9, v26
- bdz .Lprocess_block
- lvdx_u v26,0,$inp
- addi $inp,$inp,8
- vperm v26,v26,v27,v30
- vxor v10, v10, v26
- bdz .Lprocess_block
- lvdx_u v26,0,$inp
- addi $inp,$inp,8
- vperm v26,v26,v27,v31
- vxor v10, v10, v26
- bdz .Lprocess_block
- lvdx_u v26,0,$inp
- addi $inp,$inp,8
- vperm v26,v26,v27,v30
- vxor v11, v11, v26
- bdz .Lprocess_block
- lvdx_u v26,0,$inp
- addi $inp,$inp,8
- vperm v26,v26,v27,v31
- vxor v11, v11, v26
- bdz .Lprocess_block
- lvdx_u v26,0,$inp
- addi $inp,$inp,8
- vperm v26,v26,v27,v31
- vxor v12, v12, v26
- .Lprocess_block:
- bl KeccakF1600_int
- b .Loop_absorb
- .align 4
- .Labsorbed:
- li r11,16
- stvx_4w v0,0,$A_jagged ; return A[5][5]
- li r10,32
- stvx_4w v1,r11,$A_jagged
- addi r11,r11,32
- stvx_4w v2,r10,$A_jagged
- addi r10,r10,32
- stvx_4w v3,r11,$A_jagged
- addi r11,r11,32
- stvx_4w v4,r10,$A_jagged
- addi r10,r10,32
- stvx_4w v5,r11,$A_jagged
- addi r11,r11,32
- stvx_4w v6,r10,$A_jagged
- addi r10,r10,32
- stvx_4w v7,r11,$A_jagged
- addi r11,r11,32
- stvx_4w v8,r10,$A_jagged
- addi r10,r10,32
- stvx_4w v9,r11,$A_jagged
- addi r11,r11,32
- stvx_4w v10,r10,$A_jagged
- addi r10,r10,32
- stvx_4w v11,r11,$A_jagged
- stvdx_u v12,r10,$A_jagged
- mr r3,$len ; return value
- li r10,`15+6*$SIZE_T`
- li r11,`31+6*$SIZE_T`
- mtlr r8
- mtspr 256, r7 ; restore vrsave
- lvx v20,r10,$sp
- addi r10,r10,32
- lvx v21,r11,$sp
- addi r11,r11,32
- lvx v22,r10,$sp
- addi r10,r10,32
- lvx v23,r11,$sp
- addi r11,r11,32
- lvx v24,r10,$sp
- addi r10,r10,32
- lvx v25,r11,$sp
- addi r11,r11,32
- lvx v26,r10,$sp
- addi r10,r10,32
- lvx v27,r11,$sp
- addi r11,r11,32
- lvx v28,r10,$sp
- addi r10,r10,32
- lvx v29,r11,$sp
- addi r11,r11,32
- lvx v30,r10,$sp
- lvx v31,r11,$sp
- addi $sp,$sp,$FRAME
- blr
- .long 0
- .byte 0,12,0x04,1,0x80,0,4,0
- .long 0
- .size SHA3_absorb,.-SHA3_absorb
- ___
- }
- {
- my ($A_jagged,$out,$len,$bsz) = map("r$_",(3..6));
- $code.=<<___;
- .globl SHA3_squeeze
- .type SHA3_squeeze,\@function
- .align 5
- SHA3_squeeze:
- mflr r9 ; r9 is not touched by KeccakF1600
- subi $out,$out,1 ; prepare for stbu
- addi r8,$A_jagged,4 ; prepare volatiles
- mr r10,$bsz
- li r11,0
- b .Loop_squeeze
- .align 4
- .Loop_squeeze:
- lwzx r7,r11,r8 ; lo
- lwzx r0,r11,$A_jagged ; hi
- ${UCMP}i $len,8
- blt .Lsqueeze_tail
- stbu r7,1($out) ; write lo
- srwi r7,r7,8
- stbu r7,1($out)
- srwi r7,r7,8
- stbu r7,1($out)
- srwi r7,r7,8
- stbu r7,1($out)
- stbu r0,1($out) ; write hi
- srwi r0,r0,8
- stbu r0,1($out)
- srwi r0,r0,8
- stbu r0,1($out)
- srwi r0,r0,8
- stbu r0,1($out)
- subic. $len,$len,8
- beqlr ; return if done
- subic. r10,r10,8
- ble .Loutput_expand
- addi r11,r11,16 ; calculate jagged index
- cmplwi r11,`16*5`
- blt .Loop_squeeze
- subi r11,r11,72
- beq .Loop_squeeze
- addi r11,r11,72
- cmplwi r11,`16*5+8`
- subi r11,r11,8
- beq .Loop_squeeze
- addi r11,r11,8
- cmplwi r11,`16*10`
- subi r11,r11,72
- beq .Loop_squeeze
- addi r11,r11,72
- blt .Loop_squeeze
- subi r11,r11,8
- b .Loop_squeeze
- .align 4
- .Loutput_expand:
- bl KeccakF1600
- mtlr r9
- addi r8,$A_jagged,4 ; restore volatiles
- mr r10,$bsz
- li r11,0
- b .Loop_squeeze
- .align 4
- .Lsqueeze_tail:
- mtctr $len
- subic. $len,$len,4
- ble .Loop_tail_lo
- li r8,4
- mtctr r8
- .Loop_tail_lo:
- stbu r7,1($out)
- srdi r7,r7,8
- bdnz .Loop_tail_lo
- ble .Lsqueeze_done
- mtctr $len
- .Loop_tail_hi:
- stbu r0,1($out)
- srdi r0,r0,8
- bdnz .Loop_tail_hi
- .Lsqueeze_done:
- blr
- .long 0
- .byte 0,12,0x14,0,0,0,4,0
- .long 0
- .size SHA3_squeeze,.-SHA3_squeeze
- ___
- }
- $code.=<<___;
- .align 6
- PICmeup:
- mflr r0
- bcl 20,31,\$+4
- mflr r12 ; vvvvvv "distance" between . and 1st data entry
- addi r12,r12,`64-8`
- mtlr r0
- blr
- .long 0
- .byte 0,12,0x14,0,0,0,0,0
- .space `64-9*4`
- .type rhotates,\@object
- .align 6
- rhotates:
- .quad 0, 36
- .quad 1, 44
- .quad 62, 6
- .quad 28, 55
- .quad 27, 20
- .quad 3, 41
- .quad 10, 45
- .quad 43, 15
- .quad 25, 21
- .quad 39, 8
- .quad 18, 2
- .quad 61, 56
- .quad 14, 14
- .size rhotates,.-rhotates
- .quad 0,0
- .quad 0x0001020304050607,0x1011121314151617
- .quad 0x1011121314151617,0x0001020304050607
- .type iotas,\@object
- iotas:
- .quad 0x0000000000000001,0
- .quad 0x0000000000008082,0
- .quad 0x800000000000808a,0
- .quad 0x8000000080008000,0
- .quad 0x000000000000808b,0
- .quad 0x0000000080000001,0
- .quad 0x8000000080008081,0
- .quad 0x8000000000008009,0
- .quad 0x000000000000008a,0
- .quad 0x0000000000000088,0
- .quad 0x0000000080008009,0
- .quad 0x000000008000000a,0
- .quad 0x000000008000808b,0
- .quad 0x800000000000008b,0
- .quad 0x8000000000008089,0
- .quad 0x8000000000008003,0
- .quad 0x8000000000008002,0
- .quad 0x8000000000000080,0
- .quad 0x000000000000800a,0
- .quad 0x800000008000000a,0
- .quad 0x8000000080008081,0
- .quad 0x8000000000008080,0
- .quad 0x0000000080000001,0
- .quad 0x8000000080008008,0
- .size iotas,.-iotas
- .asciz "Keccak-1600 absorb and squeeze for PowerISA 2.07, CRYPTOGAMS by <appro\@openssl.org>"
- ___
- foreach (split("\n",$code)) {
- s/\`([^\`]*)\`/eval $1/ge;
- if ($flavour =~ /le$/) { # little-endian
- s/\?([a-z]+)/;$1/;
- } else { # big-endian
- s/\?([a-z]+)/$1/;
- }
- print $_,"\n";
- }
- close STDOUT;
|