From 08a11d1a05e5e1885d2601d789231b7313ce1440 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 21 Feb 2013 20:59:57 -0800 Subject: [PATCH] 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() ? ;) --- .../curve25519/ref/crypto_scalarmult.h | 1 + .../crypto_scalarmult/curve25519/ref/smult.c | 14 ++++++++++++-- .../include/sodium/crypto_scalarmult_curve25519.h | 2 ++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/libsodium/crypto_scalarmult/curve25519/ref/crypto_scalarmult.h b/src/libsodium/crypto_scalarmult/curve25519/ref/crypto_scalarmult.h index ab642f74..cefb476c 100644 --- a/src/libsodium/crypto_scalarmult/curve25519/ref/crypto_scalarmult.h +++ b/src/libsodium/crypto_scalarmult/curve25519/ref/crypto_scalarmult.h @@ -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 diff --git a/src/libsodium/crypto_scalarmult/curve25519/ref/smult.c b/src/libsodium/crypto_scalarmult/curve25519/ref/smult.c index 6a479558..2764fce3 100644 --- a/src/libsodium/crypto_scalarmult/curve25519/ref/smult.c +++ b/src/libsodium/crypto_scalarmult/curve25519/ref/smult.c @@ -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; -} +} \ No newline at end of file diff --git a/src/libsodium/include/sodium/crypto_scalarmult_curve25519.h b/src/libsodium/include/sodium/crypto_scalarmult_curve25519.h index d3f677ab..c3be0fec 100644 --- a/src/libsodium/include/sodium/crypto_scalarmult_curve25519.h +++ b/src/libsodium/include/sodium/crypto_scalarmult_curve25519.h @@ -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