Hello,
SP800-56A (revision 3) section 5.6.2.3.3 now mandates a check that the
generated public key (Q) multiplied by the curve order (n) results in an
identity element (= an infinity point).
It seem that it is not possible to implement this check with the
Nettle's public API. The attached patch naively multiplies Q by n but
it causes the valgrind errors below.
As it works with the curve order minus 1, I added the following check
instead in my library, though I'm not sure if this satisfies the
original requirement:
P = (n - 1) * Q
where P's x-coordinate is the same as Q's, and P also lies on the same
curve so that indicates P + Q (= n * Q) is an infinity point, according
to the group law.
Is there a better (direct) way to implement the check? Suggestions
appreciated.
Conditional jump or move depends on uninitialised value(s)
at 0x4880DFB: _nettle_ecc_mul_a (ecc-mul-a.c:145)
by 0x48815F8: nettle_ecc_point_mul (ecc-point-mul.c:55)
by 0x4012EB: main (ecc-test.c:36)
Conditional jump or move depends on uninitialised value(s)
at 0x487D1D9: _nettle_sec_tabselect (sec-tabselect.c:54)
by 0x4880E1B: _nettle_ecc_mul_a (ecc-mul-a.c:147)
by 0x48815F8: nettle_ecc_point_mul (ecc-point-mul.c:55)
by 0x4012EB: main (ecc-test.c:36)
Conditional jump or move depends on uninitialised value(s)
at 0x487E0F3: _nettle_ecc_mod_add (ecc-mod-arith.c:53)
by 0x487F51B: _nettle_ecc_dup_jj (ecc-dup-jj.c:81)
by 0x4880E66: _nettle_ecc_mul_a (ecc-mul-a.c:171)
by 0x48815F8: nettle_ecc_point_mul (ecc-point-mul.c:55)
by 0x4012EB: main (ecc-test.c:36)
Regards,
--
Daiki Ueno
#include <nettle/ecdsa.h>
#include <nettle/ecc-curve.h>
#include <assert.h>
#include <string.h>
static void
myrandom (void *ctx, size_t length, uint8_t *dst)
{
memset (dst, 0, length);
*dst = 0xff;
}
int
main (void)
{
const struct ecc_curve *curve = nettle_get_secp_256r1 ();
struct ecc_point pub;
struct ecc_scalar key;
mpz_t nz, x, y;
struct ecc_scalar n;
struct ecc_point r;
ecc_point_init (&pub, curve);
ecc_scalar_init (&key, curve);
ecc_scalar_init (&n, curve);
ecc_point_init (&r, curve);
ecdsa_generate_keypair (&pub, &key, NULL, myrandom);
/* Calculate P = nQ and check if it is an infinity point. */
mpz_init_set_str (nz, "ffffffff00000000ffffffffffffffff"
"bce6faada7179e84f3b9cac2fc632551", 16);
ecc_scalar_set (&n, nz);
mpz_clear (nz);
ecc_point_mul (&r, &n, &pub);
mpz_init (x);
mpz_init (y);
ecc_point_get (&r, x, y);
assert (mpz_cmp_ui (x, 0) == 0);
assert (mpz_cmp_ui (y, 0) == 0);
mpz_clear (x);
mpz_clear (y);
ecc_point_clear (&pub);
ecc_scalar_clear (&key);
ecc_scalar_clear (&n);
ecc_point_clear (&r);
return 0;
}
/**
* Local variables:
* compile-command: "gcc -o ecc-test ecc-test.c `pkg-config hogweed --cflags --libs` -lgmp"
* End:
*/