Full Disclosure mailing list archives

xxt encryption util


From: full-disclosure () lists netsys com (full-disclosure () lists netsys com)
Date: Fri, 23 Aug 2002 06:18:47 -0700

  This message is in MIME format.  The first part should be readable text,
  while the remaining parts are likely unreadable without MIME-aware tools.
  Send mail to mime () docserver cac washington edu for more info.

---1062731517-1852493920-1030108727=:13004
Content-Type: TEXT/PLAIN; charset=US-ASCII

/* xxt encryptor by aliver               */
/*     just to prove I dont just talk    */
/*     about coding. I do it quite a bit */
/*     as well...                        */
/*                                       */
/* Preamble:                             */
/* Just tighten your fists, squint your  */
/* eyes, press your lips together, turn  */
/* beet red, quiver, pound the table,    */
/* adjust your white cap and scream:     */
/* "It can't be! Blackhats can't code!"  */
/*                                       */
/* An implementation of xxtea encryption */
/* A very small (code wise) secure block */
/* cipher. Supposedly faster than btea   */
/* and for files of any non-trival size  */
/* it's gonna be way faster than TEA or  */
/* IDEA. At worst it's something like 4x */
/* the speed of DES, and more secure by  */
/* a factor of 2^72 ~ 4.7 x 10^21        */
/* My tests seemed to indicate that xxt  */
/* is about 3x the speed of mcrypt with  */
/* the same options. Not that mcrypt is  */
/* not a great piece of work. It is.     */
/*                                       */
/* The xxtea algorithm was designed by:  */
/* David Wheeler and Roger Needham. Some */
/* code from their publications was used */
/* for some of the encryption portions.  */
/* However it was altered to be 64 bit   */
/* architecture friendly.                */
/*                                       */
/* MD5 Hashing was invented by:          */
/* Professor Ronald Rivest               */
/* I use MD5 to hash the key. The MD5    */
/* implementation here is uses a public  */
/* domain RFC1321 ripoff implementation  */
/* from:                                 */
/* L. Peter Deutsch                      */
/* so the RSA folks can't claim I owe    */
/* them anything.                        */
/*****************************************/
/* Compile with cc -O3 -o xxt xxt.c      */
/* "xxt -h" for help, after that         */
/* tested on IRIX, Solaris, Linux        */
/* NetBSD, and AIX                       */


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <inttypes.h>
#include <string.h>
#include <errno.h>
#include <netinet/in.h>

long btea( int32_t * v, int32_t n , int32_t * k );
char * memncat(char *binstr_a,int size_a,char *binstr_b,int size_b);
char * cnp(char *bytestream, int block, int size);
void showhelp(void);

#define MX (z>>5^y<<2)+(y>>3^z<<4)^(sum^y)+(k[p&3^e]^z) ;

/* most of the MD5 hashing stuff is from L. Peter Deutsch */
/* see his notice at the bottom along with the algorithm  */
#ifndef md5_INCLUDED
#define md5_INCLUDED
typedef unsigned char md5_byte_t; /* 8-bit byte */
typedef unsigned int md5_word_t; /* 32-bit word */
typedef struct md5_state_s {
    md5_word_t count[2];
    md5_word_t abcd[4];
    md5_byte_t buf[64];
} md5_state_t;

void md5_init(md5_state_t *pms);
void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes);
void md5_finish(md5_state_t *pms, md5_byte_t digest[16]);
#endif

/* you can get some trival speedups with MSB if you define this right */
#undef BYTE_ORDER       /* 1 = big-endian, -1 = little-endian, 0 = unknown */
#ifdef ARCH_IS_BIG_ENDIAN
#  define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1)
#else
#  define BYTE_ORDER 0
#endif

#define T_MASK ((md5_word_t)~0)
#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87)
#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9)
#define T3    0x242070db
#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111)
#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050)
#define T6    0x4787c62a
#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec)
#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe)
#define T9    0x698098d8
#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850)
#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e)
#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841)
#define T13    0x6b901122
#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c)
#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71)
#define T16    0x49b40821
#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d)
#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf)
#define T19    0x265e5a51
#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855)
#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2)
#define T22    0x02441453
#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e)
#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437)
#define T25    0x21e1cde6
#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829)
#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278)
#define T28    0x455a14ed
#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa)
#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07)
#define T31    0x676f02d9
#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375)
#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd)
#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e)
#define T35    0x6d9d6122
#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3)
#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb)
#define T38    0x4bdecfa9
#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f)
#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f)
#define T41    0x289b7ec6
#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805)
#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a)
#define T44    0x04881d05
#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6)
#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a)
#define T47    0x1fa27cf8
#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a)
#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb)
#define T50    0x432aff97
#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58)
#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6)
#define T53    0x655b59c3
#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d)
#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82)
#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e)
#define T57    0x6fa87e4f
#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f)
#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb)
#define T60    0x4e0811a1
#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d)
#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca)
#define T63    0x2ad7d2bb
#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e)


int main (int argc, char *argv[]){
   extern char *optarg;
   extern int  optind;
   extern int errno;
   int c;
   int i;
   int j;
   int sl;
   int debug = 0;
   int unlinkit = 0;
   int use_out = 0;
   int use_kp  = 0;
   int first_block = 1;
   int fd_in;
   int fd_out;
   int encrypt = 0;
   int decrypt = 0;
   int bl = 0;
   int bytes_read;
   int pad;
   int noumask = 0;
   uint32_t filesize = 0;
   uint32_t filesize_msb = 0;
   uint32_t read_filesize_msb = 0;
   uint32_t read_filesize = 0;
   uint32_t bsf = 0;
   char *in_file = NULL;
   char *out_file = NULL;
   char *keyphrase = NULL;
   char *keyenv = NULL;
   char hash[16];
   char thash[17];
   char hbuf[3];
   char fb_buffer[64];
   /* u_char *plaintext = NULL; */
   u_char plaintext[64];
   struct stat statbuf;
   md5_state_t state;
   md5_byte_t digest[32];

   while( (c = getopt(argc,argv,"i:o:k:g:hxdeuv")) != -1 ){
      switch(c){
         case 'h':
           showhelp();
           break;
         case 'v':
            debug = 1;
           break;
         case 'i':
            if(NULL == (in_file = (char *) malloc(strlen(optarg) + 2))){
              fprintf(stderr,"FATAL: cannot allocate memory.\n");
              exit(1);
            }
            strncpy(in_file,optarg,strlen(optarg) + 1);
           break;
         case 'o':
            use_out = 1;
            if(NULL == (out_file = (char *) malloc(strlen(optarg) + 2))){
              fprintf(stderr,"FATAL: cannot allocate memory.\n");
              exit(1);
            }
            strncpy(out_file,optarg,strlen(optarg) + 1);
           break;
         case 'k':
            fprintf(stderr,"WARNING: using a keyphrase from the command line can be insecure.\n");
            use_kp = 1;
            if(NULL == (keyphrase = (char *) malloc(strlen(optarg) + 2))){
              fprintf(stderr,"FATAL: cannot allocate memory.\n");
              exit(1);
            }
            strncpy(keyphrase,optarg,strlen(optarg) + 1);
           break;
         case 'g':
            use_kp = 1;
            keyenv = getenv(optarg);
            if(NULL == (keyphrase = (char *) malloc(strlen(keyenv) + 2))){
              fprintf(stderr,"FATAL: cannot allocate memory.\n");
              exit(1);
            }
            strncpy(keyphrase,keyenv,strlen(keyenv) + 1);
           break;
         case 'd':
            decrypt = 1;
           break;
         case 'e':
            encrypt = 1;
           break;
         case 'u':
            unlinkit = 1;
           break;
         case 'x':
            noumask = 1;
           break;
      } /* end of switch() */
   } /* end of while getopt() */

   /* you must use a key file or a key phrase */
   if(!use_kp){
       fprintf(stderr,"FATAL: I wont encrypt without a key!\n\n");
       showhelp();
       exit(1);
   }

   /* one mode, and only one mode. */
   if((decrypt && encrypt) || (!encrypt && !decrypt)){
       fprintf(stderr,"FATAL: Your encrypt/decrypt options are missing or do not make sense.\n");
       exit(1);
   }

   /* They must give us an input file, and it must */
   /* be statable and readable by us or we fail    */
   if(in_file != NULL){
      if(-1 == (stat(in_file,&statbuf))){
         fprintf(stderr,"FATAL: cannot stat the input file!\n");
         exit(1);
      }
      if(statbuf.st_size == (off_t) 0){
         fprintf(stderr,"FATAL: WTF are you encrypting an empty file for?\n");
         exit(1);
      } else {
         (off_t) filesize = statbuf.st_size;
         filesize_msb = htonl(filesize);
      }
      if(!noumask) umask(077);
      if(-1 == (fd_in = open(in_file,O_RDONLY))){
         fprintf(stderr,"FATAL: Cannot open() the file.\n\t%s\n",strerror(errno));
         exit(1);
      }
   } else {
      fprintf(stderr,"FATAL: no input file!\n");
      exit(1);
   }

   /* if they didn't provide an out file, let's use */
   /* in_file.xxt as the out_file name              */
   if(out_file == NULL){
      use_out = 1;
      if(NULL == (out_file = (char *) malloc(strlen(in_file) + 6))){
        fprintf(stderr,"FATAL: cannot allocate memory.\n");
        exit(1);
      }
      snprintf(out_file,strlen(in_file) + 6,"%s.xxt",in_file);
      if(!noumask) umask(077);
      if(-1 == (fd_out = open(out_file,O_WRONLY|O_CREAT,00600))){
         fprintf(stderr,"FATAL: cannot open the output file %s for writing.\n\t%s\n"
                 ,out_file
                 ,strerror(errno));
         exit(1);
      }
   } else {
      if(!noumask) umask(077);
      if(-1 == (fd_out = open(out_file,O_WRONLY|O_CREAT,00600))){
         fprintf(stderr,"FATAL: cannot open the output file %s for writing.\n\t%s\n"
                ,out_file
                ,strerror(errno));
         exit(1);
      }
   }

   /* try to pull a fast one and wipe the arguments */
   /* a person could still try and race to get them */
   /* but it'd be pretty tough (NOT impossible) I'm */
   /* just making it harder, but I'm not going to   */
   /* say that this makes it a totally secure way   */
   /* to make passing the key on the command line a */
   /* sane or good idea. It's there because while   */
   /* you are in a hurry (we blackhats are never in */
   /* a hurry, har har) it can be useful.           */
   for (i = 1; i < argc; ++i) {
        sl = strlen(argv[i]);
        for (j = 0; j < sl; ++j)
            argv[i][j] = 0;
   }

   memset(hash,0,16);
   /* lets hash the keys. We get a 256 bit hash    */
   /* from md5, but xxtea takes a 128 bit key so   */
   /* the hash is truncated to the first 128 bits  */
   md5_init(&state);
   md5_append(&state, (const md5_byte_t *) keyphrase, strlen(keyphrase));
   md5_finish(&state, digest);
   for (i = 0; i < 8; i++) {
      snprintf(hbuf,3,"%02x",digest[i]);
      memcpy(hash+(i*2),hbuf,2);
   }

   /* show a summary of args if we are in verbose mode */
   if(debug){
      printf("---=[  Your option summary ]=--- \n");
      printf("INFILE    == %s\n",in_file);
      printf("OUTFILE   == %s\n",out_file);
      printf("UNLINK    == %d\n",unlinkit);
      memcpy(thash,hash,16);
      thash[16] = '\0';
      /* printf("HASH      == %s\n",thash); */
   }

   if(encrypt){
     while(first_block){
        bytes_read = read(fd_in,plaintext,60);
        if(bytes_read == -1){
           printf("FATAL:  Problem reading input file.\n\t%s\n",strerror(errno));
           exit(1);
        }
        /* if the initial input isn't at least 60 bytes */
        /* we are going to have to pad it. */
        if(bytes_read != 60){
           pad = 60 - bytes_read ;
           memcpy(plaintext+bytes_read,hash,pad);
        }
        memcpy(fb_buffer, &filesize_msb, 4);
        memcpy(fb_buffer+4, plaintext, 60);
        btea((int32_t *) fb_buffer, 16, (int32_t *) hash);
        write(fd_out,(char *) fb_buffer,64);
        first_block = 0;
     }
     while( (bytes_read = read(fd_in,plaintext,64)) ){
           if(bytes_read == 64){
             btea((int32_t *) plaintext, 16, (int32_t *) hash);
             write(fd_out,(char *) plaintext,64);
           } else {
             pad = 64 - bytes_read;
             memcpy(plaintext+bytes_read,hash,pad);
             btea((int32_t *) plaintext, 16, (int32_t *) hash);
             write(fd_out,(char *) plaintext,64);
           }
     }
   } else if(decrypt) {
     while(first_block){
        read(fd_in,plaintext,64);
        btea((int32_t *) plaintext, -16, (int32_t *) hash);
        memcpy(&read_filesize_msb,plaintext,4);
        read_filesize = ntohl(read_filesize_msb);
        if(read_filesize >= 60){
          write(fd_out,(char *) plaintext+4,60);
        } else {
          write(fd_out,(char *) plaintext+4,read_filesize);
        }
        bsf += 64;
        first_block = 0;
     }
     while(0 != (bytes_read = read(fd_in,plaintext,64)) ){
           btea((int32_t *) plaintext, -16, (int32_t *) hash);
           bsf += 64;
           if(bsf < (read_filesize + 4) && read_filesize > 64){
              write(fd_out,(char *) plaintext,64);
           } else {
              bl = 64 - (bsf - (read_filesize + 4)); /* calc how much is really left */
              write(fd_out,(char *) plaintext,bl);
           }
     }
   }

   /* if they want to delete the infile */
   if(unlinkit) unlink(in_file);

   /* free dynamically allocated memory and zero out the contents to */
   /* try to make recovery of information about what we did harder   */
   memset(in_file,0,strlen(in_file));
   free(in_file);
   if(use_kp){
      memset(keyphrase,0,strlen(keyphrase));
      free(keyphrase);
   }
   if(use_out){
      memset(out_file,0,strlen(out_file));
      free(out_file);
   }
   close(fd_out);
   close(fd_in);
   return(0);
}

