Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Signatures made with micro-ecc are not always accepted by libsecp256k1 #145

Closed
kristofferkoch opened this issue Oct 12, 2018 · 2 comments
Closed

Comments

@kristofferkoch
Copy link

Hi,

I would like to use micro-ecc for some signature validation, and I just wanted to check that signatures generated by micro-ecc could be verified by libsecp256k1 and vice versa.

However, I see that around half of the signatures generated by micro-ecc is rejected by libsecp256k1, but (as far as I've seen) all libsecp256k1 signatures are accepted by micro-ecc.

I've created a repo with the test case and instructions at https://github.com/kristofferkoch/micro-ecc-test

I'm using the deterministic signature generation, and compressed public key format.

@douglasbakkum
Copy link

Probably the micro-ecc code does not normalize the signature.

https://github.com/bitcoin/bips/blob/master/bip-0062.mediawiki#low-s-values-in-signatures

This function could help:

int uECC_normalize_signature(uint8_t *signature,
                             uECC_Curve curve)
{
    uECC_word_t s[uECC_MAX_WORDS];
#if uECC_VLI_NATIVE_LITTLE_ENDIAN
    bcopy((uint8_t *) s, signature + curve->num_bytes, BITS_TO_BYTES(curve->num_n_bits));
#else
    uECC_vli_bytesToNative(s, signature + curve->num_bytes,
                           BITS_TO_BYTES(curve->num_n_bits)); /* tmp = d */
#endif

    if (uECC_vli_cmp(s, curve->half_n, curve->num_words) == 1) {
        uECC_vli_sub(s, curve->n, s, curve->num_words); /* s = n - s */
#if uECC_VLI_NATIVE_LITTLE_ENDIAN
        bcopy((uint8_t *) signature + curve->num_bytes, (uint8_t *) s, curve->num_bytes);
#else
        uECC_vli_nativeToBytes(signature + curve->num_bytes, curve->num_bytes, s);
#endif
        return 1;
    } else {
        return 0;
    }
}

(This worked for me but hasn't been tested on the latest master branch.)

@kristofferkoch
Copy link
Author

Hi,

I couldn't get your normalize function to work right away, but I tried doing it on the python/secp256k1 side. That worked for all the failing tests.

I'm going to try to make a pull request for adding your normalize function if I get it working.

Thanks a lot!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants