; --------------------------------------------------------------------------- ; Copyright (c) 1998-2007, Brian Gladman, Worcester, UK. All rights reserved. ; ; LICENSE TERMS ; ; The free distribution and use of this software is allowed (with or without ; changes) provided that: ; ; 1. source code distributions include the above copyright notice, this ; list of conditions and the following disclaimer; ; ; 2. binary distributions include the above copyright notice, this list ; of conditions and the following disclaimer in their documentation; ; ; 3. the name of the copyright holder is not used to endorse products ; built using this software without specific written permission. ; ; DISCLAIMER ; ; This software is provided 'as is' with no explicit or implied warranties ; in respect of its properties, including, but not limited to, correctness ; and/or fitness for purpose. ; --------------------------------------------------------------------------- ; Issue 20/12/2007 ; ; This code requires either ASM_X86_V2 or ASM_X86_V2C to be set in aesopt.h ; and the same define to be set here as well. If AES_V2C is set this file ; requires the C files aeskey.c and aestab.c for support. ; An AES implementation for x86 processors using the YASM (or NASM) assembler. ; This is a full assembler implementation covering encryption, decryption and ; key scheduling. It uses 2k bytes of tables but its encryption and decryption ; performance is very close to that obtained using large tables. Key schedule ; expansion is slower for both encryption and decryption but this is likely to ; be offset by the much smaller load that this version places on the processor ; cache. I acknowledge the contribution made by Daniel Bernstein to aspects of ; the design of the AES round function used here. ; ; This code provides the standard AES block size (128 bits, 16 bytes) and the ; three standard AES key sizes (128, 192 and 256 bits). It has the same call ; interface as my C implementation. The ebx, esi, edi and ebp registers are ; preserved across calls but eax, ecx and edx and the artihmetic status flags ; are not. Although this is a full assembler implementation, it can be used ; in conjunction with my C code which provides faster key scheduling using ; large tables. In this case aeskey.c should be compiled with ASM_X86_V2C ; defined. It is also important that the defines below match those used in the ; C code. This code uses the VC++ register saving conentions; if it is used ; with another compiler, conventions for using and saving registers may need ; to be checked (and calling conventions). The YASM command line for the VC++ ; custom build step is: ; ; yasm -Xvc -f win32 -D -o "$(TargetDir)\$(InputName).obj" "$(InputPath)" ; ; For the cryptlib build this is (pcg): ; ; yasm -Xvc -f win32 -D ASM_X86_V2C -o aescrypt2.obj aes_x86_v2.asm ; ; where is ASM_X86_V2 or ASM_X86_V2C. The calling intefaces are: ; ; AES_RETURN aes_encrypt(const unsigned char in_blk[], ; unsigned char out_blk[], const aes_encrypt_ctx cx[1]); ; ; AES_RETURN aes_decrypt(const unsigned char in_blk[], ; unsigned char out_blk[], const aes_decrypt_ctx cx[1]); ; ; AES_RETURN aes_encrypt_key(const unsigned char key[], ; const aes_encrypt_ctx cx[1]); ; ; AES_RETURN aes_decrypt_key(const unsigned char key[], ; const aes_decrypt_ctx cx[1]); ; ; AES_RETURN aes_encrypt_key(const unsigned char key[], ; unsigned int len, const aes_decrypt_ctx cx[1]); ; ; AES_RETURN aes_decrypt_key(const unsigned char key[], ; unsigned int len, const aes_decrypt_ctx cx[1]); ; ; where is 128, 102 or 256. In the last two calls the length can be in ; either bits or bytes. ; The DLL interface must use the _stdcall convention in which the number ; of bytes of parameter space is added after an @ to the sutine's name. ; We must also remove our parameters from the stack before return (see ; the do_exit macro). Define DLL_EXPORT for the Dynamic Link Library version. ; ; Adapted for TrueCrypt: ; - All tables generated at run-time ; - Adapted for 16-bit environment ; CPU 386 USE16 SEGMENT _TEXT PUBLIC CLASS=CODE USE16 SEGMENT _DATA PUBLIC CLASS=DATA USE16 GROUP DGROUP _TEXT _DATA extern _aes_dec_tab ; Aestab.c extern _aes_enc_tab ; %define DLL_EXPORT ; The size of the code can be reduced by using functions for the encryption ; and decryption rounds in place of macro expansion %define REDUCE_CODE_SIZE ; Comment in/out the following lines to obtain the desired subroutines. These ; selections MUST match those in the C header file aes.h ; %define AES_128 ; define if AES with 128 bit keys is needed ; %define AES_192 ; define if AES with 192 bit keys is needed %define AES_256 ; define if AES with 256 bit keys is needed ; %define AES_VAR ; define if a variable key size is needed %define ENCRYPTION ; define if encryption is needed %define DECRYPTION ; define if decryption is needed ; %define AES_REV_DKS ; define if key decryption schedule is reversed %ifndef ASM_X86_V2C %define ENCRYPTION_KEY_SCHEDULE ; define if encryption key expansion is needed %define DECRYPTION_KEY_SCHEDULE ; define if decryption key expansion is needed %endif ; The encryption key schedule has the following in memory layout where N is the ; number of rounds (10, 12 or 14): ; ; lo: | input key (round 0) | ; each round is four 32-bit words ; | encryption round 1 | ; | encryption round 2 | ; .... ; | encryption round N-1 | ; hi: | encryption round N | ; ; The decryption key schedule is normally set up so that it has the same ; layout as above by actually reversing the order of the encryption key ; schedule in memory (this happens when AES_REV_DKS is set): ; ; lo: | decryption round 0 | = | encryption round N | ; | decryption round 1 | = INV_MIX_COL[ | encryption round N-1 | ] ; | decryption round 2 | = INV_MIX_COL[ | encryption round N-2 | ] ; .... .... ; | decryption round N-1 | = INV_MIX_COL[ | encryption round 1 | ] ; hi: | decryption round N | = | input key (round 0) | ; ; with rounds except the first and last modified using inv_mix_column() ; But if AES_REV_DKS is NOT set the order of keys is left as it is for ; encryption so that it has to be accessed in reverse when used for ; decryption (although the inverse mix column modifications are done) ; ; lo: | decryption round 0 | = | input key (round 0) | ; | decryption round 1 | = INV_MIX_COL[ | encryption round 1 | ] ; | decryption round 2 | = INV_MIX_COL[ | encryption round 2 | ] ; .... .... ; | decryption round N-1 | = INV_MIX_COL[ | encryption round N-1 | ] ; hi: | decryption round N | = | encryption round N | ; ; This layout is faster when the assembler key scheduling provided here ; is used. ; ; End of user defines %ifdef AES_VAR %ifndef AES_128 %define AES_128 %endif %ifndef AES_192 %define AES_192 %endif %ifndef AES_256 %define AES_256 %endif %endif %ifdef AES_VAR %define KS_LENGTH 60 %elifdef AES_256 %define KS_LENGTH 60 %elifdef AES_192 %define KS_LENGTH 52 %else %define KS_LENGTH 44 %endif ; These macros implement stack based local variables %macro save 2 mov [esp+4*%1],%2 %endmacro %macro restore 2 mov %1,[esp+4*%2] %endmacro %ifdef REDUCE_CODE_SIZE %macro mf_call 1 call %1 %endmacro %else %macro mf_call 1 %1 %endmacro %endif ; the DLL has to implement the _stdcall calling interface on return ; In this case we have to take our parameters (3 4-byte pointers) ; off the stack %define parms 12 %macro do_name 1-2 parms %ifndef DLL_EXPORT global %1 %1: %else global %1@%2 export %1@%2 %1@%2: %endif %endmacro %macro do_call 1-2 parms %ifndef DLL_EXPORT call %1 add esp,%2 %else call %1@%2 %endif %endmacro %macro do_exit 0-1 parms %ifdef DLL_EXPORT ret %1 %else ret %endif %endmacro ; finite field multiplies by {02}, {04} and {08} %define f2(x) ((x<<1)^(((x>>7)&1)*0x11b)) %define f4(x) ((x<<2)^(((x>>6)&1)*0x11b)^(((x>>6)&2)*0x11b)) %define f8(x) ((x<<3)^(((x>>5)&1)*0x11b)^(((x>>5)&2)*0x11b)^(((x>>5)&4)*0x11b)) ; finite field multiplies required in table generation %define f3(x) (f2(x) ^ x) %define f9(x) (f8(x) ^ x) %define fb(x) (f8(x) ^ f2(x) ^ x) %define fd(x) (f8(x) ^ f4(x) ^ x) %define fe(x) (f8(x) ^ f4(x) ^ f2(x)) %define etab_0(x) [_aes_enc_tab+4+8*x] %define etab_1(x) [_aes_enc_tab+3+8*x] %define etab_2(x) [_aes_enc_tab+2+8*x] %define etab_3(x) [_aes_enc_tab+1+8*x] %define etab_b(x) byte [_aes_enc_tab+1+8*x] ; used with movzx for 0x000000xx %define etab_w(x) word [_aes_enc_tab+8*x] ; used with movzx for 0x0000xx00 %define btab_0(x) [_aes_enc_tab+6+8*x] %define btab_1(x) [_aes_enc_tab+5+8*x] %define btab_2(x) [_aes_enc_tab+4+8*x] %define btab_3(x) [_aes_enc_tab+3+8*x] ; ROUND FUNCTION. Build column[2] on ESI and column[3] on EDI that have the ; round keys pre-loaded. Build column[0] in EBP and column[1] in EBX. ; ; Input: ; ; EAX column[0] ; EBX column[1] ; ECX column[2] ; EDX column[3] ; ESI column key[round][2] ; EDI column key[round][3] ; EBP scratch ; ; Output: ; ; EBP column[0] unkeyed ; EBX column[1] unkeyed ; ESI column[2] keyed ; EDI column[3] keyed ; EAX scratch ; ECX scratch ; EDX scratch %macro rnd_fun 2 rol ebx,16 %1 esi, cl, 0, ebp %1 esi, dh, 1, ebp %1 esi, bh, 3, ebp %1 edi, dl, 0, ebp %1 edi, ah, 1, ebp %1 edi, bl, 2, ebp %2 ebp, al, 0, ebp shr ebx,16 and eax,0xffff0000 or eax,ebx shr edx,16 %1 ebp, ah, 1, ebx %1 ebp, dh, 3, ebx %2 ebx, dl, 2, ebx %1 ebx, ch, 1, edx %1 ebx, al, 0, edx shr eax,16 shr ecx,16 %1 ebp, cl, 2, edx %1 edi, ch, 3, edx %1 esi, al, 2, edx %1 ebx, ah, 3, edx %endmacro ; Basic MOV and XOR Operations for normal rounds %macro nr_xor 4 movzx %4,%2 xor %1,etab_%3(%4) %endmacro %macro nr_mov 4 movzx %4,%2 mov %1,etab_%3(%4) %endmacro ; Basic MOV and XOR Operations for last round %if 1 %macro lr_xor 4 movzx %4,%2 movzx %4,etab_b(%4) %if %3 != 0 shl %4,8*%3 %endif xor %1,%4 %endmacro %macro lr_mov 4 movzx %4,%2 movzx %1,etab_b(%4) %if %3 != 0 shl %1,8*%3 %endif %endmacro %else ; less effective but worth leaving as an option %macro lr_xor 4 movzx %4,%2 mov %4,btab_%3(%4)
;; rdrand.asm - written and placed in public domain by Jeffrey Walton and Uri Blumenthal.
;;              Copyright assigned to the Crypto++ project.

