├── Makefile ├── README.md ├── main.c ├── masked_combined.c ├── masked_combined.h ├── maths.c └── maths.h /Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | gcc main.c masked_combined.c maths.c 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Higher-Order-Masked-AES-128 2 | 3 | Implemention in C of the higher-order masking scheme proposed in [0] with CPRR method from [1]. 4 | 5 | The AES implementation uses the Common Shares method [3], and the Random Reduction method [2] to increase the performance of the implementation. 6 | 7 | 8 | ### SecEvalCombined 9 | The most interesting function is the 'SecEvalCombined' function which implements the Common Shares and Random Reduction from [2] and [3] respectively. 10 | 11 | 12 | 13 | ### References 14 | 15 | 16 | [0] "Provably Secure Higher Order Masking of AES" 17 | 18 | [1] "Higher-Order Side Channel Security and Mask Refreshing" 19 | 20 | [2] "Further Improving Efficiency of Higher-Order Masking Schemes by Decreasing Randomness Complexity" 21 | 22 | [3] "Faster Evaluation of SBoxes via Common Shares" 23 | 24 | -------------------------------------------------------------------------------- /main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * AES-128 Encryption - Main File 3 | */ 4 | 5 | #include "stdint.h" 6 | #include 7 | #include "masked_combined.h" 8 | // Fixed 16 Byte Input 9 | uint8_t input[16] = {0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, 0x0d, 0x32, 0x55, 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90}; 10 | 11 | // Fixed 16 Byte Key 12 | uint8_t key[16] = {0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a}; 13 | 14 | 15 | 16 | int main(void) { 17 | uint8_t output[16]; 18 | Encrypt(output, input, key); 19 | for(int i = 0; i < 16; i++) { 20 | printf("%02x", output[i]); 21 | } 22 | printf("\n"); 23 | } 24 | 25 | -------------------------------------------------------------------------------- /masked_combined.c: -------------------------------------------------------------------------------- 1 | #include "stdint.h" 2 | #include "masked_combined.h" 3 | #include "maths.h" 4 | static uint8_t state[16][NUM_SHARES]; 5 | static uint8_t round_key[16][NUM_SHARES]; 6 | 7 | void Encrypt(uint8_t* output, uint8_t* input, uint8_t* key) { 8 | uint8_t rcon[10] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36}; 9 | uint8_t round; 10 | uint8_t i, j, d; 11 | uint8_t tmp[4][NUM_SHARES]; 12 | 13 | // Mask both the input and key 14 | MaskArray(state, input, 16); 15 | MaskArray(round_key, key, 16); 16 | 17 | 18 | for(round = 0; round < 10; round++) { 19 | // Add Round Key Stage 20 | for(j = 0; j < NUM_SHARES; j++) { 21 | for(i = 0; i < 16; i++) { 22 | state[i][j] ^= round_key[i][j]; 23 | } 24 | } 25 | 26 | CombinedSbox(state); 27 | ShiftRowsMixColumns(state, round); 28 | 29 | // Key Schedule 30 | round_key[0][0] ^= rcon[round]; 31 | DualSbox(tmp[0], tmp[1], round_key[13], round_key[14]); 32 | DualSbox(tmp[2], tmp[3], round_key[15], round_key[12]); 33 | for(d = 0; d < NUM_SHARES; d++) { 34 | round_key[0][d] ^= tmp[0][d]; 35 | round_key[1][d] ^= tmp[1][d]; 36 | round_key[2][d] ^= tmp[2][d]; 37 | round_key[3][d] ^= tmp[3][d]; 38 | 39 | round_key[4][d] ^= round_key[0][d]; 40 | round_key[5][d] ^= round_key[1][d]; 41 | round_key[6][d] ^= round_key[2][d]; 42 | round_key[7][d] ^= round_key[3][d]; 43 | round_key[8][d] ^= round_key[4][d]; 44 | round_key[9][d] ^= round_key[5][d]; 45 | round_key[10][d] ^= round_key[6][d]; 46 | round_key[11][d] ^= round_key[7][d]; 47 | round_key[12][d] ^= round_key[8][d]; 48 | round_key[13][d] ^= round_key[9][d]; 49 | round_key[14][d] ^= round_key[10][d]; 50 | round_key[15][d] ^= round_key[11][d]; 51 | } 52 | } 53 | // Final Add Round Key 54 | for(j = 0; j < NUM_SHARES; j++) { 55 | for(i = 0; i < 16; i++) { 56 | state[i][j] ^= round_key[i][j]; 57 | } 58 | } 59 | 60 | // Unmask the state revealing the encrypted output 61 | UnMaskArray(output, state, 16); 62 | } 63 | 64 | /* 65 | Takes an array and produces a set of shares for each element 66 | */ 67 | void MaskArray(uint8_t y[][NUM_SHARES], uint8_t x[], uint8_t length) { 68 | uint8_t i,j; 69 | for(i = 0; i < length; i++) { 70 | y[i][0] = x[i]; 71 | for(j = 1; j < NUM_SHARES; j++) { 72 | y[i][j] = getRand(); 73 | y[i][0] = y[i][0] ^ y[i][j]; 74 | } 75 | } 76 | } 77 | 78 | /* 79 | Unmasked an array. 80 | */ 81 | void UnMaskArray(uint8_t y[], uint8_t x[][NUM_SHARES], uint8_t length) { 82 | uint8_t i,j; 83 | for(i = 0; i < length; i++) { 84 | y[i] = x[i][0]; 85 | for(j = 1; j < NUM_SHARES; j++) { 86 | y[i] ^= x[i][j]; 87 | } 88 | } 89 | } 90 | 91 | 92 | /* 93 | * Combined Sbox function 94 | * Computes the sbox for all 16 bytes of the state in 'parallel' 95 | */ 96 | void CombinedSbox(uint8_t s[16][NUM_SHARES]) { 97 | uint8_t i,j; 98 | uint8_t a[16][NUM_SHARES]; 99 | uint8_t w[16][NUM_SHARES]; 100 | 101 | SecEvalCombined(w, s, fifth); 102 | SecEvalCombined(a, w, fifth); 103 | SecEvalCombined(w, a, fifth); 104 | 105 | SecMultCombined(a, s, w, snd); 106 | 107 | for(i = 0; i < 16; i++) { 108 | for(j = 0; j < NUM_SHARES; j++) { 109 | // We have merged the affine lookup table with the last linear 110 | // squaring in the extended addition chain. 111 | s[i][j] = l_affine_snd[a[i][j]]; 112 | } 113 | if((NUM_SHARES & 1) == 0) { 114 | s[i][0] ^= 0x63; 115 | } 116 | } 117 | } 118 | 119 | 120 | 121 | void DualSbox(uint8_t y1[], uint8_t y2[], uint8_t x1[], uint8_t x2[]) { 122 | 123 | uint8_t j; 124 | uint8_t w[2][NUM_SHARES]; 125 | uint8_t a[2][NUM_SHARES]; 126 | 127 | SecEvalTwoQuadraticRand(w[0], w[1], x1, x2, fifth); 128 | SecEvalTwoQuadraticRand(a[0], a[1], w[0], w[1], fifth); 129 | SecEvalTwoQuadraticRand(w[0], w[1], a[0], a[1], fifth); 130 | 131 | SecTwoMultSmall(a[0], a[1], x1, x2, w[0], w[1], snd); 132 | 133 | for(j = 0; j < NUM_SHARES; j++) { 134 | y1[j] = l_affine_snd[a[0][j]]; 135 | y2[j] = l_affine_snd[a[1][j]]; 136 | } 137 | if((NUM_SHARES & 1) == 0) { 138 | y1[0] ^= 0x63; 139 | y2[0] ^= 0x63; 140 | } 141 | } 142 | 143 | void ShiftRowsMixColumns(uint8_t s[][NUM_SHARES], uint8_t round) { 144 | uint8_t temp, share; 145 | uint8_t i; 146 | uint8_t Tmp,Tm,t; 147 | uint8_t r; 148 | for(share = 0; share < NUM_SHARES; share++) { 149 | // Rotate first row 1 columns to left 150 | temp = s[1][share]; 151 | s[1][share] = s[5][share]; 152 | s[5][share] = s[9][share]; 153 | s[9][share] = s[13][share]; 154 | s[13][share] = temp; 155 | 156 | // Rotate second row 2 columns to left 157 | temp = s[2][share]; 158 | s[2][share] = s[10][share]; 159 | s[10][share] = temp; 160 | 161 | temp = s[6][share]; 162 | s[6][share] = s[14][share]; 163 | s[14][share] = temp; 164 | 165 | // Rotate third row 3 columns to left 166 | temp = s[3][share]; 167 | s[3][share] = s[15][share]; 168 | s[15][share] = s[11][share]; 169 | s[11][share] = s[7][share]; 170 | s[7][share] = temp; 171 | 172 | if(round < 9) { 173 | for(i = 0; i < 16; i += 4) { 174 | r = i; 175 | t = s[r][share]; 176 | Tmp = s[r][share] ^ s[r+1][share] ^ s[r+2][share] ^ s[r+3][share] ; 177 | 178 | Tm = s[r][share] ^ s[r+1][share]; 179 | Tm = xtime(Tm); 180 | s[r+0][share] ^= Tm ^ Tmp; 181 | 182 | Tm = s[r+1][share] ^ s[r+2][share]; 183 | Tm = xtime(Tm); 184 | s[r+1][share] ^= Tm ^ Tmp; 185 | 186 | Tm = s[r+2][share] ^ s[r+3][share]; 187 | Tm = xtime(Tm); 188 | s[r+2][share] ^= Tm ^ Tmp; 189 | 190 | Tm = s[r+3][share] ^ t; 191 | Tm = xtime(Tm); 192 | s[r+3][share] ^= Tm ^ Tmp; 193 | } 194 | } 195 | } 196 | } 197 | 198 | /* 199 | * SecEval Function 200 | * Based on the CPRR SecEval function, this first runs the input 201 | * through the Common Shares function and then uses the first 202 | * technique by Zhang et al. for Random Reduction by 50% 203 | */ 204 | void SecEvalCombined(uint8_t w[16][NUM_SHARES], uint8_t z[16][NUM_SHARES], const uint8_t h[]) { 205 | uint8_t i,j,k,r,s0,t0,t1; 206 | 207 | for(i = 0; i < (NUM_SHARES/2); i++) { 208 | r = getRand(); 209 | for(j = 0; j < 16; j++) { 210 | // Common Shares 211 | z[j][(NUM_SHARES/2) + i] = (z[j][(NUM_SHARES/2) + i] ^ r) ^ z[j][i]; 212 | z[j][i] = r; 213 | 214 | // The first section of the O(n) space complexity CPRR SecEval 215 | w[j][(NUM_SHARES/2) + i] = h[z[j][(NUM_SHARES/2) + i]]; 216 | w[j][i] = h[r]; 217 | } 218 | } 219 | 220 | 221 | for(i = 0; i < NUM_SHARES; i++) { 222 | for(j = (i + 1); j < NUM_SHARES; j++) { 223 | s0 = getRand(); 224 | t0 = h[s0] ^ h[z[0][i] ^ s0]; 225 | t1 = h[(z[0][i] ^ s0) ^ z[0][j]] ^ h[z[0][j] ^ s0]; 226 | w[0][i] ^= t0; 227 | w[0][j] ^= t1; 228 | 229 | // Checks if the function can re-use the values already calculated 230 | if((i < (NUM_SHARES/2)) && (j < (NUM_SHARES/2))) { 231 | for(k = 1; k < 16; k++) { 232 | w[k][i] ^= t0; 233 | w[k][j] ^= t1; 234 | } 235 | } else { 236 | for(k = 1; k < 16; k++) { 237 | s0 = getRand(); 238 | w[k][i] ^= h[s0] ^ h[z[k][i] ^ s0]; 239 | w[k][j] ^= h[(z[k][i] ^ s0) ^ z[k][j]] ^ h[z[k][j] ^ s0]; 240 | } 241 | } 242 | } 243 | } 244 | } 245 | 246 | /* 247 | * SecMult for 16 bytes 248 | */ 249 | void SecMultCombined(uint8_t c[][NUM_SHARES], uint8_t a[][NUM_SHARES], uint8_t b[][NUM_SHARES], const uint8_t f[]) { 250 | uint8_t tmp0, k, i, j; 251 | // First zero out the output array 252 | for(i = 0; i < NUM_SHARES; i++) { 253 | for(k = 0; k < 16; k++) { 254 | c[k][i] = 0; 255 | } 256 | } 257 | // Multiply the masked a and b for each of the 16 bytes 258 | for(i = 0; i < NUM_SHARES; i++) { 259 | for(k = 0; k < 16; k++) { 260 | c[k][i] ^= gfMul(f[a[k][i]],b[k][i]); 261 | for(j = (i+1); j < NUM_SHARES; j++) { 262 | tmp0 = getRand(); 263 | c[k][i] ^= tmp0; 264 | c[k][j] ^= (tmp0 ^ gfMul(f[a[k][i]],b[k][j])) ^ gfMul(f[a[k][j]],b[k][i]); 265 | } 266 | } 267 | } 268 | } 269 | 270 | void SecTwoMultSmall(uint8_t c0[], uint8_t c1[], uint8_t aa0[], uint8_t aa1[], uint8_t bb0[], uint8_t bb1[], const uint8_t f[]) { 271 | uint8_t tmp0, tmp1, i, j; 272 | uint8_t ran = 0; 273 | for(i = 0; i < NUM_SHARES; i++) { 274 | c0[i] = gfMul(f[aa0[i]],bb0[i]); 275 | c1[i] = gfMul(f[aa1[i]],bb1[i]); 276 | } 277 | for(i = 0; i < NUM_SHARES; i++) { 278 | for(j = (i+1); j < NUM_SHARES; j++) { 279 | tmp0 = getRand(); ran++; 280 | c0[i] = c0[i] ^ tmp0; 281 | c0[j] = c0[j] ^ (tmp0 ^ gfMul(f[aa0[i]],bb0[j])) ^ gfMul(f[aa0[j]],bb0[i]); 282 | 283 | tmp1 = getRand(); ran++; 284 | c1[i] = c1[i] ^ tmp1; 285 | c1[j] = c1[j] ^ (tmp1 ^ gfMul(f[aa1[i]],bb1[j])) ^ gfMul(f[aa1[j]],bb1[i]); 286 | } 287 | } 288 | } 289 | 290 | void SecEvalTwoQuadraticRand(uint8_t y0[], uint8_t y1[], uint8_t aa0[], uint8_t aa1[], const uint8_t h[]) { 291 | uint8_t i, j, s0, s1, t0, t1, r; 292 | uint8_t a0[NUM_SHARES]; 293 | uint8_t a1[NUM_SHARES]; 294 | for(i = 0; i < (NUM_SHARES/2); i++) { 295 | r = getRand(); 296 | a0[i] = r; 297 | a1[i] = r; 298 | 299 | a0[(NUM_SHARES/2) + i] = (aa0[(NUM_SHARES/2) + i] ^ r) ^ aa0[i]; 300 | a1[(NUM_SHARES/2) + i] = (aa1[(NUM_SHARES/2) + i] ^ r) ^ aa1[i]; 301 | 302 | y0[i] = h[r]; 303 | y0[(NUM_SHARES/2) + i] = h[a0[(NUM_SHARES/2) + i]]; 304 | y1[i] = h[r]; 305 | y1[(NUM_SHARES/2) + i] = h[a1[(NUM_SHARES/2) + i]]; 306 | } 307 | 308 | for(i = 0; i < NUM_SHARES; i++) { 309 | for(j = (i + 1); j < NUM_SHARES; j++) { 310 | s0 = getRand(); 311 | t0 = h[s0] ^ h[a0[i] ^ s0]; 312 | t1 = h[(a0[i] ^ s0) ^ a0[j]] ^ h[a0[j] ^ s0]; 313 | y0[i] ^= t0; 314 | y0[j] ^= t1; 315 | 316 | if((i < (NUM_SHARES/2)) && (j < (NUM_SHARES/2))) { 317 | y1[i] ^= t0; 318 | y1[j] ^= t1; 319 | } else { 320 | s1 = getRand(); 321 | y1[i] ^= h[s1] ^ h[a1[i] ^ s1]; 322 | y1[j] ^= h[(a1[i] ^ s1) ^ a1[j]] ^ h[a1[j] ^ s1]; 323 | } 324 | } 325 | } 326 | } 327 | 328 | 329 | 330 | -------------------------------------------------------------------------------- /masked_combined.h: -------------------------------------------------------------------------------- 1 | // The number of shares used for masking 2 | #define NUM_SHARES 2 3 | 4 | 5 | 6 | void Encrypt(uint8_t* output, uint8_t* input, uint8_t* key); 7 | void MaskArray(uint8_t y[][NUM_SHARES], uint8_t x[], uint8_t length); 8 | void UnMaskArray(uint8_t y[], uint8_t x[][NUM_SHARES], uint8_t length); 9 | void CombinedSbox(uint8_t s[16][NUM_SHARES]); 10 | void DualSbox(uint8_t y1[], uint8_t y2[], uint8_t x1[], uint8_t x2[]); 11 | void ShiftRowsMixColumns(uint8_t s[][NUM_SHARES], uint8_t round); 12 | void SecEvalCombined(uint8_t w[16][NUM_SHARES], uint8_t z[16][NUM_SHARES], const uint8_t h[]); 13 | void SecMultCombined(uint8_t c[][NUM_SHARES], uint8_t a[][NUM_SHARES], uint8_t b[][NUM_SHARES], const uint8_t f[]); 14 | void SecTwoMultSmall(uint8_t c0[], uint8_t c1[], uint8_t aa0[], uint8_t aa1[], uint8_t bb0[], uint8_t bb1[], const uint8_t f[]); 15 | void SecEvalTwoQuadraticRand(uint8_t y0[], uint8_t y1[], uint8_t aa0[], uint8_t aa1[], const uint8_t h[]); 16 | 17 | 18 | 19 | static const uint8_t fifth[256] = { 20 | 0x00, 0x01, 0x20, 0x33, 0x6c, 0x72, 0x3a, 0x36, 0x2f, 0x8d, 0xc2, 0x72, 0x01, 0xbc, 0x9a, 0x35, 21 | 0x97, 0xd8, 0x10, 0x4d, 0x33, 0x63, 0xc2, 0x80, 0x20, 0xcc, 0x6a, 0x94, 0xc6, 0x35, 0xfa, 0x1b, 22 | 0x7d, 0xcb, 0x5e, 0xfa, 0x36, 0x9f, 0x63, 0xd8, 0x3a, 0x2f, 0xd4, 0xd3, 0x33, 0x39, 0xab, 0xb3, 23 | 0x6c, 0x94, 0xe8, 0x02, 0xef, 0x08, 0x1d, 0xe8, 0xb3, 0xe8, 0xfa, 0xb3, 0x72, 0x36, 0x4d, 0x1b, 24 | 0x39, 0xcb, 0x08, 0xe8, 0x35, 0xd8, 0x72, 0x8d, 0x9a, 0xcb, 0x66, 0x25, 0xd4, 0x9a, 0x5e, 0x02, 25 | 0x01, 0xbd, 0x97, 0x39, 0xc5, 0x66, 0x25, 0x94, 0x3a, 0x25, 0x61, 0x6c, 0xbc, 0xbc, 0x91, 0x83, 26 | 0x2f, 0x6a, 0x1d, 0x4a, 0x04, 0x5e, 0x40, 0x08, 0xe4, 0x02, 0x1b, 0xef, 0x8d, 0x74, 0x04, 0xef, 27 | 0x91, 0x9a, 0x04, 0x1d, 0x72, 0x66, 0x91, 0x97, 0xc2, 0x6a, 0x9a, 0x20, 0x63, 0xd4, 0x4d, 0xe8, 28 | 0x61, 0x25, 0x08, 0x5e, 0x1b, 0x40, 0x04, 0x4d, 0xfa, 0x1d, 0x5e, 0xab, 0xc2, 0x3a, 0x10, 0xfa, 29 | 0xc6, 0xcc, 0x08, 0x10, 0x74, 0x61, 0xcc, 0xcb, 0xc5, 0x6c, 0xc6, 0x7d, 0x35, 0x83, 0x40, 0xe4, 30 | 0x20, 0xd3, 0x4a, 0xab, 0x7d, 0x91, 0x61, 0x9f, 0xd3, 0x83, 0x74, 0x36, 0xcc, 0x83, 0x1d, 0x40, 31 | 0x01, 0xbc, 0xcc, 0x63, 0x94, 0x36, 0x2f, 0x9f, 0x6a, 0x74, 0x6a, 0x66, 0xbd, 0xbc, 0xcb, 0xd8, 32 | 0x97, 0x20, 0xef, 0x4a, 0x8d, 0x25, 0x83, 0x39, 0x80, 0x94, 0x35, 0x33, 0xd8, 0xd3, 0x1b, 0x02, 33 | 0x9f, 0x66, 0x40, 0xab, 0x4d, 0xab, 0xe4, 0x10, 0x10, 0x4a, 0x02, 0x4a, 0x80, 0xc5, 0xe4, 0xb3, 34 | 0xbd, 0xbd, 0xc6, 0xd4, 0x80, 0x9f, 0x8d, 0x80, 0xc2, 0x61, 0x74, 0xc5, 0xbd, 0x01, 0x7d, 0xd3, 35 | 0x33, 0x7d, 0xef, 0xb3, 0xc6, 0x97, 0x6c, 0x2f, 0xd4, 0x39, 0xc5, 0x3a, 0x63, 0x91, 0x04, 0xe4 36 | }; 37 | 38 | static const uint8_t snd[256] = { 39 | 0x00, 0x01, 0x04, 0x05, 0x10, 0x11, 0x14, 0x15, 0x40, 0x41, 0x44, 0x45, 0x50, 0x51, 0x54, 0x55, 40 | 0x1b, 0x1a, 0x1f, 0x1e, 0x0b, 0x0a, 0x0f, 0x0e, 0x5b, 0x5a, 0x5f, 0x5e, 0x4b, 0x4a, 0x4f, 0x4e, 41 | 0x6c, 0x6d, 0x68, 0x69, 0x7c, 0x7d, 0x78, 0x79, 0x2c, 0x2d, 0x28, 0x29, 0x3c, 0x3d, 0x38, 0x39, 42 | 0x77, 0x76, 0x73, 0x72, 0x67, 0x66, 0x63, 0x62, 0x37, 0x36, 0x33, 0x32, 0x27, 0x26, 0x23, 0x22, 43 | 0xab, 0xaa, 0xaf, 0xae, 0xbb, 0xba, 0xbf, 0xbe, 0xeb, 0xea, 0xef, 0xee, 0xfb, 0xfa, 0xff, 0xfe, 44 | 0xb0, 0xb1, 0xb4, 0xb5, 0xa0, 0xa1, 0xa4, 0xa5, 0xf0, 0xf1, 0xf4, 0xf5, 0xe0, 0xe1, 0xe4, 0xe5, 45 | 0xc7, 0xc6, 0xc3, 0xc2, 0xd7, 0xd6, 0xd3, 0xd2, 0x87, 0x86, 0x83, 0x82, 0x97, 0x96, 0x93, 0x92, 46 | 0xdc, 0xdd, 0xd8, 0xd9, 0xcc, 0xcd, 0xc8, 0xc9, 0x9c, 0x9d, 0x98, 0x99, 0x8c, 0x8d, 0x88, 0x89, 47 | 0x9a, 0x9b, 0x9e, 0x9f, 0x8a, 0x8b, 0x8e, 0x8f, 0xda, 0xdb, 0xde, 0xdf, 0xca, 0xcb, 0xce, 0xcf, 48 | 0x81, 0x80, 0x85, 0x84, 0x91, 0x90, 0x95, 0x94, 0xc1, 0xc0, 0xc5, 0xc4, 0xd1, 0xd0, 0xd5, 0xd4, 49 | 0xf6, 0xf7, 0xf2, 0xf3, 0xe6, 0xe7, 0xe2, 0xe3, 0xb6, 0xb7, 0xb2, 0xb3, 0xa6, 0xa7, 0xa2, 0xa3, 50 | 0xed, 0xec, 0xe9, 0xe8, 0xfd, 0xfc, 0xf9, 0xf8, 0xad, 0xac, 0xa9, 0xa8, 0xbd, 0xbc, 0xb9, 0xb8, 51 | 0x31, 0x30, 0x35, 0x34, 0x21, 0x20, 0x25, 0x24, 0x71, 0x70, 0x75, 0x74, 0x61, 0x60, 0x65, 0x64, 52 | 0x2a, 0x2b, 0x2e, 0x2f, 0x3a, 0x3b, 0x3e, 0x3f, 0x6a, 0x6b, 0x6e, 0x6f, 0x7a, 0x7b, 0x7e, 0x7f, 53 | 0x5d, 0x5c, 0x59, 0x58, 0x4d, 0x4c, 0x49, 0x48, 0x1d, 0x1c, 0x19, 0x18, 0x0d, 0x0c, 0x09, 0x08, 54 | 0x46, 0x47, 0x42, 0x43, 0x56, 0x57, 0x52, 0x53, 0x06, 0x07, 0x02, 0x03, 0x16, 0x17, 0x12, 0x13 55 | }; 56 | 57 | static const uint8_t l_affine_snd[256] = { 58 | 0x63, 0x7c, 0x1f, 0x00, 0x92, 0x8d, 0xee, 0xf1, 0xa4, 0xbb, 0xd8, 0xc7, 0x55, 0x4a, 0x29, 0x36, 59 | 0x4b, 0x54, 0x37, 0x28, 0xba, 0xa5, 0xc6, 0xd9, 0x8c, 0x93, 0xf0, 0xef, 0x7d, 0x62, 0x01, 0x1e, 60 | 0xc3, 0xdc, 0xbf, 0xa0, 0x32, 0x2d, 0x4e, 0x51, 0x04, 0x1b, 0x78, 0x67, 0xf5, 0xea, 0x89, 0x96, 61 | 0xeb, 0xf4, 0x97, 0x88, 0x1a, 0x05, 0x66, 0x79, 0x2c, 0x33, 0x50, 0x4f, 0xdd, 0xc2, 0xa1, 0xbe, 62 | 0xd6, 0xc9, 0xaa, 0xb5, 0x27, 0x38, 0x5b, 0x44, 0x11, 0x0e, 0x6d, 0x72, 0xe0, 0xff, 0x9c, 0x83, 63 | 0xfe, 0xe1, 0x82, 0x9d, 0x0f, 0x10, 0x73, 0x6c, 0x39, 0x26, 0x45, 0x5a, 0xc8, 0xd7, 0xb4, 0xab, 64 | 0x76, 0x69, 0x0a, 0x15, 0x87, 0x98, 0xfb, 0xe4, 0xb1, 0xae, 0xcd, 0xd2, 0x40, 0x5f, 0x3c, 0x23, 65 | 0x5e, 0x41, 0x22, 0x3d, 0xaf, 0xb0, 0xd3, 0xcc, 0x99, 0x86, 0xe5, 0xfa, 0x68, 0x77, 0x14, 0x0b, 66 | 0xdb, 0xc4, 0xa7, 0xb8, 0x2a, 0x35, 0x56, 0x49, 0x1c, 0x03, 0x60, 0x7f, 0xed, 0xf2, 0x91, 0x8e, 67 | 0xf3, 0xec, 0x8f, 0x90, 0x02, 0x1d, 0x7e, 0x61, 0x34, 0x2b, 0x48, 0x57, 0xc5, 0xda, 0xb9, 0xa6, 68 | 0x7b, 0x64, 0x07, 0x18, 0x8a, 0x95, 0xf6, 0xe9, 0xbc, 0xa3, 0xc0, 0xdf, 0x4d, 0x52, 0x31, 0x2e, 69 | 0x53, 0x4c, 0x2f, 0x30, 0xa2, 0xbd, 0xde, 0xc1, 0x94, 0x8b, 0xe8, 0xf7, 0x65, 0x7a, 0x19, 0x06, 70 | 0x6e, 0x71, 0x12, 0x0d, 0x9f, 0x80, 0xe3, 0xfc, 0xa9, 0xb6, 0xd5, 0xca, 0x58, 0x47, 0x24, 0x3b, 71 | 0x46, 0x59, 0x3a, 0x25, 0xb7, 0xa8, 0xcb, 0xd4, 0x81, 0x9e, 0xfd, 0xe2, 0x70, 0x6f, 0x0c, 0x13, 72 | 0xce, 0xd1, 0xb2, 0xad, 0x3f, 0x20, 0x43, 0x5c, 0x09, 0x16, 0x75, 0x6a, 0xf8, 0xe7, 0x84, 0x9b, 73 | 0xe6, 0xf9, 0x9a, 0x85, 0x17, 0x08, 0x6b, 0x74, 0x21, 0x3e, 0x5d, 0x42, 0xd0, 0xcf, 0xac, 0xb3 74 | }; 75 | -------------------------------------------------------------------------------- /maths.c: -------------------------------------------------------------------------------- 1 | #include "maths.h" 2 | #include "stdint.h" 3 | uint8_t gfMul(uint8_t a, uint8_t b) { 4 | int s = 0; 5 | #if GFMUL_ASM 6 | __asm__ __volatile__ ( 7 | "ldrb r0, [%[table], %[a]]\n\t" // r0 = table[a] 8 | "ldrb r1, [%[table], %[b]]\n\t" // r1 = table[b] 9 | "add r0, r0, r1\n\t" // r0 = table[a] + table[b] 10 | 11 | 12 | "add %[table], %[table], #255\n\t" 13 | "add %[table], %[table], #1\n\t" 14 | "ldrb r0, [%[table], r0]\n\t" // r0 = atable[r0]; 15 | 16 | // Check if a or b == 0 17 | "mov r1, %[a]\n\t" 18 | "mul r1, r1, %[b]\n\t" 19 | "beq set_zero\n\t" 20 | 21 | "mov %[s], r0\n\t" 22 | "b gfmul_return\n\t" 23 | 24 | "set_zero:" 25 | "mov %[s], #0\n\t" 26 | "b gfmul_return\n\t" 27 | 28 | "gfmul_return:\n\t" 29 | :[s]"+l" (s) 30 | :[a]"l" (a), [b]"l" (b), [table]"l" (table) 31 | :"r0", "r1", "memory" 32 | ); 33 | #else 34 | s = table[a] + table[b]; 35 | int q; 36 | /* Get the antilog */ 37 | s = table[s+256]; 38 | uint8_t z = 0; 39 | q = s; 40 | if(a == 0) { 41 | s = z; 42 | } else { 43 | s = q; 44 | } 45 | if(b == 0) { 46 | s = z; 47 | } else { 48 | q = z; 49 | } 50 | #endif 51 | return s; 52 | } 53 | 54 | uint8_t getRand(void) { 55 | // This should be replace with actual random number generator that isn't terrible 56 | return rand() % 256; 57 | } 58 | -------------------------------------------------------------------------------- /maths.h: -------------------------------------------------------------------------------- 1 | #include "stdint.h" 2 | static const uint8_t table[798] = { 3 | 0x00, 0x00, 0x19, 0x01, 0x32, 0x02, 0x1a, 0xc6, 0x4b, 0xc7, 0x1b, 0x68, 0x33, 0xee, 0xdf, 0x03, 4 | 0x64, 0x04, 0xe0, 0x0e, 0x34, 0x8d, 0x81, 0xef, 0x4c, 0x71, 0x08, 0xc8, 0xf8, 0x69, 0x1c, 0xc1, 5 | 0x7d, 0xc2, 0x1d, 0xb5, 0xf9, 0xb9, 0x27, 0x6a, 0x4d, 0xe4, 0xa6, 0x72, 0x9a, 0xc9, 0x09, 0x78, 6 | 0x65, 0x2f, 0x8a, 0x05, 0x21, 0x0f, 0xe1, 0x24, 0x12, 0xf0, 0x82, 0x45, 0x35, 0x93, 0xda, 0x8e, 7 | 0x96, 0x8f, 0xdb, 0xbd, 0x36, 0xd0, 0xce, 0x94, 0x13, 0x5c, 0xd2, 0xf1, 0x40, 0x46, 0x83, 0x38, 8 | 0x66, 0xdd, 0xfd, 0x30, 0xbf, 0x06, 0x8b, 0x62, 0xb3, 0x25, 0xe2, 0x98, 0x22, 0x88, 0x91, 0x10, 9 | 0x7e, 0x6e, 0x48, 0xc3, 0xa3, 0xb6, 0x1e, 0x42, 0x3a, 0x6b, 0x28, 0x54, 0xfa, 0x85, 0x3d, 0xba, 10 | 0x2b, 0x79, 0x0a, 0x15, 0x9b, 0x9f, 0x5e, 0xca, 0x4e, 0xd4, 0xac, 0xe5, 0xf3, 0x73, 0xa7, 0x57, 11 | 0xaf, 0x58, 0xa8, 0x50, 0xf4, 0xea, 0xd6, 0x74, 0x4f, 0xae, 0xe9, 0xd5, 0xe7, 0xe6, 0xad, 0xe8, 12 | 0x2c, 0xd7, 0x75, 0x7a, 0xeb, 0x16, 0x0b, 0xf5, 0x59, 0xcb, 0x5f, 0xb0, 0x9c, 0xa9, 0x51, 0xa0, 13 | 0x7f, 0x0c, 0xf6, 0x6f, 0x17, 0xc4, 0x49, 0xec, 0xd8, 0x43, 0x1f, 0x2d, 0xa4, 0x76, 0x7b, 0xb7, 14 | 0xcc, 0xbb, 0x3e, 0x5a, 0xfb, 0x60, 0xb1, 0x86, 0x3b, 0x52, 0xa1, 0x6c, 0xaa, 0x55, 0x29, 0x9d, 15 | 0x97, 0xb2, 0x87, 0x90, 0x61, 0xbe, 0xdc, 0xfc, 0xbc, 0x95, 0xcf, 0xcd, 0x37, 0x3f, 0x5b, 0xd1, 16 | 0x53, 0x39, 0x84, 0x3c, 0x41, 0xa2, 0x6d, 0x47, 0x14, 0x2a, 0x9e, 0x5d, 0x56, 0xf2, 0xd3, 0xab, 17 | 0x44, 0x11, 0x92, 0xd9, 0x23, 0x20, 0x2e, 0x89, 0xb4, 0x7c, 0xb8, 0x26, 0x77, 0x99, 0xe3, 0xa5, 18 | 0x67, 0x4a, 0xed, 0xde, 0xc5, 0x31, 0xfe, 0x18, 0x0d, 0x63, 0x8c, 0x80, 0xc0, 0xf7, 0x70, 0x07, 19 | 20 | 21 | 0x01, 0x03, 0x05, 0x0f, 0x11, 0x33, 0x55, 0xff, 0x1a, 0x2e, 0x72, 0x96, 0xa1, 0xf8, 0x13, 0x35, 22 | 0x5f, 0xe1, 0x38, 0x48, 0xd8, 0x73, 0x95, 0xa4, 0xf7, 0x02, 0x06, 0x0a, 0x1e, 0x22, 0x66, 0xaa, 23 | 0xe5, 0x34, 0x5c, 0xe4, 0x37, 0x59, 0xeb, 0x26, 0x6a, 0xbe, 0xd9, 0x70, 0x90, 0xab, 0xe6, 0x31, 24 | 0x53, 0xf5, 0x04, 0x0c, 0x14, 0x3c, 0x44, 0xcc, 0x4f, 0xd1, 0x68, 0xb8, 0xd3, 0x6e, 0xb2, 0xcd, 25 | 0x4c, 0xd4, 0x67, 0xa9, 0xe0, 0x3b, 0x4d, 0xd7, 0x62, 0xa6, 0xf1, 0x08, 0x18, 0x28, 0x78, 0x88, 26 | 0x83, 0x9e, 0xb9, 0xd0, 0x6b, 0xbd, 0xdc, 0x7f, 0x81, 0x98, 0xb3, 0xce, 0x49, 0xdb, 0x76, 0x9a, 27 | 0xb5, 0xc4, 0x57, 0xf9, 0x10, 0x30, 0x50, 0xf0, 0x0b, 0x1d, 0x27, 0x69, 0xbb, 0xd6, 0x61, 0xa3, 28 | 0xfe, 0x19, 0x2b, 0x7d, 0x87, 0x92, 0xad, 0xec, 0x2f, 0x71, 0x93, 0xae, 0xe9, 0x20, 0x60, 0xa0, 29 | 0xfb, 0x16, 0x3a, 0x4e, 0xd2, 0x6d, 0xb7, 0xc2, 0x5d, 0xe7, 0x32, 0x56, 0xfa, 0x15, 0x3f, 0x41, 30 | 0xc3, 0x5e, 0xe2, 0x3d, 0x47, 0xc9, 0x40, 0xc0, 0x5b, 0xed, 0x2c, 0x74, 0x9c, 0xbf, 0xda, 0x75, 31 | 0x9f, 0xba, 0xd5, 0x64, 0xac, 0xef, 0x2a, 0x7e, 0x82, 0x9d, 0xbc, 0xdf, 0x7a, 0x8e, 0x89, 0x80, 32 | 0x9b, 0xb6, 0xc1, 0x58, 0xe8, 0x23, 0x65, 0xaf, 0xea, 0x25, 0x6f, 0xb1, 0xc8, 0x43, 0xc5, 0x54, 33 | 0xfc, 0x1f, 0x21, 0x63, 0xa5, 0xf4, 0x07, 0x09, 0x1b, 0x2d, 0x77, 0x99, 0xb0, 0xcb, 0x46, 0xca, 34 | 0x45, 0xcf, 0x4a, 0xde, 0x79, 0x8b, 0x86, 0x91, 0xa8, 0xe3, 0x3e, 0x42, 0xc6, 0x51, 0xf3, 0x0e, 35 | 0x12, 0x36, 0x5a, 0xee, 0x29, 0x7b, 0x8d, 0x8c, 0x8f, 0x8a, 0x85, 0x94, 0xa7, 0xf2, 0x0d, 0x17, 36 | 0x39, 0x4b, 0xdd, 0x7c, 0x84, 0x97, 0xa2, 0xfd, 0x1c, 0x24, 0x6c, 0xb4, 0xc7, 0x52, 0xf6, 0x01, 37 | 38 | 0x03, 0x05, 0x0f, 0x11, 0x33, 0x55, 0xff, 0x1a, 0x2e, 0x72, 0x96, 0xa1, 0xf8, 0x13, 0x35, 39 | 0x5f, 0xe1, 0x38, 0x48, 0xd8, 0x73, 0x95, 0xa4, 0xf7, 0x02, 0x06, 0x0a, 0x1e, 0x22, 0x66, 0xaa, 40 | 0xe5, 0x34, 0x5c, 0xe4, 0x37, 0x59, 0xeb, 0x26, 0x6a, 0xbe, 0xd9, 0x70, 0x90, 0xab, 0xe6, 0x31, 41 | 0x53, 0xf5, 0x04, 0x0c, 0x14, 0x3c, 0x44, 0xcc, 0x4f, 0xd1, 0x68, 0xb8, 0xd3, 0x6e, 0xb2, 0xcd, 42 | 0x4c, 0xd4, 0x67, 0xa9, 0xe0, 0x3b, 0x4d, 0xd7, 0x62, 0xa6, 0xf1, 0x08, 0x18, 0x28, 0x78, 0x88, 43 | 0x83, 0x9e, 0xb9, 0xd0, 0x6b, 0xbd, 0xdc, 0x7f, 0x81, 0x98, 0xb3, 0xce, 0x49, 0xdb, 0x76, 0x9a, 44 | 0xb5, 0xc4, 0x57, 0xf9, 0x10, 0x30, 0x50, 0xf0, 0x0b, 0x1d, 0x27, 0x69, 0xbb, 0xd6, 0x61, 0xa3, 45 | 0xfe, 0x19, 0x2b, 0x7d, 0x87, 0x92, 0xad, 0xec, 0x2f, 0x71, 0x93, 0xae, 0xe9, 0x20, 0x60, 0xa0, 46 | 0xfb, 0x16, 0x3a, 0x4e, 0xd2, 0x6d, 0xb7, 0xc2, 0x5d, 0xe7, 0x32, 0x56, 0xfa, 0x15, 0x3f, 0x41, 47 | 0xc3, 0x5e, 0xe2, 0x3d, 0x47, 0xc9, 0x40, 0xc0, 0x5b, 0xed, 0x2c, 0x74, 0x9c, 0xbf, 0xda, 0x75, 48 | 0x9f, 0xba, 0xd5, 0x64, 0xac, 0xef, 0x2a, 0x7e, 0x82, 0x9d, 0xbc, 0xdf, 0x7a, 0x8e, 0x89, 0x80, 49 | 0x9b, 0xb6, 0xc1, 0x58, 0xe8, 0x23, 0x65, 0xaf, 0xea, 0x25, 0x6f, 0xb1, 0xc8, 0x43, 0xc5, 0x54, 50 | 0xfc, 0x1f, 0x21, 0x63, 0xa5, 0xf4, 0x07, 0x09, 0x1b, 0x2d, 0x77, 0x99, 0xb0, 0xcb, 0x46, 0xca, 51 | 0x45, 0xcf, 0x4a, 0xde, 0x79, 0x8b, 0x86, 0x91, 0xa8, 0xe3, 0x3e, 0x42, 0xc6, 0x51, 0xf3, 0x0e, 52 | 0x12, 0x36, 0x5a, 0xee, 0x29, 0x7b, 0x8d, 0x8c, 0x8f, 0x8a, 0x85, 0x94, 0xa7, 0xf2, 0x0d, 0x17, 53 | 0x39, 0x4b, 0xdd, 0x7c, 0x84, 0x97, 0xa2, 0xfd, 0x1c, 0x24, 0x6c, 0xb4, 0xc7, 0x52, 0xf6, 0x01 54 | 55 | }; 56 | 57 | #define xtime(x) ((x<<1) ^ (((x>>7) & 1) * 0x1b)) 58 | uint8_t gfMul(uint8_t a, uint8_t b); 59 | uint8_t getRand(void); 60 | --------------------------------------------------------------------------------