extract https://github.com/kmackay/micro-ecc @ b335ee8 () at deps/micro-ecc
diff --git a/deps/micro-ecc/README.md b/deps/micro-ecc/README.md
index 01926e3..111321b 100644
--- a/deps/micro-ecc/README.md
+++ b/deps/micro-ecc/README.md
@@ -19,7 +19,7 @@
 Usage Notes
 -----------
 ### Point Representation ###
-Compressed points are represented in the standard format as defined in http://www.secg.org/collateral/sec1_final.pdf; uncompressed points are represented in standard format, but without the `0x04` prefix. All functions except `uECC_compress()` only accept uncompressed points; use `uECC_compress()` and `uECC_decompress()` to convert between compressed and uncompressed point representations.
+Compressed points are represented in the standard format as defined in http://www.secg.org/sec1-v2.pdf; uncompressed points are represented in standard format, but without the `0x04` prefix. All functions except `uECC_decompress()` only accept uncompressed points; use `uECC_compress()` and `uECC_decompress()` to convert between compressed and uncompressed point representations.
 
 Private keys are represented in the standard format.
 
@@ -27,7 +27,7 @@
 
 I recommend just copying (or symlink) the uECC files into your project. Then just `#include "uECC.h"` to use the micro-ecc functions.
 
-For use with Arduino, you can just create a symlink to the `uECC` directory in your Arduino `libraries` directory. You can then use uECC just like any other Arduino library (uECC should show up in the **Sketch**=>**Import Library** submenu).
+For use with Arduino, you can use the Library Manager to download micro-ecc (**Sketch**=>**Include Library**=>**Manage Libraries**). You can then use uECC just like any other Arduino library (uECC should show up in the **Sketch**=>**Import Library** submenu).
 
 See uECC.h for documentation for each function.
 
diff --git a/deps/micro-ecc/asm_arm.inc b/deps/micro-ecc/asm_arm.inc
index 688fdc7..e3c8cb1 100644
--- a/deps/micro-ecc/asm_arm.inc
+++ b/deps/micro-ecc/asm_arm.inc
@@ -620,7 +620,7 @@
         "str %[r3], [%[r0], %[r6]] \n\t" /* result[num_words * 2 - 1] = c0 */
         "pop {%[r0]} \n\t"               /* pop result off the stack */
         
-        ".syntax divided \n\t"
+        RESUME_SYNTAX
         : [r3] "+l" (num_words), [r4] "=&l" (r4),
           [r5] "=&l" (r5), [r6] "=&l" (r6), [r7] "=&l" (r7)
         : [r0] "l" (result), [r1] "l" (left), [r2] "l" (right)
@@ -805,7 +805,7 @@
         "str %[r2], [%[r0], %[r5]] \n\t" /* result[num_words * 2 - 1] = c0 */
         "pop {%[r0]} \n\t"               /* pop result off the stack */
 
-        ".syntax divided \n\t"
+        RESUME_SYNTAX
         : [r2] "+l" (num_words), [r3] "=&l" (r3), [r4] "=&l" (r4),
           [r5] "=&l" (r5), [r6] "=&l" (r6), [r7] "=&l" (r7)
         : [r0] "l" (result), [r1] "l" (left)
diff --git a/deps/micro-ecc/asm_avr.inc b/deps/micro-ecc/asm_avr.inc
index c988040..c14bf55 100644
--- a/deps/micro-ecc/asm_avr.inc
+++ b/deps/micro-ecc/asm_avr.inc
@@ -37,12 +37,12 @@
         "sbc r31, __zero_reg__ \n\t"
         IJMP
     #endif
-        
+
         REPEAT(uECC_MAX_WORDS, "st x+, __zero_reg__ \n\t")
         "1: \n\t"
         : "+x" (v)
         : [num] "r" (num_words)
-        : 
+        :
     #if (uECC_MAX_WORDS != uECC_MIN_WORDS)
           "r30", "r31", "cc"
     #endif
@@ -60,16 +60,16 @@
         "sbc r31, __zero_reg__ \n\t"
         IJMP
     #endif
-        
+
         REPEAT(uECC_MAX_WORDS,
             "ld r0, y+ \n\t"
             "st x+, r0 \n\t")
         "1: \n\t"
         : "+x" (d), "+y" (src)
         : [num] "r" ((uint8_t)(num_words * 2))
-        : "r0",
+        : "r0"
     #if (uECC_MAX_WORDS != uECC_MIN_WORDS)
-          "r30", "r31", "cc"
+          , "r30", "r31", "cc"
     #endif
     );
 }
@@ -84,7 +84,7 @@
         "sub r30, %[jump] \n\t"
         "sbc r31, __zero_reg__ \n\t"
     #endif
-        
+
         "add r26, %[num] \n\t"
         "adc r27, __zero_reg__ \n\t"
         "ld r0, -x \n\t"
@@ -93,7 +93,7 @@
     #if (uECC_MAX_WORDS != uECC_MIN_WORDS)
         IJMP
     #endif
