]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
Add back the elliptic curve (ECC) files
authorTravis Cross <tc@traviscross.com>
Sun, 10 Feb 2013 21:54:15 +0000 (21:54 +0000)
committerTravis Cross <tc@traviscross.com>
Mon, 11 Feb 2013 16:42:08 +0000 (16:42 +0000)
Signed-off-by: Travis Cross <tc@traviscross.com>
Signed-off-by: Philip Zimmermann <prz@mit.edu>
libs/libzrtp/include/zrtp_config_user.h
libs/libzrtp/include/zrtp_ec.h [new file with mode: 0644]
libs/libzrtp/projects/win/libzrtp.vcproj
libs/libzrtp/projects/win_ce/libzrtp_wince.vcproj
libs/libzrtp/projects/win_kernel/MAKEFILE.WIN32
libs/libzrtp/projects/win_kernel/MAKEFILE.WIN64
libs/libzrtp/src/zrtp_crypto_ec.c [new file with mode: 0644]
libs/libzrtp/src/zrtp_crypto_ecdh.c [new file with mode: 0644]
libs/libzrtp/src/zrtp_crypto_ecdsa.c [new file with mode: 0644]

index 352770eaa47283815a37cf226d7f23adc73c9e92..c87a6c790eef3931801d042c76fd564aa038443e 100644 (file)
 #endif
 
 #ifndef ZRTP_ENABLE_EC
-#define ZRTP_ENABLE_EC                         0
+#define ZRTP_ENABLE_EC                         1
 #endif
 
 #ifndef ZRTP_DEBUG_WITH_PJSIP
diff --git a/libs/libzrtp/include/zrtp_ec.h b/libs/libzrtp/include/zrtp_ec.h
new file mode 100644 (file)
index 0000000..c4d2f71
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * zrtp_crypto_ec.c - Elliptic Curve Low Level Crypto functions for ZRTP.
+ * NSA Suite B Elliptic Curves from NIST SP 800-56A and FIPS 186-3.
+ *
+ * Copyright (c) 2006-2009 Philip R. Zimmermann. All rights reserved.
+ * This is NOT licensed under the GPL or any other open source license.
+ * For licensing terms or other information,
+ * contact:  Philip Zimmermann <prz@mit.edu>.
+ * For more contact information, see http://philzimmermann.com
+ */
+#ifndef __ZRTP_CRYPTO_EC_H__
+#define __ZRTP_CRYPTO_EC_H__
+
+#include "bn.h"
+
+#include "zrtp_config.h"
+#include "zrtp_types.h"
+#include "zrtp_error.h"
+
+#if (defined(ZRTP_ENABLE_EC) && (ZRTP_ENABLE_EC == 1))
+
+#define ZRTP_MAXECBITS 521
+#define ZRTP_MAXECWORDS        ((ZRTP_MAXECBITS+7)/8)
+
+typedef struct zrtp_ec_params
+{
+       unsigned                ec_bits;                                                /* # EC bits: 256, 384, 521 */
+       uint8_t                 P_data[ZRTP_MAXECWORDS];                /* curve field prime */
+       uint8_t                 n_data[ZRTP_MAXECWORDS];                /* curve order (# points) */
+       uint8_t                 b_data[ZRTP_MAXECWORDS];                /* curve param, y^3 = x^2 -3x + b */
+       uint8_t                 Gx_data[ZRTP_MAXECWORDS];               /* curve point, x coordinate */
+       uint8_t                 Gy_data[ZRTP_MAXECWORDS];               /* curve point, y coordinate */
+} zrtp_ec_params_t;
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif 
+/*============================================================================*/
+/*       Elliptic Curve library                                                                          */
+/*============================================================================*/
+
+int zrtp_ecAdd ( struct BigNum *rsltx,
+                                struct BigNum *rslty,
+                                struct BigNum *p1x,
+                                struct BigNum *p1y,
+                                struct BigNum *p2x,
+                                struct BigNum *p2y,
+                                struct BigNum *mod);
+
+int zrtp_ecMul ( struct BigNum *rsltx,
+                                struct BigNum *rslty,
+                                struct BigNum *mult,
+                                struct BigNum *basex,
+                                struct BigNum *basey,
+                                struct BigNum *mod);
+
+zrtp_status_t zrtp_ec_random_point( zrtp_global_t *zrtp,
+                                                                       struct BigNum *P,
+                                                                       struct BigNum *n,
+                                                                       struct BigNum *Gx,
+                                                                       struct BigNum *Gy,
+                                                                       struct BigNum *pkx,
+                                                                       struct BigNum *pky,
+                                                                       struct BigNum *sv,
+                                                                       uint8_t *test_sv_data,
+                                                                       size_t test_sv_data_len);
+
+extern zrtp_status_t zrtp_ec_init_params(struct zrtp_ec_params *params, uint32_t bits );
+
+
+/* Useful bignum utility functions not defined in bignum library */
+int bnAddMod_ (struct BigNum *rslt, struct BigNum *n1, struct BigNum *mod);
+int bnAddQMod_ (struct BigNum *rslt, unsigned n1, struct BigNum *mod);
+int bnSubMod_ (struct BigNum *rslt, struct BigNum *n1, struct BigNum *mod);
+int bnSubQMod_ (struct BigNum *rslt, unsigned n1, struct BigNum *mod);
+int bnMulMod_ (struct BigNum *rslt, struct BigNum *n1, struct BigNum *n2, struct BigNum *mod);
+int bnMulQMod_ (struct BigNum *rslt, struct BigNum *n1, unsigned n2, struct BigNum *mod);
+int bnSquareMod_ (struct BigNum *rslt, struct BigNum *n1, struct BigNum *mod);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /*ZRTP_ENABLE_EC*/
+
+#endif /* __ZRTP_CRYPTO_EC_H__ */
index 38fd62fbb47e31214be90eb9785a0c3f64079a20..485bd2f02d527932ab8528e81422a5d661332ea0 100644 (file)
@@ -43,7 +43,7 @@
                                Name="VCCLCompilerTool"\r
                                Optimization="0"\r
                                AdditionalIncludeDirectories="../../include;../../third_party/bnlib;../../third_party/bgaes;../../test/include"\r
-                               PreprocessorDefinitions="WIN32;_DEBUG;_LIB;HAVE_CONFIG_H=1;ZRTP_ENABLE_EC=0"\r
+                               PreprocessorDefinitions="WIN32;_DEBUG;_LIB;HAVE_CONFIG_H=1;ZRTP_ENABLE_EC=1"\r
                                MinimalRebuild="true"\r
                                BasicRuntimeChecks="3"\r
                                RuntimeLibrary="1"\r
                        <Tool\r
                                Name="VCCLCompilerTool"\r
                                AdditionalIncludeDirectories="../../include;../../third_party/bnlib;../../third_party/bgaes"\r
-                               PreprocessorDefinitions="WIN32;NDEBUG;_LIB;HAVE_CONFIG_H=1;ZRTP_ENABLE_EC=0"\r
+                               PreprocessorDefinitions="WIN32;NDEBUG;_LIB;HAVE_CONFIG_H=1;ZRTP_ENABLE_EC=1"\r
                                ExceptionHandling="0"\r
                                RuntimeLibrary="0"\r
                                StructMemberAlignment="0"\r
                                RelativePath="..\..\include\zrtp_crypto.h"\r
                                >\r
                        </File>\r
+                       <File\r
+                               RelativePath="..\..\include\zrtp_ec.h"\r
+                               >\r
+                       </File>\r
                        <File\r
                                RelativePath="..\..\include\zrtp_engine.h"\r
                                >\r
                                RelativePath="..\..\include\zrtp_utils.h"\r
                                >\r
                        </File>\r
+                       <File\r
+                               RelativePath="..\..\include\zrtp_version.h"\r
+                               >\r
+                       </File>\r
                </Filter>\r
                <Filter\r
                        Name="src"\r
                                RelativePath="..\..\src\zrtp_crypto_atl.c"\r
                                >\r
                        </File>\r
+                       <File\r
+                               RelativePath="..\..\src\zrtp_crypto_ec.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\zrtp_crypto_ecdh.c"\r
+                               >\r
+                       </File>\r
                        <File\r
                                RelativePath="..\..\src\zrtp_crypto_hash.c"\r
                                >\r
index d16b5559d6078dd489632d2503f96537a545496b..cbe4fb4389fe411b32cf066805faecd51cdd01cc 100644 (file)
@@ -52,7 +52,7 @@
                                ExecutionBucket="7"\r
                                Optimization="0"\r
                                AdditionalIncludeDirectories="../../third_party/bnlib;../../include;../../include/enterprise;../../third_party/bgaes;../../test/include"\r
-                               PreprocessorDefinitions="_DEBUG;_WIN32_WCE=$(CEVER);UNDER_CE;$(PLATFORMDEFINES);WINCE;DEBUG;_LIB;$(ARCHFAM);$(_ARCHFAM_);_UNICODE;UNICODE;ZRTP_ENABLE_EC=0"\r
+                               PreprocessorDefinitions="_DEBUG;_WIN32_WCE=$(CEVER);UNDER_CE;$(PLATFORMDEFINES);WINCE;DEBUG;_LIB;$(ARCHFAM);$(_ARCHFAM_);_UNICODE;UNICODE;ZRTP_ENABLE_EC=1"\r
                                MinimalRebuild="true"\r
                                RuntimeLibrary="1"\r
                                StructMemberAlignment="0"\r
                                ExecutionBucket="7"\r
                                Optimization="0"\r
                                AdditionalIncludeDirectories="../../third_party/bnlib;../../include;../../include/enterprise;../../third_party/bgaes;../../test/include"\r
-                               PreprocessorDefinitions="_DEBUG;_WIN32_WCE=$(CEVER);UNDER_CE;$(PLATFORMDEFINES);WINCE;DEBUG;_LIB;$(ARCHFAM);$(_ARCHFAM_);_UNICODE;ZRTP_ENABLE_EC=0"\r
+                               PreprocessorDefinitions="_DEBUG;_WIN32_WCE=$(CEVER);UNDER_CE;$(PLATFORMDEFINES);WINCE;DEBUG;_LIB;$(ARCHFAM);$(_ARCHFAM_);_UNICODE;ZRTP_ENABLE_EC=1"\r
                                MinimalRebuild="true"\r
                                RuntimeLibrary="1"\r
                                BufferSecurityCheck="false"\r
                                ExecutionBucket="7"\r
                                Optimization="2"\r
                                AdditionalIncludeDirectories="../../third_party/bnlib;../../include;../../include/enterprise;../../third_party/bgaes;../../test/include"\r
-                               PreprocessorDefinitions="NDEBUG;_WIN32_WCE=$(CEVER);UNDER_CE;$(PLATFORMDEFINES);WINCE;_LIB;$(ARCHFAM);$(_ARCHFAM_);_UNICODE;ZRTP_ENABLE_EC=0"\r
+                               PreprocessorDefinitions="NDEBUG;_WIN32_WCE=$(CEVER);UNDER_CE;$(PLATFORMDEFINES);WINCE;_LIB;$(ARCHFAM);$(_ARCHFAM_);_UNICODE;ZRTP_ENABLE_EC=1"\r
                                RuntimeLibrary="0"\r
                                BufferSecurityCheck="false"\r
                                UsePrecompiledHeader="0"\r
                                ExecutionBucket="7"\r
                                Optimization="2"\r
                                AdditionalIncludeDirectories="../../third_party/bnlib;../../include;../../include/enterprise;../../third_party/bgaes;../../test/include"\r
-                               PreprocessorDefinitions="NDEBUG;_WIN32_WCE=$(CEVER);UNDER_CE;$(PLATFORMDEFINES);WINCE;_LIB;$(ARCHFAM);$(_ARCHFAM_);_UNICODE;UNICODE;ZRTP_ENABLE_EC=0"\r
+                               PreprocessorDefinitions="NDEBUG;_WIN32_WCE=$(CEVER);UNDER_CE;$(PLATFORMDEFINES);WINCE;_LIB;$(ARCHFAM);$(_ARCHFAM_);_UNICODE;UNICODE;ZRTP_ENABLE_EC=1"\r
                                RuntimeLibrary="0"\r
                                BufferSecurityCheck="false"\r
                                UsePrecompiledHeader="0"\r
                                RelativePath="..\..\include\zrtp_crypto.h"\r
                                >\r
                        </File>\r