void showhelp(void){
   printf("\nxxt - an xxtea based variable block-mode file encryptor.\n");
   printf("by aliver\n\n");
   printf("+---=[ Options ]=--------------------------+\n");
   printf("|                                          |\n");
   printf("| -h print help        -v be verbose       |\n");
   printf("| -i input_file        -o output_file      |\n");
   printf("| -k keyphrase         -g key env_variable |\n");
   printf("| -u unlink input_file after encryption    |\n");
   printf("| -x dont set umask to a safe value        |\n");
   printf("| Example:                                 |\n");
   printf("| \"xxt -k secretpass -i test -d\"           |\n");
   printf("| You get \"test.xxt\" and deletes \"test\"    |\n");
   printf("|                                          |\n");
   printf("+------------------------------------------+\n");

}


/* nearly all the following xxtea crypto */
/* code from the post script             */
/* by David Wheeler and Roger Needham    */
/* I've altered it to be more portable   */
/* on 64 bit platforms by making use of  */
/* definitions in stdint.h               */
long btea( int32_t * v, int32_t n , int32_t * k ) {
    uint32_t z=v[n-1], y=v[0], sum=0,e,
    DELTA=0x9e3779b9 ;
    int32_t p, q ;
    if ( n>1) {
        /* Coding Part */
        q = 6+52/n ;
        while ( q-- > 0 ) {
            sum += DELTA ;
            e = sum >> 2&3 ;
            for ( p = 0 ; p < n-1 ; p++ )
                y = v[p+1],
                z = v[p] += MX
                y = v[0] ;
            z = v[n-1] += MX
         }
         return 0 ;
    }
    /* Decoding Part */
    else if ( n <-1 ) {
        n = -n ;
        q = 6+52/n ;
        sum = q*DELTA ;
        while (sum != 0) {
            e = sum>>2 & 3 ;
            for (p = n-1 ; p > 0 ; p-- )
                z = v[p-1],
                y = v[p] -= MX
                z = v[n-1] ;
            y = v[0] -= MX
            sum -= DELTA ;
        }
        return 0 ;
    }
    return 1 ;
} /* Signal n=0,1,-1 */



/* MD5 algorithm used to hash the keys given to xxt */
/* This source code has been altered to better suit */
/* my purposes (speed, and formatting) and I am now */
/* declaring it so nobody has a fit about it. Now   */
/* you can read Peter's notice below. It only       */
/* applies to the MD5 hashing part of xxt !         */

/*
  Copyright (C) 1999, 2000, 2002 Aladdin Enterprises.  All rights reserved.

  This software is provided 'as-is', without any express or implied
  warranty.  In no event will the authors be held liable for any damages
  arising from the use of this software.

  Permission is granted to anyone to use this software for any purpose,
  including commercial applications, and to alter it and redistribute it
  freely, subject to the following restrictions:

  1. The origin of this software must not be misrepresented; you must not
     claim that you wrote the original software. If you use this software
     in a product, an acknowledgment in the product documentation would be
     appreciated but is not required.
  2. Altered source versions must be plainly marked as such, and must not be
     misrepresented as being the original software.
  3. This notice may not be removed or altered from any source distribution.

  L. Peter Deutsch
  ghost () aladdin com

 */

static void md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/){
    md5_word_t
        a = pms->abcd[0], b = pms->abcd[1],
        c = pms->abcd[2], d = pms->abcd[3];
    md5_word_t t;
#if BYTE_ORDER > 0
    /* Define storage only for big-endian CPUs. */
    md5_word_t X[16];
#else
    /* Define storage for little-endian or both types of CPUs. */
    md5_word_t xbuf[16];
    const md5_word_t *X;
#endif

    {
#if BYTE_ORDER == 0
        /*
         * Determine dynamically whether this is a big-endian or
         * little-endian machine, since we can use a more efficient
         * algorithm on the latter.
         */
        static const int w = 1;

        if (*((const md5_byte_t *)&w)) /* dynamic little-endian */
#endif
#if BYTE_ORDER <= 0             /* little-endian */
        {
            /*
             * On little-endian machines, we can process properly aligned
             * data without copying it.
             */
            if (!((data - (const md5_byte_t *)0) & 3)) {
                /* data are properly aligned */
                X = (const md5_word_t *)data;
            } else {
                /* not aligned */
                memcpy(xbuf, data, 64);
                X = xbuf;
            }
        }
#endif
#if BYTE_ORDER == 0
        else                    /* dynamic big-endian */
#endif
#if BYTE_ORDER >= 0             /* big-endian */
        {
            /*
             * On big-endian machines, we must arrange the bytes in the
             * right order.
             */
            const md5_byte_t *xp = data;
            int i;

#  if BYTE_ORDER == 0
            X = xbuf;           /* (dynamic only) */
#  else
#    define xbuf X              /* (static only) */
#  endif
            for (i = 0; i < 16; ++i, xp += 4)
                xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
        }
#endif
    }

#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))

    /* Round 1. */
    /* Let [abcd k s i] denote the operation
       a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
#define SET(a, b, c, d, k, s, Ti)\
  t = a + F(b,c,d) + X[k] + Ti;\
  a = ROTATE_LEFT(t, s) + b
    /* Do the following 16 operations. */
    SET(a, b, c, d,  0,  7,  T1);
    SET(d, a, b, c,  1, 12,  T2);
    SET(c, d, a, b,  2, 17,  T3);
    SET(b, c, d, a,  3, 22,  T4);
    SET(a, b, c, d,  4,  7,  T5);
    SET(d, a, b, c,  5, 12,  T6);
    SET(c, d, a, b,  6, 17,  T7);
    SET(b, c, d, a,  7, 22,  T8);
    SET(a, b, c, d,  8,  7,  T9);
    SET(d, a, b, c,  9, 12, T10);
    SET(c, d, a, b, 10, 17, T11);
    SET(b, c, d, a, 11, 22, T12);
    SET(a, b, c, d, 12,  7, T13);
    SET(d, a, b, c, 13, 12, T14);
    SET(c, d, a, b, 14, 17, T15);
    SET(b, c, d, a, 15, 22, T16);
#undef SET

     /* Round 2. */
     /* Let [abcd k s i] denote the operation
          a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
#define SET(a, b, c, d, k, s, Ti)\
  t = a + G(b,c,d) + X[k] + Ti;\
  a = ROTATE_LEFT(t, s) + b
     /* Do the following 16 operations. */
    SET(a, b, c, d,  1,  5, T17);
    SET(d, a, b, c,  6,  9, T18);
    SET(c, d, a, b, 11, 14, T19);
    SET(b, c, d, a,  0, 20, T20);
    SET(a, b, c, d,  5,  5, T21);
    SET(d, a, b, c, 10,  9, T22);
    SET(c, d, a, b, 15, 14, T23);
    SET(b, c, d, a,  4, 20, T24);
    SET(a, b, c, d,  9,  5, T25);
    SET(d, a, b, c, 14,  9, T26);
    SET(c, d, a, b,  3, 14, T27);
    SET(b, c, d, a,  8, 20, T28);
    SET(a, b, c, d, 13,  5, T29);
    SET(d, a, b, c,  2,  9, T30);
    SET(c, d, a, b,  7, 14, T31);
    SET(b, c, d, a, 12, 20, T32);
#undef SET

     /* Round 3. */
     /* Let [abcd k s t] denote the operation
          a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define SET(a, b, c, d, k, s, Ti)\
  t = a + H(b,c,d) + X[k] + Ti;\
  a = ROTATE_LEFT(t, s) + b
     /* Do the following 16 operations. */
    SET(a, b, c, d,  5,  4, T33);
    SET(d, a, b, c,  8, 11, T34);
    SET(c, d, a, b, 11, 16, T35);
    SET(b, c, d, a, 14, 23, T36);
    SET(a, b, c, d,  1,  4, T37);
    SET(d, a, b, c,  4, 11, T38);
    SET(c, d, a, b,  7, 16, T39);
    SET(b, c, d, a, 10, 23, T40);
    SET(a, b, c, d, 13,  4, T41);
    SET(d, a, b, c,  0, 11, T42);
    SET(c, d, a, b,  3, 16, T43);
    SET(b, c, d, a,  6, 23, T44);
    SET(a, b, c, d,  9,  4, T45);
    SET(d, a, b, c, 12, 11, T46);
    SET(c, d, a, b, 15, 16, T47);
    SET(b, c, d, a,  2, 23, T48);
#undef SET

     /* Round 4. */
     /* Let [abcd k s t] denote the operation
          a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
#define I(x, y, z) ((y) ^ ((x) | ~(z)))
#define SET(a, b, c, d, k, s, Ti)\
  t = a + I(b,c,d) + X[k] + Ti;\
  a = ROTATE_LEFT(t, s) + b
     /* Do the following 16 operations. */
    SET(a, b, c, d,  0,  6, T49);
    SET(d, a, b, c,  7, 10, T50);
    SET(c, d, a, b, 14, 15, T51);
    SET(b, c, d, a,  5, 21, T52);
    SET(a, b, c, d, 12,  6, T53);
    SET(d, a, b, c,  3, 10, T54);
    SET(c, d, a, b, 10, 15, T55);
    SET(b, c, d, a,  1, 21, T56);
    SET(a, b, c, d,  8,  6, T57);
    SET(d, a, b, c, 15, 10, T58);
    SET(c, d, a, b,  6, 15, T59);
    SET(b, c, d, a, 13, 21, T60);
    SET(a, b, c, d,  4,  6, T61);
    SET(d, a, b, c, 11, 10, T62);
    SET(c, d, a, b,  2, 15, T63);
    SET(b, c, d, a,  9, 21, T64);
#undef SET

     /* Then perform the following additions. (That is increment each
        of the four registers by the value it had before this block
        was started.) */
    pms->abcd[0] += a;
    pms->abcd[1] += b;
    pms->abcd[2] += c;
    pms->abcd[3] += d;
}

void md5_init(md5_state_t *pms){
    pms->count[0] = pms->count[1] = 0;
    pms->abcd[0] = 0x67452301;
    pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476;
    pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301;
    pms->abcd[3] = 0x10325476;
}

void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes){
    const md5_byte_t *p = data;
    int left = nbytes;
    int offset = (pms->count[0] >> 3) & 63;
    md5_word_t nbits = (md5_word_t)(nbytes << 3);

    if (nbytes <= 0)
        return;

    /* Update the message length. */
    pms->count[1] += nbytes >> 29;
    pms->count[0] += nbits;
    if (pms->count[0] < nbits)
        pms->count[1]++;

    /* Process an initial partial block. */
    if (offset) {
        int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);

        memcpy(pms->buf + offset, p, copy);
        if (offset + copy < 64)
            return;
        p += copy;
        left -= copy;
        md5_process(pms, pms->buf);
    }

    /* Process full blocks. */
    for (; left >= 64; p += 64, left -= 64)
        md5_process(pms, p);

    /* Process a final partial block. */
    if (left)
        memcpy(pms->buf, p, left);
}

void md5_finish(md5_state_t *pms, md5_byte_t digest[16]) {
    static const md5_byte_t pad[64] = {
        0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    };
    md5_byte_t data[8];
    int i;

    /* Save the length before padding. */
    for (i = 0; i < 8; ++i)
        data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
    /* Pad to 56 bytes mod 64. */
    md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
    /* Append the length. */
    md5_append(pms, data, 8);
    for (i = 0; i < 16; ++i)
        digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
}


---1062731517-1852493920-1030108727=:13004
Content-Type: TEXT/PLAIN; charset=US-ASCII; name="xxt.c"
Content-Transfer-Encoding: BASE64
Content-ID: <Pine.SGI.4.44.0208230618470.13004@hexeris>
Content-Description: xxt encryption util code
Content-Disposition: attachment; filename="xxt.c"