-        
+
         REPEAT(DEC(uECC_MAX_WORDS),
             "ld r0, -x \n\t"
             "ror r0 \n\t"
@@ -137,15 +137,15 @@
         "sub r30, %[num] \n\t"
         "sbc r31, __zero_reg__ \n\t"
     #endif
-    
+
         "clc \n\t"
     #if (uECC_MAX_WORDS != uECC_MIN_WORDS)
         IJMP
         REPEATM(uECC_MAX_WORDS, ADD_RJPM_TABLE)
     #endif
-    
+
         REPEATM(uECC_MAX_WORDS, ADD_RJPM_DEST)
-        
+
         "mov %[clb], __zero_reg__ \n\t"
         "adc %[clb], %[clb] \n\t" /* Store carry bit. */
 
@@ -184,15 +184,15 @@
         "sub r30, %[num] \n\t"
         "sbc r31, __zero_reg__ \n\t"
     #endif
-    
+
         "clc \n\t"
     #if (uECC_MAX_WORDS != uECC_MIN_WORDS)
         IJMP
         REPEATM(uECC_MAX_WORDS, SUB_RJPM_TABLE)
     #endif
-    
+
         REPEATM(uECC_MAX_WORDS, SUB_RJPM_DEST)
-        
+
         "mov %[clb], __zero_reg__ \n\t"
         "adc %[clb], %[clb] \n\t" /* Store carry bit. */
 
@@ -216,7 +216,7 @@
                                 wordcount_t num_words) {
     /* num_words should already be in r18. */
     register wordcount_t r18 __asm__("r18") = num_words;
-    
+
     __asm__ volatile (
         "push r18 \n\t"
 #if (uECC_MIN_WORDS == 20)
@@ -268,7 +268,7 @@
                                   wordcount_t num_words) {
     /* num_words should already be in r20. */
     register wordcount_t r20 __asm__("r20") = num_words;
-    
+
     __asm__ volatile (
         "push r20 \n\t"
 #if (uECC_MIN_WORDS == 20)
@@ -329,7 +329,7 @@
     	"out __SP_H__, r31 \n\t"
     	"out __SREG__, r0 \n\t"
     	"out __SP_L__, r30 \n\t"
-    	
+
     	"adiw r30, 25 \n\t" /* we are shifting by 31 bits, so shift over 4 bytes
     	                       (+ 1 since z initially points below the stack) */
         "adiw r26, 40 \n\t" /* end of product */
@@ -384,10 +384,10 @@
         "ld r18, z \n\t"
         "adc r18, r1 \n\t"
         "st z+, r18 \n\t"
-        
+
         "sbiw r30, 24 \n\t" /* move z back to point at tmp */
         "sbiw r26, 40 \n\t" /* move x back to point at product */
-        
+
         /* add low bytes of tmp to product, storing in result */
         "ld r18, z+ \n\t"
         "ld r19, x+ \n\t"
@@ -403,13 +403,13 @@
            z is 20 bytes into tmp */
         "sbiw r28, 20 \n\t" /* move y back to point at result */
         "adiw r30, 4 \n\t"  /* move z to point to the end of tmp */
-        
+
         /* do omega_mult again with the 4 relevant bytes */
         /* z points to the end of tmp, x points to the end of product */
         "ld r18, -z \n\t" /* Load word. */
         "lsr r18 \n\t"    /* Shift. */
         "st -x, r18 \n\t" /* Store the first result word. */
-        
+
         "ld r18, -z \n\t"
         "ror r18 \n\t"
         "st -x, r18 \n\t"
@@ -419,11 +419,11 @@
         "ld r18, -z \n\t"
         "ror r18 \n\t"
         "st -x, r18 \n\t"
-        
+
         "eor r18, r18 \n\t" /* r18 = 0 */
         "ror r18 \n\t"      /* get last bit */
         "st -x, r18 \n\t"   /* store it */
-        
+
         "sbiw r26, 3 \n\t" /* move x back to point at beginning */
         /* now we add a copy of the 4 bytes */
         "ld r18, z+ \n\t"
@@ -432,29 +432,29 @@
         "st x+, r18 \n\t"
         "ld r18, z+ \n\t"
         "st x+, r18 \n\t"
-        
+
         "ld r18, z+ \n\t"
         "ld r19, x \n\t"
         "add r18, r19 \n\t"
         "st x+, r18 \n\t"
-        
+
         /* Propagate over the remaining bytes */
         "ld r18, x \n\t"
         "adc r18, r1 \n\t"
         "st x+, r18 \n\t"
-        
+
         "ld r18, x \n\t"
         "adc r18, r1 \n\t"
         "st x+, r18 \n\t"
-        
+
         "ld r18, x \n\t"
         "adc r18, r1 \n\t"
         "st x+, r18 \n\t"
-        
+
         "ld r18, x \n\t"
         "adc r18, r1 \n\t"
         "st x+, r18 \n\t"
-        
+
         /* now z points to the end of tmp, x points to the end of product
            (y still points at result) */
         "sbiw r26, 8 \n\t" /* move x back to point at beginning of actual data */
@@ -468,23 +468,23 @@
             "ld r19, y \n\t"
             "adc r18, r19 \n\t"
             "st y+, r18 \n\t")
-        
+
         /* Done adding, now propagate carry bit */
         REPEAT(12,
             "ld r18, y \n\t"
             "adc r18, __zero_reg__ \n\t"
             "st y+, r18 \n\t")
-        
+
         "adc %[carry], __zero_reg__ \n\t" /* Store carry bit (carry flag is cleared). */
         "sbiw r28, 20 \n\t" /* move y back to point at result */
-        
+
         "sbiw r30, 1 \n\t" /* fix stack pointer */
     	"in r0, __SREG__ \n\t"
     	"cli \n\t"
     	"out __SP_H__, r31 \n\t"
     	"out __SREG__, r0 \n\t"
     	"out __SP_L__, r30 \n\t"
-        
+
         : "+x" (product), [carry] "+r" (carry)
         : "y" (result)
         : "r0", "r18", "r19", "r30", "r31", "cc"
@@ -517,7 +517,7 @@
     	"out __SP_H__, r31 \n\t"
     	"out __SREG__, r0 \n\t"
     	"out __SP_L__, r30 \n\t"
-    	
+
     	"adiw r30, 1 \n\t"  /* add 1 since z initially points below the stack */
         "adiw r26, 32 \n\t" /* product + uECC_WORDS */
         "ldi r25, 0x03 \n\t"
@@ -526,12 +526,12 @@
         "ld r19, x+ \n\t"
         "ld r20, x+ \n\t"
         "ld r21, x+ \n\t"
-        
+
         "mul r24, r18 \n\t"
         "st z+, r0 \n\t"
         "mov r22, r1 \n\t"
         "ldi r23, 0 \n\t"
-        
+
         "mul r24, r19 \n\t"
         "add r22, r0 \n\t"
         "adc r23, r1 \n\t" /* can't overflow */
@@ -540,7 +540,7 @@
         "adc r23, r1 \n\t" /* can't overflow */
         "st z+, r22 \n\t"
         "ldi r22, 0 \n\t"
-        
+
         "mul r24, r20 \n\t"
         "add r23, r0 \n\t"
         "adc r22, r1 \n\t"
@@ -549,7 +549,7 @@
         "adc r22, r1 \n\t"
         "st z+, r23 \n\t"
         "ldi r23, 0 \n\t"
-        
+
         "mul r24, r21 \n\t"
         "add r22, r0 \n\t"
         "adc r23, r1 \n\t"
@@ -558,7 +558,7 @@
         "adc r23, r1 \n\t"
         "st z+, r22 \n\t"
         "ldi r22, 0 \n\t"
-        
+
         /* now we start adding the 2^32 part as well */
         "add r23, r18 \n\t" // 28
         "adc r22, r22 \n\t"
@@ -571,7 +571,7 @@
         "adc r22, r1 \n\t"
         "st z+, r23 \n\t"
         "ldi r23, 0 \n\t"
-        
+
         "add r22, r19 \n\t" // 27
         "adc r23, r23 \n\t"
         "ld r19, x+ \n\t"
@@ -583,7 +583,7 @@
         "adc r23, r1 \n\t"
         "st z+, r22 \n\t"
         "ldi r22, 0 \n\t"
-        
+
         REPEAT(6, // 26 - 3
             "add r23, r20 \n\t"
             "adc r22, r22 \n\t"
@@ -596,7 +596,7 @@
             "adc r22, r1 \n\t"
             "st z+, r23 \n\t"
             "ldi r23, 0 \n\t"
-            
+
             "add r22, r21 \n\t"
             "adc r23, r23 \n\t"
             "ld r21, x+ \n\t"
@@ -608,7 +608,7 @@
             "adc r23, r1 \n\t"
             "st z+, r22 \n\t"
             "ldi r22, 0 \n\t"
-            
+
             "add r23, r18 \n\t"
             "adc r22, r22 \n\t"
             "ld r18, x+ \n\t"
@@ -620,7 +620,7 @@
             "adc r22, r1 \n\t"
             "st z+, r23 \n\t"
             "ldi r23, 0 \n\t"
-            
+
             "add r22, r19 \n\t"
             "adc r23, r23 \n\t"
             "ld r19, x+ \n\t"
@@ -644,7 +644,7 @@
         "adc r22, r1 \n\t"
         "st z+, r23 \n\t"
         "ldi r23, 0 \n\t"
-        
+
         "add r22, r21 \n\t" // 1
         "adc r23, r23 \n\t"
         "ld r21, x+ \n\t"
@@ -656,7 +656,7 @@
         "adc r23, r1 \n\t"
         "st z+, r22 \n\t"
         "ldi r22, 0 \n\t"
-        
+
         /* Now finish the carries etc */
         "add r23, r18 \n\t"
         "adc r22, r22 \n\t"
@@ -665,27 +665,27 @@
         "adc r22, r1 \n\t"
         "st z+, r23 \n\t"
         "ldi r23, 0 \n\t"
-        
+
         "add r22, r19 \n\t"
         "adc r23, r23 \n\t"
         "st z+, r22 \n\t"
         "ldi r22, 0 \n\t"
-        
+
         "add r23, r20 \n\t"
         "adc r22, r22 \n\t"
         "st z+, r23 \n\t"
         "ldi r23, 0 \n\t"
-        
+
         "add r22, r21 \n\t"
         "adc r23, r23 \n\t"
         "st z+, r22 \n\t"
         "st z+, r23 \n\t"
         "eor r1, r1 \n\t" /* make r1 be 0 again */
-        
+
         "sbiw r30, 37 \n\t" /* move z back to point at tmp */
         "subi r26, 64 \n\t" /* move x back to point at product */
         "sbc r27, __zero_reg__ \n\t"
-        
+
         /* add low bytes of tmp to product, storing in result */
         "ld r18, z+ \n\t"
         "ld r19, x+ \n\t"
@@ -696,7 +696,7 @@
             "ld r19, x+ \n\t"
             "adc r18, r19 \n\t"
             "st y+, r18 \n\t")
-        
+
         "adc %[carry], __zero_reg__ \n\t" /* Store carry bit (carry flag is cleared). */
         /* at this point x is at the end of product, y is at the end of result,
            z is 32 bytes into tmp */
@@ -710,12 +710,12 @@
         "ld r19, z+ \n\t"
         "ld r20, z+ \n\t"
         "ld r21, z+ \n\t"
-        
+
         "mul r24, r18 \n\t"
         "st x+, r0 \n\t"
         "mov r22, r1 \n\t"
         "ldi r23, 0 \n\t"
-        
+
         "mul r24, r19 \n\t"
         "add r22, r0 \n\t"
         "adc r23, r1 \n\t" /* can't overflow */
@@ -724,7 +724,7 @@
         "adc r23, r1 \n\t" /* can't overflow */
         "st x+, r22 \n\t"
         "ldi r22, 0 \n\t"
-        
+
         "mul r24, r20 \n\t"
         "add r23, r0 \n\t"
         "adc r22, r1 \n\t"
@@ -733,7 +733,7 @@
         "adc r22, r1 \n\t"
         "st x+, r23 \n\t"
         "ldi r23, 0 \n\t"
-        
+
         "mul r24, r21 \n\t"
         "add r22, r0 \n\t"
         "adc r23, r1 \n\t"
@@ -742,7 +742,7 @@
         "adc r23, r1 \n\t"
         "st x+, r22 \n\t"
         "ldi r22, 0 \n\t"
-        
+
         "add r23, r18 \n\t"
         "adc r22, r22 \n\t"
         "ld r18, z+ \n\t"
@@ -754,7 +754,7 @@
         "adc r22, r1 \n\t"
         "st x+, r23 \n\t"
         "ldi r23, 0 \n\t"
-        
+
         /* Now finish the carries etc */
         "add r22, r19 \n\t"
         "adc r23, r23 \n\t"
@@ -763,23 +763,23 @@
         "adc r23, r1 \n\t"
         "st x+, r22 \n\t"
         "ldi r22, 0 \n\t"
-        
+
         "add r23, r20 \n\t"
         "adc r22, r22 \n\t"
         "st x+, r23 \n\t"
         "ldi r23, 0 \n\t"
-        
+
         "add r22, r21 \n\t"
         "adc r23, r23 \n\t"
         "st x+, r22 \n\t"
         "ldi r22, 0 \n\t"
-        
+
         "add r23, r18 \n\t"
         "adc r22, r22 \n\t"
         "st x+, r23 \n\t"
         "st x+, r22 \n\t"
         "eor r1, r1 \n\t" /* make r1 be 0 again */
-        
+
         /* now z points to the end of tmp, x points to the end of product
            (y still points at result) */
         "sbiw r26, 10 \n\t" /* move x back to point at beginning of actual data */
@@ -793,28 +793,28 @@
             "ld r19, y \n\t"
             "adc r18, r19 \n\t"
             "st y+, r18 \n\t")
-        
+
         /* Done adding, now propagate carry bit */
         REPEAT(22,
             "ld r18, y \n\t"
             "adc r18, __zero_reg__ \n\t"
             "st y+, r18 \n\t")
-        
+
         "adc %[carry], __zero_reg__ \n\t"    /* Store carry bit (carry flag is cleared). */
         "sbiw r28, 32 \n\t" /* move y back to point at result */
-        
+
         "sbiw r30, 1 \n\t" /* fix stack pointer */
     	"in r0, __SREG__ \n\t"
     	"cli \n\t"
     	"out __SP_H__, r31 \n\t"
     	"out __SREG__, r0 \n\t"
     	"out __SP_L__, r30 \n\t"
-        
+
         : "+x" (product), [carry] "+r" (carry)
         : "y" (result)
         : "r0", "r18", "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r30", "r31", "cc"
     );
