📜  附加秘密共享和共享激活-使用Python

📅  最后修改于: 2021-08-24 04:40:40             🧑  作者: Mango

秘密共享方案是一种加密方案,其中涉及将秘密值分解为多个碎片/份额,从而阻止单个股东完全了解原始秘密。因此,该秘密被分成多个份额,并在多个参与者之间分配。因此,对秘密值的控制是分布式的,而不是由单个方持有。

秘密共享方案的最简单示例是“附加秘密共享” ,它涉及将数字秘密分解为多个片段,这些片段加起来就等于原始秘密。分成股份后,每个股份分配给不同的参与者。没有任何个人参与者具有足够的信息来重建秘密。要重建秘密,所有参与者都必须将他们的份额集中在一起以揭示原始秘密价值。

附加秘密共享

图1:使用加性共享在三个方之间划分秘密

例子
假定存在以下条件:

  • 我们要划分的秘密由值s = 12345给出
  • 系统中的参与者人数为n = 3 。因此,我们需要获得三份,每一方各一次
  • 当各方汇集并合并其股份时,秘密就被揭示了

秘密的一个任意划分可能是: 12345 = 3512 + 2100 + 6733 。因此,第一方获得的份额值为3512,第二方获得的份额为2100,第三方获得的份额为6733。显然,除非所有三方都共享他们的份额,否则无法透露秘密。这种方案称为n出n共享方案,因为秘密重建需要所有份额。

有限域上的加性共享

按照惯例,秘密值和共享值绑定到进行所有计算的有限字段。在这种方案中,除最后一部分以外的所有部分都是随机选择的,以确保它们属于所选的有限域。假定总共n个份额中的(n-1)个是S(1),S(2),…,S(n-1) 。最终份额的计算公式为S(n)= V –(S(1)+ S(2)+…+ S(n-1)) ,其中V是原始机密的值。

概括地说,我们选择(n-1)个随机份额并计算最终份额。

import random
  
def getAdditiveShares(secret, N, fieldSize):
    '''Generate N additive shares from 'secret' in finite field of size 'fieldSize'.'''
  
    # Generate n-1 shares randomly
    shares = [random.randrange(fieldSize) for i in range(N-1)]
  
    # Append final share by subtracting all shares from secret
    # Modulo is done with fieldSize to ensure share is within finite field
    shares.append((secret - sum(shares)) % fieldSize )
    return shares
  
def reconstructSecret(shares, fieldSize):
    '''Regenerate secret from additive shares'''
    return sum(shares) % fieldSize
  
if __name__ == "__main__":
    # Generating the shares
    shares = getAdditiveShares(1234, 5, 10**5)
    print('Shares are:', shares)
      
    # Reconstructing the secret from shares
    print('Reconstructed secret:', reconstructSecret(shares, 10**5))
输出:
Shares are: [488, 62586, 9652, 49515, 78993]
Reconstructed secret: 1234

激活附加股

主动激活是指在固定间隔后刷新共享,以减少攻击者访问机密的可能性。假定攻击者可以在某个合理的时间内访问任何参与者所持有的股份。但是,单个共享的妥协并不能揭示整个秘密。这样,攻击者将必须妥协所有生成的份额才能访问实际机密。这就是主动化发挥作用的地方。使用Proactivization,可以在固定间隔后任意刷新所有共享,以使攻击者永远无法访问所有最新共享。因此,如果以某种速度刷新份额,以使对手在任何给定时间只能访问所有份额的子集,则可以保护该方案免遭损害。

Proactivization的目标是保持相同的键值,但不更改其股份代表。每个生命周期之后都会生成一组新的添加剂份额,如下所示:

  1. 每个加性份额S(i)细分为子片段d(i,1),d(i,2),…,d(i,n),这样所有d(i,j)的总和即为S(i )n是系统中的参与者人数
  2. 子片段d(i,j)由拥有方i分配给方j 。以这种方式,所有参与者交换其子片段。
  3. 要计算它的刷新份额,舞会上,增加了子片从所有其他参与者收到如下: {d(i)}^{new}={\sum_{j=1}^{n?}}{d(j, i)}

仔细观察,我们发现每个股东实际上都是在自己的股份上进行加性分享,并在参与者之间分配所产生的子股。随后,每个参与者将收到的子份额相加。以这种方式,原始秘密在刷新参与者持有的股份的同时得以保留。

激活附加股

图02:在激活中刷新了共享份额,而没有更改秘密本身

# Additive Sharing with facility to Refresh shares via Proactivization
import random
  
def getAdditiveShares(secret, N, fieldSize):
    '''Generate N additive shares from 'secret' in finite field of size 'fieldSize'.'''
  
    # Generate n-1 shares randomly
    shares = [random.randrange(fieldSize) for i in range(N-1)]
    # Append final share by subtracting all shares from secret
    shares.append((secret - sum(shares)) % fieldSize )
    return shares
  
def reconstructSecret(shares, fieldSize):
    '''Regenerate secret from additive shares'''
    return sum(shares) % fieldSize
  
def proactivizeShares(shares):
    '''Refreshed shares by proactivization'''
      
    n = len(shares)
    refreshedShares = [0]*n
  
    for s in shares:
  
        # Divide each share into sub-fragments usng additive sharing
        subShares = getAdditiveShares(s, n, 10**5)
  
        # Add subfragments of corresponding parties
        for p, sub in enumerate(subShares):
            refreshedShares[p] += sub
              
    return refreshedShares
  
if __name__ == "__main__":
    # Generating the shares
    shares = getAdditiveShares(1234, 5, 10**5)
    print('Shares are:', shares)
  
    # Running Proactivization
    newShares = proactivizeShares(shares)
    print('Refreshed Shares are:', newShares)
      
    # Reconstructing secret from refreshed shares
    print('Secret:', reconstructSecret(newShares, 10**5))
输出:
Shares are: [45142, 41833, 39277, 49009, 25973]
Refreshed Shares are: [298371, 255404, 117787, 239851, 189821]
Secret: 1234