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

**Example**

Assume that the following conditions exist:

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. And to begin with your Machine Learning Journey, join the **Machine Learning - Basic Level Course**

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

- 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)**andis the number of participants in the system**n**

- The sub-fragment
**d(i, j)**is distributed by the owning party,*“*, to the party**i**“*“*. In this manner, all participants exchange their subfragments.**j**“ - To compute its refreshed share, party
adds the sub-fragments it received from all other participants as follows:**i**

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.

## Python3

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