LyogeHh0IGVuY3J5cHRvciBieSBhbGl2ZXIgICAgICAgICAgICAgICAqLw0K
LyogICAgIGp1c3QgdG8gcHJvdmUgSSBkb250IGp1c3QgdGFsayAgICAqLw0K
LyogICAgIGFib3V0IGNvZGluZy4gSSBkbyBpdCBxdWl0ZSBhIGJpdCAqLw0K
LyogICAgIGFzIHdlbGwuLi4gICAgICAgICAgICAgICAgICAgICAgICAqLw0K
LyogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLw0K
LyogUHJlYW1ibGU6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLw0K
LyogSnVzdCB0aWdodGVuIHlvdXIgZmlzdHMsIHNxdWludCB5b3VyICAqLw0K
LyogZXllcywgcHJlc3MgeW91ciBsaXBzIHRvZ2V0aGVyLCB0dXJuICAqLw0K
LyogYmVldCByZWQsIHF1aXZlciwgcG91bmQgdGhlIHRhYmxlLCAgICAqLw0K
LyogYWRqdXN0IHlvdXIgd2hpdGUgY2FwIGFuZCBzY3JlYW06ICAgICAqLw0K
LyogIkl0IGNhbid0IGJlISBCbGFja2hhdHMgY2FuJ3QgY29kZSEiICAqLw0K
LyogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLw0K
LyogQW4gaW1wbGVtZW50YXRpb24gb2YgeHh0ZWEgZW5jcnlwdGlvbiAqLw0K
LyogQSB2ZXJ5IHNtYWxsIChjb2RlIHdpc2UpIHNlY3VyZSBibG9jayAqLw0K
LyogY2lwaGVyLiBTdXBwb3NlZGx5IGZhc3RlciB0aGFuIGJ0ZWEgICAqLw0K
LyogYW5kIGZvciBmaWxlcyBvZiBhbnkgbm9uLXRyaXZhbCBzaXplICAqLw0K
LyogaXQncyBnb25uYSBiZSB3YXkgZmFzdGVyIHRoYW4gVEVBIG9yICAqLw0K
LyogSURFQS4gQXQgd29yc3QgaXQncyBzb21ldGhpbmcgbGlrZSA0eCAqLw0K
LyogdGhlIHNwZWVkIG9mIERFUywgYW5kIG1vcmUgc2VjdXJlIGJ5ICAqLw0K
LyogYSBmYWN0b3Igb2YgMl43MiB+IDQuNyB4IDEwXjIxICAgICAgICAqLw0K
LyogTXkgdGVzdHMgc2VlbWVkIHRvIGluZGljYXRlIHRoYXQgeHh0ICAqLw0K
LyogaXMgYWJvdXQgM3ggdGhlIHNwZWVkIG9mIG1jcnlwdCB3aXRoICAqLw0K
LyogdGhlIHNhbWUgb3B0aW9ucy4gTm90IHRoYXQgbWNyeXB0IGlzICAqLw0K
Lyogbm90IGEgZ3JlYXQgcGllY2Ugb2Ygd29yay4gSXQgaXMuICAgICAqLw0K
LyogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLw0K
LyogVGhlIHh4dGVhIGFsZ29yaXRobSB3YXMgZGVzaWduZWQgYnk6ICAqLw0K
LyogRGF2aWQgV2hlZWxlciBhbmQgUm9nZXIgTmVlZGhhbS4gU29tZSAqLw0K
LyogY29kZSBmcm9tIHRoZWlyIHB1YmxpY2F0aW9ucyB3YXMgdXNlZCAqLw0K
LyogZm9yIHNvbWUgb2YgdGhlIGVuY3J5cHRpb24gcG9ydGlvbnMuICAqLw0K
LyogSG93ZXZlciBpdCB3YXMgYWx0ZXJlZCB0byBiZSA2NCBiaXQgICAqLw0K
LyogYXJjaGl0ZWN0dXJlIGZyaWVuZGx5LiAgICAgICAgICAgICAgICAqLw0K
LyogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLw0K
LyogTUQ1IEhhc2hpbmcgd2FzIGludmVudGVkIGJ5OiAgICAgICAgICAqLw0K
LyogUHJvZmVzc29yIFJvbmFsZCBSaXZlc3QgICAgICAgICAgICAgICAqLw0K
LyogSSB1c2UgTUQ1IHRvIGhhc2ggdGhlIGtleS4gVGhlIE1ENSAgICAqLw0K
LyogaW1wbGVtZW50YXRpb24gaGVyZSBpcyB1c2VzIGEgcHVibGljICAqLw0K
LyogZG9tYWluIFJGQzEzMjEgcmlwb2ZmIGltcGxlbWVudGF0aW9uICAqLw0K
LyogZnJvbTogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLw0K
LyogTC4gUGV0ZXIgRGV1dHNjaCAgICAgICAgICAgICAgICAgICAgICAqLw0K
Lyogc28gdGhlIFJTQSBmb2xrcyBjYW4ndCBjbGFpbSBJIG93ZSAgICAqLw0K
LyogdGhlbSBhbnl0aGluZy4gICAgICAgICAgICAgICAgICAgICAgICAqLw0K
LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLw0K
LyogQ29tcGlsZSB3aXRoIGNjIC1PMyAtbyB4eHQgeHh0LmMgICAgICAqLw0K
LyogInh4dCAtaCIgZm9yIGhlbHAsIGFmdGVyIHRoYXQgICAgICAgICAqLw0K
LyogdGVzdGVkIG9uIElSSVgsIFNvbGFyaXMsIExpbnV4ICAgICAgICAqLw0K
LyogTmV0QlNELCBhbmQgQUlYICAgICAgICAgICAgICAgICAgICAgICAqLw0K
DQoNCiNpbmNsdWRlIDxzdGRpby5oPg0KI2luY2x1ZGUgPHN0ZGxpYi5oPg0K
I2luY2x1ZGUgPHVuaXN0ZC5oPg0KI2luY2x1ZGUgPGZjbnRsLmg+DQojaW5j
bHVkZSA8c3lzL3R5cGVzLmg+DQojaW5jbHVkZSA8c3lzL3N0YXQuaD4NCiNp
bmNsdWRlIDxpbnR0eXBlcy5oPg0KI2luY2x1ZGUgPHN0cmluZy5oPg0KI2lu
Y2x1ZGUgPGVycm5vLmg+DQojaW5jbHVkZSA8bmV0aW5ldC9pbi5oPg0KDQps
b25nIGJ0ZWEoIGludDMyX3QgKiB2LCBpbnQzMl90IG4gLCBpbnQzMl90ICog
ayApOw0KY2hhciAqIG1lbW5jYXQoY2hhciAqYmluc3RyX2EsaW50IHNpemVf
YSxjaGFyICpiaW5zdHJfYixpbnQgc2l6ZV9iKTsNCmNoYXIgKiBjbnAoY2hh
ciAqYnl0ZXN0cmVhbSwgaW50IGJsb2NrLCBpbnQgc2l6ZSk7DQp2b2lkIHNo
b3doZWxwKHZvaWQpOw0KDQojZGVmaW5lIE1YICh6Pj41Xnk8PDIpKyh5Pj4z
Xno8PDQpXihzdW1eeSkrKGtbcCYzXmVdXnopIDsNCg0KLyogbW9zdCBvZiB0
aGUgTUQ1IGhhc2hpbmcgc3R1ZmYgaXMgZnJvbSBMLiBQZXRlciBEZXV0c2No
ICovDQovKiBzZWUgaGlzIG5vdGljZSBhdCB0aGUgYm90dG9tIGFsb25nIHdp
dGggdGhlIGFsZ29yaXRobSAgKi8NCiNpZm5kZWYgbWQ1X0lOQ0xVREVEDQoj
ZGVmaW5lIG1kNV9JTkNMVURFRA0KdHlwZWRlZiB1bnNpZ25lZCBjaGFyIG1k
NV9ieXRlX3Q7IC8qIDgtYml0IGJ5dGUgKi8NCnR5cGVkZWYgdW5zaWduZWQg
aW50IG1kNV93b3JkX3Q7IC8qIDMyLWJpdCB3b3JkICovDQp0eXBlZGVmIHN0
cnVjdCBtZDVfc3RhdGVfcyB7DQogICAgbWQ1X3dvcmRfdCBjb3VudFsyXTsN
CiAgICBtZDVfd29yZF90IGFiY2RbNF07DQogICAgbWQ1X2J5dGVfdCBidWZb
NjRdOw0KfSBtZDVfc3RhdGVfdDsNCg0Kdm9pZCBtZDVfaW5pdChtZDVfc3Rh
dGVfdCAqcG1zKTsNCnZvaWQgbWQ1X2FwcGVuZChtZDVfc3RhdGVfdCAqcG1z
LCBjb25zdCBtZDVfYnl0ZV90ICpkYXRhLCBpbnQgbmJ5dGVzKTsNCnZvaWQg
bWQ1X2ZpbmlzaChtZDVfc3RhdGVfdCAqcG1zLCBtZDVfYnl0ZV90IGRpZ2Vz
dFsxNl0pOw0KI2VuZGlmIA0KDQovKiB5b3UgY2FuIGdldCBzb21lIHRyaXZh
bCBzcGVlZHVwcyB3aXRoIE1TQiBpZiB5b3UgZGVmaW5lIHRoaXMgcmlnaHQg
Ki8NCiN1bmRlZiBCWVRFX09SREVSCS8qIDEgPSBiaWctZW5kaWFuLCAtMSA9
IGxpdHRsZS1lbmRpYW4sIDAgPSB1bmtub3duICovDQojaWZkZWYgQVJDSF9J
U19CSUdfRU5ESUFODQojICBkZWZpbmUgQllURV9PUkRFUiAoQVJDSF9JU19C
SUdfRU5ESUFOID8gMSA6IC0xKQ0KI2Vsc2UNCiMgIGRlZmluZSBCWVRFX09S
REVSIDANCiNlbmRpZg0KDQojZGVmaW5lIFRfTUFTSyAoKG1kNV93b3JkX3Qp
fjApDQojZGVmaW5lIFQxIC8qIDB4ZDc2YWE0NzggKi8gKFRfTUFTSyBeIDB4
Mjg5NTViODcpDQojZGVmaW5lIFQyIC8qIDB4ZThjN2I3NTYgKi8gKFRfTUFT
SyBeIDB4MTczODQ4YTkpDQojZGVmaW5lIFQzICAgIDB4MjQyMDcwZGINCiNk
ZWZpbmUgVDQgLyogMHhjMWJkY2VlZSAqLyAoVF9NQVNLIF4gMHgzZTQyMzEx
MSkNCiNkZWZpbmUgVDUgLyogMHhmNTdjMGZhZiAqLyAoVF9NQVNLIF4gMHgw
YTgzZjA1MCkNCiNkZWZpbmUgVDYgICAgMHg0Nzg3YzYyYQ0KI2RlZmluZSBU
NyAvKiAweGE4MzA0NjEzICovIChUX01BU0sgXiAweDU3Y2ZiOWVjKQ0KI2Rl
ZmluZSBUOCAvKiAweGZkNDY5NTAxICovIChUX01BU0sgXiAweDAyYjk2YWZl
KQ0KI2RlZmluZSBUOSAgICAweDY5ODA5OGQ4DQojZGVmaW5lIFQxMCAvKiAw
eDhiNDRmN2FmICovIChUX01BU0sgXiAweDc0YmIwODUwKQ0KI2RlZmluZSBU
MTEgLyogMHhmZmZmNWJiMSAqLyAoVF9NQVNLIF4gMHgwMDAwYTQ0ZSkNCiNk
ZWZpbmUgVDEyIC8qIDB4ODk1Y2Q3YmUgKi8gKFRfTUFTSyBeIDB4NzZhMzI4
NDEpDQojZGVmaW5lIFQxMyAgICAweDZiOTAxMTIyDQojZGVmaW5lIFQxNCAv
KiAweGZkOTg3MTkzICovIChUX01BU0sgXiAweDAyNjc4ZTZjKQ0KI2RlZmlu
ZSBUMTUgLyogMHhhNjc5NDM4ZSAqLyAoVF9NQVNLIF4gMHg1OTg2YmM3MSkN
CiNkZWZpbmUgVDE2ICAgIDB4NDliNDA4MjENCiNkZWZpbmUgVDE3IC8qIDB4
ZjYxZTI1NjIgKi8gKFRfTUFTSyBeIDB4MDllMWRhOWQpDQojZGVmaW5lIFQx
OCAvKiAweGMwNDBiMzQwICovIChUX01BU0sgXiAweDNmYmY0Y2JmKQ0KI2Rl
ZmluZSBUMTkgICAgMHgyNjVlNWE1MQ0KI2RlZmluZSBUMjAgLyogMHhlOWI2
YzdhYSAqLyAoVF9NQVNLIF4gMHgxNjQ5Mzg1NSkNCiNkZWZpbmUgVDIxIC8q
IDB4ZDYyZjEwNWQgKi8gKFRfTUFTSyBeIDB4MjlkMGVmYTIpDQojZGVmaW5l
IFQyMiAgICAweDAyNDQxNDUzDQojZGVmaW5lIFQyMyAvKiAweGQ4YTFlNjgx
ICovIChUX01BU0sgXiAweDI3NWUxOTdlKQ0KI2RlZmluZSBUMjQgLyogMHhl
N2QzZmJjOCAqLyAoVF9NQVNLIF4gMHgxODJjMDQzNykNCiNkZWZpbmUgVDI1
ICAgIDB4MjFlMWNkZTYNCiNkZWZpbmUgVDI2IC8qIDB4YzMzNzA3ZDYgKi8g
KFRfTUFTSyBeIDB4M2NjOGY4MjkpDQojZGVmaW5lIFQyNyAvKiAweGY0ZDUw
ZDg3ICovIChUX01BU0sgXiAweDBiMmFmMjc4KQ0KI2RlZmluZSBUMjggICAg
MHg0NTVhMTRlZA0KI2RlZmluZSBUMjkgLyogMHhhOWUzZTkwNSAqLyAoVF9N
QVNLIF4gMHg1NjFjMTZmYSkNCiNkZWZpbmUgVDMwIC8qIDB4ZmNlZmEzZjgg
Ki8gKFRfTUFTSyBeIDB4MDMxMDVjMDcpDQojZGVmaW5lIFQzMSAgICAweDY3
NmYwMmQ5DQojZGVmaW5lIFQzMiAvKiAweDhkMmE0YzhhICovIChUX01BU0sg
XiAweDcyZDViMzc1KQ0KI2RlZmluZSBUMzMgLyogMHhmZmZhMzk0MiAqLyAo
VF9NQVNLIF4gMHgwMDA1YzZiZCkNCiNkZWZpbmUgVDM0IC8qIDB4ODc3MWY2
ODEgKi8gKFRfTUFTSyBeIDB4Nzg4ZTA5N2UpDQojZGVmaW5lIFQzNSAgICAw
eDZkOWQ2MTIyDQojZGVmaW5lIFQzNiAvKiAweGZkZTUzODBjICovIChUX01B
U0sgXiAweDAyMWFjN2YzKQ0KI2RlZmluZSBUMzcgLyogMHhhNGJlZWE0NCAq
LyAoVF9NQVNLIF4gMHg1YjQxMTViYikNCiNkZWZpbmUgVDM4ICAgIDB4NGJk
ZWNmYTkNCiNkZWZpbmUgVDM5IC8qIDB4ZjZiYjRiNjAgKi8gKFRfTUFTSyBe
IDB4MDk0NGI0OWYpDQojZGVmaW5lIFQ0MCAvKiAweGJlYmZiYzcwICovIChU
X01BU0sgXiAweDQxNDA0MzhmKQ0KI2RlZmluZSBUNDEgICAgMHgyODliN2Vj
Ng0KI2RlZmluZSBUNDIgLyogMHhlYWExMjdmYSAqLyAoVF9NQVNLIF4gMHgx
NTVlZDgwNSkNCiNkZWZpbmUgVDQzIC8qIDB4ZDRlZjMwODUgKi8gKFRfTUFT
SyBeIDB4MmIxMGNmN2EpDQojZGVmaW5lIFQ0NCAgICAweDA0ODgxZDA1DQoj
ZGVmaW5lIFQ0NSAvKiAweGQ5ZDRkMDM5ICovIChUX01BU0sgXiAweDI2MmIy
ZmM2KQ0KI2RlZmluZSBUNDYgLyogMHhlNmRiOTllNSAqLyAoVF9NQVNLIF4g
MHgxOTI0NjYxYSkNCiNkZWZpbmUgVDQ3ICAgIDB4MWZhMjdjZjgNCiNkZWZp
bmUgVDQ4IC8qIDB4YzRhYzU2NjUgKi8gKFRfTUFTSyBeIDB4M2I1M2E5OWEp
DQojZGVmaW5lIFQ0OSAvKiAweGY0MjkyMjQ0ICovIChUX01BU0sgXiAweDBi
ZDZkZGJiKQ0KI2RlZmluZSBUNTAgICAgMHg0MzJhZmY5Nw0KI2RlZmluZSBU
NTEgLyogMHhhYjk0MjNhNyAqLyAoVF9NQVNLIF4gMHg1NDZiZGM1OCkNCiNk
ZWZpbmUgVDUyIC8qIDB4ZmM5M2EwMzkgKi8gKFRfTUFTSyBeIDB4MDM2YzVm
YzYpDQojZGVmaW5lIFQ1MyAgICAweDY1NWI1OWMzDQojZGVmaW5lIFQ1NCAv
KiAweDhmMGNjYzkyICovIChUX01BU0sgXiAweDcwZjMzMzZkKQ0KI2RlZmlu
ZSBUNTUgLyogMHhmZmVmZjQ3ZCAqLyAoVF9NQVNLIF4gMHgwMDEwMGI4MikN
CiNkZWZpbmUgVDU2IC8qIDB4ODU4NDVkZDEgKi8gKFRfTUFTSyBeIDB4N2E3
YmEyMmUpDQojZGVmaW5lIFQ1NyAgICAweDZmYTg3ZTRmDQojZGVmaW5lIFQ1
OCAvKiAweGZlMmNlNmUwICovIChUX01BU0sgXiAweDAxZDMxOTFmKQ0KI2Rl
ZmluZSBUNTkgLyogMHhhMzAxNDMxNCAqLyAoVF9NQVNLIF4gMHg1Y2ZlYmNl
YikNCiNkZWZpbmUgVDYwICAgIDB4NGUwODExYTENCiNkZWZpbmUgVDYxIC8q
IDB4Zjc1MzdlODIgKi8gKFRfTUFTSyBeIDB4MDhhYzgxN2QpDQojZGVmaW5l
IFQ2MiAvKiAweGJkM2FmMjM1ICovIChUX01BU0sgXiAweDQyYzUwZGNhKQ0K
I2RlZmluZSBUNjMgICAgMHgyYWQ3ZDJiYg0KI2RlZmluZSBUNjQgLyogMHhl
Yjg2ZDM5MSAqLyAoVF9NQVNLIF4gMHgxNDc5MmM2ZSkNCg0KDQppbnQgbWFp
biAoaW50IGFyZ2MsIGNoYXIgKmFyZ3ZbXSl7DQogICBleHRlcm4gY2hhciAq
b3B0YXJnOw0KICAgZXh0ZXJuIGludCAgb3B0aW5kOw0KICAgZXh0ZXJuIGlu
dCBlcnJubzsNCiAgIGludCBjOw0KICAgaW50IGk7DQogICBpbnQgajsNCiAg
IGludCBzbDsNCiAgIGludCBkZWJ1ZyA9IDA7DQogICBpbnQgdW5saW5raXQg
PSAwOw0KICAgaW50IHVzZV9vdXQgPSAwOw0KICAgaW50IHVzZV9rcCAgPSAw
Ow0KICAgaW50IGZpcnN0X2Jsb2NrID0gMTsNCiAgIGludCBmZF9pbjsNCiAg
IGludCBmZF9vdXQ7DQogICBpbnQgZW5jcnlwdCA9IDA7DQogICBpbnQgZGVj
cnlwdCA9IDA7DQogICBpbnQgYmwgPSAwOw0KICAgaW50IGJ5dGVzX3JlYWQ7
DQogICBpbnQgcGFkOw0KICAgaW50IG5vdW1hc2sgPSAwOw0KICAgdWludDMy
X3QgZmlsZXNpemUgPSAwOw0KICAgdWludDMyX3QgZmlsZXNpemVfbXNiID0g
MDsNCiAgIHVpbnQzMl90IHJlYWRfZmlsZXNpemVfbXNiID0gMDsNCiAgIHVp
bnQzMl90IHJlYWRfZmlsZXNpemUgPSAwOw0KICAgdWludDMyX3QgYnNmID0g
MDsNCiAgIGNoYXIgKmluX2ZpbGUgPSBOVUxMOw0KICAgY2hhciAqb3V0X2Zp
bGUgPSBOVUxMOw0KICAgY2hhciAqa2V5cGhyYXNlID0gTlVMTDsNCiAgIGNo
YXIgKmtleWVudiA9IE5VTEw7DQogICBjaGFyIGhhc2hbMTZdOw0KICAgY2hh
ciB0aGFzaFsxN107DQogICBjaGFyIGhidWZbM107DQogICBjaGFyIGZiX2J1
ZmZlcls2NF07DQogICAvKiB1X2NoYXIgKnBsYWludGV4dCA9IE5VTEw7ICov
DQogICB1X2NoYXIgcGxhaW50ZXh0WzY0XTsNCiAgIHN0cnVjdCBzdGF0IHN0
YXRidWY7DQogICBtZDVfc3RhdGVfdCBzdGF0ZTsNCiAgIG1kNV9ieXRlX3Qg
ZGlnZXN0WzMyXTsNCiAgIA0KICAgd2hpbGUoIChjID0gZ2V0b3B0KGFyZ2Ms
YXJndiwiaTpvOms6ZzpoeGRldXYiKSkgIT0gLTEgKXsNCiAgICAgIHN3aXRj
aChjKXsNCiAgICAgICAgIGNhc2UgJ2gnOg0KICAgICAgICAgICBzaG93aGVs
cCgpOw0KICAgICAgICAgICBicmVhazsNCiAgICAgICAgIGNhc2UgJ3YnOg0K
ICAgICAgICAgICAgZGVidWcgPSAxOw0KICAgICAgICAgICBicmVhazsNCiAg
ICAgICAgIGNhc2UgJ2knOg0KICAgICAgICAgICAgaWYoTlVMTCA9PSAoaW5f
ZmlsZSA9IChjaGFyICopIG1hbGxvYyhzdHJsZW4ob3B0YXJnKSArIDIpKSl7
DQogICAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCJGQVRBTDogY2Fubm90
IGFsbG9jYXRlIG1lbW9yeS5cbiIpOw0KICAgICAgICAgICAgICBleGl0KDEp
Ow0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgc3RybmNweShpbl9maWxl
LG9wdGFyZyxzdHJsZW4ob3B0YXJnKSArIDEpOw0KICAgICAgICAgICBicmVh
azsNCiAgICAgICAgIGNhc2UgJ28nOg0KICAgICAgICAgICAgdXNlX291dCA9
IDE7DQogICAgICAgICAgICBpZihOVUxMID09IChvdXRfZmlsZSA9IChjaGFy
ICopIG1hbGxvYyhzdHJsZW4ob3B0YXJnKSArIDIpKSl7DQogICAgICAgICAg
ICAgIGZwcmludGYoc3RkZXJyLCJGQVRBTDogY2Fubm90IGFsbG9jYXRlIG1l
bW9yeS5cbiIpOw0KICAgICAgICAgICAgICBleGl0KDEpOw0KICAgICAgICAg
ICAgfQ0KICAgICAgICAgICAgc3RybmNweShvdXRfZmlsZSxvcHRhcmcsc3Ry
bGVuKG9wdGFyZykgKyAxKTsNCiAgICAgICAgICAgYnJlYWs7DQogICAgICAg
ICBjYXNlICdrJzoNCiAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCJXQVJO
SU5HOiB1c2luZyBhIGtleXBocmFzZSBmcm9tIHRoZSBjb21tYW5kIGxpbmUg
Y2FuIGJlIGluc2VjdXJlLlxuIik7DQogICAgICAgICAgICB1c2Vfa3AgPSAx
Ow0KICAgICAgICAgICAgaWYoTlVMTCA9PSAoa2V5cGhyYXNlID0gKGNoYXIg
KikgbWFsbG9jKHN0cmxlbihvcHRhcmcpICsgMikpKXsNCiAgICAgICAgICAg
ICAgZnByaW50ZihzdGRlcnIsIkZBVEFMOiBjYW5ub3QgYWxsb2NhdGUgbWVt
b3J5LlxuIik7DQogICAgICAgICAgICAgIGV4aXQoMSk7DQogICAgICAgICAg
ICB9DQogICAgICAgICAgICBzdHJuY3B5KGtleXBocmFzZSxvcHRhcmcsc3Ry
bGVuKG9wdGFyZykgKyAxKTsNCiAgICAgICAgICAgYnJlYWs7DQogICAgICAg
ICBjYXNlICdnJzoNCiAgICAgICAgICAgIHVzZV9rcCA9IDE7DQogICAgICAg
ICAgICBrZXllbnYgPSBnZXRlbnYob3B0YXJnKTsNCiAgICAgICAgICAgIGlm
KE5VTEwgPT0gKGtleXBocmFzZSA9IChjaGFyICopIG1hbGxvYyhzdHJsZW4o
a2V5ZW52KSArIDIpKSl7DQogICAgICAgICAgICAgIGZwcmludGYoc3RkZXJy
LCJGQVRBTDogY2Fubm90IGFsbG9jYXRlIG1lbW9yeS5cbiIpOw0KICAgICAg
ICAgICAgICBleGl0KDEpOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAg
c3RybmNweShrZXlwaHJhc2Usa2V5ZW52LHN0cmxlbihrZXllbnYpICsgMSk7
DQogICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgY2FzZSAnZCc6DQogICAg
ICAgICAgICBkZWNyeXB0ID0gMTsNCiAgICAgICAgICAgYnJlYWs7DQogICAg
ICAgICBjYXNlICdlJzoNCiAgICAgICAgICAgIGVuY3J5cHQgPSAxOw0KICAg
ICAgICAgICBicmVhazsNCiAgICAgICAgIGNhc2UgJ3UnOg0KICAgICAgICAg
ICAgdW5saW5raXQgPSAxOw0KICAgICAgICAgICBicmVhazsNCiAgICAgICAg
IGNhc2UgJ3gnOg0KICAgICAgICAgICAgbm91bWFzayA9IDE7DQogICAgICAg
ICAgIGJyZWFrOw0KICAgICAgfSAvKiBlbmQgb2Ygc3dpdGNoKCkgKi8NCiAg
IH0gLyogZW5kIG9mIHdoaWxlIGdldG9wdCgpICovDQoNCiAgIC8qIHlvdSBt
dXN0IHVzZSBhIGtleSBmaWxlIG9yIGEga2V5IHBocmFzZSAqLw0KICAgaWYo
IXVzZV9rcCl7DQogICAgICAgZnByaW50ZihzdGRlcnIsIkZBVEFMOiBJIHdv
bnQgZW5jcnlwdCB3aXRob3V0IGEga2V5IVxuXG4iKTsNCiAgICAgICBzaG93
aGVscCgpOw0KICAgICAgIGV4aXQoMSk7ICAgDQogICB9DQogICAgDQogICAv
KiBvbmUgbW9kZSwgYW5kIG9ubHkgb25lIG1vZGUuICovDQogICBpZigoZGVj
cnlwdCAmJiBlbmNyeXB0KSB8fCAoIWVuY3J5cHQgJiYgIWRlY3J5cHQpKXsN
CiAgICAgICBmcHJpbnRmKHN0ZGVyciwiRkFUQUw6IFlvdXIgZW5jcnlwdC9k
ZWNyeXB0IG9wdGlvbnMgYXJlIG1pc3Npbmcgb3IgZG8gbm90IG1ha2Ugc2Vu
c2UuXG4iKTsNCiAgICAgICBleGl0KDEpOyAgIA0KICAgfQ0KICAgDQogICAv
KiBUaGV5IG11c3QgZ2l2ZSB1cyBhbiBpbnB1dCBmaWxlLCBhbmQgaXQgbXVz
dCAqLw0KICAgLyogYmUgc3RhdGFibGUgYW5kIHJlYWRhYmxlIGJ5IHVzIG9y
IHdlIGZhaWwgICAgKi8NCiAgIGlmKGluX2ZpbGUgIT0gTlVMTCl7DQogICAg
ICBpZigtMSA9PSAoc3RhdChpbl9maWxlLCZzdGF0YnVmKSkpew0KICAgICAg
ICAgZnByaW50ZihzdGRlcnIsIkZBVEFMOiBjYW5ub3Qgc3RhdCB0aGUgaW5w
dXQgZmlsZSFcbiIpOw0KICAgICAgICAgZXhpdCgxKTsNCiAgICAgIH0NCiAg
ICAgIGlmKHN0YXRidWYuc3Rfc2l6ZSA9PSAob2ZmX3QpIDApew0KICAgICAg
ICAgZnByaW50ZihzdGRlcnIsIkZBVEFMOiBXVEYgYXJlIHlvdSBlbmNyeXB0
aW5nIGFuIGVtcHR5IGZpbGUgZm9yP1xuIik7DQogICAgICAgICBleGl0KDEp
Ow0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgIChvZmZfdCkgZmlsZXNpemUg
PSBzdGF0YnVmLnN0X3NpemU7DQogICAgICAgICBmaWxlc2l6ZV9tc2IgPSBo
dG9ubChmaWxlc2l6ZSk7DQogICAgICB9DQogICAgICBpZighbm91bWFzaykg
dW1hc2soMDc3KTsNCiAgICAgIGlmKC0xID09IChmZF9pbiA9IG9wZW4oaW5f
ZmlsZSxPX1JET05MWSkpKXsNCiAgICAgICAgIGZwcmludGYoc3RkZXJyLCJG
QVRBTDogQ2Fubm90IG9wZW4oKSB0aGUgZmlsZS5cblx0JXNcbiIsc3RyZXJy
b3IoZXJybm8pKTsNCiAgICAgICAgIGV4aXQoMSk7ICAgIA0KICAgICAgfQ0K
ICAgfSBlbHNlIHsNCiAgICAgIGZwcmludGYoc3RkZXJyLCJGQVRBTDogbm8g
aW5wdXQgZmlsZSFcbiIpOw0KICAgICAgZXhpdCgxKTsNCiAgIH0NCg0KICAg
LyogaWYgdGhleSBkaWRuJ3QgcHJvdmlkZSBhbiBvdXQgZmlsZSwgbGV0J3Mg
dXNlICovDQogICAvKiBpbl9maWxlLnh4dCBhcyB0aGUgb3V0X2ZpbGUgbmFt
ZSAgICAgICAgICAgICAgKi8NCiAgIGlmKG91dF9maWxlID09IE5VTEwpew0K
ICAgICAgdXNlX291dCA9IDE7DQogICAgICBpZihOVUxMID09IChvdXRfZmls
ZSA9IChjaGFyICopIG1hbGxvYyhzdHJsZW4oaW5fZmlsZSkgKyA2KSkpew0K
ICAgICAgICBmcHJpbnRmKHN0ZGVyciwiRkFUQUw6IGNhbm5vdCBhbGxvY2F0
ZSBtZW1vcnkuXG4iKTsNCiAgICAgICAgZXhpdCgxKTsNCiAgICAgIH0NCiAg
ICAgIHNucHJpbnRmKG91dF9maWxlLHN0cmxlbihpbl9maWxlKSArIDYsIiVz
Lnh4dCIsaW5fZmlsZSk7DQogICAgICBpZighbm91bWFzaykgdW1hc2soMDc3
KTsNCiAgICAgIGlmKC0xID09IChmZF9vdXQgPSBvcGVuKG91dF9maWxlLE9f
V1JPTkxZfE9fQ1JFQVQsMDA2MDApKSl7DQogICAgICAgICBmcHJpbnRmKHN0
ZGVyciwiRkFUQUw6IGNhbm5vdCBvcGVuIHRoZSBvdXRwdXQgZmlsZSAlcyBm
b3Igd3JpdGluZy5cblx0JXNcbiINCiAgICAgICAgICAgICAgICAgLG91dF9m
aWxlDQogICAgICAgICAgICAgICAgICxzdHJlcnJvcihlcnJubykpOw0KICAg
ICAgICAgZXhpdCgxKTsNCiAgICAgIH0NCiAgIH0gZWxzZSB7DQogICAgICBp
Zighbm91bWFzaykgdW1hc2soMDc3KTsNCiAgICAgIGlmKC0xID09IChmZF9v
dXQgPSBvcGVuKG91dF9maWxlLE9fV1JPTkxZfE9fQ1JFQVQsMDA2MDApKSl7
DQogICAgICAgICBmcHJpbnRmKHN0ZGVyciwiRkFUQUw6IGNhbm5vdCBvcGVu
IHRoZSBvdXRwdXQgZmlsZSAlcyBmb3Igd3JpdGluZy5cblx0JXNcbiINCiAg
ICAgICAgICAgICAgICAsb3V0X2ZpbGUNCiAgICAgICAgICAgICAgICAsc3Ry
ZXJyb3IoZXJybm8pKTsNCiAgICAgICAgIGV4aXQoMSk7DQogICAgICB9DQog
ICB9DQogICANCiAgIC8qIHRyeSB0byBwdWxsIGEgZmFzdCBvbmUgYW5kIHdp
cGUgdGhlIGFyZ3VtZW50cyAqLw0KICAgLyogYSBwZXJzb24gY291bGQgc3Rp
bGwgdHJ5IGFuZCByYWNlIHRvIGdldCB0aGVtICovDQogICAvKiBidXQgaXQn
ZCBiZSBwcmV0dHkgdG91Z2ggKE5PVCBpbXBvc3NpYmxlKSBJJ20gKi8NCiAg
IC8qIGp1c3QgbWFraW5nIGl0IGhhcmRlciwgYnV0IEknbSBub3QgZ29pbmcg
dG8gICAqLw0KICAgLyogc2F5IHRoYXQgdGhpcyBtYWtlcyBpdCBhIHRvdGFs
bHkgc2VjdXJlIHdheSAgICovDQogICAvKiB0byBtYWtlIHBhc3NpbmcgdGhl
IGtleSBvbiB0aGUgY29tbWFuZCBsaW5lIGEgKi8NCiAgIC8qIHNhbmUgb3Ig
Z29vZCBpZGVhLiBJdCdzIHRoZXJlIGJlY2F1c2Ugd2hpbGUgICAqLw0KICAg
LyogeW91IGFyZSBpbiBhIGh1cnJ5ICh3ZSBibGFja2hhdHMgYXJlIG5ldmVy
IGluICovDQogICAvKiBhIGh1cnJ5LCBoYXIgaGFyKSBpdCBjYW4gYmUgdXNl
ZnVsLiAgICAgICAgICAgKi8NCiAgIGZvciAoaSA9IDE7IGkgPCBhcmdjOyAr
K2kpIHsNCiAgICAgICAgc2wgPSBzdHJsZW4oYXJndltpXSk7DQogICAgICAg
IGZvciAoaiA9IDA7IGogPCBzbDsgKytqKQ0KICAgICAgICAgICAgYXJndltp
XVtqXSA9IDA7DQogICB9DQogICAgDQogICBtZW1zZXQoaGFzaCwwLDE2KTsN
CiAgIC8qIGxldHMgaGFzaCB0aGUga2V5cy4gV2UgZ2V0IGEgMjU2IGJpdCBo
YXNoICAgICovDQogICAvKiBmcm9tIG1kNSwgYnV0IHh4dGVhIHRha2VzIGEg
MTI4IGJpdCBrZXkgc28gICAqLw0KICAgLyogdGhlIGhhc2ggaXMgdHJ1bmNh
dGVkIHRvIHRoZSBmaXJzdCAxMjggYml0cyAgKi8NCiAgIG1kNV9pbml0KCZz
dGF0ZSk7DQogICBtZDVfYXBwZW5kKCZzdGF0ZSwgKGNvbnN0IG1kNV9ieXRl
X3QgKikga2V5cGhyYXNlLCBzdHJsZW4oa2V5cGhyYXNlKSk7DQogICBtZDVf
ZmluaXNoKCZzdGF0ZSwgZGlnZXN0KTsNCiAgIGZvciAoaSA9IDA7IGkgPCA4
OyBpKyspIHsNCiAgICAgIHNucHJpbnRmKGhidWYsMywiJTAyeCIsZGlnZXN0
W2ldKTsNCiAgICAgIG1lbWNweShoYXNoKyhpKjIpLGhidWYsMik7DQogICB9
DQoNCiAgIC8qIHNob3cgYSBzdW1tYXJ5IG9mIGFyZ3MgaWYgd2UgYXJlIGlu
IHZlcmJvc2UgbW9kZSAqLw0KICAgaWYoZGVidWcpew0KICAgICAgcHJpbnRm
KCItLS09WyAgWW91ciBvcHRpb24gc3VtbWFyeSBdPS0tLSBcbiIpOw0KICAg
ICAgcHJpbnRmKCJJTkZJTEUgICAgPT0gJXNcbiIsaW5fZmlsZSk7DQogICAg
ICBwcmludGYoIk9VVEZJTEUgICA9PSAlc1xuIixvdXRfZmlsZSk7DQogICAg
ICBwcmludGYoIlVOTElOSyAgICA9PSAlZFxuIix1bmxpbmtpdCk7DQogICAg
ICBtZW1jcHkodGhhc2gsaGFzaCwxNik7DQogICAgICB0aGFzaFsxNl0gPSAn
XDAnOw0KICAgICAgLyogcHJpbnRmKCJIQVNIICAgICAgPT0gJXNcbiIsdGhh
c2gpOyAqLw0KICAgfQ0KICAgDQogICBpZihlbmNyeXB0KXsNCiAgICAgd2hp
bGUoZmlyc3RfYmxvY2spew0KICAgICAgICBieXRlc19yZWFkID0gcmVhZChm
ZF9pbixwbGFpbnRleHQsNjApOw0KICAgICAgICBpZihieXRlc19yZWFkID09
IC0xKXsNCiAgICAgICAgICAgcHJpbnRmKCJGQVRBTDogIFByb2JsZW0gcmVh
ZGluZyBpbnB1dCBmaWxlLlxuXHQlc1xuIixzdHJlcnJvcihlcnJubykpOw0K
ICAgICAgICAgICBleGl0KDEpOw0KICAgICAgICB9DQogICAgICAgIC8qIGlm
IHRoZSBpbml0aWFsIGlucHV0IGlzbid0IGF0IGxlYXN0IDYwIGJ5dGVzICov
DQogICAgICAgIC8qIHdlIGFyZSBnb2luZyB0byBoYXZlIHRvIHBhZCBpdC4g
Ki8NCiAgICAgICAgaWYoYnl0ZXNfcmVhZCAhPSA2MCl7DQogICAgICAgICAg
IHBhZCA9IDYwIC0gYnl0ZXNfcmVhZCA7DQogICAgICAgICAgIG1lbWNweShw
bGFpbnRleHQrYnl0ZXNfcmVhZCxoYXNoLHBhZCk7IA0KICAgICAgICB9DQog
ICAgICAgIG1lbWNweShmYl9idWZmZXIsICZmaWxlc2l6ZV9tc2IsIDQpOw0K
ICAgICAgICBtZW1jcHkoZmJfYnVmZmVyKzQsIHBsYWludGV4dCwgNjApOw0K
ICAgICAgICBidGVhKChpbnQzMl90ICopIGZiX2J1ZmZlciwgMTYsIChpbnQz
Ml90ICopIGhhc2gpOw0KICAgICAgICB3cml0ZShmZF9vdXQsKGNoYXIgKikg
ZmJfYnVmZmVyLDY0KTsNCiAgICAgICAgZmlyc3RfYmxvY2sgPSAwOw0KICAg
ICB9DQogICAgIHdoaWxlKCAoYnl0ZXNfcmVhZCA9IHJlYWQoZmRfaW4scGxh
aW50ZXh0LDY0KSkgKXsNCiAgICAgICAgICAgaWYoYnl0ZXNfcmVhZCA9PSA2
NCl7DQogICAgICAgICAgICAgYnRlYSgoaW50MzJfdCAqKSBwbGFpbnRleHQs
IDE2LCAoaW50MzJfdCAqKSBoYXNoKTsNCiAgICAgICAgICAgICB3cml0ZShm
ZF9vdXQsKGNoYXIgKikgcGxhaW50ZXh0LDY0KTsNCiAgICAgICAgICAgfSBl
bHNlIHsNCiAgICAgICAgICAgICBwYWQgPSA2NCAtIGJ5dGVzX3JlYWQ7DQog
ICAgICAgICAgICAgbWVtY3B5KHBsYWludGV4dCtieXRlc19yZWFkLGhhc2gs
cGFkKTsNCiAgICAgICAgICAgICBidGVhKChpbnQzMl90ICopIHBsYWludGV4
dCwgMTYsIChpbnQzMl90ICopIGhhc2gpOw0KICAgICAgICAgICAgIHdyaXRl
KGZkX291dCwoY2hhciAqKSBwbGFpbnRleHQsNjQpOw0KICAgICAgICAgICB9
DQogICAgIH0NCiAgIH0gZWxzZSBpZihkZWNyeXB0KSB7DQogICAgIHdoaWxl
KGZpcnN0X2Jsb2NrKXsNCiAgICAgICAgcmVhZChmZF9pbixwbGFpbnRleHQs
NjQpOw0KICAgICAgICBidGVhKChpbnQzMl90ICopIHBsYWludGV4dCwgLTE2
LCAoaW50MzJfdCAqKSBoYXNoKTsNCiAgICAgICAgbWVtY3B5KCZyZWFkX2Zp
bGVzaXplX21zYixwbGFpbnRleHQsNCk7DQogICAgICAgIHJlYWRfZmlsZXNp
emUgPSBudG9obChyZWFkX2ZpbGVzaXplX21zYik7DQogICAgICAgIGlmKHJl
YWRfZmlsZXNpemUgPj0gNjApew0KICAgICAgICAgIHdyaXRlKGZkX291dCwo
Y2hhciAqKSBwbGFpbnRleHQrNCw2MCk7DQogICAgICAgIH0gZWxzZSB7DQog
ICAgICAgICAgd3JpdGUoZmRfb3V0LChjaGFyICopIHBsYWludGV4dCs0LHJl
YWRfZmlsZXNpemUpOw0KICAgICAgICB9IA0KICAgICAgICBic2YgKz0gNjQ7
DQogICAgICAgIGZpcnN0X2Jsb2NrID0gMDsNCiAgICAgfQ0KICAgICB3aGls
ZSgwICE9IChieXRlc19yZWFkID0gcmVhZChmZF9pbixwbGFpbnRleHQsNjQp
KSApew0KICAgICAgICAgICBidGVhKChpbnQzMl90ICopIHBsYWludGV4dCwg
LTE2LCAoaW50MzJfdCAqKSBoYXNoKTsNCiAgICAgICAgICAgYnNmICs9IDY0
Ow0KICAgICAgICAgICBpZihic2YgPCAocmVhZF9maWxlc2l6ZSArIDQpICYm
IHJlYWRfZmlsZXNpemUgPiA2NCl7DQogICAgICAgICAgICAgIHdyaXRlKGZk
X291dCwoY2hhciAqKSBwbGFpbnRleHQsNjQpOw0KICAgICAgICAgICB9IGVs
c2Ugew0KICAgICAgICAgICAgICBibCA9IDY0IC0gKGJzZiAtIChyZWFkX2Zp
bGVzaXplICsgNCkpOyAvKiBjYWxjIGhvdyBtdWNoIGlzIHJlYWxseSBsZWZ0
ICovDQogICAgICAgICAgICAgIHdyaXRlKGZkX291dCwoY2hhciAqKSBwbGFp
bnRleHQsYmwpOw0KICAgICAgICAgICB9DQogICAgIH0NCiAgIH0NCiAgIA0K
ICAgLyogaWYgdGhleSB3YW50IHRvIGRlbGV0ZSB0aGUgaW5maWxlICovDQog
ICBpZih1bmxpbmtpdCkgdW5saW5rKGluX2ZpbGUpOw0KICAgDQogICAvKiBm
cmVlIGR5bmFtaWNhbGx5IGFsbG9jYXRlZCBtZW1vcnkgYW5kIHplcm8gb3V0
IHRoZSBjb250ZW50cyB0byAqLw0KICAgLyogdHJ5IHRvIG1ha2UgcmVjb3Zl
cnkgb2YgaW5mb3JtYXRpb24gYWJvdXQgd2hhdCB3ZSBkaWQgaGFyZGVyICAg
Ki8NCiAgIG1lbXNldChpbl9maWxlLDAsc3RybGVuKGluX2ZpbGUpKTsNCiAg
IGZyZWUoaW5fZmlsZSk7DQogICBpZih1c2Vfa3Apew0KICAgICAgbWVtc2V0
KGtleXBocmFzZSwwLHN0cmxlbihrZXlwaHJhc2UpKTsNCiAgICAgIGZyZWUo
a2V5cGhyYXNlKTsNCiAgIH0NCiAgIGlmKHVzZV9vdXQpeyANCiAgICAgIG1l
bXNldChvdXRfZmlsZSwwLHN0cmxlbihvdXRfZmlsZSkpOw0KICAgICAgZnJl
ZShvdXRfZmlsZSk7DQogICB9DQogICBjbG9zZShmZF9vdXQpOw0KICAgY2xv
c2UoZmRfaW4pOw0KICAgcmV0dXJuKDApOw0KfQ0KDQp2b2lkIHNob3doZWxw
KHZvaWQpew0KICAgcHJpbnRmKCJcbnh4dCAtIGFuIHh4dGVhIGJhc2VkIHZh
cmlhYmxlIGJsb2NrLW1vZGUgZmlsZSBlbmNyeXB0b3IuXG4iKTsNCiAgIHBy
aW50ZigiYnkgYWxpdmVyXG5cbiIpOw0KICAgcHJpbnRmKCIrLS0tPVsgT3B0
aW9ucyBdPS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tK1xuIik7DQogICBw
cmludGYoInwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICB8XG4iKTsNCiAgIHByaW50ZigifCAtaCBwcmludCBoZWxwICAgICAg
ICAtdiBiZSB2ZXJib3NlICAgICAgIHxcbiIpOw0KICAgcHJpbnRmKCJ8IC1p
IGlucHV0X2ZpbGUgICAgICAgIC1vIG91dHB1dF9maWxlICAgICAgfFxuIik7
DQogICBwcmludGYoInwgLWsga2V5cGhyYXNlICAgICAgICAgLWcga2V5IGVu
dl92YXJpYWJsZSB8XG4iKTsNCiAgIHByaW50ZigifCAtdSB1bmxpbmsgaW5w
dXRfZmlsZSBhZnRlciBlbmNyeXB0aW9uICAgIHxcbiIpOw0KICAgcHJpbnRm
KCJ8IC14IGRvbnQgc2V0IHVtYXNrIHRvIGEgc2FmZSB2YWx1ZSAgICAgICAg
fFxuIik7DQogICBwcmludGYoInwgRXhhbXBsZTogICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICB8XG4iKTsNCiAgIHByaW50ZigifCBcInh4dCAt
ayBzZWNyZXRwYXNzIC1pIHRlc3QgLWRcIiAgICAgICAgICAgfFxuIik7DQog
ICBwcmludGYoInwgWW91IGdldCBcInRlc3QueHh0XCIgYW5kIGRlbGV0ZXMg
XCJ0ZXN0XCIgICAgfFxuIik7ICAgICAgICAgICAgDQogICBwcmludGYoInwg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4i
KTsNCiAgIHByaW50ZigiKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLStcbiIpOw0KICAgDQp9DQoNCg0KLyogbmVhcmx5IGFs
bCB0aGUgZm9sbG93aW5nIHh4dGVhIGNyeXB0byAqLw0KLyogY29kZSBmcm9t
IHRoZSBwb3N0IHNjcmlwdCAgICAgICAgICAgICAqLw0KLyogYnkgRGF2aWQg
V2hlZWxlciBhbmQgUm9nZXIgTmVlZGhhbSAgICAqLw0KLyogSSd2ZSBhbHRl
cmVkIGl0IHRvIGJlIG1vcmUgcG9ydGFibGUgICAqLw0KLyogb24gNjQgYml0
IHBsYXRmb3JtcyBieSBtYWtpbmcgdXNlIG9mICAqLw0KLyogZGVmaW5pdGlv
bnMgaW4gc3RkaW50LmggICAgICAgICAgICAgICAqLw0KbG9uZyBidGVhKCBp
bnQzMl90ICogdiwgaW50MzJfdCBuICwgaW50MzJfdCAqIGsgKSB7DQogICAg
dWludDMyX3Qgej12W24tMV0sIHk9dlswXSwgc3VtPTAsZSwNCiAgICBERUxU
QT0weDllMzc3OWI5IDsNCiAgICBpbnQzMl90IHAsIHEgOw0KICAgIGlmICgg
bj4xKSB7DQogICAgICAgIC8qIENvZGluZyBQYXJ0ICovDQogICAgICAgIHEg
PSA2KzUyL24gOw0KICAgICAgICB3aGlsZSAoIHEtLSA+IDAgKSB7DQogICAg
ICAgICAgICBzdW0gKz0gREVMVEEgOw0KICAgICAgICAgICAgZSA9IHN1bSA+
PiAyJjMgOw0KICAgICAgICAgICAgZm9yICggcCA9IDAgOyBwIDwgbi0xIDsg
cCsrICkNCiAgICAgICAgICAgICAgICB5ID0gdltwKzFdLA0KICAgICAgICAg
ICAgICAgIHogPSB2W3BdICs9IE1YDQogICAgICAgICAgICAgICAgeSA9IHZb
MF0gOw0KICAgICAgICAgICAgeiA9IHZbbi0xXSArPSBNWA0KICAgICAgICAg
fQ0KICAgICAgICAgcmV0dXJuIDAgOw0KICAgIH0NCiAgICAvKiBEZWNvZGlu
ZyBQYXJ0ICovDQogICAgZWxzZSBpZiAoIG4gPC0xICkgew0KICAgICAgICBu
ID0gLW4gOw0KICAgICAgICBxID0gNis1Mi9uIDsNCiAgICAgICAgc3VtID0g
cSpERUxUQSA7DQogICAgICAgIHdoaWxlIChzdW0gIT0gMCkgew0KICAgICAg
ICAgICAgZSA9IHN1bT4+MiAmIDMgOw0KICAgICAgICAgICAgZm9yIChwID0g
bi0xIDsgcCA+IDAgOyBwLS0gKQ0KICAgICAgICAgICAgICAgIHogPSB2W3At
MV0sDQogICAgICAgICAgICAgICAgeSA9IHZbcF0gLT0gTVgNCiAgICAgICAg
ICAgICAgICB6ID0gdltuLTFdIDsNCiAgICAgICAgICAgIHkgPSB2WzBdIC09
IE1YDQogICAgICAgICAgICBzdW0gLT0gREVMVEEgOw0KICAgICAgICB9DQog
ICAgICAgIHJldHVybiAwIDsNCiAgICB9DQogICAgcmV0dXJuIDEgOw0KfSAv
KiBTaWduYWwgbj0wLDEsLTEgKi8NCg0KDQoNCi8qIE1ENSBhbGdvcml0aG0g
dXNlZCB0byBoYXNoIHRoZSBrZXlzIGdpdmVuIHRvIHh4dCAqLw0KLyogVGhp
cyBzb3VyY2UgY29kZSBoYXMgYmVlbiBhbHRlcmVkIHRvIGJldHRlciBzdWl0
ICovIA0KLyogbXkgcHVycG9zZXMgKHNwZWVkLCBhbmQgZm9ybWF0dGluZykg
YW5kIEkgYW0gbm93ICovDQovKiBkZWNsYXJpbmcgaXQgc28gbm9ib2R5IGhh
cyBhIGZpdCBhYm91dCBpdC4gTm93ICAgKi8NCi8qIHlvdSBjYW4gcmVhZCBQ
ZXRlcidzIG5vdGljZSBiZWxvdy4gSXQgb25seSAgICAgICAqLw0KLyogYXBw
bGllcyB0byB0aGUgTUQ1IGhhc2hpbmcgcGFydCBvZiB4eHQgISAgICAgICAg
ICovDQoNCi8qDQogIENvcHlyaWdodCAoQykgMTk5OSwgMjAwMCwgMjAwMiBB
bGFkZGluIEVudGVycHJpc2VzLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4NCg0K
ICBUaGlzIHNvZnR3YXJlIGlzIHByb3ZpZGVkICdhcy1pcycsIHdpdGhvdXQg
YW55IGV4cHJlc3Mgb3IgaW1wbGllZA0KICB3YXJyYW50eS4gIEluIG5vIGV2
ZW50IHdpbGwgdGhlIGF1dGhvcnMgYmUgaGVsZCBsaWFibGUgZm9yIGFueSBk
YW1hZ2VzDQogIGFyaXNpbmcgZnJvbSB0aGUgdXNlIG9mIHRoaXMgc29mdHdh
cmUuDQoNCiAgUGVybWlzc2lvbiBpcyBncmFudGVkIHRvIGFueW9uZSB0byB1
c2UgdGhpcyBzb2Z0d2FyZSBmb3IgYW55IHB1cnBvc2UsDQogIGluY2x1ZGlu
ZyBjb21tZXJjaWFsIGFwcGxpY2F0aW9ucywgYW5kIHRvIGFsdGVyIGl0IGFu
ZCByZWRpc3RyaWJ1dGUgaXQNCiAgZnJlZWx5LCBzdWJqZWN0IHRvIHRoZSBm
b2xsb3dpbmcgcmVzdHJpY3Rpb25zOg0KDQogIDEuIFRoZSBvcmlnaW4gb2Yg
dGhpcyBzb2Z0d2FyZSBtdXN0IG5vdCBiZSBtaXNyZXByZXNlbnRlZDsgeW91
IG11c3Qgbm90DQogICAgIGNsYWltIHRoYXQgeW91IHdyb3RlIHRoZSBvcmln
aW5hbCBzb2Z0d2FyZS4gSWYgeW91IHVzZSB0aGlzIHNvZnR3YXJlDQogICAg
IGluIGEgcHJvZHVjdCwgYW4gYWNrbm93bGVkZ21lbnQgaW4gdGhlIHByb2R1
Y3QgZG9jdW1lbnRhdGlvbiB3b3VsZCBiZQ0KICAgICBhcHByZWNpYXRlZCBi
dXQgaXMgbm90IHJlcXVpcmVkLg0KICAyLiBBbHRlcmVkIHNvdXJjZSB2ZXJz
aW9ucyBtdXN0IGJlIHBsYWlubHkgbWFya2VkIGFzIHN1Y2gsIGFuZCBtdXN0
IG5vdCBiZQ0KICAgICBtaXNyZXByZXNlbnRlZCBhcyBiZWluZyB0aGUgb3Jp
Z2luYWwgc29mdHdhcmUuDQogIDMuIFRoaXMgbm90aWNlIG1heSBub3QgYmUg
cmVtb3ZlZCBvciBhbHRlcmVkIGZyb20gYW55IHNvdXJjZSBkaXN0cmlidXRp
b24uDQoNCiAgTC4gUGV0ZXIgRGV1dHNjaA0KICBnaG9zdEBhbGFkZGluLmNv
bQ0KDQogKi8NCg0Kc3RhdGljIHZvaWQgbWQ1X3Byb2Nlc3MobWQ1X3N0YXRl
X3QgKnBtcywgY29uc3QgbWQ1X2J5dGVfdCAqZGF0YSAvKls2NF0qLyl7DQog
ICAgbWQ1X3dvcmRfdA0KCWEgPSBwbXMtPmFiY2RbMF0sIGIgPSBwbXMtPmFi
Y2RbMV0sDQoJYyA9IHBtcy0+YWJjZFsyXSwgZCA9IHBtcy0+YWJjZFszXTsN
CiAgICBtZDVfd29yZF90IHQ7DQojaWYgQllURV9PUkRFUiA+IDANCiAgICAv
KiBEZWZpbmUgc3RvcmFnZSBvbmx5IGZvciBiaWctZW5kaWFuIENQVXMuICov
DQogICAgbWQ1X3dvcmRfdCBYWzE2XTsNCiNlbHNlDQogICAgLyogRGVmaW5l
IHN0b3JhZ2UgZm9yIGxpdHRsZS1lbmRpYW4gb3IgYm90aCB0eXBlcyBvZiBD
UFVzLiAqLw0KICAgIG1kNV93b3JkX3QgeGJ1ZlsxNl07DQogICAgY29uc3Qg
bWQ1X3dvcmRfdCAqWDsNCiNlbmRpZg0KDQogICAgew0KI2lmIEJZVEVfT1JE
RVIgPT0gMA0KCS8qDQoJICogRGV0ZXJtaW5lIGR5bmFtaWNhbGx5IHdoZXRo
ZXIgdGhpcyBpcyBhIGJpZy1lbmRpYW4gb3INCgkgKiBsaXR0bGUtZW5kaWFu
IG1hY2hpbmUsIHNpbmNlIHdlIGNhbiB1c2UgYSBtb3JlIGVmZmljaWVudA0K
CSAqIGFsZ29yaXRobSBvbiB0aGUgbGF0dGVyLg0KCSAqLw0KCXN0YXRpYyBj
b25zdCBpbnQgdyA9IDE7DQoNCglpZiAoKigoY29uc3QgbWQ1X2J5dGVfdCAq
KSZ3KSkgLyogZHluYW1pYyBsaXR0bGUtZW5kaWFuICovDQojZW5kaWYNCiNp
ZiBCWVRFX09SREVSIDw9IDAJCS8qIGxpdHRsZS1lbmRpYW4gKi8NCgl7DQoJ
ICAgIC8qDQoJICAgICAqIE9uIGxpdHRsZS1lbmRpYW4gbWFjaGluZXMsIHdl
IGNhbiBwcm9jZXNzIHByb3Blcmx5IGFsaWduZWQNCgkgICAgICogZGF0YSB3
aXRob3V0IGNvcHlpbmcgaXQuDQoJICAgICAqLw0KCSAgICBpZiAoISgoZGF0
YSAtIChjb25zdCBtZDVfYnl0ZV90ICopMCkgJiAzKSkgew0KCQkvKiBkYXRh
IGFyZSBwcm9wZXJseSBhbGlnbmVkICovDQoJCVggPSAoY29uc3QgbWQ1X3dv
cmRfdCAqKWRhdGE7DQoJICAgIH0gZWxzZSB7DQoJCS8qIG5vdCBhbGlnbmVk
ICovDQoJCW1lbWNweSh4YnVmLCBkYXRhLCA2NCk7DQoJCVggPSB4YnVmOw0K
CSAgICB9DQoJfQ0KI2VuZGlmDQojaWYgQllURV9PUkRFUiA9PSAwDQoJZWxz
ZQkJCS8qIGR5bmFtaWMgYmlnLWVuZGlhbiAqLw0KI2VuZGlmDQojaWYgQllU
RV9PUkRFUiA+PSAwCQkvKiBiaWctZW5kaWFuICovDQoJew0KCSAgICAvKg0K
CSAgICAgKiBPbiBiaWctZW5kaWFuIG1hY2hpbmVzLCB3ZSBtdXN0IGFycmFu
Z2UgdGhlIGJ5dGVzIGluIHRoZQ0KCSAgICAgKiByaWdodCBvcmRlci4NCgkg
ICAgICovDQoJICAgIGNvbnN0IG1kNV9ieXRlX3QgKnhwID0gZGF0YTsNCgkg
ICAgaW50IGk7DQoNCiMgIGlmIEJZVEVfT1JERVIgPT0gMA0KCSAgICBYID0g
eGJ1ZjsJCS8qIChkeW5hbWljIG9ubHkpICovDQojICBlbHNlDQojICAgIGRl
ZmluZSB4YnVmIFgJCS8qIChzdGF0aWMgb25seSkgKi8NCiMgIGVuZGlmDQoJ
ICAgIGZvciAoaSA9IDA7IGkgPCAxNjsgKytpLCB4cCArPSA0KQ0KCQl4YnVm
W2ldID0geHBbMF0gKyAoeHBbMV0gPDwgOCkgKyAoeHBbMl0gPDwgMTYpICsg
KHhwWzNdIDw8IDI0KTsNCgl9DQojZW5kaWYNCiAgICB9DQoNCiNkZWZpbmUg
Uk9UQVRFX0xFRlQoeCwgbikgKCgoeCkgPDwgKG4pKSB8ICgoeCkgPj4gKDMy
IC0gKG4pKSkpDQoNCiAgICAvKiBSb3VuZCAxLiAqLw0KICAgIC8qIExldCBb
YWJjZCBrIHMgaV0gZGVub3RlIHRoZSBvcGVyYXRpb24NCiAgICAgICBhID0g
YiArICgoYSArIEYoYixjLGQpICsgWFtrXSArIFRbaV0pIDw8PCBzKS4gKi8N
CiNkZWZpbmUgRih4LCB5LCB6KSAoKCh4KSAmICh5KSkgfCAofih4KSAmICh6
KSkpDQojZGVmaW5lIFNFVChhLCBiLCBjLCBkLCBrLCBzLCBUaSlcDQogIHQg
PSBhICsgRihiLGMsZCkgKyBYW2tdICsgVGk7XA0KICBhID0gUk9UQVRFX0xF
RlQodCwgcykgKyBiDQogICAgLyogRG8gdGhlIGZvbGxvd2luZyAxNiBvcGVy
YXRpb25zLiAqLw0KICAgIFNFVChhLCBiLCBjLCBkLCAgMCwgIDcsICBUMSk7
DQogICAgU0VUKGQsIGEsIGIsIGMsICAxLCAxMiwgIFQyKTsNCiAgICBTRVQo
YywgZCwgYSwgYiwgIDIsIDE3LCAgVDMpOw0KICAgIFNFVChiLCBjLCBkLCBh
LCAgMywgMjIsICBUNCk7DQogICAgU0VUKGEsIGIsIGMsIGQsICA0LCAgNywg
IFQ1KTsNCiAgICBTRVQoZCwgYSwgYiwgYywgIDUsIDEyLCAgVDYpOw0KICAg
IFNFVChjLCBkLCBhLCBiLCAgNiwgMTcsICBUNyk7DQogICAgU0VUKGIsIGMs
IGQsIGEsICA3LCAyMiwgIFQ4KTsNCiAgICBTRVQoYSwgYiwgYywgZCwgIDgs
ICA3LCAgVDkpOw0KICAgIFNFVChkLCBhLCBiLCBjLCAgOSwgMTIsIFQxMCk7
DQogICAgU0VUKGMsIGQsIGEsIGIsIDEwLCAxNywgVDExKTsNCiAgICBTRVQo
YiwgYywgZCwgYSwgMTEsIDIyLCBUMTIpOw0KICAgIFNFVChhLCBiLCBjLCBk
LCAxMiwgIDcsIFQxMyk7DQogICAgU0VUKGQsIGEsIGIsIGMsIDEzLCAxMiwg
VDE0KTsNCiAgICBTRVQoYywgZCwgYSwgYiwgMTQsIDE3LCBUMTUpOw0KICAg
IFNFVChiLCBjLCBkLCBhLCAxNSwgMjIsIFQxNik7DQojdW5kZWYgU0VUDQoN
CiAgICAgLyogUm91bmQgMi4gKi8NCiAgICAgLyogTGV0IFthYmNkIGsgcyBp
XSBkZW5vdGUgdGhlIG9wZXJhdGlvbg0KICAgICAgICAgIGEgPSBiICsgKChh
ICsgRyhiLGMsZCkgKyBYW2tdICsgVFtpXSkgPDw8IHMpLiAqLw0KI2RlZmlu
ZSBHKHgsIHksIHopICgoKHgpICYgKHopKSB8ICgoeSkgJiB+KHopKSkNCiNk
ZWZpbmUgU0VUKGEsIGIsIGMsIGQsIGssIHMsIFRpKVwNCiAgdCA9IGEgKyBH
KGIsYyxkKSArIFhba10gKyBUaTtcDQogIGEgPSBST1RBVEVfTEVGVCh0LCBz
KSArIGINCiAgICAgLyogRG8gdGhlIGZvbGxvd2luZyAxNiBvcGVyYXRpb25z
LiAqLw0KICAgIFNFVChhLCBiLCBjLCBkLCAgMSwgIDUsIFQxNyk7DQogICAg
U0VUKGQsIGEsIGIsIGMsICA2LCAgOSwgVDE4KTsNCiAgICBTRVQoYywgZCwg
YSwgYiwgMTEsIDE0LCBUMTkpOw0KICAgIFNFVChiLCBjLCBkLCBhLCAgMCwg
MjAsIFQyMCk7DQogICAgU0VUKGEsIGIsIGMsIGQsICA1LCAgNSwgVDIxKTsN
CiAgICBTRVQoZCwgYSwgYiwgYywgMTAsICA5LCBUMjIpOw0KICAgIFNFVChj
LCBkLCBhLCBiLCAxNSwgMTQsIFQyMyk7DQogICAgU0VUKGIsIGMsIGQsIGEs
ICA0LCAyMCwgVDI0KTsNCiAgICBTRVQoYSwgYiwgYywgZCwgIDksICA1LCBU
MjUpOw0KICAgIFNFVChkLCBhLCBiLCBjLCAxNCwgIDksIFQyNik7DQogICAg
U0VUKGMsIGQsIGEsIGIsICAzLCAxNCwgVDI3KTsNCiAgICBTRVQoYiwgYywg
ZCwgYSwgIDgsIDIwLCBUMjgpOw0KICAgIFNFVChhLCBiLCBjLCBkLCAxMywg
IDUsIFQyOSk7DQogICAgU0VUKGQsIGEsIGIsIGMsICAyLCAgOSwgVDMwKTsN
CiAgICBTRVQoYywgZCwgYSwgYiwgIDcsIDE0LCBUMzEpOw0KICAgIFNFVChi
LCBjLCBkLCBhLCAxMiwgMjAsIFQzMik7DQojdW5kZWYgU0VUDQoNCiAgICAg
LyogUm91bmQgMy4gKi8NCiAgICAgLyogTGV0IFthYmNkIGsgcyB0XSBkZW5v
dGUgdGhlIG9wZXJhdGlvbg0KICAgICAgICAgIGEgPSBiICsgKChhICsgSChi
LGMsZCkgKyBYW2tdICsgVFtpXSkgPDw8IHMpLiAqLw0KI2RlZmluZSBIKHgs
IHksIHopICgoeCkgXiAoeSkgXiAoeikpDQojZGVmaW5lIFNFVChhLCBiLCBj
LCBkLCBrLCBzLCBUaSlcDQogIHQgPSBhICsgSChiLGMsZCkgKyBYW2tdICsg
VGk7XA0KICBhID0gUk9UQVRFX0xFRlQodCwgcykgKyBiDQogICAgIC8qIERv
IHRoZSBmb2xsb3dpbmcgMTYgb3BlcmF0aW9ucy4gKi8NCiAgICBTRVQoYSwg
YiwgYywgZCwgIDUsICA0LCBUMzMpOw0KICAgIFNFVChkLCBhLCBiLCBjLCAg
OCwgMTEsIFQzNCk7DQogICAgU0VUKGMsIGQsIGEsIGIsIDExLCAxNiwgVDM1
KTsNCiAgICBTRVQoYiwgYywgZCwgYSwgMTQsIDIzLCBUMzYpOw0KICAgIFNF
VChhLCBiLCBjLCBkLCAgMSwgIDQsIFQzNyk7DQogICAgU0VUKGQsIGEsIGIs
IGMsICA0LCAxMSwgVDM4KTsNCiAgICBTRVQoYywgZCwgYSwgYiwgIDcsIDE2
LCBUMzkpOw0KICAgIFNFVChiLCBjLCBkLCBhLCAxMCwgMjMsIFQ0MCk7DQog
ICAgU0VUKGEsIGIsIGMsIGQsIDEzLCAgNCwgVDQxKTsNCiAgICBTRVQoZCwg
YSwgYiwgYywgIDAsIDExLCBUNDIpOw0KICAgIFNFVChjLCBkLCBhLCBiLCAg
MywgMTYsIFQ0Myk7DQogICAgU0VUKGIsIGMsIGQsIGEsICA2LCAyMywgVDQ0
KTsNCiAgICBTRVQoYSwgYiwgYywgZCwgIDksICA0LCBUNDUpOw0KICAgIFNF
VChkLCBhLCBiLCBjLCAxMiwgMTEsIFQ0Nik7DQogICAgU0VUKGMsIGQsIGEs
IGIsIDE1LCAxNiwgVDQ3KTsNCiAgICBTRVQoYiwgYywgZCwgYSwgIDIsIDIz
LCBUNDgpOw0KI3VuZGVmIFNFVA0KDQogICAgIC8qIFJvdW5kIDQuICovDQog
ICAgIC8qIExldCBbYWJjZCBrIHMgdF0gZGVub3RlIHRoZSBvcGVyYXRpb24N
CiAgICAgICAgICBhID0gYiArICgoYSArIEkoYixjLGQpICsgWFtrXSArIFRb
aV0pIDw8PCBzKS4gKi8NCiNkZWZpbmUgSSh4LCB5LCB6KSAoKHkpIF4gKCh4
KSB8IH4oeikpKQ0KI2RlZmluZSBTRVQoYSwgYiwgYywgZCwgaywgcywgVGkp
XA0KICB0ID0gYSArIEkoYixjLGQpICsgWFtrXSArIFRpO1wNCiAgYSA9IFJP
VEFURV9MRUZUKHQsIHMpICsgYg0KICAgICAvKiBEbyB0aGUgZm9sbG93aW5n
IDE2IG9wZXJhdGlvbnMuICovDQogICAgU0VUKGEsIGIsIGMsIGQsICAwLCAg
NiwgVDQ5KTsNCiAgICBTRVQoZCwgYSwgYiwgYywgIDcsIDEwLCBUNTApOw0K
ICAgIFNFVChjLCBkLCBhLCBiLCAxNCwgMTUsIFQ1MSk7DQogICAgU0VUKGIs
IGMsIGQsIGEsICA1LCAyMSwgVDUyKTsNCiAgICBTRVQoYSwgYiwgYywgZCwg
MTIsICA2LCBUNTMpOw0KICAgIFNFVChkLCBhLCBiLCBjLCAgMywgMTAsIFQ1
NCk7DQogICAgU0VUKGMsIGQsIGEsIGIsIDEwLCAxNSwgVDU1KTsNCiAgICBT
RVQoYiwgYywgZCwgYSwgIDEsIDIxLCBUNTYpOw0KICAgIFNFVChhLCBiLCBj
LCBkLCAgOCwgIDYsIFQ1Nyk7DQogICAgU0VUKGQsIGEsIGIsIGMsIDE1LCAx
MCwgVDU4KTsNCiAgICBTRVQoYywgZCwgYSwgYiwgIDYsIDE1LCBUNTkpOw0K
ICAgIFNFVChiLCBjLCBkLCBhLCAxMywgMjEsIFQ2MCk7DQogICAgU0VUKGEs
IGIsIGMsIGQsICA0LCAgNiwgVDYxKTsNCiAgICBTRVQoZCwgYSwgYiwgYywg
MTEsIDEwLCBUNjIpOw0KICAgIFNFVChjLCBkLCBhLCBiLCAgMiwgMTUsIFQ2
Myk7DQogICAgU0VUKGIsIGMsIGQsIGEsICA5LCAyMSwgVDY0KTsNCiN1bmRl
ZiBTRVQNCg0KICAgICAvKiBUaGVuIHBlcmZvcm0gdGhlIGZvbGxvd2luZyBh
ZGRpdGlvbnMuIChUaGF0IGlzIGluY3JlbWVudCBlYWNoDQogICAgICAgIG9m
IHRoZSBmb3VyIHJlZ2lzdGVycyBieSB0aGUgdmFsdWUgaXQgaGFkIGJlZm9y
ZSB0aGlzIGJsb2NrDQogICAgICAgIHdhcyBzdGFydGVkLikgKi8NCiAgICBw
bXMtPmFiY2RbMF0gKz0gYTsNCiAgICBwbXMtPmFiY2RbMV0gKz0gYjsNCiAg
ICBwbXMtPmFiY2RbMl0gKz0gYzsNCiAgICBwbXMtPmFiY2RbM10gKz0gZDsN
Cn0NCg0Kdm9pZCBtZDVfaW5pdChtZDVfc3RhdGVfdCAqcG1zKXsNCiAgICBw
bXMtPmNvdW50WzBdID0gcG1zLT5jb3VudFsxXSA9IDA7DQogICAgcG1zLT5h
YmNkWzBdID0gMHg2NzQ1MjMwMTsNCiAgICBwbXMtPmFiY2RbMV0gPSAvKjB4
ZWZjZGFiODkqLyBUX01BU0sgXiAweDEwMzI1NDc2Ow0KICAgIHBtcy0+YWJj
ZFsyXSA9IC8qMHg5OGJhZGNmZSovIFRfTUFTSyBeIDB4Njc0NTIzMDE7DQog
ICAgcG1zLT5hYmNkWzNdID0gMHgxMDMyNTQ3NjsNCn0NCg0Kdm9pZCBtZDVf
YXBwZW5kKG1kNV9zdGF0ZV90ICpwbXMsIGNvbnN0IG1kNV9ieXRlX3QgKmRh
dGEsIGludCBuYnl0ZXMpew0KICAgIGNvbnN0IG1kNV9ieXRlX3QgKnAgPSBk
YXRhOw0KICAgIGludCBsZWZ0ID0gbmJ5dGVzOw0KICAgIGludCBvZmZzZXQg
PSAocG1zLT5jb3VudFswXSA+PiAzKSAmIDYzOw0KICAgIG1kNV93b3JkX3Qg
bmJpdHMgPSAobWQ1X3dvcmRfdCkobmJ5dGVzIDw8IDMpOw0KDQogICAgaWYg
KG5ieXRlcyA8PSAwKQ0KCXJldHVybjsNCg0KICAgIC8qIFVwZGF0ZSB0aGUg
bWVzc2FnZSBsZW5ndGguICovDQogICAgcG1zLT5jb3VudFsxXSArPSBuYnl0
ZXMgPj4gMjk7DQogICAgcG1zLT5jb3VudFswXSArPSBuYml0czsNCiAgICBp
ZiAocG1zLT5jb3VudFswXSA8IG5iaXRzKQ0KCXBtcy0+Y291bnRbMV0rKzsN
Cg0KICAgIC8qIFByb2Nlc3MgYW4gaW5pdGlhbCBwYXJ0aWFsIGJsb2NrLiAq
Lw0KICAgIGlmIChvZmZzZXQpIHsNCglpbnQgY29weSA9IChvZmZzZXQgKyBu
Ynl0ZXMgPiA2NCA/IDY0IC0gb2Zmc2V0IDogbmJ5dGVzKTsNCg0KCW1lbWNw
eShwbXMtPmJ1ZiArIG9mZnNldCwgcCwgY29weSk7DQoJaWYgKG9mZnNldCAr
IGNvcHkgPCA2NCkNCgkgICAgcmV0dXJuOw0KCXAgKz0gY29weTsNCglsZWZ0
IC09IGNvcHk7DQoJbWQ1X3Byb2Nlc3MocG1zLCBwbXMtPmJ1Zik7DQogICAg
fQ0KDQogICAgLyogUHJvY2VzcyBmdWxsIGJsb2Nrcy4gKi8NCiAgICBmb3Ig
KDsgbGVmdCA+PSA2NDsgcCArPSA2NCwgbGVmdCAtPSA2NCkNCgltZDVfcHJv
Y2VzcyhwbXMsIHApOw0KDQogICAgLyogUHJvY2VzcyBhIGZpbmFsIHBhcnRp
YWwgYmxvY2suICovDQogICAgaWYgKGxlZnQpDQoJbWVtY3B5KHBtcy0+YnVm
LCBwLCBsZWZ0KTsNCn0NCg0Kdm9pZCBtZDVfZmluaXNoKG1kNV9zdGF0ZV90
ICpwbXMsIG1kNV9ieXRlX3QgZGlnZXN0WzE2XSkgew0KICAgIHN0YXRpYyBj
b25zdCBtZDVfYnl0ZV90IHBhZFs2NF0gPSB7DQoJMHg4MCwgMCwgMCwgMCwg
MCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwNCgkwLCAwLCAw
LCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLA0KCTAs
IDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAs
DQoJMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwg
MCwgMA0KICAgIH07DQogICAgbWQ1X2J5dGVfdCBkYXRhWzhdOw0KICAgIGlu
dCBpOw0KDQogICAgLyogU2F2ZSB0aGUgbGVuZ3RoIGJlZm9yZSBwYWRkaW5n
LiAqLw0KICAgIGZvciAoaSA9IDA7IGkgPCA4OyArK2kpDQoJZGF0YVtpXSA9
IChtZDVfYnl0ZV90KShwbXMtPmNvdW50W2kgPj4gMl0gPj4gKChpICYgMykg
PDwgMykpOw0KICAgIC8qIFBhZCB0byA1NiBieXRlcyBtb2QgNjQuICovDQog
ICAgbWQ1X2FwcGVuZChwbXMsIHBhZCwgKCg1NSAtIChwbXMtPmNvdW50WzBd
ID4+IDMpKSAmIDYzKSArIDEpOw0KICAgIC8qIEFwcGVuZCB0aGUgbGVuZ3Ro
LiAqLw0KICAgIG1kNV9hcHBlbmQocG1zLCBkYXRhLCA4KTsNCiAgICBmb3Ig
KGkgPSAwOyBpIDwgMTY7ICsraSkNCglkaWdlc3RbaV0gPSAobWQ1X2J5dGVf
dCkocG1zLT5hYmNkW2kgPj4gMl0gPj4gKChpICYgMykgPDwgMykpOw0KfQ0K
DQo=
---1062731517-1852493920-1030108727=:13004--


Current thread: