Nikos Mavrogiannopoulos nmav@gnutls.org writes:
If there is a function to do the DH multiplication k*(ecdsa_public_key) I think the gnutls could be tested with that interface, if I get some time to do that.
I'm looking into an interface redesign of the high-level ecdsa, using types
/* Represents a point on the ECC curve */ struct ecc_point { const struct ecc_curve *ecc; /* Allocated using the same allocation function as GMP. */ mp_limb_t *p; };
/* Represents a non-zero scalar, an element of Z_q^*, where q is the group order of the curve. */ struct ecc_scalar { const struct ecc_curve *ecc; /* Allocated using the same allocation function as GMP. */ mp_limb_t *p; };
(which are identical, except that they use different allocation size and contents for p...). I think this will be good enough for both ECDH and ECDSA. Some questions:
1. For the final multiplication in ECDH, do you want the complete point, or do you need the x coordinate only?
2. I wonder if I should somehow add some aliases, ecdsa_public_key <=> ecc_point, ecdsa_private_key <=> ecc_scalar?
3. Is there any need to support operations involving the zero point (group zero, curve infinity)? For now, I don't have any high-level function to add two points.
About the zero point, here's a comment from my current implementation of ecdsa_verify.
/* u = 0 can happen only if h = 0 or h = q, which is extremely unlikely. */ if (!zero_p (ecc, u1)) { /* Total storage: 6*ecc->size + ECC_MUL_G_ITCH (ecc->size) */ ecc_mul_g (ecc, P1, u1, u1 + ecc->size);
/* NOTE: ecc_add_jjj and/or ecc_j_to_a will produce garbage in case u1 G = +/- u2 V. However, anyone who gets his or her hands on a signature where this happens during verification, can also get the private key as z = +/- u1 / u_2 (mod q). And then it doesn't matter very much if verification of signatures with that key succeeds or fails.
u1 G = - u2 V can never happen for a correctly generated signature, since it implies k = 0.
u1 G = u2 V is possible, if we are unlucky enough to get h / s_1 = z. Hitting that is about as unlikely as finding the private key by guessing. */ /* Total storage: 6*ecc->size + ECC_ADD_JJJ_ITCH (ecc->size) */ ecc_add_jjj (ecc, P1, P1, P2, u1); }
If/when I switch to different primitives for ecdsa_verify, which are not side-channel silent, I ought to handle those corner cases correctly. But I wonder how important that really is.
And during signing, would it make sense to check if z s_1 = h (here, z is the private key, s_1 is the x coordinate of k G, and h is the message digest), and try a new random k in that case? In addition to the checks for s_1 == 0 or s_2 == 0?
Regards, /Niels