diff options
Diffstat (limited to 'crypto-mcf.c')
-rw-r--r-- | crypto-mcf.c | 61 |
1 files changed, 35 insertions, 26 deletions
diff --git a/crypto-mcf.c b/crypto-mcf.c index 66e92f0..8ad3eb8 100644 --- a/crypto-mcf.c +++ b/crypto-mcf.c @@ -3,31 +3,47 @@ #include <stdio.h> #include <stdint.h> #include <float.h> - +#include <stdint.h> #include <math.h> +#ifndef S_SPLINT_S /* Including this here triggers a known bug in splint */ +#include <unistd.h> +#endif + #include "libscrypt.h" -/* Although log2 exists in GNU99 C, more portable code shouldn't use it -* Note that this function returns a float and hence is not compatible with the -* GNU prototype -*/ -static double scrypt_log2( uint32_t n ) -{ - // log(n)/log(2) is log2. - double temp; - /* Using the temp variable keeps splint happy */ - temp = log(2); - return (log((double)n) / temp); +/* ilog2 for powers of two */ +static uint32_t scrypt_ilog2(uint32_t n) +{ +#ifndef S_SPLINT_S + + /* Check for a valid power of two */ + if (n < 2 || (n & (n - 1))) + return -1; +#endif + uint32_t t = 1; + while (((uint32_t)1 << t) < n) + { + if(t > SCRYPT_SAFE_N) + return (uint32_t) -1; /* Check for insanity */ + t++; + } + + return t; } -int libscrypt_mcf(uint32_t N, uint32_t r, uint32_t p, char *salt, char *hash, char *mcf) -{ +#ifdef _MSC_VER + #define SNPRINTF _snprintf +#else + #define SNPRINTF snprintf +#endif +int libscrypt_mcf(uint32_t N, uint32_t r, uint32_t p, const char *salt, + const char *hash, char *mcf) +{ - uint32_t params; + uint32_t t, params; int s; - double t, t2, fracpart; if(!mcf || !hash) return 0; @@ -38,15 +54,8 @@ int libscrypt_mcf(uint32_t N, uint32_t r, uint32_t p, char *salt, char *hash, ch if(r > (uint8_t)(-1) || p > (uint8_t)(-1)) return 0; - - t = scrypt_log2(N); - - /* The "whole numebr" check below is non-trivial due to precision - * issues, where you could printf("%d", (int)t) and find yourself - * looking at (expected value) -1 - */ - fracpart = modf(t, &t2); - if(fracpart > DBL_EPSILON) + t = scrypt_ilog2(N); + if (t < 1) return 0; params = (r << 8) + p; @@ -56,7 +65,7 @@ int libscrypt_mcf(uint32_t N, uint32_t r, uint32_t p, char *salt, char *hash, ch * determined that mcf should be defined as at least SCRYPT_MCF_LEN * in length */ - s = snprintf(mcf, SCRYPT_MCF_LEN, SCRYPT_MCF_ID "$%06x$%s$%s", (unsigned int)params, salt, hash); + s = SNPRINTF(mcf, SCRYPT_MCF_LEN, SCRYPT_MCF_ID "$%06x$%s$%s", (unsigned int)params, salt, hash); if (s > SCRYPT_MCF_LEN) return 0; |