summaryrefslogtreecommitdiff
path: root/cipher/ecc-misc.c
diff options
context:
space:
mode:
authorNIIBE Yutaka <gniibe@fsij.org>2015-08-06 17:31:41 +0900
committerNIIBE Yutaka <gniibe@fsij.org>2015-08-06 17:31:41 +0900
commite93f4c21c59756604440ad8cbf27e67d29c99ffd (patch)
tree4b97f8a1f8d8804f6897c3afb21527897eda04e6 /cipher/ecc-misc.c
parentb4b1d872ba651bc44761b35d245b1a519a33f515 (diff)
downloadlibgcrypt-e93f4c21c59756604440ad8cbf27e67d29c99ffd.tar.gz
Add Curve25519 support.
* cipher/ecc-curves.c (curve_aliases, domain_parms): Add Curve25519. * tests/curves.c (N_CURVES): It's 22 now. * src/cipher.h (PUBKEY_FLAG_DJB_TWEAK): New. * cipher/ecc-common.h (_gcry_ecc_mont_decodepoint): New. * cipher/ecc-misc.c (_gcry_ecc_mont_decodepoint): New. * cipher/ecc.c (nist_generate_key): Handle the case of PUBKEY_FLAG_DJB_TWEAK and Montgomery curve. (test_ecdh_only_keys, check_secret_key): Likewise. (ecc_generate): Support Curve25519 which is Montgomery curve with flag PUBKEY_FLAG_DJB_TWEAK and PUBKEY_FLAG_COMP. (ecc_encrypt_raw): Get flags from KEYPARMS and handle PUBKEY_FLAG_DJB_TWEAK and Montgomery curve. (ecc_decrypt_raw): Likewise. (compute_keygrip): Handle the case of PUBKEY_FLAG_DJB_TWEAK. * cipher/pubkey-util.c (_gcry_pk_util_parse_flaglist): PUBKEY_FLAG_EDDSA implies PUBKEY_FLAG_DJB_TWEAK. Parse "djb-tweak" for PUBKEY_FLAG_DJB_TWEAK. -- With PUBKEY_FLAG_DJB_TWEAK, secret key has msb set and it should be always multiple by cofactor.
Diffstat (limited to 'cipher/ecc-misc.c')
-rw-r--r--cipher/ecc-misc.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/cipher/ecc-misc.c b/cipher/ecc-misc.c
index 88266b55..2f2e5937 100644
--- a/cipher/ecc-misc.c
+++ b/cipher/ecc-misc.c
@@ -287,3 +287,51 @@ _gcry_ecc_compute_public (mpi_point_t Q, mpi_ec_t ec,
return Q;
}
+
+
+gpg_err_code_t
+_gcry_ecc_mont_decodepoint (gcry_mpi_t pk, mpi_ec_t ctx, mpi_point_t result)
+{
+ unsigned char *rawmpi;
+ unsigned int rawmpilen;
+
+ if (mpi_is_opaque (pk))
+ {
+ const unsigned char *buf;
+ unsigned char *p;
+
+ buf = mpi_get_opaque (pk, &rawmpilen);
+ if (!buf)
+ return GPG_ERR_INV_OBJ;
+ rawmpilen = (rawmpilen + 7)/8;
+
+ if (rawmpilen > 1 && (rawmpilen%2) && buf[0] == 0x40)
+ {
+ rawmpilen--;
+ buf++;
+ }
+
+ rawmpi = xtrymalloc (rawmpilen? rawmpilen:1);
+ if (!rawmpi)
+ return gpg_err_code_from_syserror ();
+
+ p = rawmpi + rawmpilen;
+ while (p > rawmpi)
+ *--p = *buf++;
+ }
+ else
+ {
+ /* Note: Without using an opaque MPI it is not reliable possible
+ to find out whether the public key has been given in
+ uncompressed format. Thus we expect native EdDSA format. */
+ rawmpi = _gcry_mpi_get_buffer (pk, ctx->nbits/8, &rawmpilen, NULL);
+ if (!rawmpi)
+ return gpg_err_code_from_syserror ();
+ }
+
+ _gcry_mpi_set_buffer (result->x, rawmpi, rawmpilen, 0);
+ xfree (rawmpi);
+ mpi_set_ui (result->z, 1);
+
+ return 0;
+}