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

RFC 6979 conformance #51

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open

Conversation

concise
Copy link

@concise concise commented Aug 7, 2015

Hi. After understanding how RFC6979 actually works, I'd like to propose a small change to make the PRNG in uECC_sign_deterministic conform to RFC6979 for those implemented curves except secp160r1, without messing with bits2octets.

In addition to two local buffers of length ~ uECC_BYTES bytes, only one vli_ modular reduction ( t <- t mod n ), one vli_nativeToBytes function call, and one vli_bytesToNative function call must need to be added. I think the increase in signing time and code size is negligible.

@concise concise force-pushed the rfc6979-conformance branch 9 times, most recently from 42a75a2 to e29363a Compare August 8, 2015 05:11
@kmackay
Copy link
Owner

kmackay commented Aug 8, 2015

I am not opposed to including strict RFC 6979 conformance for verification purposes, as long as it is #ifdef'd out by default (ie, have a STRICT_RFC_6769 macro).

I would suggest that you implement bits2octets and bits2int as separate functions; that will make the implementation clearer.

@concise
Copy link
Author

concise commented Aug 9, 2015

I am not opposed to including strict RFC6979 conformance for verification purposes, as long as it is #ifdef'd out by default (ie, have a STRICT_RFC_6769 macro).

I would suggest that you implement bits2octets and bits2int as separate functions; that will make the implementation clearer.

I can refactor and rebase the RFC6979 code onto the runtime branch within a #ifdef STRICT_RFC_6769 - #endif block later when I have some time.

Please note that bits2int() is not an RFC6979-specific function. It should have been implemented as an important subroutine used by ECDSA signing operation to handle arbitrary-length message digests, as mentioned in issue #53.

We can write a bits2octets() function that is only used for RFC6979, but optimally that is not required, because by the definition from RFC6979, we have

bits2octets(x) := int2octets(bits2int(x) mod curve_n)

but we must compute bits2int(x) at some point during ECDSA signing operation, no matter whether RFC6979 deterministic RNG is used or not. All we have to do beyond that, for RFC6979, is (1) at most one big integer subtraction and (2) conversion from big integer back to a sequence of bytes. Of course, we can choose to make the code look simpler.

Part A

    bits2int(x)

        1) If xlen > nlen, truncate the input bit string so that
           its length does not exceed nlen bits, by keeping only
           the leftmost nlen bits.  If xlen <= nlen, do nothing.

        2) Convert the bit string to an unsigned integer using
           most significant bit first ordering.

        nlen := the bit length of curve_n
        xlen := the bit length of x        == 8 * (the byte length of x)

        This is a "standard" subroutine for ECDSA signature scheme
        that has to be invoked each time we generate a signature.
Part B

    x mod curve_n

        This modular reduction can be done by at most one subtraction
        because x is less than 2^nlen.
Part C

    int2octets(x)

        Convert an integer x in the range [0, curve_n - 1] into
        an octet string using most significant octet first ordering.

        The length of the octet string must equal to the byte length
        of curve_n.

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

Successfully merging this pull request may close these issues.

2 participants