RSA乘法同态

1.RSA乘法同态

RSA算法介绍

RSA算法是一种广泛使用的非对称加密算法,由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)于1977年提出。它的安全性基于大数分解的难度。下面是RSA算法的详细原理:

  1. 生成密钥:
    • 选择两个大素数 p p p q q q
    • 计算它们的乘积 n = p q n = pq n=pq n n n的长度,即其位数,决定了密钥的长度。
    • 计算欧拉函数 ϕ ( n ) = ( p − 1 ) ( q − 1 ) \phi(n) = (p-1)(q-1) ϕ(n)=(p1)(q1)
    • 选择一个整数 e e e,作为公钥指数,它必须小于 ϕ ( n ) \phi(n) ϕ(n)且与 ϕ ( n ) \phi(n) ϕ(n)互质。通常, e e e选择65537,因为它既不太大也不太小,且为质数。
    • 计算 e e e的模逆元 d d d,满足 e d ≡ 1 m o d    ϕ ( n ) ed \equiv 1 \mod \phi(n) ed1modϕ(n) d d d作为私钥指数。
  2. 加密过程:
    • 假设有一条消息 M M M,其中 M M M是一个小于 n n n的数字。
    • 加密后的消息 C C C计算为 C = M e m o d    n C = M^e \mod n C=Memodn
  3. 解密过程:
    • 使用私钥 d d d对密文 C C C进行解密,计算 M = C d m o d    n M = C^d \mod n M=Cdmodn
    • 由于 e d ≡ 1 m o d    ϕ ( n ) ed \equiv 1 \mod \phi(n) ed1modϕ(n),解密后得到的 M M M将是原始消息。

要理解为什么当 e × d e \times d e×d 1 1 1加上 φ ( n ) \varphi(n) φ(n)的倍数时, ( M e ) d (M^e)^d (Me)d n n n总是等于 M M M,我们需要依赖于数论中的一些基本概念,特别是费马小定理和欧拉定理。

  1. 费马小定理:费马小定理指出,如果 p p p是一个质数,且 a a a是任何不是 p p p的倍数的整数,则 a p − 1 ≡ 1 m o d    p a^{p-1} \equiv 1 \mod p ap11modp。这意味着 a p − 1 a^{p-1} ap1除以 p p p的余数是1。

  2. 欧拉定理:欧拉定理是费马小定理的推广。它指出,如果 n n n a a a是互质的,则 a φ ( n ) ≡ 1 m o d    n a^{\varphi(n)} \equiv 1 \mod n aφ(n)1modn,其中 φ ( n ) \varphi(n) φ(n)是欧拉函数,表示小于或等于 n n n的正整数中与 n n n互质的数的数量。

在RSA加密中, n = p × q n = p \times q n=p×q,其中 p p p q q q是两个不同的质数,所以对于任何与 n n n互质的整数 M M M(即几乎所有小于 n n n的整数),欧拉定理告诉我们 M φ ( n ) ≡ 1 m o d    n M^{\varphi(n)} \equiv 1 \mod n Mφ(n)1modn

现在,如果 e × d ≡ 1 m o d    φ ( n ) e \times d \equiv 1 \mod \varphi(n) e×d1modφ(n),那么存在一个整数 k k k使得 e × d = 1 + k × φ ( n ) e \times d = 1 + k \times \varphi(n) e×d=1+k×φ(n)。所以对于任何整数 M M M

M e × d = M 1 + k × φ ( n ) = M × ( M φ ( n ) ) k M^{e \times d} = M^{1 + k \times \varphi(n)} = M \times (M^{\varphi(n)})^k Me×d=M1+k×φ(n)=M×(Mφ(n))k

根据欧拉定理,我们知道 ( M φ ( n ) ) k ≡ 1 k m o d    n (M^{\varphi(n)})^k \equiv 1^k \mod n (Mφ(n))k1kmodn。所以,

M e × d ≡ M × 1 k = M m o d    n M^{e \times d} \equiv M \times 1^k = M \mod n Me×dM×1k=Mmodn

因此,当 ( M e ) d (M^e)^d (Me)d n n n时,它总是等于 M M M。这是RSA加密能够成功解密的数学基础。

