]> git.cryptolib.org Git - avr-crypto-lib.git/blob - test_src/main-rsaes_oaep-test.c
f3199756299931d92de47944266cfe0601028ab2
[avr-crypto-lib.git] / test_src / main-rsaes_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 "rsaes_oaep.h"
32
33 #include "performance_test.h"
34
35 const char* algo_name = "RSAES-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         a->info = 0;
427         bigint_changeendianess(a);
428         bigint_adjust(a);
429         return 0;
430 }
431
432 uint8_t pre_alloc_key_crt(void){
433         uint8_t c;
434         pub_key.modulus = malloc(sizeof(bigint_t));
435         if(!pub_key.modulus){
436                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
437                 return 2;
438         }
439         priv_key.modulus = pub_key.modulus;
440         priv_key.n = 5;
441         priv_key.components = malloc(5 * sizeof(bigint_t*));
442         if(!priv_key.components){
443                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
444                 return 2;
445         }
446         pub_key.exponent = malloc(sizeof(bigint_t));
447         if(!pub_key.exponent){
448                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
449                 return 2;
450         }
451         for(c=0; c<5; ++c){
452                 priv_key.components[c] = malloc(sizeof(bigint_t));
453                 if(!priv_key.components[c]){
454                         cli_putstr_P(PSTR("\r\nERROR: OOM!"));
455                         return 2;
456                 }
457         }
458         return 0;
459 }
460
461 void free_key(void){
462         uint8_t c;
463         free(pub_key.modulus->wordv);
464         free(pub_key.exponent->wordv);
465         free(pub_key.modulus);
466         pub_key.modulus = priv_key.modulus = NULL;
467         free(pub_key.exponent);
468         pub_key.exponent = NULL;
469         for(c = 0; c < priv_key.n; ++c){
470                 free(priv_key.components[c]->wordv);
471                 free(priv_key.components[c]);
472         }
473         free(priv_key.components);
474         priv_key.components = NULL;
475 }
476
477 uint8_t read_key_crt(void){
478         uint8_t r;
479         cli_putstr_P(PSTR("\r\n== reading key (crt) =="));
480         r = pre_alloc_key_crt();
481         if(r) return r;
482         r = read_bigint(pub_key.modulus,"\r\n = module =");
483         if(r) return r;
484         r = read_bigint(pub_key.exponent,"\r\n = public exponent =");
485         if(r) return r;
486         r = read_bigint(priv_key.components[0],"\r\n = p (first prime) =");
487         if(r) return r;
488         r = read_bigint(priv_key.components[1],"\r\n = q (second prime) =");
489         if(r) return r;
490         r = read_bigint(priv_key.components[2],"\r\n = dp (p's exponent) =");
491         if(r) return r;
492         r = read_bigint(priv_key.components[3],"\r\n = dq (q's exponent) =");
493         if(r) return r;
494         r = read_bigint(priv_key.components[4],"\r\n = qInv (q' coefficient) =");
495         return r;
496 }
497
498 uint8_t read_key_conv(void){
499         uint8_t r;
500         cli_putstr_P(PSTR("\r\n== reading key (crt) =="));
501         pub_key.modulus = malloc(sizeof(bigint_t));
502         if(!pub_key.modulus){
503                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
504                 return 2;
505         }
506         r = read_bigint(pub_key.modulus,"\r\n = module =");
507         if(r) return r;
508         priv_key.modulus = pub_key.modulus;
509         priv_key.n = 1;
510         pub_key.exponent = malloc(sizeof(bigint_t));
511         if(!pub_key.exponent){
512                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
513                 return 2;
514         }
515         priv_key.components = malloc(sizeof(bigint_t*));
516         if(!priv_key.components){
517                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
518                 return 2;
519         }
520         priv_key.components[0] = malloc(sizeof(bigint_t));
521         if(!priv_key.components[0]){
522                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
523                 return 2;
524         }
525         r = read_bigint(pub_key.exponent,"\r\n = public exponent =");
526         if(r) return r;
527         r = read_bigint(priv_key.components[0],"\r\n = private exponent =");
528         return r;
529 }
530
531 void load_priv_conventional(void){
532         bigint_t *epriv;
533         epriv = malloc(sizeof(bigint_t));
534         if(!epriv){
535                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
536                 return;
537         }
538         epriv->length_B = (sizeof(PRIV_EXPONENT) + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t);
539         epriv->wordv =  malloc(epriv->length_B * sizeof(bigint_word_t));
540         if(!epriv->wordv){
541                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
542                 return;
543         }
544         memcpy(epriv->wordv, PRIV_EXPONENT, sizeof(PRIV_EXPONENT));
545         priv_key.components = malloc(sizeof(bigint_t*));
546         priv_key.components[0] = epriv;
547         priv_key.n = 1;
548         bigint_changeendianess(epriv);
549         bigint_adjust(epriv);
550 }
551
552
553 void load_priv_crt_mono(void){
554         bigint_t **v;
555         const uint8_t *bv[5] = {P,Q,DP,DQ,QINV};
556         uint16_t sv[5] = {sizeof(P), sizeof(Q), sizeof(DP), sizeof(DQ), sizeof(QINV)};
557         uint8_t i;
558         v = malloc(5 * sizeof(bigint_t));
559         if(!v){
560                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
561                 return;
562         }
563         priv_key.components = malloc(5*sizeof(bigint_t*));
564         if(!priv_key.components){
565                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
566                 return;
567         }
568         priv_key.n = 5;
569         for(i=0; i<5; ++i){
570                 v[i] = malloc(sizeof(bigint_t));
571                 v[i]->info = 0;
572                 v[i]->length_B = (sv[i] + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t);
573                 v[i]->wordv = calloc(v[i]->length_B , sizeof(bigint_word_t));
574                 if(!v[i]->wordv){
575                         cli_putstr_P(PSTR("\r\nERROR: OOM!"));
576                         return;
577                 }
578                 memcpy(v[i]->wordv, bv[i], sv[i]);
579                 bigint_changeendianess(v[i]);
580                 bigint_adjust(v[i]);
581                 priv_key.components[i] = v[i];
582         }
583 }
584
585 uint8_t load_bigint_from_os(bigint_t* a, PGM_VOID_P os, uint16_t length_B){
586         a->length_B = BIGINT_CEIL(length_B) / sizeof(bigint_word_t);
587         a->wordv = malloc(BIGINT_CEIL(length_B));
588         if(!a->wordv){
589                 cli_putstr_P(PSTR("\r\nOOM!\r\n"));
590                 return 1;
591         }
592         memset(a->wordv, 0, sizeof(bigint_word_t));
593         memcpy_P((uint8_t*)a->wordv + BIGINT_OFF(length_B), os, length_B);
594         a->info = 0;
595         bigint_changeendianess(a);
596         bigint_adjust(a);
597         return 0;
598 }
599
600 void load_fix_rsa(void){
601         if(keys_allocated){
602                 free_key();
603         }
604         keys_allocated = 1;
605
606         if(pre_alloc_key_crt()){
607                 cli_putstr_P(PSTR("\r\nOOM!\r\n"));
608                 return;
609         }
610
611         load_bigint_from_os(pub_key.modulus, MODULUS, sizeof(MODULUS));
612         load_bigint_from_os(pub_key.exponent, PUB_EXPONENT, sizeof(PUB_EXPONENT));
613         priv_key.n = 5;
614         load_bigint_from_os(priv_key.components[0], P, sizeof(P));
615         load_bigint_from_os(priv_key.components[1], Q, sizeof(Q));
616         load_bigint_from_os(priv_key.components[2], DP, sizeof(DP));
617         load_bigint_from_os(priv_key.components[3], DQ, sizeof(DQ));
618         load_bigint_from_os(priv_key.components[4], QINV, sizeof(QINV));
619
620 //      load_priv_conventional();
621 //      load_priv_crt_mono();
622 }
623
624 void quick_test(void){
625         uint8_t *ciphertext, *plaintext, rc;
626         uint8_t seed[sizeof(SEED)];
627         uint16_t clen, plen;
628         ciphertext = malloc(clen = pub_key.modulus->length_B * sizeof(bigint_word_t));
629         plaintext = malloc(pub_key.modulus->length_B * sizeof(bigint_word_t));
630         memcpy_P(plaintext, MSG, sizeof(MSG));
631         memcpy_P(seed, SEED, sizeof(SEED));
632         cli_putstr_P(PSTR("\r\nplaintext:"));
633         cli_hexdump_block(plaintext, sizeof(MSG), 4, 8);
634         cli_putstr_P(PSTR("\r\nencrypting: ..."));
635         rc = rsa_encrypt_oaep(ciphertext, &clen, plaintext, sizeof(MSG), &pub_key, NULL, NULL, seed);
636         if(rc){
637                 cli_putstr_P(PSTR("\r\nERROR: rsa_encrypt_oaep returned: "));
638                 cli_hexdump_byte(rc);
639                 return;
640
641         }
642
643         cli_putstr_P(PSTR("\r\n\r\nciphertext:"));
644         cli_hexdump_block(ciphertext, clen, 4, 8);
645         if(clen!=sizeof(ENCRYPTED)){
646                         cli_putstr_P(PSTR("\r\n>>FAIL (no size match)<<"));
647         }else{
648                 if(memcmp_P(ciphertext, ENCRYPTED, clen)){
649                         cli_putstr_P(PSTR("\r\n>>FAIL (no content match)<<"));
650                 }else{
651                         cli_putstr_P(PSTR("\r\n>>OK<<"));
652                 }
653         }
654
655         cli_putstr_P(PSTR("\r\ndecrypting: ..."));
656         rc = rsa_decrypt_oaep(plaintext, &plen, ciphertext, clen, &priv_key, NULL, NULL, NULL);
657         if(rc){
658                 cli_putstr_P(PSTR("\r\nERROR: rsa_decrypt_oaep returned: "));
659                 cli_hexdump_byte(rc);
660                 return;
661         }
662         cli_putstr_P(PSTR("\r\n\r\nplaintext:"));
663         cli_hexdump_block(plaintext, plen, 4, 8);
664
665         free(ciphertext);
666         free(plaintext);
667 }
668
669 void run_seed_test(void){
670         uint8_t *msg, *ciph, *msg_;
671         uint16_t msg_len, ciph_len, msg_len_;
672         uint8_t seed[20], seed_out[20];
673         char read_int_str[18];
674         cli_putstr_P(PSTR("\r\n== test with given seed =="));
675         cli_putstr_P(PSTR("\r\n = message ="));
676         cli_putstr_P(PSTR("\r\n  length: "));
677         cli_getsn(read_int_str, 16);
678         msg_len = own_atou(read_int_str);
679         msg = malloc(msg_len);
680         if(!msg){
681                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
682                 return;
683         }
684         ciph = malloc(bigint_length_B(pub_key.modulus));
685         if(!ciph){
686                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
687                 return;
688         }
689         msg_ = malloc(bigint_length_B(pub_key.modulus) + sizeof(bigint_word_t));
690         if(!msg_){
691                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
692                 return;
693         }
694         cli_putstr_P(PSTR("\r\n  data: "));
695         read_os(msg, msg_len, NULL);
696         cli_putstr_P(PSTR("\r\n  seed (20 bytes): "));
697         read_os(seed, 20, NULL);
698
699         cli_putstr_P(PSTR("\r\n  encrypting ..."));
700         rsa_encrypt_oaep(ciph, &ciph_len, msg, msg_len, &pub_key, NULL, NULL, seed);
701         cli_putstr_P(PSTR("\r\n  ciphertext:"));
702         cli_hexdump_block(ciph, ciph_len, 4, 16);
703         cli_putstr_P(PSTR("\r\n  decrypting ... "));
704         rsa_decrypt_oaep(msg_, &msg_len_, ciph, ciph_len, &priv_key, NULL, NULL, seed_out);
705         cli_putstr_P(PSTR("[done]"));
706         if(msg_len != msg_len_){
707                 char tstr[16];
708                 cli_putstr_P(PSTR("\r\nERROR: wrong decrypted message length ("));
709                 itoa(msg_len_, tstr, 10);
710                 cli_putstr(tstr);
711                 cli_putstr_P(PSTR(" instead of "));
712                 itoa(msg_len, tstr, 10);
713                 cli_putstr(tstr);
714                 cli_putc(')');
715                 goto end;
716         }
717         if(memcmp(msg, msg_, msg_len)){
718                 cli_putstr_P(PSTR("\r\nERROR: wrong decrypted message:"));
719                 cli_hexdump_block(msg_, msg_len_, 4, 16);
720                 cli_putstr_P(PSTR("\r\nreference:"));
721                 cli_hexdump_block(msg, msg_len, 4, 16);
722                 goto end;
723         }
724
725         if(memcmp(seed, seed_out, 20)){
726                 cli_putstr_P(PSTR("\r\nERROR: wrong decrypted seed:"));
727                 cli_hexdump_block(seed_out, 20, 4, 16);
728                 cli_putstr_P(PSTR("\r\nreference:"));
729                 cli_hexdump_block(seed, 20, 4, 16);
730                 goto end;
731         }
732         cli_putstr_P(PSTR("\r\n  >>OK<<"));
733 end:
734         free(msg);
735         free(msg_);
736         free(ciph);
737 }
738
739 void reset_prng(void){
740         uint8_t buf[16];
741         memset(buf, 0, 16);
742         random_seed(buf);
743         cli_putstr_P(PSTR("\r\nPRNG reset"));
744 }
745
746 void rsa_init(void){
747         prng_get_byte = random8;
748 }
749
750 void load_key(void){
751         if(keys_allocated){
752                 free_key();
753         }
754         keys_allocated = 1;
755         read_key_crt();
756 }
757
758 void test_dump(void){
759         char lstr[16];
760         int len;
761         cli_putstr_P(PSTR("\r\nenter dump length: "));
762         cli_getsn_cecho(lstr, 15);
763         len = own_atou(lstr);
764         cli_putstr_P(PSTR("\r\ndumping 0x"));
765         cli_hexdump_rev(&len, 2);
766         cli_putstr_P(PSTR(" byte:"));
767         cli_hexdump_block(pub_key.modulus->wordv, len, 4, 8);
768 }
769
770 /*****************************************************************************
771  *  main                                                                                                                                         *
772  *****************************************************************************/
773
774 const char echo_test_str[]    PROGMEM = "echo-test";
775 const char reset_prng_str[]   PROGMEM = "reset-prng";
776 const char load_key_str[]     PROGMEM = "load-key";
777 const char load_fix_key_str[] PROGMEM = "load-fix-key";
778 const char quick_test_str[]   PROGMEM = "quick-test";
779 const char seed_test_str[]    PROGMEM = "seed-test";
780 const char dump_test_str[]    PROGMEM = "dump-test";
781 const char performance_str[]  PROGMEM = "performance";
782 const char echo_str[]         PROGMEM = "echo";
783
784 const cmdlist_entry_t cmdlist[] PROGMEM = {
785         { reset_prng_str,       NULL, reset_prng                    },
786         { load_key_str,         NULL, load_key                      },
787         { load_fix_key_str,     NULL, load_fix_rsa                  },
788         { quick_test_str,       NULL, quick_test                    },
789         { seed_test_str,        NULL, run_seed_test                 },
790         { dump_test_str,        NULL, test_dump                     },
791 //      { performance_str,      NULL, testrun_performance_bigint    },
792         { echo_str,         (void*)1, (void_fpt)echo_ctrl           },
793         { NULL,                 NULL, NULL                          }
794 };
795
796 void dump_sp(void){
797         uint8_t x;
798         uint8_t *xa = &x;
799         cli_putstr_P(PSTR("\r\nstack pointer: ~"));
800         cli_hexdump_rev(&xa, 4);
801 }
802
803 int main (void){
804         main_setup();
805
806         for(;;){
807                 welcome_msg(algo_name);
808                 rsa_init();
809                 cmd_interface(cmdlist);
810         }
811 }