On 7/25/2018 2:05 PM, Adam Petcher wrote:
On 7/25/2018 11:24 AM, Michael StJohns wrote:
*sigh* Private keys are big integers. There's an associated
parameter used in signing that the implementation described in the
RFC (*not a standard please note*) generates from a common random
byte array - that byte array is NOT a (or the) private key.
E.g. Private key ::= OctetToInteger(Adjust(Left (HASH(random),
length))) and SigningValue ::= Right(HASH(random),length).
Instead, you can get the exact same result (deterministic signatures)
- and store a bog standard EC private key - by
PrivateKey ::= OctetToInteger(Adjust(random));
Did you mean PrivateKey ::= OctetToInteger(random)? Setting/clearing
bits here destroys information. If we don't prune here, then we can
reverse this operation later to get the byte array back to give to the
hash.
No - I meant what I wrote:
1) generate a private key from a random and store it as a big integer.
E.g. generate a byte array of the appropriate length (32), twiddle the
bits as described in step 2 of section 5.1.5 of RFC8032 and -
interpreting that buffer as a little-endian encoding, save 's' (the
secret scalar - aka - the actual private key) as a BigInteger.
That's the limit of what goes into the PrivateKey spec/interface.
2) When you do a signing, do SigningValue =
HASH(IntegerToLittleEndianOctets(s)).
3) When done with signing, throw away the hash value - it doesn't need
to be stored.
The *only* important characteristics of the signing value are a) it's
confidential, and b) it's the same for each signature. It could even be
a random value generated and stored at the same time as the private key
- but why?
SigningValue ::= HASH (IntegerToOctet(PrivateKey)); // signing value
may be regenerated at any time and need not be stored in the
ECPrivateKey class.
With the modification above, I agree that this would give the value
that can be split in half to produce the scalar value (after pruning
and interpreting as an integer) and the prefix that is used in signing.
I think there may be some issues with this approach, but we need to
start by agreeing on what you are proposing. Can you confirm that my
understanding of your proposal is correct, or else clarify it for me?
What I'm trying to get to is make the java interfaces for EC private
keys consistent regardless of which of the curve flavor you want to
use. In each and every case, looking behind the specified external
representation, the scalar 's' can be represented as a BigInteger.
Internal representation IN A SPECIFIC IMPLEMENTATION might use little
endian internally, but that's irrelevant here for the purposes of java
interfaces. (At least in my opinion).
Later, Mike