+                       <File\r
+                               RelativePath="..\..\include\zrtp_ec.h"\r
+                               >\r
+                       </File>\r
                        <File\r
                                RelativePath="..\..\include\zrtp_engine.h"\r
                                >\r
                                RelativePath="..\..\src\zrtp_crypto_atl.c"\r
                                >\r
                        </File>\r
+                       <File\r
+                               RelativePath="..\..\src\zrtp_crypto_ec.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\zrtp_crypto_ecdh.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\src\zrtp_crypto_ecdsa.c"\r
+                               >\r
+                       </File>\r
                        <File\r
                                RelativePath="..\..\src\zrtp_crypto_hash.c"\r
                                >\r
                                RelativePath="..\..\src\zrtp_engine.c"\r
                                >\r
                        </File>\r
+                       <File\r
+                               RelativePath="..\..\src\zrtp_engine_driven.c"\r
+                               >\r
+                       </File>\r
                        <File\r
                                RelativePath="..\..\src\zrtp_iface_cache.c"\r
                                >\r
index e44b9559338a2521c01c628d043ac6d4146d6cc9..2b15ded64ad8472a49028aad800cb65106e1d3a7 100644 (file)
@@ -43,6 +43,9 @@ protocol = \
                ../../src/zrtp_crypto_sas.obj \\r
                ../../src/zrtp_datatypes.obj \\r
                ../../src/zrtp_engine.obj \\r
+               ../../src/enterprise/zrtp_engine_driven.obj \\r
+               ../../src/enterprise/zrtp_crypto_ec.obj  \\r
+               ../../src/enterprise/zrtp_crypto_ecdh.obj  \\r
                ../../src/zrtp_iface_sys.obj \\r
                ../../src/zrtp_initiator.obj \\r
                ../../src/zrtp_legal.obj \\r
@@ -71,13 +74,13 @@ OBJECTS  = $(bnlib) $(protocol) $(bgaes)
 \r
 # Debug\r
 \r
-OUT_DIR = debug.km\r
+OUT_DIR = debug_ec.km\r
 \r
 DEFINES_D = -D_X86_=1 -Di386=1 -DSTD_CALL -DCONDITION_HANDLING=1 \\r
 -DNT_UP=1 -DNT_INST=0 -DWIN32=100 -D_NT1X_=100 \\r
 -DWINNT=1 -D_WIN32_WINNT=0x0500 -DWIN32_LEAN_AND_MEAN=1 -DDBG=1 -D_DEBUG -DDEBUG -DDEVL=1 \\r
 -DFPO=0 -D_DLL=1 -D_IDWBUILD -DRDRDBG -DSRVDBG -DDBG_MESSAGES=1 \\r
--D_UNICODE -DLITTLE_ENDIAN -DZRTP_USE_ENTERPRISE=0\r
+-D_UNICODE -DLITTLE_ENDIAN -DZRTP_USE_ENTERPRISE=1\r
 \r
 CFLAGS_D = $(DEFINES_D) -Zel -Zp8 -Gy -cbstring -Gz -QIfdiv- -QIf -Gi- -Gm- -GX- \\r
 -GR- -GF -FI$(DDK)\inc\$(OS)\warning.h -Z7 -Od -Oi -Oy- -W3\r
@@ -86,13 +89,13 @@ CFLAGS_D = $(DEFINES_D) -Zel -Zp8 -Gy -cbstring -Gz -QIfdiv- -QIf -Gi- -Gm- -GX-
 \r
 # Release\r
 \r
-OUT_DIR = release.km\r
+OUT_DIR = release_ec.km\r
 \r
 DEFINES_D = -D_X86_=1 -Di386=1 -DSTD_CALL -DCONDITION_HANDLING=1 \\r
 -DNT_UP=1 -DNO_DISK_ACCESS -DNT_INST=0 -DWIN32=100 -D_NT1X_=100 \\r
 -DWINNT=1 -D_WIN32_WINNT=0x0500 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 \\r
 -DFPO=1 -DNDEBUG -D_DLL=1 -D_IDWBUILD -D_UNICODE \\r
--DLITTLE_ENDIAN  -DZRTP_USE_ENTERPRISE=0\r
+-DLITTLE_ENDIAN -DZRTP_USE_ENTERPRISE=1\r
 \r
 CFLAGS_D = $(DEFINES_D) -Zel -Zp8 -Gy -cbstring -Gz -QIfdiv- -QIf -Gi- -Gm- -GX- \\r
 -GR- -GF -Oxs -Oy -FI$(DDK)\inc\$(OS)\warning.h -W3 -FAcs -Z7\r
index 52a1cb7e4d7f433120ad99b997db28a88dbc6eef..ccc2a73a17805b835354fdb493c1ab7220ea97e1 100644 (file)
@@ -44,6 +44,9 @@ protocol = \
                ../../src/zrtp_crypto_sas.obj \\r
                ../../src/zrtp_datatypes.obj \\r
                ../../src/zrtp_engine.obj \\r
+               ../../src/enterprise/zrtp_engine_driven.obj \\r
+               ../../src/enterprise/zrtp_crypto_ec.obj  \\r
+               ../../src/enterprise/zrtp_crypto_ecdh.obj  \\r
                ../../src/zrtp_iface_sys.obj \\r
                ../../src/zrtp_initiator.obj \\r
                ../../src/zrtp_legal.obj \\r
@@ -72,14 +75,14 @@ OBJECTS  = $(bnlib) $(protocol) $(bgaes)
 \r
 # Debug\r
 \r
-OUT_DIR = debug64.km\r
+OUT_DIR = debug64_ec.km\r
 \r
 DEFINES_D = -DWIN64=1 -D_WIN64=1 -D_AMD64_=1 -D_M_AMD64 -D_WINDOWS \\r
 -DSTD_CALL -DCONDITION_HANDLING=1 \\r
 -DNT_UP=1 -DNT_INST=0 -D_NT1X_=100 \\r
 -DWINNT=1 -D_WIN32_WINNT=0x0500 -DWIN32_LEAN_AND_MEAN=1 -DDBG=1 -D_DEBUG -DDEBUG -DDEVL=1 \\r
 -DFPO=0 -D_DLL=1 -D_IDWBUILD -DRDRDBG -DSRVDBG -DDBG_MESSAGES=1 \\r
--D_UNICODE -DLITTLE_ENDIAN -DZRTP_USE_ENTERPRISE=0\r
+-D_UNICODE -DLITTLE_ENDIAN -DZRTP_USE_ENTERPRISE=1\r
 \r
 CFLAGS_D = $(DEFINES_D) -Zp8 -Gy -cbstring -Gz -Gm- -EHs-c- \\r
 -GR- -GF -FI$(DDK)\inc\$(OS)\warning.h -Z7 -Od -Oi -Oy- -W3\r
@@ -88,14 +91,14 @@ CFLAGS_D = $(DEFINES_D) -Zp8 -Gy -cbstring -Gz -Gm- -EHs-c- \
 \r
 # Release\r
 \r
-OUT_DIR = release64.km\r
+OUT_DIR = release64_ec.km\r
 \r
 DEFINES_D = -DWIN64=1 -D_WIN64=1 -D_AMD64_=1 -D_M_AMD64 -D_WINDOWS \\r
 -DSTD_CALL -DCONDITION_HANDLING=1 \\r
 -DNT_UP=1 -DNO_DISK_ACCESS -DNT_INST=0 -DWIN32=100 -D_NT1X_=100 \\r
 -DWINNT=1 -D_WIN32_WINNT=0x0500 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 \\r
 -DFPO=1 -DNDEBUG -D_DLL=1 -D_IDWBUILD -D_UNICODE \\r
--DLITTLE_ENDIAN  -DZRTP_USE_ENTERPRISE=0\r
+-DLITTLE_ENDIAN -DZRTP_USE_ENTERPRISE=1\r
 \r
 CFLAGS_D = $(DEFINES_D) -Zel -Zp8 -Gy -cbstring -Gz -QIfdiv- -QIf -Gi- -Gm- -GX- \\r
 -GR- -GF -Oxs -Oy -FI$(DDK)\inc\$(OS)\warning.h -W3 -FAcs -Z7\r
