跳转至

Rabin 密码体制

Rabin 密码体制使用平方映射加密:

\[ c\equiv m^2\pmod n,\qquad n=pq \]

它与“\(e=2\) 的 RSA”形式相似,但并不是标准 RSA,因为 \(2\) 与 \(\varphi(n)\) 不互素,不存在唯一的私钥指数。知道 \(p,q\) 后可以高效求模平方根,但通常会得到四个候选明文。

Blum 素数情形

若:

\[ p\equiv q\equiv3\pmod4 \]

则模 \(p\) 和模 \(q\) 的平方根可直接计算:

\[ r_p\equiv c^{(p+1)/4}\pmod p,\qquad r_q\equiv c^{(q+1)/4}\pmod q \]

每个素数模数下都有正负两个根,使用 CRT 组合后得到四个根。

Python 实现

def rabin_decrypt(c, p, q):
    if p % 4 != 3 or q % 4 != 3:
        raise ValueError("该简化公式要求 p、q 均模 4 余 3")

    rp = pow(c, (p + 1) // 4, p)
    rq = pow(c, (q + 1) // 4, q)
    inv_q_mod_p = pow(q, -1, p)
    inv_p_mod_q = pow(p, -1, q)
    n = p * q

    roots = set()
    for root_p in (rp, -rp % p):
        for root_q in (rq, -rq % q):
            root = (
                root_p * q * inv_q_mod_p
                + root_q * p * inv_p_mod_q
            ) % n
            roots.add(root)
    return sorted(roots)


p, q = 7, 11
message = 20
n = p * q
c = pow(message, 2, n)
print(rabin_decrypt(c, p, q))

筛选正确明文

Rabin 解密的核心歧义是四个根都在数学上成立。题目通常通过以下信息确定正确结果:

  • 固定前缀,例如 flag{;
  • 冗余编码或校验位;
  • 已知消息长度;
  • 哈希值或结构化格式。
for value in rabin_decrypt(c, p, q):
    data = value.to_bytes((value.bit_length() + 7) // 8, "big")
    if data.startswith(b"flag{"):
        print(data)

与 e 为 2 的幂的关系

Rabin 对应一次平方,即 \(e=2\)。当 \(e=2^t\) 且 \(t>1\) 时,需要求更高阶的 \(2^t\) 次根或连续求平方根,候选数量通常更多。

安全说明

Rabin 的陷门问题与整数分解紧密相关,但朴素方案是确定性的、具有明文歧义,也缺少现代加密所需的完整安全性质。实际系统不应使用教科书式 Rabin 或无填充 RSA,应采用经过标准化和审查的公钥加密方案。