-    
+
     if (carry > 0) {
         --carry;
         uECC_vli_sub(result, result, curve_secp256k1.p, 32);
@@ -845,7 +845,7 @@
 
     __asm__ volatile (
         "clc \n\t"
-        
+
         "1: \n\t"
         "ld %[left], x+ \n\t"  /* Load left byte. */
         "ld %[right], y+ \n\t" /* Load right byte. */
@@ -853,12 +853,12 @@
         "st z+, %[left] \n\t"  /* Store the result. */
         "dec %[i] \n\t"
         "brne 1b \n\t"
-        
+
         "adc %[carry], %[carry] \n\t" /* Store carry bit. */
 
         : "+z" (r), "+x" (left), "+y" (right), [i] "+r" (num_words),
             [carry] "+r" (carry), [left] "=&r" (left_byte), [right] "=&r" (right_byte)
-        : 
+        :
         : "cc"
     );
     return carry;
@@ -878,7 +878,7 @@
 
     __asm__ volatile (
         "clc \n\t"
-        
+
         "1: \n\t"
         "ld %[left], x+ \n\t"  /* Load left byte. */
         "ld %[right], y+ \n\t" /* Load right byte. */
@@ -886,10 +886,10 @@
         "st z+, %[left] \n\t"  /* Store the result. */
         "dec %[i] \n\t"
         "brne 1b \n\t"
-        
+
         "adc %[borrow], %[borrow] \n\t" /* Store carry bit in borrow. */
 
-        : "+z" (r), "+x" (left), "+y" (right), [i] "+r" (i),
+        : "+z" (r), "+x" (left), "+y" (right), [i] "+r" (num_words),
             [borrow] "+r" (borrow), [left] "=&r" (left_byte), [right] "=&r" (right_byte)
         :
         : "cc"
@@ -911,86 +911,86 @@
     uint8_t r2 = 0;
     uint8_t zero = 0;
     uint8_t k, i;
-    
+
     __asm__ volatile (
         "ldi %[k], 1 \n\t" /* k = 1; k < num_words; ++k */
-        
+
         "1: \n\t"
         "ldi %[i], 0 \n\t"  /* i = 0; i < k; ++i */
-        
+
         "add r28, %[k] \n\t" /* pre-add right ptr */
         "adc r29, %[zero] \n\t"
-        
+
         "2: \n\t"
         "ld r0, x+ \n\t"
         "ld r1, -y \n\t"
         "mul r0, r1 \n\t"
-        
+
         "add %[r0], r0 \n\t"
         "adc %[r1], r1 \n\t"
         "adc %[r2], %[zero] \n\t"
-        
+
         "inc %[i] \n\t"
         "cp %[i], %[k] \n\t"
         "brlo 2b \n\t" /* loop if i < k */
-        
+
         "sub r26, %[k] \n\t" /* fix up left ptr */
         "sbc r27, %[zero] \n\t"
-        
+
         "st z+, %[r0] \n\t"  /* Store the result. */
         "mov %[r0], %[r1] \n\t"
         "mov %[r1], %[r2] \n\t"
         "mov %[r2], %[zero] \n\t"
-        
+
         "inc %[k] \n\t"
         "cp %[k], %[num] \n\t"
         "brlo 1b \n\t" /* loop if k < num_words */
-        
+
         /* second half */
         "mov %[k], %[num] \n\t" /* k = num_words; k > 0; --k */
         "add r28, %[num] \n\t" /* move right ptr to point at the end of right */
         "adc r29, %[zero] \n\t"
-        
+
         "1: \n\t"
         "ldi %[i], 0 \n\t" /* i = 0; i < k; ++i */
-        
+
         "2: \n\t"
         "ld r0, x+ \n\t"
         "ld r1, -y \n\t"
         "mul r0, r1 \n\t"
-        
+
         "add %[r0], r0 \n\t"
         "adc %[r1], r1 \n\t"
         "adc %[r2], %[zero] \n\t"
-        
+
         "inc %[i] \n\t"
         "cp %[i], %[k] \n\t"
         "brlo 2b \n\t" /* loop if i < k */
-        
+
         "add r28, %[k] \n\t" /* fix up right ptr */
         "adc r29, %[zero] \n\t"
-        
+
         "st z+, %[r0] \n\t"  /* Store the result. */
         "mov %[r0], %[r1] \n\t"
         "mov %[r1], %[r2] \n\t"
         "mov %[r2], %[zero] \n\t"
-        
+
         "dec %[k] \n\t"
         "sub r26, %[k] \n\t" /* fix up left ptr (after k is decremented, so next time
                                 we start 1 higher) */
         "sbc r27, %[zero] \n\t"
-        
+
         "cp %[k], %[zero] \n\t"
         "brne 1b \n\t" /* loop if k > 0 */
-        
+
         "st z+, %[r0] \n\t"  /* Store last result byte. */
         "eor r1, r1 \n\t" /* fix r1 to be 0 again */
-    
+
         : "+z" (result), "+x" (left), "+y" (right),
           [r0] "+r" (r0), [r1] "+r" (r1), [r2] "+r" (r2),
           [zero] "+r" (zero), [num] "+r" (num_words),
           [k] "=&r" (k), [i] "=&r" (i)
-        : 
+        :
         : "r0", "cc"
     );
 }
@@ -1007,18 +1007,18 @@
     uint8_t r2 = 0;
     uint8_t zero = 0;
     uint8_t k;
-    
+
     __asm__ volatile (
         "ldi %[k], 1 \n\t" /* k = 1; k < num_words * 2; ++k */
-        
+
         "1: \n\t"
-        
+
         "movw r26, %[orig] \n\t"  /* copy orig ptr to 'left' ptr */
         "movw r30, %[orig] \n\t"  /* copy orig ptr to 'right' ptr */
         "cp %[k], %[num] \n\t"
         "brlo 2f \n\t"
         "breq 2f \n\t"
-        
+
         /* when k > num_words, we start from (k - num_words) on the 'left' ptr */
         "add r26, %[k] \n\t"
         "adc r27, %[zero] \n\t"
@@ -1027,11 +1027,11 @@
         "add r30, %[num] \n\t" /* move right ptr to point at the end */
         "adc r31, %[zero] \n\t"
         "rjmp 3f \n\t"
-        
+
         "2: \n\t" /* when k <= num_words, we add k to the 'right' ptr */
         "add r30, %[k] \n\t" /* pre-add 'right' ptr */
         "adc r31, %[zero] \n\t"
-        
+
         "3: \n\t"
         "ld r0, x+ \n\t"
         "cp r26, r30 \n\t" /* if left == right here, then we are done after this mult
@@ -1039,7 +1039,7 @@
         "breq 4f \n\t"
         "ld r1, -z \n\t"
         "mul r0, r1 \n\t"
-        
+
         /* add twice since it costs the same as doubling */
         "add %[r0], r0 \n\t"
         "adc %[r1], r1 \n\t"
@@ -1047,18 +1047,18 @@
         "add %[r0], r0 \n\t"
         "adc %[r1], r1 \n\t"
         "adc %[r2], %[zero] \n\t"
-        
+
         "cpse r26, r30 \n\t" /* if left == right here, then we are done */
         "rjmp 3b \n\t"
         "rjmp 5f \n\t" /* skip code for non-doubled mult */
-        
+
         "4: \n\t"
         "ld r1, -z \n\t"
         "mul r0, r1 \n\t"
         "add %[r0], r0 \n\t"
         "adc %[r1], r1 \n\t"
         "adc %[r2], %[zero] \n\t"
-        
+
         "5: \n\t"
         "movw r30, %[result] \n\t" /* make z point to result */
         "st z+, %[r0] \n\t"        /* Store the result. */
@@ -1066,15 +1066,15 @@
         "mov %[r0], %[r1] \n\t"
         "mov %[r1], %[r2] \n\t"
         "mov %[r2], %[zero] \n\t"
-        
+
         "inc %[k] \n\t"
         "cp %[k], %[max] \n\t"
         "brlo 1b \n\t" /* loop if k < num_words * 2 */
-        
+
         "movw r30, %[result] \n\t"  /* make z point to result */
         "st z+, %[r0] \n\t"  /* Store last result byte. */
         "eor r1, r1 \n\t" /* fix r1 to be 0 again */
-    
+
         : [result] "+r" (r),
           [r0] "+r" (r0), [r1] "+r" (r1), [r2] "+r" (r2), [zero] "+r" (zero),
           [k] "=&a" (k)
diff --git a/deps/micro-ecc/emk_project.py b/deps/micro-ecc/emk_project.py
index 940fadc..957dd79 100644
--- a/deps/micro-ecc/emk_project.py
+++ b/deps/micro-ecc/emk_project.py
@@ -12,6 +12,11 @@
 c_link_flags = []
 cxx_link_flags = ["-fno-rtti", "-fno-exceptions"]
 
+if "root" in emk.options:
+    root = emk.options["root"]
+else:
+    root = "/"
+
 def setup_build_dir():
     build_arch = None
     if "arch" in emk.options:
@@ -54,9 +59,9 @@
     global c
     global link
 
-    c.compiler = c.GccCompiler("/Projects/avr-tools/bin/avr-")
+    c.compiler = c.GccCompiler(root + "Projects/avr-tools/bin/avr-")
     c.flags += ["-mmcu=atmega256rfr2", "-ffunction-sections", "-fdata-sections"]
-    link.linker = link.GccLinker("/Projects/avr-tools/bin/avr-")
+    link.linker = link.GccLinker(root + "Projects/avr-tools/bin/avr-")
     link.flags += ["-mmcu=atmega256rfr2", "-mrelax", "-Wl,--gc-sections"]
     link.strip = True
 
@@ -66,30 +71,30 @@
     global asm
     global utils
 
-    asm.assembler = asm.GccAssembler("/cross/arm_cortex/bin/arm-none-eabi-")
-    c.compiler = c.GccCompiler("/cross/arm_cortex/bin/arm-none-eabi-")
-    link.linker = link.GccLinker("/cross/arm_cortex/bin/arm-none-eabi-")
+    asm.assembler = asm.GccAssembler(root + "cross/arm_cortex/bin/arm-none-eabi-")
+    c.compiler = c.GccCompiler(root + "cross/arm_cortex/bin/arm-none-eabi-")
+    link.linker = link.GccLinker(root + "cross/arm_cortex/bin/arm-none-eabi-")
 
     c.flags.extend(["-mcpu=cortex-m0", "-mthumb", "-ffunction-sections", "-fdata-sections", "-fno-builtin-fprintf", "-fno-builtin-printf"])
     c.defines["LPC11XX"] = 1
-    
+
     link.local_flags.extend(["-mcpu=cortex-m0", "-mthumb", "-nostartfiles", "-nostdlib", "-Wl,--gc-sections"])
-    link.local_flags.extend(["-Tflash.lds", "-L/Projects/lpc11xx/core", "/Projects/lpc11xx/core/" + emk.build_dir + "/board_cstartup.o"])
+    link.local_flags.extend(["-Tflash.lds", "-L" + root + "Projects/lpc11xx/core", root + "Projects/lpc11xx/core/" + emk.build_dir + "/board_cstartup.o"])
     link.local_syslibs += ["gcc"]
-    link.depdirs += ["/Projects/lpc11xx/stdlib"]
+    link.depdirs += [root + "Projects/lpc11xx/stdlib"]
 
     def do_objcopy(produces, requires):
-        utils.call("/cross/arm_cortex/bin/arm-none-eabi-objcopy", "-O", "binary", requires[0], produces[0])
+        utils.call(root + "cross/arm_cortex/bin/arm-none-eabi-objcopy", "-O", "binary", requires[0], produces[0])
 
     def handle_exe(path):
-        emk.depend(path, "/Projects/lpc11xx/core/" + emk.build_dir + "/board_cstartup.o")
+        emk.depend(path, root + "Projects/lpc11xx/core/" + emk.build_dir + "/board_cstartup.o")
         emk.rule(do_objcopy, path + ".bin", path, cwd_safe=True, ex_safe=True)
         emk.autobuild(path + ".bin")
 
     link.exe_funcs.append(handle_exe)
     link.strip = True
-    
-    emk.recurse("/Projects/lpc11xx/core")
+
+    emk.recurse(root + "Projects/lpc11xx/core")
 
 def setup_linux_rpi():
     global c
@@ -97,7 +102,7 @@
 
     c.compiler = c.GccCompiler("/Volumes/xtools/arm-none-linux-gnueabi/bin/arm-none-linux-gnueabi-")
     link.linker = link.GccLinker("/Volumes/xtools/arm-none-linux-gnueabi/bin/arm-none-linux-gnueabi-")
-    
+
     c.flags.extend(["-fomit-frame-pointer"])
 
 setup_build_dir()
diff --git a/deps/micro-ecc/test/ecc_test/ecc_test.ino b/deps/micro-ecc/examples/ecc_test/ecc_test.ino
similarity index 98%
rename from deps/micro-ecc/test/ecc_test/ecc_test.ino
rename to deps/micro-ecc/examples/ecc_test/ecc_test.ino
index c3c8900..64a0be5 100644
--- a/deps/micro-ecc/test/ecc_test/ecc_test.ino
+++ b/deps/micro-ecc/examples/ecc_test/ecc_test.ino
@@ -1,7 +1,5 @@
 #include <uECC.h>
 
-extern "C" {
-
 static int RNG(uint8_t *dest, unsigned size) {
   // Use the least-significant bits from the ADC for an unconnected pin (or connected to a source of 
   // random noise). This can take a long time to generate random data if the result of analogRead(0) 
@@ -29,8 +27,6 @@
   return 1;
 }
 
-}  // extern "C"
-
 void setup() {
   Serial.begin(115200);
   Serial.print("Testing ecc\n");
@@ -82,4 +78,3 @@
     Serial.print("Shared secrets are identical\n");
   }
 }
-
diff --git a/deps/micro-ecc/library.properties b/deps/micro-ecc/library.properties
new file mode 100644
index 0000000..390bdc8
--- /dev/null
+++ b/deps/micro-ecc/library.properties
@@ -0,0 +1,9 @@
+name=micro-ecc
+version=1.0.0
+author=Kenneth MacKay
+maintainer=Kenneth MacKay
+sentence=uECC
+paragraph=A small and fast ECDH and ECDSA implementation for 8-bit, 32-bit, and 64-bit processors.
+category=Other
+url=https://github.com/kmackay/micro-ecc
+architectures=*
diff --git a/deps/micro-ecc/platform-specific.inc b/deps/micro-ecc/platform-specific.inc
index 1bb595a..7e0373f 100644
--- a/deps/micro-ecc/platform-specific.inc
+++ b/deps/micro-ecc/platform-specific.inc
@@ -8,6 +8,10 @@
 #if (defined(_WIN32) || defined(_WIN64))
 /* Windows */
 
+// use pragma syntax to prevent tweaking the linker script for getting CryptXYZ function
+#pragma comment(lib, "crypt32.lib")
+#pragma comment(lib, "advapi32.lib")
+
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
 #include <wincrypt.h>
@@ -62,6 +66,29 @@
 }
 #define default_RNG_defined 1
 
