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 24package ct32 25 26func ShiftRows(q *[8]uint32) { 27 for i, x := range q { 28 q[i] = (x & 0x000000FF) | 29 ((x & 0x0000FC00) >> 2) | ((x & 0x00000300) << 6) | 30 ((x & 0x00F00000) >> 4) | ((x & 0x000F0000) << 4) | 31 ((x & 0xC0000000) >> 6) | ((x & 0x3F000000) << 2) 32 } 33} 34 35func MixColumns(q *[8]uint32) { 36 var q0, q1, q2, q3, q4, q5, q6, q7 uint32 37 var r0, r1, r2, r3, r4, r5, r6, r7 uint32 38 39 q0 = q[0] 40 q1 = q[1] 41 q2 = q[2] 42 q3 = q[3] 43 q4 = q[4] 44 q5 = q[5] 45 q6 = q[6] 46 q7 = q[7] 47 r0 = (q0 >> 8) | (q0 << 24) 48 r1 = (q1 >> 8) | (q1 << 24) 49 r2 = (q2 >> 8) | (q2 << 24) 50 r3 = (q3 >> 8) | (q3 << 24) 51 r4 = (q4 >> 8) | (q4 << 24) 52 r5 = (q5 >> 8) | (q5 << 24) 53 r6 = (q6 >> 8) | (q6 << 24) 54 r7 = (q7 >> 8) | (q7 << 24) 55 56 q[0] = q7 ^ r7 ^ r0 ^ rotr16(q0^r0) 57 q[1] = q0 ^ r0 ^ q7 ^ r7 ^ r1 ^ rotr16(q1^r1) 58 q[2] = q1 ^ r1 ^ r2 ^ rotr16(q2^r2) 59 q[3] = q2 ^ r2 ^ q7 ^ r7 ^ r3 ^ rotr16(q3^r3) 60 q[4] = q3 ^ r3 ^ q7 ^ r7 ^ r4 ^ rotr16(q4^r4) 61 q[5] = q4 ^ r4 ^ r5 ^ rotr16(q5^r5) 62 q[6] = q5 ^ r5 ^ r6 ^ rotr16(q6^r6) 63 q[7] = q6 ^ r6 ^ r7 ^ rotr16(q7^r7) 64} 65 66func encrypt(numRounds int, skey []uint32, q *[8]uint32) { 67 AddRoundKey(q, skey) 68 for u := 1; u < numRounds; u++ { 69 Sbox(q) 70 ShiftRows(q) 71 MixColumns(q) 72 AddRoundKey(q, skey[u<<3:]) 73 } 74 Sbox(q) 75 ShiftRows(q) 76 AddRoundKey(q, skey[numRounds<<3:]) 77} 78