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

Committer:
allankliu
Date:
Wed Sep 13 09:24:51 2017 +0000
Revision:
2:a2a77f01dd26
Parent:
0:f83fc7ecf97b
Improved Random Number Generator with two seperate ADCs for MSB/LSB

Who changed what in which revision?

UserRevisionLine numberNew contents of line
allankliu 0:f83fc7ecf97b 1 /*
allankliu 0:f83fc7ecf97b 2 * Micro-ECC ported to mbed platform
allankliu 0:f83fc7ecf97b 3 * Original Author: Ken MacKay
allankliu 0:f83fc7ecf97b 4 * Original Project: https://github.com/kmackay/micro-ecc
allankliu 0:f83fc7ecf97b 5 * Ported by: Allan K Liu
allankliu 0:f83fc7ecf97b 6 *
allankliu 0:f83fc7ecf97b 7 * Micro-ECC is ported to mbed to evalute its performance
allankliu 0:f83fc7ecf97b 8 * Micro-ECC is optimized for ARM/ARM-thumb/ARM-thumb2/AVR platform
allankliu 0:f83fc7ecf97b 9 * Micro-ECC mbed version disabled thumb/thumb2 optimization because of its GCC syntax.
allankliu 0:f83fc7ecf97b 10 * PS: I am not good at assembly for those projects.
allankliu 2:a2a77f01dd26 11 * Micro-ECC is highly sensitive to Random Number Generator, using two seperate ADC as input
allankliu 0:f83fc7ecf97b 12 */
allankliu 0:f83fc7ecf97b 13
allankliu 0:f83fc7ecf97b 14 #include "mbed.h"
allankliu 0:f83fc7ecf97b 15 #include "uECC.h"
allankliu 0:f83fc7ecf97b 16
allankliu 0:f83fc7ecf97b 17 Serial pc(USBTX, USBRX);
allankliu 2:a2a77f01dd26 18 AnalogIn rnd1(A1);
allankliu 2:a2a77f01dd26 19 AnalogIn rnd2(A2);
allankliu 2:a2a77f01dd26 20 AnalogIn rnd3(A3);
allankliu 2:a2a77f01dd26 21 AnalogIn rnd4(A4);
allankliu 2:a2a77f01dd26 22 AnalogIn rnd5(A5);
allankliu 2:a2a77f01dd26 23
allankliu 0:f83fc7ecf97b 24 Timer t;
allankliu 0:f83fc7ecf97b 25
allankliu 2:a2a77f01dd26 26 //#define RNG_TEST 1
allankliu 2:a2a77f01dd26 27 #if defined(RNG_TEST)
allankliu 2:a2a77f01dd26 28 void randtest()
allankliu 0:f83fc7ecf97b 29 {
allankliu 0:f83fc7ecf97b 30 uint8_t buf[16];
allankliu 0:f83fc7ecf97b 31
allankliu 2:a2a77f01dd26 32 pc.printf("randtest():\r\n");
allankliu 0:f83fc7ecf97b 33 for(int i=0; i<16; i++){
allankliu 0:f83fc7ecf97b 34 buf[i] = rand();
allankliu 0:f83fc7ecf97b 35 pc.printf("%02X",buf[i]);
allankliu 0:f83fc7ecf97b 36 }
allankliu 2:a2a77f01dd26 37 }
allankliu 2:a2a77f01dd26 38 #endif
allankliu 2:a2a77f01dd26 39
allankliu 2:a2a77f01dd26 40 void adctest()
allankliu 2:a2a77f01dd26 41 {
allankliu 2:a2a77f01dd26 42 float buf[5];
allankliu 2:a2a77f01dd26 43 buf[0] = rnd1.read()*3300;
allankliu 2:a2a77f01dd26 44 buf[1] = rnd2.read()*3300;
allankliu 2:a2a77f01dd26 45 buf[2] = rnd3.read()*3300;
allankliu 2:a2a77f01dd26 46 buf[3] = rnd4.read()*3300;
allankliu 2:a2a77f01dd26 47 buf[4] = rnd5.read()*3300;
allankliu 2:a2a77f01dd26 48 pc.printf("adctest():\r\n");
allankliu 2:a2a77f01dd26 49 for(int i=0; i<5; i++){
allankliu 2:a2a77f01dd26 50 pc.printf("%.0f\t",buf[i]);
allankliu 2:a2a77f01dd26 51 }
allankliu 2:a2a77f01dd26 52 pc.printf("\r\n");
allankliu 2:a2a77f01dd26 53 }
allankliu 2:a2a77f01dd26 54
allankliu 2:a2a77f01dd26 55 static int rawadc2int() {
allankliu 2:a2a77f01dd26 56 uint8_t lsb;
allankliu 2:a2a77f01dd26 57 uint8_t msb;
allankliu 0:f83fc7ecf97b 58
allankliu 2:a2a77f01dd26 59 msb = uint8_t(rnd1.read()*3300);
allankliu 2:a2a77f01dd26 60 lsb = uint8_t(rnd3.read()*3300);
allankliu 2:a2a77f01dd26 61 return ((msb<<8)|lsb);
allankliu 0:f83fc7ecf97b 62 }
allankliu 2:a2a77f01dd26 63
allankliu 0:f83fc7ecf97b 64 static int RNG(uint8_t *dest, unsigned size) {
allankliu 0:f83fc7ecf97b 65 // Use the least-significant bits from the ADC for an unconnected pin (or connected to a source of
allankliu 0:f83fc7ecf97b 66 // random noise). This can take a long time to generate random data if the result of analogRead(0)
allankliu 0:f83fc7ecf97b 67 // doesn't change very frequently.
allankliu 2:a2a77f01dd26 68 pc.printf("RNG():\r\n");
allankliu 0:f83fc7ecf97b 69 while (size) {
allankliu 0:f83fc7ecf97b 70 uint8_t val = 0;
allankliu 0:f83fc7ecf97b 71 for (unsigned i = 0; i < 8; ++i) {
allankliu 0:f83fc7ecf97b 72 //int init = rnd.read();
allankliu 2:a2a77f01dd26 73 //int init = rand();
allankliu 2:a2a77f01dd26 74 //int init = rnd1.read()*3300;
allankliu 2:a2a77f01dd26 75 int init = rawadc2int();
allankliu 0:f83fc7ecf97b 76 pc.printf("%04X",init);
allankliu 0:f83fc7ecf97b 77 int count = 0;
allankliu 0:f83fc7ecf97b 78 //while (rnd.read() == init) {
allankliu 2:a2a77f01dd26 79 //while (rand() == init) {
allankliu 2:a2a77f01dd26 80 //while((rnd1.read()*3300) == init){
allankliu 2:a2a77f01dd26 81 while(rawadc2int() == init){
allankliu 0:f83fc7ecf97b 82 ++count;
allankliu 0:f83fc7ecf97b 83 }
allankliu 0:f83fc7ecf97b 84
allankliu 0:f83fc7ecf97b 85 if (count == 0) {
allankliu 0:f83fc7ecf97b 86 val = (val << 1) | (init & 0x01);
allankliu 0:f83fc7ecf97b 87 } else {
allankliu 0:f83fc7ecf97b 88 val = (val << 1) | (count & 0x01);
allankliu 0:f83fc7ecf97b 89 }
allankliu 0:f83fc7ecf97b 90 }
allankliu 0:f83fc7ecf97b 91 *dest = val;
allankliu 0:f83fc7ecf97b 92 ++dest;
allankliu 0:f83fc7ecf97b 93 --size;
allankliu 0:f83fc7ecf97b 94 pc.printf("\r\n");
allankliu 0:f83fc7ecf97b 95 }
allankliu 0:f83fc7ecf97b 96
allankliu 0:f83fc7ecf97b 97 // NOTE: it would be a good idea to hash the resulting random data using SHA-256 or similar.
allankliu 0:f83fc7ecf97b 98 return 1;
allankliu 0:f83fc7ecf97b 99 }
allankliu 0:f83fc7ecf97b 100
allankliu 0:f83fc7ecf97b 101 void dumphex(const char* name, uint8_t* buf, uint8_t size){
allankliu 0:f83fc7ecf97b 102 pc.printf(name);
allankliu 0:f83fc7ecf97b 103 for(int i=0; i<size; i++){
allankliu 0:f83fc7ecf97b 104 pc.printf("%02X",buf[i]);
allankliu 0:f83fc7ecf97b 105 }
allankliu 0:f83fc7ecf97b 106 pc.printf("\r\n");
allankliu 0:f83fc7ecf97b 107 }
allankliu 0:f83fc7ecf97b 108
allankliu 0:f83fc7ecf97b 109 void loop(){
allankliu 0:f83fc7ecf97b 110 const struct uECC_Curve_t * curve = uECC_secp160r1();
allankliu 0:f83fc7ecf97b 111 int r;
allankliu 0:f83fc7ecf97b 112 long d;
allankliu 0:f83fc7ecf97b 113
allankliu 0:f83fc7ecf97b 114 uint8_t private1[21];
allankliu 0:f83fc7ecf97b 115 uint8_t private2[21];
allankliu 0:f83fc7ecf97b 116
allankliu 0:f83fc7ecf97b 117 uint8_t public1[40];
allankliu 0:f83fc7ecf97b 118 uint8_t public2[40];
allankliu 0:f83fc7ecf97b 119
allankliu 0:f83fc7ecf97b 120 uint8_t secret1[20];
allankliu 0:f83fc7ecf97b 121 uint8_t secret2[20];
allankliu 0:f83fc7ecf97b 122
allankliu 2:a2a77f01dd26 123 memset(private1, 0, 21);
allankliu 2:a2a77f01dd26 124 memset(private2, 0, 21);
allankliu 2:a2a77f01dd26 125 memset(public1, 0, 40);
allankliu 2:a2a77f01dd26 126 memset(public2, 0, 40);
allankliu 2:a2a77f01dd26 127 memset(secret1, 0, 20);
allankliu 2:a2a77f01dd26 128 memset(secret2, 0, 20);
allankliu 2:a2a77f01dd26 129
allankliu 0:f83fc7ecf97b 130 pc.printf("Start ECC computation\r\n");
allankliu 0:f83fc7ecf97b 131 pc.printf("make key 1\r\n");
allankliu 0:f83fc7ecf97b 132 t.start();
allankliu 0:f83fc7ecf97b 133 uECC_make_key(public1, private1, curve);
allankliu 2:a2a77f01dd26 134 dumphex("public1:\r\n", public1, sizeof(public1));
allankliu 2:a2a77f01dd26 135 dumphex("private1:\r\n", private1, sizeof(private1));
allankliu 2:a2a77f01dd26 136 t.stop(); d = t.read_ms(); t.reset(); t.start();
allankliu 0:f83fc7ecf97b 137 pc.printf("time: %dms\r\n",d);
allankliu 0:f83fc7ecf97b 138
allankliu 0:f83fc7ecf97b 139 pc.printf("make key 2\r\n");
allankliu 0:f83fc7ecf97b 140 t.start();
allankliu 0:f83fc7ecf97b 141 uECC_make_key(public2, private2, curve);
allankliu 2:a2a77f01dd26 142 dumphex("public2:\r\n", public2, sizeof(public2));
allankliu 2:a2a77f01dd26 143 dumphex("private2:\r\n", private2, sizeof(private2));
allankliu 2:a2a77f01dd26 144 t.stop(); d = t.read_ms(); t.reset(); t.start();
allankliu 0:f83fc7ecf97b 145 pc.printf("time: %dms\r\n",d);
allankliu 0:f83fc7ecf97b 146
allankliu 0:f83fc7ecf97b 147 pc.printf("make share secret 1\r\n");
allankliu 0:f83fc7ecf97b 148 t.start();
allankliu 0:f83fc7ecf97b 149 r = uECC_shared_secret(public2, private1, secret1, curve);
allankliu 0:f83fc7ecf97b 150 pc.printf("r: %04X\r\n",r);
allankliu 2:a2a77f01dd26 151 dumphex("secret1:\r\n", secret1, sizeof(secret1));
allankliu 2:a2a77f01dd26 152 t.stop(); d = t.read_ms(); t.reset(); t.start();
allankliu 0:f83fc7ecf97b 153 pc.printf("time: %dms\r\n",d);
allankliu 0:f83fc7ecf97b 154
allankliu 0:f83fc7ecf97b 155 pc.printf("make share secret 2\r\n");
allankliu 0:f83fc7ecf97b 156 t.start();
allankliu 0:f83fc7ecf97b 157 r = uECC_shared_secret(public1, private2, secret2, curve);
allankliu 0:f83fc7ecf97b 158 pc.printf("r: %04X\r\n",r);
allankliu 2:a2a77f01dd26 159 dumphex("secret2:\r\n", secret2, sizeof(secret2));
allankliu 2:a2a77f01dd26 160 t.stop(); d = t.read_ms(); t.reset(); t.start();
allankliu 0:f83fc7ecf97b 161 pc.printf("time: %dms\r\n",d);
allankliu 0:f83fc7ecf97b 162
allankliu 0:f83fc7ecf97b 163 pc.printf("\r\n\r\n");
allankliu 0:f83fc7ecf97b 164 wait(1);
allankliu 0:f83fc7ecf97b 165 }
allankliu 0:f83fc7ecf97b 166
allankliu 0:f83fc7ecf97b 167 int main() {
allankliu 0:f83fc7ecf97b 168 pc.baud(115200);
allankliu 2:a2a77f01dd26 169 printf("\033[2J\033[0;0H"); // return to 0,0 and clear screen in VT100
allankliu 2:a2a77f01dd26 170 pc.printf("\r\nmicroECC test\r\n");
allankliu 2:a2a77f01dd26 171
allankliu 2:a2a77f01dd26 172 #if defined(RNG_TEST)
allankliu 2:a2a77f01dd26 173 // Test rand() functions is turly random.
allankliu 2:a2a77f01dd26 174 for(int i=0; i<4; i++){
allankliu 2:a2a77f01dd26 175 randtest();
allankliu 2:a2a77f01dd26 176 pc.printf("\r\n");
allankliu 2:a2a77f01dd26 177 }
allankliu 2:a2a77f01dd26 178 #endif
allankliu 2:a2a77f01dd26 179
allankliu 2:a2a77f01dd26 180 #if(0)
allankliu 2:a2a77f01dd26 181 for(int i=0; i<10; i++){
allankliu 2:a2a77f01dd26 182 adctest();
allankliu 2:a2a77f01dd26 183 wait(1);
allankliu 2:a2a77f01dd26 184 }
allankliu 2:a2a77f01dd26 185 #endif
allankliu 0:f83fc7ecf97b 186 uECC_set_rng(&RNG);
allankliu 0:f83fc7ecf97b 187 pc.printf("\r\n");
allankliu 0:f83fc7ecf97b 188
allankliu 2:a2a77f01dd26 189 loop();
allankliu 2:a2a77f01dd26 190
allankliu 0:f83fc7ecf97b 191 while(1) {
allankliu 2:a2a77f01dd26 192 ;
allankliu 0:f83fc7ecf97b 193 }
allankliu 0:f83fc7ecf97b 194 }