]>
git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/poly1305/asm/poly1305-ppc.pl
2 # Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
4 # Licensed under the OpenSSL license (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
10 # ====================================================================
11 # Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
12 # project. The module is, however, dual licensed under OpenSSL and
13 # CRYPTOGAMS licenses depending on where you obtain it. For further
14 # details see http://www.openssl.org/~appro/cryptogams/.
15 # ====================================================================
17 # This module implements Poly1305 hash for PowerPC.
21 # Numbers are cycles per processed byte with poly1305_blocks alone,
22 # and improvement coefficients relative to gcc-generated code.
26 # Freescale e300 14.8/+80% -
28 # PPC970 7.00/+114% 3.51/+205%
29 # POWER7 3.75/+260% 1.93/+100%
33 # Do we need floating-point implementation for PPC? Results presented
34 # in poly1305_ieee754.c are tricky to compare to, because they are for
35 # compiler-generated code. On the other hand it's known that floating-
36 # point performance can be dominated by FPU latency, which means that
37 # there is limit even for ideally optimized (and even vectorized) code.
38 # And this limit is estimated to be higher than above -m64 results. Or
39 # in other words floating-point implementation can be meaningful to
40 # consider only in 32-bit application context. We probably have to
41 # recognize that 32-bit builds are getting less popular on high-end
42 # systems and therefore tend to target embedded ones, which might not
45 # On side note, Power ISA 2.07 enables vector base 2^26 implementation,
46 # and POWER8 might have capacity to break 1.0 cycle per byte barrier...
50 if ($flavour =~ /64/) {
57 } elsif ($flavour =~ /32/) {
64 } else { die "nonsense $flavour"; }
66 # Define endianness based on flavour
68 $LITTLE_ENDIAN = ($flavour=~/le$/) ?
$SIZE_T : 0;
70 $0 =~ m/(.*[\/\\])[^\
/\\]+$/; $dir=$1;
71 ( $xlate="${dir}ppc-xlate.pl" and -f
$xlate ) or
72 ( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f
$xlate) or
73 die "can't locate ppc-xlate.pl";
75 open STDOUT
,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!";
80 my ($ctx,$inp,$len,$padbit) = map("r$_",(3..6));
81 my ($mac,$nonce)=($inp,$len);
88 if ($flavour =~ /64/) {
89 ###############################################################################
90 # base 2^64 implementation
92 my ($h0,$h1,$h2,$d0,$d1,$d2, $r0,$r1,$s1, $t0,$t1) = map("r$_",(7..12,27..31));
95 .globl
.poly1305_init_int
99 std r0
,0($ctx) # zero hash value
106 $code.=<<___
if ($LITTLE_ENDIAN);
107 ld
$d0,0($inp) # load key material
110 $code.=<<___
if (!$LITTLE_ENDIAN);
112 lwbrx
$d0,0,$inp # load key material
122 lis
$h1,0xfff # 0x0fff0000
123 ori
$h1,$h1,0xfffc # 0x0ffffffc
124 insrdi
$h1,$h1,32,0 # 0x0ffffffc0ffffffc
125 ori
$h0,$h1,3 # 0x0ffffffc0fffffff
130 std
$d0,32($ctx) # store key
137 .byte
0,12,0x14,0,0,0,2,0
138 .size
.poly1305_init_int
,.-.poly1305_init_int
140 .globl
.poly1305_blocks
146 $STU $sp,-$FRAME($sp)
148 $PUSH r27
,`$FRAME-$SIZE_T*5`($sp)
149 $PUSH r28
,`$FRAME-$SIZE_T*4`($sp)
150 $PUSH r29
,`$FRAME-$SIZE_T*3`($sp)
151 $PUSH r30
,`$FRAME-$SIZE_T*2`($sp)
152 $PUSH r31
,`$FRAME-$SIZE_T*1`($sp)
153 $PUSH r0
,`$FRAME+$LRSAVE`($sp)
155 ld
$r0,32($ctx) # load key
158 ld
$h0,0($ctx) # load hash value
164 add
$s1,$s1,$r1 # s1 = r1 + r1>>2
171 $code.=<<___
if ($LITTLE_ENDIAN);
172 ld
$t0,0($inp) # load input
175 $code.=<<___
if (!$LITTLE_ENDIAN);
177 lwbrx
$t0,0,$inp # load input
189 addc
$h0,$h0,$t0 # accumulate input
192 mulld
$d0,$h0,$r0 # h0*r0
196 mulld
$t0,$h1,$s1 # h1*5*r1
201 mulld
$t0,$h0,$r1 # h0*r1
206 mulld
$t0,$h1,$r0 # h1*r0
211 mulld
$t0,$h2,$s1 # h2*5*r1
212 mulld
$t1,$h2,$r0 # h2*r0
216 andc
$t0,$d2,$mask # final reduction step
226 std
$h0,0($ctx) # store hash value
230 $POP r27
,`$FRAME-$SIZE_T*5`($sp)
231 $POP r28
,`$FRAME-$SIZE_T*4`($sp)
232 $POP r29
,`$FRAME-$SIZE_T*3`($sp)
233 $POP r30
,`$FRAME-$SIZE_T*2`($sp)
234 $POP r31
,`$FRAME-$SIZE_T*1`($sp)
239 .byte
0,12,4,1,0x80,5,4,0
240 .size
.poly1305_blocks
,.-.poly1305_blocks
242 .globl
.poly1305_emit
245 ld
$h0,0($ctx) # load hash
248 ld
$padbit,0($nonce) # load nonce
251 addic
$d0,$h0,5 # compare to modulus
255 srdi
$mask,$d2,2 # did it carry/borrow?
265 $code.=<<___
if (!$LITTLE_ENDIAN);
266 rotldi
$padbit,$padbit,32 # flip nonce words
267 rotldi
$nonce,$nonce,32
270 addc
$h0,$h0,$padbit # accumulate nonce
273 $code.=<<___
if ($LITTLE_ENDIAN);
274 std
$h0,0($mac) # write result
277 $code.=<<___
if (!$LITTLE_ENDIAN);
280 stwbrx
$h0,0,$mac # write result
291 .byte
0,12,0x14,0,0,0,3,0
292 .size
.poly1305_emit
,.-.poly1305_emit
295 ###############################################################################
296 # base 2^32 implementation
298 my ($h0,$h1,$h2,$h3,$h4, $r0,$r1,$r2,$r3, $s1,$s2,$s3,
299 $t0,$t1,$t2,$t3, $D0,$D1,$D2,$D3, $d0,$d1,$d2,$d3
300 ) = map("r$_",(7..12,14..31));
303 .globl
.poly1305_init_int
307 stw r0
,0($ctx) # zero hash value
316 $code.=<<___
if ($LITTLE_ENDIAN);
317 lw
$h0,0($inp) # load key material
322 $code.=<<___
if (!$LITTLE_ENDIAN);
324 lwbrx
$h0,0,$inp # load key material
332 lis
$mask,0xf000 # 0xf0000000
334 andc
$r0,$r0,$mask # 0x0ffffffc
341 stw
$h0,32($ctx) # store key
350 .byte
0,12,0x14,0,0,0,2,0
351 .size
.poly1305_init_int
,.-.poly1305_init_int
353 .globl
.poly1305_blocks
359 $STU $sp,-$FRAME($sp)
361 $PUSH r14
,`$FRAME-$SIZE_T*18`($sp)
362 $PUSH r15
,`$FRAME-$SIZE_T*17`($sp)
363 $PUSH r16
,`$FRAME-$SIZE_T*16`($sp)
364 $PUSH r17
,`$FRAME-$SIZE_T*15`($sp)
365 $PUSH r18
,`$FRAME-$SIZE_T*14`($sp)
366 $PUSH r19
,`$FRAME-$SIZE_T*13`($sp)
367 $PUSH r20
,`$FRAME-$SIZE_T*12`($sp)
368 $PUSH r21
,`$FRAME-$SIZE_T*11`($sp)
369 $PUSH r22
,`$FRAME-$SIZE_T*10`($sp)
370 $PUSH r23
,`$FRAME-$SIZE_T*9`($sp)
371 $PUSH r24
,`$FRAME-$SIZE_T*8`($sp)
372 $PUSH r25
,`$FRAME-$SIZE_T*7`($sp)
373 $PUSH r26
,`$FRAME-$SIZE_T*6`($sp)
374 $PUSH r27
,`$FRAME-$SIZE_T*5`($sp)
375 $PUSH r28
,`$FRAME-$SIZE_T*4`($sp)
376 $PUSH r29
,`$FRAME-$SIZE_T*3`($sp)
377 $PUSH r30
,`$FRAME-$SIZE_T*2`($sp)
378 $PUSH r31
,`$FRAME-$SIZE_T*1`($sp)
379 $PUSH r0
,`$FRAME+$LRSAVE`($sp)
381 lwz
$r0,32($ctx) # load key
386 lwz
$h0,0($ctx) # load hash value
395 add
$s1,$s1,$r1 # si = ri + ri>>2
405 $code.=<<___
if ($LITTLE_ENDIAN);
406 lwz
$d0,0($inp) # load input
411 $code.=<<___
if (!$LITTLE_ENDIAN);
413 lwbrx
$d0,0,$inp # load input
423 addc
$h0,$h0,$d0 # accumulate input
427 mullw
$d0,$h0,$r0 # h0*r0
430 mullw
$d1,$h0,$r1 # h0*r1
433 mullw
$d2,$h0,$r2 # h0*r2
439 mullw
$d3,$h0,$r3 # h0*r3
442 mullw
$t0,$h1,$s3 # h1*s3
445 mullw
$t2,$h1,$r0 # h1*r0
450 mullw
$t0,$h1,$r1 # h1*r1
455 mullw
$t2,$h1,$r2 # h1*r2
460 mullw
$t0,$h2,$s2 # h2*s2
465 mullw
$t2,$h2,$s3 # h2*s3
470 mullw
$t0,$h2,$r0 # h2*r0
475 mullw
$t2,$h2,$r1 # h2*r1
480 mullw
$t0,$h3,$s1 # h3*s1
485 mullw
$t2,$h3,$s2 # h3*s2
490 mullw
$t0,$h3,$s3 # h3*s3
495 mullw
$t2,$h3,$r0 # h3*r0
500 mullw
$t0,$h4,$s1 # h4*s1
505 mullw
$t1,$h4,$s2 # h4*s2
510 mullw
$t2,$h4,$s3 # h4*s3
514 mullw
$h4,$h4,$r0 # h4*r0
521 andc
$D0,$h4,$mask # final reduction step
533 stw
$h0,0($ctx) # store hash value
539 $POP r14
,`$FRAME-$SIZE_T*18`($sp)
540 $POP r15
,`$FRAME-$SIZE_T*17`($sp)
541 $POP r16
,`$FRAME-$SIZE_T*16`($sp)
542 $POP r17
,`$FRAME-$SIZE_T*15`($sp)
543 $POP r18
,`$FRAME-$SIZE_T*14`($sp)
544 $POP r19
,`$FRAME-$SIZE_T*13`($sp)
545 $POP r20
,`$FRAME-$SIZE_T*12`($sp)
546 $POP r21
,`$FRAME-$SIZE_T*11`($sp)
547 $POP r22
,`$FRAME-$SIZE_T*10`($sp)
548 $POP r23
,`$FRAME-$SIZE_T*9`($sp)
549 $POP r24
,`$FRAME-$SIZE_T*8`($sp)
550 $POP r25
,`$FRAME-$SIZE_T*7`($sp)
551 $POP r26
,`$FRAME-$SIZE_T*6`($sp)
552 $POP r27
,`$FRAME-$SIZE_T*5`($sp)
553 $POP r28
,`$FRAME-$SIZE_T*4`($sp)
554 $POP r29
,`$FRAME-$SIZE_T*3`($sp)
555 $POP r30
,`$FRAME-$SIZE_T*2`($sp)
556 $POP r31
,`$FRAME-$SIZE_T*1`($sp)
561 .byte
0,12,4,1,0x80,18,4,0
562 .size
.poly1305_blocks
,.-.poly1305_blocks
564 .globl
.poly1305_emit
567 $STU $sp,-$FRAME($sp)
569 $PUSH r28
,`$FRAME-$SIZE_T*4`($sp)
570 $PUSH r29
,`$FRAME-$SIZE_T*3`($sp)
571 $PUSH r30
,`$FRAME-$SIZE_T*2`($sp)
572 $PUSH r31
,`$FRAME-$SIZE_T*1`($sp)
573 $PUSH r0
,`$FRAME+$LRSAVE`($sp)
575 lwz
$h0,0($ctx) # load hash
581 addic
$d0,$h0,5 # compare to modulus
587 srwi
$mask,$mask,2 # did it carry/borrow?
595 lwz
$d0,0($nonce) # load nonce
607 addc
$h0,$h0,$d0 # accumulate nonce
612 $code.=<<___
if ($LITTLE_ENDIAN);
613 stw
$h0,0($mac) # write result
618 $code.=<<___
if (!$LITTLE_ENDIAN);
620 stwbrx
$h0,0,$mac # write result
628 $POP r28
,`$FRAME-$SIZE_T*4`($sp)
629 $POP r29
,`$FRAME-$SIZE_T*3`($sp)
630 $POP r30
,`$FRAME-$SIZE_T*2`($sp)
631 $POP r31
,`$FRAME-$SIZE_T*1`($sp)
635 .byte
0,12,4,1,0x80,4,3,0
636 .size
.poly1305_emit
,.-.poly1305_emit
640 .asciz
"Poly1305 for PPC, CRYPTOGAMS by <appro\@openssl.org>"
643 $code =~ s/\`([^\`]*)\`/eval $1/gem;