ecc: Refactor ecc.c
[libgcrypt.git] / cipher / ecc-eddsa.c
1 /* ecc-eddsa.c  -  Elliptic Curve EdDSA signatures
2  * Copyright (C) 2013 g10 Code GmbH
3  *
4  * This file is part of Libgcrypt.
5  *
6  * Libgcrypt is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as
8  * published by the Free Software Foundation; either version 2.1 of
9  * the License, or (at your option) any later version.
10  *
11  * Libgcrypt is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <config.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <errno.h>
25
26 #include "g10lib.h"
27 #include "mpi.h"
28 #include "cipher.h"
29 #include "context.h"
30 #include "ec-context.h"
31 #include "ecc-common.h"
32
33
34 \f
35 static void
36 reverse_buffer (unsigned char *buffer, unsigned int length)
37 {
38   unsigned int tmp, i;
39
40   for (i=0; i < length/2; i++)
41     {
42       tmp = buffer[i];
43       buffer[i] = buffer[length-1-i];
44       buffer[length-1-i] = tmp;
45     }
46 }
47
48
49 \f
50 /* Encode MPI using the EdDSA scheme.  MINLEN specifies the required
51    length of the buffer in bytes.  On success 0 is returned an a
52    malloced buffer with the encoded point is stored at R_BUFFER; the
53    length of this buffer is stored at R_BUFLEN.  */
54 static gpg_err_code_t
55 eddsa_encodempi (gcry_mpi_t mpi, unsigned int minlen,
56                  unsigned char **r_buffer, unsigned int *r_buflen)
57 {
58   unsigned char *rawmpi;
59   unsigned int rawmpilen;
60
61   rawmpi = _gcry_mpi_get_buffer (mpi, minlen, &rawmpilen, NULL);
62   if (!rawmpi)
63     return gpg_err_code_from_syserror ();
64
65   *r_buffer = rawmpi;
66   *r_buflen = rawmpilen;
67   return 0;
68 }
69
70
71 /* Encode (X,Y) using the EdDSA scheme.  MINLEN is the required length
72    in bytes for the result.  On success 0 is returned and a malloced
73    buffer with the encoded point is stored at R_BUFFER; the length of
74    this buffer is stored at R_BUFLEN.  */
75 static gpg_err_code_t
76 eddsa_encode_x_y (gcry_mpi_t x, gcry_mpi_t y, unsigned int minlen,
77                   unsigned char **r_buffer, unsigned int *r_buflen)
78 {
79   unsigned char *rawmpi;
80   unsigned int rawmpilen;
81
82   rawmpi = _gcry_mpi_get_buffer (y, minlen, &rawmpilen, NULL);
83   if (!rawmpi)
84     return gpg_err_code_from_syserror ();
85   if (mpi_test_bit (x, 0) && rawmpilen)
86     rawmpi[rawmpilen - 1] |= 0x80;  /* Set sign bit.  */
87
88   *r_buffer = rawmpi;
89   *r_buflen = rawmpilen;
90   return 0;
91 }
92
93 /* Encode POINT using the EdDSA scheme.  X and Y are either scratch
94    variables supplied by the caller or NULL.  CTX is the usual
95    context.  On success 0 is returned and a malloced buffer with the
96    encoded point is stored at R_BUFFER; the length of this buffer is
97    stored at R_BUFLEN.  */
98 gpg_err_code_t
99 _gcry_ecc_eddsa_encodepoint (mpi_point_t point, mpi_ec_t ec,
100                              gcry_mpi_t x_in, gcry_mpi_t y_in,
101                              unsigned char **r_buffer, unsigned int *r_buflen)
102 {
103   gpg_err_code_t rc;
104   gcry_mpi_t x, y;
105
106   x = x_in? x_in : mpi_new (0);
107   y = y_in? y_in : mpi_new (0);
108
109   if (_gcry_mpi_ec_get_affine (x, y, point, ec))
110     {
111       log_error ("eddsa_encodepoint: Failed to get affine coordinates\n");
112       rc = GPG_ERR_INTERNAL;
113     }
114   else
115     rc = eddsa_encode_x_y (x, y, ec->nbits/8, r_buffer, r_buflen);
116
117   if (!x_in)
118     mpi_free (x);
119   if (!y_in)
120     mpi_free (y);
121   return rc;
122 }
123
124
125 /* Decode the EdDSA style encoded PK and set it into RESULT.  CTX is
126    the usual curve context.  If R_ENCPK is not NULL, the encoded PK is
127    stored at that address; this is a new copy to be released by the
128    caller.  In contrast to the supplied PK, this is not an MPI and
129    thus guarnateed to be properly padded.  R_ENCPKLEN received the
130    length of that encoded key.  */
131 gpg_err_code_t
132 _gcry_ecc_eddsa_decodepoint (gcry_mpi_t pk, mpi_ec_t ctx, mpi_point_t result,
133                              unsigned char **r_encpk, unsigned int *r_encpklen)
134 {
135   gpg_err_code_t rc;
136   unsigned char *rawmpi;
137   unsigned int rawmpilen;
138   gcry_mpi_t yy, t, x, p1, p2, p3;
139   int sign;
140
141   if (mpi_is_opaque (pk))
142     {
143       const unsigned char *buf;
144
145       buf = gcry_mpi_get_opaque (pk, &rawmpilen);
146       if (!buf)
147         return GPG_ERR_INV_OBJ;
148       rawmpilen = (rawmpilen + 7)/8;
149
150       /* First check whether the public key has been given in standard
151          uncompressed format.  No need to recover x in this case.
152          Detection is easy: The size of the buffer will be odd and the
153          first byte be 0x04.  */
154       if (rawmpilen > 1 && buf[0] == 0x04 && (rawmpilen%2))
155         {
156           gcry_mpi_t y;
157
158           rc = gcry_mpi_scan (&x, GCRYMPI_FMT_STD,
159                               buf+1, (rawmpilen-1)/2, NULL);
160           if (rc)
161             return rc;
162           rc = gcry_mpi_scan (&y, GCRYMPI_FMT_STD,
163                               buf+1+(rawmpilen-1)/2, (rawmpilen-1)/2, NULL);
164           if (rc)
165             {
166               mpi_free (x);
167               return rc;
168             }
169
170           if (r_encpk)
171             {
172               rc = eddsa_encode_x_y (x, y, ctx->nbits/8, r_encpk, r_encpklen);
173               if (rc)
174                 {
175                   mpi_free (x);
176                   mpi_free (y);
177                   return rc;
178                 }
179             }
180           mpi_snatch (result->x, x);
181           mpi_snatch (result->y, y);
182           mpi_set_ui (result->z, 1);
183           return 0;
184         }
185
186       /* EdDSA compressed point.  */
187       rawmpi = gcry_malloc (rawmpilen? rawmpilen:1);
188       if (!rawmpi)
189         return gpg_err_code_from_syserror ();
190       memcpy (rawmpi, buf, rawmpilen);
191       reverse_buffer (rawmpi, rawmpilen);
192     }
193   else
194     {
195       /* Note: Without using an opaque MPI it is not reliable possible
196          to find out whether the public key has been given in
197          uncompressed format.  Thus we expect EdDSA format here.  */
198       rawmpi = _gcry_mpi_get_buffer (pk, ctx->nbits/8, &rawmpilen, NULL);
199       if (!rawmpi)
200         return gpg_err_code_from_syserror ();
201     }
202
203   if (rawmpilen)
204     {
205       sign = !!(rawmpi[0] & 0x80);
206       rawmpi[0] &= 0x7f;
207     }
208   else
209     sign = 0;
210   _gcry_mpi_set_buffer (result->y, rawmpi, rawmpilen, 0);
211   if (r_encpk)
212     {
213       /* Revert to little endian.  */
214       if (sign && rawmpilen)
215         rawmpi[0] |= 0x80;
216       reverse_buffer (rawmpi, rawmpilen);
217       *r_encpk = rawmpi;
218       if (r_encpklen)
219         *r_encpklen = rawmpilen;
220     }
221   else
222     gcry_free (rawmpi);
223
224   /* Now recover X.  */
225   /* t = (y^2-1) · ((b*y^2+1)^{p-2} mod p) */
226   x = mpi_new (0);
227   yy = mpi_new (0);
228   mpi_mul (yy, result->y, result->y);
229   t = mpi_copy (yy);
230   mpi_mul (t, t, ctx->b);
231   mpi_add_ui (t, t, 1);
232   p2 = mpi_copy (ctx->p);
233   mpi_sub_ui (p2, p2, 2);
234   mpi_powm (t, t, p2, ctx->p);
235
236   mpi_sub_ui (yy, yy, 1);
237   mpi_mul (t, yy, t);
238
239   /* x = t^{(p+3)/8} mod p */
240   p3 = mpi_copy (ctx->p);
241   mpi_add_ui (p3, p3, 3);
242   mpi_fdiv_q (p3, p3, mpi_const (MPI_C_EIGHT));
243   mpi_powm (x, t, p3, ctx->p);
244
245   /* (x^2 - t) % p != 0 ? x = (x*(2^{(p-1)/4} mod p)) % p */
246   mpi_mul (yy, x, x);
247   mpi_subm (yy, yy, t, ctx->p);
248   if (mpi_cmp_ui (yy, 0))
249     {
250       p1 = mpi_copy (ctx->p);
251       mpi_sub_ui (p1, p1, 1);
252       mpi_fdiv_q (p1, p1, mpi_const (MPI_C_FOUR));
253       mpi_powm (yy, mpi_const (MPI_C_TWO), p1, ctx->p);
254       mpi_mulm (x, x, yy, ctx->p);
255     }
256   else
257     p1 = NULL;
258
259   /* is_odd(x) ? x = p-x */
260   if (mpi_test_bit (x, 0))
261     mpi_sub (x, ctx->p, x);
262
263   /* lowbit(x) != highbit(input) ?  x = p-x */
264   if (mpi_test_bit (x, 0) != sign)
265     mpi_sub (x, ctx->p, x);
266
267   mpi_set (result->x, x);
268   mpi_set_ui (result->z, 1);
269
270   gcry_mpi_release (x);
271   gcry_mpi_release (yy);
272   gcry_mpi_release (t);
273   gcry_mpi_release (p3);
274   gcry_mpi_release (p2);
275   gcry_mpi_release (p1);
276
277   return 0;
278 }
279
280
281 /* Ed25519 version of the key generation.  */
282 gpg_err_code_t
283 _gcry_ecc_eddsa_genkey (ECC_secret_key *sk, elliptic_curve_t *E, mpi_ec_t ctx,
284                         gcry_random_level_t random_level)
285 {
286   gpg_err_code_t rc;
287   int b = 256/8;             /* The only size we currently support.  */
288   gcry_mpi_t a, x, y;
289   mpi_point_struct Q;
290   char *dbuf;
291   size_t dlen;
292   gcry_buffer_t hvec[1];
293   unsigned char *hash_d = NULL;
294
295   point_init (&Q);
296   memset (hvec, 0, sizeof hvec);
297
298   a = mpi_snew (0);
299   x = mpi_new (0);
300   y = mpi_new (0);
301
302   /* Generate a secret.  */
303   hash_d = gcry_malloc_secure (2*b);
304   if (!hash_d)
305     {
306       rc = gpg_error_from_syserror ();
307       goto leave;
308     }
309   dlen = b;
310   dbuf = gcry_random_bytes_secure (dlen, random_level);
311
312   /* Compute the A value.  */
313   hvec[0].data = dbuf;
314   hvec[0].len = dlen;
315   rc = _gcry_md_hash_buffers (GCRY_MD_SHA512, 0, hash_d, hvec, 1);
316   if (rc)
317     goto leave;
318   sk->d = _gcry_mpi_set_opaque (NULL, dbuf, dlen*8);
319   dbuf = NULL;
320   reverse_buffer (hash_d, 32);  /* Only the first half of the hash.  */
321   hash_d[0] = (hash_d[0] & 0x7f) | 0x40;
322   hash_d[31] &= 0xf8;
323   _gcry_mpi_set_buffer (a, hash_d, 32, 0);
324   gcry_free (hash_d); hash_d = NULL;
325   /* log_printmpi ("ecgen         a", a); */
326
327   /* Compute Q.  */
328   _gcry_mpi_ec_mul_point (&Q, a, &E->G, ctx);
329   if (DBG_CIPHER)
330     log_printpnt ("ecgen      pk", &Q, ctx);
331
332   /* Copy the stuff to the key structures. */
333   sk->E.model = E->model;
334   sk->E.dialect = E->dialect;
335   sk->E.p = mpi_copy (E->p);
336   sk->E.a = mpi_copy (E->a);
337   sk->E.b = mpi_copy (E->b);
338   point_init (&sk->E.G);
339   point_set (&sk->E.G, &E->G);
340   sk->E.n = mpi_copy (E->n);
341   point_init (&sk->Q);
342   point_set (&sk->Q, &Q);
343
344  leave:
345   gcry_mpi_release (a);
346   gcry_mpi_release (x);
347   gcry_mpi_release (y);
348   gcry_free (hash_d);
349   return rc;
350 }
351
352
353 /* Compute an EdDSA signature. See:
354  *   [ed25519] 23pp. (PDF) Daniel J. Bernstein, Niels Duif, Tanja
355  *   Lange, Peter Schwabe, Bo-Yin Yang. High-speed high-security
356  *   signatures.  Journal of Cryptographic Engineering 2 (2012), 77-89.
357  *   Document ID: a1a62a2f76d23f65d622484ddd09caf8.
358  *   URL: http://cr.yp.to/papers.html#ed25519. Date: 2011.09.26.
359  *
360  * Despite that this function requires the specification of a hash
361  * algorithm, we only support what has been specified by the paper.
362  * This may change in the future.  Note that we don't check the used
363  * curve; the user is responsible to use Ed25519.
364  *
365  * Return the signature struct (r,s) from the message hash.  The caller
366  * must have allocated R_R and S.
367  */
368 gpg_err_code_t
369 _gcry_ecc_eddsa_sign (gcry_mpi_t input, ECC_secret_key *skey,
370                       gcry_mpi_t r_r, gcry_mpi_t s, int hashalgo, gcry_mpi_t pk)
371 {
372   int rc;
373   mpi_ec_t ctx = NULL;
374   int b;
375   unsigned int tmp;
376   unsigned char *digest;
377   gcry_buffer_t hvec[3];
378   const void *mbuf;
379   size_t mlen;
380   unsigned char *rawmpi = NULL;
381   unsigned int rawmpilen;
382   unsigned char *encpk = NULL; /* Encoded public key.  */
383   unsigned int encpklen;
384   mpi_point_struct I;          /* Intermediate value.  */
385   mpi_point_struct Q;          /* Public key.  */
386   gcry_mpi_t a, x, y, r;
387
388   memset (hvec, 0, sizeof hvec);
389
390   if (!mpi_is_opaque (input))
391     return GPG_ERR_INV_DATA;
392   if (hashalgo != GCRY_MD_SHA512)
393     return GPG_ERR_DIGEST_ALGO;
394
395   /* Initialize some helpers.  */
396   point_init (&I);
397   point_init (&Q);
398   a = mpi_snew (0);
399   x = mpi_new (0);
400   y = mpi_new (0);
401   r = mpi_new (0);
402   ctx = _gcry_mpi_ec_p_internal_new (skey->E.model, skey->E.dialect,
403                                      skey->E.p, skey->E.a, skey->E.b);
404   b = (ctx->nbits+7)/8;
405   if (b != 256/8)
406     return GPG_ERR_INTERNAL; /* We only support 256 bit. */
407
408   digest = gcry_calloc_secure (2, b);
409   if (!digest)
410     {
411       rc = gpg_err_code_from_syserror ();
412       goto leave;
413     }
414
415   /* Hash the secret key.  We clear DIGEST so we can use it as input
416      to left pad the key with zeroes for hashing.  */
417   rawmpi = _gcry_mpi_get_buffer (skey->d, 0, &rawmpilen, NULL);
418   if (!rawmpi)
419     {
420       rc = gpg_err_code_from_syserror ();
421       goto leave;
422     }
423   hvec[0].data = digest;
424   hvec[0].off = 0;
425   hvec[0].len = b > rawmpilen? b - rawmpilen : 0;
426   hvec[1].data = rawmpi;
427   hvec[1].off = 0;
428   hvec[1].len = rawmpilen;
429   rc = _gcry_md_hash_buffers (hashalgo, 0, digest, hvec, 2);
430   gcry_free (rawmpi); rawmpi = NULL;
431   if (rc)
432     goto leave;
433
434   /* Compute the A value (this modifies DIGEST).  */
435   reverse_buffer (digest, 32);  /* Only the first half of the hash.  */
436   digest[0] = (digest[0] & 0x7f) | 0x40;
437   digest[31] &= 0xf8;
438   _gcry_mpi_set_buffer (a, digest, 32, 0);
439
440   /* Compute the public key if it has not been supplied as optional
441      parameter.  */
442   if (pk)
443     {
444       rc = _gcry_ecc_eddsa_decodepoint (pk, ctx, &Q,  &encpk, &encpklen);
445       if (rc)
446         goto leave;
447       if (DBG_CIPHER)
448         log_printhex ("* e_pk", encpk, encpklen);
449       if (!_gcry_mpi_ec_curve_point (&Q, ctx))
450         {
451           rc = GPG_ERR_BROKEN_PUBKEY;
452           goto leave;
453         }
454     }
455   else
456     {
457       _gcry_mpi_ec_mul_point (&Q, a, &skey->E.G, ctx);
458       rc = _gcry_ecc_eddsa_encodepoint (&Q, ctx, x, y, &encpk, &encpklen);
459       if (rc)
460         goto leave;
461       if (DBG_CIPHER)
462         log_printhex ("  e_pk", encpk, encpklen);
463     }
464
465   /* Compute R.  */
466   mbuf = gcry_mpi_get_opaque (input, &tmp);
467   mlen = (tmp +7)/8;
468   if (DBG_CIPHER)
469     log_printhex ("     m", mbuf, mlen);
470
471   hvec[0].data = digest;
472   hvec[0].off  = 32;
473   hvec[0].len  = 32;
474   hvec[1].data = (char*)mbuf;
475   hvec[1].len  = mlen;
476   rc = _gcry_md_hash_buffers (hashalgo, 0, digest, hvec, 2);
477   if (rc)
478     goto leave;
479   reverse_buffer (digest, 64);
480   if (DBG_CIPHER)
481     log_printhex ("     r", digest, 64);
482   _gcry_mpi_set_buffer (r, digest, 64, 0);
483   _gcry_mpi_ec_mul_point (&I, r, &skey->E.G, ctx);
484   if (DBG_CIPHER)
485     log_printpnt ("   r", &I, ctx);
486
487   /* Convert R into affine coordinates and apply encoding.  */
488   rc = _gcry_ecc_eddsa_encodepoint (&I, ctx, x, y, &rawmpi, &rawmpilen);
489   if (rc)
490     goto leave;
491   if (DBG_CIPHER)
492     log_printhex ("   e_r", rawmpi, rawmpilen);
493
494   /* S = r + a * H(encodepoint(R) + encodepoint(pk) + m) mod n  */
495   hvec[0].data = rawmpi;  /* (this is R) */
496   hvec[0].off  = 0;
497   hvec[0].len  = rawmpilen;
498   hvec[1].data = encpk;
499   hvec[1].off  = 0;
500   hvec[1].len  = encpklen;
501   hvec[2].data = (char*)mbuf;
502   hvec[2].off  = 0;
503   hvec[2].len  = mlen;
504   rc = _gcry_md_hash_buffers (hashalgo, 0, digest, hvec, 3);
505   if (rc)
506     goto leave;
507
508   /* No more need for RAWMPI thus we now transfer it to R_R.  */
509   gcry_mpi_set_opaque (r_r, rawmpi, rawmpilen*8);
510   rawmpi = NULL;
511
512   reverse_buffer (digest, 64);
513   if (DBG_CIPHER)
514     log_printhex (" H(R+)", digest, 64);
515   _gcry_mpi_set_buffer (s, digest, 64, 0);
516   mpi_mulm (s, s, a, skey->E.n);
517   mpi_addm (s, s, r, skey->E.n);
518   rc = eddsa_encodempi (s, b, &rawmpi, &rawmpilen);
519   if (rc)
520     goto leave;
521   if (DBG_CIPHER)
522     log_printhex ("   e_s", rawmpi, rawmpilen);
523   gcry_mpi_set_opaque (s, rawmpi, rawmpilen*8);
524   rawmpi = NULL;
525
526   rc = 0;
527
528  leave:
529   gcry_mpi_release (a);
530   gcry_mpi_release (x);
531   gcry_mpi_release (y);
532   gcry_mpi_release (r);
533   gcry_free (digest);
534   _gcry_mpi_ec_free (ctx);
535   point_free (&I);
536   point_free (&Q);
537   gcry_free (encpk);
538   gcry_free (rawmpi);
539   return rc;
540 }
541
542
543 /* Verify an EdDSA signature.  See sign_eddsa for the reference.
544  * Check if R_IN and S_IN verifies INPUT.  PKEY has the curve
545  * parameters and PK is the EdDSA style encoded public key.
546  */
547 gpg_err_code_t
548 _gcry_ecc_eddsa_verify (gcry_mpi_t input, ECC_public_key *pkey,
549                         gcry_mpi_t r_in, gcry_mpi_t s_in, int hashalgo,
550                         gcry_mpi_t pk)
551 {
552   int rc;
553   mpi_ec_t ctx = NULL;
554   int b;
555   unsigned int tmp;
556   mpi_point_struct Q;          /* Public key.  */
557   unsigned char *encpk = NULL; /* Encoded public key.  */
558   unsigned int encpklen;
559   const void *mbuf, *rbuf;
560   unsigned char *tbuf = NULL;
561   size_t mlen, rlen;
562   unsigned int tlen;
563   unsigned char digest[64];
564   gcry_buffer_t hvec[3];
565   gcry_mpi_t h, s;
566   mpi_point_struct Ia, Ib;
567
568   if (!mpi_is_opaque (input) || !mpi_is_opaque (r_in) || !mpi_is_opaque (s_in))
569     return GPG_ERR_INV_DATA;
570   if (hashalgo != GCRY_MD_SHA512)
571     return GPG_ERR_DIGEST_ALGO;
572
573   point_init (&Q);
574   point_init (&Ia);
575   point_init (&Ib);
576   h = mpi_new (0);
577   s = mpi_new (0);
578
579   ctx = _gcry_mpi_ec_p_internal_new (pkey->E.model, pkey->E.dialect,
580                                      pkey->E.p, pkey->E.a, pkey->E.b);
581   b = ctx->nbits/8;
582   if (b != 256/8)
583     return GPG_ERR_INTERNAL; /* We only support 256 bit. */
584
585   /* Decode and check the public key.  */
586   rc = _gcry_ecc_eddsa_decodepoint (pk, ctx, &Q, &encpk, &encpklen);
587   if (rc)
588     goto leave;
589   if (!_gcry_mpi_ec_curve_point (&Q, ctx))
590     {
591       rc = GPG_ERR_BROKEN_PUBKEY;
592       goto leave;
593     }
594   if (DBG_CIPHER)
595     log_printhex ("  e_pk", encpk, encpklen);
596   if (encpklen != b)
597     {
598       rc = GPG_ERR_INV_LENGTH;
599       goto leave;
600     }
601
602   /* Convert the other input parameters.  */
603   mbuf = gcry_mpi_get_opaque (input, &tmp);
604   mlen = (tmp +7)/8;
605   if (DBG_CIPHER)
606     log_printhex ("     m", mbuf, mlen);
607   rbuf = gcry_mpi_get_opaque (r_in, &tmp);
608   rlen = (tmp +7)/8;
609   if (DBG_CIPHER)
610     log_printhex ("     r", rbuf, rlen);
611   if (rlen != b)
612     {
613       rc = GPG_ERR_INV_LENGTH;
614       goto leave;
615     }
616
617   /* h = H(encodepoint(R) + encodepoint(pk) + m)  */
618   hvec[0].data = (char*)rbuf;
619   hvec[0].off  = 0;
620   hvec[0].len  = rlen;
621   hvec[1].data = encpk;
622   hvec[1].off  = 0;
623   hvec[1].len  = encpklen;
624   hvec[2].data = (char*)mbuf;
625   hvec[2].off  = 0;
626   hvec[2].len  = mlen;
627   rc = _gcry_md_hash_buffers (hashalgo, 0, digest, hvec, 3);
628   if (rc)
629     goto leave;
630   reverse_buffer (digest, 64);
631   if (DBG_CIPHER)
632     log_printhex (" H(R+)", digest, 64);
633   _gcry_mpi_set_buffer (h, digest, 64, 0);
634
635   /* According to the paper the best way for verification is:
636          encodepoint(sG - h·Q) = encodepoint(r)
637      because we don't need to decode R. */
638   {
639     void *sbuf;
640     unsigned int slen;
641
642     sbuf = _gcry_mpi_get_opaque_copy (s_in, &tmp);
643     slen = (tmp +7)/8;
644     reverse_buffer (sbuf, slen);
645     if (DBG_CIPHER)
646       log_printhex ("     s", sbuf, slen);
647     _gcry_mpi_set_buffer (s, sbuf, slen, 0);
648     gcry_free (sbuf);
649     if (slen != b)
650       {
651         rc = GPG_ERR_INV_LENGTH;
652         goto leave;
653       }
654   }
655
656   _gcry_mpi_ec_mul_point (&Ia, s, &pkey->E.G, ctx);
657   _gcry_mpi_ec_mul_point (&Ib, h, &Q, ctx);
658   _gcry_mpi_neg (Ib.x, Ib.x);
659   _gcry_mpi_ec_add_points (&Ia, &Ia, &Ib, ctx);
660   rc = _gcry_ecc_eddsa_encodepoint (&Ia, ctx, s, h, &tbuf, &tlen);
661   if (rc)
662     goto leave;
663   if (tlen != rlen || memcmp (tbuf, rbuf, tlen))
664     {
665       rc = GPG_ERR_BAD_SIGNATURE;
666       goto leave;
667     }
668
669   rc = 0;
670
671  leave:
672   gcry_free (encpk);
673   gcry_free (tbuf);
674   _gcry_mpi_ec_free (ctx);
675   gcry_mpi_release (s);
676   gcry_mpi_release (h);
677   point_free (&Ia);
678   point_free (&Ib);
679   point_free (&Q);
680   return rc;
681 }