;; This ASM file provides RDSEED to downlevel Microsoft tool chains.
;; Everything "just works" under Visual Studio. Other platforms will
;; have to run MASM/MASM-64 and then link to the object files.

;; set ASFLAGS=/nologo /D_M_X86 /W3 /Cx /Zi /safeseh
;; set ASFLAGS64=/nologo /D_M_X64 /W3 /Cx /Zi
;; "C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\bin\ml.exe" %ASFLAGS% /Fo rdrand-x86.obj /c rdrand.asm
;; "C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\bin\amd64\ml64.exe" %ASFLAGS64% /Fo rdrand-x64.obj /c rdrand.asm

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

TITLE    MASM_RDSEED_GenerateBlock source file
SUBTITLE Microsoft specific ASM code to utilize RDSEED for down level Microsoft toolchains

PUBLIC MASM_RDSEED_GenerateBlock

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; C/C++ Function prototypes (both are fastcall)
;;   X86:
;;      extern "C" void __fastcall MASM_RDSEED_GenerateBlock(byte* ptr, size_t size);
;;   X64:
;;      extern "C" void __fastcall MASM_RDSEED_GenerateBlock(byte* ptr, size_t size);

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

IFDEF _M_X86    ;; Set via the command line

.486
.MODEL FLAT

;; Fastcall calling conventions exports
ALIAS <@MASM_RDSEED_GenerateBlock@8> = <MASM_RDSEED_GenerateBlock>

