diff options
author | NIIBE Yutaka <gniibe@fsij.org> | 2020-06-11 17:19:00 +0900 |
---|---|---|
committer | NIIBE Yutaka <gniibe@fsij.org> | 2020-06-16 10:30:52 +0900 |
commit | e25446ecc04442b399302ce72db6d5ea2e9e85e8 (patch) | |
tree | 823df49ea56d4c0d8619083eef75e7ccf47d4a31 /cipher/ecc-eddsa.c | |
parent | bd22b029bbf50737f90535c506fba4f812bcf040 (diff) | |
download | libgcrypt-e25446ecc04442b399302ce72db6d5ea2e9e85e8.tar.gz |
ecc: Support Ed448 for key generation.
* cipher/ecc-eddsa.c (_gcry_ecc_eddsa_compute_h_d): Support Ed448.
(_gcry_ecc_eddsa_genkey): Support Ed448, using
_gcry_ecc_eddsa_compute_h_d.
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
Diffstat (limited to 'cipher/ecc-eddsa.c')
-rw-r--r-- | cipher/ecc-eddsa.c | 77 |
1 files changed, 45 insertions, 32 deletions
diff --git a/cipher/ecc-eddsa.c b/cipher/ecc-eddsa.c index 0054aad6..1b49840a 100644 --- a/cipher/ecc-eddsa.c +++ b/cipher/ecc-eddsa.c @@ -505,13 +505,21 @@ _gcry_ecc_eddsa_compute_h_d (unsigned char **r_digest, mpi_ec_t ec) *r_digest = NULL; - hashalgo = GCRY_MD_SHA512; - if (hashalgo != GCRY_MD_SHA512) - return GPG_ERR_DIGEST_ALGO; - b = (ec->nbits+7)/8; - if (b != 256/8) - return GPG_ERR_INTERNAL; /* We only support 256 bit. */ + + /* + * Choice of hashalgo is curve specific. + * For now, it's determine by the bit size of the field. + */ + if (ec->nbits == 255) + hashalgo = GCRY_MD_SHA512; + else if (ec->nbits == 448) + { + b++; + hashalgo = GCRY_MD_SHAKE256; + } + else + return GPG_ERR_NOT_IMPLEMENTED; /* Note that we clear DIGEST so we can use it as input to left pad the key with zeroes for hashing. */ @@ -543,9 +551,20 @@ _gcry_ecc_eddsa_compute_h_d (unsigned char **r_digest, mpi_ec_t ec) } /* Compute the A value. */ - reverse_buffer (digest, 32); /* Only the first half of the hash. */ - digest[0] = (digest[0] & 0x7f) | 0x40; - digest[31] &= 0xf8; + reverse_buffer (digest, b); /* Only the first half of the hash. */ + + /* Field specific handling of clearing/setting bits. */ + if (ec->nbits == 255) + { + digest[0] = (digest[0] & 0x7f) | 0x40; + digest[31] &= 0xf8; + } + else + { + digest[0] = 0; + digest[1] |= 0x80; + digest[56] &= 0xfc; + } *r_digest = digest; return 0; @@ -567,50 +586,45 @@ gpg_err_code_t _gcry_ecc_eddsa_genkey (mpi_ec_t ec, int flags) { gpg_err_code_t rc; - int b = 256/8; /* The only size we currently support. */ + int b; gcry_mpi_t a, x, y; mpi_point_struct Q; gcry_random_level_t random_level; char *dbuf; size_t dlen; - gcry_buffer_t hvec[1]; unsigned char *hash_d = NULL; point_init (&Q); - memset (hvec, 0, sizeof hvec); if ((flags & PUBKEY_FLAG_TRANSIENT_KEY)) random_level = GCRY_STRONG_RANDOM; else random_level = GCRY_VERY_STRONG_RANDOM; + b = (ec->nbits+7)/8; + + if (ec->nbits == 255) + ; + else if (ec->nbits == 448) + b++; + else + return GPG_ERR_NOT_IMPLEMENTED; + + dlen = b; + a = mpi_snew (0); x = mpi_new (0); y = mpi_new (0); /* Generate a secret. */ - hash_d = xtrymalloc_secure (2*b); - if (!hash_d) - { - rc = gpg_err_code_from_syserror (); - goto leave; - } - dlen = b; dbuf = _gcry_random_bytes_secure (dlen, random_level); - - /* Compute the A value. */ - hvec[0].data = dbuf; - hvec[0].len = dlen; - rc = _gcry_md_hash_buffers (GCRY_MD_SHA512, 0, hash_d, hvec, 1); + ec->d = _gcry_mpi_set_opaque (NULL, dbuf, dlen*8); + rc = _gcry_ecc_eddsa_compute_h_d (&hash_d, ec); if (rc) goto leave; - ec->d = _gcry_mpi_set_opaque (NULL, dbuf, dlen*8); - dbuf = NULL; - reverse_buffer (hash_d, 32); /* Only the first half of the hash. */ - hash_d[0] = (hash_d[0] & 0x7f) | 0x40; - hash_d[31] &= 0xf8; - _gcry_mpi_set_buffer (a, hash_d, 32, 0); - xfree (hash_d); hash_d = NULL; + + _gcry_mpi_set_buffer (a, hash_d, b, 0); + xfree (hash_d); /* log_printmpi ("ecgen a", a); */ /* Compute Q. */ @@ -627,7 +641,6 @@ _gcry_ecc_eddsa_genkey (mpi_ec_t ec, int flags) _gcry_mpi_release (a); _gcry_mpi_release (x); _gcry_mpi_release (y); - xfree (hash_d); return rc; } |