SPDZ详细介绍及代码实现

目录

Part 1 使用预先计算的三元组进行安全计算

Part 2 三元组的扩充


Part 1 使用预先计算的三元组进行安全计算

这是最开始的一篇SPDZ文章,与其他的安全计算有所不同,SPDZ支持双方私有值计算,它允许将部分计算转移到离线阶段。最早在SPDZ‘12DKLPSS’13中提出,存在几种实现方式比如 cryptography group。我们的目标只是被动安全性,并假设一个加密提供者将诚实地生成所需的三元组。存在多个数据提供者和两台服务器,他们都是半诚实模型。乘法三元组

简单的加法共享数据:

def share(secret):
    share0 = random.randrange(Q)
    share1 = (secret - share0) % Q
    return [share0, share1]

恢复秘密:

def reconstruct(share0, share1):
    return (share0 + share1) % Q
class PrivateValue:

    def __init__(self, value, share0=None, share1=None):
        if not value is None:
            share0, share1 = share(value)
        self.share0 = share0
        self.share1 = share1

    def reconstruct(self):
        return PublicValue(reconstruct(self.share0, self.share1))

线性操作:加·减x+y,x-y

class PrivateValue:

    ...

    def add(x, y):
        if type(y) is PublicValue:
            share0 = (x.share0 + y.value) % Q
            share1 =  x.share1
            return PrivateValue(None, share0, share1)    
        if type(y) is PrivateValue:
            share0 = (x.share0 + y.share0) % Q
            share1 = (x.share1 + y.share1) % Q
            return PrivateValue(None, share0, share1)

    def sub(x, y):
        if type(y) is PublicValue:
            share0 = (x.share0 - y.value) % Q
            share1 =  x.share1
            return PrivateValue(None, share0, share1)
        if type(y) is PrivateValue:
            share0 = (x.share0 - y.share0) % Q
            share1 = (x.share1 - y.share1) % Q
            return PrivateValue(None, share0, share1)
x = PrivateValue(5)
y = PrivateValue(3)

z = x + y
assert z.reconstruct() == 8

每个服务器执行共享实现常数乘:k·x

class PrivateValue:

    ...

    def mul(x, y):
        if type(y) is PublicValue:
            share0 = (x.share0 * y.value) % Q
            share1 = (x.share1 * y.value) % Q
            return PrivateValue(None, share0, share1)
x = PrivateValue(5)
y = PublicValue(3)

z = x * y
assert z.reconstruct() == 15

变量乘 x*y

class PrivateValue:

    def generate_mul_triple():
        a = random.randrange(Q)
        b = random.randrange(Q)
        c = (a * b) % Q
        return PrivateValue(a), PrivateValue(b), PrivateValue(c)
    def mul(x, y):
        if type(y) is PublicValue:
            ...
        if type(y) is PrivateValue:
            a, b, a_mul_b = generate_mul_triple()
   # local masking followed by communication of the reconstructed values
            alpha = (x - a).reconstruct()
            beta  = (y - b).reconstruct()
            # local re-combination           
            return alpha.mul(beta) + \
                   alpha.mul(b) + \
                   a.mul(beta) + \
                   a_mul_b

对于原理可参考文章:乘法三元组

Part 2 三元组的扩充

平方:

class PrivateValue:
    
    def generate_square_triple():
        a = random.randrange(Q)
        aa = pow(a, 2, Q)
        return PrivateValue(a), PrivateValue(aa)
    
    def square(x):
        a, aa = generate_square_triple()
        alpha = (x - a).reconstruct()
        return alpha.square() + \
               (a * alpha) * 2 + \
               aa

立方:

def generate_pows_triple(exponent, shape):
    a = np.random.randint(Q, size=shape)
    return [ share(np.power(a, e) % Q) for e in range(1, exponent+1) ]
def pows(x, triple):
    # local masking     a = triple[0]
    v = sub(x, a)
    # communication: the players simultanously send their share to the other     
    epsilon = reconstruct(v)
    # local combination to compute all powers     x_powers = []
    for exponent in range(1, len(triple)+1):
        # prepare all term values         a_powers = [ONE] + triple[:exponent]
        e_powers = [ pow(epsilon, e, Q) for e in range(exponent+1) ]
        coeffs   = [ binom(exponent, k) for k in range(exponent+1) ]
        # compute and sum terms         
        terms = ( mul_public(a,e*c) for a,e,c in zip(a_powers,reversed(e_powers),coeffs) )
        x_powers.append(reduce(lambda x,y: add(x, y), terms))
    return x_powers

n次方:

def generate_statistical_mask():
    return random.randrange(2*BOUND * 10**KAPPA)

def generate_zero_triple(field):
    return share(0, field)

def convert(x, from_field, to_field, zero_triple):
    # local mapping to positive representation     x = add_public(x, BOUND, from_field)
    # local masking and conversion by player 0     r = generate_statistical_mask()
    y0 = (zero_triple[0] - r) % to_field
    # exchange of masked share: one round of communication     e = (x[0] + r) % from_field
    # local conversion by player 1     xr = (e + x[1]) % from_field
    y1 = (zero_triple[1] + xr) % to_field
    # local mapping back from positive representation     y = [y0, y1]
    y = sub_public(y, BOUND, to_field)
    return y

def upshare(x, large_zero_triple):
    return convert(x, Q, P, large_zero_triple)

def downshare(x, small_zero_triple):
    return convert(x, P, Q, small_zero_triple)

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值