aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNIIBE Yutaka <[email protected]>2021-10-21 04:28:04 +0000
committerNIIBE Yutaka <[email protected]>2021-10-21 04:28:04 +0000
commitd506ec268564b61c676786168292013e120dd9d8 (patch)
treee82dc23110a4c7a0aebae2481f10477e8b2a58b1
parentexperiment: Add copyright notice. (diff)
downloadgnupg-d506ec268564b61c676786168292013e120dd9d8.tar.gz
gnupg-d506ec268564b61c676786168292013e120dd9d8.zip
experiment: Generate new Ed448 signature.
Signed-off-by: NIIBE Yutaka <[email protected]>
-rw-r--r--g10/sign.c71
1 files changed, 69 insertions, 2 deletions
diff --git a/g10/sign.c b/g10/sign.c
index ea3de620b..c7bfff89c 100644
--- a/g10/sign.c
+++ b/g10/sign.c
@@ -404,6 +404,49 @@ hash_sigversion_to_magic (gcry_md_hd_t md, const PKT_signature *sig,
}
+/* Return SOS for MPI zero representation. */
+static gcry_mpi_t
+sos_zero (void)
+{
+ gcry_mpi_t a;
+
+ a = gcry_mpi_set_opaque (NULL, NULL, 0);
+ gcry_mpi_set_flag (a, GCRYMPI_FLAG_USER2);
+ return a;
+}
+
+
+/* Return SOS for Ed448 signature. */
+static gcry_mpi_t
+sos_sig_448 (gcry_mpi_t r, gcry_mpi_t s)
+{
+ gcry_mpi_t a;
+ unsigned char *p;
+ const unsigned char *p_r, *p_s;
+ unsigned int nbits;
+
+ p_r = gcry_mpi_get_opaque (r, &nbits);
+ if ((nbits+7)/8 != 57)
+ return NULL;
+
+ p_s = gcry_mpi_get_opaque (s, &nbits);
+ if ((nbits+7)/8 != 57)
+ return NULL;
+
+ p = xtrymalloc (1 + 57 + 57);
+ if (!p)
+ return NULL;
+
+ p[0] = 0x40;
+ memcpy (p+1, p_r, 57);
+ memcpy (p+1+57, p_s, 57);
+
+ a = gcry_mpi_set_opaque (NULL, p, 0);
+ gcry_mpi_set_flag (a, GCRYMPI_FLAG_USER2);
+ return a;
+}
+
+
/* Perform the sign operation. If CACHE_NONCE is given the agent is
* advised to use that cached passphrase for the key. SIGNHINTS has
* hints so that we can do some additional checks. */
@@ -509,9 +552,33 @@ do_sign (ctrl_t ctrl, PKT_public_key *pksk, PKT_signature *sig,
else if (pksk->pubkey_algo == PUBKEY_ALGO_ECDSA
|| pksk->pubkey_algo == PUBKEY_ALGO_EDDSA)
{
- err = sexp_extract_param_sos (s_sigval, "r", &sig->data[0]);
+ gcry_mpi_t sig_r = NULL;
+ gcry_mpi_t sig_s = NULL;
+
+ err = sexp_extract_param_sos (s_sigval, "r", &sig_r);
if (!err)
- err = sexp_extract_param_sos (s_sigval, "s", &sig->data[1]);
+ err = sexp_extract_param_sos (s_sigval, "s", &sig_s);
+
+ if (!err)
+ {
+ int is_ed448 = openpgp_oid_is_ed448 (pksk->pkey[0]);
+
+ if (is_ed448)
+ {
+ sig->data[0] = sos_sig_448 (sig_r, sig_s);
+ if (!sig->data[0])
+ err = gpg_error_from_syserror ();
+ else
+ sig->data[1] = sos_zero ();
+ mpi_release (sig_r);
+ mpi_release (sig_s);
+ }
+ else
+ {
+ sig->data[0] = sig_r;
+ sig->data[1] = sig_s;
+ }
+ }
}
else
{