~ubuntu-branches/ubuntu/lucid/openssl/lucid-security

« back to all changes in this revision

Viewing changes to crypto/sha/asm/sha512-x86_64.pl

  • Committer: Bazaar Package Importer
  • Author(s): Kurt Roeckx
  • Date: 2009-06-13 18:15:46 UTC
  • mto: (11.1.5 squeeze)
  • mto: This revision was merged to the branch mainline in revision 34.
  • Revision ID: james.westby@ubuntu.com-20090613181546-vbfntai3b009dl1u
Tags: upstream-0.9.8k
ImportĀ upstreamĀ versionĀ 0.9.8k

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/env perl
 
2
#
 
3
# ====================================================================
 
4
# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
 
5
# project. Rights for redistribution and usage in source and binary
 
6
# forms are granted according to the OpenSSL license.
 
7
# ====================================================================
 
8
#
 
9
# sha256/512_block procedure for x86_64.
 
10
#
 
11
# 40% improvement over compiler-generated code on Opteron. On EM64T
 
12
# sha256 was observed to run >80% faster and sha512 - >40%. No magical
 
13
# tricks, just straight implementation... I really wonder why gcc
 
14
# [being armed with inline assembler] fails to generate as fast code.
 
15
# The only thing which is cool about this module is that it's very
 
16
# same instruction sequence used for both SHA-256 and SHA-512. In
 
17
# former case the instructions operate on 32-bit operands, while in
 
18
# latter - on 64-bit ones. All I had to do is to get one flavor right,
 
19
# the other one passed the test right away:-)
 
20
#
 
21
# sha256_block runs in ~1005 cycles on Opteron, which gives you
 
22
# asymptotic performance of 64*1000/1005=63.7MBps times CPU clock
 
23
# frequency in GHz. sha512_block runs in ~1275 cycles, which results
 
24
# in 128*1000/1275=100MBps per GHz. Is there room for improvement?
 
25
# Well, if you compare it to IA-64 implementation, which maintains
 
26
# X[16] in register bank[!], tends to 4 instructions per CPU clock
 
27
# cycle and runs in 1003 cycles, 1275 is very good result for 3-way
 
28
# issue Opteron pipeline and X[16] maintained in memory. So that *if*
 
29
# there is a way to improve it, *then* the only way would be to try to
 
30
# offload X[16] updates to SSE unit, but that would require "deeper"
 
31
# loop unroll, which in turn would naturally cause size blow-up, not
 
32
# to mention increased complexity! And once again, only *if* it's
 
33
# actually possible to noticeably improve overall ILP, instruction
 
34
# level parallelism, on a given CPU implementation in this case.
 
35
#
 
36
# Special note on Intel EM64T. While Opteron CPU exhibits perfect
 
37
# perfromance ratio of 1.5 between 64- and 32-bit flavors [see above],
 
38
# [currently available] EM64T CPUs apparently are far from it. On the
 
39
# contrary, 64-bit version, sha512_block, is ~30% *slower* than 32-bit
 
40
# sha256_block:-( This is presumably because 64-bit shifts/rotates
 
41
# apparently are not atomic instructions, but implemented in microcode.
 
42
 
 
43
$output=shift;
 
44
 
 
45
$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
 
