|
Message-ID: <20110326022134.GC15508@openwall.com> Date: Sat, 26 Mar 2011 05:21:34 +0300 From: Solar Designer <solar@...nwall.com> To: john-dev@...ts.openwall.com Subject: Re: pow64of32 Lukas, On Thu, Mar 24, 2011 at 06:01:59PM +0100, ?ukasz Odzioba wrote: > i was looking into the JtR sources Great! > and found that powering function > implementation is not optimal. It is O(n), but we can do that in > logarithmic time. Yes, and the code in charset.c uses a slow sorting algorithm. None of this matters much. These only affect the "--make-charset=..." option, which is not performance critical, as long as it completes in a few seconds. I intend to re-work the incremental mode, at which point I might as well either upgrade the 64-bit integer math stuff to 128-bit (since 64-bit became insufficient for some uses lately) or move to floating-point (except for the add32to64() call from status.c, which will need to stay integer for precision). > It's not a big deal but mayby code listed below, would be better (for > the peace of mind). > > void pow64of32(int64 *dst,unsigned int x,int n) > {//O(logn) > int64 tmp={0,1}; > while(n--){ > if(n%2) > mul64by32(&tmp,x); > x*=x; > n/=2; > } > } Unfortunately, it's not that simple. Even with three trivial bugs in the code above fixed (see below), there's the issue with 32-bit overflow on "x*=x;" So we'd need to upgrade "x" to 64-bit as well, and then we need a mul64by64(), which is not implemented currently. Overall, I think this peace of mind is not worth the added complexity. We may instead add a comment that these functions are not performance critical and thus are simple rather than fast. Test program, showing errors starting with "16 8" (the 32-bit overflow): --- #include "math.h" #include <string.h> #include <stdio.h> static void l_pow64of32(int64 *dst,unsigned int x,int n) {//O(logn) int64 tmp={1,0}; while(n){ if(n%2) mul64by32(&tmp,x); x*=x; n/=2; } *dst = tmp; } int main(void) { int64 y1, y2; unsigned int x, n; for (n = 0; n < 100; n++) { printf("n=%u\n", n); for (x = 0; x < 100; x++) { pow64of32(&y1, x, n); l_pow64of32(&y2, x, n); if (memcmp(&y1, &y2, sizeof(y1))) printf("%u %u\n", x, n); } } return 0; } --- That said, I appreciate you looking into the code and your proposal. Thank you! Alexander
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.