ENDIF

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

IFDEF _M_X86    ;; Set via the command line

.CODE
ALIGN   8
OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE

;; No need for Load_Arguments due to fastcall
;;   ECX (in): arg1, byte* buffer
;;   EDX (in): arg2, size_t bsize

MASM_RDSEED_GenerateBlock PROC   ;; arg1:DWORD, arg2:DWORD

    MWSIZE EQU 04h    ;; machine word size
    buffer EQU ecx
    bsize  EQU edx

            ;; Top of While loop
RDSEED_GenerateBlock_Top:

            ;; Check remaining size
    cmp     bsize, 0
    je      RDSEED_GenerateBlock_Return

RDSEED_Call_EAX:
            ;; RDSEED is not available prior to VS2012. Just emit
            ;;   the byte codes using DB. This is `rdseed eax`.
    DB      0Fh, 0C7h, 0F8h

            ;; If CF=1, the number returned by RDSEED is valid.
            ;; If CF=0, a random number was not available.

            ;; Retry immediately
    jnc     RDSEED_Call_EAX

RDSEED_succeeded:

    cmp     bsize, MWSIZE
    jb      RDSEED_Partial_Machine_Word

RDSEED_Full_Machine_Word:

    mov     DWORD PTR [buffer], eax
    add     buffer, MWSIZE        ;; No need for Intel Core 2 slow workarounds, like
    sub     bsize, MWSIZE         ;;   `lea buffer,[buffer+MWSIZE]` for faster adds

            ;; Continue
    jmp     RDSEED_GenerateBlock_Top

            ;; 1,2,3 bytes remain
