Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
jvdsn
GitHub Repository: jvdsn/crypto-attacks
Path: blob/master/attacks/acd/sda.py
2589 views
1
import os
2
import sys
3
4
from sage.all import ZZ
5
from sage.all import matrix
6
7
path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(os.path.abspath(__file__)))))
8
if sys.path[1] != path:
9
sys.path.insert(1, path)
10
11
from shared import symmetric_mod
12
from shared.lattice import shortest_vectors
13
14
15
def attack(x, rho):
16
"""
17
Solves the ACD problem using the simultaneous Diophantine approximation approach.
18
More information: Galbraith D. S. et al., "Algorithms for the Approximate Common Divisor Problem" (Section 3)
19
:param x: the x samples, with xi = p * qi + ri
20
:param rho: the bit length of the r values
21
:return: the secret integer p and a list containing the r values, or None if p could not be found
22
"""
23
assert len(x) >= 2, "At least two x values are required."
24
25
R = 2 ** (rho + 1)
26
27
B = matrix(ZZ, len(x), len(x))
28
B[0, 0] = R
29
for i in range(1, len(x)):
30
B[0, i] = x[i]
31
B[i, i] = -x[0]
32
33
for v in shortest_vectors(B):
34
if v[0] != 0 and v[0] % R == 0:
35
q0 = v[0] // R
36
r0 = symmetric_mod(x[0], q0)
37
p = abs((x[0] - r0) // q0)
38
r = [symmetric_mod(xi, p) for xi in x]
39
if all(-R < ri < R for ri in r):
40
return int(p), r
41
42