+#elif defined(RIOT_VERSION)
+
+#include <random.h>
+
+static int default_RNG(uint8_t *dest, unsigned size) {
+    random_bytes(dest, size);
+    return 1;
+}
+#define default_RNG_defined 1
+
+#elif defined(NRF52_SERIES)
+
+#include "app_error.h"
+#include "nrf_crypto_rng.h"
+
+static int default_RNG(uint8_t *dest, unsigned size) 
+{
+    // make sure to call nrf_crypto_init and nrf_crypto_rng_init first
+    ret_code_t ret_code = nrf_crypto_rng_vector_generate(dest, size);
+    return (ret_code == NRF_SUCCESS) ? 1 : 0;
+}
+#define default_RNG_defined 1
+
 #endif /* platform */
 
 #endif /* _UECC_PLATFORM_SPECIFIC_H_ */
diff --git a/deps/micro-ecc/test/ecdsa_test_vectors.c b/deps/micro-ecc/test/ecdsa_test_vectors.c
new file mode 100644
index 0000000..1e902b2
--- /dev/null
+++ b/deps/micro-ecc/test/ecdsa_test_vectors.c
@@ -0,0 +1,128 @@
+/* Copyright 2020, Kenneth MacKay. Licensed under the BSD 2-clause license. */
+
+#include "uECC.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+typedef struct {
+  const char* private_key;
+  const char* public_key;
+  const char* k;
+  const char* hash;
+  const char* r;
+  const char* s;
+} Test;
+
+Test secp256k1_tests[] = {
+    {
+        "ebb2c082fd7727890a28ac82f6bdf97bad8de9f5d7c9028692de1a255cad3e0f",
+        "779dd197a5df977ed2cf6cb31d82d43328b790dc6b3b7d4437a427bd5847dfcde94b724a555b6d017bb7607c3e3281daf5b1699d6ef4124975c9237b917d426f",
+        "49a0d7b786ec9cde0d0721d72804befd06571c974b191efb42ecf322ba9ddd9a",
+        "4b688df40bcedbe641ddb16ff0a1842d9c67ea1c3bf63f3e0471baa664531d1a",
+        "241097efbf8b63bf145c8961dbdf10c310efbb3b2676bbc0f8b08505c9e2f795",
+        "021006b7838609339e8b415a7f9acb1b661828131aef1ecbc7955dfb01f3ca0e"
+    },
+};
+
+extern int uECC_sign_with_k(const uint8_t *private_key,
+                            const uint8_t *message_hash,
+                            unsigned hash_size,
+                            const uint8_t *k,
+                            uint8_t *signature,
+                            uECC_Curve curve);
+
+
+void vli_print(uint8_t *vli, unsigned int size) {
+    for(unsigned i=0; i<size; ++i) {
+        printf("%02X ", (unsigned)vli[i]);
+    }
+    printf("\n");
+}
+
+void strtobytes(const char* str, uint8_t* bytes, int count) {
+  for (int c = 0; c < count; ++c) {
+    if (sscanf(str, "%2hhx", &bytes[c]) != 1) {
+      printf("Failed to read string to bytes");
+      exit(1);
+    }
+    str += 2;
+  }
+}
+
+int run(Test* tests, int num_tests, uECC_Curve curve) {
+    uint8_t private[32] = {0};
+    uint8_t public[64] = {0};
+    uint8_t k[32] = {0};
+    uint8_t hash[32] = {0};
+    uint8_t r[32] = {0};
+    uint8_t s[32] = {0};
+
+    uint8_t signature[64] = {0};
+
+    int result;
+    int i;
+    int private_key_size;
+    int public_key_size;
+    int all_success = 1;
+
+    private_key_size = uECC_curve_private_key_size(curve);
+    public_key_size = uECC_curve_public_key_size(curve);
+
+    for (i = 0; i < num_tests; ++i) {
+        strtobytes(tests[i].private_key, private, private_key_size);
+        strtobytes(tests[i].public_key, public, public_key_size);
+        strtobytes(tests[i].k, k, private_key_size);
+        strtobytes(tests[i].hash, hash, private_key_size);
+        strtobytes(tests[i].r, r, private_key_size);
+        strtobytes(tests[i].s, s, private_key_size);
+
+        result = uECC_sign_with_k(private, hash, private_key_size, k, signature, curve);
+        if (!result) {
+            all_success = 0;
+            printf("  Sign failed for test %d\n", i);
+        }
+        if (result) {
+            if (memcmp(signature, r, private_key_size) != 0) {
+                all_success = 0;
+                printf("  Got incorrect r for test %d\n", i);
+                printf("    Expected: ");
+                vli_print(r, private_key_size);
+                printf("    Calculated: ");
+                vli_print(signature, private_key_size);
+            }
+            if (memcmp(signature + private_key_size, s, private_key_size) != 0) {
+                all_success = 0;
+                printf("  Got incorrect s for test %d\n", i);
+                printf("    Expected: ");
+                vli_print(s, private_key_size);
+                printf("    Calculated: ");
+                vli_print(signature + private_key_size, private_key_size);
+            }
+
+            result = uECC_verify(public, hash, private_key_size, signature, curve);
+            if (!result) {
+                printf("  Verify failed for test %d\n", i);
+            }
+        }
+    }
+
+    return all_success;
+}
+
+#define RUN_TESTS(curve) \
+    printf(#curve ":\n"); \
+    if (run(curve##_tests, sizeof(curve##_tests) / sizeof(curve##_tests[0]), uECC_##curve()) ) { \
+        printf("  All passed\n"); \
+    } else { \
+        printf("  Failed\n"); \
+    }
+
+int main() {
+#if uECC_SUPPORTS_secp256k1
+    RUN_TESTS(secp256k1)
+#endif
+
+    return 0;
+}
diff --git a/deps/micro-ecc/test/public_key_test_vectors.c b/deps/micro-ecc/test/public_key_test_vectors.c
new file mode 100644
index 0000000..a0afba8
--- /dev/null
+++ b/deps/micro-ecc/test/public_key_test_vectors.c
@@ -0,0 +1,338 @@
+/* Copyright 2020, Kenneth MacKay. Licensed under the BSD 2-clause license. */
+
+#include "uECC.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+typedef struct {
+  const char* k;
+  const char* Q;
+  int success;
+} Test;
+
+Test secp160r1_tests[] = {
+    /* Note, I couldn't find any test vectors for secp160r1 online, so these are just
+       generated on my desktop using uECC. */
+    {
+        "000000000000000000000000000000000000000000",
+        "00000000000000000000000000000000000000000000000000000000000000000000000000000000",
+        0
+    },
+    {
+        "000000000000000000000000000000000000000001",
+        "00000000000000000000000000000000000000000000000000000000000000000000000000000000",
+        0
+    },
+    {
+        "000000000000000000000000000000000000000002",
+        "02F997F33C5ED04C55D3EDF8675D3E92E8F46686F083A323482993E9440E817E21CFB7737DF8797B",
+        1
+    },
+    {
+        "000000000000000000000000000000000000000003",
+        "7B76FF541EF363F2DF13DE1650BD48DAA958BC59C915CA790D8C8877B55BE0079D12854FFE9F6F5A",
+        1
+    },
+    {   /* n - 4 */
+        "0100000000000000000001F4C8F927AED3CA752253",
+        "B4041D8683BE99F0AFE01C307B1AD4C100CF2A88C0CD35127BE0F73FF99F338B350B5A42864112F7",
+        1
+    },
+    {   /* n - 3 */
+        "0100000000000000000001F4C8F927AED3CA752254",
+        "7B76FF541EF363F2DF13DE1650BD48DAA958BC5936EA3586F27377884AA41FF862ED7AAF816090A5",
+        1
+    },
+    {   /* n - 2 */
+        "0100000000000000000001F4C8F927AED3CA752255",
+        "00000000000000000000000000000000000000000000000000000000000000000000000000000000",
+        0
+    },
+    {   /* n - 1 */
+        "0100000000000000000001F4C8F927AED3CA752256",
+        "00000000000000000000000000000000000000000000000000000000000000000000000000000000",
+        0
+    },
+    {   /* n */
+        "0100000000000000000001F4C8F927AED3CA752257",
+        "00000000000000000000000000000000000000000000000000000000000000000000000000000000",
+        0
+    },
+};
+
+
+Test secp192r1_tests[] = {
+    {
+        "000000000000000000000000000000000000000000000000",
+        "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+        0
+    },
+    {
+        "000000000000000000000000000000000000000000000001",
+        "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF101207192B95FFC8DA78631011ED6B24CDD573F977A11E794811",
+        0
+    },
+    {
+        "000000000000000000000000000000000000000000000002",
+        "DAFEBF5828783F2AD35534631588A3F629A70FB16982A888DD6BDA0D993DA0FA46B27BBC141B868F59331AFA5C7E93AB",
+        1
+    },
+    {
+        "000000000000000000000000000000000000000000000003",
+        "76E32A2557599E6EDCD283201FB2B9AADFD0D359CBB263DA782C37E372BA4520AA62E0FED121D49EF3B543660CFD05FD",
+        1
+    },
+    {   /* n - 4 */
+        "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D2282D",
+        "35433907297CC378B0015703374729D7A4FE46647084E4BA5D9B667B0DECA3CFE15C534F88932B0DDAC764CEE24C41CD",
+        1
+    },
+    {   /* n - 3 */
+        "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D2282E",
+        "76E32A2557599E6EDCD283201FB2B9AADFD0D359CBB263DA87D3C81C8D45BADF559D1F012EDE2B600C4ABC99F302FA02",
+        1
+    },
+    {   /* n - 2 */
+        "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D2282F",
+        "DAFEBF5828783F2AD35534631588A3F629A70FB16982A888229425F266C25F05B94D8443EBE4796FA6CCE505A3816C54",
+        0
+    },
+    {   /* n - 1 */
+        "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22830",
+        "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012F8E6D46A003725879CEFEE1294DB32298C06885EE186B7EE",
+        0
+    },
+    {   /* n */
+        "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831",
+        "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+        0
+    },
+};
+
+Test secp224r1_tests[] = {
+    {
+        "00000000000000000000000000000000000000000000000000000000",
+        "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+        0
+    },
+    {
+        "00000000000000000000000000000000000000000000000000000001",
+        "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34",
+        0
+    },
+    {
+        "00000000000000000000000000000000000000000000000000000002",
+        "706A46DC76DCB76798E60E6D89474788D16DC18032D268FD1A704FA61C2B76A7BC25E7702A704FA986892849FCA629487ACF3709D2E4E8BB",
+        1
+    },
+    {
+        "00000000000000000000000000000000000000000000000000000003",
+        "DF1B1D66A551D0D31EFF822558B9D2CC75C2180279FE0D08FD896D04A3F7F03CADD0BE444C0AA56830130DDF77D317344E1AF3591981A925",
+        1
+    },
+    {   /* n - 4 */
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A39",
+        "AE99FEEBB5D26945B54892092A8AEE02912930FA41CD114E40447301FB7DA7F5F13A43B81774373C879CD32D6934C05FA758EEB14FCFAB38",
+        1
+    },
+    {   /* n - 3 */
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3A",
+        "DF1B1D66A551D0D31EFF822558B9D2CC75C2180279FE0D08FD896D045C080FC3522F41BBB3F55A97CFECF21F882CE8CBB1E50CA6E67E56DC",
+        1
+    },
+    {   /* n - 2 */
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3B",
+        "706A46DC76DCB76798E60E6D89474788D16DC18032D268FD1A704FA6E3D4895843DA188FD58FB0567976D7B50359D6B78530C8F62D1B1746",
+        0
+    },
+    {   /* n - 1 */
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3C",
+        "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D2142C89C774A08DC04B3DD201932BC8A5EA5F8B89BBB2A7E667AFF81CD",
+        0
+    },
+    {   /* n */
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D",
+        "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+        0
+    },
+};
+
+Test secp256r1_tests[] = {
+    {
+        "0000000000000000000000000000000000000000000000000000000000000000",
+        "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+        0
+    },
+    {
+        "0000000000000000000000000000000000000000000000000000000000000001",
+        "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5",
+        0
+    },
+    {
+        "0000000000000000000000000000000000000000000000000000000000000002",
+        "7CF27B188D034F7E8A52380304B51AC3C08969E277F21B35A60B48FC4766997807775510DB8ED040293D9AC69F7430DBBA7DADE63CE982299E04B79D227873D1",
+        1
+    },
+    {
+        "0000000000000000000000000000000000000000000000000000000000000003",
+        "5ECBE4D1A6330A44C8F7EF951D4BF165E6C6B721EFADA985FB41661BC6E7FD6C8734640C4998FF7E374B06CE1A64A2ECD82AB036384FB83D9A79B127A27D5032",
+        1
+    },
+    {   /* n - 4 */
+        "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC63254D",
+        "E2534A3532D08FBBA02DDE659EE62BD0031FE2DB785596EF509302446B0308521F0EA8A4B39CC339E62011A02579D289B103693D0CF11FFAA3BD3DC0E7B12739",
+        1
+    },
+    {   /* n - 3 */
+        "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC63254E",
+        "5ECBE4D1A6330A44C8F7EF951D4BF165E6C6B721EFADA985FB41661BC6E7FD6C78CB9BF2B6670082C8B4F931E59B5D1327D54FCAC7B047C265864ED85D82AFCD",
+        1
+    },
+    {   /* n - 2 */
+        "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC63254F",
+        "7CF27B188D034F7E8A52380304B51AC3C08969E277F21B35A60B48FC47669978F888AAEE24712FC0D6C26539608BCF244582521AC3167DD661FB4862DD878C2E",
+        0
+    },
+    {   /* n - 1 */
+        "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632550",
+        "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296B01CBD1C01E58065711814B583F061E9D431CCA994CEA1313449BF97C840AE0A",
+        0
+    },
+    {   /* n */
+        "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551",
+        "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+        0
+    },
+};
+
+Test secp256k1_tests[] = {
+    {
+        "0000000000000000000000000000000000000000000000000000000000000000",
+        "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+        0
+    },
+    {
+        "0000000000000000000000000000000000000000000000000000000000000001",
+        "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8",
+        0
+    },
+    {
+        "0000000000000000000000000000000000000000000000000000000000000002",
+        "C6047F9441ED7D6D3045406E95C07CD85C778E4B8CEF3CA7ABAC09B95C709EE51AE168FEA63DC339A3C58419466CEAEEF7F632653266D0E1236431A950CFE52A",
+        1
+    },
+    {
+        "0000000000000000000000000000000000000000000000000000000000000003",
+        "F9308A019258C31049344F85F89D5229B531C845836F99B08601F113BCE036F9388F7B0F632DE8140FE337E62A37F3566500A99934C2231B6CB9FD7584B8E672",
+        1
+    },
+    {   /* n - 4 */
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD036413D",
+        "E493DBF1C10D80F3581E4904930B1404CC6C13900EE0758474FA94ABE8C4CD13AE1266C15F2BAA48A9BD1DF6715AEBB7269851CC404201BF30168422B88C630D",
+        1
+    },
+    {   /* n - 3 */
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD036413E",
+        "F9308A019258C31049344F85F89D5229B531C845836F99B08601F113BCE036F9C77084F09CD217EBF01CC819D5C80CA99AFF5666CB3DDCE4934602897B4715BD",
+        1
+    },
+    {   /* n - 2 */
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD036413F",
+        "C6047F9441ED7D6D3045406E95C07CD85C778E4B8CEF3CA7ABAC09B95C709EE5E51E970159C23CC65C3A7BE6B99315110809CD9ACD992F1EDC9BCE55AF301705",
+        0
+    },
+    {   /* n - 1 */
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364140",
+        "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798B7C52588D95C3B9AA25B0403F1EEF75702E84BB7597AABE663B82F6F04EF2777",
+        0
+    },
+    {   /* n */
+        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141",
+        "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+        0
+    },
+};
+
+
+void vli_print(uint8_t *vli, unsigned int size) {
+    for(unsigned i=0; i<size; ++i) {
+        printf("%02X ", (unsigned)vli[i]);
+    }
+    printf("\n");
+}
+
+void strtobytes(const char* str, uint8_t* bytes, int count) {
+  for (int c = 0; c < count; ++c) {
+    if (sscanf(str, "%2hhx", &bytes[c]) != 1) {
+      printf("Failed to read string to bytes");
+      exit(1);
+    }
+    str += 2;
+  }
+}
+
+int run(Test* tests, int num_tests, uECC_Curve curve) {
+    uint8_t private[32] = {0};
+    uint8_t public[64] = {0};
+    uint8_t expected[64] = {0};
+    int result;
+    int i;
+    int private_key_size;
+    int public_key_size;
+    int all_success = 1;
+
+    private_key_size = uECC_curve_private_key_size(curve);
+    public_key_size = uECC_curve_public_key_size(curve);
+
+    for (i = 0; i < num_tests; ++i) {
+        strtobytes(tests[i].k, private, private_key_size);
+        result = uECC_compute_public_key(private, public, curve);
+        if (result != tests[i].success) {
+            all_success = 0;
+            printf("  Got unexpected result from test %d: %d\n", i, result);
+        }
+        if (result) {
+            strtobytes(tests[i].Q, expected, public_key_size);
+            if (memcmp(public, expected, public_key_size) != 0) {
+                all_success = 0;
+                printf("  Got incorrect public key for test %d\n", i);
+                printf("    Expected: ");
+                vli_print(expected, public_key_size);
+                printf("    Calculated: ");
+                vli_print(public, public_key_size);
+            }
+        }
+    }
+
+    return all_success;
+}
+
+#define RUN_TESTS(curve) \
+    printf(#curve ":\n"); \
+    if (run(curve##_tests, sizeof(curve##_tests) / sizeof(curve##_tests[0]), uECC_##curve()) ) { \
+        printf("  All passed\n"); \
+    } else { \
+        printf("  Failed\n"); \
+    }
+
+int main() {
+#if uECC_SUPPORTS_secp160r1
+    RUN_TESTS(secp160r1)
+#endif
+#if uECC_SUPPORTS_secp192r1
+    RUN_TESTS(secp192r1)
+#endif
+#if uECC_SUPPORTS_secp224r1
+    RUN_TESTS(secp224r1)
+#endif
+#if uECC_SUPPORTS_secp256r1
+    RUN_TESTS(secp256r1)
+#endif
+#if uECC_SUPPORTS_secp256k1
+    RUN_TESTS(secp256k1)
+#endif
+
+    return 0;
+}
diff --git a/deps/micro-ecc/uECC.c b/deps/micro-ecc/uECC.c
index daa144a..a3d502c 100644
--- a/deps/micro-ecc/uECC.c
+++ b/deps/micro-ecc/uECC.c
@@ -13,73 +13,78 @@
     #define uECC_VLI_API static
 #endif
 
-#define CONCATX(a, ...) a ## __VA_ARGS__
-#define CONCAT(a, ...) CONCATX(a, __VA_ARGS__)
+#if (uECC_PLATFORM == uECC_avr) || \
+    (uECC_PLATFORM == uECC_arm) || \
+    (uECC_PLATFORM == uECC_arm_thumb) || \
+    (uECC_PLATFORM == uECC_arm_thumb2)
+    #define CONCATX(a, ...) a ## __VA_ARGS__
+    #define CONCAT(a, ...) CONCATX(a, __VA_ARGS__)
 
-#define STRX(a) #a
-#define STR(a) STRX(a)
+    #define STRX(a) #a
+    #define STR(a) STRX(a)
 
-#define EVAL(...)  EVAL1(EVAL1(EVAL1(EVAL1(__VA_ARGS__))))
-#define EVAL1(...) EVAL2(EVAL2(EVAL2(EVAL2(__VA_ARGS__))))
-#define EVAL2(...) EVAL3(EVAL3(EVAL3(EVAL3(__VA_ARGS__))))
-#define EVAL3(...) EVAL4(EVAL4(EVAL4(EVAL4(__VA_ARGS__))))
-#define EVAL4(...) __VA_ARGS__
+    #define EVAL(...)  EVAL1(EVAL1(EVAL1(EVAL1(__VA_ARGS__))))
+    #define EVAL1(...) EVAL2(EVAL2(EVAL2(EVAL2(__VA_ARGS__))))
+    #define EVAL2(...) EVAL3(EVAL3(EVAL3(EVAL3(__VA_ARGS__))))
+    #define EVAL3(...) EVAL4(EVAL4(EVAL4(EVAL4(__VA_ARGS__))))
+    #define EVAL4(...) __VA_ARGS__
 
-#define DEC_1  0
-#define DEC_2  1
-#define DEC_3  2
-#define DEC_4  3
-#define DEC_5  4
-#define DEC_6  5
-#define DEC_7  6
-#define DEC_8  7
-#define DEC_9  8
-#define DEC_10 9
-#define DEC_11 10
-#define DEC_12 11
-#define DEC_13 12
-#define DEC_14 13
-#define DEC_15 14
-#define DEC_16 15
-#define DEC_17 16
-#define DEC_18 17
-#define DEC_19 18
-#define DEC_20 19
-#define DEC_21 20
-#define DEC_22 21
-#define DEC_23 22
-#define DEC_24 23
-#define DEC_25 24
-#define DEC_26 25
-#define DEC_27 26
-#define DEC_28 27
-#define DEC_29 28
-#define DEC_30 29
-#define DEC_31 30
-#define DEC_32 31
+    #define DEC_1  0
+    #define DEC_2  1
+    #define DEC_3  2
+    #define DEC_4  3
+    #define DEC_5  4
+    #define DEC_6  5
+    #define DEC_7  6
+    #define DEC_8  7
+    #define DEC_9  8
+    #define DEC_10 9
+    #define DEC_11 10
+    #define DEC_12 11
+    #define DEC_13 12
+    #define DEC_14 13
+    #define DEC_15 14
+    #define DEC_16 15
+    #define DEC_17 16
+    #define DEC_18 17
+    #define DEC_19 18
+    #define DEC_20 19
+    #define DEC_21 20
+    #define DEC_22 21
+    #define DEC_23 22
+    #define DEC_24 23
+    #define DEC_25 24
+    #define DEC_26 25
+    #define DEC_27 26
+    #define DEC_28 27
+    #define DEC_29 28
+    #define DEC_30 29
+    #define DEC_31 30
+    #define DEC_32 31
 
-#define DEC(N) CONCAT(DEC_, N)
+    #define DEC(N) CONCAT(DEC_, N)
 
-#define SECOND_ARG(_, val, ...) val
-#define SOME_CHECK_0 ~, 0
-#define GET_SECOND_ARG(...) SECOND_ARG(__VA_ARGS__, SOME,)
-#define SOME_OR_0(N) GET_SECOND_ARG(CONCAT(SOME_CHECK_, N))
+    #define SECOND_ARG(_, val, ...) val
+    #define SOME_CHECK_0 ~, 0
+    #define GET_SECOND_ARG(...) SECOND_ARG(__VA_ARGS__, SOME,)
+    #define SOME_OR_0(N) GET_SECOND_ARG(CONCAT(SOME_CHECK_, N))
 
-#define EMPTY(...)
-#define DEFER(...) __VA_ARGS__ EMPTY()
+    #define EMPTY(...)
+    #define DEFER(...) __VA_ARGS__ EMPTY()
 
-#define REPEAT_NAME_0() REPEAT_0
-#define REPEAT_NAME_SOME() REPEAT_SOME
-#define REPEAT_0(...)
-#define REPEAT_SOME(N, stuff) DEFER(CONCAT(REPEAT_NAME_, SOME_OR_0(DEC(N))))()(DEC(N), stuff) stuff
-#define REPEAT(N, stuff) EVAL(REPEAT_SOME(N, stuff))
+    #define REPEAT_NAME_0() REPEAT_0
+    #define REPEAT_NAME_SOME() REPEAT_SOME
+    #define REPEAT_0(...)
+    #define REPEAT_SOME(N, stuff) DEFER(CONCAT(REPEAT_NAME_, SOME_OR_0(DEC(N))))()(DEC(N), stuff) stuff
+    #define REPEAT(N, stuff) EVAL(REPEAT_SOME(N, stuff))
 
-#define REPEATM_NAME_0() REPEATM_0
-#define REPEATM_NAME_SOME() REPEATM_SOME
-#define REPEATM_0(...)
-#define REPEATM_SOME(N, macro) macro(N) \
-    DEFER(CONCAT(REPEATM_NAME_, SOME_OR_0(DEC(N))))()(DEC(N), macro)
-#define REPEATM(N, macro) EVAL(REPEATM_SOME(N, macro))
+    #define REPEATM_NAME_0() REPEATM_0
+    #define REPEATM_NAME_SOME() REPEATM_SOME
+    #define REPEATM_0(...)
+    #define REPEATM_SOME(N, macro) macro(N) \
+        DEFER(CONCAT(REPEATM_NAME_, SOME_OR_0(DEC(N))))()(DEC(N), macro)
+    #define REPEATM(N, macro) EVAL(REPEATM_SOME(N, macro))
+#endif
 
 #include "platform-specific.inc"
 
@@ -912,19 +917,54 @@
     return carry;
 }
 
+/* Generates a random integer in the range 0 < random < top.
+   Both random and top have num_words words. */
+uECC_VLI_API int uECC_generate_random_int(uECC_word_t *random,
+                                          const uECC_word_t *top,
+                                          wordcount_t num_words) {
+    uECC_word_t mask = (uECC_word_t)-1;
+    uECC_word_t tries;
+    bitcount_t num_bits = uECC_vli_numBits(top, num_words);
+
+    if (!g_rng_function) {
+        return 0;
+    }
+
+    for (tries = 0; tries < uECC_RNG_MAX_TRIES; ++tries) {
+        if (!g_rng_function((uint8_t *)random, num_words * uECC_WORD_SIZE)) {
+            return 0;
+        }
+        random[num_words - 1] &= mask >> ((bitcount_t)(num_words * uECC_WORD_SIZE * 8 - num_bits));
+        if (!uECC_vli_isZero(random, num_words) &&
+                uECC_vli_cmp(top, random, num_words) == 1) {
+            return 1;
+        }
+    }
+    return 0;
+}
+
 static uECC_word_t EccPoint_compute_public_key(uECC_word_t *result,
                                                uECC_word_t *private_key,
                                                uECC_Curve curve) {
     uECC_word_t tmp1[uECC_MAX_WORDS];
     uECC_word_t tmp2[uECC_MAX_WORDS];
     uECC_word_t *p2[2] = {tmp1, tmp2};
+    uECC_word_t *initial_Z = 0;
     uECC_word_t carry;
 
     /* Regularize the bitcount for the private key so that attackers cannot use a side channel
        attack to learn the number of leading zeros. */
     carry = regularize_k(private_key, tmp1, tmp2, curve);
 
-    EccPoint_mult(result, curve->G, p2[!carry], 0, curve->num_n_bits + 1, curve);
+    /* If an RNG function was specified, try to get a random initial Z value to improve
+       protection against side-channel attacks. */
+    if (g_rng_function) {
+        if (!uECC_generate_random_int(p2[carry], curve->p, curve->num_words)) {
+            return 0;
+        }
+        initial_Z = p2[carry];
+    }
+    EccPoint_mult(result, curve->G, p2[!carry], initial_Z, curve->num_n_bits + 1, curve);
 
     if (EccPoint_isZero(result, curve)) {
         return 0;
@@ -954,7 +994,7 @@
 uECC_VLI_API void uECC_vli_nativeToBytes(uint8_t *bytes,
                                          int num_bytes,
                                          const uECC_word_t *native) {
-    wordcount_t i;
+    int i;
     for (i = 0; i < num_bytes; ++i) {
         unsigned b = num_bytes - 1 - i;
         bytes[i] = native[b / uECC_WORD_SIZE] >> (8 * (b % uECC_WORD_SIZE));
@@ -964,7 +1004,7 @@
 uECC_VLI_API void uECC_vli_bytesToNative(uECC_word_t *native,
                                          const uint8_t *bytes,
                                          int num_bytes) {
-    wordcount_t i;
+    int i;
     uECC_vli_clear(native, (num_bytes + (uECC_WORD_SIZE - 1)) / uECC_WORD_SIZE);
     for (i = 0; i < num_bytes; ++i) {
         unsigned b = num_bytes - 1 - i;
@@ -975,32 +1015,6 @@
 
 #endif /* uECC_WORD_SIZE */
 
-/* Generates a random integer in the range 0 < random < top.
-   Both random and top have num_words words. */
-uECC_VLI_API int uECC_generate_random_int(uECC_word_t *random,
-                                          const uECC_word_t *top,
-                                          wordcount_t num_words) {
-    uECC_word_t mask = (uECC_word_t)-1;
-    uECC_word_t tries;
-    bitcount_t num_bits = uECC_vli_numBits(top, num_words);
-
-    if (!g_rng_function) {
-        return 0;
-    }
-
-    for (tries = 0; tries < uECC_RNG_MAX_TRIES; ++tries) {
-        if (!g_rng_function((uint8_t *)random, num_words * uECC_WORD_SIZE)) {
-            return 0;
-	    }
-        random[num_words - 1] &= mask >> ((bitcount_t)(num_words * uECC_WORD_SIZE * 8 - num_bits));
-        if (!uECC_vli_isZero(random, num_words) &&
-		        uECC_vli_cmp(top, random, num_words) == 1) {
-            return 1;
-        }
-    }
-    return 0;
-}
-
 int uECC_make_key(uint8_t *public_key,
                   uint8_t *private_key,
                   uECC_Curve curve) {
@@ -1115,7 +1129,7 @@
 }
 #endif /* uECC_SUPPORT_COMPRESSED_POINT */
 
-int uECC_valid_point(const uECC_word_t *point, uECC_Curve curve) {
+uECC_VLI_API int uECC_valid_point(const uECC_word_t *point, uECC_Curve curve) {
     uECC_word_t tmp1[uECC_MAX_WORDS];
     uECC_word_t tmp2[uECC_MAX_WORDS];
     wordcount_t num_words = curve->num_words;
@@ -1210,7 +1224,7 @@
     bcopy((uint8_t *) native, bits, bits_size);
 #else
     uECC_vli_bytesToNative(native, bits, bits_size);
-#endif    
+#endif
     if (bits_size * 8 <= (unsigned)curve->num_n_bits) {
         return;
     }
@@ -1229,7 +1243,7 @@
     }
 }
 
-static int uECC_sign_with_k(const uint8_t *private_key,
+static int uECC_sign_with_k_internal(const uint8_t *private_key,
                             const uint8_t *message_hash,
                             unsigned hash_size,
                             uECC_word_t *k,
@@ -1239,6 +1253,7 @@
     uECC_word_t tmp[uECC_MAX_WORDS];
     uECC_word_t s[uECC_MAX_WORDS];
     uECC_word_t *k2[2] = {tmp, s};
+    uECC_word_t *initial_Z = 0;
 #if uECC_VLI_NATIVE_LITTLE_ENDIAN
     uECC_word_t *p = (uECC_word_t *)signature;
 #else
@@ -1255,7 +1270,15 @@
     }
 
     carry = regularize_k(k, tmp, s, curve);
-    EccPoint_mult(p, curve->G, k2[!carry], 0, num_n_bits + 1, curve);
+    /* If an RNG function was specified, try to get a random initial Z value to improve
+       protection against side-channel attacks. */
+    if (g_rng_function) {
+        if (!uECC_generate_random_int(k2[carry], curve->p, num_words)) {
+            return 0;
+        }
+        initial_Z = k2[carry];
+    }
+    EccPoint_mult(p, curve->G, k2[!carry], initial_Z, num_n_bits + 1, curve);
     if (uECC_vli_isZero(p, num_words)) {
         return 0;
     }
@@ -1299,10 +1322,22 @@
     bcopy((uint8_t *) signature + curve->num_bytes, (uint8_t *) s, curve->num_bytes);
 #else
     uECC_vli_nativeToBytes(signature + curve->num_bytes, curve->num_bytes, s);
-#endif    
+#endif
     return 1;
 }
 
+/* For testing - sign with an explicitly specified k value */
+int uECC_sign_with_k(const uint8_t *private_key,
+                            const uint8_t *message_hash,
+                            unsigned hash_size,
+                            const uint8_t *k,
+                            uint8_t *signature,
+                            uECC_Curve curve) {
+    uECC_word_t k2[uECC_MAX_WORDS];
+    bits2int(k2, k, BITS_TO_BYTES(curve->num_n_bits), curve);
+    return uECC_sign_with_k_internal(private_key, message_hash, hash_size, k2, signature, curve);
+}
+
 int uECC_sign(const uint8_t *private_key,
               const uint8_t *message_hash,
               unsigned hash_size,
@@ -1316,7 +1351,7 @@
             return 0;
         }
 
-        if (uECC_sign_with_k(private_key, message_hash, hash_size, k, signature, curve)) {
+        if (uECC_sign_with_k_internal(private_key, message_hash, hash_size, k, signature, curve)) {
             return 1;
         }
     }
@@ -1432,7 +1467,7 @@
                 mask >> ((bitcount_t)(num_n_words * uECC_WORD_SIZE * 8 - num_n_bits));
         }
 
-        if (uECC_sign_with_k(private_key, message_hash, hash_size, T, signature, curve)) {
+        if (uECC_sign_with_k_internal(private_key, message_hash, hash_size, T, signature, curve)) {
             return 1;
         }
 
@@ -1472,7 +1507,7 @@
     uECC_word_t *_public = (uECC_word_t *)public_key;
 #else
     uECC_word_t _public[uECC_MAX_WORDS * 2];
-#endif    
+#endif
     uECC_word_t r[uECC_MAX_WORDS], s[uECC_MAX_WORDS];
     wordcount_t num_words = curve->num_words;
     wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits);
diff --git a/deps/micro-ecc/uECC.h b/deps/micro-ecc/uECC.h
index 9911763..dcbdbfa 100644
--- a/deps/micro-ecc/uECC.h
+++ b/deps/micro-ecc/uECC.h
@@ -38,13 +38,16 @@
 #endif
 
 /* uECC_VLI_NATIVE_LITTLE_ENDIAN - If enabled (defined as nonzero), this will switch to native
-little-endian format for *all* arrays passed in and out of the public API. This includes public 
-and private keys, shared secrets, signatures and message hashes. 
+little-endian format for *all* arrays passed in and out of the public API. This includes public
+and private keys, shared secrets, signatures and message hashes.
 Using this switch reduces the amount of call stack memory used by uECC, since less intermediate
-translations are required. 
+translations are required.
 Note that this will *only* work on native little-endian processors and it will treat the uint8_t
-arrays passed into the public API as word arrays, therefore requiring the provided byte arrays 
-to be word aligned on architectures that do not support unaligned accesses. */
+arrays passed into the public API as word arrays, therefore requiring the provided byte arrays
+to be word aligned on architectures that do not support unaligned accesses.
+IMPORTANT: Keys and signatures generated with uECC_VLI_NATIVE_LITTLE_ENDIAN=1 are incompatible
+with keys and signatures generated with uECC_VLI_NATIVE_LITTLE_ENDIAN=0; all parties must use
+the same endianness. */
 #ifndef uECC_VLI_NATIVE_LITTLE_ENDIAN
     #define uECC_VLI_NATIVE_LITTLE_ENDIAN 0
 #endif
@@ -163,7 +166,9 @@
 int uECC_make_key(uint8_t *public_key, uint8_t *private_key, uECC_Curve curve);
 
 /* uECC_shared_secret() function.
-Compute a shared secret given your secret key and someone else's public key.
+Compute a shared secret given your secret key and someone else's public key. If the public key
+is not from a trusted source and has not been previously verified, you should verify it first
+using uECC_valid_public_key().
 Note: It is recommended that you hash the result of uECC_shared_secret() before using it for
 symmetric encryption or HMAC.