在RSA加密中,如果加密消息 M M M n n n不互质(即 M M M n n n有一个以上的公共质因数),则可能会出现问题。由于 n = p × q n = p \times q n=p×q是两个质数的乘积,如果 M M M n n n不互质,那么 M M M必须是 p p p q q q的倍数。

在实际应用中,这种情况几乎不会发生,原因如下:

  1. 大质数的选择:在RSA中, p p p q q q通常选择为非常大的质数,这意味着 n n n也会非常大。因此,随机选择的消息 M M M n n n不互质的概率非常小。

  2. 消息编码:在实际的RSA实现中,消息 M M M通常会通过某种形式的编码(如填充方案)进行处理,以确保它们与 n n n互质。这样的编码不仅增加了安全性,还帮助避免了 M M M n n n不互质的情况。

  3. 小概率事件:即使没有特殊的编码,由于 n n n非常大,随机选择的消息 M M M n n n不互质的概率仍然非常小。

如果在极少数情况下 M M M确实不与 n n n互质,那么RSA加密可能不会正确工作。然而,由于这种情况发生的概率极低,并且现代RSA实现通常包含了防止这种情况发生的机制,所以在实际应用中几乎可以忽略这一问题。

RSA算法的安全性基于大数分解的困难性。目前没有已知的有效方法可以在合理的时间内分解一个大的 n n n。因此,只要 p p p q q q足够大,RSA算法就被认为是安全的。但是,如果 p p p q q q的值泄露或者它们太小,那么算法的安全性就会受到威胁。此外,随着量子计算的发展,RSA的安全性可能会受到挑战,因为量子计算机潜在地能够在多项式时间内分解大数。

为什么这样的设计是安全的?

RSA算法的安全性基于大数分解的困难性,这是因为在当前的计算能力下,将一个大整数分解为其质因数是一项极其困难的任务。下面详细解释为什么这一点对RSA算法至关重要:

  1. 大数分解的计算难度:

    • 当我们选择两个大素数 p p p q q q并将它们相乘得到 n n n时,逆向工程——即将 n n n分解回 p p p q q q——在数学上是非常困难的。对于较小的数,分解可能是可行的,但随着数的增大,所需的计算资源和时间呈指数级增长。
  2. RSA算法的工作原理:

    • RSA算法的安全性依赖于公钥和私钥的生成。公钥包含 n n n e e e,而私钥是 d d d。要从公钥计算出私钥,攻击者需要知道 n n n的质因数 p p p q q q。只要 p p p q q q保持秘密,通过公钥计算私钥就几乎是不可能的。
  3. 小素数的问题:

    • 如果 p p p q q q太小,或者它们的选择方式使它们容易被预测,那么通过现代计算机的力量可以相对容易地分解 n n n。这会暴露出私钥,从而破坏整个加密系统的安全性。
  4. 量子计算的威胁:

    • 量子计算机利用量子比特进行计算,这使它们在处理某些特定类型的问题时比经典计算机更有效率。尤其是,量子计算机潜在地可以运行像Shor算法这样的算法,这种算法在理论上可以在多项式时间内分解大数。如果能够实现足够强大的量子计算机,RSA算法的安全性将会受到严重威胁。

因此,RSA算法的安全性在很大程度上取决于当前计算技术无法在实际时间内分解大的 n n n。但这也意味着随着计算技术的发展,特别是量子计算的进步,RSA算法可能需要适应更高的安全标准,例如使用更大的密钥尺寸,或者转向量子安全的加密方法。

RSA的乘法同态性质

RSA算法本身并不是一个同态加密算法,但它确实展示了一定程度的同态性质。在RSA的上下文中,我们可以观察到乘法同态的一个简单示例。这意味着,如果你有两个加密的消息,你可以在不解密的情况下将它们相乘,并且结果仍然是有效的加密形式。

让我们通过一个简单的例子来展示这一点。假设我们有两个消息 M 1 M_1 M1 M 2 M_2 M2,以及RSA的公钥 ( n , e ) (n, e) (n,e)和私钥 d d d

加密

