[git] GCRYPT - branch, ECC-INTEGRATION-1-5, updated. libgcrypt-1.4.4-51-g8993868

by Andrey Jivsov cvs at cvs.gnupg.org
Tue Jan 11 05:31:35 CET 2011


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "The GNU crypto library".

The branch, ECC-INTEGRATION-1-5 has been updated
       via  899386826c85f1e757e75bcc5d5b2159d05676a0 (commit)
      from  2c32b631acc1637c1d7826bcdcecf6c0ae9ce7fc (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 899386826c85f1e757e75bcc5d5b2159d05676a0
Author: Andrey Jivsov <openpgp at brainhub.org>
Date:   Mon Jan 10 20:11:54 2011 -0800

    'g10/gpg2 --encrypt --debug 15 -r ecdsa -a  -o _e.asc _'  and 'g10/gpg2 --debug 15 _e.asc', as well as decoding of an old message posted on https://sites.google.com/site/brainhub/pgpecckeys work.
    
    This is the milestone 2 that brings in ECDH support from http://code.google.com/p/gnupg-ecc/source/detail?r=15 .
    
    Updated the ECDH code to work with latest gnupg that doesn't expose private components of a public key.

diff --git a/cipher/ecc.c b/cipher/ecc.c
index fdcbb4c..f33cc1c 100644
--- a/cipher/ecc.c
+++ b/cipher/ecc.c
@@ -1337,36 +1337,61 @@ ecc_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey,
 }
 
 
-/* ecdh is very simple. It is basically the implementation of the primitive operation in the EC field. 
- * 'data' is scalar, 2-MPI array pkey uniquely defines a point on the curve.
+/* ecdh raw is classic 2-round DH protocol published in 1976. 
+ * Some overloading is needed to fit it to encrypt/decrypt PK interface of libgcrypt.
+ * 
+ * The only need for this complexity is that some designs of client of libgcrypt 
+ * don't allow to get the private components of public keys.
  *
- * The complexity of ECDH encryption is shifted into OpenPGP layer to keep libgcrypt
- * layer generic. ecc_encrypt is identical to ecc_decrypt due to the symmetry of DH protocol.
+ * Overview of ecc_encrypt_raw and ecc_decrypt_raw.
+ *
+ * As with any PK operation, encrypt version uses a public key and decrypt -- private.  
+ *
+ * Symbols used bellow:
+ *     G - field generator point
+ *     x - private long-term scalar
+ *    xG - public long-term key
+ *     k - ephemeral scalar
+ *    kG - ephemeral public key
+ *   xkG - shared secret
+ *
+ * ecc_encrypt_raw description:
+ *   input:
+ *     data[0] : private scalar (k)
+ *   output: 
+ *     resaddr[0] : shared point (k*x*G, where x is the secret scalar of pkey; it's the shared secret)
+ *     resaddr[1] : generated ephemeral public key (kG)
+ *
+ * ecc_decrypt_raw description:
+ *   input:
+ *     data[0] : a point kG (ephemeral public key)
+ *   output:
+ *     result[0] : shared point (k*x*G, where x is the secret scalar of pkey; it's the shared secret)
  */
 static gcry_err_code_t
