crypto_scalarmult_raw()

This provides a more direct interface to the crypto_scalarmult function.
By default, this function includes some bit-twiddling, which, to the
best of my understanding, ensures the integer provided as the left
operand of the multiplication operation fits within a specific limit.
(I believe this limit is the order of NaCl's standard group element,
but am not entirely certain). This change allows a user to pass in
an integer which is not subject to this bit-twiddling and can be passed
in wholesale.

The reason NaCl provides this API is to intentionally make it
easy-to-use for the purposes of computing public keys from private keys
or for performing Diffie-Hellman. The API it provides now makes it
quite difficult to do anything wrong yet still get a correct answer.

If we split this function in half, however, we can expose some
power-user functionality. Specifically I need this to implement
semiprivate keys:

https://gist.github.com/tarcieri/4760215

I've been double checking my implementation against a similar version in
SAGE for the past week or so trying to figure out what's wrong, and
today it was pointed out to me that NaCl's scalar multiplication
function automatically performs bit-twiddling for you.

I would love to continue to experiment with semiprivate keys on top of
NaCl. I have no serious intentions of actually using them as part of a
cryptosystem until there's some sort of proof of their security, or at
the very least, some reasonably educated guesses as to its security
properties.

That said, I would love to have this API. If there's worries about
exposing power-user APIs like this, perhaps we can be a bit more
"shouty" in the API name?

crypto_scalarmult_dangerously_direct_access() ? ;)
This commit is contained in:
Tony Arcieri
2013-02-21 20:59:57 -08:00
parent 0926fc974d
commit 08a11d1a05
3 changed files with 15 additions and 2 deletions
@@ -4,6 +4,7 @@
#include "crypto_scalarmult_curve25519.h"
#define crypto_scalarmult crypto_scalarmult_curve25519
#define crypto_scalarmult_raw crypto_scalarmult_curve25519_raw
#define crypto_scalarmult_base crypto_scalarmult_curve25519_base
#define crypto_scalarmult_BYTES crypto_scalarmult_curve25519_BYTES
#define crypto_scalarmult_SCALARBYTES crypto_scalarmult_curve25519_SCALARBYTES
@@ -248,13 +248,23 @@ int crypto_scalarmult(unsigned char *q,
const unsigned char *n,
const unsigned char *p)
{
unsigned int work[96];
unsigned char e[32];
unsigned int i;
for (i = 0;i < 32;++i) e[i] = n[i];
e[0] &= 248;
e[31] &= 127;
e[31] |= 64;
return crypto_scalarmult_raw(q, e, p);
}
int crypto_scalarmult_raw(unsigned char *q,
const unsigned char *n,
const unsigned char *p)
{
unsigned int work[96];
unsigned char e[32];
unsigned int i;
for (i = 0;i < 32;++i) e[i] = n[i];
for (i = 0;i < 32;++i) work[i] = p[i];
mainloop(work,e);
recip(work + 32,work + 32);
@@ -262,4 +272,4 @@ int crypto_scalarmult(unsigned char *q,
freeze(work + 64);
for (i = 0;i < 32;++i) q[i] = work[64 + i];
return 0;
}
}
@@ -8,12 +8,14 @@
extern "C" {
#endif
extern int crypto_scalarmult_curve25519_ref(unsigned char *,const unsigned char *,const unsigned char *);
extern int crypto_scalarmult_curve25519_ref_raw(unsigned char *,const unsigned char *, const unsigned char *);
extern int crypto_scalarmult_curve25519_ref_base(unsigned char *,const unsigned char *);
#ifdef __cplusplus
}
#endif
#define crypto_scalarmult_curve25519 crypto_scalarmult_curve25519_ref
#define crypto_scalarmult_curve25519_raw crypto_scalarmult_curve25519_ref_raw
#define crypto_scalarmult_curve25519_base crypto_scalarmult_curve25519_ref_base
#define crypto_scalarmult_curve25519_BYTES crypto_scalarmult_curve25519_ref_BYTES
#define crypto_scalarmult_curve25519_SCALARBYTES crypto_scalarmult_curve25519_ref_SCALARBYTES