The meet-in-the-middle attack (MITM) is a generic space–time tradeoff cryptographic attack against encryption schemes which rely on performing multiple encryption operations in sequence. The MITM attack is the primary reason why Double DES is not used and why a Triple DES key (168-bit) can be bruteforced by an attacker with 2^56 space and 2^112 operations
- This script illustrates how we can use MITM to solve a specific discrete log problem square-root of the operations of the simplest brute force attack.
- Given prime
p
- then
Zp* = {1, 2, 3, ..., p-1}
- let
g
andh
be elements inZp*
such that - such that
h mod p = g^x mod p
where0 < x < 2^40
- find
x
givenh
,g
, andp
$ python mitm.py
Given p, g, and h, such that p is prime, and both g and h is less than p
Find x such that g^x mod p = h (g^x is g raised to the power of x)
p =
13407807929942597099574024998205
84612747936582059239337772356144
37217640300735469768018742981669
03427690031858186486050853753882
811946569946433649006084171
g =
11717829880366207009516117596335
36708855808499999895220559997945
90639294997365837466705721764714
60312928594829675428279466566527
115212748467589894601965568
h =
32394751040504504435652643787280
65788649097520952449527834792452
97198197614329255807385693795855
31805328789280014947060973941085
77585732452307673444020333
finding x...
x = 375374217830
- let
B = 2^20
thenB^2 = 2^40
- then
x= xo * B + x1
wherexo
andx1
are in{0, 1, ..., B-1}
- Then smallest
x
isx = 0 * B + O = 0
- and the largest
x
isx = B * (B-1) + B - 1 = B^2 - B + B -1 = B^2 - 1 = 2^40 - 1
- Then:
h = g^x
h = g^(xo * B + x1)
h = g^(xo * B) * g^(x1)
h / g^(x1) = g^(xo*B)
- Find
xo
andx1
giveng
,h
,B
- Build a hash table key:
h / g^(x1)
, with valuex1
forx1
in{ 0, 1, 2, .., 2^20 - 1}
- For each value
x0
in{0, 1, 2, ... 20^20 -1}
check if(g^B)^(x0) mod P
is in hash table. If it is then you've foundx0
andx1
- Return
x = xo * B + x1
- Work is
2^20
multiplications and2^20
lookups in the worst case - If we attack it by bruteforce , we would do
2^40
multiplications - So the work is squareroot of brute force
(x mod p) / ( y mod p) = ((x mod p) * (y_inverse mod p)) mod p
- Be smart. Do not do redundant exponentiations.
# Efficient
gB = g**B % p
z = h
print(x, z)
for x in range(1, n):
z = z*gB % p
print(x, z)
# Inefficient
for x in range(n):
y = g**(B*x)
z = h*y % p
print(x, z)
y_inverse * y mod p = 1
Given p is prime,
then for every element x in set Zp* = {1, ..., p - 1}
the element x is invertible (there exist an x_inverse such that:
x_inverse * x mod p = 1
The following is true (according to Fermat's 1640)
x^(p - 1) mod = 1
x ^ (p - 2) * x mod p = 1
x_inverse = x^(p-2)