Skip to content
Related Articles

Related Articles

Additive Secret Sharing and Share Proactivization – Using Python
  • Last Updated : 01 Aug, 2020

A Secret Sharing Scheme is a Cryptographic Scheme that involves the breaking up of a secret value into multiple fragments/shares in a manner that prevents a single shareholder from having complete knowledge of the original secret. Thus, the secret is divided into multiple shares and distributed among multiple participants. Therefore, the control over the secret value is distributed and not held by a single party.

The simplest example of a Secret Sharing Scheme is Additive Secret Sharing which involves breaking a numeric secret into fragments that add up to the original secret. Once divided into shares, each share is distributed to different participants. None of the individual participants have enough information to reconstruct the secret. To reconstruct the secret, all participant must pool their shares together to reveal the original secret value.

Additive secret sharing

Fig 1: Division of a secret among three parties using Additive Sharing

Example
Assume that the following conditions exist:

  • The secret we want to divide is given by the value s = 12345
  • The number of participants in the system are n = 3. Thus, we need to obtain three shares, one for each party
  • When all parties pool and combine their shares, the secret is revealed

One arbitrary division of the secret might be: 12345 = 3512 + 2100 + 6733. Thus, the first party is given a share with value 3512, the second party is given 2100 and the third party gets 6733. Clearly, unless all three parties pool their shares, the secret cannot be revealed. Such a scheme is called an n-out-of-n sharing scheme since all shares are required for secret reconstruction.

Additive Sharing over a Finite Field

Conventionally, the secret values and share values are bound to a finite field where all computations take place. All but the last shares, in such a scheme, are picked randomly, ensuring they belong to the chosen finite field. Assume (n-1) out of the total n shares are S(1), S(2), …, S(n-1). The final share is computed as S(n) = V – (S(1) + S(2) + … + S(n-1)) where V is the value of the original secret.



To recapitulate, we pick (n-1) random shares and compute the final share.

filter_none

edit
close

play_arrow

link
brightness_4
code

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))

chevron_right


Output:

Shares are: [488, 62586, 9652, 49515, 78993]
Reconstructed secret: 1234

Proactivization of Additive Shares

Proactivization refers to the refreshing of the shares after fixed intervals to reduce the possibility of an attacker accessing the secret. It is assumed that an attacker can gain access to the shares held by any participant in some reasonable time. However, the compromise of a single share does not reveal the entire secret. As such, the attacker will have to compromise all the generated shares to gain access to the actual secret. This is where Proactivization comes into play. Using Proactivization, all shares are arbitrarily refreshed after a fixed interval such that the attacker may never have access to all of the most current shares. Thus, if the shares are refreshed at a rate such that the adversary only has access to just a subset of all shares at any given point, the scheme is protected from compromise.

The goal with Proactivization is to maintain the same key value yet to change its share representation. A new set of additive shares are generated after each lifecycle as follows:

  1. Each additive share S(i) is subdivided into sub-fragments d(i, 1), d(i, 2), …, d(i, n) such the summation of all d(i, j) yields S(i) and n is the number of participants in the system
  2. The sub-fragment d(i, j) is distributed by the owning party, i, to the party j. In this manner, all participants exchange their subfragments.
  3. To compute its refreshed share, party i adds the sub-fragments it recieved from all other participants as follows: {d(i)}^{new}={\sum_{j=1}^{n?}}{d(j, i)}

On closer observation, we see that each shareholder essentially performs additive sharing on their own shares and distibuted the generated sub-shares among the participants. Subsequently, each participant adds up the recieved sub-shares. In this manner, the original secret is preserved while refreshing the shares held by the participants.

Proactivization of Additive Shares

Fig 02: Additive shares are refreshed in Proactivization without altering the secret itself

filter_none

edit
close

play_arrow

link
brightness_4
code

# 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))

chevron_right


Output:

Shares are: [45142, 41833, 39277, 49009, 25973]
Refreshed Shares are: [298371, 255404, 117787, 239851, 189821]
Secret: 1234

Attention geek! Strengthen your foundations with the Python Programming Foundation Course and learn the basics.

To begin with, your interview preparations Enhance your Data Structures concepts with the Python DS Course.

My Personal Notes arrow_drop_up
Recommended Articles
Page :