ECDSA public key verification for a given curve

Hi,

Can someone point me to an example showing how to perform key pair verification (NOT signature verification).
NIST website provides 4 files to test ECDSA.

KeyPair.req
PKV.req     // This is what I'm interested in. Inputs provided are curve, Qx and Qy
SigGen.req
SigVer.req

Thanks!

Hi @athorath
Do you mean to verify that the keypair is a valide key pair? Meaning, the public key is the pair of the private key?
If so, I would suggest using mbedtls_pk_check_pair once you have the parsed public and private keys.
Regards,
Mbed TLS Team member
Ron

@roneld01: Thanks for responding.
I will try out the mbedtls_pk_check_pair() function.

Here what I’m trying to do is validate a particular public key for a given curve.
Input file would look like this:

#  CAVS 17.6
#  "PKV" information 
#  Curves selected: P-192 

[P-192]

Qx = a76db2128543b449ad6b245b476213c4edfa15c4bb840520
Qy = 13d2f5392a0963e72f739c2f1bc94b2b110a66eac9d22cbf2
// Result = F    <-- Result (what I'm trying to determine)

Qx = 517c2b0270e15de63fa012153d9510fd80ceda4617ca6963
Qy = 3ce6d4434b8c8947337068cd40f6c43c52153b784a465875
// Result = P    <-- Result  (what I'm trying to determine)

I’m sorry about the confusion in the question.
Basically for a given curve, should determine if the public key is valid or not.
Reference: Section 6.3 (pg 4)
ECDSA Validation System (NIST website)

Hi @athorath
In this case, [mbedtls_ecp_check_pubkey()] (mbedtls/ecp.c at development · Mbed-TLS/mbedtls · GitHub) should answer your needs.
Regards

@roneld01 : Thanks for that suggestion. Again, I’ve the same problem (atleast I think so) as RSA verification.
I’ve shown my entire code including all structures and values passed in. I know we talked about endian-ness being an issue. With the code and inputs shown below, we can confirm that this might not (or might) be the issue.

My code:

typedef struct EParams
{
        unsigned char Qx[146]; 
        unsigned char Qy[146]; 
        int qxLength, qyLength;
        int isValid;
} EParams;

void PKVerification(EParams *params)
{
        mbedtls_ecp_group_id id;
        mbedtls_ecp_point P;
        int rc = -1;
        mbedtls_ecp_group grp;

        id = MBEDTLS_ECP_DP_SECP192R1;

        mbedtls_ecp_point_init( &P );
        mbedtls_ecp_group_init( &grp );
        rc = mbedtls_ecp_group_load( &grp, id );
        mbedtls_mpi_read_binary(&P.X, params->Qx, params->qxLength);
        mbedtls_mpi_read_binary(&P.Y, params->Qy, params->qyLength);
		
		rc = mbedtls_ecp_check_pubkey(&grp, &P);
        printf("\n\nmbedtls_ecp_check_pubkey : %d\n\n", rc);

		// All debug statements' outputs shown below
        /*printf("\nQx length : %d\n", params->qxLength);
        printf("\nQy length : %d\n", params->qyLength);
        printf("\nInput QX : "); printHexString(params->Qx, params->qxLength, stdout);
        printf("\nInput QY : "); printHexString(params->Qy, params->qyLength, stdout);

        mbedtls_mpi_write_file("\nMPI QX : ", &P.X, 16, stdout);
        mbedtls_mpi_write_file("\nMPI QY : ", &P.Y, 16, stdout);
        */
        
fail:
        mbedtls_ecp_group_free( &grp );
        mbedtls_ecp_point_free( &P );
        return;
}

The input is shown below:

[P-192]

Qx = a76db2128543b449ad6b245b476213c4edfa15c4bb840520
Qy = 13d2f5392a0963e72f739c2f1bc94b2b110a66eac9d22cbf2

The output from my function is shown below:

Qx length : 24

Qy length : 25

Input QX : a76db2128543b449ad6b245b476213c4edfa15c4bb840520

Input QY : 013d2f5392a0963e72f739c2f1bc94b2b110a66eac9d22cbf2

MPI QX : A76DB2128543B449AD6B245B476213C4EDFA15C4BB840520

MPI QY : 013D2F5392A0963E72F739C2F1BC94B2B110A66EAC9D22CBF2

mbedtls_ecp_check_pubkey : -19584

Atleast “I think” my APIs and the input formats are correct. Do you see anything wrong with my calls or data?

I see this issue: github_issue. This talks about endian-ness. Not sure what version that’s fixed in. I’m using version 2.9.0.

I’ve run the following command to confirm my system is little endian and it returns 1.

$ echo -n I | od -to2 | head -n1 | cut -f2 -d" " | cut -c6

Ref: stackoverflow_link

My OS is:

$ uname -ra
Linux thorath-vm 3.16.0-77-generic #99~14.04.1-Ubuntu SMP Tue Jun 28 19:17:10 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

I can’t stress enough how grateful I am for the help I’m getting.
THANKS!!!

Hi @athorath
the reason you are getting the failure is because Mbed TLS supports normalized(affine) points.
The failed points you encounter happen because the points are not normalized, such that Z is 0 or 1.
You can look at the implementation of static function ecp_normalize_jac() to see how to normalize the points. You will need to call mbedtls_mpi_lset(&P.Z, 1); before.
Regards

@roneld01: Thanks a lot for the suggestion, that fixed my problem!