-ecc_encrypt (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, gcry_mpi_t *pkey, int flags)
+ecc_encrypt_raw (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, gcry_mpi_t *pkey, int flags)
 {
   ECC_secret_key sk;
-  mpi_point_t R;	/* result that we return */
   mpi_ec_t ctx;
-  gcry_mpi_t result;
+  gcry_mpi_t result[2];
+  mpi_point_t  eph_Q;
   int err;
 
   (void)algo;
   (void)flags;
 
   if (DBG_CIPHER)
-    log_debug ("Called ecc_encrypt data size=%d bits, flags=%08x\n", gcry_mpi_get_nbits (data), flags);
+    log_debug ("Called ecc_encrypt_raw data size=%d bits, flags=%08x\n", gcry_mpi_get_nbits (data), flags);
 
   if ( !data || !pkey[0] || !pkey[1] )
     return GPG_ERR_BAD_MPI;
 
   if (DBG_CIPHER)
   {
-    log_mpidump ("ecdh encrypt c   ", pkey[0]);
-    log_mpidump ("ecdh encrypt q   ", pkey[1]);
-    log_mpidump ("ecdh encrypt p   ", pkey[2]);
-    log_mpidump ("ecdh encrypt data", data);
+    log_mpidump ("ecdh encrypt PK c  ", pkey[0]);
+    log_mpidump ("ecdh encrypt PK q  ", pkey[1]);
+    log_mpidump ("ecdh encrypt PK p  ", pkey[2]);
+    log_mpidump ("ecdh encrypt data k", data);
   }
 
   if( (err=mpi_to_name_oid( pkey[0], sk.E.name_oid )) )
@@ -1385,6 +1410,108 @@ ecc_encrypt (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, gcry_mpi_t *pkey, in
 
   ctx = _gcry_mpi_ec_init (sk.E.p, sk.E.a);
 
+
+  /* the following is false: assert( mpi_cmp_ui( R.x, 1 )==0 );, so */
+  {
+    mpi_point_t R;	/* result that we return */
+    gcry_mpi_t x,y;
+
+    x = mpi_new (0);	
+    y = mpi_new (0);	
+
+    point_init (&R);
+
+    _gcry_mpi_ec_mul_point (&R, sk.d, &sk.Q, ctx);
+
+    if (_gcry_mpi_ec_get_affine (x, y, &R, ctx))
+        log_fatal ("ecdh: Failed to get affine coordinates for xkG\n");
+
+    result[0] = ec2os( x, y, sk.E.p );	/* xkG */
+
+    _gcry_mpi_ec_mul_point (&R, sk.d, &sk.E.G, ctx);
+
+    if (_gcry_mpi_ec_get_affine (x, y, &R, ctx))
+        log_fatal ("ecdh: Failed to get affine coordinates for kG\n");
+
+    result[1] = ec2os( x, y, sk.E.p );	/* kG */
+
+    mpi_free(x);
+    mpi_free(y);
+
+    point_free( &R );
+  }
+
+  _gcry_mpi_ec_free (ctx);
+  ecc_sk_free( &sk );
+
+  if( result[0] == NULL || result[1] == NULL )  {
+    mpi_free( result[0] );
+    mpi_free( result[1] );
+    return GPG_ERR_ENOMEM;
+  }
+
+  /* success */
+
+   /* none of 2 returned values are used as is; they are further processed at OpenPGP layer.
+    * However, they match the number of MPIs (2) needed to encrypt a message in OpenPGP format 
+    */
+  resarr[0] = result[0];
+  resarr[1] = result[1];	
+
+  return GPG_ERR_NO_ERROR;
+}
+
+ /*  input:
+ *     data[0] : a point kG (ephemeral public key)
+ *   output:
+ *     resaddr[0] : shared point k*x*G
+ *
+ *  see ecc_encrypt_raw for details.
+ */
+static gcry_err_code_t
+ecc_decrypt_raw (int algo, gcry_mpi_t *result, gcry_mpi_t *data, gcry_mpi_t *skey, int flags)
+{
+  ECC_secret_key sk;
+  mpi_point_t R;	/* result that we return */
+  mpi_ec_t ctx;
+  gcry_mpi_t r;
+  int err;
+
+  (void)algo;
+  (void)flags;
+
+  *result = NULL;
+
+  if (DBG_CIPHER)
+    log_debug ("Called ecc_encrypt_raw data size=%d bits, flags=%08x\n", gcry_mpi_get_nbits (data), flags);
+
+  if ( !data || !data[0] || !skey[0] || !skey[1] || !skey[3] )
+    return GPG_ERR_BAD_MPI;
+
+  if (DBG_CIPHER)
+  {
+    log_mpidump ("ecdh decrypt SK c   ", skey[0]);
+    log_mpidump ("ecdh decrypt SK q   ", skey[1]);
+    log_mpidump ("ecdh decrypt SK p   ", skey[2]);
+    log_mpidump ("ecdh decrypt data kG", data[0]);
+  }
+
+  if( (err=mpi_to_name_oid( skey[0], sk.E.name_oid )) )
+    return err;
+  if( (err=fill_in_curve( sk.E.name_oid, &sk.E )) )
+    return err;
+
+  point_init (&sk.Q);
+  err = os2ec (&sk.Q, data[0]);
+  sk.d = gcry_mpi_copy( skey[3] );
+  if (err)
+    {
+      ecc_sk_free( &sk );
+      return err;
+    }
+
+  ctx = _gcry_mpi_ec_init (sk.E.p, sk.E.a);
+
   point_init (&R);
   _gcry_mpi_ec_mul_point (&R, sk.d, &sk.Q, ctx);
 
@@ -1397,7 +1524,7 @@ ecc_encrypt (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, gcry_mpi_t *pkey, in
     if (_gcry_mpi_ec_get_affine (x, y, &R, ctx))
         log_fatal ("ecdh: Failed to get affine coordinates\n");
 
-    result = ec2os( x, y, sk.E.p );
+    r = ec2os( x, y, sk.E.p );
     mpi_free(x);
     mpi_free(y);
   }
@@ -1406,23 +1533,16 @@ ecc_encrypt (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, gcry_mpi_t *pkey, in
   _gcry_mpi_ec_free (ctx);
   ecc_sk_free( &sk );
 
-  if( result == NULL )
+  if( r == NULL )
 	return GPG_ERR_ENOMEM;
 
   /* success */
 
-  resarr[0] = result;
-  resarr[1] = mpi_new (0);	/* not used; it is constructruced at OpenPGP layer */
+  *result = r;
 
   return GPG_ERR_NO_ERROR;
 }
 
-static gcry_err_code_t
-ecc_decrypt (int algo, gcry_mpi_t *result, gcry_mpi_t *data, gcry_mpi_t *skey, int flags)
-{
-  return ecc_encrypt( algo, result, data[0], skey, flags );
-}
-
 static unsigned int
 ecc_get_nbits (int algo, gcry_mpi_t *pkey)
 {
@@ -1625,8 +1745,8 @@ gcry_pk_spec_t _gcry_pubkey_spec_ecdh =
     GCRY_PK_USAGE_ENCR,
     ecc_generate,
     ecc_check_secret_key,
-    ecc_encrypt,
-    ecc_decrypt,
+    ecc_encrypt_raw,
+    ecc_decrypt_raw,
     NULL,
     NULL,
     ecc_get_nbits

-----------------------------------------------------------------------

Summary of changes:
 cipher/ecc.c |  168 +++++++++++++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 144 insertions(+), 24 deletions(-)


hooks/post-receive
-- 
The GNU crypto library
http://git.gnupg.org




More information about the Gnupg-commits mailing list