micro-ecc icon indicating copy to clipboard operation
micro-ecc copied to clipboard

160/224 bit curves and public_key format on 64-bit arch

Open JamesTCurran opened this issue 8 years ago • 2 comments

This may be a well known characteristic, however I spent some time discovering it, so perhaps it's worth a comment somewhere (perhaps uECC.h line 151).

When generating a key pair using: int uECC_make_key() on a 64-bit machine, it is not sufficient that public_key be twice the length of the curve, in bytes. The public_key should be ( ceil( curve-size / 64 ) / 4 ) bytes long, as the X and Y points will not be stored immediately adjacent. The first byte of Y will begin at the start of the next 64-bit word. This causes a 4-byte gap between the X and Y points for the 160 and 224 bit curves.

The space is introduced in static void EccPoint_mult(); (uECC.c line 896), where the Rx and Ry are copied into result: uECC_vli_set(result + num_words, Ry[0], num_words); The start of Ry is aligned to result + num_words, which is 32-bits beyond the end of Rx, for both the 160 and 224 bit curves.

For internal data manipulation this is transparent, but when copying the key and writing to file/buffer, the extra four bytes of zeros between the Rx and Ry must be accounted for. If they are removed, then the must be re-introduced before passing the key to uECC_verify(). I imagine this is a well understood characteristic, but I thought it might be of interest.

In general, when the curve size is not an integer multiple of the native word size, it might be worth manipulating public_key in both uECC_make_key() and uECC_verify(), to respectively remove and re-introduce these four zero-bytes, such that public_key is indeed twice the length of the curve. Of course, once this trait is known, it is easy to handle, but it is not immediately obvious.

As always, I enjoy working with your code, it is an impressive piece of work.

Regards, James

JamesTCurran avatar Feb 09 '17 01:02 JamesTCurran

I can only reproduce this issue when uECC_VLI_NATIVE_LITTLE_ENDIAN is defined to 1. Is that the setup you are using?

kmackay avatar May 21 '17 17:05 kmackay

Hello Ken, yes, I only observed it with uECC_VLI_NATIVE_LITTLE_ENDIAN set to 1. Only after posting this note, I noticed that this was the default on the Repo, I chanced it to 0, and this resolved the issue. Sorry if this has wasted time for you. James

JamesTCurran avatar May 22 '17 13:05 JamesTCurran