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.

Dependencies:   mbed uECC

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

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 }