文章总览:YuanDaiMa2048博客文章总览


同态加密算法

  • (一) 同态加密算法的主要背景
  • (二) 同态加密关键算法
    • Paillier算法详细介绍
      • 密钥生成
      • 加密
      • 解密
  • (三) 同态加密应用领域
  • (四) 实现算法对应关键函数
  • (五) 实现加法同态和乘法同态代码实现

(一) 同态加密算法的主要背景

同态加密(Homomorphic Encryption)是一种重要的密码学技术,其核心概念是能够在加密状态下执行计算,并且在解密后得到的结果与在未加密状态下执行相同计算所得到的结果等价。同态加密的发展经历了算法理论和工程研发两个方向的不断推进。

在算法理论方面,同态加密的雏形可以追溯到1978年,当时RSA算法的创始人之一Rivest等人提出了全同态加密的概念。1999年,Pascal Paillier在其论文中实现了加法同态加密,即Paillier同态加密算法。随后,2009年,Gentry提出了全同态加密算法的第一代,即FHE,这一成果具有里程碑的理论意义。2012年,第二代FHE被BGV/BFV提出,通过错误学习问题构建FHE方案,从而增强了其安全性。2013年至2015年间,第三代FHE被tFHE/FHEW提出,简化了方案并稍微提高了性能。

在算法理论发展的同时,工程方面也在不断发展。2013年,IBM推出了基于BGV算法的全同态运算库HElib。2015年,微软推出了SEAL同态加密库。2017年,CKKS提出了用于处理浮点数的FHE方案。在2017年至2018年期间,tFHE同态加密库和HEAAN同态加密库相继问世。2020年,美国国防高级研究计划局启动了全同态硬件加速计划,旨在进一步推动同态加密技术的发展。

(二) 同态加密关键算法

在同态加密算法的分类中,加法同态和乘法同态是两种重要的同态性质,描述了在密文状态下执行加法和乘法运算的能力。同态加密算法根据其支持的操作类型和执行次数的不同,可以分为三种主要类型:部分同态加密、近似同态加密和全同态加密。

  1. 部分同态加密:部分同态加密算法允许某一操作被执行无限次,但仅支持加法或乘法操作。具体来说,加法同态操作允许在密文上进行无限次的加法运算,而乘法同态操作则允许在密文上进行无限次的乘法运算。这种算法的代表包括Paillier和RSA-Paillier等。

  2. 近似同态加密:近似同态加密算法具有一定的加法同态和乘法同态性质,但是只能进行有限次的密文运算。尽管不能支持无限次的操作,但它们在一定程度上保留了同态性质。这种算法的代表包括CKKS和BFV等。

  3. 全同态加密:全同态加密算法(FHE)是最理想和强大的同态加密方案。它同时支持在密文上进行加法和乘法操作,并且能够支持无限次的密文运算。这意味着在解密后得到的结果与在未加密状态下执行相同操作所得到的结果等价。全同态加密算法的代表包括Gentry的FHE方案。

加法同态的算法有Paillier算法、DGK算法、OU算法、基于格密码的方案等,乘法同态有常见的RSA算法、ElGamal算法等。

Paillier算法详细介绍

Paillier是一个支持加法同态的公钥密码系统,由Paillier在1999年的欧密会(EUROCRYPT)上首次提出。此后,在PKC’01中提出了Paillier方案的简化版本26,是当前Paillier方案的最优方案。在众多PHE方案中,Paillier方案由于效率较高、安全性证明完备的特点,在各大顶会和实际应用中被广泛使用,是隐私计算场景中最常用的PHE实例化方案之一。

密钥生成

  1. 选择两个大质数 p p p q q q,且这两个质数不相等。

  2. 计算 n = p × q n = p \times q n=p×q λ = lcm ( p − 1 , q − 1 ) \lambda = \text{lcm}(p-1, q-1) λ=lcm(p1,q1),其中 lcm \text{lcm} lcm表示最小公倍数。

  3. 选择随机整数 $ g $,其中 g ∈ Z n 2 ∗ g \in \mathbb{Z}_{n^2}^* gZn2

  4. 计算模 n 2 n^2 n2 的乘法逆元:
    μ = ( L ( g λ m o d    n 2 ) ) − 1 m o d    n \mu = (L(g^\lambda\mod n^2))^{-1} \mod n μ=(L(gλmodn2))1modn

    • 其中函数 L L L 定义为 L ( x ) = x − 1 n L(x) = \frac{x-1}{n} L(x)=nx1
  5. 得到结果:公钥 ( n , g ) (n, g) (n,g),私钥 ( l a m b d a , μ ) (lambda, \mu) (lambda,μ)

加密

  1. 对于明文 m ∈ Z n m \in \mathbb{Z}_n mZn,选择一个随机数 r ∈ Z n ∗ r \in \mathbb{Z}_n^* rZn
  2. 密文 c c c 计算如下:
    c = g m ⋅ r n m o d    n 2 c = g^m \cdot r^n \mod n^2 c=gmrnmodn2

解密

  1. 给定密文 c c c,使用私钥 ( l a m b d a , μ ) (lambda, \mu) (lambda,μ) 来解密:
    m = L ( c λ m o d    n 2 ) ⋅ μ m o d    n m = L(c^\lambda \mod n^2) \cdot \mu \mod n m=L(cλmodn2)μmodn

