Ed25519 keys: what's stored in a secret key packet?

James Bottomley James.Bottomley at HansenPartnership.com
Sun Feb 14 19:58:40 CET 2021


On Sun, 2021-02-14 at 11:07 +0100, Marco Ricci wrote:
> Greetings!
> 
> Thus spoke James Bottomley:
> > > The bit-fiddling on `LH` also guarantees that `a` is
> > > always divisible by 8.
> > 
> > Well 2^3 is the cofactor of the Bernstein curve, yes.
> 
> I'm aware. I wanted to stress that `a` has range restrictions, and
> thus has a characteristic bit pattern when serialized as an OpenPGP
> MPI.
> 
> > Firstly the EdDSA signature algorithm uses a private bit string K
> > in the computation r = H(KM).  Traditionally K is the high part of
> > the hash of the private key (i.e. LH in your description above) to
> > avoid having to rely on random numbers but the algorithm works
> > equally well if K is simply a random number.  As long as K remains
> > unknown to anyone except the signer, the signature is secure and
> > will verify correctly.
> 
> I'm aware, as well. I believe though that the normative EdDSA version
> is to use the `r = H(KM)` calculation. I see no indication in the
> EdDSA for OpenPGP spec that a non-standard version of determining `r`
> is used.

libgcrypt uses K = LH

The relevant code is ecc-eddsa.c:_gcry_ecc_eddsa_sign

The only slight deviation gnupg does for elliptic curves is that it
uses RFC6979 deterministic signatures for ECDSA.

> > Is your problem with what the standard says or what gnupg actually
> > does?  Because what it does is store the encrypted s-expression of
> > the private key in the key file exactly as libgcrypt supplies it
> > and libgcrypt makes d one of the parameters of this s-
> > expression.  d is what you call k above: the random 32 bit number.
> 
> The former, sort of. But this actually answers my question. Thanks.
> I couldn't sensibly determine what libgcrypt's output is and whether
> GnuPG transforms it or not before encoding it as an OpenPGP secret
> key packet. (I couldn't find any documentation on the s-expression
> shape, nor could I get GnuPG to actually emit the s-expression, so I
> gathered that to get my answer I'd have to write my own C program to
> interface libgcrypt, which I don't feel confident enough to attempt
> yet with my current level of familiarity with libgcrypt.) Knowing
> that libgcrypt yields the `d`/`k` value and that it ends up in the
> secret key packet clears my doubts on what those secret key packets
> really contain.
> 
> But then the spec and GnuPG's behavior differ, no? And one of them
> should be fixed -- presumably the spec, because it's still a draft,
> and because IMO the current practice is saner than the spec. Should I
> file a proper report against the spec then?

Well, it's not really relevant any more:  The spec is documenting the
secring keypacket format, which isn't used by current gnupg (it started
switching to the encrypted s-expression format in 2017).  The current
format is documented in agent/keyformat.txt

James

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: This is a digitally signed message part
URL: <https://lists.gnupg.org/pipermail/gnupg-devel/attachments/20210214/c6cda73c/attachment.sig>


More information about the Gnupg-devel mailing list