Blame lib/nettle/ecc/ecc-gostdsa-verify.c

Packit Service 991b93
/* ecc-gostdsa-verify.c
Packit Service 991b93
Packit Service 991b93
   Copyright (C) 2015 Dmitry Eremin-Solenikov
Packit Service 991b93
   Copyright (C) 2013, 2014 Niels Möller
Packit Service 991b93
Packit Service 991b93
   This file is part of GNU Nettle.
Packit Service 991b93
Packit Service 991b93
   GNU Nettle is free software: you can redistribute it and/or
Packit Service 991b93
   modify it under the terms of either:
Packit Service 991b93
Packit Service 991b93
     * the GNU Lesser General Public License as published by the Free
Packit Service 991b93
       Software Foundation; either version 3 of the License, or (at your
Packit Service 991b93
       option) any later version.
Packit Service 991b93
Packit Service 991b93
   or
Packit Service 991b93
Packit Service 991b93
     * the GNU General Public License as published by the Free
Packit Service 991b93
       Software Foundation; either version 2 of the License, or (at your
Packit Service 991b93
       option) any later version.
Packit Service 991b93
Packit Service 991b93
   or both in parallel, as here.
Packit Service 991b93
Packit Service 991b93
   GNU Nettle is distributed in the hope that it will be useful,
Packit Service 991b93
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 991b93
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 991b93
   General Public License for more details.
Packit Service 991b93
Packit Service 991b93
   You should have received copies of the GNU General Public License and
Packit Service 991b93
   the GNU Lesser General Public License along with this program.  If
Packit Service 991b93
   not, see http://www.gnu.org/licenses/.
Packit Service 991b93
*/
Packit Service 991b93
Packit Service 991b93
#if HAVE_CONFIG_H
Packit Service 991b93
# include "config.h"
Packit Service 991b93
#endif
Packit Service 991b93
Packit Service 991b93
#include <stdlib.h>
Packit Service 991b93
Packit Service 991b93
#include "gostdsa.h"
Packit Service 991b93
#include "ecc-internal.h"
Packit Service 991b93
Packit Service 991b93
/* Low-level GOST DSA verify */
Packit Service 991b93
Packit Service 991b93
static int
Packit Service 991b93
ecdsa_in_range (const struct ecc_curve *ecc, const mp_limb_t *xp)
Packit Service 991b93
{
Packit Service 991b93
  return !mpn_zero_p (xp, ecc->p.size)
Packit Service 991b93
    && mpn_cmp (xp, ecc->q.m, ecc->p.size) < 0;
Packit Service 991b93
}
Packit Service 991b93
Packit Service 991b93
mp_size_t
Packit Service 991b93
ecc_gostdsa_verify_itch (const struct ecc_curve *ecc)
Packit Service 991b93
{
Packit Service 991b93
  /* Largest storage need is for the ecc->mul call. */
Packit Service 991b93
  return 5*ecc->p.size + ecc->mul_itch;
Packit Service 991b93
}
Packit Service 991b93
Packit Service 991b93
/* FIXME: Use faster primitives, not requiring side-channel silence. */
Packit Service 991b93
int
Packit Service 991b93
ecc_gostdsa_verify (const struct ecc_curve *ecc,
Packit Service 991b93
		  const mp_limb_t *pp, /* Public key */
Packit Service 991b93
		  size_t length, const uint8_t *digest,
Packit Service 991b93
		  const mp_limb_t *rp, const mp_limb_t *sp,
Packit Service 991b93
		  mp_limb_t *scratch)
Packit Service 991b93
{
Packit Service 991b93
  /* Procedure, according to GOST R 34.10. q denotes the group
Packit Service 991b93
     order.
Packit Service 991b93
Packit Service 991b93
     1. Check 0 < r, s < q.
Packit Service 991b93
Packit Service 991b93
     2. v <-- h^{-1}  (mod q)
Packit Service 991b93
Packit Service 991b93
     3. z1  <-- s * v (mod q)
Packit Service 991b93
Packit Service 991b93
     4. z2  <-- -r * v (mod q)
Packit Service 991b93
Packit Service 991b93
     5. R = u1 G + u2 Y
Packit Service 991b93
Packit Service 991b93
     6. Signature is valid if R_x = r (mod q).
Packit Service 991b93
  */
Packit Service 991b93
Packit Service 991b93
#define hp (scratch)
Packit Service 991b93
#define vp (scratch + ecc->p.size)
Packit Service 991b93
#define z1 (scratch + 3*ecc->p.size)
Packit Service 991b93
#define z2 (scratch + 4*ecc->p.size)
Packit Service 991b93
Packit Service 991b93
#define P1 (scratch + 4*ecc->p.size)
Packit Service 991b93
#define P2 (scratch)
Packit Service 991b93
Packit Service 991b93
Packit Service 991b93
  if (! (ecdsa_in_range (ecc, rp)
Packit Service 991b93
	 && ecdsa_in_range (ecc, sp)))
Packit Service 991b93
    return 0;
Packit Service 991b93
Packit Service 991b93
  gost_hash (&ecc->q, hp, length, digest);
Packit Service 991b93
Packit Service 991b93
  if (mpn_zero_p (hp, ecc->p.size))
Packit Service 991b93
    mpn_add_1 (hp, hp, ecc->p.size, 1);
Packit Service 991b93
Packit Service 991b93
  /* Compute v */
Packit Service 991b93
  ecc->q.invert (&ecc->q, vp, hp, vp + 2*ecc->p.size);
Packit Service 991b93
Packit Service 991b93
  /* z1 = s / h, P1 = z1 * G */
Packit Service 991b93
  ecc_mod_mul (&ecc->q, z1, sp, vp);
Packit Service 991b93
Packit Service 991b93
  /* z2 = - r / h, P2 = z2 * Y */
Packit Service 991b93
  ecc_mod_mul (&ecc->q, z2, rp, vp);
Packit Service 991b93
  mpn_sub_n (z2, ecc->q.m, z2, ecc->p.size);
Packit Service 991b93
Packit Service 991b93
   /* Total storage: 5*ecc->p.size + ecc->mul_itch */
Packit Service 991b93
  ecc->mul (ecc, P2, z2, pp, z2 + ecc->p.size);
Packit Service 991b93
Packit Service 991b93
  /* Total storage: 7*ecc->p.size + ecc->mul_g_itch (ecc->p.size) */
Packit Service 991b93
  ecc->mul_g (ecc, P1, z1, P1 + 3*ecc->p.size);
Packit Service 991b93
Packit Service 991b93
  /* Total storage: 6*ecc->p.size + ecc->add_hhh_itch */
Packit Service 991b93
  ecc->add_hhh (ecc, P1, P1, P2, P1 + 3*ecc->p.size);
Packit Service 991b93
Packit Service 991b93
  /* x coordinate only, modulo q */
Packit Service 991b93
  ecc->h_to_a (ecc, 2, P2, P1, P1 + 3*ecc->p.size);
Packit Service 991b93
Packit Service 991b93
  return (mpn_cmp (rp, P2, ecc->p.size) == 0);
Packit Service 991b93
#undef P2
Packit Service 991b93
#undef P1
Packit Service 991b93
#undef z2
Packit Service 991b93
#undef z1
Packit Service 991b93
#undef hp
Packit Service 991b93
#undef vp
Packit Service 991b93
}