Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
jvdsn
GitHub Repository: jvdsn/crypto-attacks
Path: blob/master/attacks/rsa/cherkaoui_semmouni.py
2589 views
1
import logging
2
import os
3
import sys
4
from math import isqrt
5
from math import log
6
from math import sqrt
7
8
from sage.all import RR
9
from sage.all import ZZ
10
11
path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(os.path.abspath(__file__)))))
12
if sys.path[1] != path:
13
sys.path.insert(1, path)
14
15
from shared.small_roots import herrmann_may
16
17
18
def attack(N, e, beta, delta, m=1, t=None, check_bounds=True):
19
"""
20
Recovers the prime factors of a modulus and the private exponent if |p - q| is sufficiently small.
21
More information: Cherkaoui-Semmouni M. et al., "Cryptanalysis of RSA Variants with Primes Sharing Most Significant Bits"
22
:param N: the modulus
23
:param e: the exponent
24
:param beta: the parameter beta such that |p - q| <= N^beta
25
:param delta: the parameter delta such that d <= N^delta
26
:param m: the m value to use for the small roots method (default: 1)
27
:param t: the t value to use for the small roots method (default: automatically computed using m)
28
:param check_bounds: perform bounds check (default: True)
29
:return: a tuple containing the prime factors and the private exponent, or None if the factors could not be found
30
"""
31
alpha = log(e, N)
32
assert not check_bounds or delta < 2 - sqrt(2 * alpha * beta), f"Bounds check failed ({delta} < {2 - sqrt(2 * alpha * beta)})."
33
34
x, y = ZZ["x", "y"].gens()
35
A = -(N - 1) ** 2
36
f = x * y + A * x + 1
37
X = int(2 * e * RR(N) ** (delta - 2)) # Equivalent to 2N^(alpha + delta - 2)
38
Y = int(RR(N) ** (2 * beta))
39
t = int((2 - delta - 2 * beta) / (2 * beta) * m) if t is None else t
40
logging.info(f"Trying {m = }, {t = }...")
41
for x0, y0 in herrmann_may.modular_bivariate(f, e, m, t, X, Y):
42
s = isqrt(y0)
43
d = s ** 2 + 4 * N
44
p = int(-s + isqrt(d)) // 2
45
q = int(s + isqrt(d)) // 2
46
d = int(f(x0, y0) // e)
47
return p, q, d
48
49
return None
50
51