github.com/deroproject/derosuite@v2.1.6-1.0.20200307070847-0f2e589c7a2b+incompatible/cryptonight/cryptonight.go (about)

     1  // Copyright 2017-2018 DERO Project. All rights reserved.
     2  // Use of this source code in any form is governed by RESEARCH license.
     3  // license can be found in the LICENSE file.
     4  // GPG: 0F39 E425 8C65 3947 702A  8234 08B2 0360 A03A 9DE8
     5  //
     6  //
     7  // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
     8  // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     9  // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
    10  // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    11  // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
    12  // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    13  // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
    14  // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
    15  // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    16  
    17  package cryptonight
    18  
    19  //import "fmt"
    20  import "unsafe"
    21  
    22  //import "encoding/hex"
    23  import "encoding/binary"
    24  import "github.com/aead/skein"
    25  import "github.com/dchest/blake256"
    26  
    27  var HardwareAES bool = false
    28  
    29  const MAX_ARRAY_LIMIT = (4 * 1024 * 1024)
    30  
    31  func cryptonight(input []byte) []byte {
    32  
    33  	var dummy [256]byte
    34  	var S [25]uint64
    35  
    36  	var key1 [64]uint32
    37  	var key2 [64]uint32
    38  
    39  	var a [2]uint64
    40  	var b [2]uint64
    41  	var c [2]uint64
    42  
    43  	a_uint32 := (*(*[4]uint32)(unsafe.Pointer(&a[0])))[:len(a)*2]
    44  	//b_uint32 := (*(*[4]uint32)(unsafe.Pointer(&b[0])))[:len(b)*2]
    45  	c_uint32 := (*(*[4]uint32)(unsafe.Pointer(&c[0])))[:len(c)*2]
    46  
    47  	// same array is accessed as 3 different ways, buts it bettter than copying
    48  	var ScratchPad = make([]uint64, 1<<18, 1<<18)
    49  	ScratchPad_uint32 := (*(*[MAX_ARRAY_LIMIT]uint32)(unsafe.Pointer(&ScratchPad[0])))[:len(ScratchPad)*2]
    50  	// ScratchPad_byte := (*(*[MAX_ARRAY_LIMIT]byte)(unsafe.Pointer(&ScratchPad[0])))[:len(ScratchPad)*8]
    51  
    52  	copy(dummy[:], input)
    53  
    54  	for i := 0; i < 16; i++ {
    55  		S[i] = binary.LittleEndian.Uint64(dummy[i<<3:])
    56  	}
    57  	S[16] = 0x8000000000000000
    58  
    59  	keccakf(&S)
    60  
    61  	// lets convert everything back to bytes
    62  	for i := 0; i < 25; i++ {
    63  		binary.LittleEndian.PutUint64(dummy[i<<3:], S[i])
    64  	}
    65  
    66  	// extract keys
    67  	/*for i := 0 ; i <8;i++{
    68  	    key1[i] = binary.LittleEndian.Uint32(dummy[i<<2:])
    69  	    key2[i] = binary.LittleEndian.Uint32(dummy[32+(i<<2):])
    70  	}*/
    71  
    72  	expandKeyGo(dummy[0:32], key1[:], nil)
    73  	expandKeyGo(dummy[32:64], key2[:], nil)
    74  
    75  	/* for i :=0; i< 60;i++{
    76  	         fmt.Printf("%2d %X\n", i, key2[i])
    77  	}*/
    78  
    79  	// var text [128]byte
    80  	var text_uint32 [32]uint32
    81  	//copy(text[:],dummy[64:64+128]) // copy 128 bytes
    82  
    83  	for i := 0; i < 32; i++ {
    84  		text_uint32[i] = binary.LittleEndian.Uint32(dummy[64+(i<<2):])
    85  	}
    86  
    87  	/* for i :=0; i< 32;i++{
    88  	         fmt.Printf("%2d %X  i  %08X %08X\n", i, text_uint32[i] , key1[i],key1[i<<1])
    89  	}*/
    90  
    91  	for i := 0; i < 0x4000; i++ {
    92  		for j := 0; j < 8; j++ {
    93  			CNAESTransform((text_uint32[(j << 2):]), key1[:])
    94  		}
    95  
    96  		//memcpy(CNCtx.Scratchpad + (i << 4), text, 128);
    97  		copy(ScratchPad_uint32[i*32:], text_uint32[:])
    98  	}
    99  
   100  	a[0] = S[0] ^ S[4]
   101  	a[1] = S[1] ^ S[5]
   102  	b[0] = S[2] ^ S[6]
   103  	b[1] = S[3] ^ S[7]
   104  
   105  	var x [2]uint64
   106  	_ = x
   107  
   108  	// the big slow
   109  	for i := 0; i < 0x80000; i++ {
   110  		// {
   111  		c[0] = ScratchPad[((a[0]&0x1FFFF0)>>3)+0]
   112  		c[1] = ScratchPad[((a[0]&0x1FFFF0)>>3)+1]
   113  
   114  		CNAESRnd(c_uint32, a_uint32)
   115  
   116  		b[0] ^= c[0]
   117  		b[1] ^= c[1]
   118  
   119  		ScratchPad[((a[0]&0x1FFFF0)>>3)+0] = b[0]
   120  		ScratchPad[((a[0]&0x1FFFF0)>>3)+1] = b[1]
   121  
   122  		b[0] = ScratchPad[((c[0]&0x1FFFF0)>>3)+0]
   123  		b[1] = ScratchPad[((c[0]&0x1FFFF0)>>3)+1]
   124  
   125  		/*  // faster assembly implmentation for mul on amd64
   126  		x[0]= c[0]
   127  		x[1]= b[0]
   128  		mul6464128(&x[0])
   129  		a[1] += x[1]
   130  		a[0] += x[0]
   131  		*/
   132  
   133  		// time to do 64 bit * 64 bit multiply
   134  		// this is faster than the assembly
   135  		var lower64, upper64 uint64
   136  		{
   137  
   138  			x := c[0]
   139  			y := b[0]
   140  
   141  			a := x >> 32
   142  			b := x & 0xffffffff
   143  			c := y >> 32
   144  			d := y & 0xffffffff
   145  
   146  			ac := a * c
   147  			bc := b * c
   148  			ad := a * d
   149  			bd := b * d
   150  
   151  			mid34 := (bd >> 32) + (bc & 0xffffffff) + (ad & 0xffffffff)
   152  
   153  			upper64 = ac + (bc >> 32) + (ad >> 32) + (mid34 >> 32)
   154  			lower64 = (mid34 << 32) | (bd & 0xffffffff)
   155  			_ = lower64
   156  			_ = upper64
   157  
   158  		}
   159  		a[1] += lower64
   160  		a[0] += upper64
   161  
   162  		ScratchPad[((c[0]&0x1FFFF0)>>3)+0] = a[0]
   163  		ScratchPad[((c[0]&0x1FFFF0)>>3)+1] = a[1]
   164  
   165  		a[0] ^= b[0]
   166  		a[1] ^= b[1]
   167  
   168  		b[0] = c[0]
   169  		b[1] = c[1]
   170  
   171  	}
   172  
   173  	// fmt.Printf(" a %X %X\n", a[0],a[1]);
   174  	// fmt.Printf(" b %X %X\n", b[0],b[1]);
   175  
   176  	for i := 0; i < 32; i++ {
   177  		text_uint32[i] = binary.LittleEndian.Uint32(dummy[64+(i<<2):])
   178  	}
   179  
   180  	for i := 0; i < 0x4000; i++ {
   181  
   182  		for j := 0; j < 32; j++ {
   183  			text_uint32[j] ^= ScratchPad_uint32[(i*32)+j]
   184  
   185  		}
   186  		for j := 0; j < 8; j++ {
   187  			CNAESTransform((text_uint32[(j << 2):]), key2[:])
   188  		}
   189  
   190  	}
   191  
   192  	/*for i :=0; i< 32;i++{
   193  	         fmt.Printf("%2d %X\n", i, text_uint32[i])
   194  	}*/
   195  
   196  	for i := 0; i < 32; i++ {
   197  		binary.LittleEndian.PutUint32(dummy[64+(i<<2):], text_uint32[i])
   198  	}
   199  
   200  	for i := 8; i < 25; i++ {
   201  		S[i] = binary.LittleEndian.Uint64(dummy[i<<3:])
   202  	}
   203  
   204  	keccakf(&S) // do the keccak round
   205  	/* for i :=0; i< 25;i++{
   206  	         fmt.Printf("S %02d %X\n", i, S[i])
   207  	}*/
   208  
   209  	// lets convert everything back to bytes
   210  	for i := 0; i < 25; i++ {
   211  		binary.LittleEndian.PutUint64(dummy[i<<3:], S[i])
   212  	}
   213  
   214  	var resulthash []byte
   215  
   216  	switch S[0] & 3 {
   217  
   218  	case 0:
   219  		// fmt.Printf("blake\n")
   220  
   221  		// blake
   222  		blakehash := blake256.New()
   223  		blakehash.Write(dummy[:200])
   224  		resulthash = blakehash.Sum(nil) //matching
   225  
   226  	case 1: // groestl
   227  		// fmt.Printf("groestl not implemented\n")
   228  		var output [32]byte
   229  		var input = dummy[:200]
   230  		crypto_hash(output[:], input, uint64(len(input)))
   231  		resulthash = output[:]
   232  	case 2: // jh
   233  		//fmt.Printf("jh not implemented\n")
   234  
   235  		myjhash := NewJhash256()
   236  		myjhash.Write(dummy[:200])
   237  		resulthash = myjhash.Sum(nil)
   238  
   239  	case 3: // skein
   240  		//  fmt.Printf("skein\n")
   241  		skeinhash := skein.New256(nil)
   242  		skeinhash.Write(dummy[:200])
   243  		resulthash = skeinhash.Sum(nil) //matchin
   244  
   245  	}
   246  
   247  	//fmt.Printf("result hash %x\n", resulthash)
   248  
   249  	return resulthash
   250  
   251  }
   252  
   253  /* from original cryptonote source
   254  0100000000000000000000000000000000000000000000000000000000000000000000102700005a18d9489bcd353aeaf4a19323d04e90353f98f0d7cc2a030cfd76e19495547d01
   255  a73bd37aba3454776b40733854a8349fe6359eb2c91d93bc727c69431c1d1f95hash of blob
   256  
   257  // from our implementation
   258  
   259  Get long hash a73bd37aba3454776b40733854a8349fe6359eb2c91d93bc727c69431c1d1f95
   260  */
   261  
   262  func SlowHash(msg []byte) []byte {
   263  	return cryptonight(append(msg, byte(0x01)))
   264  }
   265  
   266  // Rotate
   267  
   268  func ROTL32(x uint32, y uint32) uint32 { return (((x) << (y)) | ((x) >> (32 - (y)))) }
   269  func BYTE(x, y uint32) uint32          { return (((x) >> ((y) << 3)) & 0xFF) }
   270  
   271  func SubWord(inw uint32) uint32 {
   272  	return ((CNAESSbox[BYTE(inw, 3)] << 24) | (CNAESSbox[BYTE(inw, 2)] << 16) | (CNAESSbox[BYTE(inw, 1)] << 8) | CNAESSbox[BYTE(inw, 0)])
   273  }
   274  
   275  /*
   276  func AESExpandKey256(keybuf []uint32){
   277      i := uint32(1)
   278      t := uint32(0)
   279  	for c := 8 ; c < 60; c++	{
   280  		// For 256-bit keys, an sbox permutation is done every other 4th uint generated, AND every 8th
   281  		// t := ((!(c & 3))) ? SubWord(keybuf[c - 1]) : keybuf[c - 1];
   282                if  (c & 3) == 0 {
   283                    t = SubWord(keybuf[c - 1])
   284                }else{
   285                    t = keybuf[c - 1];
   286                }
   287  
   288  		// If the uint we're generating has an index that is a multiple of 8, rotate and XOR with the round constant,
   289  		// then XOR this with previously generated uint. If it's 4 after a multiple of 8, only the sbox permutation
   290  		// is done, followed by the XOR. If neither are true, only the XOR with the previously generated uint is done.
   291  		//keybuf[c] = keybuf[c - 8] ^ ((!(c & 7)) ? ROTL32(t, 24U) ^ ((uint32_t)(CNAESRcon[i++])) : t);
   292  		if (keybuf[c - 8] ^ ((!(c & 7))) > 0) {
   293                      keybuf[c] = ROTL32(t, 24) ^ ((uint32)(CNAESRcon[i]))
   294                      i++
   295                  }else{
   296                      keybuf[c] = t;
   297                  }
   298  	}
   299  }
   300  */
   301  
   302  func CNAESTransform(X, Key []uint32) {
   303  
   304  	//  fmt.Printf("X %08X %08X  \n", X[0],X[1]) ;
   305  
   306  	/*
   307  		for i := uint32(0); i < 10; i++ {
   308  			CNAESRnd(X, Key[(i<<2):])
   309  		}*/
   310  	if HardwareAES {
   311  		/*encryptAESRound(&Key[0<<2],&X[0],&X[0])
   312  		encryptAESRound(&Key[1<<2],&X[0],&X[0])
   313  		encryptAESRound(&Key[2<<2],&X[0],&X[0])
   314  		encryptAESRound(&Key[3<<2],&X[0],&X[0])
   315  		encryptAESRound(&Key[4<<2],&X[0],&X[0])
   316  		encryptAESRound(&Key[5<<2],&X[0],&X[0])
   317  		encryptAESRound(&Key[6<<2],&X[0],&X[0])
   318  		encryptAESRound(&Key[7<<2],&X[0],&X[0])
   319  		encryptAESRound(&Key[8<<2],&X[0],&X[0])
   320  		encryptAESRound(&Key[9<<2],&X[0],&X[0])
   321  		*/
   322  		encrypt10AESRound(&Key[0<<2], &X[0], &X[0])
   323  	} else {
   324  		for i := uint32(0); i < 10; i++ {
   325  			CNAESRnd(X, Key[(i<<2):])
   326  		}
   327  
   328  	}
   329  
   330  }
   331  
   332  func CNAESRnd(X, key []uint32) {
   333  
   334  	if HardwareAES {
   335  		encryptAESRound(&key[0], &X[0], &X[0])
   336  		return
   337  	}
   338  
   339  	// use software implementation, of no AES detected or CPU not X86
   340  	var Y [4]uint32
   341  
   342  	Y[0] = CNAESTbl[BYTE(X[0], 0)] ^ ROTL32(CNAESTbl[BYTE(X[1], 1)], 8) ^ ROTL32(CNAESTbl[BYTE(X[2], 2)], 16) ^ ROTL32(CNAESTbl[BYTE(X[3], 3)], 24)
   343  	Y[1] = CNAESTbl[BYTE(X[1], 0)] ^ ROTL32(CNAESTbl[BYTE(X[2], 1)], 8) ^ ROTL32(CNAESTbl[BYTE(X[3], 2)], 16) ^ ROTL32(CNAESTbl[BYTE(X[0], 3)], 24)
   344  	Y[2] = CNAESTbl[BYTE(X[2], 0)] ^ ROTL32(CNAESTbl[BYTE(X[3], 1)], 8) ^ ROTL32(CNAESTbl[BYTE(X[0], 2)], 16) ^ ROTL32(CNAESTbl[BYTE(X[1], 3)], 24)
   345  	Y[3] = CNAESTbl[BYTE(X[3], 0)] ^ ROTL32(CNAESTbl[BYTE(X[0], 1)], 8) ^ ROTL32(CNAESTbl[BYTE(X[1], 2)], 16) ^ ROTL32(CNAESTbl[BYTE(X[2], 3)], 24)
   346  
   347  	for i := 0; i < 4; i++ {
   348  		X[i] = Y[i] ^ key[i]
   349  	}
   350  
   351  }
   352  
   353  // copied from https://golang.org/src/crypto/aes/block.go
   354  
   355  // Apply sbox0 to each byte in w.
   356  
   357  func subw(w uint32) uint32 {
   358  	return uint32(sbox0[w>>24])<<24 |
   359  		uint32(sbox0[w>>16&0xff])<<16 |
   360  		uint32(sbox0[w>>8&0xff])<<8 |
   361  		uint32(sbox0[w&0xff])
   362  }
   363  
   364  // Rotate
   365  func rotw(w uint32) uint32 { return w<<8 | w>>24 }
   366  
   367  func swap_uint32(val uint32) uint32 {
   368  	val = ((val << 8) & 0xFF00FF00) | ((val >> 8) & 0xFF00FF)
   369  	return (val << 16) | (val >> 16)
   370  }
   371  
   372  // Key expansion algorithm. See FIPS-197, Figure 11.
   373  // Their rcon[i] is our powx[i-1] << 24.
   374  
   375  func expandKeyGo(key []byte, enc, dec []uint32) {
   376  	// Encryption key setup.
   377  	var i int
   378  	nk := len(key) / 4
   379  	for i = 0; i < nk; i++ {
   380  		enc[i] = uint32(key[4*i])<<24 | uint32(key[4*i+1])<<16 | uint32(key[4*i+2])<<8 | uint32(key[4*i+3])
   381  	}
   382  
   383  	for ; i < len(enc); i++ {
   384  		t := enc[i-1]
   385  		if i%nk == 0 {
   386  			t = subw(rotw(t)) ^ (uint32(powx[i/nk-1]) << 24)
   387  		} else if nk > 6 && i%nk == 4 {
   388  			t = subw(t)
   389  		}
   390  		enc[i] = enc[i-nk] ^ t
   391  
   392  		// fmt.Printf("%2d %X\n", i, enc[i])
   393  	}
   394  
   395  	// key generated by golang need to be swapped
   396  	for i := 0; i < 60; i++ {
   397  		enc[i] = swap_uint32(enc[i])
   398  		//fmt.Printf("%2d %X\n", i, enc[i])
   399  	}
   400  
   401  	/*
   402  	   	// Derive decryption key from encryption key.
   403  	   	// Reverse the 4-word round key sets from enc to produce dec.
   404  	   	// All sets but the first and last get the MixColumn transform applied.
   405  	   	if dec == nil {
   406  	   		return
   407  	   	}
   408  	   	n := len(enc)
   409  	   	for i := 0; i < n; i += 4 {
   410  	   		ei := n - i - 4
   411  	               for j := 0; j < 4; j++ {
   412  	   			x := enc[ei+j]
   413  	   			if i > 0 && i+4 < n {
   414  	   			x = td0[sbox0[x>>24]] ^ td1[sbox0[x>>16&0xff]] ^ td2[sbox0[x>>8&0xff]] ^ td3[sbox0[x&0xff]]
   415  	   		}
   416  	   		dec[i+j] = x
   417  	   		}
   418  	   	}
   419  
   420  	*/
   421  }
   422  
   423  // copied from https://golang.org/src/crypto/aes/const.go
   424  // Powers of x mod poly in GF(2).
   425  var powx = [16]byte{
   426  	0x01,
   427  	0x02,
   428  	0x04,
   429  	0x08,
   430  	0x10,
   431  	0x20,
   432  	0x40,
   433  	0x80,
   434  	0x1b,
   435  	0x36,
   436  	0x6c,
   437  	0xd8,
   438  	0xab,
   439  	0x4d,
   440  	0x9a,
   441  	0x2f,
   442  }
   443  
   444  // FIPS-197 Figure 7. S-box substitution values in hexadecimal format.
   445  var sbox0 = [256]byte{
   446  	0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
   447  	0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
   448  	0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
   449  	0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
   450  	0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
   451  	0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
   452  	0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
   453  	0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
   454  	0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
   455  	0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
   456  	0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
   457  	0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
   458  	0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
   459  	0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
   460  	0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
   461  	0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16,
   462  }
   463  
   464  var CNAESSbox = [256]uint32{
   465  	0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
   466  	0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
   467  	0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
   468  	0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
   469  	0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
   470  	0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
   471  	0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
   472  	0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
   473  	0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
   474  	0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
   475  	0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
   476  	0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
   477  	0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
   478  	0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
   479  	0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
   480  	0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16,
   481  }
   482  var CNAESRcon = [8]uint32{0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40}
   483  var CNAESTbl = [256]uint32{0xA56363C6, 0x847C7CF8, 0x997777EE, 0x8D7B7BF6,
   484  	0x0DF2F2FF, 0xBD6B6BD6, 0xB16F6FDE, 0x54C5C591,
   485  	0x50303060, 0x03010102, 0xA96767CE, 0x7D2B2B56,
   486  	0x19FEFEE7, 0x62D7D7B5, 0xE6ABAB4D, 0x9A7676EC,
   487  	0x45CACA8F, 0x9D82821F, 0x40C9C989, 0x877D7DFA,
   488  	0x15FAFAEF, 0xEB5959B2, 0xC947478E, 0x0BF0F0FB,
   489  	0xECADAD41, 0x67D4D4B3, 0xFDA2A25F, 0xEAAFAF45,
   490  	0xBF9C9C23, 0xF7A4A453, 0x967272E4, 0x5BC0C09B,
   491  	0xC2B7B775, 0x1CFDFDE1, 0xAE93933D, 0x6A26264C,
   492  	0x5A36366C, 0x413F3F7E, 0x02F7F7F5, 0x4FCCCC83,
   493  	0x5C343468, 0xF4A5A551, 0x34E5E5D1, 0x08F1F1F9,
   494  	0x937171E2, 0x73D8D8AB, 0x53313162, 0x3F15152A,
   495  	0x0C040408, 0x52C7C795, 0x65232346, 0x5EC3C39D,
   496  	0x28181830, 0xA1969637, 0x0F05050A, 0xB59A9A2F,
   497  	0x0907070E, 0x36121224, 0x9B80801B, 0x3DE2E2DF,
   498  	0x26EBEBCD, 0x6927274E, 0xCDB2B27F, 0x9F7575EA,
   499  	0x1B090912, 0x9E83831D, 0x742C2C58, 0x2E1A1A34,
   500  	0x2D1B1B36, 0xB26E6EDC, 0xEE5A5AB4, 0xFBA0A05B,
   501  	0xF65252A4, 0x4D3B3B76, 0x61D6D6B7, 0xCEB3B37D,
   502  	0x7B292952, 0x3EE3E3DD, 0x712F2F5E, 0x97848413,
   503  	0xF55353A6, 0x68D1D1B9, 0x00000000, 0x2CEDEDC1,
   504  	0x60202040, 0x1FFCFCE3, 0xC8B1B179, 0xED5B5BB6,
   505  	0xBE6A6AD4, 0x46CBCB8D, 0xD9BEBE67, 0x4B393972,
   506  	0xDE4A4A94, 0xD44C4C98, 0xE85858B0, 0x4ACFCF85,
   507  	0x6BD0D0BB, 0x2AEFEFC5, 0xE5AAAA4F, 0x16FBFBED,
   508  	0xC5434386, 0xD74D4D9A, 0x55333366, 0x94858511,
   509  	0xCF45458A, 0x10F9F9E9, 0x06020204, 0x817F7FFE,
   510  	0xF05050A0, 0x443C3C78, 0xBA9F9F25, 0xE3A8A84B,
   511  	0xF35151A2, 0xFEA3A35D, 0xC0404080, 0x8A8F8F05,
   512  	0xAD92923F, 0xBC9D9D21, 0x48383870, 0x04F5F5F1,
   513  	0xDFBCBC63, 0xC1B6B677, 0x75DADAAF, 0x63212142,
   514  	0x30101020, 0x1AFFFFE5, 0x0EF3F3FD, 0x6DD2D2BF,
   515  	0x4CCDCD81, 0x140C0C18, 0x35131326, 0x2FECECC3,
   516  	0xE15F5FBE, 0xA2979735, 0xCC444488, 0x3917172E,
   517  	0x57C4C493, 0xF2A7A755, 0x827E7EFC, 0x473D3D7A,
   518  	0xAC6464C8, 0xE75D5DBA, 0x2B191932, 0x957373E6,
   519  	0xA06060C0, 0x98818119, 0xD14F4F9E, 0x7FDCDCA3,
   520  	0x66222244, 0x7E2A2A54, 0xAB90903B, 0x8388880B,
   521  	0xCA46468C, 0x29EEEEC7, 0xD3B8B86B, 0x3C141428,
   522  	0x79DEDEA7, 0xE25E5EBC, 0x1D0B0B16, 0x76DBDBAD,
   523  	0x3BE0E0DB, 0x56323264, 0x4E3A3A74, 0x1E0A0A14,
   524  	0xDB494992, 0x0A06060C, 0x6C242448, 0xE45C5CB8,
   525  	0x5DC2C29F, 0x6ED3D3BD, 0xEFACAC43, 0xA66262C4,
   526  	0xA8919139, 0xA4959531, 0x37E4E4D3, 0x8B7979F2,
   527  	0x32E7E7D5, 0x43C8C88B, 0x5937376E, 0xB76D6DDA,
   528  	0x8C8D8D01, 0x64D5D5B1, 0xD24E4E9C, 0xE0A9A949,
   529  	0xB46C6CD8, 0xFA5656AC, 0x07F4F4F3, 0x25EAEACF,
   530  	0xAF6565CA, 0x8E7A7AF4, 0xE9AEAE47, 0x18080810,
   531  	0xD5BABA6F, 0x887878F0, 0x6F25254A, 0x722E2E5C,
   532  	0x241C1C38, 0xF1A6A657, 0xC7B4B473, 0x51C6C697,
   533  	0x23E8E8CB, 0x7CDDDDA1, 0x9C7474E8, 0x211F1F3E,
   534  	0xDD4B4B96, 0xDCBDBD61, 0x868B8B0D, 0x858A8A0F,
   535  	0x907070E0, 0x423E3E7C, 0xC4B5B571, 0xAA6666CC,
   536  	0xD8484890, 0x05030306, 0x01F6F6F7, 0x120E0E1C,
   537  	0xA36161C2, 0x5F35356A, 0xF95757AE, 0xD0B9B969,
   538  	0x91868617, 0x58C1C199, 0x271D1D3A, 0xB99E9E27,
   539  	0x38E1E1D9, 0x13F8F8EB, 0xB398982B, 0x33111122,
   540  	0xBB6969D2, 0x70D9D9A9, 0x898E8E07, 0xA7949433,
   541  	0xB69B9B2D, 0x221E1E3C, 0x92878715, 0x20E9E9C9,
   542  	0x49CECE87, 0xFF5555AA, 0x78282850, 0x7ADFDFA5,
   543  	0x8F8C8C03, 0xF8A1A159, 0x80898909, 0x170D0D1A,
   544  	0xDABFBF65, 0x31E6E6D7, 0xC6424284, 0xB86868D0,
   545  	0xC3414182, 0xB0999929, 0x772D2D5A, 0x110F0F1E,
   546  	0xCBB0B07B, 0xFC5454A8, 0xD6BBBB6D, 0x3A16162C,
   547  }