(三) 同态加密应用领域

  1. 云计算:在云计算中,用户可以将计算和存储需求外包给云服务提供商,以节省自身的软硬件成本。然而,直接将明文数据交给云服务器存在安全风险。采用同态加密技术,用户可以在保护数据隐私的同时,利用云服务提供商的强大算力资源实现数据的托管存储和处理。

  2. 匿名投票系统:同态加密技术可以应用于匿名投票系统中,保障投票人的个人投票秘密。投票人可以使用公钥加密投票信息,并将加密投票发送到计票方。计票方利用同态特性进行计算,得到汇总结果,而投票人的隐私得到保护。

  3. 安全多方计算:安全多方计算是一组互不信任的参与者在不泄露私有信息的前提下进行的多方合作计算。同态加密技术在安全多方计算中起着重要作用,例如用于保护公司数据隐私的委托计算审计,以及保护基因组数据等隐私信息。

  4. 基因组分析:在基因组分析领域,同态加密技术被广泛应用以保护个人基因数据的隐私。通过全同态加密技术,个人基因数据在加密状态下进行存储和处理,避免了直接暴露敏感基因信息的风险。研究人员可以利用同态加密技术进行数据计算,例如基因型填补、关联研究等,而无需将原始基因数据解密。这种方式既保护了个人隐私,又促进了基因组学研究的发展。

  5. 深度学习:在深度学习领域,同态加密技术被应用于保护训练数据的隐私。深度学习模型通常需要大量的数据进行训练,其中可能包含了个人隐私信息。采用同态加密技术,可以在不暴露原始数据的情况下,对加密数据进行训练。这种方式不仅保护了数据隐私,还允许不同组织之间共享加密数据进行模型训练,从而加速了深度学习研究的进程。

  6. 隐私计算:在隐私计算领域,同态加密技术被用于私有信息检索,以保护用户的查询隐私。通常情况下,用户希望在查询数据时能够保护其隐私。利用同态加密技术,用户可以对查询数据进行加密处理,然后将加密查询数据发送给服务器进行计算。服务器在加密状态下进行计算操作,得到结果后返回给用户,而不知道查询的具体内容。这种方式有效地保护了用户的查询隐私。

(四) 实现算法对应关键函数

  1. 模幂运算

    def modpow(base, exponent, modulus):
        """
        计算模幂 (base^exponent) % modulus
        :param base: 基数
        :param exponent: 指数
        :param modulus: 模数
        :return: 返回计算结果
        """
        result = 1
        while exponent > 0:
            if exponent & 1 == 1:
                result = (result * base) % modulus
            exponent >>= 1
            base = (base * base) % modulus
        return result
    
  2. L(x)函数

    def L(x, n):
        """
        计算 L(x) = (x - 1) / n
        :param x: 待计算的值
        :param n: 模数
        :return: 返回计算结果
        """
        return (x - 1) // n
    
  3. 逆元计算

    def invmod(a, p, maxiter=1000000):
        """
        求模 p 下整数 a 的乘法逆元。
        如果存在整数 b 使得 (a * b) % p == 1,则 b 是 a 的逆元。
        :param a: 整数 a
        :param p: 模数 p
        :param maxiter: 最大迭代次数,默认为 1000000
        :return: 返回逆元 b
        """
        if a == 0:
            raise ValueError('0 has no inverse mod %d' % p)
        r = a
        d = 1
        for i in range(min(p, maxiter)):
            d = ((p // r + 1) * d) % p
            r = (d * a) % p
            if r == 1:
                break
            else:
                raise ValueError('%d has no inverse mod %d' % (a, p))
        return d
    
  4. 加密解密

    class PrivateKey(object):
        """
        私钥类
        """
    
        def __init__(self, p, q, n):
            self.l = (p - 1) * (q - 1)
            self.m = invmod(self.l, n)
    
        def __repr__(self):
            return '<PrivateKey: %s %s>' % (self.l, self.m)
    
    class PublicKey(object):
        """
        公钥类
        """
    
        @classmethod
        def from_n(cls, n):
            return cls(n)
    
        def __init__(self, n):
            self.n = n
            self.n_sq = n * n
            self.g = n + 1
    
        def __repr__(self):
            return '<PublicKey: %s>' % self.n
    
    def encrypt(pub, plain):
        """
        使用公钥加密明文
        :param pub: 公钥
        :param plain: 明文
        :return: 返回密文
        """
        while True:
            r = primes.generate_prime(int(round(math.log(pub.n, 2))))
            if r > 0 and r < pub.n:
                break
        cipher = (pow(pub.g, plain, pub.n_sq) * pow(r, pub.n, pub.n_sq)) % pub.n_sq
        return cipher
    
    def decrypt(priv, pub, cipher):
        """
        使用私钥解密密文
        :param priv: 私钥
        :param pub: 公钥
        :param cipher: 密文
        :return: 返回解密后的明文
        """
        plain = ((pow(cipher, priv.l, pub.n_sq) - 1 // pub.n) * priv.m) % pub.n
        return plain
    

(五) 实现加法同态和乘法同态代码实现

def e_add(pub, a, b):
    """
    同态加法:加密值 a 和 b 的同态加法
    :param pub: 公钥
    :param a: 加密值 a
    :param b: 加密值 b
    :return: 返回加法结果的密文
    """
    return a * b % pub.n_sq


def e_add_const(pub, a, n):
    """
    同态常数加法:将常数 n 加到加密值 a 上
    :param pub: 公钥
    :param a: 加密值 a
    :param n: 常数 n
    :return: 返回加法结果的密文
    """
    return a * modpow(pub.g, n, pub.n_sq) % pub.n_sq


def e_mul_const(pub, a, n):
    """
    同态常数乘法:将加密值 a 乘以常数 n
    :param pub: 公钥
    :param a: 加密值 a
    :param n: 常数 n
    :return: 返回乘法结果的密文
    """
    return modpow(a, n, pub.n_sq)

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部