46
( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
 
47
( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
 
48
die "can't locate x86_64-xlate.pl";
 
49
 
 
50
open STDOUT,"| $^X $xlate $output";
 
51
 
 
52
if ($output =~ /512/) {
 
53
        $func="sha512_block_data_order";
 
54
        $TABLE="K512";
 
55
        $SZ=8;
 
56
        @ROT=($A,$B,$C,$D,$E,$F,$G,$H)=("%rax","%rbx","%rcx","%rdx",
 
57
                                        "%r8", "%r9", "%r10","%r11");
 
58
        ($T1,$a0,$a1,$a2)=("%r12","%r13","%r14","%r15");
 
59
        @Sigma0=(28,34,39);
 
60
        @Sigma1=(14,18,41);
 
61
        @sigma0=(1,  8, 7);
 
62
        @sigma1=(19,61, 6);
 
63
        $rounds=80;
 
64
} else {
 
65
        $func="sha256_block_data_order";
 
66
        $TABLE="K256";
 
67
        $SZ=4;
 
68
        @ROT=($A,$B,$C,$D,$E,$F,$G,$H)=("%eax","%ebx","%ecx","%edx",
 
69
                                        "%r8d","%r9d","%r10d","%r11d");
 
70
        ($T1,$a0,$a1,$a2)=("%r12d","%r13d","%r14d","%r15d");
 
71
        @Sigma0=( 2,13,22);
 
72
        @Sigma1=( 6,11,25);
 
73
        @sigma0=( 7,18, 3);
 
74
        @sigma1=(17,19,10);
 
75
        $rounds=64;
 
76
}
 
77
 
 
78
$ctx="%rdi";    # 1st arg
 
79
$round="%rdi";  # zaps $ctx
 
80
$inp="%rsi";    # 2nd arg
 
81
$Tbl="%rbp";
 
82
 
 
83
$_ctx="16*$SZ+0*8(%rsp)";
 
84
$_inp="16*$SZ+1*8(%rsp)";
 
85
$_end="16*$SZ+2*8(%rsp)";
 
86
$_rsp="16*$SZ+3*8(%rsp)";
 
87
$framesz="16*$SZ+4*8";
 
88
 
 
89
 
 
90
sub ROUND_00_15()
 
91
{ my ($i,$a,$b,$c,$d,$e,$f,$g,$h) = @_;
 
92
 
 
93
$code.=<<___;
 
94
        mov     $e,$a0
 
95
        mov     $e,$a1
 
96
        mov     $f,$a2
 
97
 
 
98
        ror     \$$Sigma1[0],$a0
 
99
        ror     \$$Sigma1[1],$a1
 
100
        xor     $g,$a2                  # f^g
 
101
 
 
102
        xor     $a1,$a0
 
103
        ror     \$`$Sigma1[2]-$Sigma1[1]`,$a1
 
104
        and     $e,$a2                  # (f^g)&e
 
105
        mov     $T1,`$SZ*($i&0xf)`(%rsp)
 
106
 
 
107
        xor     $a1,$a0                 # Sigma1(e)
 
108
        xor     $g,$a2                  # Ch(e,f,g)=((f^g)&e)^g
 
109
        add     $h,$T1                  # T1+=h
 
110
 
 
111
        mov     $a,$h
 
112
        add     $a0,$T1                 # T1+=Sigma1(e)
 
113
 
 
114
        add     $a2,$T1                 # T1+=Ch(e,f,g)
 
115
        mov     $a,$a0
 
116
        mov     $a,$a1
 
117
 
 
118
        ror     \$$Sigma0[0],$h
 
119
        ror     \$$Sigma0[1],$a0
 
120
        mov     $a,$a2
 
121
        add     ($Tbl,$round,$SZ),$T1   # T1+=K[round]
 
122
 
 
123
        xor     $a0,$h
 
124
        ror     \$`$Sigma0[2]-$Sigma0[1]`,$a0
 
125
        or      $c,$a1                  # a|c
 
126
 
 
127
        xor     $a0,$h                  # h=Sigma0(a)
 
128
        and     $c,$a2                  # a&c
 
129
        add     $T1,$d                  # d+=T1
 
130
 
 
131
        and     $b,$a1                  # (a|c)&b
 
132
        add     $T1,$h                  # h+=T1
 
133
 
 
134
        or      $a2,$a1                 # Maj(a,b,c)=((a|c)&b)|(a&c)
 
135
        lea     1($round),$round        # round++
 
136
 
 
137
        add     $a1,$h                  # h+=Maj(a,b,c)
 
138
___
 
139
}
 
140
 
 
141
sub ROUND_16_XX()
 
142
{ my ($i,$a,$b,$c,$d,$e,$f,$g,$h) = @_;
 
143
 
 
144
$code.=<<___;
 
145
        mov     `$SZ*(($i+1)&0xf)`(%rsp),$a0
 
146
        mov     `$SZ*(($i+14)&0xf)`(%rsp),$T1
 
147
 
 
148
        mov     $a0,$a2
 
149
 
 
150
        shr     \$$sigma0[2],$a0
 
151
        ror     \$$sigma0[0],$a2
 
152
 
 
153
        xor     $a2,$a0
 
154
        ror     \$`$sigma0[1]-$sigma0[0]`,$a2
 
155
 
 
156
        xor     $a2,$a0                 # sigma0(X[(i+1)&0xf])
 
157
        mov     $T1,$a1
 
158
 
 
159
        shr     \$$sigma1[2],$T1
 
160
        ror     \$$sigma1[0],$a1
 
161
 
 
162
        xor     $a1,$T1
 
163
        ror     \$`$sigma1[1]-$sigma1[0]`,$a1
 
164
 
 
165
        xor     $a1,$T1                 # sigma1(X[(i+14)&0xf])
 
166
 
 
167
        add     $a0,$T1
 
168
 
 
169
        add     `$SZ*(($i+9)&0xf)`(%rsp),$T1
 
170
 
 
171
        add     `$SZ*($i&0xf)`(%rsp),$T1
 
172
___
 
173
        &ROUND_00_15(@_);
 
174
}
 
175
 
 
176
$code=<<___;
 
177
.text
 
178
 
 
179
.globl  $func
 
180
.type   $func,\@function,4
 
181
.align  16
 
182
$func:
 
183
        push    %rbx
 
184
        push    %rbp
 
185
        push    %r12
 
186
        push    %r13
 
187
        push    %r14
 
188
        push    %r15
 
189
        mov     %rsp,%rbp               # copy %rsp
 
190
        shl     \$4,%rdx                # num*16
 
191
        sub     \$$framesz,%rsp
 
192
        lea     ($inp,%rdx,$SZ),%rdx    # inp+num*16*$SZ
 
193
        and     \$-64,%rsp              # align stack frame
 
194
        mov     $ctx,$_ctx              # save ctx, 1st arg
 
195
        mov     $inp,$_inp              # save inp, 2nd arh
 
196
        mov     %rdx,$_end              # save end pointer, "3rd" arg
 
197
        mov     %rbp,$_rsp              # save copy of %rsp
 
198
 
 
199
        .picmeup $Tbl
 
200
        lea     $TABLE-.($Tbl),$Tbl
 
201
 
 
202
        mov     $SZ*0($ctx),$A
 
203
        mov     $SZ*1($ctx),$B
 
204
        mov     $SZ*2($ctx),$C
 
205
        mov     $SZ*3($ctx),$D
 
206
        mov     $SZ*4($ctx),$E
 
207
        mov     $SZ*5($ctx),$F
 
208
        mov     $SZ*6($ctx),$G
 
209
        mov     $SZ*7($ctx),$H
 
210
        jmp     .Lloop
 
211
 
 
212
.align  16
 
213
.Lloop:
 
214
        xor     $round,$round
 
215
___
 
216
        for($i=0;$i<16;$i++) {
 
217
                $code.="        mov     $SZ*$i($inp),$T1\n";
 
218
                $code.="        bswap   $T1\n";
 
219
                &ROUND_00_15($i,@ROT);
 
220
                unshift(@ROT,pop(@ROT));
 
221
        }
 
222
$code.=<<___;
 
223
        jmp     .Lrounds_16_xx
 
224
.align  16
 
225
.Lrounds_16_xx:
 
226
___
 
227
        for(;$i<32;$i++) {
 
228
                &ROUND_16_XX($i,@ROT);
 
229
                unshift(@ROT,pop(@ROT));
 
230
        }
 
231
 
 
232
$code.=<<___;
 
233
        cmp     \$$rounds,$round
 
234
        jb      .Lrounds_16_xx
 
235
 
 
236
        mov     $_ctx,$ctx
 
237
        lea     16*$SZ($inp),$inp
 
238
 
 
239
        add     $SZ*0($ctx),$A
 
240
        add     $SZ*1($ctx),$B
 
241
        add     $SZ*2($ctx),$C
 
242
        add     $SZ*3($ctx),$D
 
243
        add     $SZ*4($ctx),$E
 
244
        add     $SZ*5($ctx),$F
 
245
        add     $SZ*6($ctx),$G
 
246
        add     $SZ*7($ctx),$H
 
247
 
 
248
        cmp     $_end,$inp
 
249
 
 
250
        mov     $A,$SZ*0($ctx)
 
251
        mov     $B,$SZ*1($ctx)
 
252
        mov     $C,$SZ*2($ctx)
 
253
        mov     $D,$SZ*3($ctx)
 
254
        mov     $E,$SZ*4($ctx)
 
255
        mov     $F,$SZ*5($ctx)
 
256
        mov     $G,$SZ*6($ctx)
 
257
        mov     $H,$SZ*7($ctx)
 
258
        jb      .Lloop
 
259
 
 
260
        mov     $_rsp,%rsp
 
261
        pop     %r15
 
262
        pop     %r14
 
263
        pop     %r13
 
264
        pop     %r12
 
265
        pop     %rbp
 
266
        pop     %rbx
 
267
 
 
268
        ret
 
269
.size   $func,.-$func
 
270
___
 
271
 
 
272
if ($SZ==4) {
 
273
$code.=<<___;
 
274
.align  64
 
275
.type   $TABLE,\@object
 
276
$TABLE:
 
277
        .long   0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
 
278
        .long   0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
 
279
        .long   0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
 
280
        .long   0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
 
281
        .long   0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
 
282
        .long   0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
 
283
        .long   0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
 
284
        .long   0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
 
285
        .long   0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
 
286
        .long   0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
 
287
        .long   0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
 
288
        .long   0xd192e819,0xd6990624,0xf40e3585,0x106aa070
 
289
        .long   0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
 
290
        .long   0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
 
291
        .long   0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
 
292
        .long   0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
 
293
___
 
294
} else {
 
295
$code.=<<___;
 
296
.align  64
 
297
.type   $TABLE,\@object
 
298
$TABLE:
 
299
        .quad   0x428a2f98d728ae22,0x7137449123ef65cd
 
300
        .quad   0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc
 
301
        .quad   0x3956c25bf348b538,0x59f111f1b605d019
 
302
        .quad   0x923f82a4af194f9b,0xab1c5ed5da6d8118
 
303
        .quad   0xd807aa98a3030242,0x12835b0145706fbe
 
304
        .quad   0x243185be4ee4b28c,0x550c7dc3d5ffb4e2
 
305
        .quad   0x72be5d74f27b896f,0x80deb1fe3b1696b1
 
306
        .quad   0x9bdc06a725c71235,0xc19bf174cf692694
 
307
        .quad   0xe49b69c19ef14ad2,0xefbe4786384f25e3
 
308
        .quad   0x0fc19dc68b8cd5b5,0x240ca1cc77ac9c65
 
309
        .quad   0x2de92c6f592b0275,0x4a7484aa6ea6e483
 
310
        .quad   0x5cb0a9dcbd41fbd4,0x76f988da831153b5
 
311
        .quad   0x983e5152ee66dfab,0xa831c66d2db43210
 
312
        .quad   0xb00327c898fb213f,0xbf597fc7beef0ee4
 
313
        .quad   0xc6e00bf33da88fc2,0xd5a79147930aa725
 
314
        .quad   0x06ca6351e003826f,0x142929670a0e6e70
 
315
        .quad   0x27b70a8546d22ffc,0x2e1b21385c26c926
 
316
        .quad   0x4d2c6dfc5ac42aed,0x53380d139d95b3df
 
317
        .quad   0x650a73548baf63de,0x766a0abb3c77b2a8
 
318
        .quad   0x81c2c92e47edaee6,0x92722c851482353b
 
319
        .quad   0xa2bfe8a14cf10364,0xa81a664bbc423001
 
320
        .quad   0xc24b8b70d0f89791,0xc76c51a30654be30
 
321
        .quad   0xd192e819d6ef5218,0xd69906245565a910
 
322
        .quad   0xf40e35855771202a,0x106aa07032bbd1b8
 
323
        .quad   0x19a4c116b8d2d0c8,0x1e376c085141ab53
 
324
        .quad   0x2748774cdf8eeb99,0x34b0bcb5e19b48a8
 
325
        .quad   0x391c0cb3c5c95a63,0x4ed8aa4ae3418acb
 
326
        .quad   0x5b9cca4f7763e373,0x682e6ff3d6b2b8a3
 
327
        .quad   0x748f82ee5defb2fc,0x78a5636f43172f60
 
328
        .quad   0x84c87814a1f0ab72,0x8cc702081a6439ec
 
329
        .quad   0x90befffa23631e28,0xa4506cebde82bde9
 
330
        .quad   0xbef9a3f7b2c67915,0xc67178f2e372532b
 
331
        .quad   0xca273eceea26619c,0xd186b8c721c0c207
 
332
        .quad   0xeada7dd6cde0eb1e,0xf57d4f7fee6ed178
 
333
        .quad   0x06f067aa72176fba,0x0a637dc5a2c898a6
 
334
        .quad   0x113f9804bef90dae,0x1b710b35131c471b
 
335
        .quad   0x28db77f523047d84,0x32caab7b40c72493
 
336
        .quad   0x3c9ebe0a15c9bebc,0x431d67c49c100d4c
 
337
        .quad   0x4cc5d4becb3e42b6,0x597f299cfc657e2a
 
338
        .quad   0x5fcb6fab3ad6faec,0x6c44198c4a475817
 
339
___
 
340
}
 
341
 
 
342
$code =~ s/\`([^\`]*)\`/eval $1/gem;
 
343
print $code;
 
344
close STDOUT;