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

Packit Service 991b93
/* eddsa-verify.c
Packit Service 991b93
Packit Service 991b93
   Copyright (C) 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 <assert.h>
Packit Service 991b93
Packit Service 991b93
#include "eddsa.h"
Packit Service 991b93
#include "eddsa-internal.h"
Packit Service 991b93
Packit Service 991b93
#include <nettle/ecc.h>
Packit Service 991b93
#include "ecc-internal.h"
Packit Service 991b93
#include <nettle/nettle-meta.h>
Packit Service 991b93
Packit Service 991b93
/* Checks if x1/z1 == x2/z2 (mod p). Assumes z1 and z2 are
Packit Service 991b93
   non-zero. */
Packit Service 991b93
static int
Packit Service 991b93
equal_h (const struct ecc_modulo *p,
Packit Service 991b93
	 const mp_limb_t *x1, const mp_limb_t *z1,
Packit Service 991b93
	 const mp_limb_t *x2, const mp_limb_t *z2,
Packit Service 991b93
	 mp_limb_t *scratch)
Packit Service 991b93
{
Packit Service 991b93
#define t0 scratch
Packit Service 991b93
#define t1 (scratch + p->size)
Packit Service 991b93
Packit Service 991b93
  ecc_mod_mul (p, t0, x1, z2);
Packit Service 991b93
  if (mpn_cmp (t0, p->m, p->size) >= 0)
Packit Service 991b93
    mpn_sub_n (t0, t0, p->m, p->size);
Packit Service 991b93
Packit Service 991b93
  ecc_mod_mul (p, t1, x2, z1);
Packit Service 991b93
  if (mpn_cmp (t1, p->m, p->size) >= 0)
Packit Service 991b93
    mpn_sub_n (t1, t1, p->m, p->size);
Packit Service 991b93
Packit Service 991b93
  return mpn_cmp (t0, t1, p->size) == 0;
Packit Service 991b93
Packit Service 991b93
#undef t0
Packit Service 991b93
#undef t1
Packit Service 991b93
}
Packit Service 991b93
Packit Service 991b93
mp_size_t
Packit Service 991b93
_eddsa_verify_itch (const struct ecc_curve *ecc)
Packit Service 991b93
{
Packit Service 991b93
  assert (_eddsa_decompress_itch (ecc) <= ecc->mul_itch);
Packit Service 991b93
  return 8*ecc->p.size + ecc->mul_itch;
Packit Service 991b93
}
Packit Service 991b93
Packit Service 991b93
int
Packit Service 991b93
_eddsa_verify (const struct ecc_curve *ecc,
Packit Service 991b93
	       const struct ecc_eddsa *eddsa,
Packit Service 991b93
	       const uint8_t *pub,
Packit Service 991b93
	       const mp_limb_t *A,
Packit Service 991b93
	       void *ctx,
Packit Service 991b93
	       size_t length,
Packit Service 991b93
	       const uint8_t *msg,
Packit Service 991b93
	       const uint8_t *signature,
Packit Service 991b93
	       mp_limb_t *scratch)
Packit Service 991b93
{
Packit Service 991b93
  size_t nbytes;
Packit Service 991b93
#define R scratch
Packit Service 991b93
#define sp (scratch + 2*ecc->p.size)
Packit Service 991b93
#define hp (scratch + 3*ecc->p.size)
Packit Service 991b93
#define P (scratch + 5*ecc->p.size)
Packit Service 991b93
#define scratch_out (scratch + 8*ecc->p.size)
Packit Service 991b93
#define S R
Packit Service 991b93
#define hash ((uint8_t *) P)
Packit Service 991b93
Packit Service 991b93
  nbytes = 1 + ecc->p.bit_size / 8;
Packit Service 991b93
Packit Service 991b93
  /* Could maybe save some storage by delaying the R and S operations,
Packit Service 991b93
     but it makes sense to check them for validity up front. */
Packit Service 991b93
  if (!_eddsa_decompress (ecc, R, signature, R+2*ecc->p.size))
Packit Service 991b93
    return 0;
Packit Service 991b93
Packit Service 991b93
  mpn_set_base256_le (sp, ecc->q.size, signature + nbytes, nbytes);
Packit Service 991b93
  /* Check that s < q */
Packit Service 991b93
  if (mpn_cmp (sp, ecc->q.m, ecc->q.size) >= 0)
Packit Service 991b93
    return 0;
Packit Service 991b93
Packit Service 991b93
  eddsa->dom (ctx);
Packit Service 991b93
  eddsa->update (ctx, nbytes, signature);
Packit Service 991b93
  eddsa->update (ctx, nbytes, pub);
Packit Service 991b93
  eddsa->update (ctx, length, msg);
Packit Service 991b93
  eddsa->digest (ctx, 2*nbytes, hash);
Packit Service 991b93
  _eddsa_hash (&ecc->q, hp, 2*nbytes, hash);
Packit Service 991b93
Packit Service 991b93
  /* Compute h A + R - s G, which should be the neutral point */
Packit Service 991b93
  ecc->mul (ecc, P, hp, A, scratch_out);
Packit Service 991b93
  ecc->add_hh (ecc, P, P, R, scratch_out);
Packit Service 991b93
  /* Move out of the way. */
Packit Service 991b93
  mpn_copyi (hp, sp, ecc->q.size);
Packit Service 991b93
  ecc->mul_g (ecc, S, hp, scratch_out);
Packit Service 991b93
Packit Service 991b93
  return equal_h (&ecc->p,
Packit Service 991b93
		   P, P + 2*ecc->p.size,
Packit Service 991b93
		   S, S + 2*ecc->p.size, scratch_out)
Packit Service 991b93
    && equal_h (&ecc->p,
Packit Service 991b93
		P + ecc->p.size, P + 2*ecc->p.size,
Packit Service 991b93
		S + ecc->p.size, S + 2*ecc->p.size, scratch_out);
Packit Service 991b93
Packit Service 991b93
#undef R
Packit Service 991b93
#undef sp
Packit Service 991b93
#undef hp
Packit Service 991b93
#undef P
Packit Service 991b93
#undef S
Packit Service 991b93
}