diff --git a/libs/libzrtp/src/zrtp_crypto_ec.c b/libs/libzrtp/src/zrtp_crypto_ec.c
new file mode 100644 (file)
index 0000000..818081c
--- /dev/null
@@ -0,0 +1,469 @@
+/*
+ * zrtp_crypto_ec.c - Elliptic Curve Low Level Crypto functions for ZRTP.
+ * NSA Suite B Elliptic Curves from NIST SP 800-56A and FIPS 186-3.
+ *
+ * Copyright (c) 2006-2009 Philip R. Zimmermann. All rights reserved.
+ * This is NOT licensed under the GPL or any other open source license.
+ * For licensing terms or other information,
+ * contact:  Philip Zimmermann <prz@mit.edu>.
+ * For more contact information, see http://philzimmermann.com
+ */
+
+#include "zrtp.h"
+
+#if (defined(ZRTP_ENABLE_EC) && (ZRTP_ENABLE_EC == 1))
+
+/* Size of extra random data to approximate a uniform distribution mod n */
+#define UNIFORMBYTES   8
+
+
+/*============================================================================*/
+/*    Bignum Shorthand Functions                                              */
+/*============================================================================*/
+
+int bnAddMod_ (struct BigNum *rslt, struct BigNum *n1, struct BigNum *mod)
+{
+       bnAdd (rslt, n1);
+       if (bnCmp (rslt, mod) >= 0) {
+               bnSub (rslt, mod);
+       }
+       return 0;
+}
+
+int bnAddQMod_ (struct BigNum *rslt, unsigned n1, struct BigNum *mod)
+{
+       bnAddQ (rslt, n1);
+       if (bnCmp (rslt, mod) >= 0) {
+               bnSub (rslt, mod);
+       }
+       return 0;
+}
+
+int bnSubMod_ (struct BigNum *rslt, struct BigNum *n1, struct BigNum *mod)
+{
+       if (bnCmp (rslt, n1) < 0) {
+               bnAdd (rslt, mod);
+       }
+       bnSub (rslt, n1);
+       return 0;
+}
+
+int bnSubQMod_ (struct BigNum *rslt, unsigned n1, struct BigNum *mod)
+{
+       if (bnCmpQ (rslt, n1) < 0) {
+               bnAdd (rslt, mod);
+       }
+       bnSubQ (rslt, n1);
+       return 0;
+}
+
+int bnMulMod_ (struct BigNum *rslt, struct BigNum *n1, struct BigNum *n2, struct BigNum *mod)
+{
+       bnMul (rslt, n1, n2);
+       bnMod (rslt, rslt, mod);
+       return 0;
+}
+
+int bnMulQMod_ (struct BigNum *rslt, struct BigNum *n1, unsigned n2, struct BigNum *mod)
+{
+       bnMulQ (rslt, n1, n2);
+       bnMod (rslt, rslt, mod);
+       return 0;
+}
+
+int bnSquareMod_ (struct BigNum *rslt, struct BigNum *n1, struct BigNum *mod)
+{
+       bnSquare (rslt, n1);
+       bnMod (rslt, rslt, mod);
+       return 0;
+}
+
+
+/*============================================================================*/
+/*    Elliptic Curve arithmetic                                               */
+/*============================================================================*/
+
+/* Add two elliptic curve points. Any of them may be the same object. */
+int zrtp_ecAdd ( struct BigNum *rsltx, struct BigNum *rslty,
+                                struct BigNum *p1x, struct BigNum *p1y,
+                                struct BigNum *p2x, struct BigNum *p2y, struct BigNum *mod)
+{
+       struct BigNum trsltx, trslty;
+       struct BigNum t1, gam;
+       struct BigNum bnzero;
+
+       bnBegin (&bnzero);
+
+       /* Check for an operand being zero */
+       if (bnCmp (p1x, &bnzero) == 0 && bnCmp (p1y, &bnzero) == 0) {
+               bnCopy (rsltx, p2x); bnCopy (rslty, p2y);
+               bnEnd (&bnzero);
+               return 0;
+       }
+       if (bnCmp (p2x, &bnzero) == 0 && bnCmp (p2y, &bnzero) == 0) {
+               bnCopy (rsltx, p1x); bnCopy (rslty, p1y);
+               bnEnd (&bnzero);
+               return 0;
+       }
+
+       /* Check if p1 == -p2 and return 0 if so */
+       if (bnCmp (p1x, p2x) == 0) {
+               struct BigNum tsum;
+               bnBegin (&tsum);
+               bnCopy (&tsum, p1x);
+               bnAddMod_ (&tsum, p2x, mod);
+               if (bnCmp (&tsum, &bnzero) == 0) {
+                       bnSetQ (rsltx, 0); bnSetQ (rslty, 0);
+                       bnEnd (&tsum);
+                       bnEnd (&bnzero);
+                       return 0;
+               }
+               bnEnd (&tsum);
+       }
+
+       bnBegin (&t1);
+       bnBegin (&gam);
+       bnBegin (&trsltx);
+       bnBegin (&trslty);
+
+       /* Check for doubling, different formula for gamma */
+       if (bnCmp (p1x, p2x) == 0 && bnCmp (p1y, p2y) == 0) {
+               bnCopy (&t1, p1y);
+               bnAddMod_ (&t1, p1y, mod);
+               bnInv (&t1, &t1, mod);
+               bnSquareMod_ (&gam, p1x, mod);
+               bnMulQMod_ (&gam, &gam, 3, mod);
+               bnSubQMod_ (&gam, 3, mod);
+               bnMulMod_ (&gam, &gam, &t1, mod);
+       } else {
+               bnCopy (&t1, p2x);
+               bnSubMod_ (&t1, p1x, mod);
+               bnInv (&t1, &t1, mod);
+               bnCopy (&gam, p2y);
+               bnSubMod_ (&gam, p1y, mod);
+               bnMulMod_ (&gam, &gam, &t1, mod);
+       }
+
+       bnSquareMod_ (&trsltx, &gam, mod);
+       bnSubMod_ (&trsltx, p1x, mod);
+       bnSubMod_ (&trsltx, p2x, mod);
+
+       bnCopy (&trslty, p1x);
+       bnSubMod_ (&trslty, &trsltx, mod);
+       bnMulMod_ (&trslty, &trslty, &gam, mod);
+       bnSubMod_ (&trslty, p1y, mod);
+
+       bnCopy (rsltx, &trsltx);
+       bnCopy (rslty, &trslty);
+
+       bnEnd (&t1);
+       bnEnd (&gam);
+       bnEnd (&trsltx);
+       bnEnd (&trslty);
+       bnEnd (&bnzero);
+
+       return 0;
+}
+
+int zrtp_ecMul ( struct BigNum *rsltx, struct BigNum *rslty, struct BigNum *mult,
+                                struct BigNum *basex, struct BigNum *basey, struct BigNum *mod)
+{
+       struct BigNum bnzero;
+       struct BigNum tbasex, tbasey;
+       struct BigNum trsltx, trslty;
+       struct BigNum tmult;
+
+       bnBegin (&bnzero);
+       bnBegin (&tbasex);
+       bnBegin (&tbasey);
+       bnBegin (&trsltx);
+       bnBegin (&trslty);
+       bnBegin (&tmult);
+
+       /* Initialize result to 0 before additions */
+       bnSetQ (&trsltx, 0);
+       bnSetQ (&trslty, 0);
+       /* Make copies of base and multiplier */
+       bnCopy (&tbasex, basex);
+       bnCopy (&tbasey, basey);
+       bnCopy (&tmult, mult);
+       while (bnCmp (&tmult, &bnzero) > 0) {
+               /* Test lsb of mult */
+               unsigned lsw = bnLSWord (&tmult);
+               if (lsw & 1) {
+                       /* Add base to result */
+                       zrtp_ecAdd (&trsltx, &trslty, &trsltx, &trslty, &tbasex, &tbasey, mod);
+               }
+               /* Double the base */
+               zrtp_ecAdd (&tbasex, &tbasey, &tbasex, &tbasey, &tbasex, &tbasey, mod);
+               /* Shift multiplier right */
+               bnRShift (&tmult, 1);
+       }
+
+       bnCopy (rsltx, &trsltx);
+       bnCopy (rslty, &trslty);
+
+       bnEnd (&bnzero);
+       bnEnd (&tbasex);
+       bnEnd (&tbasey);
+       bnEnd (&trsltx);
+       bnEnd (&trslty);
+       bnEnd (&tmult);
+       return 0;
+}
+
+
+
+/*----------------------------------------------------------------------------*/
+/* Choose a random point on the elliptic curve.                               */
+/* Provision is made to use a given point from test vectors.                  */
+/* pkx and pky are the output point, sv is output discrete log                */
+/* Input base is Gx, Gy; curve field modulus is P; curve order is n.          */
+/*----------------------------------------------------------------------------*/
+zrtp_status_t zrtp_ec_random_point(    zrtp_global_t *zrtp,
+                                                                       struct BigNum *P,
+                                                                       struct BigNum *n,
+                                                                       struct BigNum *Gx,
+                                                                       struct BigNum *Gy,                                                                      
+                                                                       struct BigNum *pkx,
+                                                                       struct BigNum *pky,
+                                                                       struct BigNum *sv,
+                                                                       uint8_t *test_sv_data,
+                                                                   size_t test_sv_data_len)
+{
+       zrtp_status_t s = zrtp_status_fail;
+       unsigned char* buffer = zrtp_sys_alloc(sizeof(zrtp_uchar1024_t));       
+       
+       if (!buffer) {
+               return zrtp_status_alloc_fail;
+       }
+       zrtp_memset(buffer, 0, sizeof(zrtp_uchar1024_t));
+       
+       do
+       {               
+               if (test_sv_data_len != 0) {
+                       /* Force certain secret value */
+                       if (bnBytes(P) != test_sv_data_len) {                   
+                               break;
+                       }
+                       zrtp_memcpy(buffer+UNIFORMBYTES, test_sv_data, test_sv_data_len);
+               } else {
+                       /* Choose random value, larger than needed so it will be uniform */
+                       if (bnBytes(P)+UNIFORMBYTES != (uint32_t)zrtp_randstr(zrtp, buffer, bnBytes(P)+UNIFORMBYTES)) {
+                               break; /* if we can't generate random string - fail initialization */
+                       }
+               }
+
+               bnInsertBigBytes(sv, (const unsigned char *)buffer, 0, bnBytes(P)+UNIFORMBYTES);
+               bnMod(sv, sv, n);
+               zrtp_ecMul(pkx, pky, sv, Gx, Gy, P);
+
+               s = zrtp_status_ok;
+       } while (0);
+
+       if (buffer) {
+               zrtp_sys_free(buffer);
+       }
+       
+       return s;
+}
+
+
+/*============================================================================*/
+/*    Curve parameters                                                        */
+/*============================================================================*/
+
+uint8_t P_256_data[] =
+{
+       0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
+       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
+
+uint8_t n_256_data[] =
+{
+       0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
+       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+       0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84,
+       0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51
+};
+
+uint8_t b_256_data[] =
+{
+       0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a, 0x93, 0xe7,
+       0xb3, 0xeb, 0xbd, 0x55, 0x76, 0x98, 0x86, 0xbc,
+       0x65, 0x1d, 0x06, 0xb0, 0xcc, 0x53, 0xb0, 0xf6,
+       0x3b, 0xce, 0x3c, 0x3e, 0x27, 0xd2, 0x60, 0x4b
+};
+
+uint8_t Gx_256_data[] =
+{
+       0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47,
+       0xf8, 0xbc, 0xe6, 0xe5, 0x63, 0xa4, 0x40, 0xf2,
+       0x77, 0x03, 0x7d, 0x81, 0x2d, 0xeb, 0x33, 0xa0,
+       0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96
+};
+
+uint8_t Gy_256_data[] =
+{
+       0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b,
+       0x8e, 0xe7, 0xeb, 0x4a, 0x7c, 0x0f, 0x9e, 0x16,
+       0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce,
+       0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5
+};
+
+
+
+uint8_t P_384_data[] =
+{
+       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
+       0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF
+};
+
+uint8_t n_384_data[] =
+{
+       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+       0xC7, 0x63, 0x4D, 0x81, 0xF4, 0x37, 0x2D, 0xDF,
+       0x58, 0x1A, 0x0D, 0xB2, 0x48, 0xB0, 0xA7, 0x7A,
+       0xEC, 0xEC, 0x19, 0x6A, 0xCC, 0xC5, 0x29, 0x73
+};
+
+uint8_t b_384_data[] =
+{
+       0xb3, 0x31, 0x2f, 0xa7, 0xe2, 0x3e, 0xe7, 0xe4,
+       0x98, 0x8e, 0x05, 0x6b, 0xe3, 0xf8, 0x2d, 0x19,
+       0x18, 0x1d, 0x9c, 0x6e, 0xfe, 0x81, 0x41, 0x12,
+       0x03, 0x14, 0x08, 0x8f, 0x50, 0x13, 0x87, 0x5a,
+       0xc6, 0x56, 0x39, 0x8d, 0x8a, 0x2e, 0xd1, 0x9d,
+       0x2a, 0x85, 0xc8, 0xed, 0xd3, 0xec, 0x2a, 0xef
+};
+
+uint8_t Gx_384_data[] =
+{
+       0xaa, 0x87, 0xca, 0x22, 0xbe, 0x8b, 0x05, 0x37,
+       0x8e, 0xb1, 0xc7, 0x1e, 0xf3, 0x20, 0xad, 0x74,
+       0x6e, 0x1d, 0x3b, 0x62, 0x8b, 0xa7, 0x9b, 0x98,
+       0x59, 0xf7, 0x41, 0xe0, 0x82, 0x54, 0x2a, 0x38,
+       0x55, 0x02, 0xf2, 0x5d, 0xbf, 0x55, 0x29, 0x6c,
+       0x3a, 0x54, 0x5e, 0x38, 0x72, 0x76, 0x0a, 0xb7
+};
+
+uint8_t Gy_384_data[] =
+{
+       0x36, 0x17, 0xde, 0x4a, 0x96, 0x26, 0x2c, 0x6f,
+       0x5d, 0x9e, 0x98, 0xbf, 0x92, 0x92, 0xdc, 0x29,
+       0xf8, 0xf4, 0x1d, 0xbd, 0x28, 0x9a, 0x14, 0x7c,
+       0xe9, 0xda, 0x31, 0x13, 0xb5, 0xf0, 0xb8, 0xc0,
+       0x0a, 0x60, 0xb1, 0xce, 0x1d, 0x7e, 0x81, 0x9d,
+       0x7a, 0x43, 0x1d, 0x7c, 0x90, 0xea, 0x0e, 0x5f
+};
+
+
+uint8_t P_521_data[] =
+{
+       0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+       0xFF, 0xFF
+};
+
+uint8_t n_521_data[] =
+{
+       0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+       0xFF, 0xFA, 0x51, 0x86, 0x87, 0x83, 0xBF, 0x2F,
+       0x96, 0x6B, 0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09,
+       0xA5, 0xD0, 0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C,
+       0x47, 0xAE, 0xBB, 0x6F, 0xB7, 0x1E, 0x91, 0x38,
+       0x64, 0x09
+};
+
+uint8_t b_521_data[] =
+{
+       0x00, 0x51, 0x95, 0x3e, 0xb9, 0x61, 0x8e, 0x1c,
+       0x9a, 0x1f, 0x92, 0x9a, 0x21, 0xa0, 0xb6, 0x85,
+       0x40, 0xee, 0xa2, 0xda, 0x72, 0x5b, 0x99, 0xb3,
+       0x15, 0xf3, 0xb8, 0xb4, 0x89, 0x91, 0x8e, 0xf1,
+       0x09, 0xe1, 0x56, 0x19, 0x39, 0x51, 0xec, 0x7e,
+       0x93, 0x7b, 0x16, 0x52, 0xc0, 0xbd, 0x3b, 0xb1,
+       0xbf, 0x07, 0x35, 0x73, 0xdf, 0x88, 0x3d, 0x2c,
+       0x34, 0xf1, 0xef, 0x45, 0x1f, 0xd4, 0x6b, 0x50,
+       0x3f, 0x00
+};
+
+uint8_t Gx_521_data[] =
+{
+       0x00, 0xc6, 0x85, 0x8e, 0x06, 0xb7, 0x04, 0x04,
+       0xe9, 0xcd, 0x9e, 0x3e, 0xcb, 0x66, 0x23, 0x95,
+       0xb4, 0x42, 0x9c, 0x64, 0x81, 0x39, 0x05, 0x3f,
+       0xb5, 0x21, 0xf8, 0x28, 0xaf, 0x60, 0x6b, 0x4d,
+       0x3d, 0xba, 0xa1, 0x4b, 0x5e, 0x77, 0xef, 0xe7,
+       0x59, 0x28, 0xfe, 0x1d, 0xc1, 0x27, 0xa2, 0xff,
+       0xa8, 0xde, 0x33, 0x48, 0xb3, 0xc1, 0x85, 0x6a,
+       0x42, 0x9b, 0xf9, 0x7e, 0x7e, 0x31, 0xc2, 0xe5,
+       0xbd, 0x66
+};
+
+uint8_t Gy_521_data[] =
+{
+       0x01, 0x18, 0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b,
+       0xc0, 0x04, 0x5c, 0x8a, 0x5f, 0xb4, 0x2c, 0x7d,
+       0x1b, 0xd9, 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b,
+       0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17, 0x27, 0x3e,
+       0x66, 0x2c, 0x97, 0xee, 0x72, 0x99, 0x5e, 0xf4,
+       0x26, 0x40, 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad,
+       0x07, 0x61, 0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72,
+       0xc2, 0x40, 0x88, 0xbe, 0x94, 0x76, 0x9f, 0xd1,
+       0x66, 0x50
+};
+
+/*----------------------------------------------------------------------------*/
+/* Initialize the curve parameters struct                                     */
+zrtp_status_t zrtp_ec_init_params( struct zrtp_ec_params *params, uint32_t bits )
+{
+    unsigned ec_bytes = (bits+7) / 8;
+       params->ec_bits = bits;
+       switch (bits) {
+       case 256:
+               zrtp_memcpy (params->P_data, P_256_data, ec_bytes);
+               zrtp_memcpy (params->n_data, n_256_data, ec_bytes);
+               zrtp_memcpy (params->b_data, b_256_data, ec_bytes);
+               zrtp_memcpy (params->Gx_data, Gx_256_data, ec_bytes);
+               zrtp_memcpy (params->Gy_data, Gy_256_data, ec_bytes);
+               break;
+       case 384:
+               zrtp_memcpy (params->P_data, P_384_data, ec_bytes);
+               zrtp_memcpy (params->n_data, n_384_data, ec_bytes);
+               zrtp_memcpy (params->b_data, b_384_data, ec_bytes);
+               zrtp_memcpy (params->Gx_data, Gx_384_data, ec_bytes);
+               zrtp_memcpy (params->Gy_data, Gy_384_data, ec_bytes);
+               break;
+       case 521:
+               zrtp_memcpy (params->P_data, P_521_data, ec_bytes);
+               zrtp_memcpy (params->n_data, n_521_data, ec_bytes);
+               zrtp_memcpy (params->b_data, b_521_data, ec_bytes);
+               zrtp_memcpy (params->Gx_data, Gx_521_data, ec_bytes);
+               zrtp_memcpy (params->Gy_data, Gy_521_data, ec_bytes);
+               break;
+       default:
+               return zrtp_status_bad_param;
+       }
+       
+       return zrtp_status_ok;
+}
+
+#endif /*ZRTP_ENABLE_EC*/
diff --git a/libs/libzrtp/src/zrtp_crypto_ecdh.c b/libs/libzrtp/src/zrtp_crypto_ecdh.c
new file mode 100644 (file)
index 0000000..b78ecb1
--- /dev/null
@@ -0,0 +1,567 @@
+/*
+ * zrtp_crypto_ecdh.c - Elliptic Curve Diffie Hellman functions for ZRTP.
+ * NSA Suite B Elliptic Curves from NIST SP 800-56A and FIPS 186-3.
+ *
+ * Copyright (c) 2006-2009 Philip R. Zimmermann. All rights reserved.
+ * This is NOT licensed under the GPL or any other open source license.
+ * For licensing terms or other information,
+ * contact:  Philip Zimmermann <prz@mit.edu>.
+ * For more contact information, see http://philzimmermann.com
+ */
+
+#include "zrtp.h"
+
+
+#if (defined(ZRTP_ENABLE_EC) && (ZRTP_ENABLE_EC == 1))
+
+#define _ZTU_ "zrtp ecdh"
+
+static unsigned get_pbits(zrtp_pk_scheme_t *self)
+{
+       switch (self->base.id) {
+               case ZRTP_PKTYPE_EC256P:
+                       return 256;
+                       break;
+               case ZRTP_PKTYPE_EC384P:
+                       return 384;
+                       break;
+               case ZRTP_PKTYPE_EC521P:
+                       return 521;
+                       break;
+               default:
+                       return 0;
+       }
+}
+
+/*============================================================================*/
+/*    Shared Elliptic Curve functions                                         */
+/*                                                                            */
+/*    The Elliptic Curve DH algorithm and key generation is from              */
+/*    NIST SP 800-56A.  The curves used are from NSA Suite B, which           */
+/*    uses the same curves as ECDSA defined by FIPS 186-3, and are            */
+/*    also defined in RFC 4753, sections 3.1 through 3.3.                     */
+/*    The validation procedures are from NIST SP 800-56A section 5.6.2.6,     */
+/*    method 3, ECC Partial Validation.                                       */
+/*============================================================================*/
+
+
+/*----------------------------------------------------------------------------*/
+static zrtp_status_t zrtp_ecdh_init(void *s) {
+    return zrtp_status_ok;
+}
+
+static zrtp_status_t zrtp_ecdh_free(void *s) {
+    return zrtp_status_ok;
+}
+
+
+/*----------------------------------------------------------------------------*/
+/* Return dh_cc->pv holding public value and dh_cc->sv holding secret value   */
+/* The public value is an elliptic curve point encoded as the x part shifted  */
+/* left Pbits bits and or'd with the y part.                                  */
+/*----------------------------------------------------------------------------*/
+static zrtp_status_t zrtp_ecdh_initialize( zrtp_pk_scheme_t *self,
+                                                                                  zrtp_dh_crypto_context_t *dh_cc)
+{
+       zrtp_status_t s = zrtp_status_fail;
+       struct BigNum P, Gx, Gy, n;
+       struct BigNum pkx, pky; 
+       unsigned ec_bytes = 0;
+       unsigned pbits = 0;
+       struct zrtp_ec_params ec_params;
+       zrtp_time_t start_ts = zrtp_time_now();
+       
+       if (!self || !dh_cc) {
+               return zrtp_status_bad_param;
+       }
+       
+       pbits = get_pbits(self);
+       if (!pbits) {
+               return zrtp_status_bad_param;
+       }
+       
+       zrtp_ec_init_params(&ec_params, pbits);
+       
+       ec_bytes = (ec_params.ec_bits+7) / 8;
+
+       bnBegin(&P);
+       bnInsertBigBytes(&P, ec_params.P_data, 0, ec_bytes );
+       bnBegin(&Gx);
+       bnInsertBigBytes(&Gx, ec_params.Gx_data, 0, ec_bytes );
+       bnBegin(&Gy);
+       bnInsertBigBytes(&Gy, ec_params.Gy_data, 0, ec_bytes );
+       bnBegin(&n);
+       bnInsertBigBytes(&n, ec_params.n_data, 0, ec_bytes );
+
+       bnBegin(&pkx);
+       bnBegin(&pky);
+       bnBegin(&dh_cc->sv);
+       s = zrtp_ec_random_point( self->base.zrtp, &P, &n, &Gx, &Gy,
+                                                         &pkx, &pky, &dh_cc->sv,
+                                                         NULL, 0);
+               
+       if (zrtp_status_ok == s)
+       {
+               bnBegin(&dh_cc->pv);
+               bnCopy (&dh_cc->pv, &pkx);
+               bnLShift (&dh_cc->pv, pbits);
+               bnAdd (&dh_cc->pv, &pky);
+       }
+               
+       bnEnd (&pkx);
+       bnEnd (&pky);
+       bnEnd (&P);
+       bnEnd (&Gx);
+       bnEnd (&Gy);
+       bnEnd (&n);
+       
+       ZRTP_LOG(1,(_ZTU_,"\tDH TEST: zrtp_ecdh_initialize() for %.4s was executed by %llums.\n", self->base.type, zrtp_time_now()-start_ts));
+       return s;
+}
+
+
+/*----------------------------------------------------------------------------*/
+/* Compute the shared dhresult as the X coordinate of the EC point.           */
+/*----------------------------------------------------------------------------*/
+static zrtp_status_t zrtp_ecdh_compute( zrtp_pk_scheme_t *self,
+                                                                               zrtp_dh_crypto_context_t *dh_cc,                                                                                
+                                                                               struct BigNum *dhresult,
+                                                                               struct BigNum *pv)
+{
+       struct BigNum P;
+       struct BigNum pkx, pky, rsltx, rslty;
+       unsigned ec_bytes = 0;
+       unsigned pbits = 0;
+       struct zrtp_ec_params ec_params;
+       zrtp_time_t start_ts = zrtp_time_now();
+       
+       if (!self || !dh_cc || !dhresult || !pv) {
+               return zrtp_status_bad_param;
+       }
+       
+       pbits = get_pbits(self);
+       if (!pbits) {
+               return zrtp_status_bad_param;
+       }
+       
+       zrtp_ec_init_params(&ec_params, pbits);
+       
+       ec_bytes = (ec_params.ec_bits+7) / 8;
+       
+    bnBegin(&P);
+    bnInsertBigBytes( &P, ec_params.P_data, 0, ec_bytes );
+
+       bnBegin (&pkx);
+       bnBegin (&pky);
+       bnBegin (&rsltx);
+       bnBegin (&rslty);
+
+       bnSetQ (&pkx, 1);
+       bnLShift (&pkx, pbits);
+       bnMod (&pky, pv, &pkx);
+       bnCopy (&pkx, pv);
+       bnRShift (&pkx, pbits);
+
+       zrtp_ecMul (&rsltx, &rslty, &dh_cc->sv, &pkx, &pky, &P);
+       bnCopy (dhresult, &rsltx);
+
+       bnEnd (&pkx);
+       bnEnd (&pky);
+       bnEnd (&rsltx);
+       bnEnd (&rslty);
+       bnEnd (&P);
+    
+       ZRTP_LOG(1,(_ZTU_,"\tDH TEST: zrtp_ecdh_compute() for %.4s was executed by %llums.\n", self->base.type, zrtp_time_now()-start_ts));
+    return zrtp_status_ok;
+}
+
+/*----------------------------------------------------------------------------*/
+/* ECC Partial Validation per NIST SP800-56A section 5.6.2.6                  */
+/*----------------------------------------------------------------------------*/
+static zrtp_status_t zrtp_ecdh_validate( zrtp_pk_scheme_t *self,
+                                                                                struct BigNum *pv)
+{
+       zrtp_status_t s = zrtp_status_fail;
+       struct BigNum P, b;
+       struct BigNum t1, t2;
+       struct BigNum pkx, pky, bnzero;
+       unsigned ec_bytes = 0;
+       unsigned pbits = 0;
+       struct zrtp_ec_params ec_params;
+       zrtp_time_t start_ts = zrtp_time_now();
+       
+       if (!self || !pv) {
+               return zrtp_status_bad_param;
+       }
+       
+       pbits = get_pbits(self);
+       if (!pbits) {
+               return zrtp_status_bad_param;
+       }
+       
+       zrtp_ec_init_params(&ec_params, pbits);
+       
+       ec_bytes = (ec_params.ec_bits+7) / 8;
+
+    bnBegin(&P);
+    bnInsertBigBytes( &P, ec_params.P_data, 0, ec_bytes );
+    bnBegin(&b);
+    bnInsertBigBytes( &b, ec_params.b_data, 0, ec_bytes );
+
+       bnBegin (&t1);
+       bnBegin (&t2);
+       bnBegin (&pkx);
+       bnBegin (&pky);
+       bnBegin (&bnzero);
+
+       bnSetQ (&pkx, 1);
+       bnLShift (&pkx, pbits);
+       bnMod (&pky, pv, &pkx);
+       bnCopy (&pkx, pv);
+       bnRShift (&pkx, pbits);
+
+       do{
+       /* Represent point at infinity by (0, 0), make sure it's not that */
+               if (bnCmp (&pkx, &bnzero) == 0 && bnCmp (&pky, &bnzero) == 0) {
+                       break;
+               }
+       /* Check coordinates within range */
+               if (bnCmp (&pkx, &bnzero) < 0 || bnCmp (&pkx, &P) >= 0) {
+                       break;
+               }
+               if (bnCmp (&pky, &bnzero) < 0 || bnCmp (&pky, &P) >= 0) {
+                       break;
+               }
+
+               /* Check that point satisfies EC equation y^2 = x^3 - 3x + b, mod P */
+               bnSquareMod_ (&t1, &pky, &P);
+               bnSquareMod_ (&t2, &pkx, &P);
+               bnSubQMod_ (&t2, 3, &P);
+               bnMulMod_ (&t2, &t2, &pkx, &P);
+               bnAddMod_ (&t2, &b, &P);
+               if (bnCmp (&t1, &t2) != 0) {
+                       break;
+               }
+               
+               s = zrtp_status_ok;
+       } while (0);
+
+       bnEnd (&t1);
+       bnEnd (&t2);
+       bnEnd (&pkx);
+       bnEnd (&pky);
+       bnEnd (&bnzero);
+       bnEnd (&P);
+       bnEnd (&b);
+       
+       ZRTP_LOG(1,(_ZTU_,"\tDH TEST: zrtp_ecdh_validate() for %.4s was executed by %llums.\n", self->base.type, zrtp_time_now()-start_ts));
+    return s;
+}
+
+
+/*============================================================================*/
+/*    P-256, 384, 521 (FIPS 186-3) support.  See RFC 4753 3.1, 3.2, 3.3                  */
+/*============================================================================*/
+
+static uint8_t sv256_data[] = {
+       0x81, 0x42, 0x64, 0x14, 0x5F, 0x2F, 0x56, 0xF2,
+       0xE9, 0x6A, 0x8E, 0x33, 0x7A, 0x12, 0x84, 0x99,
+       0x3F, 0xAF, 0x43, 0x2A, 0x5A, 0xBC, 0xE5, 0x9E,
+       0x86, 0x7B, 0x72, 0x91, 0xD5, 0x07, 0xA3, 0xAF
+};
+static uint8_t pvx256_data[] = {
+       0x2A, 0xF5, 0x02, 0xF3, 0xBE, 0x89, 0x52, 0xF2,
+       0xC9, 0xB5, 0xA8, 0xD4, 0x16, 0x0D, 0x09, 0xE9,
+       0x71, 0x65, 0xBE, 0x50, 0xBC, 0x42, 0xAE, 0x4A,
+       0x5E, 0x8D, 0x3B, 0x4B, 0xA8, 0x3A, 0xEB, 0x15
+};
+static uint8_t pvy256_data[] = {
+       0xEB, 0x0F, 0xAF, 0x4C, 0xA9, 0x86, 0xC4, 0xD3,
+       0x86, 0x81, 0xA0, 0xF9, 0x87, 0x2D, 0x79, 0xD5,
+       0x67, 0x95, 0xBD, 0x4B, 0xFF, 0x6E, 0x6D, 0xE3,
+       0xC0, 0xF5, 0x01, 0x5E, 0xCE, 0x5E, 0xFD, 0x85
+};
+
+static uint8_t sv384_data[] = {
+       0xD2, 0x73, 0x35, 0xEA, 0x71, 0x66, 0x4A, 0xF2,
+       0x44, 0xDD, 0x14, 0xE9, 0xFD, 0x12, 0x60, 0x71,
+       0x5D, 0xFD, 0x8A, 0x79, 0x65, 0x57, 0x1C, 0x48,
+       0xD7, 0x09, 0xEE, 0x7A, 0x79, 0x62, 0xA1, 0x56,
+       0xD7, 0x06, 0xA9, 0x0C, 0xBC, 0xB5, 0xDF, 0x29,
+       0x86, 0xF0, 0x5F, 0xEA, 0xDB, 0x93, 0x76, 0xF1
+};
+static uint8_t pvx384_data[] = {
+       0x79, 0x31, 0x48, 0xF1, 0x78, 0x76, 0x34, 0xD5,
+       0xDA, 0x4C, 0x6D, 0x90, 0x74, 0x41, 0x7D, 0x05,
+       0xE0, 0x57, 0xAB, 0x62, 0xF8, 0x20, 0x54, 0xD1,
+       0x0E, 0xE6, 0xB0, 0x40, 0x3D, 0x62, 0x79, 0x54,
+       0x7E, 0x6A, 0x8E, 0xA9, 0xD1, 0xFD, 0x77, 0x42,
+       0x7D, 0x01, 0x6F, 0xE2, 0x7A, 0x8B, 0x8C, 0x66
+};
+static uint8_t pvy384_data[] = {
+       0xC6, 0xC4, 0x12, 0x94, 0x33, 0x1D, 0x23, 0xE6,
+       0xF4, 0x80, 0xF4, 0xFB, 0x4C, 0xD4, 0x05, 0x04,
+       0xC9, 0x47, 0x39, 0x2E, 0x94, 0xF4, 0xC3, 0xF0,
+       0x6B, 0x8F, 0x39, 0x8B, 0xB2, 0x9E, 0x42, 0x36,
+       0x8F, 0x7A, 0x68, 0x59, 0x23, 0xDE, 0x3B, 0x67,
+       0xBA, 0xCE, 0xD2, 0x14, 0xA1, 0xA1, 0xD1, 0x28
+};
+
+static uint8_t sv521_data[] = {
+       0x01, 0x13, 0xF8, 0x2D, 0xA8, 0x25, 0x73, 0x5E,
+       0x3D, 0x97, 0x27, 0x66, 0x83, 0xB2, 0xB7, 0x42,
+       0x77, 0xBA, 0xD2, 0x73, 0x35, 0xEA, 0x71, 0x66,
+       0x4A, 0xF2, 0x43, 0x0C, 0xC4, 0xF3, 0x34, 0x59,
+       0xB9, 0x66, 0x9E, 0xE7, 0x8B, 0x3F, 0xFB, 0x9B,
+       0x86, 0x83, 0x01, 0x5D, 0x34, 0x4D, 0xCB, 0xFE,
+       0xF6, 0xFB, 0x9A, 0xF4, 0xC6, 0xC4, 0x70, 0xBE,
+       0x25, 0x45, 0x16, 0xCD, 0x3C, 0x1A, 0x1F, 0xB4,
+       0x73, 0x62
+};
+static uint8_t pvx521_data[] = {
+       0x01, 0xEB, 0xB3, 0x4D, 0xD7, 0x57, 0x21, 0xAB,
+       0xF8, 0xAD, 0xC9, 0xDB, 0xED, 0x17, 0x88, 0x9C,
+       0xBB, 0x97, 0x65, 0xD9, 0x0A, 0x7C, 0x60, 0xF2,
+       0xCE, 0xF0, 0x07, 0xBB, 0x0F, 0x2B, 0x26, 0xE1,
+       0x48, 0x81, 0xFD, 0x44, 0x42, 0xE6, 0x89, 0xD6,
+       0x1C, 0xB2, 0xDD, 0x04, 0x6E, 0xE3, 0x0E, 0x3F,
+       0xFD, 0x20, 0xF9, 0xA4, 0x5B, 0xBD, 0xF6, 0x41,
+       0x3D, 0x58, 0x3A, 0x2D, 0xBF, 0x59, 0x92, 0x4F,
+       0xD3, 0x5C
+};
+static uint8_t pvy521_data[] = {
+       0x00, 0xF6, 0xB6, 0x32, 0xD1, 0x94, 0xC0, 0x38,
+       0x8E, 0x22, 0xD8, 0x43, 0x7E, 0x55, 0x8C, 0x55,
+       0x2A, 0xE1, 0x95, 0xAD, 0xFD, 0x15, 0x3F, 0x92,
+       0xD7, 0x49, 0x08, 0x35, 0x1B, 0x2F, 0x8C, 0x4E,
+       0xDA, 0x94, 0xED, 0xB0, 0x91, 0x6D, 0x1B, 0x53,
+       0xC0, 0x20, 0xB5, 0xEE, 0xCA, 0xED, 0x1A, 0x5F,
+       0xC3, 0x8A, 0x23, 0x3E, 0x48, 0x30, 0x58, 0x7B,
+       0xB2, 0xEE, 0x34, 0x89, 0xB3, 0xB4, 0x2A, 0x5A,
+       0x86, 0xA4
+};
+
+zrtp_status_t zrtp_ecdh_selftest(zrtp_pk_scheme_t *self)
+{
+       zrtp_status_t s = zrtp_status_fail;
+       struct BigNum P, Gx, Gy, n, sv;
+       struct BigNum pkx, pky; 
+       unsigned ec_bytes = 0;
+       unsigned pbits = 0;
+       struct zrtp_ec_params ec_params;
+       
+       zrtp_time_t start_ts = 0;
+       
+       uint8_t *sv_data        = NULL;
+       size_t sv_data_len      = 0;
+       uint8_t *pvx_data       = NULL;
+       size_t pvx_data_len = 0;
+       uint8_t *pvy_data       = NULL;
+       size_t pvy_data_len = 0;
+       
+       if (!self) {
+               return zrtp_status_bad_param;
+       }
+       
+       ZRTP_LOG(3, (_ZTU_, "PKS %.4s testing... ", self->base.type));
+       
+       switch (self->base.id) {
+               case ZRTP_PKTYPE_EC256P:
+                       sv_data                 = sv256_data;
+                       sv_data_len             = sizeof(sv256_data);
+                       pvx_data                = pvx256_data;
+                       pvx_data_len    = sizeof(pvx256_data);
+                       pvy_data                = pvy256_data;
+                       pvy_data_len    = sizeof(pvy256_data);
+                       break;
+               case ZRTP_PKTYPE_EC384P:
+                       sv_data                 = sv384_data;
+                       sv_data_len             = sizeof(sv384_data);
+                       pvx_data                = pvx384_data;
+                       pvx_data_len    = sizeof(pvx384_data);
+                       pvy_data                = pvy384_data;
+                       pvy_data_len    = sizeof(pvy384_data);
+                       break;
+               case ZRTP_PKTYPE_EC521P:
+                       sv_data                 = sv521_data;
+                       sv_data_len             = sizeof(sv521_data);
+                       pvx_data                = pvx521_data;
+                       pvx_data_len    = sizeof(pvx521_data);
+                       pvy_data                = pvy521_data;
+                       pvy_data_len    = sizeof(pvy521_data);
+                       break;
+               default:
+                       return 0;
+       }               
+       
+       pbits = get_pbits(self);
+       if (!pbits) {
+               return zrtp_status_bad_param;
+       }
+       
+       zrtp_ec_init_params(&ec_params, pbits);
+       
+       ec_bytes = (ec_params.ec_bits+7) / 8;
+       
+       bnBegin(&P);
+       bnInsertBigBytes(&P, ec_params.P_data, 0, ec_bytes );
+       bnBegin(&Gx);
+       bnInsertBigBytes(&Gx, ec_params.Gx_data, 0, ec_bytes );
+       bnBegin(&Gy);
+       bnInsertBigBytes(&Gy, ec_params.Gy_data, 0, ec_bytes );
+       bnBegin(&n);
+       bnInsertBigBytes(&n, ec_params.n_data, 0, ec_bytes );
+       
+       bnBegin(&pkx);
+       bnBegin(&pky);
+       bnBegin(&sv);
+       s = zrtp_ec_random_point( self->base.zrtp, &P, &n, &Gx, &Gy,
+                                                         &pkx, &pky, &sv,
+                                                         sv_data, sv_data_len);
+       if (zrtp_status_ok == s)
+       {
+               struct BigNum pkx1, pky1;
+               
+               bnBegin(&pkx1); bnBegin(&pky1);
+               bnInsertBigBytes(&pkx1, pvx_data, 0, pvx_data_len);
+               bnInsertBigBytes(&pky1, pvy_data, 0, pvy_data_len);
+               s = (bnCmp (&pkx1, &pkx) == 0 && bnCmp (&pky1, &pky) == 0) ? zrtp_status_ok : zrtp_status_fail;
+               bnEnd(&pkx1);
+               bnEnd(&pky1);   
+       }
+       
+       bnEnd (&pkx);
+       bnEnd (&pky);
+       bnEnd (&P);
+       bnEnd (&Gx);
+       bnEnd (&Gy);
+       bnEnd (&n);
+       bnEnd (&sv);
+       
+       if (zrtp_status_ok == s) {
+       zrtp_status_t s = zrtp_status_ok;
+       zrtp_dh_crypto_context_t alice_cc;
+       zrtp_dh_crypto_context_t bob_cc;
+       struct BigNum alice_k;
+       struct BigNum bob_k;
+       
+       start_ts = zrtp_time_now();
+       
+       bnBegin(&alice_k);
+       bnBegin(&bob_k);
+       
+       do {    
+               /* Both sides initalise DH schemes and compute secret and public values. */
+               s = self->initialize(self, &alice_cc);
+               if (zrtp_status_ok != s) {
+                       break;
+               }
+               s = self->initialize(self, &bob_cc);
+               if (zrtp_status_ok != s) {
+                       break;
+               }
+               
+               /* Both sides validate public values. (to provide exact performance estimation) */
+               s = self->validate(self, &bob_cc.pv);
+               if (zrtp_status_ok != s) {
+                       break;
+               }
+               s = self->validate(self, &alice_cc.pv);
+               if (zrtp_status_ok != s) {
+                       break;
+               }
+               
+               /* Compute secret keys and compare them. */
+               s = self->compute(self, &alice_cc, &alice_k, &bob_cc.pv);
+               if (zrtp_status_ok != s) {
+                       break;
+               }
+               s= self->compute(self, &bob_cc, &bob_k, &alice_cc.pv);
+               if (zrtp_status_ok != s) {
+                       break;
+               }
+                               
+               s = (0 == bnCmp(&alice_k, &bob_k)) ? zrtp_status_ok : zrtp_status_algo_fail;
+       } while (0);
+
+       bnEnd(&alice_k);
+       bnEnd(&bob_k);
+       }
+       ZRTP_LOGC(3, ("%s (%llu ms)\n", zrtp_log_status2str(s), (zrtp_time_now()-start_ts)/2)); 
+       
+       return s;
+}
+
+
+/*============================================================================*/
+/*    Public Key support                                                                                                         */
+/*============================================================================*/
+
+/*----------------------------------------------------------------------------*/
+zrtp_status_t zrtp_defaults_ec_pkt(zrtp_global_t* zrtp)
+{
+    zrtp_pk_scheme_t* ec256p = zrtp_sys_alloc(sizeof(zrtp_pk_scheme_t));
+    zrtp_pk_scheme_t* ec384p = zrtp_sys_alloc(sizeof(zrtp_pk_scheme_t));
+    zrtp_pk_scheme_t* ec521p = zrtp_sys_alloc(sizeof(zrtp_pk_scheme_t));
+    
+       if (!ec256p || !ec384p || !ec521p) {
+               if(ec256p) {
+                       zrtp_sys_free(ec256p);
+               }
+               if(ec384p) {
+                       zrtp_sys_free(ec384p);
+               }
+               if(ec521p) {
+                       zrtp_sys_free(ec521p);
+               }
+               return zrtp_status_alloc_fail;
+       }
+
+    zrtp_memset(ec256p, 0, sizeof(zrtp_pk_scheme_t));
+    zrtp_memcpy(ec256p->base.type, ZRTP_EC256P, ZRTP_COMP_TYPE_SIZE);
+       ec256p->base.id         = ZRTP_PKTYPE_EC256P;
+    ec256p->base.zrtp  = zrtp;
+    ec256p->sv_length  = 256/8;
+    ec256p->pv_length  = 2*256/8;
+    ec256p->base.init  = zrtp_ecdh_init;
+    ec256p->base.free  = zrtp_ecdh_free;
+    ec256p->initialize = zrtp_ecdh_initialize;
+    ec256p->compute            = zrtp_ecdh_compute;
+    ec256p->validate   = zrtp_ecdh_validate;
+       ec256p->self_test       = zrtp_ecdh_selftest;
+
+    zrtp_memset(ec384p, 0, sizeof(zrtp_pk_scheme_t));
+    zrtp_memcpy(ec384p->base.type, ZRTP_EC384P, ZRTP_COMP_TYPE_SIZE);
+       ec384p->base.id         = ZRTP_PKTYPE_EC384P;
+    ec384p->base.zrtp  = zrtp;
+    ec384p->sv_length  = 384/8;
+    ec384p->pv_length  = 2*384/8;
+    ec384p->base.init  = zrtp_ecdh_init;
+    ec384p->base.free  = zrtp_ecdh_free;
+    ec384p->initialize = zrtp_ecdh_initialize;
+    ec384p->compute            = zrtp_ecdh_compute;
+    ec384p->validate   = zrtp_ecdh_validate;
+       ec384p->self_test       = zrtp_ecdh_selftest;
+       
+
+    zrtp_memset(ec521p, 0, sizeof(zrtp_pk_scheme_t));
+    zrtp_memcpy(ec521p->base.type, ZRTP_EC521P, ZRTP_COMP_TYPE_SIZE);
+       ec521p->base.id         = ZRTP_PKTYPE_EC521P;
+    ec521p->base.zrtp  = zrtp;
+    ec521p->sv_length  = 528/8;
+    ec521p->pv_length  = 2*528/8;
+    ec521p->base.init  = zrtp_ecdh_init;
+    ec521p->base.free  = zrtp_ecdh_free;
+    ec521p->initialize = zrtp_ecdh_initialize;
+    ec521p->compute            = zrtp_ecdh_compute;
+    ec521p->validate   = zrtp_ecdh_validate;
+       ec521p->self_test       = zrtp_ecdh_selftest;
+
+    zrtp_comp_register(ZRTP_CC_PKT, ec256p, zrtp);
+    zrtp_comp_register(ZRTP_CC_PKT, ec384p, zrtp);
+    zrtp_comp_register(ZRTP_CC_PKT, ec521p, zrtp);
+
+    return zrtp_status_ok;
+}
+
+#endif /*ZRTP_ENABLE_EC*/
diff --git a/libs/libzrtp/src/zrtp_crypto_ecdsa.c b/libs/libzrtp/src/zrtp_crypto_ecdsa.c
new file mode 100644 (file)
index 0000000..679f125
--- /dev/null
@@ -0,0 +1,646 @@
+/*
+ * zrtp_crypto_ecdsa.c - Elliptic Curve Digital Signature functions for ZRTP.
+ * NSA Suite B Elliptic Curves from NIST SP 800-56A and FIPS 186-3.
+ *
+ * Copyright (c) 2006-2009 Philip R. Zimmermann. All rights reserved.
+ * This is NOT licensed under the GPL or any other open source license.
+ * For licensing terms or other information,
+ * contact:  Philip Zimmermann <prz@mit.edu>.
+ * For more contact information, see http://philzimmermann.com
+ */
+
+#include "zrtp.h"
+
+/* We don't have digital signatures ready yet. */
+#if 0
+
+/* Size of extra random data to approximate a uniform distribution mod n */
+#define UNIFORMBYTES   8
+
+/*============================================================================*/
+/*    Shared Elliptic Curve functions                                         */
+/*                                                                            */
+/*    The Elliptic Curve DSA algorithm, key generation, and curves are        */
+/*    from FIPS 186-3.  The curves used are                                   */
+/*    also defined in RFC 4753, sections 3.1 through 3.3.                     */
+/*============================================================================*/
+
+/*----------------------------------------------------------------------------*/
+/* Return dsa_cc->pv holding public value and dsa_cc->sv holding secret value */
+/* The public value is an elliptic curve point encoded as the x part shifted  */
+/* left Pbits bits and or'd with the y part.                                  */
+/*----------------------------------------------------------------------------*/
+static zrtp_status_t ECDSA_keygen( struct zrtp_sig_scheme *self,
+                                                                       zrtp_dsa_crypto_context_t *dsa_cc,
+                                                                       zrtp_ec_params_t *ec_params,
+#ifdef ZRTP_TEST_VECTORS
+                                                                       uint8_t *sv_data, size_t sv_data_len,
+                                                                       uint8_t *pvx_data, size_t pvx_data_len,
+                                                                       uint8_t *pvy_data, size_t pvy_data_len,
+#endif
+                                                                       unsigned Pbits )
+{
+       zrtp_status_t s = zrtp_status_fail;
+       struct BigNum P, Gx, Gy, n;
+       struct BigNum pkx, pky;
+       unsigned ec_bytes;
+
+       if (!ec_params)
+               return zrtp_status_bad_param;
+
+       ec_bytes = (ec_params->ec_bits+7) / 8;
+
+       do
+       {
+       if (!self || !dsa_cc)
+       {
+               s = zrtp_status_bad_param;
+               break;
+       }
+
+    bnBegin(&P);
+    bnInsertBigBytes( &P, ec_params->P_data, 0, ec_bytes );
+    bnBegin(&Gx);
+    bnInsertBigBytes( &Gx, ec_params->Gx_data, 0, ec_bytes );
+    bnBegin(&Gy);
+    bnInsertBigBytes( &Gy, ec_params->Gy_data, 0, ec_bytes );
+    bnBegin(&n);
+    bnInsertBigBytes( &n, ec_params->n_data, 0, ec_bytes );
+
+       bnBegin(&pkx);
+       bnBegin(&pky);
+       bnBegin(&dsa_cc->sv);
+       s = zrtp_ec_random_point( self->base.zrtp_global, &P, &n, &Gx, &Gy,
+#ifdef ZRTP_TEST_VECTORS
+                                                         sv_data, sv_data_len,
+                                                         pvx_data, pvx_data_len,
+                                                         pvy_data, pvy_data_len,
+#endif
+                                                         &pkx, &pky, &dsa_cc->sv );
+       if ( s != zrtp_status_ok )
+               break;
+       s = zrtp_status_fail;
+
+       bnBegin(&dsa_cc->pv);
+       bnCopy (&dsa_cc->pv, &pkx);
+       bnLShift (&dsa_cc->pv, Pbits);
+       bnAdd (&dsa_cc->pv, &pky);
+       bnEnd (&pkx);
+       bnEnd (&pky);
+       bnEnd (&P);
+       bnEnd (&Gx);
+       bnEnd (&Gy);
+       bnEnd (&n);
+
+       s = zrtp_status_ok;
+       } while (0);
+
+       return s;
+}
+
+
+/*----------------------------------------------------------------------------*/
+/* Sign the specified hash value - must be size matching the curve            */
+/*----------------------------------------------------------------------------*/
+static zrtp_status_t ECDSA_sign( struct zrtp_sig_scheme *self,
+                                                                                         zrtp_dsa_crypto_context_t *dsa_cc,
+                                                                                         zrtp_ec_params_t *ec_params,
+#ifdef ZRTP_TEST_VECTORS
+                                                                                         uint8_t *k_data, size_t k_data_len,
+                                                                                         uint8_t *rx_data, size_t rx_data_len,
+                                                                                         uint8_t *ry_data, size_t ry_data_len,
+                                                                                         uint8_t *s_data, size_t s_data_len,
+#endif
+                                                                                         uint8_t *hash, uint32_t hash_len,
+                                                                                         struct BigNum *dsasig )
+{
+       zrtp_status_t s = zrtp_status_fail;
+       struct BigNum P, Gx, Gy, n;
+       struct BigNum h, s1, k, rx, ry, kinv, pkx, pky;
+       unsigned ec_bytes;
+       
+       if (!ec_params)
+               return zrtp_status_bad_param;
+       
+       ec_bytes = (ec_params->ec_bits+7) / 8;
+
+       do
+       {
+       if (!self || !dsa_cc)
+       {
+               s = zrtp_status_bad_param;
+               break;
+       }
+
+    bnBegin(&P);
+    bnInsertBigBytes( &P, ec_params->P_data, 0, ec_bytes );
+    bnBegin(&Gx);
+    bnInsertBigBytes( &Gx, ec_params->Gx_data, 0, ec_bytes );
+    bnBegin(&Gy);
+    bnInsertBigBytes( &Gy, ec_params->Gy_data, 0, ec_bytes );
+    bnBegin(&n);
+    bnInsertBigBytes( &n, ec_params->n_data, 0, ec_bytes );
+
+       /* Hash to bignum */
+    bnBegin(&h);
+    bnInsertBigBytes( &h, hash, 0, hash_len );
+       bnMod (&h, &h, &P);
+
+       /* Unpack signing key */
+       bnBegin(&pkx);
+       bnBegin(&pky);
+       bnSetQ (&pkx, 1);
+       bnLShift (&pkx, ec_bytes*8);
+       bnMod (&pky, &dsa_cc->pv, &pkx);
+       bnCopy (&pkx, &dsa_cc->pv);
+       bnRShift (&pkx, ec_bytes*8);
+
+       /* Choose signature secret k value */
+    bnBegin(&rx);
+    bnBegin(&ry);
+    bnBegin(&k);
+       s = zrtp_ec_random_point( self->base.zrtp_global, &P, &n, &Gx, &Gy,
+#ifdef ZRTP_TEST_VECTORS
+                                                         k_data, k_data_len,
+                                                         rx_data, rx_data_len,
+                                                         ry_data, ry_data_len,
+#endif
+                                                         &rx, &ry, &k );
+       if ( s != zrtp_status_ok )
+               break;
+       s = zrtp_status_fail;
+
+#ifndef ZRTP_TEST_VECTORS
+       /* For further randomness we are going to add the secret key to k */
+       bnAddMod_ (&k, &dsa_cc->sv, &n);
+       zrtp_ecAdd (&rx, &ry, &rx, &ry, &pkx, &pky, &P);
+#endif
+
+       /* Perform the signature */
+       bnBegin (&s1);
+       bnMulMod_ (&s1, &rx, &dsa_cc->sv, &n);
+       bnAddMod_ (&s1, &h, &n);
+       bnBegin (&kinv);
+       bnInv (&kinv, &k, &n);
+       bnMulMod_ (&s1, &s1, &kinv, &n);
+
+#ifdef ZRTP_TEST_VECTORS
+       if (k_data_len != 0)
+       {
+               /* rx is checked in ec_random_point */
+               struct BigNum s2;
+               int ok;
+               bnBegin(&s2);
+               bnInsertBigBytes(&s2, s_data, 0, s_data_len);
+               ok = (bnCmp (&s1, &s2) == 0);
+               bnEnd(&s2);
+               if (!ok)
+                       break;
+       }
+#endif
+
+       /* Combine r, s into dsasig */
+       bnBegin(dsasig);
+       bnCopy (dsasig, &rx);
+       bnLShift (dsasig, ec_bytes*8);
+       bnAdd (dsasig, &s1);
+       bnEnd (&rx);
+       bnEnd (&ry);
+       bnEnd (&k);
+       bnEnd (&kinv);
+       bnEnd (&s1);
+       bnEnd (&h);
+       bnEnd (&pkx);
+       bnEnd (&pky);
+       bnEnd (&P);
+       bnEnd (&Gx);
+       bnEnd (&Gy);
+       bnEnd (&n);
+
+       s = zrtp_status_ok;
+       } while (0);
+
+       return s;
+}
+
+
+/*----------------------------------------------------------------------------*/
+/* Verify a signature value - hash must be size matching the curve            */
+/* Signing key should be in peer_pv entry of dsa_cc                           */
+/*----------------------------------------------------------------------------*/
+static zrtp_status_t ECDSA_verify( struct zrtp_sig_scheme *self,
+                                                                                         zrtp_dsa_crypto_context_t *dsa_cc,
+                                                                                         zrtp_ec_params_t *ec_params,
+                                                                                         uint8_t *hash, uint32_t hash_len,
+                                                                                         struct BigNum *dsasig )
+{
+       zrtp_status_t s = zrtp_status_fail;
+       struct BigNum P, Gx, Gy, n;
+       struct BigNum rx, ry, pkx, pky, r, s1, sinv, u1, u2, u1x, u2x, u1y, u2y, h;
+       unsigned ec_bytes;
+       
+       if (!ec_params)
+               return zrtp_status_bad_param;
+               
+       ec_bytes = (ec_params->ec_bits+7) / 8;
+
+       do
+       {
+       if (!self || !dsa_cc)
+       {
+               s = zrtp_status_bad_param;
+               break;
+       }
+
+    bnBegin(&P);
+    bnInsertBigBytes( &P, ec_params->P_data, 0, ec_bytes );
+    bnBegin(&Gx);
+    bnInsertBigBytes( &Gx, ec_params->Gx_data, 0, ec_bytes );
+    bnBegin(&Gy);
+    bnInsertBigBytes( &Gy, ec_params->Gy_data, 0, ec_bytes );
+    bnBegin(&n);
+    bnInsertBigBytes( &n, ec_params->n_data, 0, ec_bytes );
+
+       /* hash */
+    bnBegin(&h);
+    bnInsertBigBytes( &h, hash, 0, hash_len );
+       bnMod (&h, &h, &P);
+
+       /* Unpack sig */
+       bnBegin(&r);
+       bnBegin(&s1);
+       bnSetQ (&r, 1);
+       bnLShift (&r, ec_bytes*8);
+       bnMod (&s1, dsasig, &r);
+       bnCopy (&r, dsasig);
+       bnRShift (&r, ec_bytes*8);
+
+       /* Unpack signing key */
+       bnBegin(&pkx);
+       bnBegin(&pky);
+       bnSetQ (&pkx, 1);
+       bnLShift (&pkx, ec_bytes*8);
+       bnMod (&pky, &dsa_cc->peer_pv, &pkx);
+       bnCopy (&pkx, &dsa_cc->peer_pv);
+       bnRShift (&pkx, ec_bytes*8);
+
+       /* Verify signature */
+       bnBegin (&sinv);
+       bnInv (&sinv, &s1, &n);
+       bnBegin (&u1);
+       bnBegin (&u2);
+       bnMulMod_ (&u1, &sinv, &h, &n);
+       bnMulMod_ (&u2, &sinv, &r, &n);
+
+       bnBegin (&u1x);
+       bnBegin (&u1y);
+       bnBegin (&u2x);
+       bnBegin (&u2y);
+       bnBegin (&rx);
+       bnBegin (&ry);
+       zrtp_ecMul (&u1x, &u1y, &u1, &Gx, &Gy, &P);
+       zrtp_ecMul (&u2x, &u2y, &u2, &pkx, &pky, &P);
+       zrtp_ecAdd (&rx, &ry, &u1x, &u1y, &u2x, &u2y, &P);
+
+       if (bnCmp (&rx, &r) == 0) {
+               s = zrtp_status_ok;
+       } else {
+               s = zrtp_status_fail;
+       }
+
+       /* Clean up */
+       bnEnd (&rx);
+       bnEnd (&ry);
+       bnEnd (&r);
+       bnEnd (&s1);
+       bnEnd (&sinv);
+       bnEnd (&u1);
+       bnEnd (&u1x);
+       bnEnd (&u1y);
+       bnEnd (&u2);
+       bnEnd (&u2x);
+       bnEnd (&u2y);
+       bnEnd (&h);
+       bnEnd (&pkx);
+       bnEnd (&pky);
+       bnEnd (&P);
+       bnEnd (&Gx);
+       bnEnd (&Gy);
+       bnEnd (&n);
+
+       } while (0);
+
+       return s;
+}
+
+
+
+/*----------------------------------------------------------------------------*/
+static zrtp_status_t EC_dummy(void *s)
+{
+    return zrtp_status_ok;
+}
+
+
+/*============================================================================*/
+/*    P-256 (FIPS 186-3) support.  See RFC 4753, section 3.1.                            */
+/*============================================================================*/
+
+/* Test vectors from RFC4754 */
+#ifdef ZRTP_TEST_VECTORS
+static uint8_t sv256_data[] = {
+       0xDC, 0x51, 0xD3, 0x86, 0x6A, 0x15, 0xBA, 0xCD,
+       0xE3, 0x3D, 0x96, 0xF9, 0x92, 0xFC, 0xA9, 0x9D,
+       0xA7, 0xE6, 0xEF, 0x09, 0x34, 0xE7, 0x09, 0x75,
+       0x59, 0xC2, 0x7F, 0x16, 0x14, 0xC8, 0x8A, 0x7F,
+};
+static uint8_t pvx256_data[] = {
+       0x24, 0x42, 0xA5, 0xCC, 0x0E, 0xCD, 0x01, 0x5F,
+       0xA3, 0xCA, 0x31, 0xDC, 0x8E, 0x2B, 0xBC, 0x70,
+       0xBF, 0x42, 0xD6, 0x0C, 0xBC, 0xA2, 0x00, 0x85,
+       0xE0, 0x82, 0x2C, 0xB0, 0x42, 0x35, 0xE9, 0x70,
+};
+static uint8_t pvy256_data[] = {
+       0x6F, 0xC9, 0x8B, 0xD7, 0xE5, 0x02, 0x11, 0xA4,
+       0xA2, 0x71, 0x02, 0xFA, 0x35, 0x49, 0xDF, 0x79,
+       0xEB, 0xCB, 0x4B, 0xF2, 0x46, 0xB8, 0x09, 0x45,
+       0xCD, 0xDF, 0xE7, 0xD5, 0x09, 0xBB, 0xFD, 0x7D,
+};
+
+static uint8_t k256_data[] = {
+       0x9E, 0x56, 0xF5, 0x09, 0x19, 0x67, 0x84, 0xD9,
+       0x63, 0xD1, 0xC0, 0xA4, 0x01, 0x51, 0x0E, 0xE7,
+       0xAD, 0xA3, 0xDC, 0xC5, 0xDE, 0xE0, 0x4B, 0x15,
+       0x4B, 0xF6, 0x1A, 0xF1, 0xD5, 0xA6, 0xDE, 0xCE,
+};
+static uint8_t rx256_data[] = {
+       0xCB, 0x28, 0xE0, 0x99, 0x9B, 0x9C, 0x77, 0x15,
+       0xFD, 0x0A, 0x80, 0xD8, 0xE4, 0x7A, 0x77, 0x07,
+       0x97, 0x16, 0xCB, 0xBF, 0x91, 0x7D, 0xD7, 0x2E,
+       0x97, 0x56, 0x6E, 0xA1, 0xC0, 0x66, 0x95, 0x7C,
+};
+static uint8_t ry256_data[] = {
+       0x2B, 0x57, 0xC0, 0x23, 0x5F, 0xB7, 0x48, 0x97,
+       0x68, 0xD0, 0x58, 0xFF, 0x49, 0x11, 0xC2, 0x0F,
+       0xDB, 0xE7, 0x1E, 0x36, 0x99, 0xD9, 0x13, 0x39,
+       0xAF, 0xBB, 0x90, 0x3E, 0xE1, 0x72, 0x55, 0xDC,
+};
+
+static uint8_t h256_data[] = {
+       0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
+       0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
+       0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
+       0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD,
+};
+static uint8_t s256_data[] = {
+       0x86, 0xFA, 0x3B, 0xB4, 0xE2, 0x6C, 0xAD, 0x5B,
+       0xF9, 0x0B, 0x7F, 0x81, 0x89, 0x92, 0x56, 0xCE,
+       0x75, 0x94, 0xBB, 0x1E, 0xA0, 0xC8, 0x92, 0x12,
+       0x74, 0x8B, 0xFF, 0x3B, 0x3D, 0x5B, 0x03, 0x15,
+};
+
+
+#endif
+
+/*----------------------------------------------------------------------------*/
+/* Return dsa_cc->pv holding public value and dsa_cc->sv holding secret value   */
+/* The public value is an elliptic curve point encoded as the x part shifted  */
+/* left 256 bits and or'd with the y part.                                    */
+/*----------------------------------------------------------------------------*/
+static zrtp_status_t EC256P_keygen( struct zrtp_sig_scheme *self,
+                                                                           zrtp_dsa_crypto_context_t *dsa_cc )
+{
+       struct zrtp_ec_params params;
+       zrtp_ec_init_params(&params, 256);
+       return ECDSA_keygen(self, dsa_cc, &params,
+#ifdef ZRTP_TEST_VECTORS
+               sv256_data, sizeof(sv256_data),
+               pvx256_data, sizeof(pvx256_data),
+               pvy256_data, sizeof(pvy256_data),
+#endif
+               256);
+}
+
+
+/*----------------------------------------------------------------------------*/
+/* Sign the specified hash value                                              */
+/*----------------------------------------------------------------------------*/
+static zrtp_status_t EC256P_sign( struct zrtp_sig_scheme *self,
+                                                                                         zrtp_dsa_crypto_context_t *dsa_cc,
+                                                                                         uint8_t *hash, uint32_t hash_len,
+                                                                                         struct BigNum *dsasig )
+{
+       struct zrtp_ec_params params;
+       zrtp_ec_init_params(&params, 256);
+       return ECDSA_sign(self, dsa_cc, &params,
+#ifdef ZRTP_TEST_VECTORS
+               k256_data, sizeof(k256_data),
+               rx256_data, sizeof(rx256_data),
+               ry256_data, sizeof(ry256_data),
+               s256_data, sizeof(s256_data),
+               h256_data, sizeof(h256_data),
+#else
+               hash, hash_len,
+#endif
+       dsasig);
+}
+
+
+/*----------------------------------------------------------------------------*/
+/* Verify the signature on the hash value                                     */
+/*----------------------------------------------------------------------------*/
+static zrtp_status_t EC256P_verify(struct zrtp_sig_scheme *self,
+                                                                                         zrtp_dsa_crypto_context_t *dsa_cc,
+                                                                                         uint8_t *hash, uint32_t hash_len,
+                                                                                         struct BigNum *dsasig )
+{
+       struct zrtp_ec_params params;
+       zrtp_ec_init_params(&params, 256);
+       return ECDSA_verify(self, dsa_cc, &params,
+#ifdef ZRTP_TEST_VECTORS
+               h256_data, sizeof(h256_data),
+#else
+               hash, hash_len,
+#endif
+               dsasig);
+}
+
+
+
+/*============================================================================*/
+/*    P-384 (FIPS 186-3) support.  See RFC 4753, section 3.2.                            */
+/*============================================================================*/
+
+
+
+/*----------------------------------------------------------------------------*/
+/* Return dsa_cc->pv holding public value and dsa_cc->sv holding secret value   */
+/* The public value is an elliptic curve point encoded as the x part shifted  */
+/* left 384 bits and or'd with the y part.                                    */
+/*----------------------------------------------------------------------------*/
+static zrtp_status_t EC384P_keygen( struct zrtp_sig_scheme *self,
+                                                                   zrtp_dsa_crypto_context_t *dsa_cc )
+{
+       struct zrtp_ec_params params;
+       zrtp_ec_init_params(&params, 384);
+       return ECDSA_keygen(self, dsa_cc, &params,
+#ifdef ZRTP_TEST_VECTORS
+               0, 0, 0, 0, 0, 0,
+#endif
+               384);
+}
+
+
+/*----------------------------------------------------------------------------*/
+/* Sign the specified hash value                                              */
+/*----------------------------------------------------------------------------*/
+static zrtp_status_t EC384P_sign( struct zrtp_sig_scheme *self,
+                                                                                         zrtp_dsa_crypto_context_t *dsa_cc,
+                                                                                         uint8_t *hash, uint32_t hash_len,
+                                                                                         struct BigNum *dsasig )
+{
+       struct zrtp_ec_params params;
+       zrtp_ec_init_params(&params, 384);
+       return ECDSA_sign(self, dsa_cc, &params,
+#ifdef ZRTP_TEST_VECTORS
+               0, 0, 0, 0, 0, 0, 0, 0,
+#endif
+               hash, hash_len, dsasig);
+}
+
+
+/*----------------------------------------------------------------------------*/
+/* Verify the signature on the hash value                                     */
+/*----------------------------------------------------------------------------*/
+static zrtp_status_t EC384P_verify(struct zrtp_sig_scheme *self,
+                                                                                         zrtp_dsa_crypto_context_t *dsa_cc,
+                                                                                         uint8_t *hash, uint32_t hash_len,
+                                                                                         struct BigNum *dsasig )
+{
+       struct zrtp_ec_params params;
+       zrtp_ec_init_params(&params, 384);
+       return ECDSA_verify(self, dsa_cc, &params, hash, hash_len, dsasig);
+}
+
+
+
+/*============================================================================*/
+/*    P-521 (FIPS 186-3) support.  See RFC 4753, section 3.3.                            */
+/*============================================================================*/
+
+
+/*----------------------------------------------------------------------------*/
+/* Return dsa_cc->pv holding public value and dsa_cc->sv holding secret value   */
+/* The public value is an elliptic curve point encoded as the x part shifted  */
+/* left 528 bits (note, not 521) and or'd with the y part.                    */
+/*----------------------------------------------------------------------------*/
+static zrtp_status_t EC521P_keygen( struct zrtp_sig_scheme *self,
+                                                                           zrtp_dsa_crypto_context_t *dsa_cc )
+{
+       struct zrtp_ec_params params;
+       zrtp_ec_init_params(&params, 521);
+       return ECDSA_keygen(self, dsa_cc, &params,
+#ifdef ZRTP_TEST_VECTORS
+               0, 0, 0, 0, 0, 0,
+#endif
+               528);
+}
+
+
+/*----------------------------------------------------------------------------*/
+/* Sign the specified hash value                                              */
+/*----------------------------------------------------------------------------*/
+static zrtp_status_t EC521P_sign( struct zrtp_sig_scheme *self,
+                                                                                         zrtp_dsa_crypto_context_t *dsa_cc,
+                                                                                         uint8_t *hash, uint32_t hash_len,
+                                                                                         struct BigNum *dsasig )
+{
+       struct zrtp_ec_params params;
+       zrtp_ec_init_params(&params, 521);
+       return ECDSA_sign(self, dsa_cc, &params,
+#ifdef ZRTP_TEST_VECTORS
+               0, 0, 0, 0, 0, 0, 0, 0,
+#endif
+               hash, hash_len, dsasig);
+}
+
+
+/*----------------------------------------------------------------------------*/
+/* Verify the signature on the hash value                                     */
+/*----------------------------------------------------------------------------*/
+static zrtp_status_t EC521P_verify(struct zrtp_sig_scheme *self,
+                                                                                         zrtp_dsa_crypto_context_t *dsa_cc,
+                                                                                         uint8_t *hash, uint32_t hash_len,
+                                                                                         struct BigNum *dsasig )
+{
+       struct zrtp_ec_params params;
+       zrtp_ec_init_params(&params, 521);
+       return ECDSA_verify(self, dsa_cc, &params, hash, hash_len, dsasig);
+}
+
+
+
+/*============================================================================*/
+/*    Public Key support                                                                                                         */
+/*============================================================================*/
+
+
+/*----------------------------------------------------------------------------*/
+zrtp_status_t zrtp_defaults_sig(zrtp_global_ctx_t* zrtp_global)
+{
+    zrtp_sig_scheme_t* ec256p = zrtp_sys_alloc(sizeof(zrtp_sig_scheme_t));
+    zrtp_sig_scheme_t* ec384p = zrtp_sys_alloc(sizeof(zrtp_sig_scheme_t));
+    zrtp_sig_scheme_t* ec521p = zrtp_sys_alloc(sizeof(zrtp_sig_scheme_t));
+    
+       if (!ec256p || !ec384p || !ec521p)
+       {
+               if(ec256p) zrtp_sys_free(ec256p);
+               if(ec384p) zrtp_sys_free(ec384p);
+               if(ec521p) zrtp_sys_free(ec521p);
+               return zrtp_status_alloc_fail;
+       }
+
+    zrtp_memset(ec256p, 0, sizeof(zrtp_sig_scheme_t));
+    zrtp_memcpy(ec256p->base.type, ZRTP_EC256P, ZRTP_COMP_TYPE_SIZE);
+       ec256p->base.id                         = ZRTP_SIGTYPE_EC256P;
+    ec256p->base.zrtp_global   = zrtp_global;
+    ec256p->sv_length                  = 256/8;
+    ec256p->pv_length                  = 2*256/8;
+    ec256p->base.init                  = EC_dummy;
+    ec256p->base.free                  = EC_dummy;
+    ec256p->generate_key               = EC256P_keygen;
+    ec256p->sign                               = EC256P_sign;
+    ec256p->verify                             = EC256P_verify;
+
+    zrtp_memset(ec384p, 0, sizeof(zrtp_sig_scheme_t));
+    zrtp_memcpy(ec384p->base.type, ZRTP_EC384P, ZRTP_COMP_TYPE_SIZE);
+       ec384p->base.id                         = ZRTP_SIGTYPE_EC384P;
+    ec384p->base.zrtp_global   = zrtp_global;
+    ec384p->sv_length                  = 384/8;
+    ec384p->pv_length                  = 2*384/8;
+    ec384p->base.init                  = EC_dummy;
+    ec384p->base.free                  = EC_dummy;
+    ec384p->generate_key               = EC384P_keygen;
+    ec384p->sign                               = EC384P_sign;
+    ec384p->verify                             = EC384P_verify;
+
+    zrtp_memset(ec521p, 0, sizeof(zrtp_sig_scheme_t));
+    zrtp_memcpy(ec521p->base.type, ZRTP_EC521P, ZRTP_COMP_TYPE_SIZE);
+       ec521p->base.id                         = ZRTP_SIGTYPE_EC521P;
+    ec521p->base.zrtp_global   = zrtp_global;
+    ec521p->sv_length                  = 528/8;
+    ec521p->pv_length                  = 2*528/8;
+    ec521p->base.init                  = EC_dummy;
+    ec521p->base.free                  = EC_dummy;
+    ec521p->generate_key               = EC521P_keygen;
+    ec521p->sign                               = EC521P_sign;
+    ec521p->verify                             = EC521P_verify;
+
+    zrtp_register_comp(ZRTP_CC_SIG, ec256p, zrtp_global);
+    zrtp_register_comp(ZRTP_CC_SIG, ec384p, zrtp_global);
+    zrtp_register_comp(ZRTP_CC_SIG, ec521p, zrtp_global);
+
+    return zrtp_status_ok;
+}
+
+#endif /* don't have disgital signature ready for the moment*/