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 }