by Werner Koch | 15 Dec 12:15 2014
Picon

[git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-135-gad50e36

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, master has been updated
       via  ad50e360ef4851e66e51a03fc420175636336b58 (commit)
      from  4f46374502eb988d701b904f83819e2cf7b1755c (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 ad50e360ef4851e66e51a03fc420175636336b58
Author: Werner Koch <wk <at> gnupg.org>
Date:   Mon Dec 15 12:05:32 2014 +0100

    build: Add configure option --disable-doc.

    * Makefile.am (AUTOMAKE_OPTIONS): Remove.
    (doc) [!BUILD_DOC]: Do not recurse into the dir.
    * configure.ac (AM_INIT_AUTOMAKE): Add option formerly in Makefile.am.
    (BUILD_DOC): Add new am_conditional.

diff --git a/Makefile.am b/Makefile.am
index 937bdaf..2d7ca43 100644
--- a/Makefile.am
+++ b/Makefile.am
 <at>  <at>  -18,15 +18,21  <at>  <at> 
 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
(Continue reading)

Jussi Kivilinna | 12 Dec 23:52 2014
Picon
Picon

[PATCH] rijndael: use more compact look-up tables and add table prefetching

* cipher/rijndael-internal.h (rijndael_prefetchfn_t): New.
(RIJNDAEL_context): Add 'prefetch_enc_fn' and 'prefetch_dec_fn'.
* cipher/rijndael-tables.h (S, T1, T2, T3, T4, T5, T6, T7, T8, S5, U1)
(U2, U3, U4): Remove.
(encT, decT): Add.
* cipher/rijndael.c (_gcry_aes_amd64_encrypt_block)
(_gcry_aes_amd64_decrypt_block, _gcry_aes_arm_encrypt_block)
(_gcry_aes_arm_encrypt_block): Add parameter for passing table pointer
to assembly implementation.
(prefetch_table, prefetch_enc, prefetch_dec): New.
(do_setkey): Setup context prefetch functions depending on selected
rijndael implementation; Use new tables for key setup.
(prepare_decryption): Use new tables for decryption key setup.
(do_encrypt_aligned): Rename to...
(do_encrypt_fn): ... to this, change to use new compact tables and
make handle unaligned input.
(do_encrypt): Remove handling of unaligned input/output; pass table
pointer to assembly implementations.
(rijndael_encrypt, _gcry_aes_cfb_enc, _gcry_aes_cbc_enc)
(_gcry_aes_ctr_enc, _gcry_aes_cfb_dec): Prefetch encryption tables
before encryption.
(do_decrypt_aligned): Rename to...
(do_decrypt_fn): ... to this, change to use new compact tables and
make handle unaligned input.
(do_decrypt): Remove handling of unaligned input/output; pass table
pointer to assembly implementations.
(rijndael_decrypt, _gcry_aes_cbc_dec): Prefetch decryption tables
before decryption.
* cipher/rijndael-amd64.S: Use 2+2 KiB tables for
encryption+decryption; remove tables from assembly file.
(Continue reading)

Jussi Kivilinna | 6 Dec 14:22 2014
Picon
Picon

[PATCH] GCM: move Intel PCLMUL accelerated implementation to separate file

* cipher/Makefile.am: Add 'cipher-gcm-intel-pclmul.c'.
* cipher/cipher-gcm-intel-pclmul.c: New.
* cipher/cipher-gcm.c [GCM_USE_INTEL_PCLMUL]
(_gcry_ghash_setup_intel_pclmul, _gcry_ghash_intel_pclmul): New
prototypes.
[GCM_USE_INTEL_PCLMUL] (gfmul_pclmul, gfmul_pclmul_aggr4): Move
to 'cipher-gcm-intel-pclmul.c'.
(ghash): Rename to...
(ghash_internal): ...this and move GCM_USE_INTEL_PCLMUL part to new
function in 'cipher-gcm-intel-pclmul.c'.
(setupM): Move GCM_USE_INTEL_PCLMUL part to new function in
'cipher-gcm-intel-pclmul.c'; Add selection of ghash function based
on available HW acceleration.
(do_ghash_buf): Change use of 'ghash' to 'c->u_mode.gcm.ghash_fn'.
* cipher/internal.h (ghash_fn_t): New.
(gcry_cipher_handle): Remove 'use_intel_pclmul'; Add 'ghash_fn'.
--

Signed-off-by: Jussi Kivilinna <jussi.kivilinna <at> iki.fi>
---
 cipher/Makefile.am               |    4 
 cipher/cipher-gcm-intel-pclmul.c |  395 ++++++++++++++++++++++++++++++++++++++
 cipher/cipher-gcm.c              |  395 ++------------------------------------
 cipher/cipher-internal.h         |   13 +
 4 files changed, 430 insertions(+), 377 deletions(-)
 create mode 100644 cipher/cipher-gcm-intel-pclmul.c

diff --git a/cipher/Makefile.am b/cipher/Makefile.am
index d7e7773..98142ed 100644
--- a/cipher/Makefile.am
(Continue reading)

Jussi Kivilinna | 6 Dec 14:22 2014
Picon
Picon

[PATCH] rijndael: further optimizations for AES-NI accelerated CBC and CFB bulk modes

* cipher/rijndael-aesni.c (do_aesni_enc, do_aesni_dec): Pass
input/output through SSE register XMM0.
(do_aesni_cfb): Remove.
(_gcry_aes_aesni_encrypt, _gcry_aes_aesni_decrypt): Add loading/storing
input/output to/from XMM0.
(_gcry_aes_aesni_cfb_enc, _gcry_aes_aesni_cbc_enc)
(_gcry_aes_aesni_cfb_dec): Update to use renewed 'do_aesni_enc' and
move IV loading/storing outside loop.
(_gcry_aes_aesni_cbc_dec): Update to use renewed 'do_aesni_dec'.
--

CBC encryption speed is improved ~16% on Intel Haswell and CFB encryption ~8%.

Signed-off-by: Jussi Kivilinna <jussi.kivilinna <at> iki.fi>
---
 cipher/rijndael-aesni.c |  244 ++++++++++++++++++++---------------------------
 1 file changed, 104 insertions(+), 140 deletions(-)

diff --git a/cipher/rijndael-aesni.c b/cipher/rijndael-aesni.c
index e6c1051..3c367ce 100644
--- a/cipher/rijndael-aesni.c
+++ b/cipher/rijndael-aesni.c
 <at>  <at>  -340,33 +340,14  <at>  <at>  _gcry_aes_aesni_prepare_decryption (RIJNDAEL_context *ctx)
 }

 
-/* Encrypt one block using the Intel AES-NI instructions.  A and B may
-   be the same.
-
-   Our problem here is that gcc does not allow the "x" constraint for
(Continue reading)

Mike Crowe | 3 Dec 18:57 2014

lock_pool drops capabilities even when running as root

We're using libgcrypt in an embedded application that runs as root
(i.e. UID=EUID=0.) We recently discovered that libgcrypt operations that
allocate secure memory caused all the process's capabilities to be dropped
causing surprises later when the rest of the application tries to perform
privileged operations.

We upgraded libgcrypt so we could use
gcry_control(GCRYCTL_DISABLE_PRIV_DROP) but this did not help (for reasons
that were obvious once I looked more closely.)

The culprit would appear to be the code at the start of secmem.c:lock_pool
that calls cap_set_proc. Before calling my capabilities are:

 CapInh: 0000000000000000
 CapPrm: 0000001fffffffff
 CapEff: 0000001fffffffff
 CapBnd: 0000001fffffffff

afterwards they are:

 CapInh: 0000000000000000
 CapPrm: 0000000000004000
 CapEff: 0000000000000000
 CapBnd: 0000001fffffffff

Borrowing the "uid && !geteuid()" check from lower down fixes the problem
for me but I suspect that isn't sufficient for all use cases.

--- secmem.c~	2014-08-21 13:50:39.000000000 +0100
+++ secmem.c	2014-12-03 17:55:08.446683419 +0000
(Continue reading)

Jussi Kivilinna | 1 Dec 20:12 2014
Picon
Picon

[PATCH 1/4] rijndael: split AES-NI functions to separate file

* cipher/Makefile.in: Add 'rijndael-aesni.c'.
* cipher/rijndael-aesni.c: New.
* cipher/rijndael-internal.h: New.
* cipher/rijndael.c (MAXKC, MAXROUNDS, BLOCKSIZE, ATTR_ALIGNED_16)
(USE_AMD64_ASM, USE_ARM_ASM, USE_PADLOCK, USE_AESNI, RIJNDAEL_context)
(keyschenc, keyschdec, padlockkey): Move to 'rijndael-internal.h'.
(u128_s, aesni_prepare, aesni_cleanup, aesni_cleanup_2_6)
(aesni_do_setkey, do_aesni_enc, do_aesni_dec, do_aesni_enc_vec4)
(do_aesni_dec_vec4, do_aesni_cfb, do_aesni_ctr, do_aesni_ctr_4): Move
to 'rijndael-aesni.c'.
(prepare_decryption, rijndael_encrypt, _gcry_aes_cfb_enc)
(_gcry_aes_cbc_enc, _gcry_aes_ctr_enc, rijndael_decrypt)
(_gcry_aes_cfb_dec, _gcry_aes_cbc_dec) [USE_AESNI]: Move to functions
in 'rijdael-aesni.c'.
* configure.ac [mpi_cpu_arch=x86]: Add 'rijndael-aesni.lo'.
--

Clean-up rijndael.c before new new hardware acceleration support gets added.

Signed-off-by: Jussi Kivilinna <jussi.kivilinna <at> iki.fi>
---
 cipher/Makefile.am         |    3 
 cipher/rijndael-aesni.c    | 1288 +++++++++++++++++++++++++++++++++++++++++
 cipher/rijndael-internal.h |  118 ++++
 cipher/rijndael.c          | 1393 ++------------------------------------------
 configure.ac               |    7 
 5 files changed, 1478 insertions(+), 1331 deletions(-)
 create mode 100644 cipher/rijndael-aesni.c
 create mode 100644 cipher/rijndael-internal.h

(Continue reading)

Jan Bilek | 30 Nov 14:18 2014
Picon

Re: AES192 & AES256 in CBC mode [libgcrypt]

Resending as previous email seemed to be bounced back by the  
http://www.dnsbl.manitu.net/'s spam filter.

Kind Regards,
Jan

On 30/11/14 23:02, Jan Bilek wrote:
> Hello Jussi,
>
> thanks for this, however I'm not sure how to interpret your email. 
> Does it mean that my test vectors are wrong? I calculated those "in 
> hand" so this might be the case, but then my understanding of CBC is 
> incorrect.
>
> Thank you,
> Jan
>
> On 30/11/14 19:07, Jussi Kivilinna wrote:
>> Hello,
>>
>> On 28.11.2014 03:10, Jan Bilek wrote:> Hello,
>>> I've just bounced in a potential problem with libgcrypt while trying 
>>> to do AES192 & AES256 in CBC mode.
>>>
>>> All works well with AES128 for all cipher modes, however when moving 
>>> to AES192 & AES256 and GCRY_CIPHER_MODE_CBC it looks like all 
>>> buffers are being written just in first 128 bits of output.
>>>
>>> Please see example code attached.
>>>
(Continue reading)

Jan Bilek | 28 Nov 02:10 2014
Picon

AES192 & AES256 in CBC mode [libgcrypt]

Hello,

I've just bounced in a potential problem with libgcrypt while trying to do AES192 & AES256 in CBC mode.

All works well with AES128 for all cipher modes, however when moving to AES192 & AES256 and GCRY_CIPHER_MODE_CBC it looks like all buffers are being written just in first 128 bits of output.

Please see example code attached.

Let me know if you'll be able to confirm that and if confirmed if I may help with fixing it.

Thank you & Kind Regards,
Jan
Jan Bilek CTO, EFTlab Pty Ltd email: jan.bilek <at> eftlab.co.uk mob: +61 (0) 498 103 179 This message contains confidential information and is intended only for the addressee(s). E-mail transmission cannot be guaranteed to be secure or error-free as information could be intercepted, corrupted, lost, destroyed, arrive late or incomplete, or contain viruses. EFTlab Ltd cannot accept liability for any errors or omissions in the contents of this message, which may arise as a result of e-mail transmission. Please note that EFTlab Ltd may monitor, analyse and archive email traffic, data and the content of email for the purposes of security, legal compliance and staff training. If you have received this email in error please notify us at support <at> eftlab.co.uk. EFTlab is a limited company registered in England & Wales with Reg No. 07528943. The Registered Office is 21-27 Lamb's Conduit Street, London, WC1N 3GS.
Attachment (crypto_aes.cpp): text/x-c++src, 6065 bytes
_______________________________________________
Gcrypt-devel mailing list
Gcrypt-devel <at> gnupg.org
http://lists.gnupg.org/mailman/listinfo/gcrypt-devel
by Werner Koch | 24 Nov 12:32 2014
Picon

[git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-128-gd53ea84

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, master has been updated
       via  d53ea84bed37b973f7ce59262c50b33700cd8311 (commit)
       via  1b4210c204a5ef5e631187509e011b8468a134ef (commit)
      from  e6130034506013d6153465a2bedb6fb08a43f74d (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 d53ea84bed37b973f7ce59262c50b33700cd8311
Author: Werner Koch <wk <at> gnupg.org>
Date:   Mon Nov 24 12:28:33 2014 +0100

    Remove duplicated prototypes.

    * src/gcrypt-int.h (_gcry_mpi_ec_new, _gcry_mpi_ec_set_mpi)
    (gcry_mpi_ec_set_point): Remove.
    --

    Thos used gpg_error_t instead of gpg_err_code_t and the picky AIX
    compiler takes this as a severe error.

    Signed-off-by: Werner Koch <wk <at> gnupg.org>

diff --git a/src/gcrypt-int.h b/src/gcrypt-int.h
index 918937b..29d4fd3 100644
--- a/src/gcrypt-int.h
+++ b/src/gcrypt-int.h
 <at>  <at>  -416,15 +416,10  <at>  <at>  gcry_mpi_point_t _gcry_mpi_point_set (gcry_mpi_point_t point,
 gcry_mpi_point_t _gcry_mpi_point_snatch_set (gcry_mpi_point_t point,
                                             gcry_mpi_t x, gcry_mpi_t y,
                                             gcry_mpi_t z);
-gpg_error_t _gcry_mpi_ec_new (gcry_ctx_t *r_ctx,
-                             gcry_sexp_t keyparam, const char *curvename);
+
 gcry_mpi_t _gcry_mpi_ec_get_mpi (const char *name, gcry_ctx_t ctx, int copy);
 gcry_mpi_point_t _gcry_mpi_ec_get_point (const char *name,
                                         gcry_ctx_t ctx, int copy);
-gpg_error_t _gcry_mpi_ec_set_mpi (const char *name, gcry_mpi_t newvalue,
-                                 gcry_ctx_t ctx);
-gpg_error_t _gcry_mpi_ec_set_point (const char *name, gcry_mpi_point_t newvalue,
-                                   gcry_ctx_t ctx);
 int _gcry_mpi_ec_get_affine (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_point_t point,
                              mpi_ec_t ctx);
 void _gcry_mpi_ec_dup (gcry_mpi_point_t w, gcry_mpi_point_t u, gcry_ctx_t ctx);

commit 1b4210c204a5ef5e631187509e011b8468a134ef
Author: Werner Koch <wk <at> gnupg.org>
Date:   Tue Oct 14 21:29:33 2014 +0200

    tests: Add a prime mode to benchmark.

    * tests/benchmark.c (progress_cb): Add a single char mode.
    (prime_bench): New.
    (main): Add a "prime" mode.  Factor with_progress out to file scope.

    Signed-off-by: Werner Koch <wk <at> gnupg.org>

diff --git a/tests/benchmark.c b/tests/benchmark.c
index 2621551..5bf92da 100644
--- a/tests/benchmark.c
+++ b/tests/benchmark.c
 <at>  <at>  -62,6 +62,12  <at>  <at>  static int in_fips_mode;
 /* Whether we are running as part of the regression test suite.  */
 static int in_regression_test;

+/* Whether --progress is in use.  */
+static int with_progress;
+
+/* Runtime flag to switch to a different progress output.  */
+static int single_char_progress;
+

 static const char sample_private_dsa_key_1024[] =
 "(private-key\n"
 <at>  <at>  -429,9 +435,17  <at>  <at>  progress_cb (void *cb_data, const char *what, int printchar,
 {
   (void)cb_data;

-  fprintf (stderr, PGM ": progress (%s %c %d %d)\n",
-           what, printchar, current, total);
-  fflush (stderr);
+  if (single_char_progress)
+    {
+      fputc (printchar, stdout);
+      fflush (stderr);
+    }
+  else
+    {
+      fprintf (stderr, PGM ": progress (%s %c %d %d)\n",
+               what, printchar, current, total);
+      fflush (stderr);
+    }
 }

 
 <at>  <at>  -1544,6 +1558,51  <at>  <at>  mpi_bench (void)
 }

 
+static void
+prime_bench (void)
+{
+  gpg_error_t err;
+  int i;
+  gcry_mpi_t prime;
+  int old_prog = single_char_progress;
+
+  single_char_progress = 1;
+  if (!with_progress)
+    printf ("%-10s", "prime");
+  fflush (stdout);
+  start_timer ();
+  for (i=0; i < 10; i++)
+    {
+      if (with_progress)
+        fputs ("primegen ", stdout);
+      err = gcry_prime_generate (&prime,
+                                 1024, 0,
+                                 NULL,
+                                 NULL, NULL,
+                                 GCRY_WEAK_RANDOM,
+                                 GCRY_PRIME_FLAG_SECRET);
+      if (with_progress)
+        {
+          fputc ('\n', stdout);
+          fflush (stdout);
+        }
+      if (err)
+        {
+          fprintf (stderr, PGM ": error creating prime: %s\n",
+                   gpg_strerror (err));
+          exit (1);
+        }
+      gcry_mpi_release (prime);
+    }
+  stop_timer ();
+  if (with_progress)
+    printf ("%-10s", "prime");
+  printf (" %s\n", elapsed_time ()); fflush (stdout);
+
+  single_char_progress = old_prog;
+}
+
+
 int
 main( int argc, char **argv )
 {
 <at>  <at>  -1551,7 +1610,6  <at>  <at>  main( int argc, char **argv )
   int no_blinding = 0;
   int use_random_daemon = 0;
   int use_secmem = 0;
-  int with_progress = 0;
   int debug = 0;
   int pk_count = 100;

 <at>  <at>  -1582,7 +1640,7  <at>  <at>  main( int argc, char **argv )
       else if (!strcmp (*argv, "--help"))
         {
           fputs ("usage: benchmark "
-                 "[md|mac|cipher|random|mpi|rsa|dsa|ecc [algonames]]\n",
+                 "[md|mac|cipher|random|mpi|rsa|dsa|ecc|prime [algonames]]\n",
                  stdout);
           exit (0);
         }
 <at>  <at>  -1833,6 +1891,11  <at>  <at>  main( int argc, char **argv )
         gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
         ecc_bench (pk_count, 1);
     }
+  else if ( !strcmp (*argv, "prime"))
+    {
+        gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
+        prime_bench ();
+    }
   else
     {
       fprintf (stderr, PGM ": bad arguments\n");

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

Summary of changes:
 src/gcrypt-int.h  |    7 +----
 tests/benchmark.c |   73 +++++++++++++++++++++++++++++++++++++++++++++++++----
 2 files changed, 69 insertions(+), 11 deletions(-)

hooks/post-receive
--

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

_______________________________________________
Gnupg-commits mailing list
Gnupg-commits <at> gnupg.org
http://lists.gnupg.org/mailman/listinfo/gnupg-commits
by NIIBE Yutaka | 20 Nov 01:46 2014
Picon

[git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-126-ge613003

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, master has been updated
       via  e6130034506013d6153465a2bedb6fb08a43f74d (commit)
      from  95eef21583d8e998efc48f22898c1ae31b77cb48 (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 e6130034506013d6153465a2bedb6fb08a43f74d
Author: NIIBE Yutaka <gniibe <at> fsij.org>
Date:   Wed Nov 19 15:48:12 2014 +0900

    ecc: Improve Montgomery curve implementation.

    * cipher/ecc-curves.c (_gcry_ecc_fill_in_curve): Support
    MPI_EC_MONTGOMERY.
    * cipher/ecc.c (test_ecdh_only_keys): New.
    (nist_generate_key): Call test_ecdh_only_keys for MPI_EC_MONTGOMERY.
    (check_secret_key): Handle Montgomery curve of x-coordinate only.
    * mpi/ec.c (_gcry_mpi_ec_mul_point): Resize points before the loop.
    Simplify, using pointers of Q1, Q2, PRD, and SUM.
    --

diff --git a/cipher/ecc-curves.c b/cipher/ecc-curves.c
index fd47c1d..9975bb4 100644
--- a/cipher/ecc-curves.c
+++ b/cipher/ecc-curves.c
 <at>  <at>  -530,9 +530,8  <at>  <at>  _gcry_ecc_fill_in_curve (unsigned int nbits, const char *name,
     {
     case MPI_EC_WEIERSTRASS:
     case MPI_EC_EDWARDS:
-      break;
     case MPI_EC_MONTGOMERY:
-      return GPG_ERR_NOT_SUPPORTED;
+      break;
     default:
       return GPG_ERR_BUG;
     }
diff --git a/cipher/ecc.c b/cipher/ecc.c
index 8bdbd56..2f5e401 100644
--- a/cipher/ecc.c
+++ b/cipher/ecc.c
 <at>  <at>  -81,6 +81,7  <at>  <at>  static void *progress_cb_data;
 
 /* Local prototypes. */
 static void test_keys (ECC_secret_key * sk, unsigned int nbits);
+static void test_ecdh_only_keys (ECC_secret_key * sk, unsigned int nbits);
 static unsigned int ecc_get_nbits (gcry_sexp_t parms);

 
 <at>  <at>  -209,7 +210,10  <at>  <at>  nist_generate_key (ECC_secret_key *sk, elliptic_curve_t *E, mpi_ec_t ctx,

   point_free (&Q);
   /* Now we can test our keys (this should never fail!).  */
-  test_keys (sk, nbits - 64);
+  if (sk->E.model != MPI_EC_MONTGOMERY)
+    test_keys (sk, nbits - 64);
+  else
+    test_ecdh_only_keys (sk, nbits - 64);

   return 0;
 }
 <at>  <at>  -266,6 +270,80  <at>  <at>  test_keys (ECC_secret_key *sk, unsigned int nbits)
 }

 
+static void
+test_ecdh_only_keys (ECC_secret_key *sk, unsigned int nbits)
+{
+  ECC_public_key pk;
+  gcry_mpi_t test;
+  mpi_point_struct R_;
+  gcry_mpi_t x0, x1;
+  mpi_ec_t ec;
+
+  if (DBG_CIPHER)
+    log_debug ("Testing key.\n");
+
+  point_init (&R_);
+
+  pk.E = _gcry_ecc_curve_copy (sk->E);
+  point_init (&pk.Q);
+  point_set (&pk.Q, &sk->Q);
+
+  if (sk->E.dialect == ECC_DIALECT_ED25519)
+    {
+      char *rndbuf;
+
+      test = mpi_new (256);
+      rndbuf = _gcry_random_bytes (32, GCRY_WEAK_RANDOM);
+      rndbuf[0] &= 0x7f;  /* Clear bit 255. */
+      rndbuf[0] |= 0x40;  /* Set bit 254.   */
+      rndbuf[31] &= 0xf8; /* Clear bits 2..0 so that d mod 8 == 0  */
+      _gcry_mpi_set_buffer (test, rndbuf, 32, 0);
+      xfree (rndbuf);
+    }
+  else
+    {
+      test = mpi_new (nbits);
+      _gcry_mpi_randomize (test, nbits, GCRY_WEAK_RANDOM);
+    }
+
+  ec = _gcry_mpi_ec_p_internal_new (pk.E.model, pk.E.dialect, 0,
+                                    pk.E.p, pk.E.a, pk.E.b);
+  x0 = mpi_new (0);
+  x1 = mpi_new (0);
+
+  /* R_ = hkQ  <=>  R_ = hkdG  */
+  _gcry_mpi_ec_mul_point (&R_, test, &pk.Q, ec);
+  if (sk->E.dialect != ECC_DIALECT_ED25519)
+    _gcry_mpi_ec_mul_point (&R_, ec->h, &R_, ec);
+  if (_gcry_mpi_ec_get_affine (x0, NULL, &R_, ec))
+    log_fatal ("ecdh: Failed to get affine coordinates for hkQ\n");
+
+  _gcry_mpi_ec_mul_point (&R_, test, &pk.E.G, ec);
+  _gcry_mpi_ec_mul_point (&R_, sk->d, &R_, ec);
+  /* R_ = hdkG */
+  if (sk->E.dialect != ECC_DIALECT_ED25519)
+    _gcry_mpi_ec_mul_point (&R_, ec->h, &R_, ec);
+
+  if (_gcry_mpi_ec_get_affine (x1, NULL, &R_, ec))
+    log_fatal ("ecdh: Failed to get affine coordinates for hdkG\n");
+
+  if (mpi_cmp (x0, x1))
+    {
+      log_fatal ("ECDH test failed.\n");
+    }
+
+  mpi_free (x0);
+  mpi_free (x1);
+  _gcry_mpi_ec_free (ec);
+
+  point_free (&pk.Q);
+  _gcry_ecc_curve_free (&pk.E);
+
+  point_free (&R_);
+  mpi_free (test);
+}
+
+
 /*
  * To check the validity of the value, recalculate the correspondence
  * between the public value and the secret one.
 <at>  <at>  -281,7 +359,10  <at>  <at>  check_secret_key (ECC_secret_key *sk, mpi_ec_t ec, int flags)

   point_init (&Q);
   x1 = mpi_new (0);
-  y1 = mpi_new (0);
+  if (ec->model == MPI_EC_MONTGOMERY)
+    y1 = NULL;
+  else
+    y1 = mpi_new (0);

   /* G in E(F_p) */
   if (!_gcry_mpi_ec_curve_point (&sk->E.G, ec))
 <at>  <at>  -338,7 +419,7  <at>  <at>  check_secret_key (ECC_secret_key *sk, mpi_ec_t ec, int flags)
   else if (!mpi_cmp_ui (sk->Q.z, 1))
     {
       /* Fast path if Q is already in affine coordinates.  */
-      if (mpi_cmp (x1, sk->Q.x) || mpi_cmp (y1, sk->Q.y))
+      if (mpi_cmp (x1, sk->Q.x) || (!y1 && mpi_cmp (y1, sk->Q.y)))
         {
           if (DBG_CIPHER)
             log_debug
 <at>  <at>  -1581,7 +1662,7  <at>  <at>  compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparms)
       char buf[30];

       if (idx == 5)
-	continue;		/* Skip cofactor. */
+        continue;               /* Skip cofactor. */

       if (mpi_is_opaque (values[idx]))
         {
diff --git a/mpi/ec.c b/mpi/ec.c
index 80f3b22..0b7c7a7 100644
--- a/mpi/ec.c
+++ b/mpi/ec.c
 <at>  <at>  -1251,7 +1251,9  <at>  <at>  _gcry_mpi_ec_mul_point (mpi_point_t result,
       unsigned int nbits;
       int j;
       mpi_point_struct p1_, p2_;
+      mpi_point_t q1, q2, prd, sum;
       unsigned long sw;
+      size_t nlimbs;

       /* Compute scalar point multiplication with Montgomery Ladder.
          Note that we don't use Y-coordinate in the points at all.
 <at>  <at>  -1267,27 +1269,35  <at>  <at>  _gcry_mpi_ec_mul_point (mpi_point_t result,
       p2.x  = mpi_copy (point->x);
       mpi_set_ui (p2.z, 1);

+      nlimbs = 2*(nbits+BITS_PER_MPI_LIMB-1)/BITS_PER_MPI_LIMB+1;
+      mpi_resize (p1.x, nlimbs);
+      mpi_resize (p1.z, nlimbs);
+      mpi_resize (p2.x, nlimbs);
+      mpi_resize (p2.z, nlimbs);
+      mpi_resize (p1_.x, nlimbs);
+      mpi_resize (p1_.z, nlimbs);
+      mpi_resize (p2_.x, nlimbs);
+      mpi_resize (p2_.z, nlimbs);
+
+      q1 = &p1;
+      q2 = &p2;
+      prd = &p1_;
+      sum = &p2_;
+
       for (j=nbits-1; j >= 0; j--)
         {
-          sw = mpi_test_bit (scalar, j);
-          mpi_swap_cond (p1.x, p2.x, sw);
-          mpi_swap_cond (p1.z, p2.z, sw);
-          montgomery_ladder (&p1_, &p2_, &p1, &p2, point->x, ctx);
-          mpi_swap_cond (p1_.x, p2_.x, sw);
-          mpi_swap_cond (p1_.z, p2_.z, sw);
-
-          if (--j < 0)
-            break;
+          mpi_point_t t;

           sw = mpi_test_bit (scalar, j);
-          mpi_swap_cond (p1_.x, p2_.x, sw);
-          mpi_swap_cond (p1_.z, p2_.z, sw);
-          montgomery_ladder (&p1, &p2, &p1_, &p2_, point->x, ctx);
-          mpi_swap_cond (p1.x, p2.x, sw);
-          mpi_swap_cond (p1.z, p2.z, sw);
+          mpi_swap_cond (q1->x, q2->x, sw);
+          mpi_swap_cond (q1->z, q2->z, sw);
+          montgomery_ladder (prd, sum, q1, q2, point->x, ctx);
+          mpi_swap_cond (prd->x, sum->x, sw);
+          mpi_swap_cond (prd->z, sum->z, sw);
+          t = q1;  q1 = prd;  prd = t;
+          t = q2;  q2 = sum;  sum = t;
         }

-      z1 = mpi_new (0);
       mpi_clear (result->y);
       sw = (nbits & 1);
       mpi_swap_cond (p1.x, p1_.x, sw);
 <at>  <at>  -1300,12 +1310,13  <at>  <at>  _gcry_mpi_ec_mul_point (mpi_point_t result,
         }
       else
         {
+          z1 = mpi_new (0);
           ec_invm (z1, p1.z, ctx);
           ec_mulm (result->x, p1.x, z1, ctx);
           mpi_set_ui (result->z, 1);
+          mpi_free (z1);
         }

-      mpi_free (z1);
       point_free (&p1);
       point_free (&p2);
       point_free (&p1_);

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

Summary of changes:
 cipher/ecc-curves.c |    3 +-
 cipher/ecc.c        |   89 ++++++++++++++++++++++++++++++++++++++++++++++++---
 mpi/ec.c            |   43 ++++++++++++++++---------
 3 files changed, 113 insertions(+), 22 deletions(-)

hooks/post-receive
--

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

_______________________________________________
Gnupg-commits mailing list
Gnupg-commits <at> gnupg.org
http://lists.gnupg.org/mailman/listinfo/gnupg-commits
NIIBE Yutaka | 19 Nov 08:39 2014

[PATCH] ecc: Improve Montgomery curve implementation

Here is the change for Montgomery curve implementation.  I forgot to
submit this change in August.

Adding test_ecdh_only_keys is needed when we will support encryption
by Curve25519 in future.

The changes in _gcry_mpi_ec_mul_point are to make sure resizing the
MPI representation of points, and code clean up.

OK to commit?

    ecc: Improve Montgomery curve implementation.

    * cipher/ecc-curves.c (_gcry_ecc_fill_in_curve): Support
    MPI_EC_MONTGOMERY.
    * cipher/ecc.c (test_ecdh_only_keys): New.
    (nist_generate_key): Call test_ecdh_only_keys for MPI_EC_MONTGOMERY.
    (check_secret_key): Handle Montgomery curve of x-coordinate only.
    * mpi/ec.c (_gcry_mpi_ec_mul_point): Resize points before the loop.
    Simplify, using pointers of Q1, Q2, PRD, and SUM.
    --

diff --git a/cipher/ecc-curves.c b/cipher/ecc-curves.c
index fd47c1d..9975bb4 100644
--- a/cipher/ecc-curves.c
+++ b/cipher/ecc-curves.c
 <at>  <at>  -530,9 +530,8  <at>  <at>  _gcry_ecc_fill_in_curve (unsigned int nbits, const
char *name,
     {
     case MPI_EC_WEIERSTRASS:
     case MPI_EC_EDWARDS:
-      break;
     case MPI_EC_MONTGOMERY:
-      return GPG_ERR_NOT_SUPPORTED;
+      break;
     default:
       return GPG_ERR_BUG;
     }
diff --git a/cipher/ecc.c b/cipher/ecc.c
index 8bdbd56..2f5e401 100644
--- a/cipher/ecc.c
+++ b/cipher/ecc.c
 <at>  <at>  -81,6 +81,7  <at>  <at>  static void *progress_cb_data;
 
 /* Local prototypes. */
 static void test_keys (ECC_secret_key * sk, unsigned int nbits);
+static void test_ecdh_only_keys (ECC_secret_key * sk, unsigned int nbits);
 static unsigned int ecc_get_nbits (gcry_sexp_t parms);

 <at>  <at>  -209,7 +210,10  <at>  <at>  nist_generate_key (ECC_secret_key *sk,
elliptic_curve_t *E, mpi_ec_t ctx,

   point_free (&Q);
   /* Now we can test our keys (this should never fail!).  */
-  test_keys (sk, nbits - 64);
+  if (sk->E.model != MPI_EC_MONTGOMERY)
+    test_keys (sk, nbits - 64);
+  else
+    test_ecdh_only_keys (sk, nbits - 64);

   return 0;
 }
 <at>  <at>  -266,6 +270,80  <at>  <at>  test_keys (ECC_secret_key *sk, unsigned int nbits)
 }

+static void
+test_ecdh_only_keys (ECC_secret_key *sk, unsigned int nbits)
+{
+  ECC_public_key pk;
+  gcry_mpi_t test;
+  mpi_point_struct R_;
+  gcry_mpi_t x0, x1;
+  mpi_ec_t ec;
+
+  if (DBG_CIPHER)
+    log_debug ("Testing key.\n");
+
+  point_init (&R_);
+
+  pk.E = _gcry_ecc_curve_copy (sk->E);
+  point_init (&pk.Q);
+  point_set (&pk.Q, &sk->Q);
+
+  if (sk->E.dialect == ECC_DIALECT_ED25519)
+    {
+      char *rndbuf;
+
+      test = mpi_new (256);
+      rndbuf = _gcry_random_bytes (32, GCRY_WEAK_RANDOM);
+      rndbuf[0] &= 0x7f;  /* Clear bit 255. */
+      rndbuf[0] |= 0x40;  /* Set bit 254.   */
+      rndbuf[31] &= 0xf8; /* Clear bits 2..0 so that d mod 8 == 0  */
+      _gcry_mpi_set_buffer (test, rndbuf, 32, 0);
+      xfree (rndbuf);
+    }
+  else
+    {
+      test = mpi_new (nbits);
+      _gcry_mpi_randomize (test, nbits, GCRY_WEAK_RANDOM);
+    }
+
+  ec = _gcry_mpi_ec_p_internal_new (pk.E.model, pk.E.dialect, 0,
+                                    pk.E.p, pk.E.a, pk.E.b);
+  x0 = mpi_new (0);
+  x1 = mpi_new (0);
+
+  /* R_ = hkQ  <=>  R_ = hkdG  */
+  _gcry_mpi_ec_mul_point (&R_, test, &pk.Q, ec);
+  if (sk->E.dialect != ECC_DIALECT_ED25519)
+    _gcry_mpi_ec_mul_point (&R_, ec->h, &R_, ec);
+  if (_gcry_mpi_ec_get_affine (x0, NULL, &R_, ec))
+    log_fatal ("ecdh: Failed to get affine coordinates for hkQ\n");
+
+  _gcry_mpi_ec_mul_point (&R_, test, &pk.E.G, ec);
+  _gcry_mpi_ec_mul_point (&R_, sk->d, &R_, ec);
+  /* R_ = hdkG */
+  if (sk->E.dialect != ECC_DIALECT_ED25519)
+    _gcry_mpi_ec_mul_point (&R_, ec->h, &R_, ec);
+
+  if (_gcry_mpi_ec_get_affine (x1, NULL, &R_, ec))
+    log_fatal ("ecdh: Failed to get affine coordinates for hdkG\n");
+
+  if (mpi_cmp (x0, x1))
+    {
+      log_fatal ("ECDH test failed.\n");
+    }
+
+  mpi_free (x0);
+  mpi_free (x1);
+  _gcry_mpi_ec_free (ec);
+
+  point_free (&pk.Q);
+  _gcry_ecc_curve_free (&pk.E);
+
+  point_free (&R_);
+  mpi_free (test);
+}
+
+
 /*
  * To check the validity of the value, recalculate the correspondence
  * between the public value and the secret one.
 <at>  <at>  -281,7 +359,10  <at>  <at>  check_secret_key (ECC_secret_key *sk, mpi_ec_t ec,
int flags)

   point_init (&Q);
   x1 = mpi_new (0);
-  y1 = mpi_new (0);
+  if (ec->model == MPI_EC_MONTGOMERY)
+    y1 = NULL;
+  else
+    y1 = mpi_new (0);

   /* G in E(F_p) */
   if (!_gcry_mpi_ec_curve_point (&sk->E.G, ec))
 <at>  <at>  -338,7 +419,7  <at>  <at>  check_secret_key (ECC_secret_key *sk, mpi_ec_t ec,
int flags)
   else if (!mpi_cmp_ui (sk->Q.z, 1))
     {
       /* Fast path if Q is already in affine coordinates.  */
-      if (mpi_cmp (x1, sk->Q.x) || mpi_cmp (y1, sk->Q.y))
+      if (mpi_cmp (x1, sk->Q.x) || (!y1 && mpi_cmp (y1, sk->Q.y)))
         {
           if (DBG_CIPHER)
             log_debug
 <at>  <at>  -1581,7 +1662,7  <at>  <at>  compute_keygrip (gcry_md_hd_t md, gcry_sexp_t
keyparms)
       char buf[30];

       if (idx == 5)
-	continue;		/* Skip cofactor. */
+        continue;               /* Skip cofactor. */

       if (mpi_is_opaque (values[idx]))
         {
diff --git a/mpi/ec.c b/mpi/ec.c
index 80f3b22..0b7c7a7 100644
--- a/mpi/ec.c
+++ b/mpi/ec.c
 <at>  <at>  -1251,7 +1251,9  <at>  <at>  _gcry_mpi_ec_mul_point (mpi_point_t result,
       unsigned int nbits;
       int j;
       mpi_point_struct p1_, p2_;
+      mpi_point_t q1, q2, prd, sum;
       unsigned long sw;
+      size_t nlimbs;

       /* Compute scalar point multiplication with Montgomery Ladder.
          Note that we don't use Y-coordinate in the points at all.
 <at>  <at>  -1267,27 +1269,35  <at>  <at>  _gcry_mpi_ec_mul_point (mpi_point_t result,
       p2.x  = mpi_copy (point->x);
       mpi_set_ui (p2.z, 1);

+      nlimbs = 2*(nbits+BITS_PER_MPI_LIMB-1)/BITS_PER_MPI_LIMB+1;
+      mpi_resize (p1.x, nlimbs);
+      mpi_resize (p1.z, nlimbs);
+      mpi_resize (p2.x, nlimbs);
+      mpi_resize (p2.z, nlimbs);
+      mpi_resize (p1_.x, nlimbs);
+      mpi_resize (p1_.z, nlimbs);
+      mpi_resize (p2_.x, nlimbs);
+      mpi_resize (p2_.z, nlimbs);
+
+      q1 = &p1;
+      q2 = &p2;
+      prd = &p1_;
+      sum = &p2_;
+
       for (j=nbits-1; j >= 0; j--)
         {
-          sw = mpi_test_bit (scalar, j);
-          mpi_swap_cond (p1.x, p2.x, sw);
-          mpi_swap_cond (p1.z, p2.z, sw);
-          montgomery_ladder (&p1_, &p2_, &p1, &p2, point->x, ctx);
-          mpi_swap_cond (p1_.x, p2_.x, sw);
-          mpi_swap_cond (p1_.z, p2_.z, sw);
-
-          if (--j < 0)
-            break;
+          mpi_point_t t;

           sw = mpi_test_bit (scalar, j);
-          mpi_swap_cond (p1_.x, p2_.x, sw);
-          mpi_swap_cond (p1_.z, p2_.z, sw);
-          montgomery_ladder (&p1, &p2, &p1_, &p2_, point->x, ctx);
-          mpi_swap_cond (p1.x, p2.x, sw);
-          mpi_swap_cond (p1.z, p2.z, sw);
+          mpi_swap_cond (q1->x, q2->x, sw);
+          mpi_swap_cond (q1->z, q2->z, sw);
+          montgomery_ladder (prd, sum, q1, q2, point->x, ctx);
+          mpi_swap_cond (prd->x, sum->x, sw);
+          mpi_swap_cond (prd->z, sum->z, sw);
+          t = q1;  q1 = prd;  prd = t;
+          t = q2;  q2 = sum;  sum = t;
         }

-      z1 = mpi_new (0);
       mpi_clear (result->y);
       sw = (nbits & 1);
       mpi_swap_cond (p1.x, p1_.x, sw);
 <at>  <at>  -1300,12 +1310,13  <at>  <at>  _gcry_mpi_ec_mul_point (mpi_point_t result,
         }
       else
         {
+          z1 = mpi_new (0);
           ec_invm (z1, p1.z, ctx);
           ec_mulm (result->x, p1.x, z1, ctx);
           mpi_set_ui (result->z, 1);
+          mpi_free (z1);
         }

-      mpi_free (z1);
       point_free (&p1);
       point_free (&p2);
       point_free (&p1_);
--

-- 

Gmane