/* Domain Cached Credentials 2 (MSCash2) example
* written by S3nf <thes3nf at googlemail.com> in 2010
* a slow but working implementation
*
* Generating Domain Cached Credentials for modern Windows operating systems, supporting:
* - Windows Vista
* - Windows 7
* - Windows Server 2008
*
* This software is based on:
* - the MSCASH patch for john written by Alain Espinosa <alainesp at gmail.com> in 2007
* - RFC 1320 - The MD4 Message-Digest Algorithm
* - RFC 2104 - HMAC: Keyed-Hashing for Message Authentication
* - RFC 3174 - US Secure Hash Algorithm 1 (SHA1)
* - the HMAC-SHA1 implementation of the PolarSSL open source cryptagraphic library (http://p...content-available-to-author-only...l.org/)
*
* This software was written by S3nf in 2010. No copyright is claimed, and the software is hereby placed in
* the public domain. In case this attempt to disclaim copyright and place the software in the public domain
* is deemed null and void, then the software is Copyright (c) 2010 S3nf and it is hereby released to the
* general public under the following terms:
*
* Redistribution and use in source and binary forms, with or without modification, are permitted.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ITERATIONS 10240
#define INIT_MD4_A 0x67452301
#define INIT_MD4_B 0xefcdab89
#define INIT_MD4_C 0x98badcfe
#define INIT_MD4_D 0x10325476
#define SQRT_2 0x5a827999
#define SQRT_3 0x6ed9eba1
#define SHA1_DIGEST_LENGTH 20
#define INIT_SHA1_A 0x67452301
#define INIT_SHA1_B 0xEFCDAB89
#define INIT_SHA1_C 0x98BADCFE
#define INIT_SHA1_D 0x10325476
#define INIT_SHA1_E 0xC3D2E1F0
#ifndef GET_WORD_32_BE
#define GET_WORD_32_BE(n,b,i) \
{ \
(n) = ( (unsigned long) (b)[(i) ] << 24 ) \
| ( (unsigned long) (b)[(i) + 1] << 16 ) \
| ( (unsigned long) (b)[(i) + 2] << 8 ) \
| ( (unsigned long) (b)[(i) + 3] ); \
}
#endif
#ifndef PUT_WORD_32_BE
#define PUT_WORD_32_BE(n,b,i) \
{ \
(b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
(b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
(b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
(b)[(i) + 3] = (unsigned char) ( (n) ); \
}
#endif
#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
#define R(t) \
( \
temp = W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ \
W[(t - 14) & 0x0F] ^ W[ t & 0x0F], \
( W[t & 0x0F] = S(temp,1) ) \
)
#define P(a,b,c,d,e,x) \
{ \
e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \
}
/*
* byte2hexstring
* convert byte array to hex string
*/
unsigned char * byte2hexstring( unsigned char * byte, unsigned int len) {
unsigned int i;
unsigned char * hexstring;
hexstring
= malloc ( len
* 2 + 1 ) ; bzero( hexstring, 2 * len + 1 ) ;
for ( i = 0 ; i < len; i++ )
sprintf ( & hexstring
[ 2 * i
] , "%02x" , byte
[ i
] ) ;
return hexstring;
}
/*
* hmac_sha1
* based on RFC 2104, RFC 3174 and the HMAC-SHA1 implementation of the PolarSSL
* open source cryptographic library (http://w...content-available-to-author-only...l.org)
*/
static void hmac_sha1( const unsigned char * key, unsigned int keylen, const unsigned char * input, unsigned int inputlen, unsigned char * output)
{
unsigned int i, temp, W[ 16 ] ;
unsigned int A, B, C, D, E, state[ 5 ] ;
unsigned char buf[ 64 ] ;
unsigned char ipad[ 64 ] ;
unsigned char opad[ 64 ] ;
// step 1: append zeros to the end of K to create a B Byte string
buf[ inputlen] = 0x80 ;
PUT_WORD_32_BE( ( 64 + inputlen) << 3 , buf, 60 ) ;
// step 2: XOR (bitwise exclusive-OR) the B byte string computed in step 1 with ipad
// step 5: XOR (bitwise exclusive-OR) the B byte string computed in step 1 with opad
for ( i = 0 ; i < keylen; i++ )
{
ipad[ i] = ipad[ i] ^ key[ i] ;
opad[ i] = opad[ i] ^ key[ i] ;
}
// step 3: append the stream of data 'text' to the B byte sting resulting from step 2
// first part of stream (64 bytes) is ipad, second part of stream (64 bytes) is buf
// step 4: apply H to the stream (ipad & buf) generated in step 3
GET_WORD_32_BE( W[ 0 ] , ipad, 0 ) ;
GET_WORD_32_BE( W[ 1 ] , ipad, 4 ) ;
GET_WORD_32_BE( W[ 2 ] , ipad, 8 ) ;
GET_WORD_32_BE( W[ 3 ] , ipad, 12 ) ;
GET_WORD_32_BE( W[ 4 ] , ipad, 16 ) ;
GET_WORD_32_BE( W[ 5 ] , ipad, 20 ) ;
GET_WORD_32_BE( W[ 6 ] , ipad, 24 ) ;
GET_WORD_32_BE( W[ 7 ] , ipad, 28 ) ;
GET_WORD_32_BE( W[ 8 ] , ipad, 32 ) ;
GET_WORD_32_BE( W[ 9 ] , ipad, 36 ) ;
GET_WORD_32_BE( W[ 10 ] , ipad, 40 ) ;
GET_WORD_32_BE( W[ 11 ] , ipad, 44 ) ;
GET_WORD_32_BE( W[ 12 ] , ipad, 48 ) ;
GET_WORD_32_BE( W[ 13 ] , ipad, 52 ) ;
GET_WORD_32_BE( W[ 14 ] , ipad, 56 ) ;
GET_WORD_32_BE( W[ 15 ] , ipad, 60 ) ;
A = INIT_SHA1_A;
B = INIT_SHA1_B;
C = INIT_SHA1_C;
D = INIT_SHA1_D;
E = INIT_SHA1_E;
#define F(x,y,z) (z ^ (x & (y ^ z)))
#define K 0x5A827999
P( A, B, C, D, E, W[ 0 ] ) ;
P( E, A, B, C, D, W[ 1 ] ) ;
P( D, E, A, B, C, W[ 2 ] ) ;
P( C, D, E, A, B, W[ 3 ] ) ;
P( B, C, D, E, A, W[ 4 ] ) ;
P( A, B, C, D, E, W[ 5 ] ) ;
P( E, A, B, C, D, W[ 6 ] ) ;
P( D, E, A, B, C, W[ 7 ] ) ;
P( C, D, E, A, B, W[ 8 ] ) ;
P( B, C, D, E, A, W[ 9 ] ) ;
P( A, B, C, D, E, W[ 10 ] ) ;
P( E, A, B, C, D, W[ 11 ] ) ;
P( D, E, A, B, C, W[ 12 ] ) ;
P( C, D, E, A, B, W[ 13 ] ) ;
P( B, C, D, E, A, W[ 14 ] ) ;
P( A, B, C, D, E, W[ 15 ] ) ;
P( E, A, B, C, D, R( 16 ) ) ;
P( D, E, A, B, C, R( 17 ) ) ;
P( C, D, E, A, B, R( 18 ) ) ;
P( B, C, D, E, A, R( 19 ) ) ;
#undef K
#undef F
#define F(x,y,z) (x ^ y ^ z)
#define K 0x6ED9EBA1
P( A, B, C, D, E, R( 20 ) ) ;
P( E, A, B, C, D, R( 21 ) ) ;
P( D, E, A, B, C, R( 22 ) ) ;
P( C, D, E, A, B, R( 23 ) ) ;
P( B, C, D, E, A, R( 24 ) ) ;
P( A, B, C, D, E, R( 25 ) ) ;
P( E, A, B, C, D, R( 26 ) ) ;
P( D, E, A, B, C, R( 27 ) ) ;
P( C, D, E, A, B, R( 28 ) ) ;
P( B, C, D, E, A, R( 29 ) ) ;
P( A, B, C, D, E, R( 30 ) ) ;
P( E, A, B, C, D, R( 31 ) ) ;
P( D, E, A, B, C, R( 32 ) ) ;
P( C, D, E, A, B, R( 33 ) ) ;
P( B, C, D, E, A, R( 34 ) ) ;
P( A, B, C, D, E, R( 35 ) ) ;
P( E, A, B, C, D, R( 36 ) ) ;
P( D, E, A, B, C, R( 37 ) ) ;
P( C, D, E, A, B, R( 38 ) ) ;
P( B, C, D, E, A, R( 39 ) ) ;
#undef K
#undef F
#define F(x,y,z) ((x & y) | (z & (x | y)))
#define K 0x8F1BBCDC
P( A, B, C, D, E, R( 40 ) ) ;
P( E, A, B, C, D, R( 41 ) ) ;
P( D, E, A, B, C, R( 42 ) ) ;
P( C, D, E, A, B, R( 43 ) ) ;
P( B, C, D, E, A, R( 44 ) ) ;
P( A, B, C, D, E, R( 45 ) ) ;
P( E, A, B, C, D, R( 46 ) ) ;
P( D, E, A, B, C, R( 47 ) ) ;
P( C, D, E, A, B, R( 48 ) ) ;
P( B, C, D, E, A, R( 49 ) ) ;
P( A, B, C, D, E, R( 50 ) ) ;
P( E, A, B, C, D, R( 51 ) ) ;
P( D, E, A, B, C, R( 52 ) ) ;
P( C, D, E, A, B, R( 53 ) ) ;
P( B, C, D, E, A, R( 54 ) ) ;
P( A, B, C, D, E, R( 55 ) ) ;
P( E, A, B, C, D, R( 56 ) ) ;
P( D, E, A, B, C, R( 57 ) ) ;
P( C, D, E, A, B, R( 58 ) ) ;
P( B, C, D, E, A, R( 59 ) ) ;
#undef K
#undef F
#define F(x,y,z) (x ^ y ^ z)
#define K 0xCA62C1D6
P( A, B, C, D, E, R( 60 ) ) ;
P( E, A, B, C, D, R( 61 ) ) ;
P( D, E, A, B, C, R( 62 ) ) ;
P( C, D, E, A, B, R( 63 ) ) ;
P( B, C, D, E, A, R( 64 ) ) ;
P( A, B, C, D, E, R( 65 ) ) ;
P( E, A, B, C, D, R( 66 ) ) ;
P( D, E, A, B, C, R( 67 ) ) ;
P( C, D, E, A, B, R( 68 ) ) ;
P( B, C, D, E, A, R( 69 ) ) ;
P( A, B, C, D, E, R( 70 ) ) ;
P( E, A, B, C, D, R( 71 ) ) ;
P( D, E, A, B, C, R( 72 ) ) ;
P( C, D, E, A, B, R( 73 ) ) ;
P( B, C, D, E, A, R( 74 ) ) ;
P( A, B, C, D, E, R( 75 ) ) ;
P( E, A, B, C, D, R( 76 ) ) ;
P( D, E, A, B, C, R( 77 ) ) ;
P( C, D, E, A, B, R( 78 ) ) ;
P( B, C, D, E, A, R( 79 ) ) ;
#undef K
#undef F
A += INIT_SHA1_A;
B += INIT_SHA1_B;
C += INIT_SHA1_C;
D += INIT_SHA1_D;
E += INIT_SHA1_E;
state[ 0 ] = A;
state[ 1 ] = B;
state[ 2 ] = C;
state[ 3 ] = D;
state[ 4 ] = E;
// process buf (2nd part of stream)
GET_WORD_32_BE( W[ 0 ] , buf, 0 ) ;
GET_WORD_32_BE( W[ 1 ] , buf, 4 ) ;
GET_WORD_32_BE( W[ 2 ] , buf, 8 ) ;
GET_WORD_32_BE( W[ 3 ] , buf, 12 ) ;
GET_WORD_32_BE( W[ 4 ] , buf, 16 ) ;
GET_WORD_32_BE( W[ 5 ] , buf, 20 ) ;
GET_WORD_32_BE( W[ 6 ] , buf, 24 ) ;
GET_WORD_32_BE( W[ 7 ] , buf, 28 ) ;
GET_WORD_32_BE( W[ 8 ] , buf, 32 ) ;
GET_WORD_32_BE( W[ 9 ] , buf, 36 ) ;
GET_WORD_32_BE( W[ 10 ] , buf, 40 ) ;
GET_WORD_32_BE( W[ 11 ] , buf, 44 ) ;
GET_WORD_32_BE( W[ 12 ] , buf, 48 ) ;
GET_WORD_32_BE( W[ 13 ] , buf, 52 ) ;
GET_WORD_32_BE( W[ 14 ] , buf, 56 ) ;
GET_WORD_32_BE( W[ 15 ] , buf, 60 ) ;
#define F(x,y,z) (z ^ (x & (y ^ z)))
#define K 0x5A827999
P( A, B, C, D, E, W[ 0 ] ) ;
P( E, A, B, C, D, W[ 1 ] ) ;
P( D, E, A, B, C, W[ 2 ] ) ;
P( C, D, E, A, B, W[ 3 ] ) ;
P( B, C, D, E, A, W[ 4 ] ) ;
P( A, B, C, D, E, W[ 5 ] ) ;
P( E, A, B, C, D, W[ 6 ] ) ;
P( D, E, A, B, C, W[ 7 ] ) ;
P( C, D, E, A, B, W[ 8 ] ) ;
P( B, C, D, E, A, W[ 9 ] ) ;
P( A, B, C, D, E, W[ 10 ] ) ;
P( E, A, B, C, D, W[ 11 ] ) ;
P( D, E, A, B, C, W[ 12 ] ) ;
P( C, D, E, A, B, W[ 13 ] ) ;
P( B, C, D, E, A, W[ 14 ] ) ;
P( A, B, C, D, E, W[ 15 ] ) ;
P( E, A, B, C, D, R( 16 ) ) ;
P( D, E, A, B, C, R( 17 ) ) ;
P( C, D, E, A, B, R( 18 ) ) ;
P( B, C, D, E, A, R( 19 ) ) ;
#undef K
#undef F
#define F(x,y,z) (x ^ y ^ z)
#define K 0x6ED9EBA1
P( A, B, C, D, E, R( 20 ) ) ;
P( E, A, B, C, D, R( 21 ) ) ;
P( D, E, A, B, C, R( 22 ) ) ;
P( C, D, E, A, B, R( 23 ) ) ;
P( B, C, D, E, A, R( 24 ) ) ;
P( A, B, C, D, E, R( 25 ) ) ;
P( E, A, B, C, D, R( 26 ) ) ;
P( D, E, A, B, C, R( 27 ) ) ;
P( C, D, E, A, B, R( 28 ) ) ;
P( B, C, D, E, A, R( 29 ) ) ;
P( A, B, C, D, E, R( 30 ) ) ;
P( E, A, B, C, D, R( 31 ) ) ;
P( D, E, A, B, C, R( 32 ) ) ;
P( C, D, E, A, B, R( 33 ) ) ;
P( B, C, D, E, A, R( 34 ) ) ;
P( A, B, C, D, E, R( 35 ) ) ;
P( E, A, B, C, D, R( 36 ) ) ;
P( D, E, A, B, C, R( 37 ) ) ;
P( C, D, E, A, B, R( 38 ) ) ;
P( B, C, D, E, A, R( 39 ) ) ;
#undef K
#undef F
#define F(x,y,z) ((x & y) | (z & (x | y)))
#define K 0x8F1BBCDC
P( A, B, C, D, E, R( 40 ) ) ;
P( E, A, B, C, D, R( 41 ) ) ;
P( D, E, A, B, C, R( 42 ) ) ;
P( C, D, E, A, B, R( 43 ) ) ;
P( B, C, D, E, A, R( 44 ) ) ;
P( A, B, C, D, E, R( 45 ) ) ;
P( E, A, B, C, D, R( 46 ) ) ;
P( D, E, A, B, C, R( 47 ) ) ;
P( C, D, E, A, B, R( 48 ) ) ;
P( B, C, D, E, A, R( 49 ) ) ;
P( A, B, C, D, E, R( 50 ) ) ;
P( E, A, B, C, D, R( 51 ) ) ;
P( D, E, A, B, C, R( 52 ) ) ;
P( C, D, E, A, B, R( 53 ) ) ;
P( B, C, D, E, A, R( 54 ) ) ;
P( A, B, C, D, E, R( 55 ) ) ;
P( E, A, B, C, D, R( 56 ) ) ;
P( D, E, A, B, C, R( 57 ) ) ;
P( C, D, E, A, B, R( 58 ) ) ;
P( B, C, D, E, A, R( 59 ) ) ;
#undef K
#undef F
#define F(x,y,z) (x ^ y ^ z)
#define K 0xCA62C1D6
P( A, B, C, D, E, R( 60 ) ) ;
P( E, A, B, C, D, R( 61 ) ) ;
P( D, E, A, B, C, R( 62 ) ) ;
P( C, D, E, A, B, R( 63 ) ) ;
P( B, C, D, E, A, R( 64 ) ) ;
P( A, B, C, D, E, R( 65 ) ) ;
P( E, A, B, C, D, R( 66 ) ) ;
P( D, E, A, B, C, R( 67 ) ) ;
P( C, D, E, A, B, R( 68 ) ) ;
P( B, C, D, E, A, R( 69 ) ) ;
P( A, B, C, D, E, R( 70 ) ) ;
P( E, A, B, C, D, R( 71 ) ) ;
P( D, E, A, B, C, R( 72 ) ) ;
P( C, D, E, A, B, R( 73 ) ) ;
P( B, C, D, E, A, R( 74 ) ) ;
P( A, B, C, D, E, R( 75 ) ) ;
P( E, A, B, C, D, R( 76 ) ) ;
P( D, E, A, B, C, R( 77 ) ) ;
P( C, D, E, A, B, R( 78 ) ) ;
P( B, C, D, E, A, R( 79 ) ) ;
#undef K
#undef F
A += state[ 0 ] ;
B += state[ 1 ] ;
C += state[ 2 ] ;
D += state[ 3 ] ;
E += state[ 4 ] ;
PUT_WORD_32_BE( A, buf, 0 ) ;
PUT_WORD_32_BE( B, buf, 4 ) ;
PUT_WORD_32_BE( C, buf, 8 ) ;
PUT_WORD_32_BE( D, buf, 12 ) ;
PUT_WORD_32_BE( E, buf, 16 ) ;
buf[ 20 ] = 0x80 ;
PUT_WORD_32_BE( 0x2A0 , buf, 60 ) ;
// step 6: append the stream of data 'text' to the B byte sting resulting from step 2
// first part of stream (64 bytes) is opad, second part of stream (64 bytes) is the H result from step 4
// step 7: apply H to the stream (opad & buf) generated in step 6 and output the result
GET_WORD_32_BE( W[ 0 ] , opad, 0 ) ;
GET_WORD_32_BE( W[ 1 ] , opad, 4 ) ;
GET_WORD_32_BE( W[ 2 ] , opad, 8 ) ;
GET_WORD_32_BE( W[ 3 ] , opad, 12 ) ;
GET_WORD_32_BE( W[ 4 ] , opad, 16 ) ;
GET_WORD_32_BE( W[ 5 ] , opad, 20 ) ;
GET_WORD_32_BE( W[ 6 ] , opad, 24 ) ;
GET_WORD_32_BE( W[ 7 ] , opad, 28 ) ;
GET_WORD_32_BE( W[ 8 ] , opad, 32 ) ;
GET_WORD_32_BE( W[ 9 ] , opad, 36 ) ;
GET_WORD_32_BE( W[ 10 ] , opad, 40 ) ;
GET_WORD_32_BE( W[ 11 ] , opad, 44 ) ;
GET_WORD_32_BE( W[ 12 ] , opad, 48 ) ;
GET_WORD_32_BE( W[ 13 ] , opad, 52 ) ;
GET_WORD_32_BE( W[ 14 ] , opad, 56 ) ;
GET_WORD_32_BE( W[ 15 ] , opad, 60 ) ;
A = INIT_SHA1_A;
B = INIT_SHA1_B;
C = INIT_SHA1_C;
D = INIT_SHA1_D;
E = INIT_SHA1_E;
#define F(x,y,z) (z ^ (x & (y ^ z)))
#define K 0x5A827999
P( A, B, C, D, E, W[ 0 ] ) ;
P( E, A, B, C, D, W[ 1 ] ) ;
P( D, E, A, B, C, W[ 2 ] ) ;
P( C, D, E, A, B, W[ 3 ] ) ;
P( B, C, D, E, A, W[ 4 ] ) ;
P( A, B, C, D, E, W[ 5 ] ) ;
P( E, A, B, C, D, W[ 6 ] ) ;
P( D, E, A, B, C, W[ 7 ] ) ;
P( C, D, E, A, B, W[ 8 ] ) ;
P( B, C, D, E, A, W[ 9 ] ) ;
P( A, B, C, D, E, W[ 10 ] ) ;
P( E, A, B, C, D, W[ 11 ] ) ;
P( D, E, A, B, C, W[ 12 ] ) ;
P( C, D, E, A, B, W[ 13 ] ) ;
P( B, C, D, E, A, W[ 14 ] ) ;
P( A, B, C, D, E, W[ 15 ] ) ;
P( E, A, B, C, D, R( 16 ) ) ;
P( D, E, A, B, C, R( 17 ) ) ;
P( C, D, E, A, B, R( 18 ) ) ;
P( B, C, D, E, A, R( 19 ) ) ;
#undef K
#undef F
#define F(x,y,z) (x ^ y ^ z)
#define K 0x6ED9EBA1
P( A, B, C, D, E, R( 20 ) ) ;
P( E, A, B, C, D, R( 21 ) ) ;
P( D, E, A, B, C, R( 22 ) ) ;
P( C, D, E, A, B, R( 23 ) ) ;
P( B, C, D, E, A, R( 24 ) ) ;
P( A, B, C, D, E, R( 25 ) ) ;
P( E, A, B, C, D, R( 26 ) ) ;
P( D, E, A, B, C, R( 27 ) ) ;
P( C, D, E, A, B, R( 28 ) ) ;
P( B, C, D, E, A, R( 29 ) ) ;
P( A, B, C, D, E, R( 30 ) ) ;
P( E, A, B, C, D, R( 31 ) ) ;
P( D, E, A, B, C, R( 32 ) ) ;
P( C, D, E, A, B, R( 33 ) ) ;
P( B, C, D, E, A, R( 34 ) ) ;
P( A, B, C, D, E, R( 35 ) ) ;
P( E, A, B, C, D, R( 36 ) ) ;
P( D, E, A, B, C, R( 37 ) ) ;
P( C, D, E, A, B, R( 38 ) ) ;
P( B, C, D, E, A, R( 39 ) ) ;
#undef K
#undef F
#define F(x,y,z) ((x & y) | (z & (x | y)))
#define K 0x8F1BBCDC
P( A, B, C, D, E, R( 40 ) ) ;
P( E, A, B, C, D, R( 41 ) ) ;
P( D, E, A, B, C, R( 42 ) ) ;
P( C, D, E, A, B, R( 43 ) ) ;
P( B, C, D, E, A, R( 44 ) ) ;
P( A, B, C, D, E, R( 45 ) ) ;
P( E, A, B, C, D, R( 46 ) ) ;
P( D, E, A, B, C, R( 47 ) ) ;
P( C, D, E, A, B, R( 48 ) ) ;
P( B, C, D, E, A, R( 49 ) ) ;
P( A, B, C, D, E, R( 50 ) ) ;
P( E, A, B, C, D, R( 51 ) ) ;
P( D, E, A, B, C, R( 52 ) ) ;
P( C, D, E, A, B, R( 53 ) ) ;
P( B, C, D, E, A, R( 54 ) ) ;
P( A, B, C, D, E, R( 55 ) ) ;
P( E, A, B, C, D, R( 56 ) ) ;
P( D, E, A, B, C, R( 57 ) ) ;
P( C, D, E, A, B, R( 58 ) ) ;
P( B, C, D, E, A, R( 59 ) ) ;
#undef K
#undef F
#define F(x,y,z) (x ^ y ^ z)
#define K 0xCA62C1D6
P( A, B, C, D, E, R( 60 ) ) ;
P( E, A, B, C, D, R( 61 ) ) ;
P( D, E, A, B, C, R( 62 ) ) ;
P( C, D, E, A, B, R( 63 ) ) ;
P( B, C, D, E, A, R( 64 ) ) ;
P( A, B, C, D, E, R( 65 ) ) ;
P( E, A, B, C, D, R( 66 ) ) ;
P( D, E, A, B, C, R( 67 ) ) ;
P( C, D, E, A, B, R( 68 ) ) ;
P( B, C, D, E, A, R( 69 ) ) ;
P( A, B, C, D, E, R( 70 ) ) ;
P( E, A, B, C, D, R( 71 ) ) ;
P( D, E, A, B, C, R( 72 ) ) ;
P( C, D, E, A, B, R( 73 ) ) ;
P( B, C, D, E, A, R( 74 ) ) ;
P( A, B, C, D, E, R( 75 ) ) ;
P( E, A, B, C, D, R( 76 ) ) ;
P( D, E, A, B, C, R( 77 ) ) ;
P( C, D, E, A, B, R( 78 ) ) ;
P( B, C, D, E, A, R( 79 ) ) ;
#undef K
#undef F
A += INIT_SHA1_A;
B += INIT_SHA1_B;
C += INIT_SHA1_C;
D += INIT_SHA1_D;
E += INIT_SHA1_E;
// store state for 2nd part
state[ 0 ] = A;
state[ 1 ] = B;
state[ 2 ] = C;
state[ 3 ] = D;
state[ 4 ] = E;
GET_WORD_32_BE( W[ 0 ] , buf, 0 ) ;
GET_WORD_32_BE( W[ 1 ] , buf, 4 ) ;
GET_WORD_32_BE( W[ 2 ] , buf, 8 ) ;
GET_WORD_32_BE( W[ 3 ] , buf, 12 ) ;
GET_WORD_32_BE( W[ 4 ] , buf, 16 ) ;
GET_WORD_32_BE( W[ 5 ] , buf, 20 ) ;
GET_WORD_32_BE( W[ 6 ] , buf, 24 ) ;
GET_WORD_32_BE( W[ 7 ] , buf, 28 ) ;
GET_WORD_32_BE( W[ 8 ] , buf, 32 ) ;
GET_WORD_32_BE( W[ 9 ] , buf, 36 ) ;
GET_WORD_32_BE( W[ 10 ] , buf, 40 ) ;
GET_WORD_32_BE( W[ 11 ] , buf, 44 ) ;
GET_WORD_32_BE( W[ 12 ] , buf, 48 ) ;
GET_WORD_32_BE( W[ 13 ] , buf, 52 ) ;
GET_WORD_32_BE( W[ 14 ] , buf, 56 ) ;
GET_WORD_32_BE( W[ 15 ] , buf, 60 ) ;
#define F(x,y,z) (z ^ (x & (y ^ z)))
#define K 0x5A827999
P( A, B, C, D, E, W[ 0 ] ) ;
P( E, A, B, C, D, W[ 1 ] ) ;
P( D, E, A, B, C, W[ 2 ] ) ;
P( C, D, E, A, B, W[ 3 ] ) ;
P( B, C, D, E, A, W[ 4 ] ) ;
P( A, B, C, D, E, W[ 5 ] ) ;
P( E, A, B, C, D, W[ 6 ] ) ;
P( D, E, A, B, C, W[ 7 ] ) ;
P( C, D, E, A, B, W[ 8 ] ) ;
P( B, C, D, E, A, W[ 9 ] ) ;
P( A, B, C, D, E, W[ 10 ] ) ;
P( E, A, B, C, D, W[ 11 ] ) ;
P( D, E, A, B, C, W[ 12 ] ) ;
P( C, D, E, A, B, W[ 13 ] ) ;
P( B, C, D, E, A, W[ 14 ] ) ;
P( A, B, C, D, E, W[ 15 ] ) ;
P( E, A, B, C, D, R( 16 ) ) ;
P( D, E, A, B, C, R( 17 ) ) ;
P( C, D, E, A, B, R( 18 ) ) ;
P( B, C, D, E, A, R( 19 ) ) ;
#undef K
#undef F
#define F(x,y,z) (x ^ y ^ z)
#define K 0x6ED9EBA1
P( A, B, C, D, E, R( 20 ) ) ;
P( E, A, B, C, D, R( 21 ) ) ;
P( D, E, A, B, C, R( 22 ) ) ;
P( C, D, E, A, B, R( 23 ) ) ;
P( B, C, D, E, A, R( 24 ) ) ;
P( A, B, C, D, E, R( 25 ) ) ;
P( E, A, B, C, D, R( 26 ) ) ;
P( D, E, A, B, C, R( 27 ) ) ;
P( C, D, E, A, B, R( 28 ) ) ;
P( B, C, D, E, A, R( 29 ) ) ;
P( A, B, C, D, E, R( 30 ) ) ;
P( E, A, B, C, D, R( 31 ) ) ;
P( D, E, A, B, C, R( 32 ) ) ;
P( C, D, E, A, B, R( 33 ) ) ;
P( B, C, D, E, A, R( 34 ) ) ;
P( A, B, C, D, E, R( 35 ) ) ;
P( E, A, B, C, D, R( 36 ) ) ;
P( D, E, A, B, C, R( 37 ) ) ;
P( C, D, E, A, B, R( 38 ) ) ;
P( B, C, D, E, A, R( 39 ) ) ;
#undef K
#undef F
#define F(x,y,z) ((x & y) | (z & (x | y)))
#define K 0x8F1BBCDC
P( A, B, C, D, E, R( 40 ) ) ;
P( E, A, B, C, D, R( 41 ) ) ;
P( D, E, A, B, C, R( 42 ) ) ;
P( C, D, E, A, B, R( 43 ) ) ;
P( B, C, D, E, A, R( 44 ) ) ;
P( A, B, C, D, E, R( 45 ) ) ;
P( E, A, B, C, D, R( 46 ) ) ;
P( D, E, A, B, C, R( 47 ) ) ;
P( C, D, E, A, B, R( 48 ) ) ;
P( B, C, D, E, A, R( 49 ) ) ;
P( A, B, C, D, E, R( 50 ) ) ;
P( E, A, B, C, D, R( 51 ) ) ;
P( D, E, A, B, C, R( 52 ) ) ;
P( C, D, E, A, B, R( 53 ) ) ;
P( B, C, D, E, A, R( 54 ) ) ;
P( A, B, C, D, E, R( 55 ) ) ;
P( E, A, B, C, D, R( 56 ) ) ;
P( D, E, A, B, C, R( 57 ) ) ;
P( C, D, E, A, B, R( 58 ) ) ;
P( B, C, D, E, A, R( 59 ) ) ;
#undef K
#undef F
#define F(x,y,z) (x ^ y ^ z)
#define K 0xCA62C1D6
P( A, B, C, D, E, R( 60 ) ) ;
P( E, A, B, C, D, R( 61 ) ) ;
P( D, E, A, B, C, R( 62 ) ) ;
P( C, D, E, A, B, R( 63 ) ) ;
P( B, C, D, E, A, R( 64 ) ) ;
P( A, B, C, D, E, R( 65 ) ) ;
P( E, A, B, C, D, R( 66 ) ) ;
P( D, E, A, B, C, R( 67 ) ) ;
P( C, D, E, A, B, R( 68 ) ) ;
P( B, C, D, E, A, R( 69 ) ) ;
P( A, B, C, D, E, R( 70 ) ) ;
P( E, A, B, C, D, R( 71 ) ) ;
P( D, E, A, B, C, R( 72 ) ) ;
P( C, D, E, A, B, R( 73 ) ) ;
P( B, C, D, E, A, R( 74 ) ) ;
P( A, B, C, D, E, R( 75 ) ) ;
P( E, A, B, C, D, R( 76 ) ) ;
P( D, E, A, B, C, R( 77 ) ) ;
P( C, D, E, A, B, R( 78 ) ) ;
P( B, C, D, E, A, R( 79 ) ) ;
#undef K
#undef F
A += state[ 0 ] ;
B += state[ 1 ] ;
C += state[ 2 ] ;
D += state[ 3 ] ;
E += state[ 4 ] ;
PUT_WORD_32_BE( A, output, 0 ) ;
PUT_WORD_32_BE( B, output, 4 ) ;
PUT_WORD_32_BE( C, output, 8 ) ;
PUT_WORD_32_BE( D, output, 12 ) ;
PUT_WORD_32_BE( E, output, 16 ) ;
}
/* PBKDF2
* stripped-down implementation
* based on the source code written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL Project 1999
*/
static void PBKDF2_DCC2( const unsigned char * pass, const unsigned char * salt, int saltlen, unsigned char * out)
{
unsigned char temp[ SHA1_DIGEST_LENGTH] ;
unsigned char buf[ 48 ] ;
unsigned int i;
buf[ saltlen + 3 ] = 0x01 ;
hmac_sha1( pass, 16 , buf, saltlen + 4 , temp) ;
for ( i = 1 ; i < ITERATIONS; i++ )
{
hmac_sha1( pass, 16 , temp, SHA1_DIGEST_LENGTH, temp) ;
out[ 0 ] ^= temp[ 0 ] ;
out[ 1 ] ^= temp[ 1 ] ;
out[ 2 ] ^= temp[ 2 ] ;
out[ 3 ] ^= temp[ 3 ] ;
out[ 4 ] ^= temp[ 4 ] ;
out[ 5 ] ^= temp[ 5 ] ;
out[ 6 ] ^= temp[ 6 ] ;
out[ 7 ] ^= temp[ 7 ] ;
out[ 8 ] ^= temp[ 8 ] ;
out[ 9 ] ^= temp[ 9 ] ;
out[ 10 ] ^= temp[ 10 ] ;
out[ 11 ] ^= temp[ 11 ] ;
out[ 12 ] ^= temp[ 12 ] ;
out[ 13 ] ^= temp[ 13 ] ;
out[ 14 ] ^= temp[ 14 ] ;
out[ 15 ] ^= temp[ 15 ] ;
// out[16] ^= temp[16]; - was a bug?
}
}
// MD4 compression function
void md4_crypt( unsigned int * buffer, unsigned int * hash)
{
unsigned int a;
unsigned int b;
unsigned int c;
unsigned int d;
// round 1
a = 0xFFFFFFFF + buffer[ 0 ] ; a = ( a << 3 ) | ( a >> 29 ) ;
d = INIT_MD4_D + ( INIT_MD4_C ^ ( a & 0x77777777 ) ) + buffer[ 1 ] ; d = ( d << 7 ) | ( d >> 25 ) ;
c = INIT_MD4_C + ( INIT_MD4_B ^ ( d & ( a ^ INIT_MD4_B) ) ) + buffer[ 2 ] ; c = ( c << 11 ) | ( c >> 21 ) ;
b = INIT_MD4_B + ( a ^ ( c & ( d ^ a) ) ) + buffer[ 3 ] ; b = ( b << 19 ) | ( b >> 13 ) ;
a += ( d ^ ( b & ( c ^ d) ) ) + buffer[ 4 ] ; a = ( a << 3 ) | ( a >> 29 ) ;
d += ( c ^ ( a & ( b ^ c) ) ) + buffer[ 5 ] ; d = ( d << 7 ) | ( d >> 25 ) ;
c += ( b ^ ( d & ( a ^ b) ) ) + buffer[ 6 ] ; c = ( c << 11 ) | ( c >> 21 ) ;
b += ( a ^ ( c & ( d ^ a) ) ) + buffer[ 7 ] ; b = ( b << 19 ) | ( b >> 13 ) ;
a += ( d ^ ( b & ( c ^ d) ) ) + buffer[ 8 ] ; a = ( a << 3 ) | ( a >> 29 ) ;
d += ( c ^ ( a & ( b ^ c) ) ) + buffer[ 9 ] ; d = ( d << 7 ) | ( d >> 25 ) ;
c += ( b ^ ( d & ( a ^ b) ) ) + buffer[ 10 ] ; c = ( c << 11 ) | ( c >> 21 ) ;
b += ( a ^ ( c & ( d ^ a) ) ) + buffer[ 11 ] ; b = ( b << 19 ) | ( b >> 13 ) ;
a += ( d ^ ( b & ( c ^ d) ) ) + buffer[ 12 ] ; a = ( a << 3 ) | ( a >> 29 ) ;
d += ( c ^ ( a & ( b ^ c) ) ) + buffer[ 13 ] ; d = ( d << 7 ) | ( d >> 25 ) ;
c += ( b ^ ( d & ( a ^ b) ) ) + buffer[ 14 ] ; c = ( c << 11 ) | ( c >> 21 ) ;
b += ( a ^ ( c & ( d ^ a) ) ) + buffer[ 15 ] ; b = ( b << 19 ) | ( b >> 13 ) ;
// round 2
a += ( ( b & ( c | d) ) | ( c & d) ) + buffer[ 0 ] + SQRT_2; a = ( a<< 3 ) | ( a>> 29 ) ;
d += ( ( a & ( b | c) ) | ( b & c) ) + buffer[ 4 ] + SQRT_2; d = ( d<< 5 ) | ( d>> 27 ) ;
c += ( ( d & ( a | b) ) | ( a & b) ) + buffer[ 8 ] + SQRT_2; c = ( c<< 9 ) | ( c>> 23 ) ;
b += ( ( c & ( d | a) ) | ( d & a) ) + buffer[ 12 ] + SQRT_2; b = ( b<< 13 ) | ( b>> 19 ) ;
a += ( ( b & ( c | d) ) | ( c & d) ) + buffer[ 1 ] + SQRT_2; a = ( a<< 3 ) | ( a>> 29 ) ;
d += ( ( a & ( b | c) ) | ( b & c) ) + buffer[ 5 ] + SQRT_2; d = ( d<< 5 ) | ( d>> 27 ) ;
c += ( ( d & ( a | b) ) | ( a & b) ) + buffer[ 9 ] + SQRT_2; c = ( c<< 9 ) | ( c>> 23 ) ;
b += ( ( c & ( d | a) ) | ( d & a) ) + buffer[ 13 ] + SQRT_2; b = ( b<< 13 ) | ( b>> 19 ) ;
a += ( ( b & ( c | d) ) | ( c & d) ) + buffer[ 2 ] + SQRT_2; a = ( a<< 3 ) | ( a>> 29 ) ;
d += ( ( a & ( b | c) ) | ( b & c) ) + buffer[ 6 ] + SQRT_2; d = ( d<< 5 ) | ( d>> 27 ) ;
c += ( ( d & ( a | b) ) | ( a & b) ) + buffer[ 10 ] + SQRT_2; c = ( c<< 9 ) | ( c>> 23 ) ;
b += ( ( c & ( d | a) ) | ( d & a) ) + buffer[ 14 ] + SQRT_2; b = ( b<< 13 ) | ( b>> 19 ) ;
a += ( ( b & ( c | d) ) | ( c & d) ) + buffer[ 3 ] + SQRT_2; a = ( a<< 3 ) | ( a>> 29 ) ;
d += ( ( a & ( b | c) ) | ( b & c) ) + buffer[ 7 ] + SQRT_2; d = ( d<< 5 ) | ( d>> 27 ) ;
c += ( ( d & ( a | b) ) | ( a & b) ) + buffer[ 11 ] + SQRT_2; c = ( c<< 9 ) | ( c>> 23 ) ;
b += ( ( c & ( d | a) ) | ( d & a) ) + buffer[ 15 ] + SQRT_2; b = ( b<< 13 ) | ( b>> 19 ) ;
// round 3
a += ( d ^ c ^ b) + buffer[ 0 ] + SQRT_3; a = ( a << 3 ) | ( a >> 29 ) ;
d += ( c ^ b ^ a) + buffer[ 8 ] + SQRT_3; d = ( d << 9 ) | ( d >> 23 ) ;
c += ( b ^ a ^ d) + buffer[ 4 ] + SQRT_3; c = ( c << 11 ) | ( c >> 21 ) ;
b += ( a ^ d ^ c) + buffer[ 12 ] + SQRT_3; b = ( b << 15 ) | ( b >> 17 ) ;
a += ( d ^ c ^ b) + buffer[ 2 ] + SQRT_3; a = ( a << 3 ) | ( a >> 29 ) ;
d += ( c ^ b ^ a) + buffer[ 10 ] + SQRT_3; d = ( d << 9 ) | ( d >> 23 ) ;
c += ( b ^ a ^ d) + buffer[ 6 ] + SQRT_3; c = ( c << 11 ) | ( c >> 21 ) ;
b += ( a ^ d ^ c) + buffer[ 14 ] + SQRT_3; b = ( b << 15 ) | ( b >> 17 ) ;
a += ( d ^ c ^ b) + buffer[ 1 ] + SQRT_3; a = ( a << 3 ) | ( a >> 29 ) ;
d += ( c ^ b ^ a) + buffer[ 9 ] + SQRT_3; d = ( d << 9 ) | ( d >> 23 ) ;
c += ( b ^ a ^ d) + buffer[ 5 ] + SQRT_3; c = ( c << 11 ) | ( c >> 21 ) ;
b += ( a ^ d ^ c) + buffer[ 13 ] + SQRT_3; b = ( b << 15 ) | ( b >> 17 ) ;
a += ( d ^ c ^ b) + buffer[ 3 ] + SQRT_3; a = ( a << 3 ) | ( a >> 29 ) ;
d += ( c ^ b ^ a) + buffer[ 11 ] + SQRT_3; d = ( d << 9 ) | ( d >> 23 ) ;
c += ( b ^ a ^ d) + buffer[ 7 ] + SQRT_3; c = ( c << 11 ) | ( c >> 21 ) ;
b += ( a ^ d ^ c) + buffer[ 15 ] + SQRT_3; b = ( b << 15 ) | ( b >> 17 ) ;
hash[ 0 ] = a + INIT_MD4_A;
hash[ 1 ] = b + INIT_MD4_B;
hash[ 2 ] = c + INIT_MD4_C;
hash[ 3 ] = d + INIT_MD4_D;
}
// main
int main( int argc, char * argv[ ] )
{
unsigned int i;
unsigned int buffer[ 16 ] ;
unsigned int nt_hash[ 16 ] ;
unsigned int dcc_hash[ 16 ] ;
unsigned int dcc2_hash[ 16 ] ;
unsigned char salt[ 44 ] ;
unsigned char username[ ] = "test" ;
unsigned char password[ ] = "password" ;
unsigned int username_len
= strlen ( username
) ; unsigned int password_len
= strlen ( password
) ;
// convert ASCII username to Unicode (WideChar)
for ( i = 0 ; i < ( username_len >> 1 ) + 1 ; i++ )
( ( unsigned int * ) salt) [ i] = username[ 2 * i] | ( username[ 2 * i + 1 ] << 16 ) ;
// convert ASCII password to Unicode
for ( i = 0 ; i < password_len >> 1 ; i++ )
buffer[ i] = password[ 2 * i] | ( password[ 2 * i + 1 ] << 16 ) ;
// MD4 padding
if ( password_len % 2 == 1 )
buffer[ i] = password[ password_len - 1 ] | 0x800000 ;
else
buffer[ i] = 0x80 ;
// put password length at end of buffer
buffer[ 14 ] = password_len << 4 ;
// generate MD4 hash of the password (NT hash)
md4_crypt( buffer, nt_hash) ;
// concatenate NT hash and the username (salt)
memcpy ( ( unsigned char * ) nt_hash
+ 16 , salt
, username_len
<< 1 ) ;
i = username_len + 8 ;
// MD4 padding
if ( username_len % 2 == 1 )
nt_hash[ i >> 1 ] = username[ username_len - 1 ] | 0x800000 ;
else
nt_hash[ i >> 1 ] = 0x80 ;
// put length at end of buffer
nt_hash[ 14 ] = i << 4 ;
md4_crypt( nt_hash, dcc_hash) ;
// stripped-down PBKDF2 for DCC2
PBKDF2_DCC2( ( unsigned char * ) dcc_hash, salt, username_len << 1 , ( unsigned char * ) dcc2_hash) ;
// the even slower OpenSSL PBKDF2 implementation (compile with -lssl)
// PKCS5_PBKDF2_HMAC_SHA1((unsigned char*)dcc_hash, 16, salt, username_len << 1, ITERATIONS, 16, (unsigned char*)dcc2_hash);
// user credentials and DCC and DCC2 hash values
printf ( "username : %s\n " , username
) ; printf ( "password : %s\n " , password
) ; printf ( "DCC aka M$ Cache : %s\n " , byte2hexstring
( ( unsigned char * ) dcc_hash
, 16 ) ) ; printf ( "DCC2 aka M$ Cache 2: %s\n " , byte2hexstring
( ( unsigned char * ) dcc2_hash
, 16 ) ) ;
return 0 ;
}
LyogRG9tYWluIENhY2hlZCBDcmVkZW50aWFscyAyIChNU0Nhc2gyKSBleGFtcGxlIAogKiB3cml0dGVuIGJ5IFMzbmYgPHRoZXMzbmYgYXQgZ29vZ2xlbWFpbC5jb20+IGluIDIwMTAKICogYSBzbG93IGJ1dCB3b3JraW5nIGltcGxlbWVudGF0aW9uCiAqCiAqIEdlbmVyYXRpbmcgRG9tYWluIENhY2hlZCBDcmVkZW50aWFscyBmb3IgbW9kZXJuIFdpbmRvd3Mgb3BlcmF0aW5nIHN5c3RlbXMsIHN1cHBvcnRpbmc6CiAqICAgICAtIFdpbmRvd3MgVmlzdGEKICogICAgIC0gV2luZG93cyA3CiAqICAgICAtIFdpbmRvd3MgU2VydmVyIDIwMDgKICoKICogVGhpcyBzb2Z0d2FyZSBpcyBiYXNlZCBvbjoKICogICAgIC0gdGhlIE1TQ0FTSCBwYXRjaCBmb3Igam9obiB3cml0dGVuIGJ5IEFsYWluIEVzcGlub3NhIDxhbGFpbmVzcCBhdCBnbWFpbC5jb20+IGluIDIwMDcKICogICAgIC0gUkZDIDEzMjAgLSBUaGUgTUQ0IE1lc3NhZ2UtRGlnZXN0IEFsZ29yaXRobQogKiAgICAgLSBSRkMgMjEwNCAtIEhNQUM6IEtleWVkLUhhc2hpbmcgZm9yIE1lc3NhZ2UgQXV0aGVudGljYXRpb24KICogICAgIC0gUkZDIDMxNzQgLSBVUyBTZWN1cmUgSGFzaCBBbGdvcml0aG0gMSAoU0hBMSkKICogICAgIC0gdGhlIEhNQUMtU0hBMSBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgUG9sYXJTU0wgb3BlbiBzb3VyY2UgY3J5cHRhZ3JhcGhpYyBsaWJyYXJ5IChodHRwOi8vcC4uLmNvbnRlbnQtYXZhaWxhYmxlLXRvLWF1dGhvci1vbmx5Li4ubC5vcmcvKSAKICoKICogVGhpcyBzb2Z0d2FyZSB3YXMgd3JpdHRlbiBieSBTM25mIGluIDIwMTAuIE5vIGNvcHlyaWdodCBpcyBjbGFpbWVkLCBhbmQgdGhlIHNvZnR3YXJlIGlzIGhlcmVieSBwbGFjZWQgaW4KICogdGhlIHB1YmxpYyBkb21haW4uIEluIGNhc2UgdGhpcyBhdHRlbXB0IHRvIGRpc2NsYWltIGNvcHlyaWdodCBhbmQgcGxhY2UgdGhlIHNvZnR3YXJlIGluIHRoZSBwdWJsaWMgZG9tYWluCiAqIGlzIGRlZW1lZCBudWxsIGFuZCB2b2lkLCB0aGVuIHRoZSBzb2Z0d2FyZSBpcyBDb3B5cmlnaHQgKGMpIDIwMTAgUzNuZiBhbmQgaXQgaXMgaGVyZWJ5IHJlbGVhc2VkIHRvIHRoZQogKiBnZW5lcmFsIHB1YmxpYyB1bmRlciB0aGUgZm9sbG93aW5nIHRlcm1zOgogKgogKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQgbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkLgogKgogKi8KIAojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiAKI2RlZmluZSBJVEVSQVRJT05TICAgICAgICAgICAgICAgICAgMTAyNDAKIAojZGVmaW5lIElOSVRfTUQ0X0EgICAgICAgICAgICAgICAgICAweDY3NDUyMzAxCiNkZWZpbmUgSU5JVF9NRDRfQiAgICAgICAgICAgICAgICAgIDB4ZWZjZGFiODkKI2RlZmluZSBJTklUX01ENF9DICAgICAgICAgICAgICAgICAgMHg5OGJhZGNmZQojZGVmaW5lIElOSVRfTUQ0X0QgICAgICAgICAgICAgICAgICAweDEwMzI1NDc2CiAKI2RlZmluZSBTUVJUXzIgICAgICAgICAgICAgICAgICAgICAgMHg1YTgyNzk5OQojZGVmaW5lIFNRUlRfMyAgICAgICAgICAgICAgICAgICAgICAweDZlZDllYmExCiAKI2RlZmluZSBTSEExX0RJR0VTVF9MRU5HVEggICAgICAgICAgMjAKIAojZGVmaW5lIElOSVRfU0hBMV9BICAgICAgICAgICAgICAgICAweDY3NDUyMzAxCiNkZWZpbmUgSU5JVF9TSEExX0IgICAgICAgICAgICAgICAgIDB4RUZDREFCODkKI2RlZmluZSBJTklUX1NIQTFfQyAgICAgICAgICAgICAgICAgMHg5OEJBRENGRQojZGVmaW5lIElOSVRfU0hBMV9EICAgICAgICAgICAgICAgICAweDEwMzI1NDc2CiNkZWZpbmUgSU5JVF9TSEExX0UgICAgICAgICAgICAgICAgIDB4QzNEMkUxRjAKIAojaWZuZGVmIEdFVF9XT1JEXzMyX0JFCiNkZWZpbmUgR0VUX1dPUkRfMzJfQkUobixiLGkpICAgICAgICAgICAgICAgICAgICAgICAgICAgXAp7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKICAgIChuKSA9ICggKHVuc2lnbmVkIGxvbmcpIChiKVsoaSkgICAgXSA8PCAyNCApICAgICAgICBcCiAgICAgICAgfCAoICh1bnNpZ25lZCBsb25nKSAoYilbKGkpICsgMV0gPDwgMTYgKSAgICAgICAgXAogICAgICAgIHwgKCAodW5zaWduZWQgbG9uZykgKGIpWyhpKSArIDJdIDw8ICA4ICkgICAgICAgIFwKICAgICAgICB8ICggKHVuc2lnbmVkIGxvbmcpIChiKVsoaSkgKyAzXSAgICAgICApOyAgICAgICBcCn0KI2VuZGlmCiAKI2lmbmRlZiBQVVRfV09SRF8zMl9CRQojZGVmaW5lIFBVVF9XT1JEXzMyX0JFKG4sYixpKSAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICAoYilbKGkpICAgIF0gPSAodW5zaWduZWQgY2hhcikgKCAobikgPj4gMjQgKTsgICAgICAgXAogICAgKGIpWyhpKSArIDFdID0gKHVuc2lnbmVkIGNoYXIpICggKG4pID4+IDE2ICk7ICAgICAgIFwKICAgIChiKVsoaSkgKyAyXSA9ICh1bnNpZ25lZCBjaGFyKSAoIChuKSA+PiAgOCApOyAgICAgICBcCiAgICAoYilbKGkpICsgM10gPSAodW5zaWduZWQgY2hhcikgKCAobikgICAgICAgKTsgICAgICAgXAp9CiNlbmRpZgogCiNkZWZpbmUgUyh4LG4pICgoeCA8PCBuKSB8ICgoeCAmIDB4RkZGRkZGRkYpID4+ICgzMiAtIG4pKSkKIAojZGVmaW5lIFIodCkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICB0ZW1wID0gV1sodCAtICAzKSAmIDB4MEZdIF4gV1sodCAtIDgpICYgMHgwRl0gXiAgICAgXAogICAgICAgICAgIFdbKHQgLSAxNCkgJiAweDBGXSBeIFdbIHQgICAgICAmIDB4MEZdLCAgICAgIFwKICAgICggV1t0ICYgMHgwRl0gPSBTKHRlbXAsMSkgKSAgICAgICAgICAgICAgICAgICAgICAgICBcCikKIAojZGVmaW5lIFAoYSxiLGMsZCxlLHgpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICBlICs9IFMoYSw1KSArIEYoYixjLGQpICsgSyArIHg7IGIgPSBTKGIsMzApOyAgICAgICAgXAp9CiAKIAovKgogKiBieXRlMmhleHN0cmluZwogKiBjb252ZXJ0IGJ5dGUgYXJyYXkgdG8gaGV4IHN0cmluZwogKi8KdW5zaWduZWQgY2hhciAqYnl0ZTJoZXhzdHJpbmcodW5zaWduZWQgY2hhciAqIGJ5dGUsIHVuc2lnbmVkIGludCBsZW4pIHsKICAgIHVuc2lnbmVkIGludCBpOwogICAgdW5zaWduZWQgY2hhciAqaGV4c3RyaW5nOwogCiAgICBoZXhzdHJpbmcgPSBtYWxsb2MobGVuICogMiArIDEpOwogICAgYnplcm8oaGV4c3RyaW5nLCAyICogbGVuICsgMSk7CiAKICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKykKICAgICAgICBzcHJpbnRmKCZoZXhzdHJpbmdbMiAqIGldLCAiJTAyeCIsIGJ5dGVbaV0pOwogCiAgICByZXR1cm4gaGV4c3RyaW5nOwp9CiAKIAovKgogKiBobWFjX3NoYTEKICogYmFzZWQgb24gUkZDIDIxMDQsIFJGQyAzMTc0IGFuZCB0aGUgSE1BQy1TSEExIGltcGxlbWVudGF0aW9uIG9mIHRoZSBQb2xhclNTTCAKICogb3BlbiBzb3VyY2UgY3J5cHRvZ3JhcGhpYyBsaWJyYXJ5IChodHRwOi8vdy4uLmNvbnRlbnQtYXZhaWxhYmxlLXRvLWF1dGhvci1vbmx5Li4ubC5vcmcpCiAqLwpzdGF0aWMgdm9pZCBobWFjX3NoYTEoY29uc3QgdW5zaWduZWQgY2hhciAqa2V5LCB1bnNpZ25lZCBpbnQga2V5bGVuLCBjb25zdCB1bnNpZ25lZCBjaGFyICppbnB1dCwgdW5zaWduZWQgaW50IGlucHV0bGVuLCB1bnNpZ25lZCBjaGFyICpvdXRwdXQpCnsKICAgIHVuc2lnbmVkIGludCBpLCB0ZW1wLCBXWzE2XTsKICAgIHVuc2lnbmVkIGludCBBLCBCLCBDLCBELCBFLCBzdGF0ZVs1XTsKICAgIHVuc2lnbmVkIGNoYXIgYnVmWzY0XTsKICAgIHVuc2lnbmVkIGNoYXIgaXBhZFs2NF07CiAgICB1bnNpZ25lZCBjaGFyIG9wYWRbNjRdOwogCiAgICBtZW1zZXQoaXBhZCwgMHgzNiwgNjQpOwogICAgbWVtc2V0KG9wYWQsIDB4NUMsIDY0KTsKICAgIG1lbXNldChidWYsIDAsIDY0KTsKIAogICAgLy8gc3RlcCAxOiBhcHBlbmQgemVyb3MgdG8gdGhlIGVuZCBvZiBLIHRvIGNyZWF0ZSBhIEIgQnl0ZSBzdHJpbmcKICAgIG1lbWNweShidWYsIGlucHV0LCBpbnB1dGxlbik7CiAgICBidWZbaW5wdXRsZW5dID0gMHg4MDsKICAgIFBVVF9XT1JEXzMyX0JFKCg2NCArIGlucHV0bGVuKSA8PCAzLCBidWYsIDYwKTsKIAogICAgLy8gc3RlcCAyOiBYT1IgKGJpdHdpc2UgZXhjbHVzaXZlLU9SKSB0aGUgQiBieXRlIHN0cmluZyBjb21wdXRlZCBpbiBzdGVwIDEgd2l0aCBpcGFkCiAgICAvLyBzdGVwIDU6IFhPUiAoYml0d2lzZSBleGNsdXNpdmUtT1IpIHRoZSBCIGJ5dGUgc3RyaW5nIGNvbXB1dGVkIGluIHN0ZXAgMSB3aXRoIG9wYWQgICAgCiAgICBmb3IoaSA9IDA7IGkgPCBrZXlsZW47IGkrKykKICAgIHsKICAgICAgICBpcGFkW2ldID0gaXBhZFtpXSBeIGtleVtpXTsKICAgICAgICBvcGFkW2ldID0gb3BhZFtpXSBeIGtleVtpXTsKICAgIH0KIAogICAgLy8gc3RlcCAzOiBhcHBlbmQgdGhlIHN0cmVhbSBvZiBkYXRhICd0ZXh0JyB0byB0aGUgQiBieXRlIHN0aW5nIHJlc3VsdGluZyBmcm9tIHN0ZXAgMgogICAgLy8gZmlyc3QgcGFydCBvZiBzdHJlYW0gKDY0IGJ5dGVzKSBpcyBpcGFkLCBzZWNvbmQgcGFydCBvZiBzdHJlYW0gKDY0IGJ5dGVzKSBpcyBidWYKIAogICAgLy8gc3RlcCA0OiBhcHBseSBIIHRvIHRoZSBzdHJlYW0gKGlwYWQgJiBidWYpIGdlbmVyYXRlZCBpbiBzdGVwIDMKICAgIEdFVF9XT1JEXzMyX0JFKFdbIDBdLCBpcGFkLCAgMCk7CiAgICBHRVRfV09SRF8zMl9CRShXWyAxXSwgaXBhZCwgIDQpOwogICAgR0VUX1dPUkRfMzJfQkUoV1sgMl0sIGlwYWQsICA4KTsKICAgIEdFVF9XT1JEXzMyX0JFKFdbIDNdLCBpcGFkLCAxMik7CiAgICBHRVRfV09SRF8zMl9CRShXWyA0XSwgaXBhZCwgMTYpOwogICAgR0VUX1dPUkRfMzJfQkUoV1sgNV0sIGlwYWQsIDIwKTsKICAgIEdFVF9XT1JEXzMyX0JFKFdbIDZdLCBpcGFkLCAyNCk7CiAgICBHRVRfV09SRF8zMl9CRShXWyA3XSwgaXBhZCwgMjgpOwogICAgR0VUX1dPUkRfMzJfQkUoV1sgOF0sIGlwYWQsIDMyKTsKICAgIEdFVF9XT1JEXzMyX0JFKFdbIDldLCBpcGFkLCAzNik7CiAgICBHRVRfV09SRF8zMl9CRShXWzEwXSwgaXBhZCwgNDApOwogICAgR0VUX1dPUkRfMzJfQkUoV1sxMV0sIGlwYWQsIDQ0KTsKICAgIEdFVF9XT1JEXzMyX0JFKFdbMTJdLCBpcGFkLCA0OCk7CiAgICBHRVRfV09SRF8zMl9CRShXWzEzXSwgaXBhZCwgNTIpOwogICAgR0VUX1dPUkRfMzJfQkUoV1sxNF0sIGlwYWQsIDU2KTsKICAgIEdFVF9XT1JEXzMyX0JFKFdbMTVdLCBpcGFkLCA2MCk7CiAKICAgIEEgPSBJTklUX1NIQTFfQTsKICAgIEIgPSBJTklUX1NIQTFfQjsKICAgIEMgPSBJTklUX1NIQTFfQzsKICAgIEQgPSBJTklUX1NIQTFfRDsKICAgIEUgPSBJTklUX1NIQTFfRTsKIAojZGVmaW5lIEYoeCx5LHopICh6IF4gKHggJiAoeSBeIHopKSkKI2RlZmluZSBLIDB4NUE4Mjc5OTkKIAogICAgUChBLCBCLCBDLCBELCBFLCBXWzBdICk7CiAgICBQKEUsIEEsIEIsIEMsIEQsIFdbMV0gKTsKICAgIFAoRCwgRSwgQSwgQiwgQywgV1syXSApOwogICAgUChDLCBELCBFLCBBLCBCLCBXWzNdICk7CiAgICBQKEIsIEMsIEQsIEUsIEEsIFdbNF0gKTsKICAgIFAoQSwgQiwgQywgRCwgRSwgV1s1XSApOwogICAgUChFLCBBLCBCLCBDLCBELCBXWzZdICk7CiAgICBQKEQsIEUsIEEsIEIsIEMsIFdbN10gKTsKICAgIFAoQywgRCwgRSwgQSwgQiwgV1s4XSApOwogICAgUChCLCBDLCBELCBFLCBBLCBXWzldICk7CiAgICBQKEEsIEIsIEMsIEQsIEUsIFdbMTBdKTsKICAgIFAoRSwgQSwgQiwgQywgRCwgV1sxMV0pOwogICAgUChELCBFLCBBLCBCLCBDLCBXWzEyXSk7CiAgICBQKEMsIEQsIEUsIEEsIEIsIFdbMTNdKTsKICAgIFAoQiwgQywgRCwgRSwgQSwgV1sxNF0pOwogICAgUChBLCBCLCBDLCBELCBFLCBXWzE1XSk7CiAgICBQKEUsIEEsIEIsIEMsIEQsIFIoMTYpKTsKICAgIFAoRCwgRSwgQSwgQiwgQywgUigxNykpOwogICAgUChDLCBELCBFLCBBLCBCLCBSKDE4KSk7CiAgICBQKEIsIEMsIEQsIEUsIEEsIFIoMTkpKTsKIAojdW5kZWYgSwojdW5kZWYgRgogCiNkZWZpbmUgRih4LHkseikgKHggXiB5IF4geikKI2RlZmluZSBLIDB4NkVEOUVCQTEKIAogICAgUChBLCBCLCBDLCBELCBFLCBSKDIwKSk7CiAgICBQKEUsIEEsIEIsIEMsIEQsIFIoMjEpKTsKICAgIFAoRCwgRSwgQSwgQiwgQywgUigyMikpOwogICAgUChDLCBELCBFLCBBLCBCLCBSKDIzKSk7CiAgICBQKEIsIEMsIEQsIEUsIEEsIFIoMjQpKTsKICAgIFAoQSwgQiwgQywgRCwgRSwgUigyNSkpOwogICAgUChFLCBBLCBCLCBDLCBELCBSKDI2KSk7CiAgICBQKEQsIEUsIEEsIEIsIEMsIFIoMjcpKTsKICAgIFAoQywgRCwgRSwgQSwgQiwgUigyOCkpOwogICAgUChCLCBDLCBELCBFLCBBLCBSKDI5KSk7CiAgICBQKEEsIEIsIEMsIEQsIEUsIFIoMzApKTsKICAgIFAoRSwgQSwgQiwgQywgRCwgUigzMSkpOwogICAgUChELCBFLCBBLCBCLCBDLCBSKDMyKSk7CiAgICBQKEMsIEQsIEUsIEEsIEIsIFIoMzMpKTsKICAgIFAoQiwgQywgRCwgRSwgQSwgUigzNCkpOwogICAgUChBLCBCLCBDLCBELCBFLCBSKDM1KSk7CiAgICBQKEUsIEEsIEIsIEMsIEQsIFIoMzYpKTsKICAgIFAoRCwgRSwgQSwgQiwgQywgUigzNykpOwogICAgUChDLCBELCBFLCBBLCBCLCBSKDM4KSk7CiAgICBQKEIsIEMsIEQsIEUsIEEsIFIoMzkpKTsKIAojdW5kZWYgSwojdW5kZWYgRgogCiNkZWZpbmUgRih4LHkseikgKCh4ICYgeSkgfCAoeiAmICh4IHwgeSkpKQojZGVmaW5lIEsgMHg4RjFCQkNEQwogCiAgICBQKEEsIEIsIEMsIEQsIEUsIFIoNDApKTsKICAgIFAoRSwgQSwgQiwgQywgRCwgUig0MSkpOwogICAgUChELCBFLCBBLCBCLCBDLCBSKDQyKSk7CiAgICBQKEMsIEQsIEUsIEEsIEIsIFIoNDMpKTsKICAgIFAoQiwgQywgRCwgRSwgQSwgUig0NCkpOwogICAgUChBLCBCLCBDLCBELCBFLCBSKDQ1KSk7CiAgICBQKEUsIEEsIEIsIEMsIEQsIFIoNDYpKTsKICAgIFAoRCwgRSwgQSwgQiwgQywgUig0NykpOwogICAgUChDLCBELCBFLCBBLCBCLCBSKDQ4KSk7CiAgICBQKEIsIEMsIEQsIEUsIEEsIFIoNDkpKTsKICAgIFAoQSwgQiwgQywgRCwgRSwgUig1MCkpOwogICAgUChFLCBBLCBCLCBDLCBELCBSKDUxKSk7CiAgICBQKEQsIEUsIEEsIEIsIEMsIFIoNTIpKTsKICAgIFAoQywgRCwgRSwgQSwgQiwgUig1MykpOwogICAgUChCLCBDLCBELCBFLCBBLCBSKDU0KSk7CiAgICBQKEEsIEIsIEMsIEQsIEUsIFIoNTUpKTsKICAgIFAoRSwgQSwgQiwgQywgRCwgUig1NikpOwogICAgUChELCBFLCBBLCBCLCBDLCBSKDU3KSk7CiAgICBQKEMsIEQsIEUsIEEsIEIsIFIoNTgpKTsKICAgIFAoQiwgQywgRCwgRSwgQSwgUig1OSkpOwogCiN1bmRlZiBLCiN1bmRlZiBGCiAKI2RlZmluZSBGKHgseSx6KSAoeCBeIHkgXiB6KQojZGVmaW5lIEsgMHhDQTYyQzFENgogCiAgICBQKEEsIEIsIEMsIEQsIEUsIFIoNjApKTsKICAgIFAoRSwgQSwgQiwgQywgRCwgUig2MSkpOwogICAgUChELCBFLCBBLCBCLCBDLCBSKDYyKSk7CiAgICBQKEMsIEQsIEUsIEEsIEIsIFIoNjMpKTsKICAgIFAoQiwgQywgRCwgRSwgQSwgUig2NCkpOwogICAgUChBLCBCLCBDLCBELCBFLCBSKDY1KSk7CiAgICBQKEUsIEEsIEIsIEMsIEQsIFIoNjYpKTsKICAgIFAoRCwgRSwgQSwgQiwgQywgUig2NykpOwogICAgUChDLCBELCBFLCBBLCBCLCBSKDY4KSk7CiAgICBQKEIsIEMsIEQsIEUsIEEsIFIoNjkpKTsKICAgIFAoQSwgQiwgQywgRCwgRSwgUig3MCkpOwogICAgUChFLCBBLCBCLCBDLCBELCBSKDcxKSk7CiAgICBQKEQsIEUsIEEsIEIsIEMsIFIoNzIpKTsKICAgIFAoQywgRCwgRSwgQSwgQiwgUig3MykpOwogICAgUChCLCBDLCBELCBFLCBBLCBSKDc0KSk7CiAgICBQKEEsIEIsIEMsIEQsIEUsIFIoNzUpKTsKICAgIFAoRSwgQSwgQiwgQywgRCwgUig3NikpOwogICAgUChELCBFLCBBLCBCLCBDLCBSKDc3KSk7CiAgICBQKEMsIEQsIEUsIEEsIEIsIFIoNzgpKTsKICAgIFAoQiwgQywgRCwgRSwgQSwgUig3OSkpOwogCiN1bmRlZiBLCiN1bmRlZiBGCiAKICAgIEEgKz0gSU5JVF9TSEExX0E7CiAgICBCICs9IElOSVRfU0hBMV9COwogICAgQyArPSBJTklUX1NIQTFfQzsKICAgIEQgKz0gSU5JVF9TSEExX0Q7CiAgICBFICs9IElOSVRfU0hBMV9FOwogCiAgICBzdGF0ZVswXSA9IEE7CiAgICBzdGF0ZVsxXSA9IEI7CiAgICBzdGF0ZVsyXSA9IEM7CiAgICBzdGF0ZVszXSA9IEQ7CiAgICBzdGF0ZVs0XSA9IEU7CiAKICAgIC8vIHByb2Nlc3MgYnVmICgybmQgcGFydCBvZiBzdHJlYW0pCiAgICBHRVRfV09SRF8zMl9CRShXWyAwXSwgYnVmLCAgMCk7CiAgICBHRVRfV09SRF8zMl9CRShXWyAxXSwgYnVmLCAgNCk7CiAgICBHRVRfV09SRF8zMl9CRShXWyAyXSwgYnVmLCAgOCk7CiAgICBHRVRfV09SRF8zMl9CRShXWyAzXSwgYnVmLCAxMik7CiAgICBHRVRfV09SRF8zMl9CRShXWyA0XSwgYnVmLCAxNik7CiAgICBHRVRfV09SRF8zMl9CRShXWyA1XSwgYnVmLCAyMCk7CiAgICBHRVRfV09SRF8zMl9CRShXWyA2XSwgYnVmLCAyNCk7CiAgICBHRVRfV09SRF8zMl9CRShXWyA3XSwgYnVmLCAyOCk7CiAgICBHRVRfV09SRF8zMl9CRShXWyA4XSwgYnVmLCAzMik7CiAgICBHRVRfV09SRF8zMl9CRShXWyA5XSwgYnVmLCAzNik7CiAgICBHRVRfV09SRF8zMl9CRShXWzEwXSwgYnVmLCA0MCk7CiAgICBHRVRfV09SRF8zMl9CRShXWzExXSwgYnVmLCA0NCk7CiAgICBHRVRfV09SRF8zMl9CRShXWzEyXSwgYnVmLCA0OCk7CiAgICBHRVRfV09SRF8zMl9CRShXWzEzXSwgYnVmLCA1Mik7CiAgICBHRVRfV09SRF8zMl9CRShXWzE0XSwgYnVmLCA1Nik7CiAgICBHRVRfV09SRF8zMl9CRShXWzE1XSwgYnVmLCA2MCk7CiAKI2RlZmluZSBGKHgseSx6KSAoeiBeICh4ICYgKHkgXiB6KSkpCiNkZWZpbmUgSyAweDVBODI3OTk5CiAKICAgIFAoQSwgQiwgQywgRCwgRSwgV1swXSApOwogICAgUChFLCBBLCBCLCBDLCBELCBXWzFdICk7CiAgICBQKEQsIEUsIEEsIEIsIEMsIFdbMl0gKTsKICAgIFAoQywgRCwgRSwgQSwgQiwgV1szXSApOwogICAgUChCLCBDLCBELCBFLCBBLCBXWzRdICk7CiAgICBQKEEsIEIsIEMsIEQsIEUsIFdbNV0gKTsKICAgIFAoRSwgQSwgQiwgQywgRCwgV1s2XSApOwogICAgUChELCBFLCBBLCBCLCBDLCBXWzddICk7CiAgICBQKEMsIEQsIEUsIEEsIEIsIFdbOF0gKTsKICAgIFAoQiwgQywgRCwgRSwgQSwgV1s5XSApOwogICAgUChBLCBCLCBDLCBELCBFLCBXWzEwXSk7CiAgICBQKEUsIEEsIEIsIEMsIEQsIFdbMTFdKTsKICAgIFAoRCwgRSwgQSwgQiwgQywgV1sxMl0pOwogICAgUChDLCBELCBFLCBBLCBCLCBXWzEzXSk7CiAgICBQKEIsIEMsIEQsIEUsIEEsIFdbMTRdKTsKICAgIFAoQSwgQiwgQywgRCwgRSwgV1sxNV0pOwogICAgUChFLCBBLCBCLCBDLCBELCBSKDE2KSk7CiAgICBQKEQsIEUsIEEsIEIsIEMsIFIoMTcpKTsKICAgIFAoQywgRCwgRSwgQSwgQiwgUigxOCkpOwogICAgUChCLCBDLCBELCBFLCBBLCBSKDE5KSk7CiAKI3VuZGVmIEsKI3VuZGVmIEYKIAojZGVmaW5lIEYoeCx5LHopICh4IF4geSBeIHopCiNkZWZpbmUgSyAweDZFRDlFQkExCiAKICAgIFAoQSwgQiwgQywgRCwgRSwgUigyMCkpOwogICAgUChFLCBBLCBCLCBDLCBELCBSKDIxKSk7CiAgICBQKEQsIEUsIEEsIEIsIEMsIFIoMjIpKTsKICAgIFAoQywgRCwgRSwgQSwgQiwgUigyMykpOwogICAgUChCLCBDLCBELCBFLCBBLCBSKDI0KSk7CiAgICBQKEEsIEIsIEMsIEQsIEUsIFIoMjUpKTsKICAgIFAoRSwgQSwgQiwgQywgRCwgUigyNikpOwogICAgUChELCBFLCBBLCBCLCBDLCBSKDI3KSk7CiAgICBQKEMsIEQsIEUsIEEsIEIsIFIoMjgpKTsKICAgIFAoQiwgQywgRCwgRSwgQSwgUigyOSkpOwogICAgUChBLCBCLCBDLCBELCBFLCBSKDMwKSk7CiAgICBQKEUsIEEsIEIsIEMsIEQsIFIoMzEpKTsKICAgIFAoRCwgRSwgQSwgQiwgQywgUigzMikpOwogICAgUChDLCBELCBFLCBBLCBCLCBSKDMzKSk7CiAgICBQKEIsIEMsIEQsIEUsIEEsIFIoMzQpKTsKICAgIFAoQSwgQiwgQywgRCwgRSwgUigzNSkpOwogICAgUChFLCBBLCBCLCBDLCBELCBSKDM2KSk7CiAgICBQKEQsIEUsIEEsIEIsIEMsIFIoMzcpKTsKICAgIFAoQywgRCwgRSwgQSwgQiwgUigzOCkpOwogICAgUChCLCBDLCBELCBFLCBBLCBSKDM5KSk7CiAKI3VuZGVmIEsKI3VuZGVmIEYKIAojZGVmaW5lIEYoeCx5LHopICgoeCAmIHkpIHwgKHogJiAoeCB8IHkpKSkKI2RlZmluZSBLIDB4OEYxQkJDREMKIAogICAgUChBLCBCLCBDLCBELCBFLCBSKDQwKSk7CiAgICBQKEUsIEEsIEIsIEMsIEQsIFIoNDEpKTsKICAgIFAoRCwgRSwgQSwgQiwgQywgUig0MikpOwogICAgUChDLCBELCBFLCBBLCBCLCBSKDQzKSk7CiAgICBQKEIsIEMsIEQsIEUsIEEsIFIoNDQpKTsKICAgIFAoQSwgQiwgQywgRCwgRSwgUig0NSkpOwogICAgUChFLCBBLCBCLCBDLCBELCBSKDQ2KSk7CiAgICBQKEQsIEUsIEEsIEIsIEMsIFIoNDcpKTsKICAgIFAoQywgRCwgRSwgQSwgQiwgUig0OCkpOwogICAgUChCLCBDLCBELCBFLCBBLCBSKDQ5KSk7CiAgICBQKEEsIEIsIEMsIEQsIEUsIFIoNTApKTsKICAgIFAoRSwgQSwgQiwgQywgRCwgUig1MSkpOwogICAgUChELCBFLCBBLCBCLCBDLCBSKDUyKSk7CiAgICBQKEMsIEQsIEUsIEEsIEIsIFIoNTMpKTsKICAgIFAoQiwgQywgRCwgRSwgQSwgUig1NCkpOwogICAgUChBLCBCLCBDLCBELCBFLCBSKDU1KSk7CiAgICBQKEUsIEEsIEIsIEMsIEQsIFIoNTYpKTsKICAgIFAoRCwgRSwgQSwgQiwgQywgUig1NykpOwogICAgUChDLCBELCBFLCBBLCBCLCBSKDU4KSk7CiAgICBQKEIsIEMsIEQsIEUsIEEsIFIoNTkpKTsKIAojdW5kZWYgSwojdW5kZWYgRgogCiNkZWZpbmUgRih4LHkseikgKHggXiB5IF4geikKI2RlZmluZSBLIDB4Q0E2MkMxRDYKIAogICAgUChBLCBCLCBDLCBELCBFLCBSKDYwKSk7CiAgICBQKEUsIEEsIEIsIEMsIEQsIFIoNjEpKTsKICAgIFAoRCwgRSwgQSwgQiwgQywgUig2MikpOwogICAgUChDLCBELCBFLCBBLCBCLCBSKDYzKSk7CiAgICBQKEIsIEMsIEQsIEUsIEEsIFIoNjQpKTsKICAgIFAoQSwgQiwgQywgRCwgRSwgUig2NSkpOwogICAgUChFLCBBLCBCLCBDLCBELCBSKDY2KSk7CiAgICBQKEQsIEUsIEEsIEIsIEMsIFIoNjcpKTsKICAgIFAoQywgRCwgRSwgQSwgQiwgUig2OCkpOwogICAgUChCLCBDLCBELCBFLCBBLCBSKDY5KSk7CiAgICBQKEEsIEIsIEMsIEQsIEUsIFIoNzApKTsKICAgIFAoRSwgQSwgQiwgQywgRCwgUig3MSkpOwogICAgUChELCBFLCBBLCBCLCBDLCBSKDcyKSk7CiAgICBQKEMsIEQsIEUsIEEsIEIsIFIoNzMpKTsKICAgIFAoQiwgQywgRCwgRSwgQSwgUig3NCkpOwogICAgUChBLCBCLCBDLCBELCBFLCBSKDc1KSk7CiAgICBQKEUsIEEsIEIsIEMsIEQsIFIoNzYpKTsKICAgIFAoRCwgRSwgQSwgQiwgQywgUig3NykpOwogICAgUChDLCBELCBFLCBBLCBCLCBSKDc4KSk7CiAgICBQKEIsIEMsIEQsIEUsIEEsIFIoNzkpKTsKIAojdW5kZWYgSwojdW5kZWYgRgogCiAgICBBICs9IHN0YXRlWzBdOwogICAgQiArPSBzdGF0ZVsxXTsKICAgIEMgKz0gc3RhdGVbMl07CiAgICBEICs9IHN0YXRlWzNdOwogICAgRSArPSBzdGF0ZVs0XTsKIAogICAgUFVUX1dPUkRfMzJfQkUoQSwgYnVmLCAgMCk7CiAgICBQVVRfV09SRF8zMl9CRShCLCBidWYsICA0KTsKICAgIFBVVF9XT1JEXzMyX0JFKEMsIGJ1ZiwgIDgpOwogICAgUFVUX1dPUkRfMzJfQkUoRCwgYnVmLCAxMik7CiAgICBQVVRfV09SRF8zMl9CRShFLCBidWYsIDE2KTsKIAogICAgYnVmWzIwXSA9IDB4ODA7CiAgICBQVVRfV09SRF8zMl9CRSgweDJBMCwgYnVmLCA2MCk7CiAKICAgIC8vIHN0ZXAgNjogYXBwZW5kIHRoZSBzdHJlYW0gb2YgZGF0YSAndGV4dCcgdG8gdGhlIEIgYnl0ZSBzdGluZyByZXN1bHRpbmcgZnJvbSBzdGVwIDIKICAgIC8vIGZpcnN0IHBhcnQgb2Ygc3RyZWFtICg2NCBieXRlcykgaXMgb3BhZCwgc2Vjb25kIHBhcnQgb2Ygc3RyZWFtICg2NCBieXRlcykgaXMgdGhlIEggcmVzdWx0IGZyb20gc3RlcCA0CiAKICAgIC8vIHN0ZXAgNzogYXBwbHkgSCB0byB0aGUgc3RyZWFtIChvcGFkICYgYnVmKSBnZW5lcmF0ZWQgaW4gc3RlcCA2IGFuZCBvdXRwdXQgdGhlIHJlc3VsdAogICAgR0VUX1dPUkRfMzJfQkUoV1sgMF0sIG9wYWQsICAwKTsKICAgIEdFVF9XT1JEXzMyX0JFKFdbIDFdLCBvcGFkLCAgNCk7CiAgICBHRVRfV09SRF8zMl9CRShXWyAyXSwgb3BhZCwgIDgpOwogICAgR0VUX1dPUkRfMzJfQkUoV1sgM10sIG9wYWQsIDEyKTsKICAgIEdFVF9XT1JEXzMyX0JFKFdbIDRdLCBvcGFkLCAxNik7CiAgICBHRVRfV09SRF8zMl9CRShXWyA1XSwgb3BhZCwgMjApOwogICAgR0VUX1dPUkRfMzJfQkUoV1sgNl0sIG9wYWQsIDI0KTsKICAgIEdFVF9XT1JEXzMyX0JFKFdbIDddLCBvcGFkLCAyOCk7CiAgICBHRVRfV09SRF8zMl9CRShXWyA4XSwgb3BhZCwgMzIpOwogICAgR0VUX1dPUkRfMzJfQkUoV1sgOV0sIG9wYWQsIDM2KTsKICAgIEdFVF9XT1JEXzMyX0JFKFdbMTBdLCBvcGFkLCA0MCk7CiAgICBHRVRfV09SRF8zMl9CRShXWzExXSwgb3BhZCwgNDQpOwogICAgR0VUX1dPUkRfMzJfQkUoV1sxMl0sIG9wYWQsIDQ4KTsKICAgIEdFVF9XT1JEXzMyX0JFKFdbMTNdLCBvcGFkLCA1Mik7CiAgICBHRVRfV09SRF8zMl9CRShXWzE0XSwgb3BhZCwgNTYpOwogICAgR0VUX1dPUkRfMzJfQkUoV1sxNV0sIG9wYWQsIDYwKTsKIAogICAgQSA9IElOSVRfU0hBMV9BOwogICAgQiA9IElOSVRfU0hBMV9COwogICAgQyA9IElOSVRfU0hBMV9DOwogICAgRCA9IElOSVRfU0hBMV9EOwogICAgRSA9IElOSVRfU0hBMV9FOwogCiNkZWZpbmUgRih4LHkseikgKHogXiAoeCAmICh5IF4geikpKQojZGVmaW5lIEsgMHg1QTgyNzk5OQogCiAgICBQKEEsIEIsIEMsIEQsIEUsIFdbMF0gKTsKICAgIFAoRSwgQSwgQiwgQywgRCwgV1sxXSApOwogICAgUChELCBFLCBBLCBCLCBDLCBXWzJdICk7CiAgICBQKEMsIEQsIEUsIEEsIEIsIFdbM10gKTsKICAgIFAoQiwgQywgRCwgRSwgQSwgV1s0XSApOwogICAgUChBLCBCLCBDLCBELCBFLCBXWzVdICk7CiAgICBQKEUsIEEsIEIsIEMsIEQsIFdbNl0gKTsKICAgIFAoRCwgRSwgQSwgQiwgQywgV1s3XSApOwogICAgUChDLCBELCBFLCBBLCBCLCBXWzhdICk7CiAgICBQKEIsIEMsIEQsIEUsIEEsIFdbOV0gKTsKICAgIFAoQSwgQiwgQywgRCwgRSwgV1sxMF0pOwogICAgUChFLCBBLCBCLCBDLCBELCBXWzExXSk7CiAgICBQKEQsIEUsIEEsIEIsIEMsIFdbMTJdKTsKICAgIFAoQywgRCwgRSwgQSwgQiwgV1sxM10pOwogICAgUChCLCBDLCBELCBFLCBBLCBXWzE0XSk7CiAgICBQKEEsIEIsIEMsIEQsIEUsIFdbMTVdKTsKICAgIFAoRSwgQSwgQiwgQywgRCwgUigxNikpOwogICAgUChELCBFLCBBLCBCLCBDLCBSKDE3KSk7CiAgICBQKEMsIEQsIEUsIEEsIEIsIFIoMTgpKTsKICAgIFAoQiwgQywgRCwgRSwgQSwgUigxOSkpOwogCiN1bmRlZiBLCiN1bmRlZiBGCiAKI2RlZmluZSBGKHgseSx6KSAoeCBeIHkgXiB6KQojZGVmaW5lIEsgMHg2RUQ5RUJBMQogCiAgICBQKEEsIEIsIEMsIEQsIEUsIFIoMjApKTsKICAgIFAoRSwgQSwgQiwgQywgRCwgUigyMSkpOwogICAgUChELCBFLCBBLCBCLCBDLCBSKDIyKSk7CiAgICBQKEMsIEQsIEUsIEEsIEIsIFIoMjMpKTsKICAgIFAoQiwgQywgRCwgRSwgQSwgUigyNCkpOwogICAgUChBLCBCLCBDLCBELCBFLCBSKDI1KSk7CiAgICBQKEUsIEEsIEIsIEMsIEQsIFIoMjYpKTsKICAgIFAoRCwgRSwgQSwgQiwgQywgUigyNykpOwogICAgUChDLCBELCBFLCBBLCBCLCBSKDI4KSk7CiAgICBQKEIsIEMsIEQsIEUsIEEsIFIoMjkpKTsKICAgIFAoQSwgQiwgQywgRCwgRSwgUigzMCkpOwogICAgUChFLCBBLCBCLCBDLCBELCBSKDMxKSk7CiAgICBQKEQsIEUsIEEsIEIsIEMsIFIoMzIpKTsKICAgIFAoQywgRCwgRSwgQSwgQiwgUigzMykpOwogICAgUChCLCBDLCBELCBFLCBBLCBSKDM0KSk7CiAgICBQKEEsIEIsIEMsIEQsIEUsIFIoMzUpKTsKICAgIFAoRSwgQSwgQiwgQywgRCwgUigzNikpOwogICAgUChELCBFLCBBLCBCLCBDLCBSKDM3KSk7CiAgICBQKEMsIEQsIEUsIEEsIEIsIFIoMzgpKTsKICAgIFAoQiwgQywgRCwgRSwgQSwgUigzOSkpOwogCiN1bmRlZiBLCiN1bmRlZiBGCiAKI2RlZmluZSBGKHgseSx6KSAoKHggJiB5KSB8ICh6ICYgKHggfCB5KSkpCiNkZWZpbmUgSyAweDhGMUJCQ0RDCiAKICAgIFAoQSwgQiwgQywgRCwgRSwgUig0MCkpOwogICAgUChFLCBBLCBCLCBDLCBELCBSKDQxKSk7CiAgICBQKEQsIEUsIEEsIEIsIEMsIFIoNDIpKTsKICAgIFAoQywgRCwgRSwgQSwgQiwgUig0MykpOwogICAgUChCLCBDLCBELCBFLCBBLCBSKDQ0KSk7CiAgICBQKEEsIEIsIEMsIEQsIEUsIFIoNDUpKTsKICAgIFAoRSwgQSwgQiwgQywgRCwgUig0NikpOwogICAgUChELCBFLCBBLCBCLCBDLCBSKDQ3KSk7CiAgICBQKEMsIEQsIEUsIEEsIEIsIFIoNDgpKTsKICAgIFAoQiwgQywgRCwgRSwgQSwgUig0OSkpOwogICAgUChBLCBCLCBDLCBELCBFLCBSKDUwKSk7CiAgICBQKEUsIEEsIEIsIEMsIEQsIFIoNTEpKTsKICAgIFAoRCwgRSwgQSwgQiwgQywgUig1MikpOwogICAgUChDLCBELCBFLCBBLCBCLCBSKDUzKSk7CiAgICBQKEIsIEMsIEQsIEUsIEEsIFIoNTQpKTsKICAgIFAoQSwgQiwgQywgRCwgRSwgUig1NSkpOwogICAgUChFLCBBLCBCLCBDLCBELCBSKDU2KSk7CiAgICBQKEQsIEUsIEEsIEIsIEMsIFIoNTcpKTsKICAgIFAoQywgRCwgRSwgQSwgQiwgUig1OCkpOwogICAgUChCLCBDLCBELCBFLCBBLCBSKDU5KSk7CiAKI3VuZGVmIEsKI3VuZGVmIEYKIAojZGVmaW5lIEYoeCx5LHopICh4IF4geSBeIHopCiNkZWZpbmUgSyAweENBNjJDMUQ2CiAKICAgIFAoQSwgQiwgQywgRCwgRSwgUig2MCkpOwogICAgUChFLCBBLCBCLCBDLCBELCBSKDYxKSk7CiAgICBQKEQsIEUsIEEsIEIsIEMsIFIoNjIpKTsKICAgIFAoQywgRCwgRSwgQSwgQiwgUig2MykpOwogICAgUChCLCBDLCBELCBFLCBBLCBSKDY0KSk7CiAgICBQKEEsIEIsIEMsIEQsIEUsIFIoNjUpKTsKICAgIFAoRSwgQSwgQiwgQywgRCwgUig2NikpOwogICAgUChELCBFLCBBLCBCLCBDLCBSKDY3KSk7CiAgICBQKEMsIEQsIEUsIEEsIEIsIFIoNjgpKTsKICAgIFAoQiwgQywgRCwgRSwgQSwgUig2OSkpOwogICAgUChBLCBCLCBDLCBELCBFLCBSKDcwKSk7CiAgICBQKEUsIEEsIEIsIEMsIEQsIFIoNzEpKTsKICAgIFAoRCwgRSwgQSwgQiwgQywgUig3MikpOwogICAgUChDLCBELCBFLCBBLCBCLCBSKDczKSk7CiAgICBQKEIsIEMsIEQsIEUsIEEsIFIoNzQpKTsKICAgIFAoQSwgQiwgQywgRCwgRSwgUig3NSkpOwogICAgUChFLCBBLCBCLCBDLCBELCBSKDc2KSk7CiAgICBQKEQsIEUsIEEsIEIsIEMsIFIoNzcpKTsKICAgIFAoQywgRCwgRSwgQSwgQiwgUig3OCkpOwogICAgUChCLCBDLCBELCBFLCBBLCBSKDc5KSk7CiAKI3VuZGVmIEsKI3VuZGVmIEYKIAogICAgQSArPSBJTklUX1NIQTFfQTsKICAgIEIgKz0gSU5JVF9TSEExX0I7CiAgICBDICs9IElOSVRfU0hBMV9DOwogICAgRCArPSBJTklUX1NIQTFfRDsKICAgIEUgKz0gSU5JVF9TSEExX0U7CiAKICAgIC8vIHN0b3JlIHN0YXRlIGZvciAybmQgcGFydAogICAgc3RhdGVbMF0gPSBBOwogICAgc3RhdGVbMV0gPSBCOwogICAgc3RhdGVbMl0gPSBDOwogICAgc3RhdGVbM10gPSBEOwogICAgc3RhdGVbNF0gPSBFOwogCiAgICBHRVRfV09SRF8zMl9CRShXWyAwXSwgYnVmLCAgMCk7CiAgICBHRVRfV09SRF8zMl9CRShXWyAxXSwgYnVmLCAgNCk7CiAgICBHRVRfV09SRF8zMl9CRShXWyAyXSwgYnVmLCAgOCk7CiAgICBHRVRfV09SRF8zMl9CRShXWyAzXSwgYnVmLCAxMik7CiAgICBHRVRfV09SRF8zMl9CRShXWyA0XSwgYnVmLCAxNik7CiAgICBHRVRfV09SRF8zMl9CRShXWyA1XSwgYnVmLCAyMCk7CiAgICBHRVRfV09SRF8zMl9CRShXWyA2XSwgYnVmLCAyNCk7CiAgICBHRVRfV09SRF8zMl9CRShXWyA3XSwgYnVmLCAyOCk7CiAgICBHRVRfV09SRF8zMl9CRShXWyA4XSwgYnVmLCAzMik7CiAgICBHRVRfV09SRF8zMl9CRShXWyA5XSwgYnVmLCAzNik7CiAgICBHRVRfV09SRF8zMl9CRShXWzEwXSwgYnVmLCA0MCk7CiAgICBHRVRfV09SRF8zMl9CRShXWzExXSwgYnVmLCA0NCk7CiAgICBHRVRfV09SRF8zMl9CRShXWzEyXSwgYnVmLCA0OCk7CiAgICBHRVRfV09SRF8zMl9CRShXWzEzXSwgYnVmLCA1Mik7CiAgICBHRVRfV09SRF8zMl9CRShXWzE0XSwgYnVmLCA1Nik7CiAgICBHRVRfV09SRF8zMl9CRShXWzE1XSwgYnVmLCA2MCk7CiAKI2RlZmluZSBGKHgseSx6KSAoeiBeICh4ICYgKHkgXiB6KSkpCiNkZWZpbmUgSyAweDVBODI3OTk5CiAKICAgIFAoQSwgQiwgQywgRCwgRSwgV1swXSApOwogICAgUChFLCBBLCBCLCBDLCBELCBXWzFdICk7CiAgICBQKEQsIEUsIEEsIEIsIEMsIFdbMl0gKTsKICAgIFAoQywgRCwgRSwgQSwgQiwgV1szXSApOwogICAgUChCLCBDLCBELCBFLCBBLCBXWzRdICk7CiAgICBQKEEsIEIsIEMsIEQsIEUsIFdbNV0gKTsKICAgIFAoRSwgQSwgQiwgQywgRCwgV1s2XSApOwogICAgUChELCBFLCBBLCBCLCBDLCBXWzddICk7CiAgICBQKEMsIEQsIEUsIEEsIEIsIFdbOF0gKTsKICAgIFAoQiwgQywgRCwgRSwgQSwgV1s5XSApOwogICAgUChBLCBCLCBDLCBELCBFLCBXWzEwXSk7CiAgICBQKEUsIEEsIEIsIEMsIEQsIFdbMTFdKTsKICAgIFAoRCwgRSwgQSwgQiwgQywgV1sxMl0pOwogICAgUChDLCBELCBFLCBBLCBCLCBXWzEzXSk7CiAgICBQKEIsIEMsIEQsIEUsIEEsIFdbMTRdKTsKICAgIFAoQSwgQiwgQywgRCwgRSwgV1sxNV0pOwogICAgUChFLCBBLCBCLCBDLCBELCBSKDE2KSk7CiAgICBQKEQsIEUsIEEsIEIsIEMsIFIoMTcpKTsKICAgIFAoQywgRCwgRSwgQSwgQiwgUigxOCkpOwogICAgUChCLCBDLCBELCBFLCBBLCBSKDE5KSk7CiAKI3VuZGVmIEsKI3VuZGVmIEYKIAojZGVmaW5lIEYoeCx5LHopICh4IF4geSBeIHopCiNkZWZpbmUgSyAweDZFRDlFQkExCiAKICAgIFAoQSwgQiwgQywgRCwgRSwgUigyMCkpOwogICAgUChFLCBBLCBCLCBDLCBELCBSKDIxKSk7CiAgICBQKEQsIEUsIEEsIEIsIEMsIFIoMjIpKTsKICAgIFAoQywgRCwgRSwgQSwgQiwgUigyMykpOwogICAgUChCLCBDLCBELCBFLCBBLCBSKDI0KSk7CiAgICBQKEEsIEIsIEMsIEQsIEUsIFIoMjUpKTsKICAgIFAoRSwgQSwgQiwgQywgRCwgUigyNikpOwogICAgUChELCBFLCBBLCBCLCBDLCBSKDI3KSk7CiAgICBQKEMsIEQsIEUsIEEsIEIsIFIoMjgpKTsKICAgIFAoQiwgQywgRCwgRSwgQSwgUigyOSkpOwogICAgUChBLCBCLCBDLCBELCBFLCBSKDMwKSk7CiAgICBQKEUsIEEsIEIsIEMsIEQsIFIoMzEpKTsKICAgIFAoRCwgRSwgQSwgQiwgQywgUigzMikpOwogICAgUChDLCBELCBFLCBBLCBCLCBSKDMzKSk7CiAgICBQKEIsIEMsIEQsIEUsIEEsIFIoMzQpKTsKICAgIFAoQSwgQiwgQywgRCwgRSwgUigzNSkpOwogICAgUChFLCBBLCBCLCBDLCBELCBSKDM2KSk7CiAgICBQKEQsIEUsIEEsIEIsIEMsIFIoMzcpKTsKICAgIFAoQywgRCwgRSwgQSwgQiwgUigzOCkpOwogICAgUChCLCBDLCBELCBFLCBBLCBSKDM5KSk7CiAKI3VuZGVmIEsKI3VuZGVmIEYKIAojZGVmaW5lIEYoeCx5LHopICgoeCAmIHkpIHwgKHogJiAoeCB8IHkpKSkKI2RlZmluZSBLIDB4OEYxQkJDREMKIAogICAgUChBLCBCLCBDLCBELCBFLCBSKDQwKSk7CiAgICBQKEUsIEEsIEIsIEMsIEQsIFIoNDEpKTsKICAgIFAoRCwgRSwgQSwgQiwgQywgUig0MikpOwogICAgUChDLCBELCBFLCBBLCBCLCBSKDQzKSk7CiAgICBQKEIsIEMsIEQsIEUsIEEsIFIoNDQpKTsKICAgIFAoQSwgQiwgQywgRCwgRSwgUig0NSkpOwogICAgUChFLCBBLCBCLCBDLCBELCBSKDQ2KSk7CiAgICBQKEQsIEUsIEEsIEIsIEMsIFIoNDcpKTsKICAgIFAoQywgRCwgRSwgQSwgQiwgUig0OCkpOwogICAgUChCLCBDLCBELCBFLCBBLCBSKDQ5KSk7CiAgICBQKEEsIEIsIEMsIEQsIEUsIFIoNTApKTsKICAgIFAoRSwgQSwgQiwgQywgRCwgUig1MSkpOwogICAgUChELCBFLCBBLCBCLCBDLCBSKDUyKSk7CiAgICBQKEMsIEQsIEUsIEEsIEIsIFIoNTMpKTsKICAgIFAoQiwgQywgRCwgRSwgQSwgUig1NCkpOwogICAgUChBLCBCLCBDLCBELCBFLCBSKDU1KSk7CiAgICBQKEUsIEEsIEIsIEMsIEQsIFIoNTYpKTsKICAgIFAoRCwgRSwgQSwgQiwgQywgUig1NykpOwogICAgUChDLCBELCBFLCBBLCBCLCBSKDU4KSk7CiAgICBQKEIsIEMsIEQsIEUsIEEsIFIoNTkpKTsKIAojdW5kZWYgSwojdW5kZWYgRgogCiNkZWZpbmUgRih4LHkseikgKHggXiB5IF4geikKI2RlZmluZSBLIDB4Q0E2MkMxRDYKIAogICAgUChBLCBCLCBDLCBELCBFLCBSKDYwKSk7CiAgICBQKEUsIEEsIEIsIEMsIEQsIFIoNjEpKTsKICAgIFAoRCwgRSwgQSwgQiwgQywgUig2MikpOwogICAgUChDLCBELCBFLCBBLCBCLCBSKDYzKSk7CiAgICBQKEIsIEMsIEQsIEUsIEEsIFIoNjQpKTsKICAgIFAoQSwgQiwgQywgRCwgRSwgUig2NSkpOwogICAgUChFLCBBLCBCLCBDLCBELCBSKDY2KSk7CiAgICBQKEQsIEUsIEEsIEIsIEMsIFIoNjcpKTsKICAgIFAoQywgRCwgRSwgQSwgQiwgUig2OCkpOwogICAgUChCLCBDLCBELCBFLCBBLCBSKDY5KSk7CiAgICBQKEEsIEIsIEMsIEQsIEUsIFIoNzApKTsKICAgIFAoRSwgQSwgQiwgQywgRCwgUig3MSkpOwogICAgUChELCBFLCBBLCBCLCBDLCBSKDcyKSk7CiAgICBQKEMsIEQsIEUsIEEsIEIsIFIoNzMpKTsKICAgIFAoQiwgQywgRCwgRSwgQSwgUig3NCkpOwogICAgUChBLCBCLCBDLCBELCBFLCBSKDc1KSk7CiAgICBQKEUsIEEsIEIsIEMsIEQsIFIoNzYpKTsKICAgIFAoRCwgRSwgQSwgQiwgQywgUig3NykpOwogICAgUChDLCBELCBFLCBBLCBCLCBSKDc4KSk7CiAgICBQKEIsIEMsIEQsIEUsIEEsIFIoNzkpKTsKIAojdW5kZWYgSwojdW5kZWYgRgogCiAgICBBICs9IHN0YXRlWzBdOwogICAgQiArPSBzdGF0ZVsxXTsKICAgIEMgKz0gc3RhdGVbMl07CiAgICBEICs9IHN0YXRlWzNdOwogICAgRSArPSBzdGF0ZVs0XTsKIAogICAgUFVUX1dPUkRfMzJfQkUoQSwgb3V0cHV0LCAgMCk7CiAgICBQVVRfV09SRF8zMl9CRShCLCBvdXRwdXQsICA0KTsKICAgIFBVVF9XT1JEXzMyX0JFKEMsIG91dHB1dCwgIDgpOwogICAgUFVUX1dPUkRfMzJfQkUoRCwgb3V0cHV0LCAxMik7CiAgICBQVVRfV09SRF8zMl9CRShFLCBvdXRwdXQsIDE2KTsKfQogCiAKLyogUEJLREYyCiAqIHN0cmlwcGVkLWRvd24gaW1wbGVtZW50YXRpb24KICogYmFzZWQgb24gdGhlIHNvdXJjZSBjb2RlIHdyaXR0ZW4gYnkgRHIgU3RlcGhlbiBOIEhlbnNvbiAoc2hlbnNvbkBiaWdmb290LmNvbSkgZm9yIHRoZSBPcGVuU1NMIFByb2plY3QgMTk5OQogKi8Kc3RhdGljIHZvaWQgUEJLREYyX0RDQzIoY29uc3QgdW5zaWduZWQgY2hhciAqcGFzcywgY29uc3QgdW5zaWduZWQgY2hhciAqc2FsdCwgaW50IHNhbHRsZW4sIHVuc2lnbmVkIGNoYXIgKm91dCkKewogICAgdW5zaWduZWQgY2hhciB0ZW1wW1NIQTFfRElHRVNUX0xFTkdUSF07CiAgICB1bnNpZ25lZCBjaGFyIGJ1Zls0OF07CiAgICB1bnNpZ25lZCBpbnQgaTsKIAogICAgbWVtc2V0KGJ1ZiwgMCwgNDgpOwogICAgbWVtY3B5KGJ1Ziwgc2FsdCwgc2FsdGxlbik7CiAgICBidWZbc2FsdGxlbiArIDNdID0gMHgwMTsKIAogICAgaG1hY19zaGExKHBhc3MsIDE2LCBidWYsIHNhbHRsZW4gKyA0LCB0ZW1wKTsKIAogICAgbWVtY3B5KG91dCwgdGVtcCwgMTYpOwogCiAgICBmb3IgKGkgPSAxOyBpIDwgSVRFUkFUSU9OUzsgaSsrKQogICAgewogICAgICAgIGhtYWNfc2hhMShwYXNzLCAxNiwgdGVtcCwgU0hBMV9ESUdFU1RfTEVOR1RILCB0ZW1wKTsKIAogICAgICAgIG91dFsgMF0gXj0gdGVtcFswXTsKICAgICAgICBvdXRbIDFdIF49IHRlbXBbMV07CiAgICAgICAgb3V0WyAyXSBePSB0ZW1wWzJdOwogICAgICAgIG91dFsgM10gXj0gdGVtcFszXTsKICAgICAgICBvdXRbIDRdIF49IHRlbXBbNF07CiAgICAgICAgb3V0WyA1XSBePSB0ZW1wWzVdOwogICAgICAgIG91dFsgNl0gXj0gdGVtcFs2XTsKICAgICAgICBvdXRbIDddIF49IHRlbXBbN107CiAgICAgICAgb3V0WyA4XSBePSB0ZW1wWzhdOwogICAgICAgIG91dFsgOV0gXj0gdGVtcFs5XTsKICAgICAgICBvdXRbMTBdIF49IHRlbXBbMTBdOwogICAgICAgIG91dFsxMV0gXj0gdGVtcFsxMV07CiAgICAgICAgb3V0WzEyXSBePSB0ZW1wWzEyXTsKICAgICAgICBvdXRbMTNdIF49IHRlbXBbMTNdOwogICAgICAgIG91dFsxNF0gXj0gdGVtcFsxNF07CiAgICAgICAgb3V0WzE1XSBePSB0ZW1wWzE1XTsKLy8gICAgICBvdXRbMTZdIF49IHRlbXBbMTZdOyAtIHdhcyBhIGJ1Zz8KICAgIH0KfQogCiAKIAovLyBNRDQgY29tcHJlc3Npb24gZnVuY3Rpb24Kdm9pZCBtZDRfY3J5cHQodW5zaWduZWQgaW50ICpidWZmZXIsIHVuc2lnbmVkIGludCAqaGFzaCkKewogICAgdW5zaWduZWQgaW50IGE7CiAgICB1bnNpZ25lZCBpbnQgYjsKICAgIHVuc2lnbmVkIGludCBjOwogICAgdW5zaWduZWQgaW50IGQ7CiAKICAgIC8vIHJvdW5kIDEKICAgIGEgPSAweEZGRkZGRkZGICArICBidWZmZXJbMF07IGEgPSAoYSA8PCAzICkgfCAoYSA+PiAyOSk7CiAgICBkID0gSU5JVF9NRDRfRCArIChJTklUX01ENF9DIF4gKGEgJiAweDc3Nzc3Nzc3KSkgKyBidWZmZXJbMV07IGQgPSAoZCA8PCA3ICkgfCAoZCA+PiAyNSk7CiAgICBjID0gSU5JVF9NRDRfQyArIChJTklUX01ENF9CIF4gKGQgJiAoYSBeIElOSVRfTUQ0X0IpKSkgKyBidWZmZXJbMl07IGMgPSAoYyA8PCAxMSkgfCAoYyA+PiAyMSk7CiAgICBiID0gSU5JVF9NRDRfQiArIChhIF4gKGMgJiAoZCBeIGEpKSkgKyBidWZmZXJbM107IGIgPSAoYiA8PCAxOSkgfCAoYiA+PiAxMyk7IAogCiAgICBhICs9IChkIF4gKGIgJiAoYyBeIGQpKSkgICsgIGJ1ZmZlcls0XTsgIGEgPSAoYSA8PCAzICkgfCAoYSA+PiAyOSk7CiAgICBkICs9IChjIF4gKGEgJiAoYiBeIGMpKSkgICsgIGJ1ZmZlcls1XTsgIGQgPSAoZCA8PCA3ICkgfCAoZCA+PiAyNSk7CiAgICBjICs9IChiIF4gKGQgJiAoYSBeIGIpKSkgICsgIGJ1ZmZlcls2XTsgIGMgPSAoYyA8PCAxMSkgfCAoYyA+PiAyMSk7CiAgICBiICs9IChhIF4gKGMgJiAoZCBeIGEpKSkgICsgIGJ1ZmZlcls3XTsgIGIgPSAoYiA8PCAxOSkgfCAoYiA+PiAxMyk7CiAKICAgIGEgKz0gKGQgXiAoYiAmIChjIF4gZCkpKSAgKyBidWZmZXJbOF0gOyAgYSA9IChhIDw8IDMgKSB8IChhID4+IDI5KTsKICAgIGQgKz0gKGMgXiAoYSAmIChiIF4gYykpKSAgKyBidWZmZXJbOV0gOyAgZCA9IChkIDw8IDcgKSB8IChkID4+IDI1KTsKICAgIGMgKz0gKGIgXiAoZCAmIChhIF4gYikpKSAgKyBidWZmZXJbMTBdOyAgYyA9IChjIDw8IDExKSB8IChjID4+IDIxKTsKICAgIGIgKz0gKGEgXiAoYyAmIChkIF4gYSkpKSAgKyBidWZmZXJbMTFdOyAgYiA9IChiIDw8IDE5KSB8IChiID4+IDEzKTsKIAogICAgYSArPSAoZCBeIChiICYgKGMgXiBkKSkpICArIGJ1ZmZlclsxMl07IGEgPSAoYSA8PCAzICkgfCAoYSA+PiAyOSk7CiAgICBkICs9IChjIF4gKGEgJiAoYiBeIGMpKSkgICsgYnVmZmVyWzEzXTsgZCA9IChkIDw8IDcgKSB8IChkID4+IDI1KTsKICAgIGMgKz0gKGIgXiAoZCAmIChhIF4gYikpKSAgKyBidWZmZXJbMTRdOyBjID0gKGMgPDwgMTEpIHwgKGMgPj4gMjEpOwogICAgYiArPSAoYSBeIChjICYgKGQgXiBhKSkpICArIGJ1ZmZlclsxNV07IGIgPSAoYiA8PCAxOSkgfCAoYiA+PiAxMyk7CiAKICAgIC8vIHJvdW5kIDIKICAgIGEgKz0gKChiICYgKGMgfCBkKSkgfCAoYyAmIGQpKSArIGJ1ZmZlclswXSAgKyBTUVJUXzI7IGEgPSAoYTw8MyApIHwgKGE+PjI5KTsKICAgIGQgKz0gKChhICYgKGIgfCBjKSkgfCAoYiAmIGMpKSArIGJ1ZmZlcls0XSAgKyBTUVJUXzI7IGQgPSAoZDw8NSApIHwgKGQ+PjI3KTsKICAgIGMgKz0gKChkICYgKGEgfCBiKSkgfCAoYSAmIGIpKSArIGJ1ZmZlcls4XSAgKyBTUVJUXzI7IGMgPSAoYzw8OSApIHwgKGM+PjIzKTsKICAgIGIgKz0gKChjICYgKGQgfCBhKSkgfCAoZCAmIGEpKSArIGJ1ZmZlclsxMl0gKyBTUVJUXzI7IGIgPSAoYjw8MTMpIHwgKGI+PjE5KTsKIAogICAgYSArPSAoKGIgJiAoYyB8IGQpKSB8IChjICYgZCkpICsgYnVmZmVyWzFdICArIFNRUlRfMjsgYSA9IChhPDwzICkgfCAoYT4+MjkpOwogICAgZCArPSAoKGEgJiAoYiB8IGMpKSB8IChiICYgYykpICsgYnVmZmVyWzVdICArIFNRUlRfMjsgZCA9IChkPDw1ICkgfCAoZD4+MjcpOwogICAgYyArPSAoKGQgJiAoYSB8IGIpKSB8IChhICYgYikpICsgYnVmZmVyWzldICArIFNRUlRfMjsgYyA9IChjPDw5ICkgfCAoYz4+MjMpOwogICAgYiArPSAoKGMgJiAoZCB8IGEpKSB8IChkICYgYSkpICsgYnVmZmVyWzEzXSArIFNRUlRfMjsgYiA9IChiPDwxMykgfCAoYj4+MTkpOwogCiAgICBhICs9ICgoYiAmIChjIHwgZCkpIHwgKGMgJiBkKSkgKyBidWZmZXJbMl0gICsgU1FSVF8yOyBhID0gKGE8PDMgKSB8IChhPj4yOSk7CiAgICBkICs9ICgoYSAmIChiIHwgYykpIHwgKGIgJiBjKSkgKyBidWZmZXJbNl0gICsgU1FSVF8yOyBkID0gKGQ8PDUgKSB8IChkPj4yNyk7CiAgICBjICs9ICgoZCAmIChhIHwgYikpIHwgKGEgJiBiKSkgKyBidWZmZXJbMTBdICsgU1FSVF8yOyBjID0gKGM8PDkgKSB8IChjPj4yMyk7CiAgICBiICs9ICgoYyAmIChkIHwgYSkpIHwgKGQgJiBhKSkgKyBidWZmZXJbMTRdICsgU1FSVF8yOyBiID0gKGI8PDEzKSB8IChiPj4xOSk7CiAKICAgIGEgKz0gKChiICYgKGMgfCBkKSkgfCAoYyAmIGQpKSArIGJ1ZmZlclszXSAgKyBTUVJUXzI7IGEgPSAoYTw8MyApIHwgKGE+PjI5KTsKICAgIGQgKz0gKChhICYgKGIgfCBjKSkgfCAoYiAmIGMpKSArIGJ1ZmZlcls3XSAgKyBTUVJUXzI7IGQgPSAoZDw8NSApIHwgKGQ+PjI3KTsKICAgIGMgKz0gKChkICYgKGEgfCBiKSkgfCAoYSAmIGIpKSArIGJ1ZmZlclsxMV0gKyBTUVJUXzI7IGMgPSAoYzw8OSApIHwgKGM+PjIzKTsKICAgIGIgKz0gKChjICYgKGQgfCBhKSkgfCAoZCAmIGEpKSArIGJ1ZmZlclsxNV0gKyBTUVJUXzI7IGIgPSAoYjw8MTMpIHwgKGI+PjE5KTsgICAgICAgICAKIAogICAgLy8gcm91bmQgMwogICAgYSArPSAoZCBeIGMgXiBiKSArIGJ1ZmZlclswXSAgKyAgU1FSVF8zOyBhID0gKGEgPDwgMyApIHwgKGEgPj4gMjkpOwogICAgZCArPSAoYyBeIGIgXiBhKSArIGJ1ZmZlcls4XSAgKyAgU1FSVF8zOyBkID0gKGQgPDwgOSApIHwgKGQgPj4gMjMpOwogICAgYyArPSAoYiBeIGEgXiBkKSArIGJ1ZmZlcls0XSAgKyAgU1FSVF8zOyBjID0gKGMgPDwgMTEpIHwgKGMgPj4gMjEpOwogICAgYiArPSAoYSBeIGQgXiBjKSArIGJ1ZmZlclsxMl0gKyAgU1FSVF8zOyBiID0gKGIgPDwgMTUpIHwgKGIgPj4gMTcpOwogCiAgICBhICs9IChkIF4gYyBeIGIpICsgYnVmZmVyWzJdICArICBTUVJUXzM7IGEgPSAoYSA8PCAzICkgfCAoYSA+PiAyOSk7CiAgICBkICs9IChjIF4gYiBeIGEpICsgYnVmZmVyWzEwXSArICBTUVJUXzM7IGQgPSAoZCA8PCA5ICkgfCAoZCA+PiAyMyk7CiAgICBjICs9IChiIF4gYSBeIGQpICsgYnVmZmVyWzZdICArICBTUVJUXzM7IGMgPSAoYyA8PCAxMSkgfCAoYyA+PiAyMSk7CiAgICBiICs9IChhIF4gZCBeIGMpICsgYnVmZmVyWzE0XSArICBTUVJUXzM7IGIgPSAoYiA8PCAxNSkgfCAoYiA+PiAxNyk7CiAKICAgIGEgKz0gKGQgXiBjIF4gYikgKyBidWZmZXJbMV0gICsgIFNRUlRfMzsgYSA9IChhIDw8IDMgKSB8IChhID4+IDI5KTsKICAgIGQgKz0gKGMgXiBiIF4gYSkgKyBidWZmZXJbOV0gICsgIFNRUlRfMzsgZCA9IChkIDw8IDkgKSB8IChkID4+IDIzKTsKICAgIGMgKz0gKGIgXiBhIF4gZCkgKyBidWZmZXJbNV0gICsgIFNRUlRfMzsgYyA9IChjIDw8IDExKSB8IChjID4+IDIxKTsKICAgIGIgKz0gKGEgXiBkIF4gYykgKyBidWZmZXJbMTNdICsgIFNRUlRfMzsgYiA9IChiIDw8IDE1KSB8IChiID4+IDE3KTsKIAogICAgYSArPSAoZCBeIGMgXiBiKSArIGJ1ZmZlclszXSAgKyAgU1FSVF8zOyBhID0gKGEgPDwgMyApIHwgKGEgPj4gMjkpOwogCiAgICBkICs9IChjIF4gYiBeIGEpICsgYnVmZmVyWzExXSArICBTUVJUXzM7IGQgPSAoZCA8PCA5ICkgfCAoZCA+PiAyMyk7CiAgICBjICs9IChiIF4gYSBeIGQpICsgYnVmZmVyWzddICArICBTUVJUXzM7IGMgPSAoYyA8PCAxMSkgfCAoYyA+PiAyMSk7CiAgICBiICs9IChhIF4gZCBeIGMpICsgYnVmZmVyWzE1XSArICBTUVJUXzM7IGIgPSAoYiA8PCAxNSkgfCAoYiA+PiAxNyk7CiAKICAgIGhhc2hbMF0gPSBhICsgSU5JVF9NRDRfQTsKICAgIGhhc2hbMV0gPSBiICsgSU5JVF9NRDRfQjsKICAgIGhhc2hbMl0gPSBjICsgSU5JVF9NRDRfQzsKICAgIGhhc2hbM10gPSBkICsgSU5JVF9NRDRfRDsKfQogCi8vIG1haW4KaW50IG1haW4oaW50IGFyZ2MsIGNoYXIgKmFyZ3ZbXSkKewogICAgdW5zaWduZWQgaW50IGk7CiAgICB1bnNpZ25lZCBpbnQgYnVmZmVyWzE2XTsKICAgIHVuc2lnbmVkIGludCBudF9oYXNoWzE2XTsKICAgIHVuc2lnbmVkIGludCBkY2NfaGFzaFsxNl07CiAgICB1bnNpZ25lZCBpbnQgZGNjMl9oYXNoWzE2XTsKICAgIHVuc2lnbmVkIGNoYXIgc2FsdFs0NF07CiAgICB1bnNpZ25lZCBjaGFyIHVzZXJuYW1lW10gPSAidGVzdCI7CiAgICB1bnNpZ25lZCBjaGFyIHBhc3N3b3JkW10gPSAicGFzc3dvcmQiOwogICAgdW5zaWduZWQgaW50IHVzZXJuYW1lX2xlbiA9IHN0cmxlbih1c2VybmFtZSk7CiAgICB1bnNpZ25lZCBpbnQgcGFzc3dvcmRfbGVuID0gc3RybGVuKHBhc3N3b3JkKTsKIAogICAgbWVtc2V0KG50X2hhc2gsIDAsIDY0KTsKICAgIG1lbXNldChidWZmZXIsIDAsIDY0KTsKICAgIG1lbXNldChzYWx0LCAwLCA0NCk7CiAKICAgIC8vIGNvbnZlcnQgQVNDSUkgdXNlcm5hbWUgdG8gVW5pY29kZSAoV2lkZUNoYXIpCiAgICBmb3IoaSA9IDA7IGkgPCAodXNlcm5hbWVfbGVuID4+IDEpICsgMTsgaSsrKQogICAgICAgICgodW5zaWduZWQgaW50ICopc2FsdClbaV0gPSB1c2VybmFtZVsyICogaV0gfCAodXNlcm5hbWVbMiAqIGkgKyAxXSA8PCAxNik7CiAKICAgIC8vIGNvbnZlcnQgQVNDSUkgcGFzc3dvcmQgdG8gVW5pY29kZQogCiAgICBmb3IoaSA9IDA7IGkgPCBwYXNzd29yZF9sZW4gPj4gMTsgaSsrKSAgCiAgICAgICAgYnVmZmVyW2ldID0gcGFzc3dvcmRbMiAqIGldIHwgKHBhc3N3b3JkWzIgKiBpICsgMV0gPDwgMTYpOwogCiAgICAvLyBNRDQgcGFkZGluZwogICAgaWYocGFzc3dvcmRfbGVuICUgMiA9PSAxKQogICAgICAgIGJ1ZmZlcltpXSA9IHBhc3N3b3JkW3Bhc3N3b3JkX2xlbiAtIDFdIHwgMHg4MDAwMDA7CiAgICBlbHNlCiAgICAgICAgYnVmZmVyW2ldPTB4ODA7CiAKICAgIC8vIHB1dCBwYXNzd29yZCBsZW5ndGggYXQgZW5kIG9mIGJ1ZmZlcgogICAgYnVmZmVyWzE0XSA9IHBhc3N3b3JkX2xlbiA8PCA0OwogCiAgICAvLyBnZW5lcmF0ZSBNRDQgaGFzaCBvZiB0aGUgcGFzc3dvcmQgKE5UIGhhc2gpCiAgICBtZDRfY3J5cHQoYnVmZmVyLCBudF9oYXNoKTsKIAogICAgLy8gY29uY2F0ZW5hdGUgTlQgaGFzaCBhbmQgdGhlIHVzZXJuYW1lIChzYWx0KQogICAgbWVtY3B5KCh1bnNpZ25lZCBjaGFyICopbnRfaGFzaCArIDE2LCBzYWx0LCB1c2VybmFtZV9sZW4gPDwgMSk7IAogCiAgICBpID0gdXNlcm5hbWVfbGVuICsgODsKIAogICAgLy8gTUQ0IHBhZGRpbmcKICAgIGlmKHVzZXJuYW1lX2xlbiAlIDIgPT0gMSkKICAgICAgICBudF9oYXNoW2kgPj4gMV0gPSB1c2VybmFtZVt1c2VybmFtZV9sZW4gLSAxXSB8IDB4ODAwMDAwOwogICAgZWxzZQogICAgICAgIG50X2hhc2hbaSA+PiAxXSA9IDB4ODA7CiAKICAgIC8vIHB1dCBsZW5ndGggYXQgZW5kIG9mIGJ1ZmZlcgogICAgbnRfaGFzaFsxNF0gPSBpIDw8IDQ7IAogCiAgICBtZDRfY3J5cHQobnRfaGFzaCwgZGNjX2hhc2gpOwogCiAKICAgIC8vIHN0cmlwcGVkLWRvd24gUEJLREYyIGZvciBEQ0MyCiAgICBQQktERjJfRENDMigodW5zaWduZWQgY2hhciopZGNjX2hhc2gsIHNhbHQsIHVzZXJuYW1lX2xlbiA8PCAxLCAodW5zaWduZWQgY2hhciopZGNjMl9oYXNoKTsKIAogICAgLy8gdGhlIGV2ZW4gc2xvd2VyIE9wZW5TU0wgUEJLREYyIGltcGxlbWVudGF0aW9uIChjb21waWxlIHdpdGggLWxzc2wpICAgCi8vICBQS0NTNV9QQktERjJfSE1BQ19TSEExKCh1bnNpZ25lZCBjaGFyKilkY2NfaGFzaCwgMTYsIHNhbHQsIHVzZXJuYW1lX2xlbiA8PCAxLCBJVEVSQVRJT05TLCAxNiwgKHVuc2lnbmVkIGNoYXIqKWRjYzJfaGFzaCk7CiAKICAgIC8vIHVzZXIgY3JlZGVudGlhbHMgYW5kIERDQyBhbmQgRENDMiBoYXNoIHZhbHVlcwogICAgcHJpbnRmKCJ1c2VybmFtZSAgICAgICAgICAgOiAlc1xuIiwgdXNlcm5hbWUpOwogICAgcHJpbnRmKCJwYXNzd29yZCAgICAgICAgICAgOiAlc1xuIiwgcGFzc3dvcmQpOwogICAgcHJpbnRmKCJEQ0MgIGFrYSBNJCBDYWNoZSAgOiAlc1xuIiwgYnl0ZTJoZXhzdHJpbmcoKHVuc2lnbmVkIGNoYXIgKilkY2NfaGFzaCwgMTYpKTsKICAgIHByaW50ZigiRENDMiBha2EgTSQgQ2FjaGUgMjogJXNcbiIsIGJ5dGUyaGV4c3RyaW5nKCh1bnNpZ25lZCBjaGFyICopZGNjMl9oYXNoLCAxNikpOwogCiAgICByZXR1cm4gMDsKfQ==