diff --git a/README b/README index 4cdb8ab..ebd98fa 100644 --- a/README +++ b/README @@ -40,8 +40,8 @@ To make a proof, split the challenge by ":" and verify that the first token is "argon2id". Decode the iterations, memory, and digits parameters, and the challenge bytes. -Repeat the following algorithm to generate proofs until an argon2id key is found -whose first N hexadecimal digits are zero, where N is equal to the digits +Repeat the following algorithm to generate proofs until an argon2id key +is found whose first N bits are zero, where N is equal to the digits parameter: 1. Generate 16 random bytes (password). diff --git a/src/checkproof.c b/src/checkproof.c index 797015d..6c9c8d4 100644 --- a/src/checkproof.c +++ b/src/checkproof.c @@ -5,6 +5,7 @@ #include "argon2.h" #include "random.h" #include "util.h" +#include "proof.h" static void die(int exitcode, int check, char *why) @@ -75,12 +76,9 @@ main(int argc, char *argv[]) r = argon2id_ctx(&context); die(1, r != 0, "argon2id failed\n"); - for (int i = 0; i < digits; ++i) { - unsigned char n = hash[i / 2] & (i % 2 ? 0x0F : 0xF0); - if (n != 0) { - printf("proof: failed\n"); - return 1; - } + if (hash_msb(hash) < digits) { + printf("proof: failed\n"); + return 1; } printf("proof: ok\n"); diff --git a/src/mkchallenge.c b/src/mkchallenge.c index 411e77d..f3a41b0 100644 --- a/src/mkchallenge.c +++ b/src/mkchallenge.c @@ -8,7 +8,7 @@ #define ALGORITHM "argon2id" #define ITERATIONS 10 #define MEMORY 12 -#define DIGITS 5 +#define DIGITS 20 static void usage(char *argv_0) diff --git a/src/mkproof.c b/src/mkproof.c index c5bf90b..3ec703c 100644 --- a/src/mkproof.c +++ b/src/mkproof.c @@ -6,6 +6,7 @@ #include "argon2.h" #include "random.h" #include "util.h" +#include "proof.h" static void die(int check, char *why) @@ -88,14 +89,7 @@ main(int argc, char *argv[]) r = argon2id_ctx(&context); die(r != 0, "argon2id failed\n"); - valid = 1; - for (int i = 0; i < digits; ++i) { - unsigned char n = hash[i / 2] & (i % 2 ? 0x0F : 0xF0); - if (n != 0) { - valid = 0; - break; - } - } + valid = hash_msb(hash) >= digits; } if (isatty(STDERR_FILENO)) { diff --git a/src/proof.h b/src/proof.h new file mode 100644 index 0000000..b1fa399 --- /dev/null +++ b/src/proof.h @@ -0,0 +1,31 @@ + +/* number of leading zero bits in a byte */ +static inline int +msb(unsigned char b) +{ + int n = 0; + + if (b == 0) + return 8; + + while (b >>= 1) + n++; + + return 7-n; +} + +/* find the number of leading zero bits in a hash */ +static int +hash_msb(unsigned char *hash) +{ + int bits, total, i; + + for (i = 0, total = 0; i < 32; i++) { + bits = msb(hash[i]); + total += bits; + if (bits != 8) + break; + } + return total; +} +