[curves] Ed25519 "clamping" and its effect on hierarchical key derivation

Ron Garret ron at flownet.com
Fri Apr 7 17:33:59 PDT 2017


On Apr 7, 2017, at 5:06 PM, Tony Arcieri <bascule at gmail.com> wrote:

> On Fri, Apr 7, 2017 at 4:57 PM, Ron Garret <ron at flownet.com> wrote:
> Not really.  What appears to be a 64 byte secret key is actually a 32-byte secret key concatenated with the corresponding 32-byte public key.
> 
> Oleg is describing the original NaCl API (as in https://nacl.cr.yp.to/), not the API provided by the ref10 implementation (which has proliferated from SUPERCOP). My understanding is this version has various incompatibilities and security issues versus ref10.
> 
> This version uses a 64-bit secret key (sk) alongside a 32-bit public key. See Brian Warner's writeup which Oleg linked for more information.
> 
> Here is the original key generation code from NaCl (2011), which fills a 64-byte secret key buffer with 32-bytes of randomness before expanding it into 64-bytes using SHA-512. Note it also "pre-clamps" the secret scalar:
> 
> int crypto_sign_keypair(
>     unsigned char *pk,
>     unsigned char *sk
>     )
> {
>   sc25519 scsk;
>   ge25519 gepk;
> 
>   randombytes(sk, 32);
>   crypto_hash_sha512(sk, sk, 32);
>   sk[0] &= 248;
>   sk[31] &= 127;
>   sk[31] |= 64;
> 
>   sc25519_from32bytes(&scsk,sk);
> 
>   ge25519_scalarmult_base(&gepk, &scsk);
>   ge25519_pack(pk, &gepk);
>   return 0;
> }

Ah.

I’m using TweetNaCl which I had assumed had the same API as NaCl.  But it doesn’t.  TweetNacl does this:

int crypto_sign_keypair(u8 *pk, u8 *sk)
{
  u8 d[64];
  gf p[4];
  int i;

  randombytes(sk, 32);
  crypto_hash(d, sk, 32);
  d[0] &= 248;
  d[31] &= 127;
  d[31] |= 64;

  scalarbase(p,d);
  pack(pk,p);

  FOR(i,32) sk[32 + i] = pk[i];
  return 0;
}



-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://moderncrypto.org/mail-archive/curves/attachments/20170407/fd6865f7/attachment.html>


More information about the Curves mailing list