1238384Sjkim#!/usr/bin/env perl 2238384Sjkim 3238384Sjkim# ==================================================================== 4238384Sjkim# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL 5238384Sjkim# project. The module is, however, dual licensed under OpenSSL and 6238384Sjkim# CRYPTOGAMS licenses depending on where you obtain it. For further 7238384Sjkim# details see http://www.openssl.org/~appro/cryptogams/. 8238384Sjkim# ==================================================================== 9238384Sjkim 10238384Sjkim# I let hardware handle unaligned input, except on page boundaries 11238384Sjkim# (see below for details). Otherwise straightforward implementation 12238384Sjkim# with X vector in register bank. The module is big-endian [which is 13238384Sjkim# not big deal as there're no little-endian targets left around]. 14238384Sjkim 15238384Sjkim# sha256 | sha512 16238384Sjkim# -m64 -m32 | -m64 -m32 17238384Sjkim# --------------------------------------+----------------------- 18238384Sjkim# PPC970,gcc-4.0.0 +50% +38% | +40% +410%(*) 19238384Sjkim# Power6,xlc-7 +150% +90% | +100% +430%(*) 20238384Sjkim# 21238384Sjkim# (*) 64-bit code in 32-bit application context, which actually is 22238384Sjkim# on TODO list. It should be noted that for safe deployment in 23238384Sjkim# 32-bit *mutli-threaded* context asyncronous signals should be 24238384Sjkim# blocked upon entry to SHA512 block routine. This is because 25238384Sjkim# 32-bit signaling procedure invalidates upper halves of GPRs. 26238384Sjkim# Context switch procedure preserves them, but not signaling:-( 27238384Sjkim 28238384Sjkim# Second version is true multi-thread safe. Trouble with the original 29238384Sjkim# version was that it was using thread local storage pointer register. 30238384Sjkim# Well, it scrupulously preserved it, but the problem would arise the 31238384Sjkim# moment asynchronous signal was delivered and signal handler would 32238384Sjkim# dereference the TLS pointer. While it's never the case in openssl 33238384Sjkim# application or test suite, we have to respect this scenario and not 34238384Sjkim# use TLS pointer register. Alternative would be to require caller to 35238384Sjkim# block signals prior calling this routine. For the record, in 32-bit 36238384Sjkim# context R2 serves as TLS pointer, while in 64-bit context - R13. 37238384Sjkim 38238384Sjkim$flavour=shift; 39238384Sjkim$output =shift; 40238384Sjkim 41238384Sjkimif ($flavour =~ /64/) { 42238384Sjkim $SIZE_T=8; 43238384Sjkim $LRSAVE=2*$SIZE_T; 44238384Sjkim $STU="stdu"; 45238384Sjkim $UCMP="cmpld"; 46238384Sjkim $SHL="sldi"; 47238384Sjkim $POP="ld"; 48238384Sjkim $PUSH="std"; 49238384Sjkim} elsif ($flavour =~ /32/) { 50238384Sjkim $SIZE_T=4; 51238384Sjkim $LRSAVE=$SIZE_T; 52238384Sjkim $STU="stwu"; 53238384Sjkim $UCMP="cmplw"; 54238384Sjkim $SHL="slwi"; 55238384Sjkim $POP="lwz"; 56238384Sjkim $PUSH="stw"; 57238384Sjkim} else { die "nonsense $flavour"; } 58238384Sjkim 59238384Sjkim$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; 60238384Sjkim( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or 61238384Sjkim( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or 62238384Sjkimdie "can't locate ppc-xlate.pl"; 63238384Sjkim 64238384Sjkimopen STDOUT,"| $^X $xlate $flavour $output" || die "can't call $xlate: $!"; 65238384Sjkim 66238384Sjkimif ($output =~ /512/) { 67238384Sjkim $func="sha512_block_data_order"; 68238384Sjkim $SZ=8; 69238384Sjkim @Sigma0=(28,34,39); 70238384Sjkim @Sigma1=(14,18,41); 71238384Sjkim @sigma0=(1, 8, 7); 72238384Sjkim @sigma1=(19,61, 6); 73238384Sjkim $rounds=80; 74238384Sjkim $LD="ld"; 75238384Sjkim $ST="std"; 76238384Sjkim $ROR="rotrdi"; 77238384Sjkim $SHR="srdi"; 78238384Sjkim} else { 79238384Sjkim $func="sha256_block_data_order"; 80238384Sjkim $SZ=4; 81238384Sjkim @Sigma0=( 2,13,22); 82238384Sjkim @Sigma1=( 6,11,25); 83238384Sjkim @sigma0=( 7,18, 3); 84238384Sjkim @sigma1=(17,19,10); 85238384Sjkim $rounds=64; 86238384Sjkim $LD="lwz"; 87238384Sjkim $ST="stw"; 88238384Sjkim $ROR="rotrwi"; 89238384Sjkim $SHR="srwi"; 90238384Sjkim} 91238384Sjkim 92238384Sjkim$FRAME=32*$SIZE_T+16*$SZ; 93238384Sjkim$LOCALS=6*$SIZE_T; 94238384Sjkim 95238384Sjkim$sp ="r1"; 96238384Sjkim$toc="r2"; 97238384Sjkim$ctx="r3"; # zapped by $a0 98238384Sjkim$inp="r4"; # zapped by $a1 99238384Sjkim$num="r5"; # zapped by $t0 100238384Sjkim 101238384Sjkim$T ="r0"; 102238384Sjkim$a0 ="r3"; 103238384Sjkim$a1 ="r4"; 104238384Sjkim$t0 ="r5"; 105238384Sjkim$t1 ="r6"; 106238384Sjkim$Tbl="r7"; 107238384Sjkim 108238384Sjkim$A ="r8"; 109238384Sjkim$B ="r9"; 110238384Sjkim$C ="r10"; 111238384Sjkim$D ="r11"; 112238384Sjkim$E ="r12"; 113238384Sjkim$F ="r13"; $F="r2" if ($SIZE_T==8);# reassigned to exempt TLS pointer 114238384Sjkim$G ="r14"; 115238384Sjkim$H ="r15"; 116238384Sjkim 117238384Sjkim@V=($A,$B,$C,$D,$E,$F,$G,$H); 118238384Sjkim@X=("r16","r17","r18","r19","r20","r21","r22","r23", 119238384Sjkim "r24","r25","r26","r27","r28","r29","r30","r31"); 120238384Sjkim 121238384Sjkim$inp="r31"; # reassigned $inp! aliases with @X[15] 122238384Sjkim 123238384Sjkimsub ROUND_00_15 { 124238384Sjkimmy ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_; 125238384Sjkim$code.=<<___; 126238384Sjkim $LD $T,`$i*$SZ`($Tbl) 127238384Sjkim $ROR $a0,$e,$Sigma1[0] 128238384Sjkim $ROR $a1,$e,$Sigma1[1] 129238384Sjkim and $t0,$f,$e 130238384Sjkim andc $t1,$g,$e 131238384Sjkim add $T,$T,$h 132238384Sjkim xor $a0,$a0,$a1 133238384Sjkim $ROR $a1,$a1,`$Sigma1[2]-$Sigma1[1]` 134238384Sjkim or $t0,$t0,$t1 ; Ch(e,f,g) 135238384Sjkim add $T,$T,@X[$i] 136238384Sjkim xor $a0,$a0,$a1 ; Sigma1(e) 137238384Sjkim add $T,$T,$t0 138238384Sjkim add $T,$T,$a0 139238384Sjkim 140238384Sjkim $ROR $a0,$a,$Sigma0[0] 141238384Sjkim $ROR $a1,$a,$Sigma0[1] 142238384Sjkim and $t0,$a,$b 143238384Sjkim and $t1,$a,$c 144238384Sjkim xor $a0,$a0,$a1 145238384Sjkim $ROR $a1,$a1,`$Sigma0[2]-$Sigma0[1]` 146238384Sjkim xor $t0,$t0,$t1 147238384Sjkim and $t1,$b,$c 148238384Sjkim xor $a0,$a0,$a1 ; Sigma0(a) 149238384Sjkim add $d,$d,$T 150238384Sjkim xor $t0,$t0,$t1 ; Maj(a,b,c) 151238384Sjkim add $h,$T,$a0 152238384Sjkim add $h,$h,$t0 153238384Sjkim 154238384Sjkim___ 155238384Sjkim} 156238384Sjkim 157238384Sjkimsub ROUND_16_xx { 158238384Sjkimmy ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_; 159238384Sjkim$i-=16; 160238384Sjkim$code.=<<___; 161238384Sjkim $ROR $a0,@X[($i+1)%16],$sigma0[0] 162238384Sjkim $ROR $a1,@X[($i+1)%16],$sigma0[1] 163238384Sjkim $ROR $t0,@X[($i+14)%16],$sigma1[0] 164238384Sjkim $ROR $t1,@X[($i+14)%16],$sigma1[1] 165238384Sjkim xor $a0,$a0,$a1 166238384Sjkim $SHR $a1,@X[($i+1)%16],$sigma0[2] 167238384Sjkim xor $t0,$t0,$t1 168238384Sjkim $SHR $t1,@X[($i+14)%16],$sigma1[2] 169238384Sjkim add @X[$i],@X[$i],@X[($i+9)%16] 170238384Sjkim xor $a0,$a0,$a1 ; sigma0(X[(i+1)&0x0f]) 171238384Sjkim xor $t0,$t0,$t1 ; sigma1(X[(i+14)&0x0f]) 172238384Sjkim add @X[$i],@X[$i],$a0 173238384Sjkim add @X[$i],@X[$i],$t0 174238384Sjkim___ 175238384Sjkim&ROUND_00_15($i,$a,$b,$c,$d,$e,$f,$g,$h); 176238384Sjkim} 177238384Sjkim 178238384Sjkim$code=<<___; 179238384Sjkim.machine "any" 180238384Sjkim.text 181238384Sjkim 182238384Sjkim.globl $func 183238384Sjkim.align 6 184238384Sjkim$func: 185238384Sjkim $STU $sp,-$FRAME($sp) 186238384Sjkim mflr r0 187238384Sjkim $SHL $num,$num,`log(16*$SZ)/log(2)` 188238384Sjkim 189238384Sjkim $PUSH $ctx,`$FRAME-$SIZE_T*22`($sp) 190238384Sjkim 191238384Sjkim $PUSH $toc,`$FRAME-$SIZE_T*20`($sp) 192238384Sjkim $PUSH r13,`$FRAME-$SIZE_T*19`($sp) 193238384Sjkim $PUSH r14,`$FRAME-$SIZE_T*18`($sp) 194238384Sjkim $PUSH r15,`$FRAME-$SIZE_T*17`($sp) 195238384Sjkim $PUSH r16,`$FRAME-$SIZE_T*16`($sp) 196238384Sjkim $PUSH r17,`$FRAME-$SIZE_T*15`($sp) 197238384Sjkim $PUSH r18,`$FRAME-$SIZE_T*14`($sp) 198238384Sjkim $PUSH r19,`$FRAME-$SIZE_T*13`($sp) 199238384Sjkim $PUSH r20,`$FRAME-$SIZE_T*12`($sp) 200238384Sjkim $PUSH r21,`$FRAME-$SIZE_T*11`($sp) 201238384Sjkim $PUSH r22,`$FRAME-$SIZE_T*10`($sp) 202238384Sjkim $PUSH r23,`$FRAME-$SIZE_T*9`($sp) 203238384Sjkim $PUSH r24,`$FRAME-$SIZE_T*8`($sp) 204238384Sjkim $PUSH r25,`$FRAME-$SIZE_T*7`($sp) 205238384Sjkim $PUSH r26,`$FRAME-$SIZE_T*6`($sp) 206238384Sjkim $PUSH r27,`$FRAME-$SIZE_T*5`($sp) 207238384Sjkim $PUSH r28,`$FRAME-$SIZE_T*4`($sp) 208238384Sjkim $PUSH r29,`$FRAME-$SIZE_T*3`($sp) 209238384Sjkim $PUSH r30,`$FRAME-$SIZE_T*2`($sp) 210238384Sjkim $PUSH r31,`$FRAME-$SIZE_T*1`($sp) 211238384Sjkim $PUSH r0,`$FRAME+$LRSAVE`($sp) 212238384Sjkim 213238384Sjkim $LD $A,`0*$SZ`($ctx) 214238384Sjkim mr $inp,r4 ; incarnate $inp 215238384Sjkim $LD $B,`1*$SZ`($ctx) 216238384Sjkim $LD $C,`2*$SZ`($ctx) 217238384Sjkim $LD $D,`3*$SZ`($ctx) 218238384Sjkim $LD $E,`4*$SZ`($ctx) 219238384Sjkim $LD $F,`5*$SZ`($ctx) 220238384Sjkim $LD $G,`6*$SZ`($ctx) 221238384Sjkim $LD $H,`7*$SZ`($ctx) 222238384Sjkim 223238384Sjkim bl LPICmeup 224238384SjkimLPICedup: 225238384Sjkim andi. r0,$inp,3 226238384Sjkim bne Lunaligned 227238384SjkimLaligned: 228238384Sjkim add $num,$inp,$num 229238384Sjkim $PUSH $num,`$FRAME-$SIZE_T*24`($sp) ; end pointer 230238384Sjkim $PUSH $inp,`$FRAME-$SIZE_T*23`($sp) ; inp pointer 231238384Sjkim bl Lsha2_block_private 232238384Sjkim b Ldone 233238384Sjkim 234238384Sjkim; PowerPC specification allows an implementation to be ill-behaved 235238384Sjkim; upon unaligned access which crosses page boundary. "Better safe 236238384Sjkim; than sorry" principle makes me treat it specially. But I don't 237238384Sjkim; look for particular offending word, but rather for the input 238238384Sjkim; block which crosses the boundary. Once found that block is aligned 239238384Sjkim; and hashed separately... 240238384Sjkim.align 4 241238384SjkimLunaligned: 242238384Sjkim subfic $t1,$inp,4096 243238384Sjkim andi. $t1,$t1,`4096-16*$SZ` ; distance to closest page boundary 244238384Sjkim beq Lcross_page 245238384Sjkim $UCMP $num,$t1 246238384Sjkim ble- Laligned ; didn't cross the page boundary 247238384Sjkim subfc $num,$t1,$num 248238384Sjkim add $t1,$inp,$t1 249238384Sjkim $PUSH $num,`$FRAME-$SIZE_T*25`($sp) ; save real remaining num 250238384Sjkim $PUSH $t1,`$FRAME-$SIZE_T*24`($sp) ; intermediate end pointer 251238384Sjkim $PUSH $inp,`$FRAME-$SIZE_T*23`($sp) ; inp pointer 252238384Sjkim bl Lsha2_block_private 253238384Sjkim ; $inp equals to the intermediate end pointer here 254238384Sjkim $POP $num,`$FRAME-$SIZE_T*25`($sp) ; restore real remaining num 255238384SjkimLcross_page: 256238384Sjkim li $t1,`16*$SZ/4` 257238384Sjkim mtctr $t1 258238384Sjkim addi r20,$sp,$LOCALS ; aligned spot below the frame 259238384SjkimLmemcpy: 260238384Sjkim lbz r16,0($inp) 261238384Sjkim lbz r17,1($inp) 262238384Sjkim lbz r18,2($inp) 263238384Sjkim lbz r19,3($inp) 264238384Sjkim addi $inp,$inp,4 265238384Sjkim stb r16,0(r20) 266238384Sjkim stb r17,1(r20) 267238384Sjkim stb r18,2(r20) 268238384Sjkim stb r19,3(r20) 269238384Sjkim addi r20,r20,4 270238384Sjkim bdnz Lmemcpy 271238384Sjkim 272238384Sjkim $PUSH $inp,`$FRAME-$SIZE_T*26`($sp) ; save real inp 273238384Sjkim addi $t1,$sp,`$LOCALS+16*$SZ` ; fictitious end pointer 274238384Sjkim addi $inp,$sp,$LOCALS ; fictitious inp pointer 275238384Sjkim $PUSH $num,`$FRAME-$SIZE_T*25`($sp) ; save real num 276238384Sjkim $PUSH $t1,`$FRAME-$SIZE_T*24`($sp) ; end pointer 277238384Sjkim $PUSH $inp,`$FRAME-$SIZE_T*23`($sp) ; inp pointer 278238384Sjkim bl Lsha2_block_private 279238384Sjkim $POP $inp,`$FRAME-$SIZE_T*26`($sp) ; restore real inp 280238384Sjkim $POP $num,`$FRAME-$SIZE_T*25`($sp) ; restore real num 281238384Sjkim addic. $num,$num,`-16*$SZ` ; num-- 282238384Sjkim bne- Lunaligned 283238384Sjkim 284238384SjkimLdone: 285238384Sjkim $POP r0,`$FRAME+$LRSAVE`($sp) 286238384Sjkim $POP $toc,`$FRAME-$SIZE_T*20`($sp) 287238384Sjkim $POP r13,`$FRAME-$SIZE_T*19`($sp) 288238384Sjkim $POP r14,`$FRAME-$SIZE_T*18`($sp) 289238384Sjkim $POP r15,`$FRAME-$SIZE_T*17`($sp) 290238384Sjkim $POP r16,`$FRAME-$SIZE_T*16`($sp) 291238384Sjkim $POP r17,`$FRAME-$SIZE_T*15`($sp) 292238384Sjkim $POP r18,`$FRAME-$SIZE_T*14`($sp) 293238384Sjkim $POP r19,`$FRAME-$SIZE_T*13`($sp) 294238384Sjkim $POP r20,`$FRAME-$SIZE_T*12`($sp) 295238384Sjkim $POP r21,`$FRAME-$SIZE_T*11`($sp) 296238384Sjkim $POP r22,`$FRAME-$SIZE_T*10`($sp) 297238384Sjkim $POP r23,`$FRAME-$SIZE_T*9`($sp) 298238384Sjkim $POP r24,`$FRAME-$SIZE_T*8`($sp) 299238384Sjkim $POP r25,`$FRAME-$SIZE_T*7`($sp) 300238384Sjkim $POP r26,`$FRAME-$SIZE_T*6`($sp) 301238384Sjkim $POP r27,`$FRAME-$SIZE_T*5`($sp) 302238384Sjkim $POP r28,`$FRAME-$SIZE_T*4`($sp) 303238384Sjkim $POP r29,`$FRAME-$SIZE_T*3`($sp) 304238384Sjkim $POP r30,`$FRAME-$SIZE_T*2`($sp) 305238384Sjkim $POP r31,`$FRAME-$SIZE_T*1`($sp) 306238384Sjkim mtlr r0 307238384Sjkim addi $sp,$sp,$FRAME 308238384Sjkim blr 309238384Sjkim .long 0 310238384Sjkim .byte 0,12,4,1,0x80,18,3,0 311238384Sjkim .long 0 312238384Sjkim 313238384Sjkim.align 4 314238384SjkimLsha2_block_private: 315238384Sjkim___ 316238384Sjkimfor($i=0;$i<16;$i++) { 317238384Sjkim$code.=<<___ if ($SZ==4); 318238384Sjkim lwz @X[$i],`$i*$SZ`($inp) 319238384Sjkim___ 320238384Sjkim# 64-bit loads are split to 2x32-bit ones, as CPU can't handle 321238384Sjkim# unaligned 64-bit loads, only 32-bit ones... 322238384Sjkim$code.=<<___ if ($SZ==8); 323238384Sjkim lwz $t0,`$i*$SZ`($inp) 324238384Sjkim lwz @X[$i],`$i*$SZ+4`($inp) 325238384Sjkim insrdi @X[$i],$t0,32,0 326238384Sjkim___ 327238384Sjkim &ROUND_00_15($i,@V); 328238384Sjkim unshift(@V,pop(@V)); 329238384Sjkim} 330238384Sjkim$code.=<<___; 331238384Sjkim li $T,`$rounds/16-1` 332238384Sjkim mtctr $T 333238384Sjkim.align 4 334238384SjkimLrounds: 335238384Sjkim addi $Tbl,$Tbl,`16*$SZ` 336238384Sjkim___ 337238384Sjkimfor(;$i<32;$i++) { 338238384Sjkim &ROUND_16_xx($i,@V); 339238384Sjkim unshift(@V,pop(@V)); 340238384Sjkim} 341238384Sjkim$code.=<<___; 342238384Sjkim bdnz- Lrounds 343238384Sjkim 344238384Sjkim $POP $ctx,`$FRAME-$SIZE_T*22`($sp) 345238384Sjkim $POP $inp,`$FRAME-$SIZE_T*23`($sp) ; inp pointer 346238384Sjkim $POP $num,`$FRAME-$SIZE_T*24`($sp) ; end pointer 347238384Sjkim subi $Tbl,$Tbl,`($rounds-16)*$SZ` ; rewind Tbl 348238384Sjkim 349238384Sjkim $LD r16,`0*$SZ`($ctx) 350238384Sjkim $LD r17,`1*$SZ`($ctx) 351238384Sjkim $LD r18,`2*$SZ`($ctx) 352238384Sjkim $LD r19,`3*$SZ`($ctx) 353238384Sjkim $LD r20,`4*$SZ`($ctx) 354238384Sjkim $LD r21,`5*$SZ`($ctx) 355238384Sjkim $LD r22,`6*$SZ`($ctx) 356238384Sjkim addi $inp,$inp,`16*$SZ` ; advance inp 357238384Sjkim $LD r23,`7*$SZ`($ctx) 358238384Sjkim add $A,$A,r16 359238384Sjkim add $B,$B,r17 360238384Sjkim $PUSH $inp,`$FRAME-$SIZE_T*23`($sp) 361238384Sjkim add $C,$C,r18 362238384Sjkim $ST $A,`0*$SZ`($ctx) 363238384Sjkim add $D,$D,r19 364238384Sjkim $ST $B,`1*$SZ`($ctx) 365238384Sjkim add $E,$E,r20 366238384Sjkim $ST $C,`2*$SZ`($ctx) 367238384Sjkim add $F,$F,r21 368238384Sjkim $ST $D,`3*$SZ`($ctx) 369238384Sjkim add $G,$G,r22 370238384Sjkim $ST $E,`4*$SZ`($ctx) 371238384Sjkim add $H,$H,r23 372238384Sjkim $ST $F,`5*$SZ`($ctx) 373238384Sjkim $ST $G,`6*$SZ`($ctx) 374238384Sjkim $UCMP $inp,$num 375238384Sjkim $ST $H,`7*$SZ`($ctx) 376238384Sjkim bne Lsha2_block_private 377238384Sjkim blr 378238384Sjkim .long 0 379238384Sjkim .byte 0,12,0x14,0,0,0,0,0 380238384Sjkim___ 381238384Sjkim 382238384Sjkim# Ugly hack here, because PPC assembler syntax seem to vary too 383238384Sjkim# much from platforms to platform... 384238384Sjkim$code.=<<___; 385238384Sjkim.align 6 386238384SjkimLPICmeup: 387238384Sjkim mflr r0 388238384Sjkim bcl 20,31,\$+4 389238384Sjkim mflr $Tbl ; vvvvvv "distance" between . and 1st data entry 390238384Sjkim addi $Tbl,$Tbl,`64-8` 391238384Sjkim mtlr r0 392238384Sjkim blr 393238384Sjkim .long 0 394238384Sjkim .byte 0,12,0x14,0,0,0,0,0 395238384Sjkim .space `64-9*4` 396238384Sjkim___ 397238384Sjkim$code.=<<___ if ($SZ==8); 398238384Sjkim .long 0x428a2f98,0xd728ae22,0x71374491,0x23ef65cd 399238384Sjkim .long 0xb5c0fbcf,0xec4d3b2f,0xe9b5dba5,0x8189dbbc 400238384Sjkim .long 0x3956c25b,0xf348b538,0x59f111f1,0xb605d019 401238384Sjkim .long 0x923f82a4,0xaf194f9b,0xab1c5ed5,0xda6d8118 402238384Sjkim .long 0xd807aa98,0xa3030242,0x12835b01,0x45706fbe 403238384Sjkim .long 0x243185be,0x4ee4b28c,0x550c7dc3,0xd5ffb4e2 404238384Sjkim .long 0x72be5d74,0xf27b896f,0x80deb1fe,0x3b1696b1 405238384Sjkim .long 0x9bdc06a7,0x25c71235,0xc19bf174,0xcf692694 406238384Sjkim .long 0xe49b69c1,0x9ef14ad2,0xefbe4786,0x384f25e3 407238384Sjkim .long 0x0fc19dc6,0x8b8cd5b5,0x240ca1cc,0x77ac9c65 408238384Sjkim .long 0x2de92c6f,0x592b0275,0x4a7484aa,0x6ea6e483 409238384Sjkim .long 0x5cb0a9dc,0xbd41fbd4,0x76f988da,0x831153b5 410238384Sjkim .long 0x983e5152,0xee66dfab,0xa831c66d,0x2db43210 411238384Sjkim .long 0xb00327c8,0x98fb213f,0xbf597fc7,0xbeef0ee4 412238384Sjkim .long 0xc6e00bf3,0x3da88fc2,0xd5a79147,0x930aa725 413238384Sjkim .long 0x06ca6351,0xe003826f,0x14292967,0x0a0e6e70 414238384Sjkim .long 0x27b70a85,0x46d22ffc,0x2e1b2138,0x5c26c926 415238384Sjkim .long 0x4d2c6dfc,0x5ac42aed,0x53380d13,0x9d95b3df 416238384Sjkim .long 0x650a7354,0x8baf63de,0x766a0abb,0x3c77b2a8 417238384Sjkim .long 0x81c2c92e,0x47edaee6,0x92722c85,0x1482353b 418238384Sjkim .long 0xa2bfe8a1,0x4cf10364,0xa81a664b,0xbc423001 419238384Sjkim .long 0xc24b8b70,0xd0f89791,0xc76c51a3,0x0654be30 420238384Sjkim .long 0xd192e819,0xd6ef5218,0xd6990624,0x5565a910 421238384Sjkim .long 0xf40e3585,0x5771202a,0x106aa070,0x32bbd1b8 422238384Sjkim .long 0x19a4c116,0xb8d2d0c8,0x1e376c08,0x5141ab53 423238384Sjkim .long 0x2748774c,0xdf8eeb99,0x34b0bcb5,0xe19b48a8 424238384Sjkim .long 0x391c0cb3,0xc5c95a63,0x4ed8aa4a,0xe3418acb 425238384Sjkim .long 0x5b9cca4f,0x7763e373,0x682e6ff3,0xd6b2b8a3 426238384Sjkim .long 0x748f82ee,0x5defb2fc,0x78a5636f,0x43172f60 427238384Sjkim .long 0x84c87814,0xa1f0ab72,0x8cc70208,0x1a6439ec 428238384Sjkim .long 0x90befffa,0x23631e28,0xa4506ceb,0xde82bde9 429238384Sjkim .long 0xbef9a3f7,0xb2c67915,0xc67178f2,0xe372532b 430238384Sjkim .long 0xca273ece,0xea26619c,0xd186b8c7,0x21c0c207 431238384Sjkim .long 0xeada7dd6,0xcde0eb1e,0xf57d4f7f,0xee6ed178 432238384Sjkim .long 0x06f067aa,0x72176fba,0x0a637dc5,0xa2c898a6 433238384Sjkim .long 0x113f9804,0xbef90dae,0x1b710b35,0x131c471b 434238384Sjkim .long 0x28db77f5,0x23047d84,0x32caab7b,0x40c72493 435238384Sjkim .long 0x3c9ebe0a,0x15c9bebc,0x431d67c4,0x9c100d4c 436238384Sjkim .long 0x4cc5d4be,0xcb3e42b6,0x597f299c,0xfc657e2a 437238384Sjkim .long 0x5fcb6fab,0x3ad6faec,0x6c44198c,0x4a475817 438238384Sjkim___ 439238384Sjkim$code.=<<___ if ($SZ==4); 440238384Sjkim .long 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5 441238384Sjkim .long 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5 442238384Sjkim .long 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3 443238384Sjkim .long 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174 444238384Sjkim .long 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc 445238384Sjkim .long 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da 446238384Sjkim .long 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7 447238384Sjkim .long 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967 448238384Sjkim .long 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13 449238384Sjkim .long 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85 450238384Sjkim .long 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3 451238384Sjkim .long 0xd192e819,0xd6990624,0xf40e3585,0x106aa070 452238384Sjkim .long 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5 453238384Sjkim .long 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3 454238384Sjkim .long 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208 455238384Sjkim .long 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 456238384Sjkim___ 457238384Sjkim 458238384Sjkim$code =~ s/\`([^\`]*)\`/eval $1/gem; 459238384Sjkimprint $code; 460238384Sjkimclose STDOUT; 461