RDSEED_Partial_Machine_Word:

            ;; Test bit 1 to see if size is at least 2
    test    bsize, 2
    jz      RDSEED_Bit_1_Not_Set

    mov     WORD PTR [buffer], ax
    shr     eax, 16
    add     buffer, 2

RDSEED_Bit_1_Not_Set:

            ;; Test bit 0 to see if size is at least 1
    test    bsize, 1
    jz      RDSEED_Bit_0_Not_Set

    mov     BYTE PTR [buffer], al
    ;; shr     ax, 8
    ;; add     buffer, 1

RDSEED_Bit_0_Not_Set:

            ;; We've hit all the bits

RDSEED_GenerateBlock_Return:

            ;; Clear artifacts
    xor     eax, eax
    ret

MASM_RDSEED_GenerateBlock ENDP

ENDIF    ;; _M_X86

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

IFDEF _M_X64    ;; Set via the command line

.CODE
ALIGN   16
OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE

;; No need for Load_Arguments due to fastcall
;;   RCX (in): arg1, byte* buffer
;;   RDX (in): arg2, size_t bsize

MASM_RDSEED_GenerateBlock PROC   ;; arg1:QWORD, arg2:QWORD

    MWSIZE EQU 08h    ;; machine word size
    buffer EQU rcx
    bsize  EQU rdx

            ;; Top of While loop
