// PureNoise CryptoLib (c) 1997-2004, PureNoise Ltd Vaduz // Ruptor's C and Intel Assembly implementations of multiplicative inverse modulo 2^32 /* A pure C version *\ unsigned long inv32 (const unsigned long x) { unsigned long d = x - 1, c = (x >> 1) + 1, a = 0, i = 1; for (; i; i <<= 1) if (d & 1) d >>= 1, d += c, a |= i; else d >>= 1; return a + 1; } */ /* Intel/AMD version */ static __forceinline unsigned long inv32 (const unsigned long X) { _asm { mov ecx,X mov edx,X shr ecx,1 dec edx inc ecx shr edx,1 jnc __00 lea edx,[edx+ecx] __00: rcr eax,1 shr edx,1 jnc __01 lea edx,[edx+ecx] __01: rcr eax,1 shr edx,1 jnc __02 lea edx,[edx+ecx] __02: rcr eax,1 shr edx,1 jnc __03 lea edx,[edx+ecx] __03: rcr eax,1 shr edx,1 jnc __04 lea edx,[edx+ecx] __04: rcr eax,1 shr edx,1 jnc __05 lea edx,[edx+ecx] __05: rcr eax,1 shr edx,1 jnc __06 lea edx,[edx+ecx] __06: rcr eax,1 shr edx,1 jnc __07 lea edx,[edx+ecx] __07: rcr eax,1 shr edx,1 jnc __08 lea edx,[edx+ecx] __08: rcr eax,1 shr edx,1 jnc __09 lea edx,[edx+ecx] __09: rcr eax,1 shr edx,1 jnc __0a lea edx,[edx+ecx] __0a: rcr eax,1 shr edx,1 jnc __0b lea edx,[edx+ecx] __0b: rcr eax,1 shr edx,1 jnc __0c lea edx,[edx+ecx] __0c: rcr eax,1 shr edx,1 jnc __0d lea edx,[edx+ecx] __0d: rcr eax,1 shr edx,1 jnc __0e lea edx,[edx+ecx] __0e: rcr eax,1 shr edx,1 jnc __0f lea edx,[edx+ecx] __0f: rcr eax,1 shr edx,1 jnc __10 lea edx,[edx+ecx] __10: rcr eax,1 shr edx,1 jnc __11 lea edx,[edx+ecx] __11: rcr eax,1 shr edx,1 jnc __12 lea edx,[edx+ecx] __12: rcr eax,1 shr edx,1 jnc __13 lea edx,[edx+ecx] __13: rcr eax,1 shr edx,1 jnc __14 lea edx,[edx+ecx] __14: rcr eax,1 shr edx,1 jnc __15 lea edx,[edx+ecx] __15: rcr eax,1 shr edx,1 jnc __16 lea edx,[edx+ecx] __16: rcr eax,1 shr edx,1 jnc __17 lea edx,[edx+ecx] __17: rcr eax,1 shr edx,1 jnc __18 lea edx,[edx+ecx] __18: rcr eax,1 shr edx,1 jnc __19 lea edx,[edx+ecx] __19: rcr eax,1 shr edx,1 jnc __1a lea edx,[edx+ecx] __1a: rcr eax,1 shr edx,1 jnc __1b lea edx,[edx+ecx] __1b: rcr eax,1 shr edx,1 jnc __1c lea edx,[edx+ecx] __1c: rcr eax,1 shr edx,1 jnc __1d lea edx,[edx+ecx] __1d: rcr eax,1 shr edx,1 jnc __1e lea edx,[edx+ecx] __1e: rcr eax,1 shr edx,1 jnc __1f lea edx,[edx+ecx] __1f: rcr eax,1 inc eax } } /* A faster Pentium-only version. Doesn't run on some AMD processors. *\ static __forceinline unsigned long inv32 (const unsigned long X) { _asm { xor edi,edi mov esi,X mov edx,X shr esi,1 dec edx inc esi shr edx,1 mov ecx,edi cmovc ecx,esi rcr eax,1 add edx,ecx shr edx,1 mov ecx,edi cmovc ecx,esi rcr eax,1 add edx,ecx shr edx,1 mov ecx,edi cmovc ecx,esi rcr eax,1 add edx,ecx shr edx,1 mov ecx,edi cmovc ecx,esi rcr eax,1 add edx,ecx shr edx,1 mov ecx,edi cmovc ecx,esi rcr eax,1 add edx,ecx shr edx,1 mov ecx,edi cmovc ecx,esi rcr eax,1 add edx,ecx shr edx,1 mov ecx,edi cmovc ecx,esi rcr eax,1 add edx,ecx shr edx,1 mov ecx,edi cmovc ecx,esi rcr eax,1 add edx,ecx shr edx,1 mov ecx,edi cmovc ecx,esi rcr eax,1 add edx,ecx shr edx,1 mov ecx,edi cmovc ecx,esi rcr eax,1 add edx,ecx shr edx,1 mov ecx,edi cmovc ecx,esi rcr eax,1 add edx,ecx shr edx,1 mov ecx,edi cmovc ecx,esi rcr eax,1 add edx,ecx shr edx,1 mov ecx,edi cmovc ecx,esi rcr eax,1 add edx,ecx shr edx,1 mov ecx,edi cmovc ecx,esi rcr eax,1 add edx,ecx shr edx,1 mov ecx,edi cmovc ecx,esi rcr eax,1 add edx,ecx shr edx,1 mov ecx,edi cmovc ecx,esi rcr eax,1 add edx,ecx shr edx,1 mov ecx,edi cmovc ecx,esi rcr eax,1 add edx,ecx shr edx,1 mov ecx,edi cmovc ecx,esi rcr eax,1 add edx,ecx shr edx,1 mov ecx,edi cmovc ecx,esi rcr eax,1 add edx,ecx shr edx,1 mov ecx,edi cmovc ecx,esi rcr eax,1 add edx,ecx shr edx,1 mov ecx,edi cmovc ecx,esi rcr eax,1 add edx,ecx shr edx,1 mov ecx,edi cmovc ecx,esi rcr eax,1 add edx,ecx shr edx,1 mov ecx,edi cmovc ecx,esi rcr eax,1 add edx,ecx shr edx,1 mov ecx,edi cmovc ecx,esi rcr eax,1 add edx,ecx shr edx,1 mov ecx,edi cmovc ecx,esi rcr eax,1 add edx,ecx shr edx,1 mov ecx,edi cmovc ecx,esi rcr eax,1 add edx,ecx shr edx,1 mov ecx,edi cmovc ecx,esi rcr eax,1 add edx,ecx shr edx,1 mov ecx,edi cmovc ecx,esi rcr eax,1 add edx,ecx shr edx,1 mov ecx,edi cmovc ecx,esi rcr eax,1 add edx,ecx shr edx,1 mov ecx,edi cmovc ecx,esi rcr eax,1 add edx,ecx shr edx,1 mov ecx,edi cmovc ecx,esi rcr eax,1 add edx,ecx shr edx,1 mov ecx,edi cmovc ecx,esi rcr eax,1 inc eax } } */