diff --git a/firmware/applications/final.c b/firmware/applications/final.c
index d9ee29a..bedce8c 100644
--- a/firmware/applications/final.c
+++ b/firmware/applications/final.c
@@ -6,6 +6,8 @@
 
 #include <string.h>
 
+#include "basic/ecc.h"
+
 /**************************************************************************/
 
 #include "final.gen"
@@ -18,14 +20,12 @@ void forLoadables(int i){
     if(i){
         lcdSetPixel(0,0);
         font=&Font_Invaders;
-        //filetransfer_send();
-        ECIES_encyptkeygen();
-        //filetransfer_receive();
-        //rftransfer_receive(); 
-        //rftransfer_send(); 
+        ECIES_encyptkeygen(0,0,0,0,0,0);
         systickGetTicks();
-        ECIES_decryptkeygen();
-        bitstr_parse_export();
+        ECIES_embedded_public_key_validation();
+        point_copy(0,0,0,0);
+        point_is_zero(0,0);
+        bitstr_parse_export(0,0);
         nrf_rcv_pkt_time_encr();
     };
 };
diff --git a/firmware/basic/ecc.c b/firmware/basic/ecc.c
index cbdb174..7db95db 100644
--- a/firmware/basic/ecc.c
+++ b/firmware/basic/ecc.c
@@ -25,9 +25,6 @@ unsigned char rnd1()
 }
 
 
-#define MACRO(A) do { A; } while(0)
-#define MIN(a, b) ((a) < (b) ? (a) : (b))
-
 //compiles to a quite reasonable assembly code
 //void INT2CHARS (unsigned char *ptr, uint32_t val) 
 void INT2CHARS (char *ptr, uint32_t val) 
@@ -50,17 +47,6 @@ r|=*ptr--;
 return r;
 }
 
-     /* some basic bit-manipulation routines that act on these vectors follow */
-#define bitstr_getbit(A, idx) ((A[(idx) / 32] >> ((idx) % 32)) & 1)
-#define bitstr_setbit(A, idx) MACRO( A[(idx) / 32] |= 1 << ((idx) % 32) )
-#define bitstr_clrbit(A, idx) MACRO( A[(idx) / 32] &= ~(1 << ((idx) % 32)) )
-
-#define bitstr_clear(A) MACRO( memset(A, 0, sizeof(bitstr_t)) )
-#define bitstr_copy(A, B) MACRO( memcpy(A, B, sizeof(bitstr_t)) )
-#define bitstr_swap(A, B) MACRO( bitstr_t h; \
-  bitstr_copy(h, A); bitstr_copy(A, B); bitstr_copy(B, h) )
-#define bitstr_is_equal(A, B) (! memcmp(A, B, sizeof(bitstr_t)))
-
 int bitstr_is_clear(const bitstr_t x)
 {
   int i;
@@ -184,7 +170,6 @@ int bitstr_parse_export(char *exp, const char *s)
 
 
 
-#define field_set1(A) MACRO( A[0] = 1; memset(A + 1, 0, sizeof(elem_t) - 4) )
 
 int field_is1(const elem_t x)
 {
@@ -253,12 +238,6 @@ void field_invert(elem_t z, const elem_t x)                /* field inversion */
    curves). Coefficient 'b' is given in 'coeff_b'.  '(base_x, base_y)'
    is a point that generates a large prime order group.             */
 
-
-#define point_is_zero(x, y) (bitstr_is_clear(x) && bitstr_is_clear(y))
-#define point_set_zero(x, y) MACRO( bitstr_clear(x); bitstr_clear(y) )
-#define point_copy(x1, y1, x2, y2) MACRO( bitstr_copy(x1, x2); \
-                                          bitstr_copy(y1, y2) )
-
                            /* check if y^2 + x*y = x^3 + *x^2 + coeff_b holds */
 int is_point_on_curve(const elem_t x, const elem_t y)
 {
diff --git a/firmware/basic/ecc.h b/firmware/basic/ecc.h
index 73512e2..d946cd3 100644
--- a/firmware/basic/ecc.h
+++ b/firmware/basic/ecc.h
@@ -32,5 +32,27 @@ void ECIES_encryption(char *msg, const char *text, int len,
 int ECIES_decryption(char *text, const char *msg, int len, 
 		     const char *privkey);
 
+#define MACRO(A) do { A; } while(0)
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+     /* some basic bit-manipulation routines that act on these vectors follow */
+#define bitstr_getbit(A, idx) ((A[(idx) / 32] >> ((idx) % 32)) & 1)
+#define bitstr_setbit(A, idx) MACRO( A[(idx) / 32] |= 1 << ((idx) % 32) )
+#define bitstr_clrbit(A, idx) MACRO( A[(idx) / 32] &= ~(1 << ((idx) % 32)) )
+
+#define bitstr_clear(A) MACRO( memset(A, 0, sizeof(bitstr_t)) )
+#define bitstr_copy(A, B) MACRO( memcpy(A, B, sizeof(bitstr_t)) )
+#define bitstr_swap(A, B) MACRO( bitstr_t h; \
+  bitstr_copy(h, A); bitstr_copy(A, B); bitstr_copy(B, h) )
+#define bitstr_is_equal(A, B) (! memcmp(A, B, sizeof(bitstr_t)))
+
+#define field_set1(A) MACRO( A[0] = 1; memset(A + 1, 0, sizeof(elem_t) - 4) )
+
+
+#define point_is_zero(x, y) (bitstr_is_clear(x) && bitstr_is_clear(y))
+#define point_set_zero(x, y) MACRO( bitstr_clear(x); bitstr_clear(y) )
+#define point_copy(x1, y1, x2, y2) MACRO( bitstr_copy(x1, x2); \
+                                          bitstr_copy(y1, y2) )
+
+
 #endif
 
diff --git a/firmware/loadable/recvcard.c b/firmware/loadable/recvcard.c
index 57fad8b..8571f7c 100644
--- a/firmware/loadable/recvcard.c
+++ b/firmware/loadable/recvcard.c
@@ -318,3 +318,21 @@ int16_t rftransfer_receive(uint8_t *buffer, uint16_t maxlen, uint16_t timeout)
     return -2;
 }
 
+int ECIES_decryptkeygen(uint8_t *rx, uint8_t *ry,
+             uint8_t k1[16], uint8_t k2[16], const char *privkey)
+{
+  elem_t Rx, Ry, Zx, Zy;
+  exp_t d;
+  bitstr_import(Rx, (char*)rx);
+  bitstr_import(Ry, (char*)ry);
+  if (ECIES_embedded_public_key_validation(Rx, Ry) < 0)
+    return -1;
+  bitstr_parse(d, privkey);
+  point_copy(Zx, Zy, Rx, Ry);
+  point_mult(Zx, Zy, d);
+  point_double(Zx, Zy);                             /* cofactor h = 2 on B163 */
+  if (point_is_zero(Zx, Zy))
+    return -1;
+  ECIES_kdf((char*)k1,(char*) k2, Zx, Rx, Ry);
+  return 0;
+}
diff --git a/firmware/loadable/sendcard.c b/firmware/loadable/sendcard.c
index b31dae3..dae0f0e 100644
--- a/firmware/loadable/sendcard.c
+++ b/firmware/loadable/sendcard.c
@@ -282,3 +282,4 @@ void rftransfer_send(uint16_t size, uint8_t *data)
     nrf_snd_pkt_crc(32,buf);     //setup packet
     delayms(20);
 }
+