RDSEED_GenerateBlock_Top:

            ;; Check remaining size
    cmp     bsize, 0
    je      RDSEED_GenerateBlock_Return

RDSEED_Call_RAX:
            ;; RDSEED is not available prior to VS2012. Just emit
            ;;   the byte codes using DB. This is `rdseed rax`.
    DB      048h, 0Fh, 0C7h, 0F8h

            ;; If CF=1, the number returned by RDSEED is valid.
            ;; If CF=0, a random number was not available.

            ;; Retry immediately
    jnc     RDSEED_Call_RAX

RDSEED_succeeded:

    cmp     bsize, MWSIZE
    jb      RDSEED_Partial_Machine_Word

RDSEED_Full_Machine_Word:

    mov     QWORD PTR [buffer], rax
    add     buffer, MWSIZE
    sub     bsize, MWSIZE

            ;; Continue
    jmp     RDSEED_GenerateBlock_Top

            ;; 1,2,3,4,5,6,7 bytes remain
RDSEED_Partial_Machine_Word:

            ;; Test bit 2 to see if size is at least 4
    test    bsize, 4
    jz      RDSEED_Bit_2_Not_Set

    mov     DWORD PTR [buffer], eax
    shr     rax, 32
    add     buffer, 4

RDSEED_Bit_2_Not_Set:

            ;; Test bit 1 to see if size is at least 2
    test    bsize, 2
    jz      RDSEED_Bit_1_Not_Set

    mov     WORD PTR [buffer], ax
    shr     eax, 16
    add     buffer, 2

RDSEED_Bit_1_Not_Set:

            ;; Test bit 0 to see if size is at least 1
    test    bsize, 1
    jz      RDSEED_Bit_0_Not_Set

    mov     BYTE PTR [buffer], al
    ;; shr     ax, 8
    ;; add     buffer, 1

RDSEED_Bit_0_Not_Set:

            ;; We've hit all the bits

RDSEED_GenerateBlock_Return:

            ;; Clear artifacts
    xor     rax, rax
    ret

MASM_RDSEED_GenerateBlock ENDP

ENDIF    ;; _M_X64

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