加密消息 M 1 M_1 M1 M 2 M_2 M2的过程是:

  1. 加密 M 1 M_1 M1 C 1 = M 1 e m o d    n C_1 = M_1^e \mod n C1=M1emodn
  2. 加密 M 2 M_2 M2 C 2 = M 2 e m o d    n C_2 = M_2^e \mod n C2=M2emodn

乘法同态性

乘法同态性意味着对加密的消息进行乘法运算等同于对原始消息进行乘法运算,然后加密结果。也就是说, C 1 × C 2 C_1 \times C_2 C1×C2的解密结果应该等于 M 1 × M 2 M_1 \times M_2 M1×M2的加密结果。

  1. 计算 C 1 × C 2 C_1 \times C_2 C1×C2 C m u l t = C 1 × C 2 = M 1 e × M 2 e m o d    n C_{mult} = C_1 \times C_2 = M_1^e \times M_2^e \mod n Cmult=C1×C2=M1e×M2emodn
  2. 重写 C m u l t C_{mult} Cmult C m u l t = ( M 1 × M 2 ) e m o d    n C_{mult} = (M_1 \times M_2)^e \mod n Cmult=(M1×M2)emodn

解密

解密 C m u l t C_{mult} Cmult将得到 M 1 × M 2 M_1 \times M_2 M1×M2

  1. 解密 C m u l t C_{mult} Cmult M m u l t = C m u l t d m o d    n M_{mult} = C_{mult}^d \mod n Mmult=Cmultdmodn
  2. 由于 ( M 1 × M 2 ) e × d ≡ M 1 × M 2 m o d    n (M_1 \times M_2)^{e \times d }\equiv M_1 \times M_2 \mod n (M1×M2)e×dM1×M2modn,因此 M m u l t = M 1 × M 2 M_{mult} = M_1 \times M_2 Mmult=M1×M2

4. 代码实现

import random
from sympy import isprime, mod_inverse


def generate_prime_candidate(length):
    """ 随机生成一个奇数 """
    p = random.getrandbits(length)
    p |= (1 << length - 1) | 1
    return p


def generate_large_prime(length):
    """ 生成指定长度的大素数 """
    p = 4
    while not isprime(p):
        p = generate_prime_candidate(length)
    return p


def generate_keys(bit_length):
    """ 生成RSA密钥对 """
    p = generate_large_prime(bit_length)
    q = generate_large_prime(bit_length)
    n = p * q
    phi_n = (p - 1) * (q - 1)

    e = 65537
    d = mod_inverse(e, phi_n)

    # 公钥 (e, n) 和 私钥 (d, n)
    return ((e, n), (d, n))


def encrypt(public_key, plaintext):
    """ 使用公钥加密明文 """
    e, n = public_key
    ciphertext = pow(plaintext, e, n)
    return ciphertext


def decrypt(private_key, ciphertext):
    """ 使用私钥解密密文 """
    d, n = private_key
    decrypted_int = pow(ciphertext, d, n)
    return decrypted_int


def homomorphic_multiply(ciphertext1, ciphertext2, public_key):
    """ 同态乘法:乘两个密文 """
    e, n = public_key
    # 将两个密文相乘后对 n 取模
    return (ciphertext1 * ciphertext2) % n


# 生成密钥
public_key, private_key = generate_keys(16)  # 此处为16位,仅作演示;实际应用中应使用1024位或2048位

# 加密消息
plaintext1 = 500
plaintext2 = 621
ciphertext1 = encrypt(public_key, plaintext1)
print('密文:', ciphertext1)
print('明文:', decrypt(private_key, ciphertext1))
ciphertext2 = encrypt(public_key, plaintext2)
print('密文:', ciphertext2)
print('明文:', decrypt(private_key, ciphertext2))

# 同态乘法
ciphertext_he = homomorphic_multiply(ciphertext1, ciphertext2, public_key)

# 解密同态乘法结果
decrypted_he = decrypt(private_key, ciphertext_he)
print('同态密文:', ciphertext_he)
print('同态明文:', decrypted_he)

输出:

密文: 354969104
明文: 500
密文: 964115344
明文: 621
同态密文: 1648575948
同态明文: 310500
  • 22
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值