]> git.cryptolib.org Git - avr-crypto-lib.git/blob - test_src/main-rsa_oaep-test.c
adding RSA-OAEP
[avr-crypto-lib.git] / test_src / main-rsa_oaep-test.c
1 /* main-dsa-test.c */
2 /*
3     This file is part of the ARM-Crypto-Lib.
4     Copyright (C) 2010 Daniel Otte (daniel.otte@rub.de)
5
6     This program is free software: you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation, either version 3 of the License, or
9     (at your option) any later version.
10
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19 /*
20  * RSA test-suit
21  *
22 */
23 #include "main-test-common.h"
24
25 #include "noekeon.h"
26 #include "noekeon_prng.h"
27 #include "bigint.h"
28 #include "bigint_io.h"
29 #include "random_dummy.h"
30 #include "rsa_basic.h"
31 #include "rsa_oaep.h"
32
33 #include "performance_test.h"
34
35 const char* algo_name = "RSA-OAEP";
36
37 #define BIGINT_CEIL(x) ((((x) + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t)) *  sizeof(bigint_word_t))
38 #define BIGINT_OFF(x) ((sizeof(bigint_word_t) - (x) % sizeof(bigint_word_t)) % sizeof(bigint_word_t))
39
40 /*****************************************************************************
41  *  additional validation-functions                                                                                      *
42  *****************************************************************************/
43 #if 0
44 /* ==================================
45  * Example 1: A 1024-bit RSA Key Pair
46  * ================================== */
47
48 /* ------------------------------
49  * Components of the RSA Key Pair
50  * ------------------------------ */
51
52 /* RSA modulus n: */
53 const uint8_t modulus[] = {
54 0xa8, 0xb3, 0xb2, 0x84, 0xaf, 0x8e, 0xb5, 0x0b, 0x38, 0x70, 0x34, 0xa8, 0x60, 0xf1, 0x46, 0xc4,
55 0x91, 0x9f, 0x31, 0x87, 0x63, 0xcd, 0x6c, 0x55, 0x98, 0xc8, 0xae, 0x48, 0x11, 0xa1, 0xe0, 0xab,
56 0xc4, 0xc7, 0xe0, 0xb0, 0x82, 0xd6, 0x93, 0xa5, 0xe7, 0xfc, 0xed, 0x67, 0x5c, 0xf4, 0x66, 0x85,
57 0x12, 0x77, 0x2c, 0x0c, 0xbc, 0x64, 0xa7, 0x42, 0xc6, 0xc6, 0x30, 0xf5, 0x33, 0xc8, 0xcc, 0x72,
58 0xf6, 0x2a, 0xe8, 0x33, 0xc4, 0x0b, 0xf2, 0x58, 0x42, 0xe9, 0x84, 0xbb, 0x78, 0xbd, 0xbf, 0x97,
59 0xc0, 0x10, 0x7d, 0x55, 0xbd, 0xb6, 0x62, 0xf5, 0xc4, 0xe0, 0xfa, 0xb9, 0x84, 0x5c, 0xb5, 0x14,
60 0x8e, 0xf7, 0x39, 0x2d, 0xd3, 0xaa, 0xff, 0x93, 0xae, 0x1e, 0x6b, 0x66, 0x7b, 0xb3, 0xd4, 0x24,
61 0x76, 0x16, 0xd4, 0xf5, 0xba, 0x10, 0xd4, 0xcf, 0xd2, 0x26, 0xde, 0x88, 0xd3, 0x9f, 0x16, 0xfb
62 };
63
64 /* RSA public exponent e: */
65 const uint8_t public_exponent[] = {
66 0x00, 0x01, 0x00, 0x01
67 };
68
69 /* RSA private exponent d: */
70 const uint8_t private_exponent[] = {
71 0x53, 0x33, 0x9c, 0xfd, 0xb7, 0x9f, 0xc8, 0x46, 0x6a, 0x65, 0x5c, 0x73, 0x16, 0xac, 0xa8, 0x5c,
72 0x55, 0xfd, 0x8f, 0x6d, 0xd8, 0x98, 0xfd, 0xaf, 0x11, 0x95, 0x17, 0xef, 0x4f, 0x52, 0xe8, 0xfd,
73 0x8e, 0x25, 0x8d, 0xf9, 0x3f, 0xee, 0x18, 0x0f, 0xa0, 0xe4, 0xab, 0x29, 0x69, 0x3c, 0xd8, 0x3b,
74 0x15, 0x2a, 0x55, 0x3d, 0x4a, 0xc4, 0xd1, 0x81, 0x2b, 0x8b, 0x9f, 0xa5, 0xaf, 0x0e, 0x7f, 0x55,
75 0xfe, 0x73, 0x04, 0xdf, 0x41, 0x57, 0x09, 0x26, 0xf3, 0x31, 0x1f, 0x15, 0xc4, 0xd6, 0x5a, 0x73,
76 0x2c, 0x48, 0x31, 0x16, 0xee, 0x3d, 0x3d, 0x2d, 0x0a, 0xf3, 0x54, 0x9a, 0xd9, 0xbf, 0x7c, 0xbf,
77 0xb7, 0x8a, 0xd8, 0x84, 0xf8, 0x4d, 0x5b, 0xeb, 0x04, 0x72, 0x4d, 0xc7, 0x36, 0x9b, 0x31, 0xde,
78 0xf3, 0x7d, 0x0c, 0xf5, 0x39, 0xe9, 0xcf, 0xcd, 0xd3, 0xde, 0x65, 0x37, 0x29, 0xea, 0xd5, 0xd1
79 };
80
81 /* Prime p: */
82 const uint8_t p[] = {
83 0xd3, 0x27, 0x37, 0xe7, 0x26, 0x7f, 0xfe, 0x13, 0x41, 0xb2, 0xd5, 0xc0, 0xd1, 0x50, 0xa8, 0x1b,
84 0x58, 0x6f, 0xb3, 0x13, 0x2b, 0xed, 0x2f, 0x8d, 0x52, 0x62, 0x86, 0x4a, 0x9c, 0xb9, 0xf3, 0x0a,
85 0xf3, 0x8b, 0xe4, 0x48, 0x59, 0x8d, 0x41, 0x3a, 0x17, 0x2e, 0xfb, 0x80, 0x2c, 0x21, 0xac, 0xf1,
86 0xc1, 0x1c, 0x52, 0x0c, 0x2f, 0x26, 0xa4, 0x71, 0xdc, 0xad, 0x21, 0x2e, 0xac, 0x7c, 0xa3, 0x9d
87 };
88
89 /* Prime q: */
90 const uint8_t q[] = {
91 0xcc, 0x88, 0x53, 0xd1, 0xd5, 0x4d, 0xa6, 0x30, 0xfa, 0xc0, 0x04, 0xf4, 0x71, 0xf2, 0x81, 0xc7,
92 0xb8, 0x98, 0x2d, 0x82, 0x24, 0xa4, 0x90, 0xed, 0xbe, 0xb3, 0x3d, 0x3e, 0x3d, 0x5c, 0xc9, 0x3c,
93 0x47, 0x65, 0x70, 0x3d, 0x1d, 0xd7, 0x91, 0x64, 0x2f, 0x1f, 0x11, 0x6a, 0x0d, 0xd8, 0x52, 0xbe,
94 0x24, 0x19, 0xb2, 0xaf, 0x72, 0xbf, 0xe9, 0xa0, 0x30, 0xe8, 0x60, 0xb0, 0x28, 0x8b, 0x5d, 0x77
95 };
96
97 /* p's CRT exponent dP: */
98 const uint8_t dp[] = {
99 0x0e, 0x12, 0xbf, 0x17, 0x18, 0xe9, 0xce, 0xf5, 0x59, 0x9b, 0xa1, 0xc3, 0x88, 0x2f, 0xe8, 0x04,
100 0x6a, 0x90, 0x87, 0x4e, 0xef, 0xce, 0x8f, 0x2c, 0xcc, 0x20, 0xe4, 0xf2, 0x74, 0x1f, 0xb0, 0xa3,
101 0x3a, 0x38, 0x48, 0xae, 0xc9, 0xc9, 0x30, 0x5f, 0xbe, 0xcb, 0xd2, 0xd7, 0x68, 0x19, 0x96, 0x7d,
102 0x46, 0x71, 0xac, 0xc6, 0x43, 0x1e, 0x40, 0x37, 0x96, 0x8d, 0xb3, 0x78, 0x78, 0xe6, 0x95, 0xc1
103 };
104
105 /* q's CRT exponent dQ: */
106 const uint8_t dq[] = {
107 0x95, 0x29, 0x7b, 0x0f, 0x95, 0xa2, 0xfa, 0x67, 0xd0, 0x07, 0x07, 0xd6, 0x09, 0xdf, 0xd4, 0xfc,
108 0x05, 0xc8, 0x9d, 0xaf, 0xc2, 0xef, 0x6d, 0x6e, 0xa5, 0x5b, 0xec, 0x77, 0x1e, 0xa3, 0x33, 0x73,
109 0x4d, 0x92, 0x51, 0xe7, 0x90, 0x82, 0xec, 0xda, 0x86, 0x6e, 0xfe, 0xf1, 0x3c, 0x45, 0x9e, 0x1a,
110 0x63, 0x13, 0x86, 0xb7, 0xe3, 0x54, 0xc8, 0x99, 0xf5, 0xf1, 0x12, 0xca, 0x85, 0xd7, 0x15, 0x83
111 };
112
113 /* CRT coefficient qInv: */
114 const uint8_t qinv[] = {
115 0x4f, 0x45, 0x6c, 0x50, 0x24, 0x93, 0xbd, 0xc0, 0xed, 0x2a, 0xb7, 0x56, 0xa3, 0xa6, 0xed, 0x4d,
116 0x67, 0x35, 0x2a, 0x69, 0x7d, 0x42, 0x16, 0xe9, 0x32, 0x12, 0xb1, 0x27, 0xa6, 0x3d, 0x54, 0x11,
117 0xce, 0x6f, 0xa9, 0x8d, 0x5d, 0xbe, 0xfd, 0x73, 0x26, 0x3e, 0x37, 0x28, 0x14, 0x27, 0x43, 0x81,
118 0x81, 0x66, 0xed, 0x7d, 0xd6, 0x36, 0x87, 0xdd, 0x2a, 0x8c, 0xa1, 0xd2, 0xf4, 0xfb, 0xd8, 0xe1
119 };
120
121 /* ---------------------------------
122  * RSAES-OAEP Encryption Example 1.1
123  * --------------------------------- */
124
125 /* Message to be, encrypted: */
126 const uint8_t message[] = {
127 0x66, 0x28, 0x19, 0x4e, 0x12, 0x07, 0x3d, 0xb0, 0x3b, 0xa9, 0x4c, 0xda, 0x9e, 0xf9, 0x53, 0x23,
128 0x97, 0xd5, 0x0d, 0xba, 0x79, 0xb9, 0x87, 0x00, 0x4a, 0xfe, 0xfe, 0x34
129 };
130
131 /* Seed: */
132 const uint8_t seed[] = {
133 0x18, 0xb7, 0x76, 0xea, 0x21, 0x06, 0x9d, 0x69, 0x77, 0x6a, 0x33, 0xe9, 0x6b, 0xad, 0x48, 0xe1,
134 0xdd, 0xa0, 0xa5, 0xef
135 };
136
137 /* Encryption: */
138 const uint8_t encrypted[] = {
139 0x35, 0x4f, 0xe6, 0x7b, 0x4a, 0x12, 0x6d, 0x5d, 0x35, 0xfe, 0x36, 0xc7, 0x77, 0x79, 0x1a, 0x3f,
140 0x7b, 0xa1, 0x3d, 0xef, 0x48, 0x4e, 0x2d, 0x39, 0x08, 0xaf, 0xf7, 0x22, 0xfa, 0xd4, 0x68, 0xfb,
141 0x21, 0x69, 0x6d, 0xe9, 0x5d, 0x0b, 0xe9, 0x11, 0xc2, 0xd3, 0x17, 0x4f, 0x8a, 0xfc, 0xc2, 0x01,
142 0x03, 0x5f, 0x7b, 0x6d, 0x8e, 0x69, 0x40, 0x2d, 0xe5, 0x45, 0x16, 0x18, 0xc2, 0x1a, 0x53, 0x5f,
143 0xa9, 0xd7, 0xbf, 0xc5, 0xb8, 0xdd, 0x9f, 0xc2, 0x43, 0xf8, 0xcf, 0x92, 0x7d, 0xb3, 0x13, 0x22,
144 0xd6, 0xe8, 0x81, 0xea, 0xa9, 0x1a, 0x99, 0x61, 0x70, 0xe6, 0x57, 0xa0, 0x5a, 0x26, 0x64, 0x26,
145 0xd9, 0x8c, 0x88, 0x00, 0x3f, 0x84, 0x77, 0xc1, 0x22, 0x70, 0x94, 0xa0, 0xd9, 0xfa, 0x1e, 0x8c,
146 0x40, 0x24, 0x30, 0x9c, 0xe1, 0xec, 0xcc, 0xb5, 0x21, 0x00, 0x35, 0xd4, 0x7a, 0xc7, 0x2e, 0x8a
147 };
148
149 /* Message to be encrypted: */
150 const uint8_t message2[] = {
151 0x75, 0x0c, 0x40, 0x47, 0xf5, 0x47, 0xe8, 0xe4, 0x14, 0x11, 0x85, 0x65, 0x23, 0x29, 0x8a, 0xc9,
152 0xba, 0xe2, 0x45, 0xef, 0xaf, 0x13, 0x97, 0xfb, 0xe5, 0x6f, 0x9d, 0xd5
153 };
154
155 /* Seed: */
156 const uint8_t seed2[] = {
157 0x0c, 0xc7, 0x42, 0xce, 0x4a, 0x9b, 0x7f, 0x32, 0xf9, 0x51, 0xbc, 0xb2, 0x51, 0xef, 0xd9, 0x25,
158 0xfe, 0x4f, 0xe3, 0x5f
159 };
160
161 /* Encryption: */
162 const uint8_t encrypted2[] = {
163 0x64, 0x0d, 0xb1, 0xac, 0xc5, 0x8e, 0x05, 0x68, 0xfe, 0x54, 0x07, 0xe5, 0xf9, 0xb7, 0x01, 0xdf,
164 0xf8, 0xc3, 0xc9, 0x1e, 0x71, 0x6c, 0x53, 0x6f, 0xc7, 0xfc, 0xec, 0x6c, 0xb5, 0xb7, 0x1c, 0x11,
165 0x65, 0x98, 0x8d, 0x4a, 0x27, 0x9e, 0x15, 0x77, 0xd7, 0x30, 0xfc, 0x7a, 0x29, 0x93, 0x2e, 0x3f,
166 0x00, 0xc8, 0x15, 0x15, 0x23, 0x6d, 0x8d, 0x8e, 0x31, 0x01, 0x7a, 0x7a, 0x09, 0xdf, 0x43, 0x52,
167 0xd9, 0x04, 0xcd, 0xeb, 0x79, 0xaa, 0x58, 0x3a, 0xdc, 0xc3, 0x1e, 0xa6, 0x98, 0xa4, 0xc0, 0x52,
168 0x83, 0xda, 0xba, 0x90, 0x89, 0xbe, 0x54, 0x91, 0xf6, 0x7c, 0x1a, 0x4e, 0xe4, 0x8d, 0xc7, 0x4b,
169 0xbb, 0xe6, 0x64, 0x3a, 0xef, 0x84, 0x66, 0x79, 0xb4, 0xcb, 0x39, 0x5a, 0x35, 0x2d, 0x5e, 0xd1,
170 0x15, 0x91, 0x2d, 0xf6, 0x96, 0xff, 0xe0, 0x70, 0x29, 0x32, 0x94, 0x6d, 0x71, 0x49, 0x2b, 0x44
171 };
172
173 /**********************************************************************************************/
174 /* ---------------------------------
175  * RSAES-OAEP Encryption Example 2.1
176  * --------------------------------- */
177
178 /* Message to be encrypted: */
179 const uint8_t message3[] = {
180 0x8f, 0xf0, 0x0c, 0xaa, 0x60, 0x5c, 0x70, 0x28, 0x30, 0x63, 0x4d, 0x9a, 0x6c, 0x3d, 0x42, 0xc6,
181 0x52, 0xb5, 0x8c, 0xf1, 0xd9, 0x2f, 0xec, 0x57, 0x0b, 0xee, 0xe7
182 };
183
184 /* Seed: */
185 const uint8_t seed3[] = {
186 0x8c, 0x40, 0x7b, 0x5e, 0xc2, 0x89, 0x9e, 0x50, 0x99, 0xc5, 0x3e, 0x8c, 0xe7, 0x93, 0xbf, 0x94,
187 0xe7, 0x1b, 0x17, 0x82
188 };
189
190 /* Encryption: */
191 const uint8_t encrypted3[] = {
192 0x01, 0x81, 0xaf, 0x89, 0x22, 0xb9, 0xfc, 0xb4, 0xd7, 0x9d, 0x92, 0xeb, 0xe1, 0x98, 0x15, 0x99,
193 0x2f, 0xc0, 0xc1, 0x43, 0x9d, 0x8b, 0xcd, 0x49, 0x13, 0x98, 0xa0, 0xf4, 0xad, 0x3a, 0x32, 0x9a,
194 0x5b, 0xd9, 0x38, 0x55, 0x60, 0xdb, 0x53, 0x26, 0x83, 0xc8, 0xb7, 0xda, 0x04, 0xe4, 0xb1, 0x2a,
195 0xed, 0x6a, 0xac, 0xdf, 0x47, 0x1c, 0x34, 0xc9, 0xcd, 0xa8, 0x91, 0xad, 0xdc, 0xc2, 0xdf, 0x34,
196 0x56, 0x65, 0x3a, 0xa6, 0x38, 0x2e, 0x9a, 0xe5, 0x9b, 0x54, 0x45, 0x52, 0x57, 0xeb, 0x09, 0x9d,
197 0x56, 0x2b, 0xbe, 0x10, 0x45, 0x3f, 0x2b, 0x6d, 0x13, 0xc5, 0x9c, 0x02, 0xe1, 0x0f, 0x1f, 0x8a,
198 0xbb, 0x5d, 0xa0, 0xd0, 0x57, 0x09, 0x32, 0xda, 0xcf, 0x2d, 0x09, 0x01, 0xdb, 0x72, 0x9d, 0x0f,
199 0xef, 0xcc, 0x05, 0x4e, 0x70, 0x96, 0x8e, 0xa5, 0x40, 0xc8, 0x1b, 0x04, 0xbc, 0xae, 0xfe, 0x72,
200 0x0e
201 };
202 #endif
203 /**********************************************************************************************/
204
205 /* ---------------------------------
206  * RSAES-OAEP Encryption Example 2.4
207  * --------------------------------- */
208
209 /* Message to be encrypted: */
210 const uint8_t message4[] PROGMEM = {
211 0xa7, 0xeb, 0x2a, 0x50, 0x36, 0x93, 0x1d, 0x27, 0xd4, 0xe8, 0x91, 0x32, 0x6d, 0x99, 0x69, 0x2f,
212 0xfa, 0xdd, 0xa9, 0xbf, 0x7e, 0xfd, 0x3e, 0x34, 0xe6, 0x22, 0xc4, 0xad, 0xc0, 0x85, 0xf7, 0x21,
213 0xdf, 0xe8, 0x85, 0x07, 0x2c, 0x78, 0xa2, 0x03, 0xb1, 0x51, 0x73, 0x9b, 0xe5, 0x40, 0xfa, 0x8c,
214 0x15, 0x3a, 0x10, 0xf0, 0x0a
215 };
216
217 /* Seed: */
218 const uint8_t seed4[] PROGMEM = {
219 0x9a, 0x7b, 0x3b, 0x0e, 0x70, 0x8b, 0xd9, 0x6f, 0x81, 0x90, 0xec, 0xab, 0x4f, 0xb9, 0xb2, 0xb3,
220 0x80, 0x5a, 0x81, 0x56
221 };
222
223 /* Encryption: */
224 const uint8_t encrypted4[] PROGMEM = {
225 /* 0x00,*/ 0xa4, 0x57, 0x8c, 0xbc, 0x17, 0x63, 0x18, 0xa6, 0x38, 0xfb, 0xa7, 0xd0, 0x1d, 0xf1, 0x57,
226 0x46, 0xaf, 0x44, 0xd4, 0xf6, 0xcd, 0x96, 0xd7, 0xe7, 0xc4, 0x95, 0xcb, 0xf4, 0x25, 0xb0, 0x9c,
227 0x64, 0x9d, 0x32, 0xbf, 0x88, 0x6d, 0xa4, 0x8f, 0xba, 0xf9, 0x89, 0xa2, 0x11, 0x71, 0x87, 0xca,
228 0xfb, 0x1f, 0xb5, 0x80, 0x31, 0x76, 0x90, 0xe3, 0xcc, 0xd4, 0x46, 0x92, 0x0b, 0x7a, 0xf8, 0x2b,
229 0x31, 0xdb, 0x58, 0x04, 0xd8, 0x7d, 0x01, 0x51, 0x4a, 0xcb, 0xfa, 0x91, 0x56, 0xe7, 0x82, 0xf8,
230 0x67, 0xf6, 0xbe, 0xd9, 0x44, 0x9e, 0x0e, 0x9a, 0x2c, 0x09, 0xbc, 0xec, 0xc6, 0xaa, 0x08, 0x76,
231 0x36, 0x96, 0x5e, 0x34, 0xb3, 0xec, 0x76, 0x6f, 0x2f, 0xe2, 0xe4, 0x30, 0x18, 0xa2, 0xfd, 0xde,
232 0xb1, 0x40, 0x61, 0x6a, 0x0e, 0x9d, 0x82, 0xe5, 0x33, 0x10, 0x24, 0xee, 0x06, 0x52, 0xfc, 0x76,
233 0x41
234 };
235
236 /**********************************************************************************************/
237 #if 1
238 /* RSA modulus n: */
239 const uint8_t modulus2[] PROGMEM = {
240 0x01, 0x94, 0x7c, 0x7f, 0xce, 0x90, 0x42, 0x5f, 0x47, 0x27, 0x9e, 0x70, 0x85, 0x1f, 0x25, 0xd5,
241 0xe6, 0x23, 0x16, 0xfe, 0x8a, 0x1d, 0xf1, 0x93, 0x71, 0xe3, 0xe6, 0x28, 0xe2, 0x60, 0x54, 0x3e,
242 0x49, 0x01, 0xef, 0x60, 0x81, 0xf6, 0x8c, 0x0b, 0x81, 0x41, 0x19, 0x0d, 0x2a, 0xe8, 0xda, 0xba,
243 0x7d, 0x12, 0x50, 0xec, 0x6d, 0xb6, 0x36, 0xe9, 0x44, 0xec, 0x37, 0x22, 0x87, 0x7c, 0x7c, 0x1d,
244 0x0a, 0x67, 0xf1, 0x4b, 0x16, 0x94, 0xc5, 0xf0, 0x37, 0x94, 0x51, 0xa4, 0x3e, 0x49, 0xa3, 0x2d,
245 0xde, 0x83, 0x67, 0x0b, 0x73, 0xda, 0x91, 0xa1, 0xc9, 0x9b, 0xc2, 0x3b, 0x43, 0x6a, 0x60, 0x05,
246 0x5c, 0x61, 0x0f, 0x0b, 0xaf, 0x99, 0xc1, 0xa0, 0x79, 0x56, 0x5b, 0x95, 0xa3, 0xf1, 0x52, 0x66,
247 0x32, 0xd1, 0xd4, 0xda, 0x60, 0xf2, 0x0e, 0xda, 0x25, 0xe6, 0x53, 0xc4, 0xf0, 0x02, 0x76, 0x6f,
248 0x45
249 };
250
251 /* RSA public exponent e: */
252 const uint8_t public_exponent2[] PROGMEM = {
253 0x01, 0x00, 0x01
254 };
255
256 /* RSA private exponent d: */
257 const uint8_t private_exponent2[] PROGMEM = {
258 0x08, 0x23, 0xf2, 0x0f, 0xad, 0xb5, 0xda, 0x89, 0x08, 0x8a, 0x9d, 0x00, 0x89, 0x3e, 0x21, 0xfa,
259 0x4a, 0x1b, 0x11, 0xfb, 0xc9, 0x3c, 0x64, 0xa3, 0xbe, 0x0b, 0xaa, 0xea, 0x97, 0xfb, 0x3b, 0x93,
260 0xc3, 0xff, 0x71, 0x37, 0x04, 0xc1, 0x9c, 0x96, 0x3c, 0x1d, 0x10, 0x7a, 0xae, 0x99, 0x05, 0x47,
261 0x39, 0xf7, 0x9e, 0x02, 0xe1, 0x86, 0xde, 0x86, 0xf8, 0x7a, 0x6d, 0xde, 0xfe, 0xa6, 0xd8, 0xcc,
262 0xd1, 0xd3, 0xc8, 0x1a, 0x47, 0xbf, 0xa7, 0x25, 0x5b, 0xe2, 0x06, 0x01, 0xa4, 0xa4, 0xb2, 0xf0,
263 0x8a, 0x16, 0x7b, 0x5e, 0x27, 0x9d, 0x71, 0x5b, 0x1b, 0x45, 0x5b, 0xdd, 0x7e, 0xab, 0x24, 0x59,
264 0x41, 0xd9, 0x76, 0x8b, 0x9a, 0xce, 0xfb, 0x3c, 0xcd, 0xa5, 0x95, 0x2d, 0xa3, 0xce, 0xe7, 0x25,
265 0x25, 0xb4, 0x50, 0x16, 0x63, 0xa8, 0xee, 0x15, 0xc9, 0xe9, 0x92, 0xd9, 0x24, 0x62, 0xfe, 0x39
266 };
267
268 /* Prime p: */
269 const uint8_t p2[] PROGMEM = {
270 0x01, 0x59, 0xdb, 0xde, 0x04, 0xa3, 0x3e, 0xf0, 0x6f, 0xb6, 0x08, 0xb8, 0x0b, 0x19, 0x0f, 0x4d,
271 0x3e, 0x22, 0xbc, 0xc1, 0x3a, 0xc8, 0xe4, 0xa0, 0x81, 0x03, 0x3a, 0xbf, 0xa4, 0x16, 0xed, 0xb0,
272 0xb3, 0x38, 0xaa, 0x08, 0xb5, 0x73, 0x09, 0xea, 0x5a, 0x52, 0x40, 0xe7, 0xdc, 0x6e, 0x54, 0x37,
273 0x8c, 0x69, 0x41, 0x4c, 0x31, 0xd9, 0x7d, 0xdb, 0x1f, 0x40, 0x6d, 0xb3, 0x76, 0x9c, 0xc4, 0x1a,
274 0x43
275 };
276
277 /* Prime q: */
278 const uint8_t q2[] PROGMEM = {
279 0x01, 0x2b, 0x65, 0x2f, 0x30, 0x40, 0x3b, 0x38, 0xb4, 0x09, 0x95, 0xfd, 0x6f, 0xf4, 0x1a, 0x1a,
280 0xcc, 0x8a, 0xda, 0x70, 0x37, 0x32, 0x36, 0xb7, 0x20, 0x2d, 0x39, 0xb2, 0xee, 0x30, 0xcf, 0xb4,
281 0x6d, 0xb0, 0x95, 0x11, 0xf6, 0xf3, 0x07, 0xcc, 0x61, 0xcc, 0x21, 0x60, 0x6c, 0x18, 0xa7, 0x5b,
282 0x8a, 0x62, 0xf8, 0x22, 0xdf, 0x03, 0x1b, 0xa0, 0xdf, 0x0d, 0xaf, 0xd5, 0x50, 0x6f, 0x56, 0x8b,
283 0xd7
284 };
285
286 /* p's CRT exponent dP: */
287 const uint8_t dp2[] PROGMEM = {
288 0x43, 0x6e, 0xf5, 0x08, 0xde, 0x73, 0x65, 0x19, 0xc2, 0xda, 0x4c, 0x58, 0x0d, 0x98, 0xc8, 0x2c,
289 0xb7, 0x45, 0x2a, 0x3f, 0xb5, 0xef, 0xad, 0xc3, 0xb9, 0xc7, 0x78, 0x9a, 0x1b, 0xc6, 0x58, 0x4f,
290 0x79, 0x5a, 0xdd, 0xbb, 0xd3, 0x24, 0x39, 0xc7, 0x46, 0x86, 0x55, 0x2e, 0xcb, 0x6c, 0x2c, 0x30,
291 0x7a, 0x4d, 0x3a, 0xf7, 0xf5, 0x39, 0xee, 0xc1, 0x57, 0x24, 0x8c, 0x7b, 0x31, 0xf1, 0xa2, 0x55
292 };
293
294 /* q's CRT exponent dQ: */
295 const uint8_t dq2[] PROGMEM = {
296 0x01, 0x2b, 0x15, 0xa8, 0x9f, 0x3d, 0xfb, 0x2b, 0x39, 0x07, 0x3e, 0x73, 0xf0, 0x2b, 0xdd, 0x0c,
297 0x1a, 0x7b, 0x37, 0x9d, 0xd4, 0x35, 0xf0, 0x5c, 0xdd, 0xe2, 0xef, 0xf9, 0xe4, 0x62, 0x94, 0x8b,
298 0x7c, 0xec, 0x62, 0xee, 0x90, 0x50, 0xd5, 0xe0, 0x81, 0x6e, 0x07, 0x85, 0xa8, 0x56, 0xb4, 0x91,
299 0x08, 0xdc, 0xb7, 0x5f, 0x36, 0x83, 0x87, 0x4d, 0x1c, 0xa6, 0x32, 0x9a, 0x19, 0x01, 0x30, 0x66,
300 0xff
301 };
302
303 /* CRT coefficient qInv: */
304 const uint8_t qinv2[] PROGMEM = {
305 0x02, 0x70, 0xdb, 0x17, 0xd5, 0x91, 0x4b, 0x01, 0x8d, 0x76, 0x11, 0x8b, 0x24, 0x38, 0x9a, 0x73,
306 0x50, 0xec, 0x83, 0x6b, 0x00, 0x63, 0xa2, 0x17, 0x21, 0x23, 0x6f, 0xd8, 0xed, 0xb6, 0xd8, 0x9b,
307 0x51, 0xe7, 0xee, 0xb8, 0x7b, 0x61, 0x1b, 0x71, 0x32, 0xcb, 0x7e, 0xa7, 0x35, 0x6c, 0x23, 0x15,
308 0x1c, 0x1e, 0x77, 0x51, 0x50, 0x7c, 0x78, 0x6d, 0x9e, 0xe1, 0x79, 0x41, 0x70, 0xa8, 0xc8, 0xe8
309 };
310
311 #endif
312 /**********************************************************************************************/
313
314
315 uint8_t keys_allocated = 0;
316 rsa_publickey_t pub_key;
317 rsa_privatekey_t priv_key;
318
319 #if 0
320   #define MSG       message
321   #define SEED      seed
322   #define ENCRYPTED encrypted
323   #define MODULUS modulus
324   #define PUB_EXPONENT public_exponent
325   #define PRIV_EXPONENT private_exponent
326   #define P p
327   #define Q q
328   #define DP dp
329   #define DQ dq
330   #define QINV qinv
331 #else
332         #define MSG       message4
333         #define SEED      seed4
334         #define ENCRYPTED encrypted4
335         #define MODULUS modulus2
336         #define PUB_EXPONENT public_exponent2
337         #define PRIV_EXPONENT private_exponent2
338         #define P p2
339         #define Q q2
340         #define DP dp2
341         #define DQ dq2
342         #define QINV qinv2
343 #endif
344
345
346 uint8_t convert_nibble(uint8_t c){
347         if(c>='0' && c<='9'){
348                 return c - '0';
349         }
350         c |= 'A' ^ 'a';
351         if(c>='a' && c<='f'){
352                 return c - 'a' + 10;
353         }
354         return 0xff;
355 }
356
357 const char *block_ignore_string=" \t\r\n,;";
358 #define BUFFER_LIMIT 120
359 uint16_t read_os(void* dst, uint16_t length, const char* ignore_string){
360         uint16_t counter = 0;
361         uint16_t c;
362         uint8_t v, tmp = 0, idx = 0;
363         if(!ignore_string){
364                 ignore_string = block_ignore_string;
365         }
366         while(counter < length){
367                 c = cli_getc();
368                 if(c > 0xff){
369                         return counter;
370                 }
371                 if(strchr(ignore_string, c)){
372                         continue;
373                 }
374                 v = convert_nibble(c);
375                 if(v > 0x0f){
376                         return counter;
377                 }
378                 if(idx){
379                         ((uint8_t*)dst)[counter++] = (tmp << 4) | v;
380                         idx = 0;
381                         if(counter % (BUFFER_LIMIT/2) == 0){
382                                 cli_putc('.');
383                         }
384                 }else{
385                         tmp = v;
386                         idx = 1;
387                 }
388         }
389         return counter;
390 }
391
392 uint16_t own_atou(const char* str){
393         uint16_t r=0;
394         while(*str && *str >= '0' && *str <= '9'){
395                 r *= 10;
396                 r += *str++ - '0';
397         }
398         return r;
399 }
400
401 uint8_t read_bigint(bigint_t* a, char* prompt){
402         uint16_t read_length, actual_length;
403         uint8_t off;
404         uint8_t *buffer;
405         char read_int_str[18];
406         cli_putstr(prompt);
407         cli_putstr_P(PSTR("\r\n  length: "));
408         cli_getsn(read_int_str, 16);
409         read_length = own_atou(read_int_str);
410         off = (sizeof(bigint_word_t) - (read_length % sizeof(bigint_word_t))) % sizeof(bigint_word_t);
411         buffer = malloc(((read_length + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t)) * sizeof(bigint_word_t));
412         if(!buffer){
413                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
414                 return 2;
415         }
416         cli_putstr_P(PSTR("\r\n  data: "));
417         memset(buffer, 0, sizeof(bigint_word_t));
418         actual_length = read_os(buffer + off, read_length, NULL);
419         if(actual_length != read_length){
420                 cli_putstr_P(PSTR("\r\nERROR: unexpected end of data!"));
421                 free(buffer);
422                 return 1;
423         }
424         a->wordv = (bigint_word_t*)buffer;
425         a->length_B = (read_length + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t);
426         bigint_changeendianess(a);
427         bigint_adjust(a);
428         return 0;
429 }
430
431 uint8_t pre_alloc_key_crt(void){
432         uint8_t c;
433         pub_key.modulus = malloc(sizeof(bigint_t));
434         if(!pub_key.modulus){
435                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
436                 return 2;
437         }
438         priv_key.modulus = pub_key.modulus;
439         priv_key.n = 5;
440         priv_key.components = malloc(5 * sizeof(bigint_t*));
441         if(!priv_key.components){
442                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
443                 return 2;
444         }
445         pub_key.exponent = malloc(sizeof(bigint_t));
446         if(!pub_key.exponent){
447                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
448                 return 2;
449         }
450         for(c=0; c<5; ++c){
451                 priv_key.components[c] = malloc(sizeof(bigint_t));
452                 if(!priv_key.components[c]){
453                         cli_putstr_P(PSTR("\r\nERROR: OOM!"));
454                         return 2;
455                 }
456         }
457         return 0;
458 }
459
460 void free_key(void){
461         uint8_t c;
462         free(pub_key.modulus->wordv);
463         free(pub_key.exponent->wordv);
464         free(pub_key.modulus);
465         pub_key.modulus = priv_key.modulus = NULL;
466         free(pub_key.exponent);
467         pub_key.exponent = NULL;
468         for(c = 0; c < priv_key.n; ++c){
469                 free(priv_key.components[c]->wordv);
470                 free(priv_key.components[c]);
471         }
472         free(priv_key.components);
473         priv_key.components = NULL;
474 }
475
476 uint8_t read_key_crt(void){
477         uint8_t r;
478         cli_putstr_P(PSTR("\r\n== reading key (crt) =="));
479         r = pre_alloc_key_crt();
480         if(r) return r;
481         r = read_bigint(pub_key.modulus,"\r\n = module =");
482         if(r) return r;
483         r = read_bigint(pub_key.exponent,"\r\n = public exponent =");
484         if(r) return r;
485         r = read_bigint(priv_key.components[0],"\r\n = p (first prime) =");
486         if(r) return r;
487         r = read_bigint(priv_key.components[1],"\r\n = q (second prime) =");
488         if(r) return r;
489         r = read_bigint(priv_key.components[2],"\r\n = dp (p's exponent) =");
490         if(r) return r;
491         r = read_bigint(priv_key.components[3],"\r\n = dq (q's exponent) =");
492         if(r) return r;
493         r = read_bigint(priv_key.components[4],"\r\n = qInv (q' coefficient) =");
494         return r;
495 }
496
497 uint8_t read_key_conv(void){
498         uint8_t r;
499         cli_putstr_P(PSTR("\r\n== reading key (crt) =="));
500         pub_key.modulus = malloc(sizeof(bigint_t));
501         if(!pub_key.modulus){
502                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
503                 return 2;
504         }
505         r = read_bigint(pub_key.modulus,"\r\n = module =");
506         if(r) return r;
507         priv_key.modulus = pub_key.modulus;
508         priv_key.n = 1;
509         pub_key.exponent = malloc(sizeof(bigint_t));
510         if(!pub_key.exponent){
511                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
512                 return 2;
513         }
514         priv_key.components = malloc(sizeof(bigint_t*));
515         if(!priv_key.components){
516                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
517                 return 2;
518         }
519         priv_key.components[0] = malloc(sizeof(bigint_t));
520         if(!priv_key.components[0]){
521                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
522                 return 2;
523         }
524         r = read_bigint(pub_key.exponent,"\r\n = public exponent =");
525         if(r) return r;
526         r = read_bigint(priv_key.components[0],"\r\n = private exponent =");
527         return r;
528 }
529
530 void load_priv_conventional(void){
531         bigint_t *epriv;
532         epriv = malloc(sizeof(bigint_t));
533         if(!epriv){
534                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
535                 return;
536         }
537         epriv->length_B = (sizeof(PRIV_EXPONENT) + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t);
538         epriv->wordv =  malloc(epriv->length_B * sizeof(bigint_word_t));
539         if(!epriv->wordv){
540                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
541                 return;
542         }
543         memcpy(epriv->wordv, PRIV_EXPONENT, sizeof(PRIV_EXPONENT));
544         priv_key.components = malloc(sizeof(bigint_t*));
545         priv_key.components[0] = epriv;
546         priv_key.n = 1;
547         bigint_changeendianess(epriv);
548         bigint_adjust(epriv);
549 }
550
551
552 void load_priv_crt_mono(void){
553         bigint_t **v;
554         const uint8_t *bv[5] = {P,Q,DP,DQ,QINV};
555         uint16_t sv[5] = {sizeof(P), sizeof(Q), sizeof(DP), sizeof(DQ), sizeof(QINV)};
556         uint8_t i;
557         v = malloc(5 * sizeof(bigint_t));
558         if(!v){
559                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
560                 return;
561         }
562         priv_key.components = malloc(5*sizeof(bigint_t*));
563         if(!priv_key.components){
564                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
565                 return;
566         }
567         priv_key.n = 5;
568         for(i=0; i<5; ++i){
569                 v[i] = malloc(sizeof(bigint_t));
570                 v[i]->info = 0;
571                 v[i]->length_B = (sv[i] + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t);
572                 v[i]->wordv = calloc(v[i]->length_B , sizeof(bigint_word_t));
573                 if(!v[i]->wordv){
574                         cli_putstr_P(PSTR("\r\nERROR: OOM!"));
575                         return;
576                 }
577                 memcpy(v[i]->wordv, bv[i], sv[i]);
578                 bigint_changeendianess(v[i]);
579                 bigint_adjust(v[i]);
580                 priv_key.components[i] = v[i];
581         }
582 }
583
584 uint8_t load_bigint_from_os(bigint_t* a, PGM_VOID_P os, uint16_t length_B){
585         a->length_B = BIGINT_CEIL(length_B) / sizeof(bigint_word_t);
586         a->wordv = malloc(BIGINT_CEIL(length_B));
587         if(!a->wordv){
588                 cli_putstr_P(PSTR("\r\nOOM!\r\n"));
589                 return 1;
590         }
591         memset(a->wordv, 0, sizeof(bigint_word_t));
592         memcpy_P((uint8_t*)a->wordv + BIGINT_OFF(length_B), os, length_B);
593         a->info = 0;
594         bigint_changeendianess(a);
595         bigint_adjust(a);
596         return 0;
597 }
598
599 void load_fix_rsa(void){
600         if(keys_allocated){
601                 free_key();
602         }
603         keys_allocated = 1;
604
605         if(pre_alloc_key_crt()){
606                 cli_putstr_P(PSTR("\r\nOOM!\r\n"));
607                 return;
608         }
609
610         load_bigint_from_os(pub_key.modulus, MODULUS, sizeof(MODULUS));
611         load_bigint_from_os(pub_key.exponent, PUB_EXPONENT, sizeof(PUB_EXPONENT));
612         priv_key.n = 5;
613         load_bigint_from_os(priv_key.components[0], P, sizeof(P));
614         load_bigint_from_os(priv_key.components[1], Q, sizeof(Q));
615         load_bigint_from_os(priv_key.components[2], DP, sizeof(DP));
616         load_bigint_from_os(priv_key.components[3], DQ, sizeof(DQ));
617         load_bigint_from_os(priv_key.components[4], QINV, sizeof(QINV));
618
619 //      load_priv_conventional();
620 //      load_priv_crt_mono();
621 }
622
623 void quick_test(void){
624         uint8_t *ciphertext, *plaintext, rc;
625         uint8_t seed[sizeof(SEED)];
626         uint16_t clen, plen;
627         ciphertext = malloc(clen = pub_key.modulus->length_B * sizeof(bigint_word_t));
628         plaintext = malloc(pub_key.modulus->length_B * sizeof(bigint_word_t));
629         memcpy_P(plaintext, MSG, sizeof(MSG));
630         memcpy_P(seed, SEED, sizeof(SEED));
631         cli_putstr_P(PSTR("\r\nplaintext:"));
632         cli_hexdump_block(plaintext, sizeof(MSG), 4, 8);
633         cli_putstr_P(PSTR("\r\nencrypting: ..."));
634         rc = rsa_encrypt_oaep(ciphertext, &clen, plaintext, sizeof(MSG), &pub_key, NULL, NULL, seed);
635         if(rc){
636                 cli_putstr_P(PSTR("\r\nERROR: rsa_encrypt_oaep returned: "));
637                 cli_hexdump_byte(rc);
638                 return;
639
640         }
641
642         cli_putstr_P(PSTR("\r\n\r\nciphertext:"));
643         cli_hexdump_block(ciphertext, clen, 4, 8);
644         if(clen!=sizeof(ENCRYPTED)){
645                         cli_putstr_P(PSTR("\r\n>>FAIL (no size match)<<"));
646         }else{
647                 if(memcmp_P(ciphertext, ENCRYPTED, clen)){
648                         cli_putstr_P(PSTR("\r\n>>FAIL (no content match)<<"));
649                 }else{
650                         cli_putstr_P(PSTR("\r\n>>OK<<"));
651                 }
652         }
653
654         cli_putstr_P(PSTR("\r\ndecrypting: ..."));
655         rc = rsa_decrypt_oaep(plaintext, &plen, ciphertext, clen, &priv_key, NULL, NULL, NULL);
656         if(rc){
657                 cli_putstr_P(PSTR("\r\nERROR: rsa_decrypt_oaep returned: "));
658                 cli_hexdump_byte(rc);
659                 return;
660         }
661         cli_putstr_P(PSTR("\r\n\r\nplaintext:"));
662         cli_hexdump_block(plaintext, plen, 4, 8);
663
664         free(ciphertext);
665         free(plaintext);
666 }
667
668 void run_seed_test(void){
669         uint8_t *msg, *ciph, *msg_;
670         uint16_t msg_len, ciph_len, msg_len_;
671         uint8_t seed[20], seed_out[20];
672         char read_int_str[18];
673         cli_putstr_P(PSTR("\r\n== test with given seed =="));
674         cli_putstr_P(PSTR("\r\n = message ="));
675         cli_putstr_P(PSTR("\r\n  length: "));
676         cli_getsn(read_int_str, 16);
677         msg_len = own_atou(read_int_str);
678         msg = malloc(msg_len);
679         if(!msg){
680                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
681                 return;
682         }
683         ciph = malloc(bigint_length_B(pub_key.modulus));
684         if(!ciph){
685                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
686                 return;
687         }
688         msg_ = malloc(bigint_length_B(pub_key.modulus));
689         if(!msg_){
690                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
691                 return;
692         }
693         cli_putstr_P(PSTR("\r\n  data: "));
694         read_os(msg, msg_len, NULL);
695         cli_putstr_P(PSTR("\r\n  seed (20 bytes): "));
696         read_os(seed, 20, NULL);
697
698         cli_putstr_P(PSTR("\r\n  encrypting ..."));
699         rsa_encrypt_oaep(ciph, &ciph_len, msg, msg_len, &pub_key, NULL, NULL, seed);
700         cli_putstr_P(PSTR("\r\n  ciphertext:"));
701         cli_hexdump_block(ciph, ciph_len, 4, 16);
702         cli_putstr_P(PSTR("\r\n  decrypting ... "));
703         rsa_decrypt_oaep(msg_, &msg_len_, ciph, ciph_len, &priv_key, NULL, NULL, seed_out);
704         cli_putstr_P(PSTR("[done]"));
705         if(msg_len != msg_len_){
706                 char tstr[16];
707                 cli_putstr_P(PSTR("\r\nERROR: wrong decrypted message length ("));
708                 itoa(msg_len_, tstr, 10);
709                 cli_putstr(tstr);
710                 cli_putstr_P(PSTR(" instead of "));
711                 itoa(msg_len, tstr, 10);
712                 cli_putstr(tstr);
713                 cli_putc(')');
714                 goto end;
715         }
716         if(memcmp(msg, msg_, msg_len)){
717                 cli_putstr_P(PSTR("\r\nERROR: wrong decrypted message:"));
718                 cli_hexdump_block(msg_, msg_len_, 4, 16);
719                 cli_putstr_P(PSTR("\r\nreference:"));
720                 cli_hexdump_block(msg, msg_len, 4, 16);
721                 goto end;
722         }
723
724         if(memcmp(seed, seed_out, 20)){
725                 cli_putstr_P(PSTR("\r\nERROR: wrong decrypted seed:"));
726                 cli_hexdump_block(seed_out, 20, 4, 16);
727                 cli_putstr_P(PSTR("\r\nreference:"));
728                 cli_hexdump_block(seed, 20, 4, 16);
729                 goto end;
730         }
731         cli_putstr_P(PSTR("\r\n  >>OK<<"));
732 end:
733         free(msg);
734         free(msg_);
735         free(ciph);
736 }
737
738 void reset_prng(void){
739         uint8_t buf[16];
740         memset(buf, 0, 16);
741         random_seed(buf);
742         cli_putstr_P(PSTR("\r\nPRNG reset"));
743 }
744
745 void rsa_init(void){
746         prng_get_byte = random8;
747 }
748
749 void load_key(void){
750         if(keys_allocated){
751                 free_key();
752         }
753         keys_allocated = 1;
754         read_key_crt();
755 }
756
757 void test_dump(void){
758         char lstr[16];
759         int len;
760         cli_putstr_P(PSTR("\r\nenter dump length: "));
761         cli_getsn_cecho(lstr, 15);
762         len = own_atou(lstr);
763         cli_putstr_P(PSTR("\r\ndumping 0x"));
764         cli_hexdump_rev(&len, 2);
765         cli_putstr_P(PSTR(" byte:"));
766         cli_hexdump_block(pub_key.modulus->wordv, len, 4, 8);
767 }
768
769 /*****************************************************************************
770  *  main                                                                                                                                         *
771  *****************************************************************************/
772
773 const char echo_test_str[]    PROGMEM = "echo-test";
774 const char reset_prng_str[]   PROGMEM = "reset-prng";
775 const char load_key_str[]     PROGMEM = "load-key";
776 const char load_fix_key_str[] PROGMEM = "load-fix-key";
777 const char quick_test_str[]   PROGMEM = "quick-test";
778 const char seed_test_str[]    PROGMEM = "seed-test";
779 const char dump_test_str[]    PROGMEM = "dump-test";
780 const char performance_str[]  PROGMEM = "performance";
781 const char echo_str[]         PROGMEM = "echo";
782
783 const cmdlist_entry_t cmdlist[] PROGMEM = {
784         { reset_prng_str,       NULL, reset_prng                    },
785         { load_key_str,         NULL, load_key                      },
786         { load_fix_key_str,     NULL, load_fix_rsa                  },
787         { quick_test_str,       NULL, quick_test                    },
788         { seed_test_str,        NULL, run_seed_test                 },
789         { dump_test_str,        NULL, test_dump                     },
790 //      { performance_str,      NULL, testrun_performance_bigint    },
791         { echo_str,         (void*)1, (void_fpt)echo_ctrl           },
792         { NULL,                 NULL, NULL                          }
793 };
794
795 void dump_sp(void){
796         uint8_t x;
797         uint8_t *xa = &x;
798         cli_putstr_P(PSTR("\r\nstack pointer: ~"));
799         cli_hexdump_rev(&xa, 4);
800 }
801
802 int main (void){
803         main_setup();
804
805         for(;;){
806                 welcome_msg(algo_name);
807                 rsa_init();
808                 cmd_interface(cmdlist);
809         }
810 }