END
esi+16],eax xor eax,[esi-4] mov [esi+20],eax add esi,24 cmp edi,esi jg .0 jmp dec_end %endif %ifdef AES_256 %ifndef DECRYPTION_TABLE ; %define DECRYPTION_TABLE %endif do_name _aes_decrypt_key256,8 mov ax, sp movzx esp, ax push ebp push ebx push esi push edi movzx eax, word [esp+20] ; ks movzx edx, word [esp+18] ; key push ax push dx do_call _aes_encrypt_key256,4 ; generate expanded encryption key mov eax,14*16 movzx esi, word [esp+20] ; ks lea edi,[esi+eax] add esi,64 mov edx,[esi-48] ; the primary key is 8 words, of which mf_call inv_mix_col ; the top four require modification mov [esi-48],eax mov edx,[esi-44] mf_call inv_mix_col mov [esi-44],eax mov edx,[esi-40] mf_call inv_mix_col mov [esi-40],eax mov edx,[esi-36] mf_call inv_mix_col mov [esi-36],eax mov edx,[esi-32] ; the encryption key expansion cycle is mf_call inv_mix_col ; now eight words long so we need to mov [esi-32],eax ; start by doing one complete block mov edx,[esi-28] mf_call inv_mix_col mov [esi-28],eax mov edx,[esi-24] mf_call inv_mix_col mov [esi-24],eax mov edx,[esi-20] mf_call inv_mix_col mov [esi-20],eax mov edx,[esi-16] mf_call inv_mix_col mov [esi-16],eax mov edx,[esi-12] mf_call inv_mix_col mov [esi-12],eax mov edx,[esi-8] mf_call inv_mix_col mov [esi-8],eax mov edx,[esi-4] mf_call inv_mix_col mov [esi-4],eax .0: mov edx,[esi] ; we can now speed up the remaining mf_call inv_mix_col ; rounds by using the technique mov [esi],eax ; outlined earlier. But note that xor eax,[esi-28] ; there is one extra inverse mix mov [esi+4],eax ; column operation as the 256 bit xor eax,[esi-24] ; key has an extra non-linear step mov [esi+8],eax ; for the midway element. xor eax,[esi-20] mov [esi+12],eax ; the expanded key is 15 * 4 = 60 mov edx,[esi+16] ; 32-bit words of which 52 need to mf_call inv_mix_col ; be modified. We have already done mov [esi+16],eax ; 12 so 40 are left - which means xor eax,[esi-12] ; that we need exactly 5 loops of 8 mov [esi+20],eax xor eax,[esi-8] mov [esi+24],eax xor eax,[esi-4] mov [esi+28],eax add esi,32 cmp edi,esi jg .0 %endif dec_end: %ifdef AES_REV_DKS movzx esi,word [esp+20] ; this reverses the order of the .1: mov eax,[esi] ; round keys if required mov ebx,[esi+4] mov ebp,[edi] mov edx,[edi+4] mov [esi],ebp mov [esi+4],edx mov [edi],eax mov [edi+4],ebx mov eax,[esi+8] mov ebx,[esi+12] mov ebp,[edi+8] mov edx,[edi+12] mov [esi+8],ebp mov [esi+12],edx mov [edi+8],eax mov [edi+12],ebx add esi,16 sub edi,16 cmp edi,esi jg .1 %endif pop edi pop esi pop ebx pop ebp xor eax,eax do_exit 8 %ifdef AES_VAR do_name _aes_decrypt_key,12 mov ecx,[esp+4] mov eax,[esp+8] mov edx,[esp+12] push edx push ecx cmp eax,16 je .1 cmp eax,128 je .1 cmp eax,24 je .2 cmp eax,192 je .2 cmp eax,32 je .3 cmp eax,256 je .3 mov eax,-1 add esp,8 do_exit 12 .1: do_call _aes_decrypt_key128,8 do_exit 12 .2: do_call _aes_decrypt_key192,8 do_exit 12 .3: do_call _aes_decrypt_key256,8 do_exit 12 %endif %endif %ifdef DECRYPTION_TABLE ; Inverse S-box data - 256 entries section _DATA %define v8(x) fe(x), f9(x), fd(x), fb(x), fe(x), f9(x), fd(x), x _aes_dec_tab: db v8(0x52),v8(0x09),v8(0x6a),v8(0xd5),v8(0x30),v8(0x36),v8(0xa5),v8(0x38) db v8(0xbf),v8(0x40),v8(0xa3),v8(0x9e),v8(0x81),v8(0xf3),v8(0xd7),v8(0xfb) db v8(0x7c),v8(0xe3),v8(0x39),v8(0x82),v8(0x9b),v8(0x2f),v8(0xff),v8(0x87) db v8(0x34),v8(0x8e),v8(0x43),v8(0x44),v8(0xc4),v8(0xde),v8(0xe9),v8(0xcb) db v8(0x54),v8(0x7b),v8(0x94),v8(0x32),v8(0xa6),v8(0xc2),v8(0x23),v8(0x3d) db v8(0xee),v8(0x4c),v8(0x95),v8(0x0b),v8(0x42),v8(0xfa),v8(0xc3),v8(0x4e) db v8(0x08),v8(0x2e),v8(0xa1),v8(0x66),v8(0x28),v8(0xd9),v8(0x24),v8(0xb2) db v8(0x76),v8(0x5b),v8(0xa2),v8(0x49),v8(0x6d),v8(0x8b),v8(0xd1),v8(0x25) db v8(0x72),v8(0xf8),v8(0xf6),v8(0x64),v8(0x86),v8(0x68),v8(0x98),v8(0x16) db v8(0xd4),v8(0xa4),v8(0x5c),v8(0xcc),v8(0x5d),v8(0x65),v8(0xb6),v8(0x92) db v8(0x6c),v8(0x70),v8(0x48),v8(0x50),v8(0xfd),v8(0xed),v8(0xb9),v8(0xda) db v8(0x5e),v8(0x15),v8(0x46),v8(0x57),v8(0xa7),v8(0x8d),v8(0x9d),v8(0x84) db v8(0x90),v8(0xd8),v8(0xab),v8(0x00),v8(0x8c),v8(0xbc),v8(0xd3),v8(0x0a) db v8(0xf7),v8(0xe4),v8(0x58),v8(0x05),v8(0xb8),v8(0xb3),v8(0x45),v8(0x06) db v8(0xd0),v8(0x2c),v8(0x1e),v8(0x8f),v8(0xca),v8(0x3f),v8(0x0f),v8(0x02) db v8(0xc1),v8(0xaf),v8(0xbd),v8(0x03),v8(0x01),v8(0x13),v8(0x8a),v8(0x6b) db v8(0x3a),v8(0x91),v8(0x11),v8(0x41),v8(0x4f),v8(0x67),v8(0xdc),v8(0xea) db v8(0x97),v8(0xf2),v8(0xcf),v8(0xce),v8(0xf0),v8(0xb4),v8(0xe6),v8(0x73) db v8(0x96),v8(0xac),v8(0x74),v8(0x22),v8(0xe7),v8(0xad),v8(0x35),v8(0x85) db v8(0xe2),v8(0xf9),v8(0x37),v8(0xe8),v8(0x1c),v8(0x75),v8(0xdf),v8(0x6e) db v8(0x47),v8(0xf1),v8(0x1a),v8(0x71),v8(0x1d),v8(0x29),v8(0xc5),v8(0x89) db v8(0x6f),v8(0xb7),v8(0x62),v8(0x0e),v8(0xaa),v8(0x18),v8(0xbe),v8(0x1b) db v8(0xfc),v8(0x56),v8(0x3e),v8(0x4b),v8(0xc6),v8(0xd2),v8(0x79),v8(0x20) db v8(0x9a),v8(0xdb),v8(0xc0),v8(0xfe),v8(0x78),v8(0xcd),v8(0x5a),v8(0xf4) db v8(0x1f),v8(0xdd),v8(0xa8),v8(0x33),v8(0x88),v8(0x07),v8(0xc7),v8(0x31) db v8(0xb1),v8(0x12),v8(0x10),v8(0x59),v8(0x27),v8(0x80),v8(0xec),v8(0x5f) db v8(0x60),v8(0x51),v8(0x7f),v8(0xa9),v8(0x19),v8(0xb5),v8(0x4a),v8(0x0d) db v8(0x2d),v8(0xe5),v8(0x7a),v8(0x9f),v8(0x93),v8(0xc9),v8(0x9c),v8(0xef) db v8(0xa0),v8(0xe0),v8(0x3b),v8(0x4d),v8(0xae),v8(0x2a),v8(0xf5),v8(0xb0) db v8(0xc8),v8(0xeb),v8(0xbb),v8(0x3c),v8(0x83),v8(0x53),v8(0x99),v8(0x61) db v8(0x17),v8(0x2b),v8(0x04),v8(0x7e),v8(0xba),v8(0x77),v8(0xd6),v8(0x26) db v8(0xe1),v8(0x69),v8(0x14),v8(0x63),v8(0x55),v8(0x21),v8(0x0c),v8(0x7d) %endif