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@2:a2a77f01dd26, 2017-09-13 (annotated)
- 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?
User | Revision | Line number | New 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 | } |