summaryrefslogtreecommitdiff
path: root/cipher/ecc-misc.c
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2013-11-05 17:25:02 +0100
committerWerner Koch <wk@gnupg.org>2013-11-05 17:26:52 +0100
commitf09ffe8a4802af65a116e79eceeb1cb4ed4fa2f4 (patch)
tree294ee667a0c27bd20c333eab4fb69bb04b8c8de3 /cipher/ecc-misc.c
parent630aca794ddf057fb7265b7dc346374743036af4 (diff)
downloadlibgcrypt-f09ffe8a4802af65a116e79eceeb1cb4ed4fa2f4.tar.gz
ecc: Fully implement Ed25519 compression in ECDSA mode.
* src/ec-context.h (mpi_ec_ctx_s): Add field FLAGS. * mpi/ec.c (ec_p_init): Add arg FLAGS. Change all callers to pass it. * cipher/ecc-curves.c (point_from_keyparam): Add arg EC, parse as opaque mpi and use eddsa decoding depending on the flag. (_gcry_mpi_ec_new): Rearrange to parse Q and D after knowing the curve. Signed-off-by: Werner Koch <wk@gnupg.org>
Diffstat (limited to 'cipher/ecc-misc.c')
-rw-r--r--cipher/ecc-misc.c112
1 files changed, 54 insertions, 58 deletions
diff --git a/cipher/ecc-misc.c b/cipher/ecc-misc.c
index fa0bded5..6c75e75d 100644
--- a/cipher/ecc-misc.c
+++ b/cipher/ecc-misc.c
@@ -26,6 +26,7 @@
#include "g10lib.h"
#include "mpi.h"
+#include "cipher.h"
#include "context.h"
#include "ec-context.h"
#include "ecc-common.h"
@@ -263,67 +264,62 @@ _gcry_ecc_compute_public (mpi_point_t Q, mpi_ec_t ec)
if (ec->model == MPI_EC_TWISTEDEDWARDS && !ec->b)
return NULL;
- switch (ec->dialect)
+ if (ec->dialect == ECC_DIALECT_ED25519
+ && !(ec->flags & PUBKEY_FLAG_ECDSA))
{
- case ECC_DIALECT_ED25519:
- {
- gcry_mpi_t a;
- unsigned char *rawmpi = NULL;
- unsigned int rawmpilen;
- unsigned char *digest;
- gcry_buffer_t hvec[2];
- int b = (ec->nbits+7)/8;
-
- gcry_assert (b >= 32);
- digest = gcry_calloc_secure (2, b);
- if (!digest)
+ gcry_mpi_t a;
+ unsigned char *rawmpi = NULL;
+ unsigned int rawmpilen;
+ unsigned char *digest;
+ gcry_buffer_t hvec[2];
+ int b = (ec->nbits+7)/8;
+
+ gcry_assert (b >= 32);
+ digest = gcry_calloc_secure (2, b);
+ if (!digest)
+ return NULL;
+ memset (hvec, 0, sizeof hvec);
+
+ rawmpi = _gcry_mpi_get_buffer (ec->d, 0, &rawmpilen, NULL);
+ if (!rawmpi)
+ return NULL;
+ memset (digest, 0, b);
+ hvec[0].data = digest;
+ hvec[0].off = 0;
+ hvec[0].len = b > rawmpilen? b - rawmpilen : 0;
+ hvec[1].data = rawmpi;
+ hvec[1].off = 0;
+ hvec[1].len = rawmpilen;
+ /* FIXME: Put and take the hash algo from the context. */
+ rc = _gcry_md_hash_buffers (GCRY_MD_SHA512, 0, digest, hvec, 2);
+ gcry_free (rawmpi);
+ if (rc)
+ {
+ gcry_free (digest);
return NULL;
- memset (hvec, 0, sizeof hvec);
+ }
- rawmpi = _gcry_mpi_get_buffer (ec->d, 0, &rawmpilen, NULL);
- if (!rawmpi)
- return NULL;
- memset (digest, 0, b);
- hvec[0].data = digest;
- hvec[0].off = 0;
- hvec[0].len = b > rawmpilen? b - rawmpilen : 0;
- hvec[1].data = rawmpi;
- hvec[1].off = 0;
- hvec[1].len = rawmpilen;
- /* FIXME: Put and take the hash algo from the context. */
- rc = _gcry_md_hash_buffers (GCRY_MD_SHA512, 0, digest, hvec, 2);
- gcry_free (rawmpi);
- if (rc)
- {
- gcry_free (digest);
- return NULL;
- }
-
- /* Compute the A value. */
- reverse_buffer (digest, 32); /* Only the first half of the hash. */
- digest[0] = (digest[0] & 0x7f) | 0x40;
- digest[31] &= 0xf8;
- a = mpi_snew (0);
- _gcry_mpi_set_buffer (a, digest, 32, 0);
- gcry_free (digest);
-
- /* And finally the public key. */
- if (!Q)
- Q = gcry_mpi_point_new (0);
- if (Q)
- _gcry_mpi_ec_mul_point (Q, a, ec->G, ec);
- mpi_free (a);
- }
- break;
-
- default:
- {
- if (!Q)
- Q = gcry_mpi_point_new (0);
- if (Q)
- _gcry_mpi_ec_mul_point (Q, ec->d, ec->G, ec);
- }
- break;
+ /* Compute the A value. */
+ reverse_buffer (digest, 32); /* Only the first half of the hash. */
+ digest[0] = (digest[0] & 0x7f) | 0x40;
+ digest[31] &= 0xf8;
+ a = mpi_snew (0);
+ _gcry_mpi_set_buffer (a, digest, 32, 0);
+ gcry_free (digest);
+
+ /* And finally the public key. */
+ if (!Q)
+ Q = gcry_mpi_point_new (0);
+ if (Q)
+ _gcry_mpi_ec_mul_point (Q, a, ec->G, ec);
+ mpi_free (a);
+ }
+ else
+ {
+ if (!Q)
+ Q = gcry_mpi_point_new (0);
+ if (Q)
+ _gcry_mpi_ec_mul_point (Q, ec->d, ec->G, ec);
}
return Q;