comparison aes.c @ 3:ca3a006e292c

add aes.c from http://www.pittnerovi.com/jiri/hobby/electronics/crypto/
author Matt Johnston <matt@ucc.asn.au>
date Tue, 04 Jun 2013 22:11:54 +0800
parents
children 87c8d0a11906
comparison
equal deleted inserted replaced
2:0a6cbbb8c2b7 3:ca3a006e292c
1 // advanced encryption standard
2 // Original author: Karl Malbrain, [email protected]
3 // Ported to Atmel AVR by: Jiri Pittner, [email protected]
4 //
5 /*
6 This work, including the source code, documentation
7 and related data, is placed into the public domain.
8
9 The original author is Karl Malbrain.
10
11 THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY
12 OF ANY KIND, NOT EVEN THE IMPLIED WARRANTY OF
13 MERCHANTABILITY. THE AUTHOR OF THIS SOFTWARE,
14 ASSUMES _NO_ RESPONSIBILITY FOR ANY CONSEQUENCE
15 RESULTING FROM THE USE, MODIFICATION, OR
16 REDISTRIBUTION OF THIS SOFTWARE.
17 */
18
19 #include <stdlib.h>
20 #include <string.h>
21
22 #include <avr/pgmspace.h> //tables have to reside in flash memory
23
24
25 // AES only supports Nb=4
26 #define Nb 4 // number of columns in the state & expanded key
27
28 #define Nk 4 // number of columns in a key
29 #define Nr 10 // number of rounds in encryption
30
31 #define Sbox(i) (pgm_read_byte(&P_Sbox[i]))
32 const unsigned char P_Sbox[256] __attribute__ ((__progmem__)) = { // forward s-box
33 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
34 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
35 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
36 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
37 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
38 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
39 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
40 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
41 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
42 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
43 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
44 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
45 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
46 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
47 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
48 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16};
49
50 #define InvSbox(i) (pgm_read_byte(&P_InvSbox[i]))
51 const unsigned char P_InvSbox[256] __attribute__ ((__progmem__)) = { // inverse s-box
52 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
53 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
54 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
55 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
56 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
57 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
58 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
59 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
60 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
61 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
62 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
63 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
64 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
65 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
66 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
67 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d};
68
69 // combined Xtimes2[Sbox[]]
70 #define Xtime2Sbox(i) (pgm_read_byte(&P_Xtime2Sbox[i]))
71 const unsigned char P_Xtime2Sbox[256] __attribute__ ((__progmem__)) = {
72 0xc6, 0xf8, 0xee, 0xf6, 0xff, 0xd6, 0xde, 0x91, 0x60, 0x02, 0xce, 0x56, 0xe7, 0xb5, 0x4d, 0xec,
73 0x8f, 0x1f, 0x89, 0xfa, 0xef, 0xb2, 0x8e, 0xfb, 0x41, 0xb3, 0x5f, 0x45, 0x23, 0x53, 0xe4, 0x9b,
74 0x75, 0xe1, 0x3d, 0x4c, 0x6c, 0x7e, 0xf5, 0x83, 0x68, 0x51, 0xd1, 0xf9, 0xe2, 0xab, 0x62, 0x2a,
75 0x08, 0x95, 0x46, 0x9d, 0x30, 0x37, 0x0a, 0x2f, 0x0e, 0x24, 0x1b, 0xdf, 0xcd, 0x4e, 0x7f, 0xea,
76 0x12, 0x1d, 0x58, 0x34, 0x36, 0xdc, 0xb4, 0x5b, 0xa4, 0x76, 0xb7, 0x7d, 0x52, 0xdd, 0x5e, 0x13,
77 0xa6, 0xb9, 0x00, 0xc1, 0x40, 0xe3, 0x79, 0xb6, 0xd4, 0x8d, 0x67, 0x72, 0x94, 0x98, 0xb0, 0x85,
78 0xbb, 0xc5, 0x4f, 0xed, 0x86, 0x9a, 0x66, 0x11, 0x8a, 0xe9, 0x04, 0xfe, 0xa0, 0x78, 0x25, 0x4b,
79 0xa2, 0x5d, 0x80, 0x05, 0x3f, 0x21, 0x70, 0xf1, 0x63, 0x77, 0xaf, 0x42, 0x20, 0xe5, 0xfd, 0xbf,
80 0x81, 0x18, 0x26, 0xc3, 0xbe, 0x35, 0x88, 0x2e, 0x93, 0x55, 0xfc, 0x7a, 0xc8, 0xba, 0x32, 0xe6,
81 0xc0, 0x19, 0x9e, 0xa3, 0x44, 0x54, 0x3b, 0x0b, 0x8c, 0xc7, 0x6b, 0x28, 0xa7, 0xbc, 0x16, 0xad,
82 0xdb, 0x64, 0x74, 0x14, 0x92, 0x0c, 0x48, 0xb8, 0x9f, 0xbd, 0x43, 0xc4, 0x39, 0x31, 0xd3, 0xf2,
83 0xd5, 0x8b, 0x6e, 0xda, 0x01, 0xb1, 0x9c, 0x49, 0xd8, 0xac, 0xf3, 0xcf, 0xca, 0xf4, 0x47, 0x10,
84 0x6f, 0xf0, 0x4a, 0x5c, 0x38, 0x57, 0x73, 0x97, 0xcb, 0xa1, 0xe8, 0x3e, 0x96, 0x61, 0x0d, 0x0f,
85 0xe0, 0x7c, 0x71, 0xcc, 0x90, 0x06, 0xf7, 0x1c, 0xc2, 0x6a, 0xae, 0x69, 0x17, 0x99, 0x3a, 0x27,
86 0xd9, 0xeb, 0x2b, 0x22, 0xd2, 0xa9, 0x07, 0x33, 0x2d, 0x3c, 0x15, 0xc9, 0x87, 0xaa, 0x50, 0xa5,
87 0x03, 0x59, 0x09, 0x1a, 0x65, 0xd7, 0x84, 0xd0, 0x82, 0x29, 0x5a, 0x1e, 0x7b, 0xa8, 0x6d, 0x2c
88 };
89
90 // combined Xtimes3[Sbox[]]
91 #define Xtime3Sbox(i) (pgm_read_byte(&P_Xtime3Sbox[i]))
92 const unsigned char P_Xtime3Sbox[256] __attribute__ ((__progmem__)) = {
93 0xa5, 0x84, 0x99, 0x8d, 0x0d, 0xbd, 0xb1, 0x54, 0x50, 0x03, 0xa9, 0x7d, 0x19, 0x62, 0xe6, 0x9a,
94 0x45, 0x9d, 0x40, 0x87, 0x15, 0xeb, 0xc9, 0x0b, 0xec, 0x67, 0xfd, 0xea, 0xbf, 0xf7, 0x96, 0x5b,
95 0xc2, 0x1c, 0xae, 0x6a, 0x5a, 0x41, 0x02, 0x4f, 0x5c, 0xf4, 0x34, 0x08, 0x93, 0x73, 0x53, 0x3f,
96 0x0c, 0x52, 0x65, 0x5e, 0x28, 0xa1, 0x0f, 0xb5, 0x09, 0x36, 0x9b, 0x3d, 0x26, 0x69, 0xcd, 0x9f,
97 0x1b, 0x9e, 0x74, 0x2e, 0x2d, 0xb2, 0xee, 0xfb, 0xf6, 0x4d, 0x61, 0xce, 0x7b, 0x3e, 0x71, 0x97,
98 0xf5, 0x68, 0x00, 0x2c, 0x60, 0x1f, 0xc8, 0xed, 0xbe, 0x46, 0xd9, 0x4b, 0xde, 0xd4, 0xe8, 0x4a,
99 0x6b, 0x2a, 0xe5, 0x16, 0xc5, 0xd7, 0x55, 0x94, 0xcf, 0x10, 0x06, 0x81, 0xf0, 0x44, 0xba, 0xe3,
100 0xf3, 0xfe, 0xc0, 0x8a, 0xad, 0xbc, 0x48, 0x04, 0xdf, 0xc1, 0x75, 0x63, 0x30, 0x1a, 0x0e, 0x6d,
101 0x4c, 0x14, 0x35, 0x2f, 0xe1, 0xa2, 0xcc, 0x39, 0x57, 0xf2, 0x82, 0x47, 0xac, 0xe7, 0x2b, 0x95,
102 0xa0, 0x98, 0xd1, 0x7f, 0x66, 0x7e, 0xab, 0x83, 0xca, 0x29, 0xd3, 0x3c, 0x79, 0xe2, 0x1d, 0x76,
103 0x3b, 0x56, 0x4e, 0x1e, 0xdb, 0x0a, 0x6c, 0xe4, 0x5d, 0x6e, 0xef, 0xa6, 0xa8, 0xa4, 0x37, 0x8b,
104 0x32, 0x43, 0x59, 0xb7, 0x8c, 0x64, 0xd2, 0xe0, 0xb4, 0xfa, 0x07, 0x25, 0xaf, 0x8e, 0xe9, 0x18,
105 0xd5, 0x88, 0x6f, 0x72, 0x24, 0xf1, 0xc7, 0x51, 0x23, 0x7c, 0x9c, 0x21, 0xdd, 0xdc, 0x86, 0x85,
106 0x90, 0x42, 0xc4, 0xaa, 0xd8, 0x05, 0x01, 0x12, 0xa3, 0x5f, 0xf9, 0xd0, 0x91, 0x58, 0x27, 0xb9,
107 0x38, 0x13, 0xb3, 0x33, 0xbb, 0x70, 0x89, 0xa7, 0xb6, 0x22, 0x92, 0x20, 0x49, 0xff, 0x78, 0x7a,
108 0x8f, 0xf8, 0x80, 0x17, 0xda, 0x31, 0xc6, 0xb8, 0xc3, 0xb0, 0x77, 0x11, 0xcb, 0xfc, 0xd6, 0x3a
109 };
110
111 // modular multiplication tables
112 // based on:
113
114 // Xtime2[x] = (x & 0x80 ? 0x1b : 0) ^ (x + x)
115 // Xtime3[x] = x^Xtime2[x];
116
117 #define Xtime2(i) (pgm_read_byte(&P_Xtime2[i]))
118 const unsigned char P_Xtime2[256] __attribute__ ((__progmem__)) = {
119 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e,
120 0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e,
121 0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e,
122 0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e,
123 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e,
124 0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe,
125 0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde,
126 0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee, 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe,
127 0x1b, 0x19, 0x1f, 0x1d, 0x13, 0x11, 0x17, 0x15, 0x0b, 0x09, 0x0f, 0x0d, 0x03, 0x01, 0x07, 0x05,
128 0x3b, 0x39, 0x3f, 0x3d, 0x33, 0x31, 0x37, 0x35, 0x2b, 0x29, 0x2f, 0x2d, 0x23, 0x21, 0x27, 0x25,
129 0x5b, 0x59, 0x5f, 0x5d, 0x53, 0x51, 0x57, 0x55, 0x4b, 0x49, 0x4f, 0x4d, 0x43, 0x41, 0x47, 0x45,
130 0x7b, 0x79, 0x7f, 0x7d, 0x73, 0x71, 0x77, 0x75, 0x6b, 0x69, 0x6f, 0x6d, 0x63, 0x61, 0x67, 0x65,
131 0x9b, 0x99, 0x9f, 0x9d, 0x93, 0x91, 0x97, 0x95, 0x8b, 0x89, 0x8f, 0x8d, 0x83, 0x81, 0x87, 0x85,
132 0xbb, 0xb9, 0xbf, 0xbd, 0xb3, 0xb1, 0xb7, 0xb5, 0xab, 0xa9, 0xaf, 0xad, 0xa3, 0xa1, 0xa7, 0xa5,
133 0xdb, 0xd9, 0xdf, 0xdd, 0xd3, 0xd1, 0xd7, 0xd5, 0xcb, 0xc9, 0xcf, 0xcd, 0xc3, 0xc1, 0xc7, 0xc5,
134 0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed, 0xe3, 0xe1, 0xe7, 0xe5};
135
136 #define Xtime9(i) (pgm_read_byte(&P_Xtime9[i]))
137 const unsigned char P_Xtime9[256] __attribute__ ((__progmem__)) = {
138 0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f, 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77,
139 0x90, 0x99, 0x82, 0x8b, 0xb4, 0xbd, 0xa6, 0xaf, 0xd8, 0xd1, 0xca, 0xc3, 0xfc, 0xf5, 0xee, 0xe7,
140 0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04, 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c,
141 0xab, 0xa2, 0xb9, 0xb0, 0x8f, 0x86, 0x9d, 0x94, 0xe3, 0xea, 0xf1, 0xf8, 0xc7, 0xce, 0xd5, 0xdc,
142 0x76, 0x7f, 0x64, 0x6d, 0x52, 0x5b, 0x40, 0x49, 0x3e, 0x37, 0x2c, 0x25, 0x1a, 0x13, 0x08, 0x01,
143 0xe6, 0xef, 0xf4, 0xfd, 0xc2, 0xcb, 0xd0, 0xd9, 0xae, 0xa7, 0xbc, 0xb5, 0x8a, 0x83, 0x98, 0x91,
144 0x4d, 0x44, 0x5f, 0x56, 0x69, 0x60, 0x7b, 0x72, 0x05, 0x0c, 0x17, 0x1e, 0x21, 0x28, 0x33, 0x3a,
145 0xdd, 0xd4, 0xcf, 0xc6, 0xf9, 0xf0, 0xeb, 0xe2, 0x95, 0x9c, 0x87, 0x8e, 0xb1, 0xb8, 0xa3, 0xaa,
146 0xec, 0xe5, 0xfe, 0xf7, 0xc8, 0xc1, 0xda, 0xd3, 0xa4, 0xad, 0xb6, 0xbf, 0x80, 0x89, 0x92, 0x9b,
147 0x7c, 0x75, 0x6e, 0x67, 0x58, 0x51, 0x4a, 0x43, 0x34, 0x3d, 0x26, 0x2f, 0x10, 0x19, 0x02, 0x0b,
148 0xd7, 0xde, 0xc5, 0xcc, 0xf3, 0xfa, 0xe1, 0xe8, 0x9f, 0x96, 0x8d, 0x84, 0xbb, 0xb2, 0xa9, 0xa0,
149 0x47, 0x4e, 0x55, 0x5c, 0x63, 0x6a, 0x71, 0x78, 0x0f, 0x06, 0x1d, 0x14, 0x2b, 0x22, 0x39, 0x30,
150 0x9a, 0x93, 0x88, 0x81, 0xbe, 0xb7, 0xac, 0xa5, 0xd2, 0xdb, 0xc0, 0xc9, 0xf6, 0xff, 0xe4, 0xed,
151 0x0a, 0x03, 0x18, 0x11, 0x2e, 0x27, 0x3c, 0x35, 0x42, 0x4b, 0x50, 0x59, 0x66, 0x6f, 0x74, 0x7d,
152 0xa1, 0xa8, 0xb3, 0xba, 0x85, 0x8c, 0x97, 0x9e, 0xe9, 0xe0, 0xfb, 0xf2, 0xcd, 0xc4, 0xdf, 0xd6,
153 0x31, 0x38, 0x23, 0x2a, 0x15, 0x1c, 0x07, 0x0e, 0x79, 0x70, 0x6b, 0x62, 0x5d, 0x54, 0x4f, 0x46};
154
155 #define XtimeB(i) (pgm_read_byte(&P_XtimeB[i]))
156 const unsigned char P_XtimeB[256] __attribute__ ((__progmem__)) = {
157 0x00, 0x0b, 0x16, 0x1d, 0x2c, 0x27, 0x3a, 0x31, 0x58, 0x53, 0x4e, 0x45, 0x74, 0x7f, 0x62, 0x69,
158 0xb0, 0xbb, 0xa6, 0xad, 0x9c, 0x97, 0x8a, 0x81, 0xe8, 0xe3, 0xfe, 0xf5, 0xc4, 0xcf, 0xd2, 0xd9,
159 0x7b, 0x70, 0x6d, 0x66, 0x57, 0x5c, 0x41, 0x4a, 0x23, 0x28, 0x35, 0x3e, 0x0f, 0x04, 0x19, 0x12,
160 0xcb, 0xc0, 0xdd, 0xd6, 0xe7, 0xec, 0xf1, 0xfa, 0x93, 0x98, 0x85, 0x8e, 0xbf, 0xb4, 0xa9, 0xa2,
161 0xf6, 0xfd, 0xe0, 0xeb, 0xda, 0xd1, 0xcc, 0xc7, 0xae, 0xa5, 0xb8, 0xb3, 0x82, 0x89, 0x94, 0x9f,
162 0x46, 0x4d, 0x50, 0x5b, 0x6a, 0x61, 0x7c, 0x77, 0x1e, 0x15, 0x08, 0x03, 0x32, 0x39, 0x24, 0x2f,
163 0x8d, 0x86, 0x9b, 0x90, 0xa1, 0xaa, 0xb7, 0xbc, 0xd5, 0xde, 0xc3, 0xc8, 0xf9, 0xf2, 0xef, 0xe4,
164 0x3d, 0x36, 0x2b, 0x20, 0x11, 0x1a, 0x07, 0x0c, 0x65, 0x6e, 0x73, 0x78, 0x49, 0x42, 0x5f, 0x54,
165 0xf7, 0xfc, 0xe1, 0xea, 0xdb, 0xd0, 0xcd, 0xc6, 0xaf, 0xa4, 0xb9, 0xb2, 0x83, 0x88, 0x95, 0x9e,
166 0x47, 0x4c, 0x51, 0x5a, 0x6b, 0x60, 0x7d, 0x76, 0x1f, 0x14, 0x09, 0x02, 0x33, 0x38, 0x25, 0x2e,
167 0x8c, 0x87, 0x9a, 0x91, 0xa0, 0xab, 0xb6, 0xbd, 0xd4, 0xdf, 0xc2, 0xc9, 0xf8, 0xf3, 0xee, 0xe5,
168 0x3c, 0x37, 0x2a, 0x21, 0x10, 0x1b, 0x06, 0x0d, 0x64, 0x6f, 0x72, 0x79, 0x48, 0x43, 0x5e, 0x55,
169 0x01, 0x0a, 0x17, 0x1c, 0x2d, 0x26, 0x3b, 0x30, 0x59, 0x52, 0x4f, 0x44, 0x75, 0x7e, 0x63, 0x68,
170 0xb1, 0xba, 0xa7, 0xac, 0x9d, 0x96, 0x8b, 0x80, 0xe9, 0xe2, 0xff, 0xf4, 0xc5, 0xce, 0xd3, 0xd8,
171 0x7a, 0x71, 0x6c, 0x67, 0x56, 0x5d, 0x40, 0x4b, 0x22, 0x29, 0x34, 0x3f, 0x0e, 0x05, 0x18, 0x13,
172 0xca, 0xc1, 0xdc, 0xd7, 0xe6, 0xed, 0xf0, 0xfb, 0x92, 0x99, 0x84, 0x8f, 0xbe, 0xb5, 0xa8, 0xa3};
173
174 #define XtimeD(i) (pgm_read_byte(&P_XtimeD[i]))
175 const unsigned char P_XtimeD[256] __attribute__ ((__progmem__)) = {
176 0x00, 0x0d, 0x1a, 0x17, 0x34, 0x39, 0x2e, 0x23, 0x68, 0x65, 0x72, 0x7f, 0x5c, 0x51, 0x46, 0x4b,
177 0xd0, 0xdd, 0xca, 0xc7, 0xe4, 0xe9, 0xfe, 0xf3, 0xb8, 0xb5, 0xa2, 0xaf, 0x8c, 0x81, 0x96, 0x9b,
178 0xbb, 0xb6, 0xa1, 0xac, 0x8f, 0x82, 0x95, 0x98, 0xd3, 0xde, 0xc9, 0xc4, 0xe7, 0xea, 0xfd, 0xf0,
179 0x6b, 0x66, 0x71, 0x7c, 0x5f, 0x52, 0x45, 0x48, 0x03, 0x0e, 0x19, 0x14, 0x37, 0x3a, 0x2d, 0x20,
180 0x6d, 0x60, 0x77, 0x7a, 0x59, 0x54, 0x43, 0x4e, 0x05, 0x08, 0x1f, 0x12, 0x31, 0x3c, 0x2b, 0x26,
181 0xbd, 0xb0, 0xa7, 0xaa, 0x89, 0x84, 0x93, 0x9e, 0xd5, 0xd8, 0xcf, 0xc2, 0xe1, 0xec, 0xfb, 0xf6,
182 0xd6, 0xdb, 0xcc, 0xc1, 0xe2, 0xef, 0xf8, 0xf5, 0xbe, 0xb3, 0xa4, 0xa9, 0x8a, 0x87, 0x90, 0x9d,
183 0x06, 0x0b, 0x1c, 0x11, 0x32, 0x3f, 0x28, 0x25, 0x6e, 0x63, 0x74, 0x79, 0x5a, 0x57, 0x40, 0x4d,
184 0xda, 0xd7, 0xc0, 0xcd, 0xee, 0xe3, 0xf4, 0xf9, 0xb2, 0xbf, 0xa8, 0xa5, 0x86, 0x8b, 0x9c, 0x91,
185 0x0a, 0x07, 0x10, 0x1d, 0x3e, 0x33, 0x24, 0x29, 0x62, 0x6f, 0x78, 0x75, 0x56, 0x5b, 0x4c, 0x41,
186 0x61, 0x6c, 0x7b, 0x76, 0x55, 0x58, 0x4f, 0x42, 0x09, 0x04, 0x13, 0x1e, 0x3d, 0x30, 0x27, 0x2a,
187 0xb1, 0xbc, 0xab, 0xa6, 0x85, 0x88, 0x9f, 0x92, 0xd9, 0xd4, 0xc3, 0xce, 0xed, 0xe0, 0xf7, 0xfa,
188 0xb7, 0xba, 0xad, 0xa0, 0x83, 0x8e, 0x99, 0x94, 0xdf, 0xd2, 0xc5, 0xc8, 0xeb, 0xe6, 0xf1, 0xfc,
189 0x67, 0x6a, 0x7d, 0x70, 0x53, 0x5e, 0x49, 0x44, 0x0f, 0x02, 0x15, 0x18, 0x3b, 0x36, 0x21, 0x2c,
190 0x0c, 0x01, 0x16, 0x1b, 0x38, 0x35, 0x22, 0x2f, 0x64, 0x69, 0x7e, 0x73, 0x50, 0x5d, 0x4a, 0x47,
191 0xdc, 0xd1, 0xc6, 0xcb, 0xe8, 0xe5, 0xf2, 0xff, 0xb4, 0xb9, 0xae, 0xa3, 0x80, 0x8d, 0x9a, 0x97};
192
193 #define XtimeE(i) (pgm_read_byte(&P_XtimeE[i]))
194 const unsigned char P_XtimeE[256] __attribute__ ((__progmem__)) = {
195 0x00, 0x0e, 0x1c, 0x12, 0x38, 0x36, 0x24, 0x2a, 0x70, 0x7e, 0x6c, 0x62, 0x48, 0x46, 0x54, 0x5a,
196 0xe0, 0xee, 0xfc, 0xf2, 0xd8, 0xd6, 0xc4, 0xca, 0x90, 0x9e, 0x8c, 0x82, 0xa8, 0xa6, 0xb4, 0xba,
197 0xdb, 0xd5, 0xc7, 0xc9, 0xe3, 0xed, 0xff, 0xf1, 0xab, 0xa5, 0xb7, 0xb9, 0x93, 0x9d, 0x8f, 0x81,
198 0x3b, 0x35, 0x27, 0x29, 0x03, 0x0d, 0x1f, 0x11, 0x4b, 0x45, 0x57, 0x59, 0x73, 0x7d, 0x6f, 0x61,
199 0xad, 0xa3, 0xb1, 0xbf, 0x95, 0x9b, 0x89, 0x87, 0xdd, 0xd3, 0xc1, 0xcf, 0xe5, 0xeb, 0xf9, 0xf7,
200 0x4d, 0x43, 0x51, 0x5f, 0x75, 0x7b, 0x69, 0x67, 0x3d, 0x33, 0x21, 0x2f, 0x05, 0x0b, 0x19, 0x17,
201 0x76, 0x78, 0x6a, 0x64, 0x4e, 0x40, 0x52, 0x5c, 0x06, 0x08, 0x1a, 0x14, 0x3e, 0x30, 0x22, 0x2c,
202 0x96, 0x98, 0x8a, 0x84, 0xae, 0xa0, 0xb2, 0xbc, 0xe6, 0xe8, 0xfa, 0xf4, 0xde, 0xd0, 0xc2, 0xcc,
203 0x41, 0x4f, 0x5d, 0x53, 0x79, 0x77, 0x65, 0x6b, 0x31, 0x3f, 0x2d, 0x23, 0x09, 0x07, 0x15, 0x1b,
204 0xa1, 0xaf, 0xbd, 0xb3, 0x99, 0x97, 0x85, 0x8b, 0xd1, 0xdf, 0xcd, 0xc3, 0xe9, 0xe7, 0xf5, 0xfb,
205 0x9a, 0x94, 0x86, 0x88, 0xa2, 0xac, 0xbe, 0xb0, 0xea, 0xe4, 0xf6, 0xf8, 0xd2, 0xdc, 0xce, 0xc0,
206 0x7a, 0x74, 0x66, 0x68, 0x42, 0x4c, 0x5e, 0x50, 0x0a, 0x04, 0x16, 0x18, 0x32, 0x3c, 0x2e, 0x20,
207 0xec, 0xe2, 0xf0, 0xfe, 0xd4, 0xda, 0xc8, 0xc6, 0x9c, 0x92, 0x80, 0x8e, 0xa4, 0xaa, 0xb8, 0xb6,
208 0x0c, 0x02, 0x10, 0x1e, 0x34, 0x3a, 0x28, 0x26, 0x7c, 0x72, 0x60, 0x6e, 0x44, 0x4a, 0x58, 0x56,
209 0x37, 0x39, 0x2b, 0x25, 0x0f, 0x01, 0x13, 0x1d, 0x47, 0x49, 0x5b, 0x55, 0x7f, 0x71, 0x63, 0x6d,
210 0xd7, 0xd9, 0xcb, 0xc5, 0xef, 0xe1, 0xf3, 0xfd, 0xa7, 0xa9, 0xbb, 0xb5, 0x9f, 0x91, 0x83, 0x8d};
211
212 // exchanges columns in each of 4 rows
213 // row0 - unchanged, row1- shifted left 1,
214 // row2 - shifted left 2 and row3 - shifted left 3
215 void ShiftRows (unsigned char *state)
216 {
217 unsigned char tmp;
218
219 // just substitute row 0
220 state[0] = Sbox(state[0]), state[4] = Sbox(state[4]);
221 state[8] = Sbox(state[8]), state[12] = Sbox(state[12]);
222
223 // rotate row 1
224 tmp = Sbox(state[1]), state[1] = Sbox(state[5]);
225 state[5] = Sbox(state[9]), state[9] = Sbox(state[13]), state[13] = tmp;
226
227 // rotate row 2
228 tmp = Sbox(state[2]), state[2] = Sbox(state[10]), state[10] = tmp;
229 tmp = Sbox(state[6]), state[6] = Sbox(state[14]), state[14] = tmp;
230
231 // rotate row 3
232 tmp = Sbox(state[15]), state[15] = Sbox(state[11]);
233 state[11] = Sbox(state[7]), state[7] = Sbox(state[3]), state[3] = tmp;
234 }
235
236 // restores columns in each of 4 rows
237 // row0 - unchanged, row1- shifted right 1,
238 // row2 - shifted right 2 and row3 - shifted right 3
239 void InvShiftRows (unsigned char *state)
240 {
241 unsigned char tmp;
242
243 // restore row 0
244 state[0] = InvSbox(state[0]), state[4] = InvSbox(state[4]);
245 state[8] = InvSbox(state[8]), state[12] = InvSbox(state[12]);
246
247 // restore row 1
248 tmp = InvSbox(state[13]), state[13] = InvSbox(state[9]);
249 state[9] = InvSbox(state[5]), state[5] = InvSbox(state[1]), state[1] = tmp;
250
251 // restore row 2
252 tmp = InvSbox(state[2]), state[2] = InvSbox(state[10]), state[10] = tmp;
253 tmp = InvSbox(state[6]), state[6] = InvSbox(state[14]), state[14] = tmp;
254
255 // restore row 3
256 tmp = InvSbox(state[3]), state[3] = InvSbox(state[7]);
257 state[7] = InvSbox(state[11]), state[11] = InvSbox(state[15]), state[15] = tmp;
258 }
259
260 // recombine and mix each row in a column
261 void MixSubColumns (unsigned char *state)
262 {
263 unsigned char tmp[4 * Nb];
264
265 // mixing column 0
266 tmp[0] = Xtime2Sbox(state[0]) ^ Xtime3Sbox(state[5]) ^ Sbox(state[10]) ^ Sbox(state[15]);
267 tmp[1] = Sbox(state[0]) ^ Xtime2Sbox(state[5]) ^ Xtime3Sbox(state[10]) ^ Sbox(state[15]);
268 tmp[2] = Sbox(state[0]) ^ Sbox(state[5]) ^ Xtime2Sbox(state[10]) ^ Xtime3Sbox(state[15]);
269 tmp[3] = Xtime3Sbox(state[0]) ^ Sbox(state[5]) ^ Sbox(state[10]) ^ Xtime2Sbox(state[15]);
270
271 // mixing column 1
272 tmp[4] = Xtime2Sbox(state[4]) ^ Xtime3Sbox(state[9]) ^ Sbox(state[14]) ^ Sbox(state[3]);
273 tmp[5] = Sbox(state[4]) ^ Xtime2Sbox(state[9]) ^ Xtime3Sbox(state[14]) ^ Sbox(state[3]);
274 tmp[6] = Sbox(state[4]) ^ Sbox(state[9]) ^ Xtime2Sbox(state[14]) ^ Xtime3Sbox(state[3]);
275 tmp[7] = Xtime3Sbox(state[4]) ^ Sbox(state[9]) ^ Sbox(state[14]) ^ Xtime2Sbox(state[3]);
276
277 // mixing column 2
278 tmp[8] = Xtime2Sbox(state[8]) ^ Xtime3Sbox(state[13]) ^ Sbox(state[2]) ^ Sbox(state[7]);
279 tmp[9] = Sbox(state[8]) ^ Xtime2Sbox(state[13]) ^ Xtime3Sbox(state[2]) ^ Sbox(state[7]);
280 tmp[10] = Sbox(state[8]) ^ Sbox(state[13]) ^ Xtime2Sbox(state[2]) ^ Xtime3Sbox(state[7]);
281 tmp[11] = Xtime3Sbox(state[8]) ^ Sbox(state[13]) ^ Sbox(state[2]) ^ Xtime2Sbox(state[7]);
282
283 // mixing column 3
284 tmp[12] = Xtime2Sbox(state[12]) ^ Xtime3Sbox(state[1]) ^ Sbox(state[6]) ^ Sbox(state[11]);
285 tmp[13] = Sbox(state[12]) ^ Xtime2Sbox(state[1]) ^ Xtime3Sbox(state[6]) ^ Sbox(state[11]);
286 tmp[14] = Sbox(state[12]) ^ Sbox(state[1]) ^ Xtime2Sbox(state[6]) ^ Xtime3Sbox(state[11]);
287 tmp[15] = Xtime3Sbox(state[12]) ^ Sbox(state[1]) ^ Sbox(state[6]) ^ Xtime2Sbox(state[11]);
288
289 memcpy (state, tmp, sizeof(tmp));
290 }
291
292 // restore and un-mix each row in a column
293 void InvMixSubColumns (unsigned char *state)
294 {
295 unsigned char tmp[4 * Nb];
296 int i;
297
298 // restore column 0
299 tmp[0] = XtimeE(state[0]) ^ XtimeB(state[1]) ^ XtimeD(state[2]) ^ Xtime9(state[3]);
300 tmp[5] = Xtime9(state[0]) ^ XtimeE(state[1]) ^ XtimeB(state[2]) ^ XtimeD(state[3]);
301 tmp[10] = XtimeD(state[0]) ^ Xtime9(state[1]) ^ XtimeE(state[2]) ^ XtimeB(state[3]);
302 tmp[15] = XtimeB(state[0]) ^ XtimeD(state[1]) ^ Xtime9(state[2]) ^ XtimeE(state[3]);
303
304 // restore column 1
305 tmp[4] = XtimeE(state[4]) ^ XtimeB(state[5]) ^ XtimeD(state[6]) ^ Xtime9(state[7]);
306 tmp[9] = Xtime9(state[4]) ^ XtimeE(state[5]) ^ XtimeB(state[6]) ^ XtimeD(state[7]);
307 tmp[14] = XtimeD(state[4]) ^ Xtime9(state[5]) ^ XtimeE(state[6]) ^ XtimeB(state[7]);
308 tmp[3] = XtimeB(state[4]) ^ XtimeD(state[5]) ^ Xtime9(state[6]) ^ XtimeE(state[7]);
309
310 // restore column 2
311 tmp[8] = XtimeE(state[8]) ^ XtimeB(state[9]) ^ XtimeD(state[10]) ^ Xtime9(state[11]);
312 tmp[13] = Xtime9(state[8]) ^ XtimeE(state[9]) ^ XtimeB(state[10]) ^ XtimeD(state[11]);
313 tmp[2] = XtimeD(state[8]) ^ Xtime9(state[9]) ^ XtimeE(state[10]) ^ XtimeB(state[11]);
314 tmp[7] = XtimeB(state[8]) ^ XtimeD(state[9]) ^ Xtime9(state[10]) ^ XtimeE(state[11]);
315
316 // restore column 3
317 tmp[12] = XtimeE(state[12]) ^ XtimeB(state[13]) ^ XtimeD(state[14]) ^ Xtime9(state[15]);
318 tmp[1] = Xtime9(state[12]) ^ XtimeE(state[13]) ^ XtimeB(state[14]) ^ XtimeD(state[15]);
319 tmp[6] = XtimeD(state[12]) ^ Xtime9(state[13]) ^ XtimeE(state[14]) ^ XtimeB(state[15]);
320 tmp[11] = XtimeB(state[12]) ^ XtimeD(state[13]) ^ Xtime9(state[14]) ^ XtimeE(state[15]);
321
322 for( i=0; i < 4 * Nb; i++ )
323 state[i] = InvSbox(tmp[i]);
324 }
325
326 // encrypt/decrypt columns of the key
327 // n.b. you can replace this with
328 // byte-wise xor if you wish.
329
330 void AddRoundKey (unsigned *state, unsigned *key)
331 {
332 int idx;
333
334 for( idx = 0; idx < 4; idx++ )
335 state[idx] ^= key[idx];
336 }
337
338 unsigned char Rcon[11] = {
339 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36};
340
341 // produce Nb bytes for each round
342 void ExpandKey (unsigned char *key, unsigned char *expkey)
343 {
344 unsigned char tmp0, tmp1, tmp2, tmp3, tmp4;
345 unsigned idx;
346
347 memcpy (expkey, key, Nk * 4);
348
349 for( idx = Nk; idx < Nb * (Nr + 1); idx++ ) {
350 tmp0 = expkey[4*idx - 4];
351 tmp1 = expkey[4*idx - 3];
352 tmp2 = expkey[4*idx - 2];
353 tmp3 = expkey[4*idx - 1];
354 if( !(idx % Nk) ) {
355 tmp4 = tmp3;
356 tmp3 = Sbox(tmp0);
357 tmp0 = Sbox(tmp1) ^ Rcon[idx/Nk];
358 tmp1 = Sbox(tmp2);
359 tmp2 = Sbox(tmp4);
360 } else if( Nk > 6 && idx % Nk == 4 ) {
361 tmp0 = Sbox(tmp0);
362 tmp1 = Sbox(tmp1);
363 tmp2 = Sbox(tmp2);
364 tmp3 = Sbox(tmp3);
365 }
366
367 expkey[4*idx+0] = expkey[4*idx - 4*Nk + 0] ^ tmp0;
368 expkey[4*idx+1] = expkey[4*idx - 4*Nk + 1] ^ tmp1;
369 expkey[4*idx+2] = expkey[4*idx - 4*Nk + 2] ^ tmp2;
370 expkey[4*idx+3] = expkey[4*idx - 4*Nk + 3] ^ tmp3;
371 }
372 }
373
374 // encrypt one 128 bit block
375 void Encrypt (unsigned char *in, unsigned char *expkey, unsigned char *out)
376 {
377 unsigned char state[Nb * 4];
378 unsigned round;
379
380 memcpy (state, in, Nb * 4);
381 AddRoundKey ((unsigned *)state, (unsigned *)expkey);
382
383 for( round = 1; round < Nr + 1; round++ ) {
384 if( round < Nr )
385 MixSubColumns (state);
386 else
387 ShiftRows (state);
388
389 AddRoundKey ((unsigned *)state, (unsigned *)expkey + round * Nb);
390 }
391
392 memcpy (out, state, sizeof(state));
393 }
394
395 void Decrypt (unsigned char *in, unsigned char *expkey, unsigned char *out)
396 {
397 unsigned char state[Nb * 4];
398 unsigned round;
399
400 memcpy (state, in, sizeof(state));
401
402 AddRoundKey ((unsigned *)state, (unsigned *)expkey + Nr * Nb);
403 InvShiftRows(state);
404
405 for( round = Nr; round--; )
406 {
407 AddRoundKey ((unsigned *)state, (unsigned *)expkey + round * Nb);
408 if( round )
409 InvMixSubColumns (state);
410 }
411
412 memcpy (out, state, sizeof(state));
413 }
414
415
416 /*avr specific routines*/
417 #include "backward.h"
418 #include <avr/io.h>
419 #include <avr/pgmspace.h>
420 #include <avr/eeprom.h>
421 #include <avr/interrupt.h>
422 #include <avr/sleep.h>
423
424
425
426 #if defined(at90s2313) || defined(at90s8535)
427 #else
428 #define ATmega
429 #endif
430
431 #ifdef ATmega
432 #define USR UCSRA
433 #endif
434
435
436
437 void printP (PGM_P string){
438 char c;
439 c=pgm_read_byte(string);
440 while (c) {
441 loop_until_bit_is_set(USR, UDRE);
442 UDR = c;
443 c=pgm_read_byte(++string);
444 }
445 return;
446 }
447
448
449
450 void print (const char *string){
451 while (*string) {
452 loop_until_bit_is_set(USR, UDRE);
453 UDR = *string++;
454 }
455 return;
456 }
457
458 void scan(char *string){
459 char c;
460 do {
461 do {
462 loop_until_bit_is_set(USR, RXC);
463 c =UDR;
464 } while bit_is_set(USR, FE);
465 *string++ = c;
466 //echo the character
467 loop_until_bit_is_set(USR, UDRE);
468 UDR = c;
469 } while ( c != '\r' );
470 loop_until_bit_is_set(USR, UDRE);
471 UDR = '\n';
472 string[-1]=0;
473 }
474
475
476 //UART initialize
477 #ifdef ATmega
478 #define UCR UCSRB
479 #define UART_INIT(baud) { \
480 UBRRH=0; \
481 UBRRL= (XTAL/baud+15)/16-1; \
482 UCSRB=(1<<TXEN)|(1<<RXEN); \
483 UCSRC=(1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1)|(1<<USBS); }
484 #else
485 #define UART_INIT(baud) { \
486 UBRR = (XTAL/baud+15)/16-1; \
487 sbi(UCR, TXEN); \
488 sbi(UCR, RXEN); \
489 }
490 #endif
491
492 #define itoa10(N,S) itoa(N,S,10)
493 #define itoa16(N,S) itoa(N,S,16)
494
495
496 //DEMO
497
498 unsigned char sampleout[16];
499
500
501 unsigned char samplekey[] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab,
502 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
503
504 unsigned char samplein[] = {0x32, 0x43, 0xf6, 0xa8, 0x88, 0x5a, 0x30, 0x8d, 0x31,
505 0x31, 0x98, 0xa2, 0xe0, 0x37, 0x07, 0x34};
506
507 #define BAUD 115200
508
509 int main(void)
510 {
511 UART_INIT(BAUD);
512
513 unsigned char expkey[4 * Nb * (Nr + 1)];
514 unsigned char i;
515 char c[8];
516
517 printP(PSTR("Original: "));
518 for( i = 0; i < 16; i++ ) {itoa16(samplein[i],c);print(c); print(" ");}
519 printP(PSTR("\n"));
520
521 ExpandKey (samplekey, expkey);
522 Encrypt (samplein, expkey, sampleout);
523
524 printP(PSTR("Encrypted: "));
525 for( i = 0; i < 16; i++ ) {itoa16(sampleout[i],c);print(c); print(" ");}
526 printP(PSTR("\n"));
527
528 Decrypt (sampleout, expkey, samplein);
529
530 printP(PSTR("Decrypted: "));
531
532 for( i = 0; i < 16; i++ ) {itoa16(samplein[i],c);print(c); print(" ");}
533 printP(PSTR("\n"));
534 }
535