任意modのLSB Leak Attack考

 X = f_1 * f_2 * \dots * f_nとしておいて、

 X^{-1} =  f_1^{-1} * f_2^{-1} * \dots * f_n^{-1} か? →  GCD(f_1, f_2, \dots, f_n) = 1ならYes

で、ある  f_iについて

 Dec \left(C\right) = M \equiv m_0 \mod f_i

(ただし  M = m_0 + m_1f_i + m_2 f_i^2 + \dots

続いて、

 Dec\left((X^{-1})^eC\right) = X^{-1}M = (f_1f_2\dots)^{-1}(m_0 + m_1f_i + m_2f_i^2 + \dots)

 = X^{-1}m_0 + (f_1f_2\dots f_{i-1}f_{i+1}\dots)^{-1}m_1 + (f_1f_2\dots f_{i-1}f_{i+1}\dots)^{-1}f_im_2 + \dots

 \equiv X^{-1}m_0 + (f_1f_2\dots f_{i-1}f_{i+1}\dots)^{-1}m_1 \mod f_i

なので、 X^{-1}m_0引いて f_1f_2\dots f_{i-1}f_{i+1}\dots掛ければよい

 X^{-1}m_0 は \mod n f_1f_2\dots f_{i-1}f_{i+1}\dots かけるのも  \mod n

その次は

 ((X^2)^{-1})^eC \equiv X^{-2}m_0 + X^{-1}(f_1f_2\dots f_{i-1}f_{i+1}\dots)^{-1}m_1 + (f_1f_2\dots f_{i-1}f_{i+1}\dots)^{-2}m_2 \mod f_i

なので、 X^{-2}m_0 + X^{-1}(f_1f_2\dots f_{i-1}f_{i+1}\dots)^{-1}引いて (f_1f_2\dots f_{i-1}f_{i+1}\dots)^2掛ければ良い。実装的には m_0 + f_im_1を持ってるはずなので (m_0 + f_im_1)X^{-2}引けばよくなる

……という理論に基づいて書いてみたけどうまく動かない↓

from Crypto.Util.number import *


p = getPrime(256)
q = getPrime(256)
n = p * q
e = 65537
d = inverse(e, n - p - q + 1)

primes = [659, 809, 719, 647, 809, 653, 691, 911, 677]

m = getRandomNBitInteger(128)
c = pow(m, e, n)
M = primes[0]

def oracle(x):
    return pow(x, d, n) % M

X = 1
for p in primes:
    X *= p

Y = 1
for p in primes[1:]:
    Y *= p

z = oracle(c)
print(z, m % M)
for i in range(1, 10):
    inv = inverse(X ** i, n)
    c2 = (c * pow(inv, e, n)) % n

    o = oracle(c2)
    ith_z = ((o - z*inv) * pow(Y, i, n) % n) % M

    z = ith_z * (M ** i) + z
    mm = m
    for _ in range(i):
        mm = mm // M

    print([z, m % (M ** (i + 1))], [ith_z, mm % M])

というのも

 Y = AKとして、

 Dec\left((Y^{-1}_{(n)})^eC \right) = Y^{-1}M = K^{-1}(A^{-1}M)

なので、

 M' := A^{-1}M K進数で示す必要がある。すなわち

 M' = m'_0 + m'_1K + m'_2 K^2 + \cdots

で、じゃあ返ってくるのは  K^{-1}m'_0 + m'_1 ということになる

 m'_0 (m_0 * A^{-1}_{(n)}) \mod Kで求められそう。

ということは m'_1は返ってきたオラク oとして、 m'_1 \equiv o - K^{-1}_{(n)}m'_0 \mod Kで求まりそう。

ということは m'_1 \to m_1 をどうやって求めるかなんだよな

 (m_0 + m_1K)A^{-1}_{(n)} \equiv m'_0 + m'_1K  \mod K^2

のはずなので、

 m_0 + m_1K \equiv (m'_0 + m'_1K)(A^{-1}_{(n)})^{-1}_{(k^2)} \mod K^2

( (A^{-1}_{(n)})^{-1}_{(k^2)} \mod nでの A^{-1}の、 K^2での逆数をとった値)

 m_1K \equiv (m'_0 + m'_1K)(A^{-1}_{(n)})^{-1}_{(k^2)} - m_0 \mod K^2

 m_1 = ((m'_0 + m'_1K)A - m_0) K^{-1}_{(K^2)} \mod K^2

( K K^2における逆数)

ということになりそう?

一般化して、

 Y = (AK)^k

 Dec\left((Y^{-1}_{(n)})^eC\right) = Y^{-1}M = K^{-k}(A^{-k}M)

で、返ってくるのは、 M' = A^{-k}Mとして o = K^{-k}m'_0 + K^{-(k-1)}m'_1 + \cdots + m'_k \pmod K

今手元には M^\star = m_0 + m_1K + \cdots m_{k-1}K^{k-1}があるはずなので、

 m'_k = o - M^\star Y^{-1} \mod K

で、

 1 \equiv A^{-k}_{(n)}A_{inv} \mod K^{k+1}

 1 \equiv K^{-k}_{(n)}K_{inv} \mod K^{k+1}

として

 (M^\star + m_kK^k)A^{-k}_{(n)} \equiv M^\star A^{-k}_{(n)} + m'_kK^k \mod K^{k+1}

 m_k \equiv ((M^\star A^{-k}_{(n)} + m'_kK^k)A_{inv} - M^\star)K_{inv} \mod K^{k+1}