Hello,

чт, 16 янв. 2020 г. в 21:36, Niels Möller <[email protected]>:
> > From: Dmitry Eremin-Solenikov <[email protected]>
> >
> > Add GOST Digital Signature Algorithms support according to GOST R
> > 34.10-2001/-2012. English translations of these standards are provided
> > as RFC 5832 and RFC 7091.
>
> I've merged the first two patches to a branch ecc-gost. A few comments on
> the signature implementation.

Thank you!



> > +void
> > +ecc_gostdsa_sign (const struct ecc_curve *ecc,
> > +             const mp_limb_t *zp,
> > +             const mp_limb_t *kp,
> > +             size_t length, const uint8_t *digest,
> > +             mp_limb_t *rp, mp_limb_t *sp,
> > +             mp_limb_t *scratch)
> > +{
> > +#define P        scratch
> > +#define hp       (scratch + 4*ecc->p.size)
> > +#define tp       (scratch + 2*ecc->p.size)
> > +#define t2p      scratch
> > +  /* Procedure, according to GOST 34.10. q denotes the group
> > +     order.
> > +
> > +     1. k <-- uniformly random, 0 < k < q
> > +
> > +     2. C <-- (c_x, c_y) = k g
> > +
> > +     3. r <-- c_x mod q
> > +
> > +     4. s <-- (r*z + k*h) mod q.
> > +  */
>
> So no modular inversion in the signature operation? That's an
> improvement over NIST's DSA and ECDSA.

exactly.

> > diff --git a/ecc-gostdsa-verify.c b/ecc-gostdsa-verify.c
> > new file mode 100644
> > index 000000000000..4358132b2bf6
> > --- /dev/null
> > +++ b/ecc-gostdsa-verify.c
> > +/* FIXME: Use faster primitives, not requiring side-channel silence. */
> > +int
> > +ecc_gostdsa_verify (const struct ecc_curve *ecc,
> > +               const mp_limb_t *pp, /* Public key */
> > +               size_t length, const uint8_t *digest,
> > +               const mp_limb_t *rp, const mp_limb_t *sp,
> > +               mp_limb_t *scratch)
> > +{
> > +  /* Procedure, according to GOST R 34.10. q denotes the group
> > +     order.
> > +
> > +     1. Check 0 < r, s < q.
> > +
> > +     2. v <-- h^{-1}  (mod q)
> > +
> > +     3. z1  <-- s * v (mod q)
> > +
> > +     4. z2  <-- -r * v (mod q)
> > +
> > +     5. R = u1 G + u2 Y
> > +
> > +     6. Signature is valid if R_x = r (mod q).
> > +  */
> > +
> > +#define hp (scratch)
> > +#define vp (scratch + ecc->p.size)
> > +#define z1 (scratch + 3*ecc->p.size)
> > +#define z2 (scratch + 4*ecc->p.size)
> > +
> > +#define P1 (scratch + 4*ecc->p.size)
> > +#define P2 (scratch)
> > +
> > +
> > +  if (! (ecdsa_in_range (ecc, rp)
> > +      && ecdsa_in_range (ecc, sp)))
> > +    return 0;
> > +
> > +  gost_hash (&ecc->q, hp, length, digest);
> > +
> > +  if (mpn_zero_p (hp, ecc->p.size))
> > +    mpn_add_1 (hp, hp, ecc->p.size, 1);
> > +
> > +  /* Compute v */
> > +  ecc->q.invert (&ecc->q, vp, hp, vp + 2*ecc->p.size);
>
> Comment about faster primitives applies particularly to this modular
> inversion. Using mpn_gcdext, which isn't side-channel silent, is likely
> significantly faster (but a bit different interface). Would be
> interesting to add to hogweed-benchmark, to compare to other ecc
> signatures.

I'll take a look at this later.

> > diff --git a/ecc-hash.c b/ecc-hash.c
> > index 4e830a514ac4..07877110263f 100644
> > --- a/ecc-hash.c
> > +++ b/ecc-hash.c
> > @@ -62,3 +62,14 @@ ecc_hash (const struct ecc_modulo *m,
> >      /* We got a few extra bits, at the low end. Discard them. */
> >      mpn_rshift (hp, hp, m->size + 1, 8*length - m->bit_size);
> >  }
> > +
> > +void
> > +gost_hash (const struct ecc_modulo *m,
> > +        mp_limb_t *hp,
> > +        size_t length, const uint8_t *digest)
> > +{
> > +  if (length > ((size_t) m->bit_size + 7) / 8)
> > +    length = (m->bit_size + 7) / 8;
> > +
> > +  mpn_set_base256_le (hp, m->size + 1, digest, length);
> > +}
>
> It looks a bit strange to truncate the digest in this function, but I
> see that's the same as ecc_hash just above. Do you need to also handle
> the case of left-over bits, 8*length > m->bit_size?

Technically there should be no need to truncate, as the standard
enforces using  specific hash functions. I've copied this from
ecc_hash just to be on a safe side.

> Are the details very specific to gost, or could the helper be renamed
> ecc_hash_le ?

Just there is no point in doing hash_le for the generic ecc case.

> What are typical values of length, compared to the prime size?

256-bit curve, 256-bit prime, 256-bit hash function
512-bit curve, 512-bit prime, 512-bit hash function

> > --- /dev/null
> > +++ b/gostdsa.h
> > @@ -0,0 +1,102 @@
> [...]
> > +
> > +/* Development of Nettle's ECC support was funded by the .SE Internet 
> > Fund. */
>
> Left-over note?

Oops, dropped in v5.

> > diff --git a/testsuite/testutils.h b/testsuite/testutils.h
> > index f4ea38da9deb..cef7f4011a7c 100644
> > --- a/testsuite/testutils.h
> > +++ b/testsuite/testutils.h
> > @@ -22,6 +22,7 @@
> >  # include "ecc.h"
> >  # include "ecc-internal.h"
> >  # include "ecdsa.h"
> > +# include "gostdsa.h"
> >  # include "gmp-glue.h"
> >  # if NETTLE_USE_MINI_GMP
> >  #  include "knuth-lfib.h"
>
> Drop include, if nothing in testutils.h or testutils.c need gostdsa
> types.

Done.

-- 
With best wishes
Dmitry
_______________________________________________
nettle-bugs mailing list
[email protected]
http://lists.lysator.liu.se/mailman/listinfo/nettle-bugs

Reply via email to