GeeksforGeeks App
Open App
Browser
Continue

# Additive Secret Sharing and Share Proactivization – Using Python

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.

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: . 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.

## Python3

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

Output:

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

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 received from all other participants as follows:

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

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

## Python3

 # Additive Sharing with facility to Refresh shares via Proactivizationimport 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 using 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))

Output:

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

My Personal Notes arrow_drop_up