Factoring Products of Mersenne-Form Numbers (2^a-1)(2^b-1)
- •
What it is
- •
If an RSA-style modulus is built from two numbers of the specific form and (regardless of whether they're genuinely prime — the vulnerability is purely structural), the modulus can be factored almost immediately from the bit pattern of alone (in the common case ), without any general-purpose factoring algorithm. Assuming : factors as times an odd number, so counting how many times divides evenly by 2 directly reveals (the smaller exponent), from which falls out immediately and .
- •
- •
When to apply
- •
Prime-generation code explicitly builds numbers as
(1 << k) - 1for some secret exponent (a "Mersenne-form" number) — a huge red flag regardless of whether the code bothers to verify actual primality of the result.
- •
- •
Math
- •
For : — the exact count of trailing zero bits in (its 2-adic valuation) equals . (Special case: if , i.e. , is a perfect square instead — see RSA with p = q (Repeated Prime Factor).)
- •
- •
Worked example
- •
, (both real historical Mersenne-prime exponents): counting trailing zero bits of gave exactly 89 — recovering and exactly, matching the true factorization.
- •
- •
Python
- •
z = N - 1 a = 0 while z % 2 == 0: z //= 2 a += 1 p = (1 << a) - 1 q = N // p
- •
- •
SageMath
- •
Not particularly relevant — this is a direct bit-counting loop, equally minimal in either language. (An alternative, more general approach — computing gcd(N, 2^k mod N - 1) for a range of candidate k — also works and generalizes better if the exact structural form isn't fully known in advance.)
- •
- •
Cards
- •
Why does counting trailing zero bits of N-1 reveal the smaller exponent a?
- •
N-1 = 2^a · (odd number) when p=2^a-1, q=2^b-1 with a<b, so the 2-adic valuation of N-1 is exactly a.
- •
- •
What's the giveaway in source code that this technique applies?
- •
Prime generation explicitly constructs candidates as (1 << k) - 1 for a secret exponent k — a "Mersenne-form" number — rather than a standard random-prime generator.
- •
- •