1e71b7053SJung-uk Kim#! /usr/bin/env perl 217f01e99SJung-uk Kim# Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved. 3e71b7053SJung-uk Kim# 4*b077aed3SPierre Pronchery# Licensed under the Apache License 2.0 (the "License"). You may not use 5e71b7053SJung-uk Kim# this file except in compliance with the License. You can obtain a copy 6e71b7053SJung-uk Kim# in the file LICENSE in the source distribution or at 7e71b7053SJung-uk Kim# https://www.openssl.org/source/license.html 8e71b7053SJung-uk Kim 9e71b7053SJung-uk Kim# 10e71b7053SJung-uk Kim# ==================================================================== 11e71b7053SJung-uk Kim# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL 12e71b7053SJung-uk Kim# project. The module is, however, dual licensed under OpenSSL and 13e71b7053SJung-uk Kim# CRYPTOGAMS licenses depending on where you obtain it. For further 14e71b7053SJung-uk Kim# details see http://www.openssl.org/~appro/cryptogams/. 15e71b7053SJung-uk Kim# ==================================================================== 16e71b7053SJung-uk Kim# 17e71b7053SJung-uk Kim# ECP_NISTZ256 module for PPC64. 18e71b7053SJung-uk Kim# 19e71b7053SJung-uk Kim# August 2016. 20e71b7053SJung-uk Kim# 21e71b7053SJung-uk Kim# Original ECP_NISTZ256 submission targeting x86_64 is detailed in 22e71b7053SJung-uk Kim# http://eprint.iacr.org/2013/816. 23e71b7053SJung-uk Kim# 24e71b7053SJung-uk Kim# with/without -DECP_NISTZ256_ASM 25e71b7053SJung-uk Kim# POWER7 +260-530% 26e71b7053SJung-uk Kim# POWER8 +220-340% 27e71b7053SJung-uk Kim 28*b077aed3SPierre Pronchery# $output is the last argument if it looks like a file (it has an extension) 29*b077aed3SPierre Pronchery# $flavour is the first argument if it doesn't look like a file 30*b077aed3SPierre Pronchery$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; 31*b077aed3SPierre Pronchery$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; 32e71b7053SJung-uk Kim 33e71b7053SJung-uk Kim$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; 34e71b7053SJung-uk Kim( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or 35e71b7053SJung-uk Kim( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or 36e71b7053SJung-uk Kimdie "can't locate ppc-xlate.pl"; 37e71b7053SJung-uk Kim 38*b077aed3SPierre Proncheryopen OUT,"| \"$^X\" $xlate $flavour \"$output\"" 39*b077aed3SPierre Pronchery or die "can't call $xlate: $!"; 40e71b7053SJung-uk Kim*STDOUT=*OUT; 41e71b7053SJung-uk Kim 42e71b7053SJung-uk Kimmy $sp="r1"; 43e71b7053SJung-uk Kim 44e71b7053SJung-uk Kim{ 45e71b7053SJung-uk Kimmy ($rp,$ap,$bp,$bi,$acc0,$acc1,$acc2,$acc3,$poly1,$poly3, 46e71b7053SJung-uk Kim $acc4,$acc5,$a0,$a1,$a2,$a3,$t0,$t1,$t2,$t3) = 47e71b7053SJung-uk Kim map("r$_",(3..12,22..31)); 48e71b7053SJung-uk Kim 49e71b7053SJung-uk Kimmy ($acc6,$acc7)=($bp,$bi); # used in __ecp_nistz256_sqr_mont 50e71b7053SJung-uk Kim 51e71b7053SJung-uk Kim$code.=<<___; 52e71b7053SJung-uk Kim.machine "any" 53e71b7053SJung-uk Kim.text 54e71b7053SJung-uk Kim___ 55e71b7053SJung-uk Kim######################################################################## 56e71b7053SJung-uk Kim# Convert ecp_nistz256_table.c to layout expected by ecp_nistz_gather_w7 57e71b7053SJung-uk Kim# 58e71b7053SJung-uk Kim$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; 59e71b7053SJung-uk Kimopen TABLE,"<ecp_nistz256_table.c" or 60e71b7053SJung-uk Kimopen TABLE,"<${dir}../ecp_nistz256_table.c" or 61e71b7053SJung-uk Kimdie "failed to open ecp_nistz256_table.c:",$!; 62e71b7053SJung-uk Kim 63e71b7053SJung-uk Kimuse integer; 64e71b7053SJung-uk Kim 65e71b7053SJung-uk Kimforeach(<TABLE>) { 66e71b7053SJung-uk Kim s/TOBN\(\s*(0x[0-9a-f]+),\s*(0x[0-9a-f]+)\s*\)/push @arr,hex($2),hex($1)/geo; 67e71b7053SJung-uk Kim} 68e71b7053SJung-uk Kimclose TABLE; 69e71b7053SJung-uk Kim 70e71b7053SJung-uk Kim# See ecp_nistz256_table.c for explanation for why it's 64*16*37. 71e71b7053SJung-uk Kim# 64*16*37-1 is because $#arr returns last valid index or @arr, not 72e71b7053SJung-uk Kim# amount of elements. 73e71b7053SJung-uk Kimdie "insane number of elements" if ($#arr != 64*16*37-1); 74e71b7053SJung-uk Kim 75e71b7053SJung-uk Kim$code.=<<___; 76e71b7053SJung-uk Kim.type ecp_nistz256_precomputed,\@object 77e71b7053SJung-uk Kim.globl ecp_nistz256_precomputed 78e71b7053SJung-uk Kim.align 12 79e71b7053SJung-uk Kimecp_nistz256_precomputed: 80e71b7053SJung-uk Kim___ 81e71b7053SJung-uk Kim######################################################################## 82e71b7053SJung-uk Kim# this conversion smashes P256_POINT_AFFINE by individual bytes with 83e71b7053SJung-uk Kim# 64 byte interval, similar to 84e71b7053SJung-uk Kim# 1111222233334444 85e71b7053SJung-uk Kim# 1234123412341234 86e71b7053SJung-uk Kimfor(1..37) { 87e71b7053SJung-uk Kim @tbl = splice(@arr,0,64*16); 88e71b7053SJung-uk Kim for($i=0;$i<64;$i++) { 89e71b7053SJung-uk Kim undef @line; 90e71b7053SJung-uk Kim for($j=0;$j<64;$j++) { 91e71b7053SJung-uk Kim push @line,(@tbl[$j*16+$i/4]>>(($i%4)*8))&0xff; 92e71b7053SJung-uk Kim } 93e71b7053SJung-uk Kim $code.=".byte\t"; 94e71b7053SJung-uk Kim $code.=join(',',map { sprintf "0x%02x",$_} @line); 95e71b7053SJung-uk Kim $code.="\n"; 96e71b7053SJung-uk Kim } 97e71b7053SJung-uk Kim} 98e71b7053SJung-uk Kim 99e71b7053SJung-uk Kim$code.=<<___; 100e71b7053SJung-uk Kim.size ecp_nistz256_precomputed,.-ecp_nistz256_precomputed 101e71b7053SJung-uk Kim.asciz "ECP_NISTZ256 for PPC64, CRYPTOGAMS by <appro\@openssl.org>" 102e71b7053SJung-uk Kim 103e71b7053SJung-uk Kim# void ecp_nistz256_mul_mont(BN_ULONG x0[4],const BN_ULONG x1[4], 104e71b7053SJung-uk Kim# const BN_ULONG x2[4]); 105e71b7053SJung-uk Kim.globl ecp_nistz256_mul_mont 106e71b7053SJung-uk Kim.align 5 107e71b7053SJung-uk Kimecp_nistz256_mul_mont: 108e71b7053SJung-uk Kim stdu $sp,-128($sp) 109e71b7053SJung-uk Kim mflr r0 110e71b7053SJung-uk Kim std r22,48($sp) 111e71b7053SJung-uk Kim std r23,56($sp) 112e71b7053SJung-uk Kim std r24,64($sp) 113e71b7053SJung-uk Kim std r25,72($sp) 114e71b7053SJung-uk Kim std r26,80($sp) 115e71b7053SJung-uk Kim std r27,88($sp) 116e71b7053SJung-uk Kim std r28,96($sp) 117e71b7053SJung-uk Kim std r29,104($sp) 118e71b7053SJung-uk Kim std r30,112($sp) 119e71b7053SJung-uk Kim std r31,120($sp) 120e71b7053SJung-uk Kim 121e71b7053SJung-uk Kim ld $a0,0($ap) 122e71b7053SJung-uk Kim ld $bi,0($bp) 123e71b7053SJung-uk Kim ld $a1,8($ap) 124e71b7053SJung-uk Kim ld $a2,16($ap) 125e71b7053SJung-uk Kim ld $a3,24($ap) 126e71b7053SJung-uk Kim 127e71b7053SJung-uk Kim li $poly1,-1 128e71b7053SJung-uk Kim srdi $poly1,$poly1,32 # 0x00000000ffffffff 129e71b7053SJung-uk Kim li $poly3,1 130e71b7053SJung-uk Kim orc $poly3,$poly3,$poly1 # 0xffffffff00000001 131e71b7053SJung-uk Kim 132e71b7053SJung-uk Kim bl __ecp_nistz256_mul_mont 133e71b7053SJung-uk Kim 134e71b7053SJung-uk Kim mtlr r0 135e71b7053SJung-uk Kim ld r22,48($sp) 136e71b7053SJung-uk Kim ld r23,56($sp) 137e71b7053SJung-uk Kim ld r24,64($sp) 138e71b7053SJung-uk Kim ld r25,72($sp) 139e71b7053SJung-uk Kim ld r26,80($sp) 140e71b7053SJung-uk Kim ld r27,88($sp) 141e71b7053SJung-uk Kim ld r28,96($sp) 142e71b7053SJung-uk Kim ld r29,104($sp) 143e71b7053SJung-uk Kim ld r30,112($sp) 144e71b7053SJung-uk Kim ld r31,120($sp) 145e71b7053SJung-uk Kim addi $sp,$sp,128 146e71b7053SJung-uk Kim blr 147e71b7053SJung-uk Kim .long 0 148e71b7053SJung-uk Kim .byte 0,12,4,0,0x80,10,3,0 149e71b7053SJung-uk Kim .long 0 150e71b7053SJung-uk Kim.size ecp_nistz256_mul_mont,.-ecp_nistz256_mul_mont 151e71b7053SJung-uk Kim 152e71b7053SJung-uk Kim# void ecp_nistz256_sqr_mont(BN_ULONG x0[4],const BN_ULONG x1[4]); 153e71b7053SJung-uk Kim.globl ecp_nistz256_sqr_mont 154e71b7053SJung-uk Kim.align 4 155e71b7053SJung-uk Kimecp_nistz256_sqr_mont: 156e71b7053SJung-uk Kim stdu $sp,-128($sp) 157e71b7053SJung-uk Kim mflr r0 158e71b7053SJung-uk Kim std r22,48($sp) 159e71b7053SJung-uk Kim std r23,56($sp) 160e71b7053SJung-uk Kim std r24,64($sp) 161e71b7053SJung-uk Kim std r25,72($sp) 162e71b7053SJung-uk Kim std r26,80($sp) 163e71b7053SJung-uk Kim std r27,88($sp) 164e71b7053SJung-uk Kim std r28,96($sp) 165e71b7053SJung-uk Kim std r29,104($sp) 166e71b7053SJung-uk Kim std r30,112($sp) 167e71b7053SJung-uk Kim std r31,120($sp) 168e71b7053SJung-uk Kim 169e71b7053SJung-uk Kim ld $a0,0($ap) 170e71b7053SJung-uk Kim ld $a1,8($ap) 171e71b7053SJung-uk Kim ld $a2,16($ap) 172e71b7053SJung-uk Kim ld $a3,24($ap) 173e71b7053SJung-uk Kim 174e71b7053SJung-uk Kim li $poly1,-1 175e71b7053SJung-uk Kim srdi $poly1,$poly1,32 # 0x00000000ffffffff 176e71b7053SJung-uk Kim li $poly3,1 177e71b7053SJung-uk Kim orc $poly3,$poly3,$poly1 # 0xffffffff00000001 178e71b7053SJung-uk Kim 179e71b7053SJung-uk Kim bl __ecp_nistz256_sqr_mont 180e71b7053SJung-uk Kim 181e71b7053SJung-uk Kim mtlr r0 182e71b7053SJung-uk Kim ld r22,48($sp) 183e71b7053SJung-uk Kim ld r23,56($sp) 184e71b7053SJung-uk Kim ld r24,64($sp) 185e71b7053SJung-uk Kim ld r25,72($sp) 186e71b7053SJung-uk Kim ld r26,80($sp) 187e71b7053SJung-uk Kim ld r27,88($sp) 188e71b7053SJung-uk Kim ld r28,96($sp) 189e71b7053SJung-uk Kim ld r29,104($sp) 190e71b7053SJung-uk Kim ld r30,112($sp) 191e71b7053SJung-uk Kim ld r31,120($sp) 192e71b7053SJung-uk Kim addi $sp,$sp,128 193e71b7053SJung-uk Kim blr 194e71b7053SJung-uk Kim .long 0 195e71b7053SJung-uk Kim .byte 0,12,4,0,0x80,10,2,0 196e71b7053SJung-uk Kim .long 0 197e71b7053SJung-uk Kim.size ecp_nistz256_sqr_mont,.-ecp_nistz256_sqr_mont 198e71b7053SJung-uk Kim 199e71b7053SJung-uk Kim# void ecp_nistz256_add(BN_ULONG x0[4],const BN_ULONG x1[4], 200e71b7053SJung-uk Kim# const BN_ULONG x2[4]); 201e71b7053SJung-uk Kim.globl ecp_nistz256_add 202e71b7053SJung-uk Kim.align 4 203e71b7053SJung-uk Kimecp_nistz256_add: 204e71b7053SJung-uk Kim stdu $sp,-128($sp) 205e71b7053SJung-uk Kim mflr r0 206e71b7053SJung-uk Kim std r28,96($sp) 207e71b7053SJung-uk Kim std r29,104($sp) 208e71b7053SJung-uk Kim std r30,112($sp) 209e71b7053SJung-uk Kim std r31,120($sp) 210e71b7053SJung-uk Kim 211e71b7053SJung-uk Kim ld $acc0,0($ap) 212e71b7053SJung-uk Kim ld $t0, 0($bp) 213e71b7053SJung-uk Kim ld $acc1,8($ap) 214e71b7053SJung-uk Kim ld $t1, 8($bp) 215e71b7053SJung-uk Kim ld $acc2,16($ap) 216e71b7053SJung-uk Kim ld $t2, 16($bp) 217e71b7053SJung-uk Kim ld $acc3,24($ap) 218e71b7053SJung-uk Kim ld $t3, 24($bp) 219e71b7053SJung-uk Kim 220e71b7053SJung-uk Kim li $poly1,-1 221e71b7053SJung-uk Kim srdi $poly1,$poly1,32 # 0x00000000ffffffff 222e71b7053SJung-uk Kim li $poly3,1 223e71b7053SJung-uk Kim orc $poly3,$poly3,$poly1 # 0xffffffff00000001 224e71b7053SJung-uk Kim 225e71b7053SJung-uk Kim bl __ecp_nistz256_add 226e71b7053SJung-uk Kim 227e71b7053SJung-uk Kim mtlr r0 228e71b7053SJung-uk Kim ld r28,96($sp) 229e71b7053SJung-uk Kim ld r29,104($sp) 230e71b7053SJung-uk Kim ld r30,112($sp) 231e71b7053SJung-uk Kim ld r31,120($sp) 232e71b7053SJung-uk Kim addi $sp,$sp,128 233e71b7053SJung-uk Kim blr 234e71b7053SJung-uk Kim .long 0 235e71b7053SJung-uk Kim .byte 0,12,4,0,0x80,4,3,0 236e71b7053SJung-uk Kim .long 0 237e71b7053SJung-uk Kim.size ecp_nistz256_add,.-ecp_nistz256_add 238e71b7053SJung-uk Kim 239e71b7053SJung-uk Kim# void ecp_nistz256_div_by_2(BN_ULONG x0[4],const BN_ULONG x1[4]); 240e71b7053SJung-uk Kim.globl ecp_nistz256_div_by_2 241e71b7053SJung-uk Kim.align 4 242e71b7053SJung-uk Kimecp_nistz256_div_by_2: 243e71b7053SJung-uk Kim stdu $sp,-128($sp) 244e71b7053SJung-uk Kim mflr r0 245e71b7053SJung-uk Kim std r28,96($sp) 246e71b7053SJung-uk Kim std r29,104($sp) 247e71b7053SJung-uk Kim std r30,112($sp) 248e71b7053SJung-uk Kim std r31,120($sp) 249e71b7053SJung-uk Kim 250e71b7053SJung-uk Kim ld $acc0,0($ap) 251e71b7053SJung-uk Kim ld $acc1,8($ap) 252e71b7053SJung-uk Kim ld $acc2,16($ap) 253e71b7053SJung-uk Kim ld $acc3,24($ap) 254e71b7053SJung-uk Kim 255e71b7053SJung-uk Kim li $poly1,-1 256e71b7053SJung-uk Kim srdi $poly1,$poly1,32 # 0x00000000ffffffff 257e71b7053SJung-uk Kim li $poly3,1 258e71b7053SJung-uk Kim orc $poly3,$poly3,$poly1 # 0xffffffff00000001 259e71b7053SJung-uk Kim 260e71b7053SJung-uk Kim bl __ecp_nistz256_div_by_2 261e71b7053SJung-uk Kim 262e71b7053SJung-uk Kim mtlr r0 263e71b7053SJung-uk Kim ld r28,96($sp) 264e71b7053SJung-uk Kim ld r29,104($sp) 265e71b7053SJung-uk Kim ld r30,112($sp) 266e71b7053SJung-uk Kim ld r31,120($sp) 267e71b7053SJung-uk Kim addi $sp,$sp,128 268e71b7053SJung-uk Kim blr 269e71b7053SJung-uk Kim .long 0 270e71b7053SJung-uk Kim .byte 0,12,4,0,0x80,4,2,0 271e71b7053SJung-uk Kim .long 0 272e71b7053SJung-uk Kim.size ecp_nistz256_div_by_2,.-ecp_nistz256_div_by_2 273e71b7053SJung-uk Kim 274e71b7053SJung-uk Kim# void ecp_nistz256_mul_by_2(BN_ULONG x0[4],const BN_ULONG x1[4]); 275e71b7053SJung-uk Kim.globl ecp_nistz256_mul_by_2 276e71b7053SJung-uk Kim.align 4 277e71b7053SJung-uk Kimecp_nistz256_mul_by_2: 278e71b7053SJung-uk Kim stdu $sp,-128($sp) 279e71b7053SJung-uk Kim mflr r0 280e71b7053SJung-uk Kim std r28,96($sp) 281e71b7053SJung-uk Kim std r29,104($sp) 282e71b7053SJung-uk Kim std r30,112($sp) 283e71b7053SJung-uk Kim std r31,120($sp) 284e71b7053SJung-uk Kim 285e71b7053SJung-uk Kim ld $acc0,0($ap) 286e71b7053SJung-uk Kim ld $acc1,8($ap) 287e71b7053SJung-uk Kim ld $acc2,16($ap) 288e71b7053SJung-uk Kim ld $acc3,24($ap) 289e71b7053SJung-uk Kim 290e71b7053SJung-uk Kim mr $t0,$acc0 291e71b7053SJung-uk Kim mr $t1,$acc1 292e71b7053SJung-uk Kim mr $t2,$acc2 293e71b7053SJung-uk Kim mr $t3,$acc3 294e71b7053SJung-uk Kim 295e71b7053SJung-uk Kim li $poly1,-1 296e71b7053SJung-uk Kim srdi $poly1,$poly1,32 # 0x00000000ffffffff 297e71b7053SJung-uk Kim li $poly3,1 298e71b7053SJung-uk Kim orc $poly3,$poly3,$poly1 # 0xffffffff00000001 299e71b7053SJung-uk Kim 300e71b7053SJung-uk Kim bl __ecp_nistz256_add # ret = a+a // 2*a 301e71b7053SJung-uk Kim 302e71b7053SJung-uk Kim mtlr r0 303e71b7053SJung-uk Kim ld r28,96($sp) 304e71b7053SJung-uk Kim ld r29,104($sp) 305e71b7053SJung-uk Kim ld r30,112($sp) 306e71b7053SJung-uk Kim ld r31,120($sp) 307e71b7053SJung-uk Kim addi $sp,$sp,128 308e71b7053SJung-uk Kim blr 309e71b7053SJung-uk Kim .long 0 310e71b7053SJung-uk Kim .byte 0,12,4,0,0x80,4,3,0 311e71b7053SJung-uk Kim .long 0 312e71b7053SJung-uk Kim.size ecp_nistz256_mul_by_2,.-ecp_nistz256_mul_by_2 313e71b7053SJung-uk Kim 314e71b7053SJung-uk Kim# void ecp_nistz256_mul_by_3(BN_ULONG x0[4],const BN_ULONG x1[4]); 315e71b7053SJung-uk Kim.globl ecp_nistz256_mul_by_3 316e71b7053SJung-uk Kim.align 4 317e71b7053SJung-uk Kimecp_nistz256_mul_by_3: 318e71b7053SJung-uk Kim stdu $sp,-128($sp) 319e71b7053SJung-uk Kim mflr r0 320e71b7053SJung-uk Kim std r28,96($sp) 321e71b7053SJung-uk Kim std r29,104($sp) 322e71b7053SJung-uk Kim std r30,112($sp) 323e71b7053SJung-uk Kim std r31,120($sp) 324e71b7053SJung-uk Kim 325e71b7053SJung-uk Kim ld $acc0,0($ap) 326e71b7053SJung-uk Kim ld $acc1,8($ap) 327e71b7053SJung-uk Kim ld $acc2,16($ap) 328e71b7053SJung-uk Kim ld $acc3,24($ap) 329e71b7053SJung-uk Kim 330e71b7053SJung-uk Kim mr $t0,$acc0 331e71b7053SJung-uk Kim std $acc0,64($sp) 332e71b7053SJung-uk Kim mr $t1,$acc1 333e71b7053SJung-uk Kim std $acc1,72($sp) 334e71b7053SJung-uk Kim mr $t2,$acc2 335e71b7053SJung-uk Kim std $acc2,80($sp) 336e71b7053SJung-uk Kim mr $t3,$acc3 337e71b7053SJung-uk Kim std $acc3,88($sp) 338e71b7053SJung-uk Kim 339e71b7053SJung-uk Kim li $poly1,-1 340e71b7053SJung-uk Kim srdi $poly1,$poly1,32 # 0x00000000ffffffff 341e71b7053SJung-uk Kim li $poly3,1 342e71b7053SJung-uk Kim orc $poly3,$poly3,$poly1 # 0xffffffff00000001 343e71b7053SJung-uk Kim 344e71b7053SJung-uk Kim bl __ecp_nistz256_add # ret = a+a // 2*a 345e71b7053SJung-uk Kim 346e71b7053SJung-uk Kim ld $t0,64($sp) 347e71b7053SJung-uk Kim ld $t1,72($sp) 348e71b7053SJung-uk Kim ld $t2,80($sp) 349e71b7053SJung-uk Kim ld $t3,88($sp) 350e71b7053SJung-uk Kim 351e71b7053SJung-uk Kim bl __ecp_nistz256_add # ret += a // 2*a+a=3*a 352e71b7053SJung-uk Kim 353e71b7053SJung-uk Kim mtlr r0 354e71b7053SJung-uk Kim ld r28,96($sp) 355e71b7053SJung-uk Kim ld r29,104($sp) 356e71b7053SJung-uk Kim ld r30,112($sp) 357e71b7053SJung-uk Kim ld r31,120($sp) 358e71b7053SJung-uk Kim addi $sp,$sp,128 359e71b7053SJung-uk Kim blr 360e71b7053SJung-uk Kim .long 0 361e71b7053SJung-uk Kim .byte 0,12,4,0,0x80,4,2,0 362e71b7053SJung-uk Kim .long 0 363e71b7053SJung-uk Kim.size ecp_nistz256_mul_by_3,.-ecp_nistz256_mul_by_3 364e71b7053SJung-uk Kim 365e71b7053SJung-uk Kim# void ecp_nistz256_sub(BN_ULONG x0[4],const BN_ULONG x1[4], 366e71b7053SJung-uk Kim# const BN_ULONG x2[4]); 367e71b7053SJung-uk Kim.globl ecp_nistz256_sub 368e71b7053SJung-uk Kim.align 4 369e71b7053SJung-uk Kimecp_nistz256_sub: 370e71b7053SJung-uk Kim stdu $sp,-128($sp) 371e71b7053SJung-uk Kim mflr r0 372e71b7053SJung-uk Kim std r28,96($sp) 373e71b7053SJung-uk Kim std r29,104($sp) 374e71b7053SJung-uk Kim std r30,112($sp) 375e71b7053SJung-uk Kim std r31,120($sp) 376e71b7053SJung-uk Kim 377e71b7053SJung-uk Kim ld $acc0,0($ap) 378e71b7053SJung-uk Kim ld $acc1,8($ap) 379e71b7053SJung-uk Kim ld $acc2,16($ap) 380e71b7053SJung-uk Kim ld $acc3,24($ap) 381e71b7053SJung-uk Kim 382e71b7053SJung-uk Kim li $poly1,-1 383e71b7053SJung-uk Kim srdi $poly1,$poly1,32 # 0x00000000ffffffff 384e71b7053SJung-uk Kim li $poly3,1 385e71b7053SJung-uk Kim orc $poly3,$poly3,$poly1 # 0xffffffff00000001 386e71b7053SJung-uk Kim 387e71b7053SJung-uk Kim bl __ecp_nistz256_sub_from 388e71b7053SJung-uk Kim 389e71b7053SJung-uk Kim mtlr r0 390e71b7053SJung-uk Kim ld r28,96($sp) 391e71b7053SJung-uk Kim ld r29,104($sp) 392e71b7053SJung-uk Kim ld r30,112($sp) 393e71b7053SJung-uk Kim ld r31,120($sp) 394e71b7053SJung-uk Kim addi $sp,$sp,128 395e71b7053SJung-uk Kim blr 396e71b7053SJung-uk Kim .long 0 397e71b7053SJung-uk Kim .byte 0,12,4,0,0x80,4,3,0 398e71b7053SJung-uk Kim .long 0 399e71b7053SJung-uk Kim.size ecp_nistz256_sub,.-ecp_nistz256_sub 400e71b7053SJung-uk Kim 401e71b7053SJung-uk Kim# void ecp_nistz256_neg(BN_ULONG x0[4],const BN_ULONG x1[4]); 402e71b7053SJung-uk Kim.globl ecp_nistz256_neg 403e71b7053SJung-uk Kim.align 4 404e71b7053SJung-uk Kimecp_nistz256_neg: 405e71b7053SJung-uk Kim stdu $sp,-128($sp) 406e71b7053SJung-uk Kim mflr r0 407e71b7053SJung-uk Kim std r28,96($sp) 408e71b7053SJung-uk Kim std r29,104($sp) 409e71b7053SJung-uk Kim std r30,112($sp) 410e71b7053SJung-uk Kim std r31,120($sp) 411e71b7053SJung-uk Kim 412e71b7053SJung-uk Kim mr $bp,$ap 413e71b7053SJung-uk Kim li $acc0,0 414e71b7053SJung-uk Kim li $acc1,0 415e71b7053SJung-uk Kim li $acc2,0 416e71b7053SJung-uk Kim li $acc3,0 417e71b7053SJung-uk Kim 418e71b7053SJung-uk Kim li $poly1,-1 419e71b7053SJung-uk Kim srdi $poly1,$poly1,32 # 0x00000000ffffffff 420e71b7053SJung-uk Kim li $poly3,1 421e71b7053SJung-uk Kim orc $poly3,$poly3,$poly1 # 0xffffffff00000001 422e71b7053SJung-uk Kim 423e71b7053SJung-uk Kim bl __ecp_nistz256_sub_from 424e71b7053SJung-uk Kim 425e71b7053SJung-uk Kim mtlr r0 426e71b7053SJung-uk Kim ld r28,96($sp) 427e71b7053SJung-uk Kim ld r29,104($sp) 428e71b7053SJung-uk Kim ld r30,112($sp) 429e71b7053SJung-uk Kim ld r31,120($sp) 430e71b7053SJung-uk Kim addi $sp,$sp,128 431e71b7053SJung-uk Kim blr 432e71b7053SJung-uk Kim .long 0 433e71b7053SJung-uk Kim .byte 0,12,4,0,0x80,4,2,0 434e71b7053SJung-uk Kim .long 0 435e71b7053SJung-uk Kim.size ecp_nistz256_neg,.-ecp_nistz256_neg 436e71b7053SJung-uk Kim 437e71b7053SJung-uk Kim# note that __ecp_nistz256_mul_mont expects a[0-3] input pre-loaded 438e71b7053SJung-uk Kim# to $a0-$a3 and b[0] - to $bi 439e71b7053SJung-uk Kim.type __ecp_nistz256_mul_mont,\@function 440e71b7053SJung-uk Kim.align 4 441e71b7053SJung-uk Kim__ecp_nistz256_mul_mont: 442e71b7053SJung-uk Kim mulld $acc0,$a0,$bi # a[0]*b[0] 443e71b7053SJung-uk Kim mulhdu $t0,$a0,$bi 444e71b7053SJung-uk Kim 445e71b7053SJung-uk Kim mulld $acc1,$a1,$bi # a[1]*b[0] 446e71b7053SJung-uk Kim mulhdu $t1,$a1,$bi 447e71b7053SJung-uk Kim 448e71b7053SJung-uk Kim mulld $acc2,$a2,$bi # a[2]*b[0] 449e71b7053SJung-uk Kim mulhdu $t2,$a2,$bi 450e71b7053SJung-uk Kim 451e71b7053SJung-uk Kim mulld $acc3,$a3,$bi # a[3]*b[0] 452e71b7053SJung-uk Kim mulhdu $t3,$a3,$bi 453e71b7053SJung-uk Kim ld $bi,8($bp) # b[1] 454e71b7053SJung-uk Kim 455e71b7053SJung-uk Kim addc $acc1,$acc1,$t0 # accumulate high parts of multiplication 456e71b7053SJung-uk Kim sldi $t0,$acc0,32 457e71b7053SJung-uk Kim adde $acc2,$acc2,$t1 458e71b7053SJung-uk Kim srdi $t1,$acc0,32 459e71b7053SJung-uk Kim adde $acc3,$acc3,$t2 460e71b7053SJung-uk Kim addze $acc4,$t3 461e71b7053SJung-uk Kim li $acc5,0 462e71b7053SJung-uk Kim___ 463e71b7053SJung-uk Kimfor($i=1;$i<4;$i++) { 464e71b7053SJung-uk Kim ################################################################ 465e71b7053SJung-uk Kim # Reduction iteration is normally performed by accumulating 466e71b7053SJung-uk Kim # result of multiplication of modulus by "magic" digit [and 467e71b7053SJung-uk Kim # omitting least significant word, which is guaranteed to 468e71b7053SJung-uk Kim # be 0], but thanks to special form of modulus and "magic" 469e71b7053SJung-uk Kim # digit being equal to least significant word, it can be 470e71b7053SJung-uk Kim # performed with additions and subtractions alone. Indeed: 471e71b7053SJung-uk Kim # 472e71b7053SJung-uk Kim # ffff0001.00000000.0000ffff.ffffffff 473e71b7053SJung-uk Kim # * abcdefgh 474e71b7053SJung-uk Kim # + xxxxxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx.abcdefgh 475e71b7053SJung-uk Kim # 476e71b7053SJung-uk Kim # Now observing that ff..ff*x = (2^n-1)*x = 2^n*x-x, we 477e71b7053SJung-uk Kim # rewrite above as: 478e71b7053SJung-uk Kim # 479e71b7053SJung-uk Kim # xxxxxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx.abcdefgh 480e71b7053SJung-uk Kim # + abcdefgh.abcdefgh.0000abcd.efgh0000.00000000 481e71b7053SJung-uk Kim # - 0000abcd.efgh0000.00000000.00000000.abcdefgh 482e71b7053SJung-uk Kim # 483e71b7053SJung-uk Kim # or marking redundant operations: 484e71b7053SJung-uk Kim # 485e71b7053SJung-uk Kim # xxxxxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx.-------- 486e71b7053SJung-uk Kim # + abcdefgh.abcdefgh.0000abcd.efgh0000.-------- 487e71b7053SJung-uk Kim # - 0000abcd.efgh0000.--------.--------.-------- 488e71b7053SJung-uk Kim 489e71b7053SJung-uk Kim$code.=<<___; 490e71b7053SJung-uk Kim subfc $t2,$t0,$acc0 # "*0xffff0001" 491e71b7053SJung-uk Kim subfe $t3,$t1,$acc0 492e71b7053SJung-uk Kim addc $acc0,$acc1,$t0 # +=acc[0]<<96 and omit acc[0] 493e71b7053SJung-uk Kim adde $acc1,$acc2,$t1 494e71b7053SJung-uk Kim adde $acc2,$acc3,$t2 # +=acc[0]*0xffff0001 495e71b7053SJung-uk Kim adde $acc3,$acc4,$t3 496e71b7053SJung-uk Kim addze $acc4,$acc5 497e71b7053SJung-uk Kim 498e71b7053SJung-uk Kim mulld $t0,$a0,$bi # lo(a[0]*b[i]) 499e71b7053SJung-uk Kim mulld $t1,$a1,$bi # lo(a[1]*b[i]) 500e71b7053SJung-uk Kim mulld $t2,$a2,$bi # lo(a[2]*b[i]) 501e71b7053SJung-uk Kim mulld $t3,$a3,$bi # lo(a[3]*b[i]) 502e71b7053SJung-uk Kim addc $acc0,$acc0,$t0 # accumulate low parts of multiplication 503e71b7053SJung-uk Kim mulhdu $t0,$a0,$bi # hi(a[0]*b[i]) 504e71b7053SJung-uk Kim adde $acc1,$acc1,$t1 505e71b7053SJung-uk Kim mulhdu $t1,$a1,$bi # hi(a[1]*b[i]) 506e71b7053SJung-uk Kim adde $acc2,$acc2,$t2 507e71b7053SJung-uk Kim mulhdu $t2,$a2,$bi # hi(a[2]*b[i]) 508e71b7053SJung-uk Kim adde $acc3,$acc3,$t3 509e71b7053SJung-uk Kim mulhdu $t3,$a3,$bi # hi(a[3]*b[i]) 510e71b7053SJung-uk Kim addze $acc4,$acc4 511e71b7053SJung-uk Kim___ 512e71b7053SJung-uk Kim$code.=<<___ if ($i<3); 513e71b7053SJung-uk Kim ld $bi,8*($i+1)($bp) # b[$i+1] 514e71b7053SJung-uk Kim___ 515e71b7053SJung-uk Kim$code.=<<___; 516e71b7053SJung-uk Kim addc $acc1,$acc1,$t0 # accumulate high parts of multiplication 517e71b7053SJung-uk Kim sldi $t0,$acc0,32 518e71b7053SJung-uk Kim adde $acc2,$acc2,$t1 519e71b7053SJung-uk Kim srdi $t1,$acc0,32 520e71b7053SJung-uk Kim adde $acc3,$acc3,$t2 521e71b7053SJung-uk Kim adde $acc4,$acc4,$t3 522e71b7053SJung-uk Kim li $acc5,0 523e71b7053SJung-uk Kim addze $acc5,$acc5 524e71b7053SJung-uk Kim___ 525e71b7053SJung-uk Kim} 526e71b7053SJung-uk Kim$code.=<<___; 527e71b7053SJung-uk Kim # last reduction 528e71b7053SJung-uk Kim subfc $t2,$t0,$acc0 # "*0xffff0001" 529e71b7053SJung-uk Kim subfe $t3,$t1,$acc0 530e71b7053SJung-uk Kim addc $acc0,$acc1,$t0 # +=acc[0]<<96 and omit acc[0] 531e71b7053SJung-uk Kim adde $acc1,$acc2,$t1 532e71b7053SJung-uk Kim adde $acc2,$acc3,$t2 # +=acc[0]*0xffff0001 533e71b7053SJung-uk Kim adde $acc3,$acc4,$t3 534e71b7053SJung-uk Kim addze $acc4,$acc5 535e71b7053SJung-uk Kim 536e71b7053SJung-uk Kim li $t2,0 537e71b7053SJung-uk Kim addic $acc0,$acc0,1 # ret -= modulus 538e71b7053SJung-uk Kim subfe $acc1,$poly1,$acc1 539e71b7053SJung-uk Kim subfe $acc2,$t2,$acc2 540e71b7053SJung-uk Kim subfe $acc3,$poly3,$acc3 541e71b7053SJung-uk Kim subfe $acc4,$t2,$acc4 542e71b7053SJung-uk Kim 543e71b7053SJung-uk Kim addc $acc0,$acc0,$acc4 # ret += modulus if borrow 544e71b7053SJung-uk Kim and $t1,$poly1,$acc4 545e71b7053SJung-uk Kim and $t3,$poly3,$acc4 546e71b7053SJung-uk Kim adde $acc1,$acc1,$t1 547e71b7053SJung-uk Kim addze $acc2,$acc2 548e71b7053SJung-uk Kim adde $acc3,$acc3,$t3 549e71b7053SJung-uk Kim 550e71b7053SJung-uk Kim std $acc0,0($rp) 551e71b7053SJung-uk Kim std $acc1,8($rp) 552e71b7053SJung-uk Kim std $acc2,16($rp) 553e71b7053SJung-uk Kim std $acc3,24($rp) 554e71b7053SJung-uk Kim 555e71b7053SJung-uk Kim blr 556e71b7053SJung-uk Kim .long 0 557e71b7053SJung-uk Kim .byte 0,12,0x14,0,0,0,1,0 558e71b7053SJung-uk Kim .long 0 559e71b7053SJung-uk Kim.size __ecp_nistz256_mul_mont,.-__ecp_nistz256_mul_mont 560e71b7053SJung-uk Kim 561e71b7053SJung-uk Kim# note that __ecp_nistz256_sqr_mont expects a[0-3] input pre-loaded 562e71b7053SJung-uk Kim# to $a0-$a3 563e71b7053SJung-uk Kim.type __ecp_nistz256_sqr_mont,\@function 564e71b7053SJung-uk Kim.align 4 565e71b7053SJung-uk Kim__ecp_nistz256_sqr_mont: 566e71b7053SJung-uk Kim ################################################################ 567e71b7053SJung-uk Kim # | | | | | |a1*a0| | 568e71b7053SJung-uk Kim # | | | | |a2*a0| | | 569e71b7053SJung-uk Kim # | |a3*a2|a3*a0| | | | 570e71b7053SJung-uk Kim # | | | |a2*a1| | | | 571e71b7053SJung-uk Kim # | | |a3*a1| | | | | 572e71b7053SJung-uk Kim # *| | | | | | | | 2| 573e71b7053SJung-uk Kim # +|a3*a3|a2*a2|a1*a1|a0*a0| 574e71b7053SJung-uk Kim # |--+--+--+--+--+--+--+--| 575e71b7053SJung-uk Kim # |A7|A6|A5|A4|A3|A2|A1|A0|, where Ax is $accx, i.e. follow $accx 576e71b7053SJung-uk Kim # 577e71b7053SJung-uk Kim # "can't overflow" below mark carrying into high part of 578e71b7053SJung-uk Kim # multiplication result, which can't overflow, because it 579e71b7053SJung-uk Kim # can never be all ones. 580e71b7053SJung-uk Kim 581e71b7053SJung-uk Kim mulld $acc1,$a1,$a0 # a[1]*a[0] 582e71b7053SJung-uk Kim mulhdu $t1,$a1,$a0 583e71b7053SJung-uk Kim mulld $acc2,$a2,$a0 # a[2]*a[0] 584e71b7053SJung-uk Kim mulhdu $t2,$a2,$a0 585e71b7053SJung-uk Kim mulld $acc3,$a3,$a0 # a[3]*a[0] 586e71b7053SJung-uk Kim mulhdu $acc4,$a3,$a0 587e71b7053SJung-uk Kim 588e71b7053SJung-uk Kim addc $acc2,$acc2,$t1 # accumulate high parts of multiplication 589e71b7053SJung-uk Kim mulld $t0,$a2,$a1 # a[2]*a[1] 590e71b7053SJung-uk Kim mulhdu $t1,$a2,$a1 591e71b7053SJung-uk Kim adde $acc3,$acc3,$t2 592e71b7053SJung-uk Kim mulld $t2,$a3,$a1 # a[3]*a[1] 593e71b7053SJung-uk Kim mulhdu $t3,$a3,$a1 594e71b7053SJung-uk Kim addze $acc4,$acc4 # can't overflow 595e71b7053SJung-uk Kim 596e71b7053SJung-uk Kim mulld $acc5,$a3,$a2 # a[3]*a[2] 597e71b7053SJung-uk Kim mulhdu $acc6,$a3,$a2 598e71b7053SJung-uk Kim 599e71b7053SJung-uk Kim addc $t1,$t1,$t2 # accumulate high parts of multiplication 600e71b7053SJung-uk Kim addze $t2,$t3 # can't overflow 601e71b7053SJung-uk Kim 602e71b7053SJung-uk Kim addc $acc3,$acc3,$t0 # accumulate low parts of multiplication 603e71b7053SJung-uk Kim adde $acc4,$acc4,$t1 604e71b7053SJung-uk Kim adde $acc5,$acc5,$t2 605e71b7053SJung-uk Kim addze $acc6,$acc6 # can't overflow 606e71b7053SJung-uk Kim 607e71b7053SJung-uk Kim addc $acc1,$acc1,$acc1 # acc[1-6]*=2 608e71b7053SJung-uk Kim adde $acc2,$acc2,$acc2 609e71b7053SJung-uk Kim adde $acc3,$acc3,$acc3 610e71b7053SJung-uk Kim adde $acc4,$acc4,$acc4 611e71b7053SJung-uk Kim adde $acc5,$acc5,$acc5 612e71b7053SJung-uk Kim adde $acc6,$acc6,$acc6 613e71b7053SJung-uk Kim li $acc7,0 614e71b7053SJung-uk Kim addze $acc7,$acc7 615e71b7053SJung-uk Kim 616e71b7053SJung-uk Kim mulld $acc0,$a0,$a0 # a[0]*a[0] 617e71b7053SJung-uk Kim mulhdu $a0,$a0,$a0 618e71b7053SJung-uk Kim mulld $t1,$a1,$a1 # a[1]*a[1] 619e71b7053SJung-uk Kim mulhdu $a1,$a1,$a1 620e71b7053SJung-uk Kim mulld $t2,$a2,$a2 # a[2]*a[2] 621e71b7053SJung-uk Kim mulhdu $a2,$a2,$a2 622e71b7053SJung-uk Kim mulld $t3,$a3,$a3 # a[3]*a[3] 623e71b7053SJung-uk Kim mulhdu $a3,$a3,$a3 624e71b7053SJung-uk Kim addc $acc1,$acc1,$a0 # +a[i]*a[i] 625e71b7053SJung-uk Kim sldi $t0,$acc0,32 626e71b7053SJung-uk Kim adde $acc2,$acc2,$t1 627e71b7053SJung-uk Kim srdi $t1,$acc0,32 628e71b7053SJung-uk Kim adde $acc3,$acc3,$a1 629e71b7053SJung-uk Kim adde $acc4,$acc4,$t2 630e71b7053SJung-uk Kim adde $acc5,$acc5,$a2 631e71b7053SJung-uk Kim adde $acc6,$acc6,$t3 632e71b7053SJung-uk Kim adde $acc7,$acc7,$a3 633e71b7053SJung-uk Kim___ 634e71b7053SJung-uk Kimfor($i=0;$i<3;$i++) { # reductions, see commentary in 635e71b7053SJung-uk Kim # multiplication for details 636e71b7053SJung-uk Kim$code.=<<___; 637e71b7053SJung-uk Kim subfc $t2,$t0,$acc0 # "*0xffff0001" 638e71b7053SJung-uk Kim subfe $t3,$t1,$acc0 639e71b7053SJung-uk Kim addc $acc0,$acc1,$t0 # +=acc[0]<<96 and omit acc[0] 640e71b7053SJung-uk Kim sldi $t0,$acc0,32 641e71b7053SJung-uk Kim adde $acc1,$acc2,$t1 642e71b7053SJung-uk Kim srdi $t1,$acc0,32 643e71b7053SJung-uk Kim adde $acc2,$acc3,$t2 # +=acc[0]*0xffff0001 644e71b7053SJung-uk Kim addze $acc3,$t3 # can't overflow 645e71b7053SJung-uk Kim___ 646e71b7053SJung-uk Kim} 647e71b7053SJung-uk Kim$code.=<<___; 648e71b7053SJung-uk Kim subfc $t2,$t0,$acc0 # "*0xffff0001" 649e71b7053SJung-uk Kim subfe $t3,$t1,$acc0 650e71b7053SJung-uk Kim addc $acc0,$acc1,$t0 # +=acc[0]<<96 and omit acc[0] 651e71b7053SJung-uk Kim adde $acc1,$acc2,$t1 652e71b7053SJung-uk Kim adde $acc2,$acc3,$t2 # +=acc[0]*0xffff0001 653e71b7053SJung-uk Kim addze $acc3,$t3 # can't overflow 654e71b7053SJung-uk Kim 655e71b7053SJung-uk Kim addc $acc0,$acc0,$acc4 # accumulate upper half 656e71b7053SJung-uk Kim adde $acc1,$acc1,$acc5 657e71b7053SJung-uk Kim adde $acc2,$acc2,$acc6 658e71b7053SJung-uk Kim adde $acc3,$acc3,$acc7 659e71b7053SJung-uk Kim li $t2,0 660e71b7053SJung-uk Kim addze $acc4,$t2 661e71b7053SJung-uk Kim 662e71b7053SJung-uk Kim addic $acc0,$acc0,1 # ret -= modulus 663e71b7053SJung-uk Kim subfe $acc1,$poly1,$acc1 664e71b7053SJung-uk Kim subfe $acc2,$t2,$acc2 665e71b7053SJung-uk Kim subfe $acc3,$poly3,$acc3 666e71b7053SJung-uk Kim subfe $acc4,$t2,$acc4 667e71b7053SJung-uk Kim 668e71b7053SJung-uk Kim addc $acc0,$acc0,$acc4 # ret += modulus if borrow 669e71b7053SJung-uk Kim and $t1,$poly1,$acc4 670e71b7053SJung-uk Kim and $t3,$poly3,$acc4 671e71b7053SJung-uk Kim adde $acc1,$acc1,$t1 672e71b7053SJung-uk Kim addze $acc2,$acc2 673e71b7053SJung-uk Kim adde $acc3,$acc3,$t3 674e71b7053SJung-uk Kim 675e71b7053SJung-uk Kim std $acc0,0($rp) 676e71b7053SJung-uk Kim std $acc1,8($rp) 677e71b7053SJung-uk Kim std $acc2,16($rp) 678e71b7053SJung-uk Kim std $acc3,24($rp) 679e71b7053SJung-uk Kim 680e71b7053SJung-uk Kim blr 681e71b7053SJung-uk Kim .long 0 682e71b7053SJung-uk Kim .byte 0,12,0x14,0,0,0,1,0 683e71b7053SJung-uk Kim .long 0 684e71b7053SJung-uk Kim.size __ecp_nistz256_sqr_mont,.-__ecp_nistz256_sqr_mont 685e71b7053SJung-uk Kim 686e71b7053SJung-uk Kim# Note that __ecp_nistz256_add expects both input vectors pre-loaded to 687e71b7053SJung-uk Kim# $a0-$a3 and $t0-$t3. This is done because it's used in multiple 688e71b7053SJung-uk Kim# contexts, e.g. in multiplication by 2 and 3... 689e71b7053SJung-uk Kim.type __ecp_nistz256_add,\@function 690e71b7053SJung-uk Kim.align 4 691e71b7053SJung-uk Kim__ecp_nistz256_add: 692e71b7053SJung-uk Kim addc $acc0,$acc0,$t0 # ret = a+b 693e71b7053SJung-uk Kim adde $acc1,$acc1,$t1 694e71b7053SJung-uk Kim adde $acc2,$acc2,$t2 695e71b7053SJung-uk Kim li $t2,0 696e71b7053SJung-uk Kim adde $acc3,$acc3,$t3 697e71b7053SJung-uk Kim addze $t0,$t2 698e71b7053SJung-uk Kim 699e71b7053SJung-uk Kim # if a+b >= modulus, subtract modulus 700e71b7053SJung-uk Kim # 701e71b7053SJung-uk Kim # But since comparison implies subtraction, we subtract 702e71b7053SJung-uk Kim # modulus and then add it back if subtraction borrowed. 703e71b7053SJung-uk Kim 704e71b7053SJung-uk Kim subic $acc0,$acc0,-1 705e71b7053SJung-uk Kim subfe $acc1,$poly1,$acc1 706e71b7053SJung-uk Kim subfe $acc2,$t2,$acc2 707e71b7053SJung-uk Kim subfe $acc3,$poly3,$acc3 708e71b7053SJung-uk Kim subfe $t0,$t2,$t0 709e71b7053SJung-uk Kim 710e71b7053SJung-uk Kim addc $acc0,$acc0,$t0 711e71b7053SJung-uk Kim and $t1,$poly1,$t0 712e71b7053SJung-uk Kim and $t3,$poly3,$t0 713e71b7053SJung-uk Kim adde $acc1,$acc1,$t1 714e71b7053SJung-uk Kim addze $acc2,$acc2 715e71b7053SJung-uk Kim adde $acc3,$acc3,$t3 716e71b7053SJung-uk Kim 717e71b7053SJung-uk Kim std $acc0,0($rp) 718e71b7053SJung-uk Kim std $acc1,8($rp) 719e71b7053SJung-uk Kim std $acc2,16($rp) 720e71b7053SJung-uk Kim std $acc3,24($rp) 721e71b7053SJung-uk Kim 722e71b7053SJung-uk Kim blr 723e71b7053SJung-uk Kim .long 0 724e71b7053SJung-uk Kim .byte 0,12,0x14,0,0,0,3,0 725e71b7053SJung-uk Kim .long 0 726e71b7053SJung-uk Kim.size __ecp_nistz256_add,.-__ecp_nistz256_add 727e71b7053SJung-uk Kim 728e71b7053SJung-uk Kim.type __ecp_nistz256_sub_from,\@function 729e71b7053SJung-uk Kim.align 4 730e71b7053SJung-uk Kim__ecp_nistz256_sub_from: 731e71b7053SJung-uk Kim ld $t0,0($bp) 732e71b7053SJung-uk Kim ld $t1,8($bp) 733e71b7053SJung-uk Kim ld $t2,16($bp) 734e71b7053SJung-uk Kim ld $t3,24($bp) 735e71b7053SJung-uk Kim subfc $acc0,$t0,$acc0 # ret = a-b 736e71b7053SJung-uk Kim subfe $acc1,$t1,$acc1 737e71b7053SJung-uk Kim subfe $acc2,$t2,$acc2 738e71b7053SJung-uk Kim subfe $acc3,$t3,$acc3 739e71b7053SJung-uk Kim subfe $t0,$t0,$t0 # t0 = borrow ? -1 : 0 740e71b7053SJung-uk Kim 741e71b7053SJung-uk Kim # if a-b borrowed, add modulus 742e71b7053SJung-uk Kim 743e71b7053SJung-uk Kim addc $acc0,$acc0,$t0 # ret -= modulus & t0 744e71b7053SJung-uk Kim and $t1,$poly1,$t0 745e71b7053SJung-uk Kim and $t3,$poly3,$t0 746e71b7053SJung-uk Kim adde $acc1,$acc1,$t1 747e71b7053SJung-uk Kim addze $acc2,$acc2 748e71b7053SJung-uk Kim adde $acc3,$acc3,$t3 749e71b7053SJung-uk Kim 750e71b7053SJung-uk Kim std $acc0,0($rp) 751e71b7053SJung-uk Kim std $acc1,8($rp) 752e71b7053SJung-uk Kim std $acc2,16($rp) 753e71b7053SJung-uk Kim std $acc3,24($rp) 754e71b7053SJung-uk Kim 755e71b7053SJung-uk Kim blr 756e71b7053SJung-uk Kim .long 0 757e71b7053SJung-uk Kim .byte 0,12,0x14,0,0,0,3,0 758e71b7053SJung-uk Kim .long 0 759e71b7053SJung-uk Kim.size __ecp_nistz256_sub_from,.-__ecp_nistz256_sub_from 760e71b7053SJung-uk Kim 761e71b7053SJung-uk Kim.type __ecp_nistz256_sub_morf,\@function 762e71b7053SJung-uk Kim.align 4 763e71b7053SJung-uk Kim__ecp_nistz256_sub_morf: 764e71b7053SJung-uk Kim ld $t0,0($bp) 765e71b7053SJung-uk Kim ld $t1,8($bp) 766e71b7053SJung-uk Kim ld $t2,16($bp) 767e71b7053SJung-uk Kim ld $t3,24($bp) 768e71b7053SJung-uk Kim subfc $acc0,$acc0,$t0 # ret = b-a 769e71b7053SJung-uk Kim subfe $acc1,$acc1,$t1 770e71b7053SJung-uk Kim subfe $acc2,$acc2,$t2 771e71b7053SJung-uk Kim subfe $acc3,$acc3,$t3 772e71b7053SJung-uk Kim subfe $t0,$t0,$t0 # t0 = borrow ? -1 : 0 773e71b7053SJung-uk Kim 774e71b7053SJung-uk Kim # if b-a borrowed, add modulus 775e71b7053SJung-uk Kim 776e71b7053SJung-uk Kim addc $acc0,$acc0,$t0 # ret -= modulus & t0 777e71b7053SJung-uk Kim and $t1,$poly1,$t0 778e71b7053SJung-uk Kim and $t3,$poly3,$t0 779e71b7053SJung-uk Kim adde $acc1,$acc1,$t1 780e71b7053SJung-uk Kim addze $acc2,$acc2 781e71b7053SJung-uk Kim adde $acc3,$acc3,$t3 782e71b7053SJung-uk Kim 783e71b7053SJung-uk Kim std $acc0,0($rp) 784e71b7053SJung-uk Kim std $acc1,8($rp) 785e71b7053SJung-uk Kim std $acc2,16($rp) 786e71b7053SJung-uk Kim std $acc3,24($rp) 787e71b7053SJung-uk Kim 788e71b7053SJung-uk Kim blr 789e71b7053SJung-uk Kim .long 0 790e71b7053SJung-uk Kim .byte 0,12,0x14,0,0,0,3,0 791e71b7053SJung-uk Kim .long 0 792e71b7053SJung-uk Kim.size __ecp_nistz256_sub_morf,.-__ecp_nistz256_sub_morf 793e71b7053SJung-uk Kim 794e71b7053SJung-uk Kim.type __ecp_nistz256_div_by_2,\@function 795e71b7053SJung-uk Kim.align 4 796e71b7053SJung-uk Kim__ecp_nistz256_div_by_2: 797e71b7053SJung-uk Kim andi. $t0,$acc0,1 798e71b7053SJung-uk Kim addic $acc0,$acc0,-1 # a += modulus 799e71b7053SJung-uk Kim neg $t0,$t0 800e71b7053SJung-uk Kim adde $acc1,$acc1,$poly1 801e71b7053SJung-uk Kim not $t0,$t0 802e71b7053SJung-uk Kim addze $acc2,$acc2 803e71b7053SJung-uk Kim li $t2,0 804e71b7053SJung-uk Kim adde $acc3,$acc3,$poly3 805e71b7053SJung-uk Kim and $t1,$poly1,$t0 806e71b7053SJung-uk Kim addze $ap,$t2 # ap = carry 807e71b7053SJung-uk Kim and $t3,$poly3,$t0 808e71b7053SJung-uk Kim 809e71b7053SJung-uk Kim subfc $acc0,$t0,$acc0 # a -= modulus if a was even 810e71b7053SJung-uk Kim subfe $acc1,$t1,$acc1 811e71b7053SJung-uk Kim subfe $acc2,$t2,$acc2 812e71b7053SJung-uk Kim subfe $acc3,$t3,$acc3 813e71b7053SJung-uk Kim subfe $ap, $t2,$ap 814e71b7053SJung-uk Kim 815e71b7053SJung-uk Kim srdi $acc0,$acc0,1 816e71b7053SJung-uk Kim sldi $t0,$acc1,63 817e71b7053SJung-uk Kim srdi $acc1,$acc1,1 818e71b7053SJung-uk Kim sldi $t1,$acc2,63 819e71b7053SJung-uk Kim srdi $acc2,$acc2,1 820e71b7053SJung-uk Kim sldi $t2,$acc3,63 821e71b7053SJung-uk Kim srdi $acc3,$acc3,1 822e71b7053SJung-uk Kim sldi $t3,$ap,63 823e71b7053SJung-uk Kim or $acc0,$acc0,$t0 824e71b7053SJung-uk Kim or $acc1,$acc1,$t1 825e71b7053SJung-uk Kim or $acc2,$acc2,$t2 826e71b7053SJung-uk Kim or $acc3,$acc3,$t3 827e71b7053SJung-uk Kim 828e71b7053SJung-uk Kim std $acc0,0($rp) 829e71b7053SJung-uk Kim std $acc1,8($rp) 830e71b7053SJung-uk Kim std $acc2,16($rp) 831e71b7053SJung-uk Kim std $acc3,24($rp) 832e71b7053SJung-uk Kim 833e71b7053SJung-uk Kim blr 834e71b7053SJung-uk Kim .long 0 835e71b7053SJung-uk Kim .byte 0,12,0x14,0,0,0,1,0 836e71b7053SJung-uk Kim .long 0 837e71b7053SJung-uk Kim.size __ecp_nistz256_div_by_2,.-__ecp_nistz256_div_by_2 838e71b7053SJung-uk Kim___ 839e71b7053SJung-uk Kim######################################################################## 840e71b7053SJung-uk Kim# following subroutines are "literal" implementation of those found in 841e71b7053SJung-uk Kim# ecp_nistz256.c 842e71b7053SJung-uk Kim# 843e71b7053SJung-uk Kim######################################################################## 844e71b7053SJung-uk Kim# void ecp_nistz256_point_double(P256_POINT *out,const P256_POINT *inp); 845e71b7053SJung-uk Kim# 846e71b7053SJung-uk Kimif (1) { 847e71b7053SJung-uk Kimmy $FRAME=64+32*4+12*8; 848e71b7053SJung-uk Kimmy ($S,$M,$Zsqr,$tmp0)=map(64+32*$_,(0..3)); 849e71b7053SJung-uk Kim# above map() describes stack layout with 4 temporary 850e71b7053SJung-uk Kim# 256-bit vectors on top. 851e71b7053SJung-uk Kimmy ($rp_real,$ap_real) = map("r$_",(20,21)); 852e71b7053SJung-uk Kim 853e71b7053SJung-uk Kim$code.=<<___; 854e71b7053SJung-uk Kim.globl ecp_nistz256_point_double 855e71b7053SJung-uk Kim.align 5 856e71b7053SJung-uk Kimecp_nistz256_point_double: 857e71b7053SJung-uk Kim stdu $sp,-$FRAME($sp) 858e71b7053SJung-uk Kim mflr r0 859e71b7053SJung-uk Kim std r20,$FRAME-8*12($sp) 860e71b7053SJung-uk Kim std r21,$FRAME-8*11($sp) 861e71b7053SJung-uk Kim std r22,$FRAME-8*10($sp) 862e71b7053SJung-uk Kim std r23,$FRAME-8*9($sp) 863e71b7053SJung-uk Kim std r24,$FRAME-8*8($sp) 864e71b7053SJung-uk Kim std r25,$FRAME-8*7($sp) 865e71b7053SJung-uk Kim std r26,$FRAME-8*6($sp) 866e71b7053SJung-uk Kim std r27,$FRAME-8*5($sp) 867e71b7053SJung-uk Kim std r28,$FRAME-8*4($sp) 868e71b7053SJung-uk Kim std r29,$FRAME-8*3($sp) 869e71b7053SJung-uk Kim std r30,$FRAME-8*2($sp) 870e71b7053SJung-uk Kim std r31,$FRAME-8*1($sp) 871e71b7053SJung-uk Kim 872e71b7053SJung-uk Kim li $poly1,-1 873e71b7053SJung-uk Kim srdi $poly1,$poly1,32 # 0x00000000ffffffff 874e71b7053SJung-uk Kim li $poly3,1 875e71b7053SJung-uk Kim orc $poly3,$poly3,$poly1 # 0xffffffff00000001 876e71b7053SJung-uk Kim.Ldouble_shortcut: 877e71b7053SJung-uk Kim ld $acc0,32($ap) 878e71b7053SJung-uk Kim ld $acc1,40($ap) 879e71b7053SJung-uk Kim ld $acc2,48($ap) 880e71b7053SJung-uk Kim ld $acc3,56($ap) 881e71b7053SJung-uk Kim mr $t0,$acc0 882e71b7053SJung-uk Kim mr $t1,$acc1 883e71b7053SJung-uk Kim mr $t2,$acc2 884e71b7053SJung-uk Kim mr $t3,$acc3 885e71b7053SJung-uk Kim ld $a0,64($ap) # forward load for p256_sqr_mont 886e71b7053SJung-uk Kim ld $a1,72($ap) 887e71b7053SJung-uk Kim ld $a2,80($ap) 888e71b7053SJung-uk Kim ld $a3,88($ap) 889e71b7053SJung-uk Kim mr $rp_real,$rp 890e71b7053SJung-uk Kim mr $ap_real,$ap 891e71b7053SJung-uk Kim addi $rp,$sp,$S 892e71b7053SJung-uk Kim bl __ecp_nistz256_add # p256_mul_by_2(S, in_y); 893e71b7053SJung-uk Kim 894e71b7053SJung-uk Kim addi $rp,$sp,$Zsqr 895e71b7053SJung-uk Kim bl __ecp_nistz256_sqr_mont # p256_sqr_mont(Zsqr, in_z); 896e71b7053SJung-uk Kim 897e71b7053SJung-uk Kim ld $t0,0($ap_real) 898e71b7053SJung-uk Kim ld $t1,8($ap_real) 899e71b7053SJung-uk Kim ld $t2,16($ap_real) 900e71b7053SJung-uk Kim ld $t3,24($ap_real) 901e71b7053SJung-uk Kim mr $a0,$acc0 # put Zsqr aside for p256_sub 902e71b7053SJung-uk Kim mr $a1,$acc1 903e71b7053SJung-uk Kim mr $a2,$acc2 904e71b7053SJung-uk Kim mr $a3,$acc3 905e71b7053SJung-uk Kim addi $rp,$sp,$M 906e71b7053SJung-uk Kim bl __ecp_nistz256_add # p256_add(M, Zsqr, in_x); 907e71b7053SJung-uk Kim 908e71b7053SJung-uk Kim addi $bp,$ap_real,0 909e71b7053SJung-uk Kim mr $acc0,$a0 # restore Zsqr 910e71b7053SJung-uk Kim mr $acc1,$a1 911e71b7053SJung-uk Kim mr $acc2,$a2 912e71b7053SJung-uk Kim mr $acc3,$a3 913e71b7053SJung-uk Kim ld $a0,$S+0($sp) # forward load for p256_sqr_mont 914e71b7053SJung-uk Kim ld $a1,$S+8($sp) 915e71b7053SJung-uk Kim ld $a2,$S+16($sp) 916e71b7053SJung-uk Kim ld $a3,$S+24($sp) 917e71b7053SJung-uk Kim addi $rp,$sp,$Zsqr 918e71b7053SJung-uk Kim bl __ecp_nistz256_sub_morf # p256_sub(Zsqr, in_x, Zsqr); 919e71b7053SJung-uk Kim 920e71b7053SJung-uk Kim addi $rp,$sp,$S 921e71b7053SJung-uk Kim bl __ecp_nistz256_sqr_mont # p256_sqr_mont(S, S); 922e71b7053SJung-uk Kim 923e71b7053SJung-uk Kim ld $bi,32($ap_real) 924e71b7053SJung-uk Kim ld $a0,64($ap_real) 925e71b7053SJung-uk Kim ld $a1,72($ap_real) 926e71b7053SJung-uk Kim ld $a2,80($ap_real) 927e71b7053SJung-uk Kim ld $a3,88($ap_real) 928e71b7053SJung-uk Kim addi $bp,$ap_real,32 929e71b7053SJung-uk Kim addi $rp,$sp,$tmp0 930e71b7053SJung-uk Kim bl __ecp_nistz256_mul_mont # p256_mul_mont(tmp0, in_z, in_y); 931e71b7053SJung-uk Kim 932e71b7053SJung-uk Kim mr $t0,$acc0 933e71b7053SJung-uk Kim mr $t1,$acc1 934e71b7053SJung-uk Kim mr $t2,$acc2 935e71b7053SJung-uk Kim mr $t3,$acc3 936e71b7053SJung-uk Kim ld $a0,$S+0($sp) # forward load for p256_sqr_mont 937e71b7053SJung-uk Kim ld $a1,$S+8($sp) 938e71b7053SJung-uk Kim ld $a2,$S+16($sp) 939e71b7053SJung-uk Kim ld $a3,$S+24($sp) 940e71b7053SJung-uk Kim addi $rp,$rp_real,64 941e71b7053SJung-uk Kim bl __ecp_nistz256_add # p256_mul_by_2(res_z, tmp0); 942e71b7053SJung-uk Kim 943e71b7053SJung-uk Kim addi $rp,$sp,$tmp0 944e71b7053SJung-uk Kim bl __ecp_nistz256_sqr_mont # p256_sqr_mont(tmp0, S); 945e71b7053SJung-uk Kim 946e71b7053SJung-uk Kim ld $bi,$Zsqr($sp) # forward load for p256_mul_mont 947e71b7053SJung-uk Kim ld $a0,$M+0($sp) 948e71b7053SJung-uk Kim ld $a1,$M+8($sp) 949e71b7053SJung-uk Kim ld $a2,$M+16($sp) 950e71b7053SJung-uk Kim ld $a3,$M+24($sp) 951e71b7053SJung-uk Kim addi $rp,$rp_real,32 952e71b7053SJung-uk Kim bl __ecp_nistz256_div_by_2 # p256_div_by_2(res_y, tmp0); 953e71b7053SJung-uk Kim 954e71b7053SJung-uk Kim addi $bp,$sp,$Zsqr 955e71b7053SJung-uk Kim addi $rp,$sp,$M 956e71b7053SJung-uk Kim bl __ecp_nistz256_mul_mont # p256_mul_mont(M, M, Zsqr); 957e71b7053SJung-uk Kim 958e71b7053SJung-uk Kim mr $t0,$acc0 # duplicate M 959e71b7053SJung-uk Kim mr $t1,$acc1 960e71b7053SJung-uk Kim mr $t2,$acc2 961e71b7053SJung-uk Kim mr $t3,$acc3 962e71b7053SJung-uk Kim mr $a0,$acc0 # put M aside 963e71b7053SJung-uk Kim mr $a1,$acc1 964e71b7053SJung-uk Kim mr $a2,$acc2 965e71b7053SJung-uk Kim mr $a3,$acc3 966e71b7053SJung-uk Kim addi $rp,$sp,$M 967e71b7053SJung-uk Kim bl __ecp_nistz256_add 968e71b7053SJung-uk Kim mr $t0,$a0 # restore M 969e71b7053SJung-uk Kim mr $t1,$a1 970e71b7053SJung-uk Kim mr $t2,$a2 971e71b7053SJung-uk Kim mr $t3,$a3 972e71b7053SJung-uk Kim ld $bi,0($ap_real) # forward load for p256_mul_mont 973e71b7053SJung-uk Kim ld $a0,$S+0($sp) 974e71b7053SJung-uk Kim ld $a1,$S+8($sp) 975e71b7053SJung-uk Kim ld $a2,$S+16($sp) 976e71b7053SJung-uk Kim ld $a3,$S+24($sp) 977e71b7053SJung-uk Kim bl __ecp_nistz256_add # p256_mul_by_3(M, M); 978e71b7053SJung-uk Kim 979e71b7053SJung-uk Kim addi $bp,$ap_real,0 980e71b7053SJung-uk Kim addi $rp,$sp,$S 981e71b7053SJung-uk Kim bl __ecp_nistz256_mul_mont # p256_mul_mont(S, S, in_x); 982e71b7053SJung-uk Kim 983e71b7053SJung-uk Kim mr $t0,$acc0 984e71b7053SJung-uk Kim mr $t1,$acc1 985e71b7053SJung-uk Kim mr $t2,$acc2 986e71b7053SJung-uk Kim mr $t3,$acc3 987e71b7053SJung-uk Kim ld $a0,$M+0($sp) # forward load for p256_sqr_mont 988e71b7053SJung-uk Kim ld $a1,$M+8($sp) 989e71b7053SJung-uk Kim ld $a2,$M+16($sp) 990e71b7053SJung-uk Kim ld $a3,$M+24($sp) 991e71b7053SJung-uk Kim addi $rp,$sp,$tmp0 992e71b7053SJung-uk Kim bl __ecp_nistz256_add # p256_mul_by_2(tmp0, S); 993e71b7053SJung-uk Kim 994e71b7053SJung-uk Kim addi $rp,$rp_real,0 995e71b7053SJung-uk Kim bl __ecp_nistz256_sqr_mont # p256_sqr_mont(res_x, M); 996e71b7053SJung-uk Kim 997e71b7053SJung-uk Kim addi $bp,$sp,$tmp0 998e71b7053SJung-uk Kim bl __ecp_nistz256_sub_from # p256_sub(res_x, res_x, tmp0); 999e71b7053SJung-uk Kim 1000e71b7053SJung-uk Kim addi $bp,$sp,$S 1001e71b7053SJung-uk Kim addi $rp,$sp,$S 1002e71b7053SJung-uk Kim bl __ecp_nistz256_sub_morf # p256_sub(S, S, res_x); 1003e71b7053SJung-uk Kim 1004e71b7053SJung-uk Kim ld $bi,$M($sp) 1005e71b7053SJung-uk Kim mr $a0,$acc0 # copy S 1006e71b7053SJung-uk Kim mr $a1,$acc1 1007e71b7053SJung-uk Kim mr $a2,$acc2 1008e71b7053SJung-uk Kim mr $a3,$acc3 1009e71b7053SJung-uk Kim addi $bp,$sp,$M 1010e71b7053SJung-uk Kim bl __ecp_nistz256_mul_mont # p256_mul_mont(S, S, M); 1011e71b7053SJung-uk Kim 1012e71b7053SJung-uk Kim addi $bp,$rp_real,32 1013e71b7053SJung-uk Kim addi $rp,$rp_real,32 1014e71b7053SJung-uk Kim bl __ecp_nistz256_sub_from # p256_sub(res_y, S, res_y); 1015e71b7053SJung-uk Kim 1016e71b7053SJung-uk Kim mtlr r0 1017e71b7053SJung-uk Kim ld r20,$FRAME-8*12($sp) 1018e71b7053SJung-uk Kim ld r21,$FRAME-8*11($sp) 1019e71b7053SJung-uk Kim ld r22,$FRAME-8*10($sp) 1020e71b7053SJung-uk Kim ld r23,$FRAME-8*9($sp) 1021e71b7053SJung-uk Kim ld r24,$FRAME-8*8($sp) 1022e71b7053SJung-uk Kim ld r25,$FRAME-8*7($sp) 1023e71b7053SJung-uk Kim ld r26,$FRAME-8*6($sp) 1024e71b7053SJung-uk Kim ld r27,$FRAME-8*5($sp) 1025e71b7053SJung-uk Kim ld r28,$FRAME-8*4($sp) 1026e71b7053SJung-uk Kim ld r29,$FRAME-8*3($sp) 1027e71b7053SJung-uk Kim ld r30,$FRAME-8*2($sp) 1028e71b7053SJung-uk Kim ld r31,$FRAME-8*1($sp) 1029e71b7053SJung-uk Kim addi $sp,$sp,$FRAME 1030e71b7053SJung-uk Kim blr 1031e71b7053SJung-uk Kim .long 0 1032e71b7053SJung-uk Kim .byte 0,12,4,0,0x80,12,2,0 1033e71b7053SJung-uk Kim .long 0 1034e71b7053SJung-uk Kim.size ecp_nistz256_point_double,.-ecp_nistz256_point_double 1035e71b7053SJung-uk Kim___ 1036e71b7053SJung-uk Kim} 1037e71b7053SJung-uk Kim 1038e71b7053SJung-uk Kim######################################################################## 1039e71b7053SJung-uk Kim# void ecp_nistz256_point_add(P256_POINT *out,const P256_POINT *in1, 1040e71b7053SJung-uk Kim# const P256_POINT *in2); 1041e71b7053SJung-uk Kimif (1) { 1042e71b7053SJung-uk Kimmy $FRAME = 64 + 32*12 + 16*8; 1043e71b7053SJung-uk Kimmy ($res_x,$res_y,$res_z, 1044e71b7053SJung-uk Kim $H,$Hsqr,$R,$Rsqr,$Hcub, 1045e71b7053SJung-uk Kim $U1,$U2,$S1,$S2)=map(64+32*$_,(0..11)); 1046e71b7053SJung-uk Kimmy ($Z1sqr, $Z2sqr) = ($Hsqr, $Rsqr); 1047e71b7053SJung-uk Kim# above map() describes stack layout with 12 temporary 1048e71b7053SJung-uk Kim# 256-bit vectors on top. 1049e71b7053SJung-uk Kimmy ($rp_real,$ap_real,$bp_real,$in1infty,$in2infty,$temp)=map("r$_",(16..21)); 1050e71b7053SJung-uk Kim 1051e71b7053SJung-uk Kim$code.=<<___; 1052e71b7053SJung-uk Kim.globl ecp_nistz256_point_add 1053e71b7053SJung-uk Kim.align 5 1054e71b7053SJung-uk Kimecp_nistz256_point_add: 1055e71b7053SJung-uk Kim stdu $sp,-$FRAME($sp) 1056e71b7053SJung-uk Kim mflr r0 1057e71b7053SJung-uk Kim std r16,$FRAME-8*16($sp) 1058e71b7053SJung-uk Kim std r17,$FRAME-8*15($sp) 1059e71b7053SJung-uk Kim std r18,$FRAME-8*14($sp) 1060e71b7053SJung-uk Kim std r19,$FRAME-8*13($sp) 1061e71b7053SJung-uk Kim std r20,$FRAME-8*12($sp) 1062e71b7053SJung-uk Kim std r21,$FRAME-8*11($sp) 1063e71b7053SJung-uk Kim std r22,$FRAME-8*10($sp) 1064e71b7053SJung-uk Kim std r23,$FRAME-8*9($sp) 1065e71b7053SJung-uk Kim std r24,$FRAME-8*8($sp) 1066e71b7053SJung-uk Kim std r25,$FRAME-8*7($sp) 1067e71b7053SJung-uk Kim std r26,$FRAME-8*6($sp) 1068e71b7053SJung-uk Kim std r27,$FRAME-8*5($sp) 1069e71b7053SJung-uk Kim std r28,$FRAME-8*4($sp) 1070e71b7053SJung-uk Kim std r29,$FRAME-8*3($sp) 1071e71b7053SJung-uk Kim std r30,$FRAME-8*2($sp) 1072e71b7053SJung-uk Kim std r31,$FRAME-8*1($sp) 1073e71b7053SJung-uk Kim 1074e71b7053SJung-uk Kim li $poly1,-1 1075e71b7053SJung-uk Kim srdi $poly1,$poly1,32 # 0x00000000ffffffff 1076e71b7053SJung-uk Kim li $poly3,1 1077e71b7053SJung-uk Kim orc $poly3,$poly3,$poly1 # 0xffffffff00000001 1078e71b7053SJung-uk Kim 1079e71b7053SJung-uk Kim ld $a0,64($bp) # in2_z 1080e71b7053SJung-uk Kim ld $a1,72($bp) 1081e71b7053SJung-uk Kim ld $a2,80($bp) 1082e71b7053SJung-uk Kim ld $a3,88($bp) 1083e71b7053SJung-uk Kim mr $rp_real,$rp 1084e71b7053SJung-uk Kim mr $ap_real,$ap 1085e71b7053SJung-uk Kim mr $bp_real,$bp 1086e71b7053SJung-uk Kim or $t0,$a0,$a1 1087e71b7053SJung-uk Kim or $t2,$a2,$a3 1088e71b7053SJung-uk Kim or $in2infty,$t0,$t2 1089e71b7053SJung-uk Kim neg $t0,$in2infty 1090e71b7053SJung-uk Kim or $in2infty,$in2infty,$t0 1091e71b7053SJung-uk Kim sradi $in2infty,$in2infty,63 # !in2infty 1092e71b7053SJung-uk Kim addi $rp,$sp,$Z2sqr 1093e71b7053SJung-uk Kim bl __ecp_nistz256_sqr_mont # p256_sqr_mont(Z2sqr, in2_z); 1094e71b7053SJung-uk Kim 1095e71b7053SJung-uk Kim ld $a0,64($ap_real) # in1_z 1096e71b7053SJung-uk Kim ld $a1,72($ap_real) 1097e71b7053SJung-uk Kim ld $a2,80($ap_real) 1098e71b7053SJung-uk Kim ld $a3,88($ap_real) 1099e71b7053SJung-uk Kim or $t0,$a0,$a1 1100e71b7053SJung-uk Kim or $t2,$a2,$a3 1101e71b7053SJung-uk Kim or $in1infty,$t0,$t2 1102e71b7053SJung-uk Kim neg $t0,$in1infty 1103e71b7053SJung-uk Kim or $in1infty,$in1infty,$t0 1104e71b7053SJung-uk Kim sradi $in1infty,$in1infty,63 # !in1infty 1105e71b7053SJung-uk Kim addi $rp,$sp,$Z1sqr 1106e71b7053SJung-uk Kim bl __ecp_nistz256_sqr_mont # p256_sqr_mont(Z1sqr, in1_z); 1107e71b7053SJung-uk Kim 1108e71b7053SJung-uk Kim ld $bi,64($bp_real) 1109e71b7053SJung-uk Kim ld $a0,$Z2sqr+0($sp) 1110e71b7053SJung-uk Kim ld $a1,$Z2sqr+8($sp) 1111e71b7053SJung-uk Kim ld $a2,$Z2sqr+16($sp) 1112e71b7053SJung-uk Kim ld $a3,$Z2sqr+24($sp) 1113e71b7053SJung-uk Kim addi $bp,$bp_real,64 1114e71b7053SJung-uk Kim addi $rp,$sp,$S1 1115e71b7053SJung-uk Kim bl __ecp_nistz256_mul_mont # p256_mul_mont(S1, Z2sqr, in2_z); 1116e71b7053SJung-uk Kim 1117e71b7053SJung-uk Kim ld $bi,64($ap_real) 1118e71b7053SJung-uk Kim ld $a0,$Z1sqr+0($sp) 1119e71b7053SJung-uk Kim ld $a1,$Z1sqr+8($sp) 1120e71b7053SJung-uk Kim ld $a2,$Z1sqr+16($sp) 1121e71b7053SJung-uk Kim ld $a3,$Z1sqr+24($sp) 1122e71b7053SJung-uk Kim addi $bp,$ap_real,64 1123e71b7053SJung-uk Kim addi $rp,$sp,$S2 1124e71b7053SJung-uk Kim bl __ecp_nistz256_mul_mont # p256_mul_mont(S2, Z1sqr, in1_z); 1125e71b7053SJung-uk Kim 1126e71b7053SJung-uk Kim ld $bi,32($ap_real) 1127e71b7053SJung-uk Kim ld $a0,$S1+0($sp) 1128e71b7053SJung-uk Kim ld $a1,$S1+8($sp) 1129e71b7053SJung-uk Kim ld $a2,$S1+16($sp) 1130e71b7053SJung-uk Kim ld $a3,$S1+24($sp) 1131e71b7053SJung-uk Kim addi $bp,$ap_real,32 1132e71b7053SJung-uk Kim addi $rp,$sp,$S1 1133e71b7053SJung-uk Kim bl __ecp_nistz256_mul_mont # p256_mul_mont(S1, S1, in1_y); 1134e71b7053SJung-uk Kim 1135e71b7053SJung-uk Kim ld $bi,32($bp_real) 1136e71b7053SJung-uk Kim ld $a0,$S2+0($sp) 1137e71b7053SJung-uk Kim ld $a1,$S2+8($sp) 1138e71b7053SJung-uk Kim ld $a2,$S2+16($sp) 1139e71b7053SJung-uk Kim ld $a3,$S2+24($sp) 1140e71b7053SJung-uk Kim addi $bp,$bp_real,32 1141e71b7053SJung-uk Kim addi $rp,$sp,$S2 1142e71b7053SJung-uk Kim bl __ecp_nistz256_mul_mont # p256_mul_mont(S2, S2, in2_y); 1143e71b7053SJung-uk Kim 1144e71b7053SJung-uk Kim addi $bp,$sp,$S1 1145e71b7053SJung-uk Kim ld $bi,$Z2sqr($sp) # forward load for p256_mul_mont 1146e71b7053SJung-uk Kim ld $a0,0($ap_real) 1147e71b7053SJung-uk Kim ld $a1,8($ap_real) 1148e71b7053SJung-uk Kim ld $a2,16($ap_real) 1149e71b7053SJung-uk Kim ld $a3,24($ap_real) 1150e71b7053SJung-uk Kim addi $rp,$sp,$R 1151e71b7053SJung-uk Kim bl __ecp_nistz256_sub_from # p256_sub(R, S2, S1); 1152e71b7053SJung-uk Kim 1153e71b7053SJung-uk Kim or $acc0,$acc0,$acc1 # see if result is zero 1154e71b7053SJung-uk Kim or $acc2,$acc2,$acc3 1155e71b7053SJung-uk Kim or $temp,$acc0,$acc2 1156e71b7053SJung-uk Kim 1157e71b7053SJung-uk Kim addi $bp,$sp,$Z2sqr 1158e71b7053SJung-uk Kim addi $rp,$sp,$U1 1159e71b7053SJung-uk Kim bl __ecp_nistz256_mul_mont # p256_mul_mont(U1, in1_x, Z2sqr); 1160e71b7053SJung-uk Kim 1161e71b7053SJung-uk Kim ld $bi,$Z1sqr($sp) 1162e71b7053SJung-uk Kim ld $a0,0($bp_real) 1163e71b7053SJung-uk Kim ld $a1,8($bp_real) 1164e71b7053SJung-uk Kim ld $a2,16($bp_real) 1165e71b7053SJung-uk Kim ld $a3,24($bp_real) 1166e71b7053SJung-uk Kim addi $bp,$sp,$Z1sqr 1167e71b7053SJung-uk Kim addi $rp,$sp,$U2 1168e71b7053SJung-uk Kim bl __ecp_nistz256_mul_mont # p256_mul_mont(U2, in2_x, Z1sqr); 1169e71b7053SJung-uk Kim 1170e71b7053SJung-uk Kim addi $bp,$sp,$U1 1171e71b7053SJung-uk Kim ld $a0,$R+0($sp) # forward load for p256_sqr_mont 1172e71b7053SJung-uk Kim ld $a1,$R+8($sp) 1173e71b7053SJung-uk Kim ld $a2,$R+16($sp) 1174e71b7053SJung-uk Kim ld $a3,$R+24($sp) 1175e71b7053SJung-uk Kim addi $rp,$sp,$H 1176e71b7053SJung-uk Kim bl __ecp_nistz256_sub_from # p256_sub(H, U2, U1); 1177e71b7053SJung-uk Kim 1178e71b7053SJung-uk Kim or $acc0,$acc0,$acc1 # see if result is zero 1179e71b7053SJung-uk Kim or $acc2,$acc2,$acc3 1180e71b7053SJung-uk Kim or. $acc0,$acc0,$acc2 1181e71b7053SJung-uk Kim bne .Ladd_proceed # is_equal(U1,U2)? 1182e71b7053SJung-uk Kim 1183e71b7053SJung-uk Kim and. $t0,$in1infty,$in2infty 1184e71b7053SJung-uk Kim beq .Ladd_proceed # (in1infty || in2infty)? 1185e71b7053SJung-uk Kim 1186e71b7053SJung-uk Kim cmpldi $temp,0 1187e71b7053SJung-uk Kim beq .Ladd_double # is_equal(S1,S2)? 1188e71b7053SJung-uk Kim 1189e71b7053SJung-uk Kim xor $a0,$a0,$a0 1190e71b7053SJung-uk Kim std $a0,0($rp_real) 1191e71b7053SJung-uk Kim std $a0,8($rp_real) 1192e71b7053SJung-uk Kim std $a0,16($rp_real) 1193e71b7053SJung-uk Kim std $a0,24($rp_real) 1194e71b7053SJung-uk Kim std $a0,32($rp_real) 1195e71b7053SJung-uk Kim std $a0,40($rp_real) 1196e71b7053SJung-uk Kim std $a0,48($rp_real) 1197e71b7053SJung-uk Kim std $a0,56($rp_real) 1198e71b7053SJung-uk Kim std $a0,64($rp_real) 1199e71b7053SJung-uk Kim std $a0,72($rp_real) 1200e71b7053SJung-uk Kim std $a0,80($rp_real) 1201e71b7053SJung-uk Kim std $a0,88($rp_real) 1202e71b7053SJung-uk Kim b .Ladd_done 1203e71b7053SJung-uk Kim 1204e71b7053SJung-uk Kim.align 4 1205e71b7053SJung-uk Kim.Ladd_double: 1206e71b7053SJung-uk Kim ld $bp,0($sp) # back-link 1207e71b7053SJung-uk Kim mr $ap,$ap_real 1208e71b7053SJung-uk Kim mr $rp,$rp_real 1209e71b7053SJung-uk Kim ld r16,$FRAME-8*16($sp) 1210e71b7053SJung-uk Kim ld r17,$FRAME-8*15($sp) 1211e71b7053SJung-uk Kim ld r18,$FRAME-8*14($sp) 1212e71b7053SJung-uk Kim ld r19,$FRAME-8*13($sp) 1213e71b7053SJung-uk Kim stdu $bp,$FRAME-288($sp) # difference in stack frame sizes 1214e71b7053SJung-uk Kim b .Ldouble_shortcut 1215e71b7053SJung-uk Kim 1216e71b7053SJung-uk Kim.align 4 1217e71b7053SJung-uk Kim.Ladd_proceed: 1218e71b7053SJung-uk Kim addi $rp,$sp,$Rsqr 1219e71b7053SJung-uk Kim bl __ecp_nistz256_sqr_mont # p256_sqr_mont(Rsqr, R); 1220e71b7053SJung-uk Kim 1221e71b7053SJung-uk Kim ld $bi,64($ap_real) 1222e71b7053SJung-uk Kim ld $a0,$H+0($sp) 1223e71b7053SJung-uk Kim ld $a1,$H+8($sp) 1224e71b7053SJung-uk Kim ld $a2,$H+16($sp) 1225e71b7053SJung-uk Kim ld $a3,$H+24($sp) 1226e71b7053SJung-uk Kim addi $bp,$ap_real,64 1227e71b7053SJung-uk Kim addi $rp,$sp,$res_z 1228e71b7053SJung-uk Kim bl __ecp_nistz256_mul_mont # p256_mul_mont(res_z, H, in1_z); 1229e71b7053SJung-uk Kim 1230e71b7053SJung-uk Kim ld $a0,$H+0($sp) 1231e71b7053SJung-uk Kim ld $a1,$H+8($sp) 1232e71b7053SJung-uk Kim ld $a2,$H+16($sp) 1233e71b7053SJung-uk Kim ld $a3,$H+24($sp) 1234e71b7053SJung-uk Kim addi $rp,$sp,$Hsqr 1235e71b7053SJung-uk Kim bl __ecp_nistz256_sqr_mont # p256_sqr_mont(Hsqr, H); 1236e71b7053SJung-uk Kim 1237e71b7053SJung-uk Kim ld $bi,64($bp_real) 1238e71b7053SJung-uk Kim ld $a0,$res_z+0($sp) 1239e71b7053SJung-uk Kim ld $a1,$res_z+8($sp) 1240e71b7053SJung-uk Kim ld $a2,$res_z+16($sp) 1241e71b7053SJung-uk Kim ld $a3,$res_z+24($sp) 1242e71b7053SJung-uk Kim addi $bp,$bp_real,64 1243e71b7053SJung-uk Kim addi $rp,$sp,$res_z 1244e71b7053SJung-uk Kim bl __ecp_nistz256_mul_mont # p256_mul_mont(res_z, res_z, in2_z); 1245e71b7053SJung-uk Kim 1246e71b7053SJung-uk Kim ld $bi,$H($sp) 1247e71b7053SJung-uk Kim ld $a0,$Hsqr+0($sp) 1248e71b7053SJung-uk Kim ld $a1,$Hsqr+8($sp) 1249e71b7053SJung-uk Kim ld $a2,$Hsqr+16($sp) 1250e71b7053SJung-uk Kim ld $a3,$Hsqr+24($sp) 1251e71b7053SJung-uk Kim addi $bp,$sp,$H 1252e71b7053SJung-uk Kim addi $rp,$sp,$Hcub 1253e71b7053SJung-uk Kim bl __ecp_nistz256_mul_mont # p256_mul_mont(Hcub, Hsqr, H); 1254e71b7053SJung-uk Kim 1255e71b7053SJung-uk Kim ld $bi,$Hsqr($sp) 1256e71b7053SJung-uk Kim ld $a0,$U1+0($sp) 1257e71b7053SJung-uk Kim ld $a1,$U1+8($sp) 1258e71b7053SJung-uk Kim ld $a2,$U1+16($sp) 1259e71b7053SJung-uk Kim ld $a3,$U1+24($sp) 1260e71b7053SJung-uk Kim addi $bp,$sp,$Hsqr 1261e71b7053SJung-uk Kim addi $rp,$sp,$U2 1262e71b7053SJung-uk Kim bl __ecp_nistz256_mul_mont # p256_mul_mont(U2, U1, Hsqr); 1263e71b7053SJung-uk Kim 1264e71b7053SJung-uk Kim mr $t0,$acc0 1265e71b7053SJung-uk Kim mr $t1,$acc1 1266e71b7053SJung-uk Kim mr $t2,$acc2 1267e71b7053SJung-uk Kim mr $t3,$acc3 1268e71b7053SJung-uk Kim addi $rp,$sp,$Hsqr 1269e71b7053SJung-uk Kim bl __ecp_nistz256_add # p256_mul_by_2(Hsqr, U2); 1270e71b7053SJung-uk Kim 1271e71b7053SJung-uk Kim addi $bp,$sp,$Rsqr 1272e71b7053SJung-uk Kim addi $rp,$sp,$res_x 1273e71b7053SJung-uk Kim bl __ecp_nistz256_sub_morf # p256_sub(res_x, Rsqr, Hsqr); 1274e71b7053SJung-uk Kim 1275e71b7053SJung-uk Kim addi $bp,$sp,$Hcub 1276e71b7053SJung-uk Kim bl __ecp_nistz256_sub_from # p256_sub(res_x, res_x, Hcub); 1277e71b7053SJung-uk Kim 1278e71b7053SJung-uk Kim addi $bp,$sp,$U2 1279e71b7053SJung-uk Kim ld $bi,$Hcub($sp) # forward load for p256_mul_mont 1280e71b7053SJung-uk Kim ld $a0,$S1+0($sp) 1281e71b7053SJung-uk Kim ld $a1,$S1+8($sp) 1282e71b7053SJung-uk Kim ld $a2,$S1+16($sp) 1283e71b7053SJung-uk Kim ld $a3,$S1+24($sp) 1284e71b7053SJung-uk Kim addi $rp,$sp,$res_y 1285e71b7053SJung-uk Kim bl __ecp_nistz256_sub_morf # p256_sub(res_y, U2, res_x); 1286e71b7053SJung-uk Kim 1287e71b7053SJung-uk Kim addi $bp,$sp,$Hcub 1288e71b7053SJung-uk Kim addi $rp,$sp,$S2 1289e71b7053SJung-uk Kim bl __ecp_nistz256_mul_mont # p256_mul_mont(S2, S1, Hcub); 1290e71b7053SJung-uk Kim 1291e71b7053SJung-uk Kim ld $bi,$R($sp) 1292e71b7053SJung-uk Kim ld $a0,$res_y+0($sp) 1293e71b7053SJung-uk Kim ld $a1,$res_y+8($sp) 1294e71b7053SJung-uk Kim ld $a2,$res_y+16($sp) 1295e71b7053SJung-uk Kim ld $a3,$res_y+24($sp) 1296e71b7053SJung-uk Kim addi $bp,$sp,$R 1297e71b7053SJung-uk Kim addi $rp,$sp,$res_y 1298e71b7053SJung-uk Kim bl __ecp_nistz256_mul_mont # p256_mul_mont(res_y, res_y, R); 1299e71b7053SJung-uk Kim 1300e71b7053SJung-uk Kim addi $bp,$sp,$S2 1301e71b7053SJung-uk Kim bl __ecp_nistz256_sub_from # p256_sub(res_y, res_y, S2); 1302e71b7053SJung-uk Kim 1303e71b7053SJung-uk Kim ld $t0,0($bp_real) # in2 1304e71b7053SJung-uk Kim ld $t1,8($bp_real) 1305e71b7053SJung-uk Kim ld $t2,16($bp_real) 1306e71b7053SJung-uk Kim ld $t3,24($bp_real) 1307e71b7053SJung-uk Kim ld $a0,$res_x+0($sp) # res 1308e71b7053SJung-uk Kim ld $a1,$res_x+8($sp) 1309e71b7053SJung-uk Kim ld $a2,$res_x+16($sp) 1310e71b7053SJung-uk Kim ld $a3,$res_x+24($sp) 1311e71b7053SJung-uk Kim___ 1312e71b7053SJung-uk Kimfor($i=0;$i<64;$i+=32) { # conditional moves 1313e71b7053SJung-uk Kim$code.=<<___; 1314e71b7053SJung-uk Kim ld $acc0,$i+0($ap_real) # in1 1315e71b7053SJung-uk Kim ld $acc1,$i+8($ap_real) 1316e71b7053SJung-uk Kim ld $acc2,$i+16($ap_real) 1317e71b7053SJung-uk Kim ld $acc3,$i+24($ap_real) 1318e71b7053SJung-uk Kim andc $t0,$t0,$in1infty 1319e71b7053SJung-uk Kim andc $t1,$t1,$in1infty 1320e71b7053SJung-uk Kim andc $t2,$t2,$in1infty 1321e71b7053SJung-uk Kim andc $t3,$t3,$in1infty 1322e71b7053SJung-uk Kim and $a0,$a0,$in1infty 1323e71b7053SJung-uk Kim and $a1,$a1,$in1infty 1324e71b7053SJung-uk Kim and $a2,$a2,$in1infty 1325e71b7053SJung-uk Kim and $a3,$a3,$in1infty 1326e71b7053SJung-uk Kim or $t0,$t0,$a0 1327e71b7053SJung-uk Kim or $t1,$t1,$a1 1328e71b7053SJung-uk Kim or $t2,$t2,$a2 1329e71b7053SJung-uk Kim or $t3,$t3,$a3 1330e71b7053SJung-uk Kim andc $acc0,$acc0,$in2infty 1331e71b7053SJung-uk Kim andc $acc1,$acc1,$in2infty 1332e71b7053SJung-uk Kim andc $acc2,$acc2,$in2infty 1333e71b7053SJung-uk Kim andc $acc3,$acc3,$in2infty 1334e71b7053SJung-uk Kim and $t0,$t0,$in2infty 1335e71b7053SJung-uk Kim and $t1,$t1,$in2infty 1336e71b7053SJung-uk Kim and $t2,$t2,$in2infty 1337e71b7053SJung-uk Kim and $t3,$t3,$in2infty 1338e71b7053SJung-uk Kim or $acc0,$acc0,$t0 1339e71b7053SJung-uk Kim or $acc1,$acc1,$t1 1340e71b7053SJung-uk Kim or $acc2,$acc2,$t2 1341e71b7053SJung-uk Kim or $acc3,$acc3,$t3 1342e71b7053SJung-uk Kim 1343e71b7053SJung-uk Kim ld $t0,$i+32($bp_real) # in2 1344e71b7053SJung-uk Kim ld $t1,$i+40($bp_real) 1345e71b7053SJung-uk Kim ld $t2,$i+48($bp_real) 1346e71b7053SJung-uk Kim ld $t3,$i+56($bp_real) 1347e71b7053SJung-uk Kim ld $a0,$res_x+$i+32($sp) 1348e71b7053SJung-uk Kim ld $a1,$res_x+$i+40($sp) 1349e71b7053SJung-uk Kim ld $a2,$res_x+$i+48($sp) 1350e71b7053SJung-uk Kim ld $a3,$res_x+$i+56($sp) 1351e71b7053SJung-uk Kim std $acc0,$i+0($rp_real) 1352e71b7053SJung-uk Kim std $acc1,$i+8($rp_real) 1353e71b7053SJung-uk Kim std $acc2,$i+16($rp_real) 1354e71b7053SJung-uk Kim std $acc3,$i+24($rp_real) 1355e71b7053SJung-uk Kim___ 1356e71b7053SJung-uk Kim} 1357e71b7053SJung-uk Kim$code.=<<___; 1358e71b7053SJung-uk Kim ld $acc0,$i+0($ap_real) # in1 1359e71b7053SJung-uk Kim ld $acc1,$i+8($ap_real) 1360e71b7053SJung-uk Kim ld $acc2,$i+16($ap_real) 1361e71b7053SJung-uk Kim ld $acc3,$i+24($ap_real) 1362e71b7053SJung-uk Kim andc $t0,$t0,$in1infty 1363e71b7053SJung-uk Kim andc $t1,$t1,$in1infty 1364e71b7053SJung-uk Kim andc $t2,$t2,$in1infty 1365e71b7053SJung-uk Kim andc $t3,$t3,$in1infty 1366e71b7053SJung-uk Kim and $a0,$a0,$in1infty 1367e71b7053SJung-uk Kim and $a1,$a1,$in1infty 1368e71b7053SJung-uk Kim and $a2,$a2,$in1infty 1369e71b7053SJung-uk Kim and $a3,$a3,$in1infty 1370e71b7053SJung-uk Kim or $t0,$t0,$a0 1371e71b7053SJung-uk Kim or $t1,$t1,$a1 1372e71b7053SJung-uk Kim or $t2,$t2,$a2 1373e71b7053SJung-uk Kim or $t3,$t3,$a3 1374e71b7053SJung-uk Kim andc $acc0,$acc0,$in2infty 1375e71b7053SJung-uk Kim andc $acc1,$acc1,$in2infty 1376e71b7053SJung-uk Kim andc $acc2,$acc2,$in2infty 1377e71b7053SJung-uk Kim andc $acc3,$acc3,$in2infty 1378e71b7053SJung-uk Kim and $t0,$t0,$in2infty 1379e71b7053SJung-uk Kim and $t1,$t1,$in2infty 1380e71b7053SJung-uk Kim and $t2,$t2,$in2infty 1381e71b7053SJung-uk Kim and $t3,$t3,$in2infty 1382e71b7053SJung-uk Kim or $acc0,$acc0,$t0 1383e71b7053SJung-uk Kim or $acc1,$acc1,$t1 1384e71b7053SJung-uk Kim or $acc2,$acc2,$t2 1385e71b7053SJung-uk Kim or $acc3,$acc3,$t3 1386e71b7053SJung-uk Kim std $acc0,$i+0($rp_real) 1387e71b7053SJung-uk Kim std $acc1,$i+8($rp_real) 1388e71b7053SJung-uk Kim std $acc2,$i+16($rp_real) 1389e71b7053SJung-uk Kim std $acc3,$i+24($rp_real) 1390e71b7053SJung-uk Kim 1391e71b7053SJung-uk Kim.Ladd_done: 1392e71b7053SJung-uk Kim mtlr r0 1393e71b7053SJung-uk Kim ld r16,$FRAME-8*16($sp) 1394e71b7053SJung-uk Kim ld r17,$FRAME-8*15($sp) 1395e71b7053SJung-uk Kim ld r18,$FRAME-8*14($sp) 1396e71b7053SJung-uk Kim ld r19,$FRAME-8*13($sp) 1397e71b7053SJung-uk Kim ld r20,$FRAME-8*12($sp) 1398e71b7053SJung-uk Kim ld r21,$FRAME-8*11($sp) 1399e71b7053SJung-uk Kim ld r22,$FRAME-8*10($sp) 1400e71b7053SJung-uk Kim ld r23,$FRAME-8*9($sp) 1401e71b7053SJung-uk Kim ld r24,$FRAME-8*8($sp) 1402e71b7053SJung-uk Kim ld r25,$FRAME-8*7($sp) 1403e71b7053SJung-uk Kim ld r26,$FRAME-8*6($sp) 1404e71b7053SJung-uk Kim ld r27,$FRAME-8*5($sp) 1405e71b7053SJung-uk Kim ld r28,$FRAME-8*4($sp) 1406e71b7053SJung-uk Kim ld r29,$FRAME-8*3($sp) 1407e71b7053SJung-uk Kim ld r30,$FRAME-8*2($sp) 1408e71b7053SJung-uk Kim ld r31,$FRAME-8*1($sp) 1409e71b7053SJung-uk Kim addi $sp,$sp,$FRAME 1410e71b7053SJung-uk Kim blr 1411e71b7053SJung-uk Kim .long 0 1412e71b7053SJung-uk Kim .byte 0,12,4,0,0x80,16,3,0 1413e71b7053SJung-uk Kim .long 0 1414e71b7053SJung-uk Kim.size ecp_nistz256_point_add,.-ecp_nistz256_point_add 1415e71b7053SJung-uk Kim___ 1416e71b7053SJung-uk Kim} 1417e71b7053SJung-uk Kim 1418e71b7053SJung-uk Kim######################################################################## 1419e71b7053SJung-uk Kim# void ecp_nistz256_point_add_affine(P256_POINT *out,const P256_POINT *in1, 1420e71b7053SJung-uk Kim# const P256_POINT_AFFINE *in2); 1421e71b7053SJung-uk Kimif (1) { 1422e71b7053SJung-uk Kimmy $FRAME = 64 + 32*10 + 16*8; 1423e71b7053SJung-uk Kimmy ($res_x,$res_y,$res_z, 1424e71b7053SJung-uk Kim $U2,$S2,$H,$R,$Hsqr,$Hcub,$Rsqr)=map(64+32*$_,(0..9)); 1425e71b7053SJung-uk Kimmy $Z1sqr = $S2; 1426e71b7053SJung-uk Kim# above map() describes stack layout with 10 temporary 1427e71b7053SJung-uk Kim# 256-bit vectors on top. 1428e71b7053SJung-uk Kimmy ($rp_real,$ap_real,$bp_real,$in1infty,$in2infty,$temp)=map("r$_",(16..21)); 1429e71b7053SJung-uk Kim 1430e71b7053SJung-uk Kim$code.=<<___; 1431e71b7053SJung-uk Kim.globl ecp_nistz256_point_add_affine 1432e71b7053SJung-uk Kim.align 5 1433e71b7053SJung-uk Kimecp_nistz256_point_add_affine: 1434e71b7053SJung-uk Kim stdu $sp,-$FRAME($sp) 1435e71b7053SJung-uk Kim mflr r0 1436e71b7053SJung-uk Kim std r16,$FRAME-8*16($sp) 1437e71b7053SJung-uk Kim std r17,$FRAME-8*15($sp) 1438e71b7053SJung-uk Kim std r18,$FRAME-8*14($sp) 1439e71b7053SJung-uk Kim std r19,$FRAME-8*13($sp) 1440e71b7053SJung-uk Kim std r20,$FRAME-8*12($sp) 1441e71b7053SJung-uk Kim std r21,$FRAME-8*11($sp) 1442e71b7053SJung-uk Kim std r22,$FRAME-8*10($sp) 1443e71b7053SJung-uk Kim std r23,$FRAME-8*9($sp) 1444e71b7053SJung-uk Kim std r24,$FRAME-8*8($sp) 1445e71b7053SJung-uk Kim std r25,$FRAME-8*7($sp) 1446e71b7053SJung-uk Kim std r26,$FRAME-8*6($sp) 1447e71b7053SJung-uk Kim std r27,$FRAME-8*5($sp) 1448e71b7053SJung-uk Kim std r28,$FRAME-8*4($sp) 1449e71b7053SJung-uk Kim std r29,$FRAME-8*3($sp) 1450e71b7053SJung-uk Kim std r30,$FRAME-8*2($sp) 1451e71b7053SJung-uk Kim std r31,$FRAME-8*1($sp) 1452e71b7053SJung-uk Kim 1453e71b7053SJung-uk Kim li $poly1,-1 1454e71b7053SJung-uk Kim srdi $poly1,$poly1,32 # 0x00000000ffffffff 1455e71b7053SJung-uk Kim li $poly3,1 1456e71b7053SJung-uk Kim orc $poly3,$poly3,$poly1 # 0xffffffff00000001 1457e71b7053SJung-uk Kim 1458e71b7053SJung-uk Kim mr $rp_real,$rp 1459e71b7053SJung-uk Kim mr $ap_real,$ap 1460e71b7053SJung-uk Kim mr $bp_real,$bp 1461e71b7053SJung-uk Kim 1462e71b7053SJung-uk Kim ld $a0,64($ap) # in1_z 1463e71b7053SJung-uk Kim ld $a1,72($ap) 1464e71b7053SJung-uk Kim ld $a2,80($ap) 1465e71b7053SJung-uk Kim ld $a3,88($ap) 1466e71b7053SJung-uk Kim or $t0,$a0,$a1 1467e71b7053SJung-uk Kim or $t2,$a2,$a3 1468e71b7053SJung-uk Kim or $in1infty,$t0,$t2 1469e71b7053SJung-uk Kim neg $t0,$in1infty 1470e71b7053SJung-uk Kim or $in1infty,$in1infty,$t0 1471e71b7053SJung-uk Kim sradi $in1infty,$in1infty,63 # !in1infty 1472e71b7053SJung-uk Kim 1473e71b7053SJung-uk Kim ld $acc0,0($bp) # in2_x 1474e71b7053SJung-uk Kim ld $acc1,8($bp) 1475e71b7053SJung-uk Kim ld $acc2,16($bp) 1476e71b7053SJung-uk Kim ld $acc3,24($bp) 1477e71b7053SJung-uk Kim ld $t0,32($bp) # in2_y 1478e71b7053SJung-uk Kim ld $t1,40($bp) 1479e71b7053SJung-uk Kim ld $t2,48($bp) 1480e71b7053SJung-uk Kim ld $t3,56($bp) 1481e71b7053SJung-uk Kim or $acc0,$acc0,$acc1 1482e71b7053SJung-uk Kim or $acc2,$acc2,$acc3 1483e71b7053SJung-uk Kim or $acc0,$acc0,$acc2 1484e71b7053SJung-uk Kim or $t0,$t0,$t1 1485e71b7053SJung-uk Kim or $t2,$t2,$t3 1486e71b7053SJung-uk Kim or $t0,$t0,$t2 1487e71b7053SJung-uk Kim or $in2infty,$acc0,$t0 1488e71b7053SJung-uk Kim neg $t0,$in2infty 1489e71b7053SJung-uk Kim or $in2infty,$in2infty,$t0 1490e71b7053SJung-uk Kim sradi $in2infty,$in2infty,63 # !in2infty 1491e71b7053SJung-uk Kim 1492e71b7053SJung-uk Kim addi $rp,$sp,$Z1sqr 1493e71b7053SJung-uk Kim bl __ecp_nistz256_sqr_mont # p256_sqr_mont(Z1sqr, in1_z); 1494e71b7053SJung-uk Kim 1495e71b7053SJung-uk Kim mr $a0,$acc0 1496e71b7053SJung-uk Kim mr $a1,$acc1 1497e71b7053SJung-uk Kim mr $a2,$acc2 1498e71b7053SJung-uk Kim mr $a3,$acc3 1499e71b7053SJung-uk Kim ld $bi,0($bp_real) 1500e71b7053SJung-uk Kim addi $bp,$bp_real,0 1501e71b7053SJung-uk Kim addi $rp,$sp,$U2 1502e71b7053SJung-uk Kim bl __ecp_nistz256_mul_mont # p256_mul_mont(U2, Z1sqr, in2_x); 1503e71b7053SJung-uk Kim 1504e71b7053SJung-uk Kim addi $bp,$ap_real,0 1505e71b7053SJung-uk Kim ld $bi,64($ap_real) # forward load for p256_mul_mont 1506e71b7053SJung-uk Kim ld $a0,$Z1sqr+0($sp) 1507e71b7053SJung-uk Kim ld $a1,$Z1sqr+8($sp) 1508e71b7053SJung-uk Kim ld $a2,$Z1sqr+16($sp) 1509e71b7053SJung-uk Kim ld $a3,$Z1sqr+24($sp) 1510e71b7053SJung-uk Kim addi $rp,$sp,$H 1511e71b7053SJung-uk Kim bl __ecp_nistz256_sub_from # p256_sub(H, U2, in1_x); 1512e71b7053SJung-uk Kim 1513e71b7053SJung-uk Kim addi $bp,$ap_real,64 1514e71b7053SJung-uk Kim addi $rp,$sp,$S2 1515e71b7053SJung-uk Kim bl __ecp_nistz256_mul_mont # p256_mul_mont(S2, Z1sqr, in1_z); 1516e71b7053SJung-uk Kim 1517e71b7053SJung-uk Kim ld $bi,64($ap_real) 1518e71b7053SJung-uk Kim ld $a0,$H+0($sp) 1519e71b7053SJung-uk Kim ld $a1,$H+8($sp) 1520e71b7053SJung-uk Kim ld $a2,$H+16($sp) 1521e71b7053SJung-uk Kim ld $a3,$H+24($sp) 1522e71b7053SJung-uk Kim addi $bp,$ap_real,64 1523e71b7053SJung-uk Kim addi $rp,$sp,$res_z 1524e71b7053SJung-uk Kim bl __ecp_nistz256_mul_mont # p256_mul_mont(res_z, H, in1_z); 1525e71b7053SJung-uk Kim 1526e71b7053SJung-uk Kim ld $bi,32($bp_real) 1527e71b7053SJung-uk Kim ld $a0,$S2+0($sp) 1528e71b7053SJung-uk Kim ld $a1,$S2+8($sp) 1529e71b7053SJung-uk Kim ld $a2,$S2+16($sp) 1530e71b7053SJung-uk Kim ld $a3,$S2+24($sp) 1531e71b7053SJung-uk Kim addi $bp,$bp_real,32 1532e71b7053SJung-uk Kim addi $rp,$sp,$S2 1533e71b7053SJung-uk Kim bl __ecp_nistz256_mul_mont # p256_mul_mont(S2, S2, in2_y); 1534e71b7053SJung-uk Kim 1535e71b7053SJung-uk Kim addi $bp,$ap_real,32 1536e71b7053SJung-uk Kim ld $a0,$H+0($sp) # forward load for p256_sqr_mont 1537e71b7053SJung-uk Kim ld $a1,$H+8($sp) 1538e71b7053SJung-uk Kim ld $a2,$H+16($sp) 1539e71b7053SJung-uk Kim ld $a3,$H+24($sp) 1540e71b7053SJung-uk Kim addi $rp,$sp,$R 1541e71b7053SJung-uk Kim bl __ecp_nistz256_sub_from # p256_sub(R, S2, in1_y); 1542e71b7053SJung-uk Kim 1543e71b7053SJung-uk Kim addi $rp,$sp,$Hsqr 1544e71b7053SJung-uk Kim bl __ecp_nistz256_sqr_mont # p256_sqr_mont(Hsqr, H); 1545e71b7053SJung-uk Kim 1546e71b7053SJung-uk Kim ld $a0,$R+0($sp) 1547e71b7053SJung-uk Kim ld $a1,$R+8($sp) 1548e71b7053SJung-uk Kim ld $a2,$R+16($sp) 1549e71b7053SJung-uk Kim ld $a3,$R+24($sp) 1550e71b7053SJung-uk Kim addi $rp,$sp,$Rsqr 1551e71b7053SJung-uk Kim bl __ecp_nistz256_sqr_mont # p256_sqr_mont(Rsqr, R); 1552e71b7053SJung-uk Kim 1553e71b7053SJung-uk Kim ld $bi,$H($sp) 1554e71b7053SJung-uk Kim ld $a0,$Hsqr+0($sp) 1555e71b7053SJung-uk Kim ld $a1,$Hsqr+8($sp) 1556e71b7053SJung-uk Kim ld $a2,$Hsqr+16($sp) 1557e71b7053SJung-uk Kim ld $a3,$Hsqr+24($sp) 1558e71b7053SJung-uk Kim addi $bp,$sp,$H 1559e71b7053SJung-uk Kim addi $rp,$sp,$Hcub 1560e71b7053SJung-uk Kim bl __ecp_nistz256_mul_mont # p256_mul_mont(Hcub, Hsqr, H); 1561e71b7053SJung-uk Kim 1562e71b7053SJung-uk Kim ld $bi,0($ap_real) 1563e71b7053SJung-uk Kim ld $a0,$Hsqr+0($sp) 1564e71b7053SJung-uk Kim ld $a1,$Hsqr+8($sp) 1565e71b7053SJung-uk Kim ld $a2,$Hsqr+16($sp) 1566e71b7053SJung-uk Kim ld $a3,$Hsqr+24($sp) 1567e71b7053SJung-uk Kim addi $bp,$ap_real,0 1568e71b7053SJung-uk Kim addi $rp,$sp,$U2 1569e71b7053SJung-uk Kim bl __ecp_nistz256_mul_mont # p256_mul_mont(U2, in1_x, Hsqr); 1570e71b7053SJung-uk Kim 1571e71b7053SJung-uk Kim mr $t0,$acc0 1572e71b7053SJung-uk Kim mr $t1,$acc1 1573e71b7053SJung-uk Kim mr $t2,$acc2 1574e71b7053SJung-uk Kim mr $t3,$acc3 1575e71b7053SJung-uk Kim addi $rp,$sp,$Hsqr 1576e71b7053SJung-uk Kim bl __ecp_nistz256_add # p256_mul_by_2(Hsqr, U2); 1577e71b7053SJung-uk Kim 1578e71b7053SJung-uk Kim addi $bp,$sp,$Rsqr 1579e71b7053SJung-uk Kim addi $rp,$sp,$res_x 1580e71b7053SJung-uk Kim bl __ecp_nistz256_sub_morf # p256_sub(res_x, Rsqr, Hsqr); 1581e71b7053SJung-uk Kim 1582e71b7053SJung-uk Kim addi $bp,$sp,$Hcub 1583e71b7053SJung-uk Kim bl __ecp_nistz256_sub_from # p256_sub(res_x, res_x, Hcub); 1584e71b7053SJung-uk Kim 1585e71b7053SJung-uk Kim addi $bp,$sp,$U2 1586e71b7053SJung-uk Kim ld $bi,32($ap_real) # forward load for p256_mul_mont 1587e71b7053SJung-uk Kim ld $a0,$Hcub+0($sp) 1588e71b7053SJung-uk Kim ld $a1,$Hcub+8($sp) 1589e71b7053SJung-uk Kim ld $a2,$Hcub+16($sp) 1590e71b7053SJung-uk Kim ld $a3,$Hcub+24($sp) 1591e71b7053SJung-uk Kim addi $rp,$sp,$res_y 1592e71b7053SJung-uk Kim bl __ecp_nistz256_sub_morf # p256_sub(res_y, U2, res_x); 1593e71b7053SJung-uk Kim 1594e71b7053SJung-uk Kim addi $bp,$ap_real,32 1595e71b7053SJung-uk Kim addi $rp,$sp,$S2 1596e71b7053SJung-uk Kim bl __ecp_nistz256_mul_mont # p256_mul_mont(S2, in1_y, Hcub); 1597e71b7053SJung-uk Kim 1598e71b7053SJung-uk Kim ld $bi,$R($sp) 1599e71b7053SJung-uk Kim ld $a0,$res_y+0($sp) 1600e71b7053SJung-uk Kim ld $a1,$res_y+8($sp) 1601e71b7053SJung-uk Kim ld $a2,$res_y+16($sp) 1602e71b7053SJung-uk Kim ld $a3,$res_y+24($sp) 1603e71b7053SJung-uk Kim addi $bp,$sp,$R 1604e71b7053SJung-uk Kim addi $rp,$sp,$res_y 1605e71b7053SJung-uk Kim bl __ecp_nistz256_mul_mont # p256_mul_mont(res_y, res_y, R); 1606e71b7053SJung-uk Kim 1607e71b7053SJung-uk Kim addi $bp,$sp,$S2 1608e71b7053SJung-uk Kim bl __ecp_nistz256_sub_from # p256_sub(res_y, res_y, S2); 1609e71b7053SJung-uk Kim 1610e71b7053SJung-uk Kim ld $t0,0($bp_real) # in2 1611e71b7053SJung-uk Kim ld $t1,8($bp_real) 1612e71b7053SJung-uk Kim ld $t2,16($bp_real) 1613e71b7053SJung-uk Kim ld $t3,24($bp_real) 1614e71b7053SJung-uk Kim ld $a0,$res_x+0($sp) # res 1615e71b7053SJung-uk Kim ld $a1,$res_x+8($sp) 1616e71b7053SJung-uk Kim ld $a2,$res_x+16($sp) 1617e71b7053SJung-uk Kim ld $a3,$res_x+24($sp) 1618e71b7053SJung-uk Kim___ 1619e71b7053SJung-uk Kimfor($i=0;$i<64;$i+=32) { # conditional moves 1620e71b7053SJung-uk Kim$code.=<<___; 1621e71b7053SJung-uk Kim ld $acc0,$i+0($ap_real) # in1 1622e71b7053SJung-uk Kim ld $acc1,$i+8($ap_real) 1623e71b7053SJung-uk Kim ld $acc2,$i+16($ap_real) 1624e71b7053SJung-uk Kim ld $acc3,$i+24($ap_real) 1625e71b7053SJung-uk Kim andc $t0,$t0,$in1infty 1626e71b7053SJung-uk Kim andc $t1,$t1,$in1infty 1627e71b7053SJung-uk Kim andc $t2,$t2,$in1infty 1628e71b7053SJung-uk Kim andc $t3,$t3,$in1infty 1629e71b7053SJung-uk Kim and $a0,$a0,$in1infty 1630e71b7053SJung-uk Kim and $a1,$a1,$in1infty 1631e71b7053SJung-uk Kim and $a2,$a2,$in1infty 1632e71b7053SJung-uk Kim and $a3,$a3,$in1infty 1633e71b7053SJung-uk Kim or $t0,$t0,$a0 1634e71b7053SJung-uk Kim or $t1,$t1,$a1 1635e71b7053SJung-uk Kim or $t2,$t2,$a2 1636e71b7053SJung-uk Kim or $t3,$t3,$a3 1637e71b7053SJung-uk Kim andc $acc0,$acc0,$in2infty 1638e71b7053SJung-uk Kim andc $acc1,$acc1,$in2infty 1639e71b7053SJung-uk Kim andc $acc2,$acc2,$in2infty 1640e71b7053SJung-uk Kim andc $acc3,$acc3,$in2infty 1641e71b7053SJung-uk Kim and $t0,$t0,$in2infty 1642e71b7053SJung-uk Kim and $t1,$t1,$in2infty 1643e71b7053SJung-uk Kim and $t2,$t2,$in2infty 1644e71b7053SJung-uk Kim and $t3,$t3,$in2infty 1645e71b7053SJung-uk Kim or $acc0,$acc0,$t0 1646e71b7053SJung-uk Kim or $acc1,$acc1,$t1 1647e71b7053SJung-uk Kim or $acc2,$acc2,$t2 1648e71b7053SJung-uk Kim or $acc3,$acc3,$t3 1649e71b7053SJung-uk Kim___ 1650e71b7053SJung-uk Kim$code.=<<___ if ($i==0); 1651e71b7053SJung-uk Kim ld $t0,32($bp_real) # in2 1652e71b7053SJung-uk Kim ld $t1,40($bp_real) 1653e71b7053SJung-uk Kim ld $t2,48($bp_real) 1654e71b7053SJung-uk Kim ld $t3,56($bp_real) 1655e71b7053SJung-uk Kim___ 1656e71b7053SJung-uk Kim$code.=<<___ if ($i==32); 1657e71b7053SJung-uk Kim li $t0,1 # Lone_mont 1658e71b7053SJung-uk Kim not $t1,$poly1 1659e71b7053SJung-uk Kim li $t2,-1 1660e71b7053SJung-uk Kim not $t3,$poly3 1661e71b7053SJung-uk Kim___ 1662e71b7053SJung-uk Kim$code.=<<___; 1663e71b7053SJung-uk Kim ld $a0,$res_x+$i+32($sp) 1664e71b7053SJung-uk Kim ld $a1,$res_x+$i+40($sp) 1665e71b7053SJung-uk Kim ld $a2,$res_x+$i+48($sp) 1666e71b7053SJung-uk Kim ld $a3,$res_x+$i+56($sp) 1667e71b7053SJung-uk Kim std $acc0,$i+0($rp_real) 1668e71b7053SJung-uk Kim std $acc1,$i+8($rp_real) 1669e71b7053SJung-uk Kim std $acc2,$i+16($rp_real) 1670e71b7053SJung-uk Kim std $acc3,$i+24($rp_real) 1671e71b7053SJung-uk Kim___ 1672e71b7053SJung-uk Kim} 1673e71b7053SJung-uk Kim$code.=<<___; 1674e71b7053SJung-uk Kim ld $acc0,$i+0($ap_real) # in1 1675e71b7053SJung-uk Kim ld $acc1,$i+8($ap_real) 1676e71b7053SJung-uk Kim ld $acc2,$i+16($ap_real) 1677e71b7053SJung-uk Kim ld $acc3,$i+24($ap_real) 1678e71b7053SJung-uk Kim andc $t0,$t0,$in1infty 1679e71b7053SJung-uk Kim andc $t1,$t1,$in1infty 1680e71b7053SJung-uk Kim andc $t2,$t2,$in1infty 1681e71b7053SJung-uk Kim andc $t3,$t3,$in1infty 1682e71b7053SJung-uk Kim and $a0,$a0,$in1infty 1683e71b7053SJung-uk Kim and $a1,$a1,$in1infty 1684e71b7053SJung-uk Kim and $a2,$a2,$in1infty 1685e71b7053SJung-uk Kim and $a3,$a3,$in1infty 1686e71b7053SJung-uk Kim or $t0,$t0,$a0 1687e71b7053SJung-uk Kim or $t1,$t1,$a1 1688e71b7053SJung-uk Kim or $t2,$t2,$a2 1689e71b7053SJung-uk Kim or $t3,$t3,$a3 1690e71b7053SJung-uk Kim andc $acc0,$acc0,$in2infty 1691e71b7053SJung-uk Kim andc $acc1,$acc1,$in2infty 1692e71b7053SJung-uk Kim andc $acc2,$acc2,$in2infty 1693e71b7053SJung-uk Kim andc $acc3,$acc3,$in2infty 1694e71b7053SJung-uk Kim and $t0,$t0,$in2infty 1695e71b7053SJung-uk Kim and $t1,$t1,$in2infty 1696e71b7053SJung-uk Kim and $t2,$t2,$in2infty 1697e71b7053SJung-uk Kim and $t3,$t3,$in2infty 1698e71b7053SJung-uk Kim or $acc0,$acc0,$t0 1699e71b7053SJung-uk Kim or $acc1,$acc1,$t1 1700e71b7053SJung-uk Kim or $acc2,$acc2,$t2 1701e71b7053SJung-uk Kim or $acc3,$acc3,$t3 1702e71b7053SJung-uk Kim std $acc0,$i+0($rp_real) 1703e71b7053SJung-uk Kim std $acc1,$i+8($rp_real) 1704e71b7053SJung-uk Kim std $acc2,$i+16($rp_real) 1705e71b7053SJung-uk Kim std $acc3,$i+24($rp_real) 1706e71b7053SJung-uk Kim 1707e71b7053SJung-uk Kim mtlr r0 1708e71b7053SJung-uk Kim ld r16,$FRAME-8*16($sp) 1709e71b7053SJung-uk Kim ld r17,$FRAME-8*15($sp) 1710e71b7053SJung-uk Kim ld r18,$FRAME-8*14($sp) 1711e71b7053SJung-uk Kim ld r19,$FRAME-8*13($sp) 1712e71b7053SJung-uk Kim ld r20,$FRAME-8*12($sp) 1713e71b7053SJung-uk Kim ld r21,$FRAME-8*11($sp) 1714e71b7053SJung-uk Kim ld r22,$FRAME-8*10($sp) 1715e71b7053SJung-uk Kim ld r23,$FRAME-8*9($sp) 1716e71b7053SJung-uk Kim ld r24,$FRAME-8*8($sp) 1717e71b7053SJung-uk Kim ld r25,$FRAME-8*7($sp) 1718e71b7053SJung-uk Kim ld r26,$FRAME-8*6($sp) 1719e71b7053SJung-uk Kim ld r27,$FRAME-8*5($sp) 1720e71b7053SJung-uk Kim ld r28,$FRAME-8*4($sp) 1721e71b7053SJung-uk Kim ld r29,$FRAME-8*3($sp) 1722e71b7053SJung-uk Kim ld r30,$FRAME-8*2($sp) 1723e71b7053SJung-uk Kim ld r31,$FRAME-8*1($sp) 1724e71b7053SJung-uk Kim addi $sp,$sp,$FRAME 1725e71b7053SJung-uk Kim blr 1726e71b7053SJung-uk Kim .long 0 1727e71b7053SJung-uk Kim .byte 0,12,4,0,0x80,16,3,0 1728e71b7053SJung-uk Kim .long 0 1729e71b7053SJung-uk Kim.size ecp_nistz256_point_add_affine,.-ecp_nistz256_point_add_affine 1730e71b7053SJung-uk Kim___ 1731e71b7053SJung-uk Kim} 1732e71b7053SJung-uk Kimif (1) { 1733e71b7053SJung-uk Kimmy ($ordk,$ord0,$ord1,$t4) = map("r$_",(18..21)); 1734e71b7053SJung-uk Kimmy ($ord2,$ord3,$zr) = ($poly1,$poly3,"r0"); 1735e71b7053SJung-uk Kim 1736e71b7053SJung-uk Kim$code.=<<___; 1737e71b7053SJung-uk Kim######################################################################## 1738e71b7053SJung-uk Kim# void ecp_nistz256_ord_mul_mont(uint64_t res[4], uint64_t a[4], 1739e71b7053SJung-uk Kim# uint64_t b[4]); 1740e71b7053SJung-uk Kim.globl ecp_nistz256_ord_mul_mont 1741e71b7053SJung-uk Kim.align 5 1742e71b7053SJung-uk Kimecp_nistz256_ord_mul_mont: 1743e71b7053SJung-uk Kim stdu $sp,-160($sp) 1744e71b7053SJung-uk Kim std r18,48($sp) 1745e71b7053SJung-uk Kim std r19,56($sp) 1746e71b7053SJung-uk Kim std r20,64($sp) 1747e71b7053SJung-uk Kim std r21,72($sp) 1748e71b7053SJung-uk Kim std r22,80($sp) 1749e71b7053SJung-uk Kim std r23,88($sp) 1750e71b7053SJung-uk Kim std r24,96($sp) 1751e71b7053SJung-uk Kim std r25,104($sp) 1752e71b7053SJung-uk Kim std r26,112($sp) 1753e71b7053SJung-uk Kim std r27,120($sp) 1754e71b7053SJung-uk Kim std r28,128($sp) 1755e71b7053SJung-uk Kim std r29,136($sp) 1756e71b7053SJung-uk Kim std r30,144($sp) 1757e71b7053SJung-uk Kim std r31,152($sp) 1758e71b7053SJung-uk Kim 1759e71b7053SJung-uk Kim ld $a0,0($ap) 1760e71b7053SJung-uk Kim ld $bi,0($bp) 1761e71b7053SJung-uk Kim ld $a1,8($ap) 1762e71b7053SJung-uk Kim ld $a2,16($ap) 1763e71b7053SJung-uk Kim ld $a3,24($ap) 1764e71b7053SJung-uk Kim 1765e71b7053SJung-uk Kim lis $ordk,0xccd1 1766e71b7053SJung-uk Kim lis $ord0,0xf3b9 1767e71b7053SJung-uk Kim lis $ord1,0xbce6 1768e71b7053SJung-uk Kim ori $ordk,$ordk,0xc8aa 1769e71b7053SJung-uk Kim ori $ord0,$ord0,0xcac2 1770e71b7053SJung-uk Kim ori $ord1,$ord1,0xfaad 1771e71b7053SJung-uk Kim sldi $ordk,$ordk,32 1772e71b7053SJung-uk Kim sldi $ord0,$ord0,32 1773e71b7053SJung-uk Kim sldi $ord1,$ord1,32 1774e71b7053SJung-uk Kim oris $ordk,$ordk,0xee00 1775e71b7053SJung-uk Kim oris $ord0,$ord0,0xfc63 1776e71b7053SJung-uk Kim oris $ord1,$ord1,0xa717 1777e71b7053SJung-uk Kim ori $ordk,$ordk,0xbc4f # 0xccd1c8aaee00bc4f 1778e71b7053SJung-uk Kim ori $ord0,$ord0,0x2551 # 0xf3b9cac2fc632551 1779e71b7053SJung-uk Kim ori $ord1,$ord1,0x9e84 # 0xbce6faada7179e84 1780e71b7053SJung-uk Kim li $ord2,-1 # 0xffffffffffffffff 1781e71b7053SJung-uk Kim sldi $ord3,$ord2,32 # 0xffffffff00000000 1782e71b7053SJung-uk Kim li $zr,0 1783e71b7053SJung-uk Kim 1784e71b7053SJung-uk Kim mulld $acc0,$a0,$bi # a[0]*b[0] 1785e71b7053SJung-uk Kim mulhdu $t0,$a0,$bi 1786e71b7053SJung-uk Kim 1787e71b7053SJung-uk Kim mulld $acc1,$a1,$bi # a[1]*b[0] 1788e71b7053SJung-uk Kim mulhdu $t1,$a1,$bi 1789e71b7053SJung-uk Kim 1790e71b7053SJung-uk Kim mulld $acc2,$a2,$bi # a[2]*b[0] 1791e71b7053SJung-uk Kim mulhdu $t2,$a2,$bi 1792e71b7053SJung-uk Kim 1793e71b7053SJung-uk Kim mulld $acc3,$a3,$bi # a[3]*b[0] 1794e71b7053SJung-uk Kim mulhdu $acc4,$a3,$bi 1795e71b7053SJung-uk Kim 1796e71b7053SJung-uk Kim mulld $t4,$acc0,$ordk 1797e71b7053SJung-uk Kim 1798e71b7053SJung-uk Kim addc $acc1,$acc1,$t0 # accumulate high parts of multiplication 1799e71b7053SJung-uk Kim adde $acc2,$acc2,$t1 1800e71b7053SJung-uk Kim adde $acc3,$acc3,$t2 1801e71b7053SJung-uk Kim addze $acc4,$acc4 1802e71b7053SJung-uk Kim li $acc5,0 1803e71b7053SJung-uk Kim___ 1804e71b7053SJung-uk Kimfor ($i=1;$i<4;$i++) { 1805e71b7053SJung-uk Kim ################################################################ 1806e71b7053SJung-uk Kim # ffff0000.ffffffff.yyyyyyyy.zzzzzzzz 1807e71b7053SJung-uk Kim # * abcdefgh 1808e71b7053SJung-uk Kim # + xxxxxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx 1809e71b7053SJung-uk Kim # 1810e71b7053SJung-uk Kim # Now observing that ff..ff*x = (2^n-1)*x = 2^n*x-x, we 1811e71b7053SJung-uk Kim # rewrite above as: 1812e71b7053SJung-uk Kim # 1813e71b7053SJung-uk Kim # xxxxxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx 1814e71b7053SJung-uk Kim # - 0000abcd.efgh0000.abcdefgh.00000000.00000000 1815e71b7053SJung-uk Kim # + abcdefgh.abcdefgh.yzayzbyz.cyzdyzey.zfyzgyzh 1816e71b7053SJung-uk Kim$code.=<<___; 1817e71b7053SJung-uk Kim ld $bi,8*$i($bp) # b[i] 1818e71b7053SJung-uk Kim 1819e71b7053SJung-uk Kim sldi $t0,$t4,32 1820e71b7053SJung-uk Kim subfc $acc2,$t4,$acc2 1821e71b7053SJung-uk Kim srdi $t1,$t4,32 1822e71b7053SJung-uk Kim subfe $acc3,$t0,$acc3 1823e71b7053SJung-uk Kim subfe $acc4,$t1,$acc4 1824e71b7053SJung-uk Kim subfe $acc5,$zr,$acc5 1825e71b7053SJung-uk Kim 1826e71b7053SJung-uk Kim addic $t0,$acc0,-1 # discarded 1827e71b7053SJung-uk Kim mulhdu $t1,$ord0,$t4 1828e71b7053SJung-uk Kim mulld $t2,$ord1,$t4 1829e71b7053SJung-uk Kim mulhdu $t3,$ord1,$t4 1830e71b7053SJung-uk Kim 1831e71b7053SJung-uk Kim adde $t2,$t2,$t1 1832e71b7053SJung-uk Kim mulld $t0,$a0,$bi 1833e71b7053SJung-uk Kim addze $t3,$t3 1834e71b7053SJung-uk Kim mulld $t1,$a1,$bi 1835e71b7053SJung-uk Kim 1836e71b7053SJung-uk Kim addc $acc0,$acc1,$t2 1837e71b7053SJung-uk Kim mulld $t2,$a2,$bi 1838e71b7053SJung-uk Kim adde $acc1,$acc2,$t3 1839e71b7053SJung-uk Kim mulld $t3,$a3,$bi 1840e71b7053SJung-uk Kim adde $acc2,$acc3,$t4 1841e71b7053SJung-uk Kim adde $acc3,$acc4,$t4 1842e71b7053SJung-uk Kim addze $acc4,$acc5 1843e71b7053SJung-uk Kim 1844e71b7053SJung-uk Kim addc $acc0,$acc0,$t0 # accumulate low parts 1845e71b7053SJung-uk Kim mulhdu $t0,$a0,$bi 1846e71b7053SJung-uk Kim adde $acc1,$acc1,$t1 1847e71b7053SJung-uk Kim mulhdu $t1,$a1,$bi 1848e71b7053SJung-uk Kim adde $acc2,$acc2,$t2 1849e71b7053SJung-uk Kim mulhdu $t2,$a2,$bi 1850e71b7053SJung-uk Kim adde $acc3,$acc3,$t3 1851e71b7053SJung-uk Kim mulhdu $t3,$a3,$bi 1852e71b7053SJung-uk Kim addze $acc4,$acc4 1853e71b7053SJung-uk Kim mulld $t4,$acc0,$ordk 1854e71b7053SJung-uk Kim addc $acc1,$acc1,$t0 # accumulate high parts 1855e71b7053SJung-uk Kim adde $acc2,$acc2,$t1 1856e71b7053SJung-uk Kim adde $acc3,$acc3,$t2 1857e71b7053SJung-uk Kim adde $acc4,$acc4,$t3 1858e71b7053SJung-uk Kim addze $acc5,$zr 1859e71b7053SJung-uk Kim___ 1860e71b7053SJung-uk Kim} 1861e71b7053SJung-uk Kim$code.=<<___; 1862e71b7053SJung-uk Kim sldi $t0,$t4,32 # last reduction 1863e71b7053SJung-uk Kim subfc $acc2,$t4,$acc2 1864e71b7053SJung-uk Kim srdi $t1,$t4,32 1865e71b7053SJung-uk Kim subfe $acc3,$t0,$acc3 1866e71b7053SJung-uk Kim subfe $acc4,$t1,$acc4 1867e71b7053SJung-uk Kim subfe $acc5,$zr,$acc5 1868e71b7053SJung-uk Kim 1869e71b7053SJung-uk Kim addic $t0,$acc0,-1 # discarded 1870e71b7053SJung-uk Kim mulhdu $t1,$ord0,$t4 1871e71b7053SJung-uk Kim mulld $t2,$ord1,$t4 1872e71b7053SJung-uk Kim mulhdu $t3,$ord1,$t4 1873e71b7053SJung-uk Kim 1874e71b7053SJung-uk Kim adde $t2,$t2,$t1 1875e71b7053SJung-uk Kim addze $t3,$t3 1876e71b7053SJung-uk Kim 1877e71b7053SJung-uk Kim addc $acc0,$acc1,$t2 1878e71b7053SJung-uk Kim adde $acc1,$acc2,$t3 1879e71b7053SJung-uk Kim adde $acc2,$acc3,$t4 1880e71b7053SJung-uk Kim adde $acc3,$acc4,$t4 1881e71b7053SJung-uk Kim addze $acc4,$acc5 1882e71b7053SJung-uk Kim 1883e71b7053SJung-uk Kim subfc $acc0,$ord0,$acc0 # ret -= modulus 1884e71b7053SJung-uk Kim subfe $acc1,$ord1,$acc1 1885e71b7053SJung-uk Kim subfe $acc2,$ord2,$acc2 1886e71b7053SJung-uk Kim subfe $acc3,$ord3,$acc3 1887e71b7053SJung-uk Kim subfe $acc4,$zr,$acc4 1888e71b7053SJung-uk Kim 1889e71b7053SJung-uk Kim and $t0,$ord0,$acc4 1890e71b7053SJung-uk Kim and $t1,$ord1,$acc4 1891e71b7053SJung-uk Kim addc $acc0,$acc0,$t0 # ret += modulus if borrow 1892e71b7053SJung-uk Kim and $t3,$ord3,$acc4 1893e71b7053SJung-uk Kim adde $acc1,$acc1,$t1 1894e71b7053SJung-uk Kim adde $acc2,$acc2,$acc4 1895e71b7053SJung-uk Kim adde $acc3,$acc3,$t3 1896e71b7053SJung-uk Kim 1897e71b7053SJung-uk Kim std $acc0,0($rp) 1898e71b7053SJung-uk Kim std $acc1,8($rp) 1899e71b7053SJung-uk Kim std $acc2,16($rp) 1900e71b7053SJung-uk Kim std $acc3,24($rp) 1901e71b7053SJung-uk Kim 1902e71b7053SJung-uk Kim ld r18,48($sp) 1903e71b7053SJung-uk Kim ld r19,56($sp) 1904e71b7053SJung-uk Kim ld r20,64($sp) 1905e71b7053SJung-uk Kim ld r21,72($sp) 1906e71b7053SJung-uk Kim ld r22,80($sp) 1907e71b7053SJung-uk Kim ld r23,88($sp) 1908e71b7053SJung-uk Kim ld r24,96($sp) 1909e71b7053SJung-uk Kim ld r25,104($sp) 1910e71b7053SJung-uk Kim ld r26,112($sp) 1911e71b7053SJung-uk Kim ld r27,120($sp) 1912e71b7053SJung-uk Kim ld r28,128($sp) 1913e71b7053SJung-uk Kim ld r29,136($sp) 1914e71b7053SJung-uk Kim ld r30,144($sp) 1915e71b7053SJung-uk Kim ld r31,152($sp) 1916e71b7053SJung-uk Kim addi $sp,$sp,160 1917e71b7053SJung-uk Kim blr 1918e71b7053SJung-uk Kim .long 0 1919e71b7053SJung-uk Kim .byte 0,12,4,0,0x80,14,3,0 1920e71b7053SJung-uk Kim .long 0 1921e71b7053SJung-uk Kim.size ecp_nistz256_ord_mul_mont,.-ecp_nistz256_ord_mul_mont 1922e71b7053SJung-uk Kim 1923e71b7053SJung-uk Kim################################################################################ 1924e71b7053SJung-uk Kim# void ecp_nistz256_ord_sqr_mont(uint64_t res[4], uint64_t a[4], 1925*b077aed3SPierre Pronchery# uint64_t rep); 1926e71b7053SJung-uk Kim.globl ecp_nistz256_ord_sqr_mont 1927e71b7053SJung-uk Kim.align 5 1928e71b7053SJung-uk Kimecp_nistz256_ord_sqr_mont: 1929e71b7053SJung-uk Kim stdu $sp,-160($sp) 1930e71b7053SJung-uk Kim std r18,48($sp) 1931e71b7053SJung-uk Kim std r19,56($sp) 1932e71b7053SJung-uk Kim std r20,64($sp) 1933e71b7053SJung-uk Kim std r21,72($sp) 1934e71b7053SJung-uk Kim std r22,80($sp) 1935e71b7053SJung-uk Kim std r23,88($sp) 1936e71b7053SJung-uk Kim std r24,96($sp) 1937e71b7053SJung-uk Kim std r25,104($sp) 1938e71b7053SJung-uk Kim std r26,112($sp) 1939e71b7053SJung-uk Kim std r27,120($sp) 1940e71b7053SJung-uk Kim std r28,128($sp) 1941e71b7053SJung-uk Kim std r29,136($sp) 1942e71b7053SJung-uk Kim std r30,144($sp) 1943e71b7053SJung-uk Kim std r31,152($sp) 1944e71b7053SJung-uk Kim 1945e71b7053SJung-uk Kim mtctr $bp 1946e71b7053SJung-uk Kim 1947e71b7053SJung-uk Kim ld $a0,0($ap) 1948e71b7053SJung-uk Kim ld $a1,8($ap) 1949e71b7053SJung-uk Kim ld $a2,16($ap) 1950e71b7053SJung-uk Kim ld $a3,24($ap) 1951e71b7053SJung-uk Kim 1952e71b7053SJung-uk Kim lis $ordk,0xccd1 1953e71b7053SJung-uk Kim lis $ord0,0xf3b9 1954e71b7053SJung-uk Kim lis $ord1,0xbce6 1955e71b7053SJung-uk Kim ori $ordk,$ordk,0xc8aa 1956e71b7053SJung-uk Kim ori $ord0,$ord0,0xcac2 1957e71b7053SJung-uk Kim ori $ord1,$ord1,0xfaad 1958e71b7053SJung-uk Kim sldi $ordk,$ordk,32 1959e71b7053SJung-uk Kim sldi $ord0,$ord0,32 1960e71b7053SJung-uk Kim sldi $ord1,$ord1,32 1961e71b7053SJung-uk Kim oris $ordk,$ordk,0xee00 1962e71b7053SJung-uk Kim oris $ord0,$ord0,0xfc63 1963e71b7053SJung-uk Kim oris $ord1,$ord1,0xa717 1964e71b7053SJung-uk Kim ori $ordk,$ordk,0xbc4f # 0xccd1c8aaee00bc4f 1965e71b7053SJung-uk Kim ori $ord0,$ord0,0x2551 # 0xf3b9cac2fc632551 1966e71b7053SJung-uk Kim ori $ord1,$ord1,0x9e84 # 0xbce6faada7179e84 1967e71b7053SJung-uk Kim li $ord2,-1 # 0xffffffffffffffff 1968e71b7053SJung-uk Kim sldi $ord3,$ord2,32 # 0xffffffff00000000 1969e71b7053SJung-uk Kim li $zr,0 1970e71b7053SJung-uk Kim b .Loop_ord_sqr 1971e71b7053SJung-uk Kim 1972e71b7053SJung-uk Kim.align 5 1973e71b7053SJung-uk Kim.Loop_ord_sqr: 1974e71b7053SJung-uk Kim ################################################################ 1975e71b7053SJung-uk Kim # | | | | | |a1*a0| | 1976e71b7053SJung-uk Kim # | | | | |a2*a0| | | 1977e71b7053SJung-uk Kim # | |a3*a2|a3*a0| | | | 1978e71b7053SJung-uk Kim # | | | |a2*a1| | | | 1979e71b7053SJung-uk Kim # | | |a3*a1| | | | | 1980e71b7053SJung-uk Kim # *| | | | | | | | 2| 1981e71b7053SJung-uk Kim # +|a3*a3|a2*a2|a1*a1|a0*a0| 1982e71b7053SJung-uk Kim # |--+--+--+--+--+--+--+--| 1983e71b7053SJung-uk Kim # |A7|A6|A5|A4|A3|A2|A1|A0|, where Ax is $accx, i.e. follow $accx 1984e71b7053SJung-uk Kim # 1985e71b7053SJung-uk Kim # "can't overflow" below mark carrying into high part of 1986e71b7053SJung-uk Kim # multiplication result, which can't overflow, because it 1987e71b7053SJung-uk Kim # can never be all ones. 1988e71b7053SJung-uk Kim 1989e71b7053SJung-uk Kim mulld $acc1,$a1,$a0 # a[1]*a[0] 1990e71b7053SJung-uk Kim mulhdu $t1,$a1,$a0 1991e71b7053SJung-uk Kim mulld $acc2,$a2,$a0 # a[2]*a[0] 1992e71b7053SJung-uk Kim mulhdu $t2,$a2,$a0 1993e71b7053SJung-uk Kim mulld $acc3,$a3,$a0 # a[3]*a[0] 1994e71b7053SJung-uk Kim mulhdu $acc4,$a3,$a0 1995e71b7053SJung-uk Kim 1996e71b7053SJung-uk Kim addc $acc2,$acc2,$t1 # accumulate high parts of multiplication 1997e71b7053SJung-uk Kim mulld $t0,$a2,$a1 # a[2]*a[1] 1998e71b7053SJung-uk Kim mulhdu $t1,$a2,$a1 1999e71b7053SJung-uk Kim adde $acc3,$acc3,$t2 2000e71b7053SJung-uk Kim mulld $t2,$a3,$a1 # a[3]*a[1] 2001e71b7053SJung-uk Kim mulhdu $t3,$a3,$a1 2002e71b7053SJung-uk Kim addze $acc4,$acc4 # can't overflow 2003e71b7053SJung-uk Kim 2004e71b7053SJung-uk Kim mulld $acc5,$a3,$a2 # a[3]*a[2] 2005e71b7053SJung-uk Kim mulhdu $acc6,$a3,$a2 2006e71b7053SJung-uk Kim 2007e71b7053SJung-uk Kim addc $t1,$t1,$t2 # accumulate high parts of multiplication 2008e71b7053SJung-uk Kim mulld $acc0,$a0,$a0 # a[0]*a[0] 2009e71b7053SJung-uk Kim addze $t2,$t3 # can't overflow 2010e71b7053SJung-uk Kim 2011e71b7053SJung-uk Kim addc $acc3,$acc3,$t0 # accumulate low parts of multiplication 2012e71b7053SJung-uk Kim mulhdu $a0,$a0,$a0 2013e71b7053SJung-uk Kim adde $acc4,$acc4,$t1 2014e71b7053SJung-uk Kim mulld $t1,$a1,$a1 # a[1]*a[1] 2015e71b7053SJung-uk Kim adde $acc5,$acc5,$t2 2016e71b7053SJung-uk Kim mulhdu $a1,$a1,$a1 2017e71b7053SJung-uk Kim addze $acc6,$acc6 # can't overflow 2018e71b7053SJung-uk Kim 2019e71b7053SJung-uk Kim addc $acc1,$acc1,$acc1 # acc[1-6]*=2 2020e71b7053SJung-uk Kim mulld $t2,$a2,$a2 # a[2]*a[2] 2021e71b7053SJung-uk Kim adde $acc2,$acc2,$acc2 2022e71b7053SJung-uk Kim mulhdu $a2,$a2,$a2 2023e71b7053SJung-uk Kim adde $acc3,$acc3,$acc3 2024e71b7053SJung-uk Kim mulld $t3,$a3,$a3 # a[3]*a[3] 2025e71b7053SJung-uk Kim adde $acc4,$acc4,$acc4 2026e71b7053SJung-uk Kim mulhdu $a3,$a3,$a3 2027e71b7053SJung-uk Kim adde $acc5,$acc5,$acc5 2028e71b7053SJung-uk Kim adde $acc6,$acc6,$acc6 2029e71b7053SJung-uk Kim addze $acc7,$zr 2030e71b7053SJung-uk Kim 2031e71b7053SJung-uk Kim addc $acc1,$acc1,$a0 # +a[i]*a[i] 2032e71b7053SJung-uk Kim mulld $t4,$acc0,$ordk 2033e71b7053SJung-uk Kim adde $acc2,$acc2,$t1 2034e71b7053SJung-uk Kim adde $acc3,$acc3,$a1 2035e71b7053SJung-uk Kim adde $acc4,$acc4,$t2 2036e71b7053SJung-uk Kim adde $acc5,$acc5,$a2 2037e71b7053SJung-uk Kim adde $acc6,$acc6,$t3 2038e71b7053SJung-uk Kim adde $acc7,$acc7,$a3 2039e71b7053SJung-uk Kim___ 2040e71b7053SJung-uk Kimfor($i=0; $i<4; $i++) { # reductions 2041e71b7053SJung-uk Kim$code.=<<___; 2042e71b7053SJung-uk Kim addic $t0,$acc0,-1 # discarded 2043e71b7053SJung-uk Kim mulhdu $t1,$ord0,$t4 2044e71b7053SJung-uk Kim mulld $t2,$ord1,$t4 2045e71b7053SJung-uk Kim mulhdu $t3,$ord1,$t4 2046e71b7053SJung-uk Kim 2047e71b7053SJung-uk Kim adde $t2,$t2,$t1 2048e71b7053SJung-uk Kim addze $t3,$t3 2049e71b7053SJung-uk Kim 2050e71b7053SJung-uk Kim addc $acc0,$acc1,$t2 2051e71b7053SJung-uk Kim adde $acc1,$acc2,$t3 2052e71b7053SJung-uk Kim adde $acc2,$acc3,$t4 2053e71b7053SJung-uk Kim adde $acc3,$zr,$t4 # can't overflow 2054e71b7053SJung-uk Kim___ 2055e71b7053SJung-uk Kim$code.=<<___ if ($i<3); 2056e71b7053SJung-uk Kim mulld $t3,$acc0,$ordk 2057e71b7053SJung-uk Kim___ 2058e71b7053SJung-uk Kim$code.=<<___; 2059e71b7053SJung-uk Kim sldi $t0,$t4,32 2060e71b7053SJung-uk Kim subfc $acc1,$t4,$acc1 2061e71b7053SJung-uk Kim srdi $t1,$t4,32 2062e71b7053SJung-uk Kim subfe $acc2,$t0,$acc2 2063e71b7053SJung-uk Kim subfe $acc3,$t1,$acc3 # can't borrow 2064e71b7053SJung-uk Kim___ 2065e71b7053SJung-uk Kim ($t3,$t4) = ($t4,$t3); 2066e71b7053SJung-uk Kim} 2067e71b7053SJung-uk Kim$code.=<<___; 2068e71b7053SJung-uk Kim addc $acc0,$acc0,$acc4 # accumulate upper half 2069e71b7053SJung-uk Kim adde $acc1,$acc1,$acc5 2070e71b7053SJung-uk Kim adde $acc2,$acc2,$acc6 2071e71b7053SJung-uk Kim adde $acc3,$acc3,$acc7 2072e71b7053SJung-uk Kim addze $acc4,$zr 2073e71b7053SJung-uk Kim 2074e71b7053SJung-uk Kim subfc $acc0,$ord0,$acc0 # ret -= modulus 2075e71b7053SJung-uk Kim subfe $acc1,$ord1,$acc1 2076e71b7053SJung-uk Kim subfe $acc2,$ord2,$acc2 2077e71b7053SJung-uk Kim subfe $acc3,$ord3,$acc3 2078e71b7053SJung-uk Kim subfe $acc4,$zr,$acc4 2079e71b7053SJung-uk Kim 2080e71b7053SJung-uk Kim and $t0,$ord0,$acc4 2081e71b7053SJung-uk Kim and $t1,$ord1,$acc4 2082e71b7053SJung-uk Kim addc $a0,$acc0,$t0 # ret += modulus if borrow 2083e71b7053SJung-uk Kim and $t3,$ord3,$acc4 2084e71b7053SJung-uk Kim adde $a1,$acc1,$t1 2085e71b7053SJung-uk Kim adde $a2,$acc2,$acc4 2086e71b7053SJung-uk Kim adde $a3,$acc3,$t3 2087e71b7053SJung-uk Kim 2088e71b7053SJung-uk Kim bdnz .Loop_ord_sqr 2089e71b7053SJung-uk Kim 2090e71b7053SJung-uk Kim std $a0,0($rp) 2091e71b7053SJung-uk Kim std $a1,8($rp) 2092e71b7053SJung-uk Kim std $a2,16($rp) 2093e71b7053SJung-uk Kim std $a3,24($rp) 2094e71b7053SJung-uk Kim 2095e71b7053SJung-uk Kim ld r18,48($sp) 2096e71b7053SJung-uk Kim ld r19,56($sp) 2097e71b7053SJung-uk Kim ld r20,64($sp) 2098e71b7053SJung-uk Kim ld r21,72($sp) 2099e71b7053SJung-uk Kim ld r22,80($sp) 2100e71b7053SJung-uk Kim ld r23,88($sp) 2101e71b7053SJung-uk Kim ld r24,96($sp) 2102e71b7053SJung-uk Kim ld r25,104($sp) 2103e71b7053SJung-uk Kim ld r26,112($sp) 2104e71b7053SJung-uk Kim ld r27,120($sp) 2105e71b7053SJung-uk Kim ld r28,128($sp) 2106e71b7053SJung-uk Kim ld r29,136($sp) 2107e71b7053SJung-uk Kim ld r30,144($sp) 2108e71b7053SJung-uk Kim ld r31,152($sp) 2109e71b7053SJung-uk Kim addi $sp,$sp,160 2110e71b7053SJung-uk Kim blr 2111e71b7053SJung-uk Kim .long 0 2112e71b7053SJung-uk Kim .byte 0,12,4,0,0x80,14,3,0 2113e71b7053SJung-uk Kim .long 0 2114e71b7053SJung-uk Kim.size ecp_nistz256_ord_sqr_mont,.-ecp_nistz256_ord_sqr_mont 2115e71b7053SJung-uk Kim___ 2116e71b7053SJung-uk Kim} } 2117e71b7053SJung-uk Kim 2118e71b7053SJung-uk Kim######################################################################## 2119e71b7053SJung-uk Kim# scatter-gather subroutines 2120e71b7053SJung-uk Kim{ 2121e71b7053SJung-uk Kimmy ($out,$inp,$index,$mask)=map("r$_",(3..7)); 2122e71b7053SJung-uk Kim$code.=<<___; 2123e71b7053SJung-uk Kim######################################################################## 2124e71b7053SJung-uk Kim# void ecp_nistz256_scatter_w5(void *out, const P256_POINT *inp, 2125e71b7053SJung-uk Kim# int index); 2126e71b7053SJung-uk Kim.globl ecp_nistz256_scatter_w5 2127e71b7053SJung-uk Kim.align 4 2128e71b7053SJung-uk Kimecp_nistz256_scatter_w5: 2129e71b7053SJung-uk Kim slwi $index,$index,2 2130e71b7053SJung-uk Kim add $out,$out,$index 2131e71b7053SJung-uk Kim 2132e71b7053SJung-uk Kim ld r8, 0($inp) # X 2133e71b7053SJung-uk Kim ld r9, 8($inp) 2134e71b7053SJung-uk Kim ld r10,16($inp) 2135e71b7053SJung-uk Kim ld r11,24($inp) 2136e71b7053SJung-uk Kim 2137e71b7053SJung-uk Kim stw r8, 64*0-4($out) 2138e71b7053SJung-uk Kim srdi r8, r8, 32 2139e71b7053SJung-uk Kim stw r9, 64*1-4($out) 2140e71b7053SJung-uk Kim srdi r9, r9, 32 2141e71b7053SJung-uk Kim stw r10,64*2-4($out) 2142e71b7053SJung-uk Kim srdi r10,r10,32 2143e71b7053SJung-uk Kim stw r11,64*3-4($out) 2144e71b7053SJung-uk Kim srdi r11,r11,32 2145e71b7053SJung-uk Kim stw r8, 64*4-4($out) 2146e71b7053SJung-uk Kim stw r9, 64*5-4($out) 2147e71b7053SJung-uk Kim stw r10,64*6-4($out) 2148e71b7053SJung-uk Kim stw r11,64*7-4($out) 2149e71b7053SJung-uk Kim addi $out,$out,64*8 2150e71b7053SJung-uk Kim 2151e71b7053SJung-uk Kim ld r8, 32($inp) # Y 2152e71b7053SJung-uk Kim ld r9, 40($inp) 2153e71b7053SJung-uk Kim ld r10,48($inp) 2154e71b7053SJung-uk Kim ld r11,56($inp) 2155e71b7053SJung-uk Kim 2156e71b7053SJung-uk Kim stw r8, 64*0-4($out) 2157e71b7053SJung-uk Kim srdi r8, r8, 32 2158e71b7053SJung-uk Kim stw r9, 64*1-4($out) 2159e71b7053SJung-uk Kim srdi r9, r9, 32 2160e71b7053SJung-uk Kim stw r10,64*2-4($out) 2161e71b7053SJung-uk Kim srdi r10,r10,32 2162e71b7053SJung-uk Kim stw r11,64*3-4($out) 2163e71b7053SJung-uk Kim srdi r11,r11,32 2164e71b7053SJung-uk Kim stw r8, 64*4-4($out) 2165e71b7053SJung-uk Kim stw r9, 64*5-4($out) 2166e71b7053SJung-uk Kim stw r10,64*6-4($out) 2167e71b7053SJung-uk Kim stw r11,64*7-4($out) 2168e71b7053SJung-uk Kim addi $out,$out,64*8 2169e71b7053SJung-uk Kim 2170e71b7053SJung-uk Kim ld r8, 64($inp) # Z 2171e71b7053SJung-uk Kim ld r9, 72($inp) 2172e71b7053SJung-uk Kim ld r10,80($inp) 2173e71b7053SJung-uk Kim ld r11,88($inp) 2174e71b7053SJung-uk Kim 2175e71b7053SJung-uk Kim stw r8, 64*0-4($out) 2176e71b7053SJung-uk Kim srdi r8, r8, 32 2177e71b7053SJung-uk Kim stw r9, 64*1-4($out) 2178e71b7053SJung-uk Kim srdi r9, r9, 32 2179e71b7053SJung-uk Kim stw r10,64*2-4($out) 2180e71b7053SJung-uk Kim srdi r10,r10,32 2181e71b7053SJung-uk Kim stw r11,64*3-4($out) 2182e71b7053SJung-uk Kim srdi r11,r11,32 2183e71b7053SJung-uk Kim stw r8, 64*4-4($out) 2184e71b7053SJung-uk Kim stw r9, 64*5-4($out) 2185e71b7053SJung-uk Kim stw r10,64*6-4($out) 2186e71b7053SJung-uk Kim stw r11,64*7-4($out) 2187e71b7053SJung-uk Kim 2188e71b7053SJung-uk Kim blr 2189e71b7053SJung-uk Kim .long 0 2190e71b7053SJung-uk Kim .byte 0,12,0x14,0,0,0,3,0 2191e71b7053SJung-uk Kim .long 0 2192e71b7053SJung-uk Kim.size ecp_nistz256_scatter_w5,.-ecp_nistz256_scatter_w5 2193e71b7053SJung-uk Kim 2194e71b7053SJung-uk Kim######################################################################## 2195e71b7053SJung-uk Kim# void ecp_nistz256_gather_w5(P256_POINT *out, const void *inp, 2196e71b7053SJung-uk Kim# int index); 2197e71b7053SJung-uk Kim.globl ecp_nistz256_gather_w5 2198e71b7053SJung-uk Kim.align 4 2199e71b7053SJung-uk Kimecp_nistz256_gather_w5: 2200e71b7053SJung-uk Kim neg r0,$index 2201e71b7053SJung-uk Kim sradi r0,r0,63 2202e71b7053SJung-uk Kim 2203e71b7053SJung-uk Kim add $index,$index,r0 2204e71b7053SJung-uk Kim slwi $index,$index,2 2205e71b7053SJung-uk Kim add $inp,$inp,$index 2206e71b7053SJung-uk Kim 2207e71b7053SJung-uk Kim lwz r5, 64*0($inp) 2208e71b7053SJung-uk Kim lwz r6, 64*1($inp) 2209e71b7053SJung-uk Kim lwz r7, 64*2($inp) 2210e71b7053SJung-uk Kim lwz r8, 64*3($inp) 2211e71b7053SJung-uk Kim lwz r9, 64*4($inp) 2212e71b7053SJung-uk Kim lwz r10,64*5($inp) 2213e71b7053SJung-uk Kim lwz r11,64*6($inp) 2214e71b7053SJung-uk Kim lwz r12,64*7($inp) 2215e71b7053SJung-uk Kim addi $inp,$inp,64*8 2216e71b7053SJung-uk Kim sldi r9, r9, 32 2217e71b7053SJung-uk Kim sldi r10,r10,32 2218e71b7053SJung-uk Kim sldi r11,r11,32 2219e71b7053SJung-uk Kim sldi r12,r12,32 2220e71b7053SJung-uk Kim or r5,r5,r9 2221e71b7053SJung-uk Kim or r6,r6,r10 2222e71b7053SJung-uk Kim or r7,r7,r11 2223e71b7053SJung-uk Kim or r8,r8,r12 2224e71b7053SJung-uk Kim and r5,r5,r0 2225e71b7053SJung-uk Kim and r6,r6,r0 2226e71b7053SJung-uk Kim and r7,r7,r0 2227e71b7053SJung-uk Kim and r8,r8,r0 2228e71b7053SJung-uk Kim std r5,0($out) # X 2229e71b7053SJung-uk Kim std r6,8($out) 2230e71b7053SJung-uk Kim std r7,16($out) 2231e71b7053SJung-uk Kim std r8,24($out) 2232e71b7053SJung-uk Kim 2233e71b7053SJung-uk Kim lwz r5, 64*0($inp) 2234e71b7053SJung-uk Kim lwz r6, 64*1($inp) 2235e71b7053SJung-uk Kim lwz r7, 64*2($inp) 2236e71b7053SJung-uk Kim lwz r8, 64*3($inp) 2237e71b7053SJung-uk Kim lwz r9, 64*4($inp) 2238e71b7053SJung-uk Kim lwz r10,64*5($inp) 2239e71b7053SJung-uk Kim lwz r11,64*6($inp) 2240e71b7053SJung-uk Kim lwz r12,64*7($inp) 2241e71b7053SJung-uk Kim addi $inp,$inp,64*8 2242e71b7053SJung-uk Kim sldi r9, r9, 32 2243e71b7053SJung-uk Kim sldi r10,r10,32 2244e71b7053SJung-uk Kim sldi r11,r11,32 2245e71b7053SJung-uk Kim sldi r12,r12,32 2246e71b7053SJung-uk Kim or r5,r5,r9 2247e71b7053SJung-uk Kim or r6,r6,r10 2248e71b7053SJung-uk Kim or r7,r7,r11 2249e71b7053SJung-uk Kim or r8,r8,r12 2250e71b7053SJung-uk Kim and r5,r5,r0 2251e71b7053SJung-uk Kim and r6,r6,r0 2252e71b7053SJung-uk Kim and r7,r7,r0 2253e71b7053SJung-uk Kim and r8,r8,r0 2254e71b7053SJung-uk Kim std r5,32($out) # Y 2255e71b7053SJung-uk Kim std r6,40($out) 2256e71b7053SJung-uk Kim std r7,48($out) 2257e71b7053SJung-uk Kim std r8,56($out) 2258e71b7053SJung-uk Kim 2259e71b7053SJung-uk Kim lwz r5, 64*0($inp) 2260e71b7053SJung-uk Kim lwz r6, 64*1($inp) 2261e71b7053SJung-uk Kim lwz r7, 64*2($inp) 2262e71b7053SJung-uk Kim lwz r8, 64*3($inp) 2263e71b7053SJung-uk Kim lwz r9, 64*4($inp) 2264e71b7053SJung-uk Kim lwz r10,64*5($inp) 2265e71b7053SJung-uk Kim lwz r11,64*6($inp) 2266e71b7053SJung-uk Kim lwz r12,64*7($inp) 2267e71b7053SJung-uk Kim sldi r9, r9, 32 2268e71b7053SJung-uk Kim sldi r10,r10,32 2269e71b7053SJung-uk Kim sldi r11,r11,32 2270e71b7053SJung-uk Kim sldi r12,r12,32 2271e71b7053SJung-uk Kim or r5,r5,r9 2272e71b7053SJung-uk Kim or r6,r6,r10 2273e71b7053SJung-uk Kim or r7,r7,r11 2274e71b7053SJung-uk Kim or r8,r8,r12 2275e71b7053SJung-uk Kim and r5,r5,r0 2276e71b7053SJung-uk Kim and r6,r6,r0 2277e71b7053SJung-uk Kim and r7,r7,r0 2278e71b7053SJung-uk Kim and r8,r8,r0 2279e71b7053SJung-uk Kim std r5,64($out) # Z 2280e71b7053SJung-uk Kim std r6,72($out) 2281e71b7053SJung-uk Kim std r7,80($out) 2282e71b7053SJung-uk Kim std r8,88($out) 2283e71b7053SJung-uk Kim 2284e71b7053SJung-uk Kim blr 2285e71b7053SJung-uk Kim .long 0 2286e71b7053SJung-uk Kim .byte 0,12,0x14,0,0,0,3,0 2287e71b7053SJung-uk Kim .long 0 2288e71b7053SJung-uk Kim.size ecp_nistz256_gather_w5,.-ecp_nistz256_gather_w5 2289e71b7053SJung-uk Kim 2290e71b7053SJung-uk Kim######################################################################## 2291e71b7053SJung-uk Kim# void ecp_nistz256_scatter_w7(void *out, const P256_POINT_AFFINE *inp, 2292e71b7053SJung-uk Kim# int index); 2293e71b7053SJung-uk Kim.globl ecp_nistz256_scatter_w7 2294e71b7053SJung-uk Kim.align 4 2295e71b7053SJung-uk Kimecp_nistz256_scatter_w7: 2296e71b7053SJung-uk Kim li r0,8 2297e71b7053SJung-uk Kim mtctr r0 2298e71b7053SJung-uk Kim add $out,$out,$index 2299e71b7053SJung-uk Kim subi $inp,$inp,8 2300e71b7053SJung-uk Kim 2301e71b7053SJung-uk Kim.Loop_scatter_w7: 2302e71b7053SJung-uk Kim ldu r0,8($inp) 2303e71b7053SJung-uk Kim stb r0,64*0($out) 2304e71b7053SJung-uk Kim srdi r0,r0,8 2305e71b7053SJung-uk Kim stb r0,64*1($out) 2306e71b7053SJung-uk Kim srdi r0,r0,8 2307e71b7053SJung-uk Kim stb r0,64*2($out) 2308e71b7053SJung-uk Kim srdi r0,r0,8 2309e71b7053SJung-uk Kim stb r0,64*3($out) 2310e71b7053SJung-uk Kim srdi r0,r0,8 2311e71b7053SJung-uk Kim stb r0,64*4($out) 2312e71b7053SJung-uk Kim srdi r0,r0,8 2313e71b7053SJung-uk Kim stb r0,64*5($out) 2314e71b7053SJung-uk Kim srdi r0,r0,8 2315e71b7053SJung-uk Kim stb r0,64*6($out) 2316e71b7053SJung-uk Kim srdi r0,r0,8 2317e71b7053SJung-uk Kim stb r0,64*7($out) 2318e71b7053SJung-uk Kim addi $out,$out,64*8 2319e71b7053SJung-uk Kim bdnz .Loop_scatter_w7 2320e71b7053SJung-uk Kim 2321e71b7053SJung-uk Kim blr 2322e71b7053SJung-uk Kim .long 0 2323e71b7053SJung-uk Kim .byte 0,12,0x14,0,0,0,3,0 2324e71b7053SJung-uk Kim .long 0 2325e71b7053SJung-uk Kim.size ecp_nistz256_scatter_w7,.-ecp_nistz256_scatter_w7 2326e71b7053SJung-uk Kim 2327e71b7053SJung-uk Kim######################################################################## 2328e71b7053SJung-uk Kim# void ecp_nistz256_gather_w7(P256_POINT_AFFINE *out, const void *inp, 2329e71b7053SJung-uk Kim# int index); 2330e71b7053SJung-uk Kim.globl ecp_nistz256_gather_w7 2331e71b7053SJung-uk Kim.align 4 2332e71b7053SJung-uk Kimecp_nistz256_gather_w7: 2333e71b7053SJung-uk Kim li r0,8 2334e71b7053SJung-uk Kim mtctr r0 2335e71b7053SJung-uk Kim neg r0,$index 2336e71b7053SJung-uk Kim sradi r0,r0,63 2337e71b7053SJung-uk Kim 2338e71b7053SJung-uk Kim add $index,$index,r0 2339e71b7053SJung-uk Kim add $inp,$inp,$index 2340e71b7053SJung-uk Kim subi $out,$out,8 2341e71b7053SJung-uk Kim 2342e71b7053SJung-uk Kim.Loop_gather_w7: 2343e71b7053SJung-uk Kim lbz r5, 64*0($inp) 2344e71b7053SJung-uk Kim lbz r6, 64*1($inp) 2345e71b7053SJung-uk Kim lbz r7, 64*2($inp) 2346e71b7053SJung-uk Kim lbz r8, 64*3($inp) 2347e71b7053SJung-uk Kim lbz r9, 64*4($inp) 2348e71b7053SJung-uk Kim lbz r10,64*5($inp) 2349e71b7053SJung-uk Kim lbz r11,64*6($inp) 2350e71b7053SJung-uk Kim lbz r12,64*7($inp) 2351e71b7053SJung-uk Kim addi $inp,$inp,64*8 2352e71b7053SJung-uk Kim 2353e71b7053SJung-uk Kim sldi r6, r6, 8 2354e71b7053SJung-uk Kim sldi r7, r7, 16 2355e71b7053SJung-uk Kim sldi r8, r8, 24 2356e71b7053SJung-uk Kim sldi r9, r9, 32 2357e71b7053SJung-uk Kim sldi r10,r10,40 2358e71b7053SJung-uk Kim sldi r11,r11,48 2359e71b7053SJung-uk Kim sldi r12,r12,56 2360e71b7053SJung-uk Kim 2361e71b7053SJung-uk Kim or r5,r5,r6 2362e71b7053SJung-uk Kim or r7,r7,r8 2363e71b7053SJung-uk Kim or r9,r9,r10 2364e71b7053SJung-uk Kim or r11,r11,r12 2365e71b7053SJung-uk Kim or r5,r5,r7 2366e71b7053SJung-uk Kim or r9,r9,r11 2367e71b7053SJung-uk Kim or r5,r5,r9 2368e71b7053SJung-uk Kim and r5,r5,r0 2369e71b7053SJung-uk Kim stdu r5,8($out) 2370e71b7053SJung-uk Kim bdnz .Loop_gather_w7 2371e71b7053SJung-uk Kim 2372e71b7053SJung-uk Kim blr 2373e71b7053SJung-uk Kim .long 0 2374e71b7053SJung-uk Kim .byte 0,12,0x14,0,0,0,3,0 2375e71b7053SJung-uk Kim .long 0 2376e71b7053SJung-uk Kim.size ecp_nistz256_gather_w7,.-ecp_nistz256_gather_w7 2377e71b7053SJung-uk Kim___ 2378e71b7053SJung-uk Kim} 2379e71b7053SJung-uk Kim 2380e71b7053SJung-uk Kimforeach (split("\n",$code)) { 2381e71b7053SJung-uk Kim s/\`([^\`]*)\`/eval $1/ge; 2382e71b7053SJung-uk Kim 2383e71b7053SJung-uk Kim print $_,"\n"; 2384e71b7053SJung-uk Kim} 238517f01e99SJung-uk Kimclose STDOUT or die "error closing STDOUT: $!"; # enforce flush 2386