github.com/mad-day/Yawning-crypto@v0.0.0-20190711051033-5a5f8cca32ec/bsaes/ct64/aes_ct64_dec.go (about)

     1  // Copyright (c) 2016 Thomas Pornin <pornin@bolet.org>
     2  // Copyright (c) 2017 Yawning Angel <yawning at schwanenlied dot me>
     3  //
     4  // Permission is hereby granted, free of charge, to any person obtaining
     5  // a copy of this software and associated documentation files (the
     6  // "Software"), to deal in the Software without restriction, including
     7  // without limitation the rights to use, copy, modify, merge, publish,
     8  // distribute, sublicense, and/or sell copies of the Software, and to
     9  // permit persons to whom the Software is furnished to do so, subject to
    10  // the following conditions:
    11  //
    12  // The above copyright notice and this permission notice shall be
    13  // included in all copies or substantial portions of the Software.
    14  //
    15  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    16  // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    17  // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
    18  // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
    19  // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
    20  // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
    21  // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    22  // SOFTWARE.
    23  
    24  package ct64
    25  
    26  func InvSbox(q *[8]uint64) {
    27  	// See ct32/Impl32.InvSbox(). This is the natural extension
    28  	// to 64-bit registers.
    29  	var q0, q1, q2, q3, q4, q5, q6, q7 uint64
    30  
    31  	q0 = ^q[0]
    32  	q1 = ^q[1]
    33  	q2 = q[2]
    34  	q3 = q[3]
    35  	q4 = q[4]
    36  	q5 = ^q[5]
    37  	q6 = ^q[6]
    38  	q7 = q[7]
    39  	q[7] = q1 ^ q4 ^ q6
    40  	q[6] = q0 ^ q3 ^ q5
    41  	q[5] = q7 ^ q2 ^ q4
    42  	q[4] = q6 ^ q1 ^ q3
    43  	q[3] = q5 ^ q0 ^ q2
    44  	q[2] = q4 ^ q7 ^ q1
    45  	q[1] = q3 ^ q6 ^ q0
    46  	q[0] = q2 ^ q5 ^ q7
    47  
    48  	Sbox(q)
    49  
    50  	q0 = ^q[0]
    51  	q1 = ^q[1]
    52  	q2 = q[2]
    53  	q3 = q[3]
    54  	q4 = q[4]
    55  	q5 = ^q[5]
    56  	q6 = ^q[6]
    57  	q7 = q[7]
    58  	q[7] = q1 ^ q4 ^ q6
    59  	q[6] = q0 ^ q3 ^ q5
    60  	q[5] = q7 ^ q2 ^ q4
    61  	q[4] = q6 ^ q1 ^ q3
    62  	q[3] = q5 ^ q0 ^ q2
    63  	q[2] = q4 ^ q7 ^ q1
    64  	q[1] = q3 ^ q6 ^ q0
    65  	q[0] = q2 ^ q5 ^ q7
    66  }
    67  
    68  func InvShiftRows(q *[8]uint64) {
    69  	for i, x := range q {
    70  		q[i] = (x & 0x000000000000FFFF) |
    71  			((x & 0x000000000FFF0000) << 4) |
    72  			((x & 0x00000000F0000000) >> 12) |
    73  			((x & 0x000000FF00000000) << 8) |
    74  			((x & 0x0000FF0000000000) >> 8) |
    75  			((x & 0x000F000000000000) << 12) |
    76  			((x & 0xFFF0000000000000) >> 4)
    77  	}
    78  }
    79  
    80  func InvMixColumns(q *[8]uint64) {
    81  	q0 := q[0]
    82  	q1 := q[1]
    83  	q2 := q[2]
    84  	q3 := q[3]
    85  	q4 := q[4]
    86  	q5 := q[5]
    87  	q6 := q[6]
    88  	q7 := q[7]
    89  	r0 := (q0 >> 16) | (q0 << 48)
    90  	r1 := (q1 >> 16) | (q1 << 48)
    91  	r2 := (q2 >> 16) | (q2 << 48)
    92  	r3 := (q3 >> 16) | (q3 << 48)
    93  	r4 := (q4 >> 16) | (q4 << 48)
    94  	r5 := (q5 >> 16) | (q5 << 48)
    95  	r6 := (q6 >> 16) | (q6 << 48)
    96  	r7 := (q7 >> 16) | (q7 << 48)
    97  
    98  	q[0] = q5 ^ q6 ^ q7 ^ r0 ^ r5 ^ r7 ^ rotr32(q0^q5^q6^r0^r5)
    99  	q[1] = q0 ^ q5 ^ r0 ^ r1 ^ r5 ^ r6 ^ r7 ^ rotr32(q1^q5^q7^r1^r5^r6)
   100  	q[2] = q0 ^ q1 ^ q6 ^ r1 ^ r2 ^ r6 ^ r7 ^ rotr32(q0^q2^q6^r2^r6^r7)
   101  	q[3] = q0 ^ q1 ^ q2 ^ q5 ^ q6 ^ r0 ^ r2 ^ r3 ^ r5 ^ rotr32(q0^q1^q3^q5^q6^q7^r0^r3^r5^r7)
   102  	q[4] = q1 ^ q2 ^ q3 ^ q5 ^ r1 ^ r3 ^ r4 ^ r5 ^ r6 ^ r7 ^ rotr32(q1^q2^q4^q5^q7^r1^r4^r5^r6)
   103  	q[5] = q2 ^ q3 ^ q4 ^ q6 ^ r2 ^ r4 ^ r5 ^ r6 ^ r7 ^ rotr32(q2^q3^q5^q6^r2^r5^r6^r7)
   104  	q[6] = q3 ^ q4 ^ q5 ^ q7 ^ r3 ^ r5 ^ r6 ^ r7 ^ rotr32(q3^q4^q6^q7^r3^r6^r7)
   105  	q[7] = q4 ^ q5 ^ q6 ^ r4 ^ r6 ^ r7 ^ rotr32(q4^q5^q7^r4^r7)
   106  }
   107  
   108  func decrypt(numRounds int, skey []uint64, q *[8]uint64) {
   109  	AddRoundKey(q, skey[numRounds<<3:])
   110  	for u := numRounds - 1; u > 0; u-- {
   111  		InvShiftRows(q)
   112  		InvSbox(q)
   113  		AddRoundKey(q, skey[u<<3:])
   114  		InvMixColumns(q)
   115  	}
   116  	InvShiftRows(q)
   117  	InvSbox(q)
   118  	AddRoundKey(q, skey)
   119  }