Micro-ECC is an open source implementation for ECC running in an embedded microcontroller. This is a port for mbed. Please do more test and update assembly optimization for Cortex-M, aka, ARM-thumb.
main.cpp
00001 /* 00002 * Micro-ECC ported to mbed platform 00003 * Original Author: Ken MacKay 00004 * Original Project: https://github.com/kmackay/micro-ecc 00005 * Ported by: Allan K Liu 00006 * 00007 * Micro-ECC is ported to mbed to evalute its performance 00008 * Micro-ECC is optimized for ARM/ARM-thumb/ARM-thumb2/AVR platform 00009 * Micro-ECC mbed version disabled thumb/thumb2 optimization because of its GCC syntax. 00010 * PS: I am not good at assembly for those projects. 00011 * Micro-ECC is highly sensitive to Random Number Generator, using two seperate ADC as input 00012 */ 00013 00014 #include "mbed.h" 00015 #include "uECC.h" 00016 00017 Serial pc(USBTX, USBRX); 00018 AnalogIn rnd1(A1); 00019 AnalogIn rnd2(A2); 00020 AnalogIn rnd3(A3); 00021 AnalogIn rnd4(A4); 00022 AnalogIn rnd5(A5); 00023 00024 Timer t; 00025 00026 //#define RNG_TEST 1 00027 #if defined(RNG_TEST) 00028 void randtest() 00029 { 00030 uint8_t buf[16]; 00031 00032 pc.printf("randtest():\r\n"); 00033 for(int i=0; i<16; i++){ 00034 buf[i] = rand(); 00035 pc.printf("%02X",buf[i]); 00036 } 00037 } 00038 #endif 00039 00040 void adctest() 00041 { 00042 float buf[5]; 00043 buf[0] = rnd1.read()*3300; 00044 buf[1] = rnd2.read()*3300; 00045 buf[2] = rnd3.read()*3300; 00046 buf[3] = rnd4.read()*3300; 00047 buf[4] = rnd5.read()*3300; 00048 pc.printf("adctest():\r\n"); 00049 for(int i=0; i<5; i++){ 00050 pc.printf("%.0f\t",buf[i]); 00051 } 00052 pc.printf("\r\n"); 00053 } 00054 00055 static int rawadc2int() { 00056 uint8_t lsb; 00057 uint8_t msb; 00058 00059 msb = uint8_t(rnd1.read()*3300); 00060 lsb = uint8_t(rnd3.read()*3300); 00061 return ((msb<<8)|lsb); 00062 } 00063 00064 static int RNG(uint8_t *dest, unsigned size) { 00065 // Use the least-significant bits from the ADC for an unconnected pin (or connected to a source of 00066 // random noise). This can take a long time to generate random data if the result of analogRead(0) 00067 // doesn't change very frequently. 00068 pc.printf("RNG():\r\n"); 00069 while (size) { 00070 uint8_t val = 0; 00071 for (unsigned i = 0; i < 8; ++i) { 00072 //int init = rnd.read(); 00073 //int init = rand(); 00074 //int init = rnd1.read()*3300; 00075 int init = rawadc2int(); 00076 pc.printf("%04X",init); 00077 int count = 0; 00078 //while (rnd.read() == init) { 00079 //while (rand() == init) { 00080 //while((rnd1.read()*3300) == init){ 00081 while(rawadc2int() == init){ 00082 ++count; 00083 } 00084 00085 if (count == 0) { 00086 val = (val << 1) | (init & 0x01); 00087 } else { 00088 val = (val << 1) | (count & 0x01); 00089 } 00090 } 00091 *dest = val; 00092 ++dest; 00093 --size; 00094 pc.printf("\r\n"); 00095 } 00096 00097 // NOTE: it would be a good idea to hash the resulting random data using SHA-256 or similar. 00098 return 1; 00099 } 00100 00101 void dumphex(const char* name, uint8_t* buf, uint8_t size){ 00102 pc.printf(name); 00103 for(int i=0; i<size; i++){ 00104 pc.printf("%02X",buf[i]); 00105 } 00106 pc.printf("\r\n"); 00107 } 00108 00109 void loop(){ 00110 const struct uECC_Curve_t * curve = uECC_secp160r1(); 00111 int r; 00112 long d; 00113 00114 uint8_t private1[21]; 00115 uint8_t private2[21]; 00116 00117 uint8_t public1[40]; 00118 uint8_t public2[40]; 00119 00120 uint8_t secret1[20]; 00121 uint8_t secret2[20]; 00122 00123 memset(private1, 0, 21); 00124 memset(private2, 0, 21); 00125 memset(public1, 0, 40); 00126 memset(public2, 0, 40); 00127 memset(secret1, 0, 20); 00128 memset(secret2, 0, 20); 00129 00130 pc.printf("Start ECC computation\r\n"); 00131 pc.printf("make key 1\r\n"); 00132 t.start(); 00133 uECC_make_key(public1, private1, curve); 00134 dumphex("public1:\r\n", public1, sizeof(public1)); 00135 dumphex("private1:\r\n", private1, sizeof(private1)); 00136 t.stop(); d = t.read_ms(); t.reset(); t.start(); 00137 pc.printf("time: %dms\r\n",d); 00138 00139 pc.printf("make key 2\r\n"); 00140 t.start(); 00141 uECC_make_key(public2, private2, curve); 00142 dumphex("public2:\r\n", public2, sizeof(public2)); 00143 dumphex("private2:\r\n", private2, sizeof(private2)); 00144 t.stop(); d = t.read_ms(); t.reset(); t.start(); 00145 pc.printf("time: %dms\r\n",d); 00146 00147 pc.printf("make share secret 1\r\n"); 00148 t.start(); 00149 r = uECC_shared_secret(public2, private1, secret1, curve); 00150 pc.printf("r: %04X\r\n",r); 00151 dumphex("secret1:\r\n", secret1, sizeof(secret1)); 00152 t.stop(); d = t.read_ms(); t.reset(); t.start(); 00153 pc.printf("time: %dms\r\n",d); 00154 00155 pc.printf("make share secret 2\r\n"); 00156 t.start(); 00157 r = uECC_shared_secret(public1, private2, secret2, curve); 00158 pc.printf("r: %04X\r\n",r); 00159 dumphex("secret2:\r\n", secret2, sizeof(secret2)); 00160 t.stop(); d = t.read_ms(); t.reset(); t.start(); 00161 pc.printf("time: %dms\r\n",d); 00162 00163 pc.printf("\r\n\r\n"); 00164 wait(1); 00165 } 00166 00167 int main() { 00168 pc.baud(115200); 00169 printf("\033[2J\033[0;0H"); // return to 0,0 and clear screen in VT100 00170 pc.printf("\r\nmicroECC test\r\n"); 00171 00172 #if defined(RNG_TEST) 00173 // Test rand() functions is turly random. 00174 for(int i=0; i<4; i++){ 00175 randtest(); 00176 pc.printf("\r\n"); 00177 } 00178 #endif 00179 00180 #if(0) 00181 for(int i=0; i<10; i++){ 00182 adctest(); 00183 wait(1); 00184 } 00185 #endif 00186 uECC_set_rng(&RNG); 00187 pc.printf("\r\n"); 00188 00189 loop(); 00190 00191 while(1) { 00192 ; 00193 } 00194 }
Generated on Wed Jul 13 2022 23:22:10 by
1.7.2