Writing

Iris nutshellensisleg. cstef, 29.xi.2024

Shamir Secret Sharing in a Nutshell

How to split a secret among multiple persons, so that only any subset of n people can recover it ?

16 min readcrypto

[!NOTE] I am not a cryptographer, nor a mathematician. This article is the result of my own research and understanding of the subject. If you find any mistakes, please let me know!

The vast majority of what is written here is taken from various sources, which are listed at the end of this article. I highly recommend you to read them if you want to dive deeper into the subject.

The main idea behind Shamir Secret Sharing (SSS) is to split a secret 𝑠 into 𝑛 parts, such that any 𝑘 parts can be used to reconstruct the secret, but any 𝑘−1 parts are not enough to do so, and do not give any information about the secret.

Splitting the Secret

Let’s take the following example: we want to split the secret 𝑠=42 into 𝑛=5 parts, such that any 𝑘=3 parts can be used to reconstruct the secret. It is supposed we are working in a finite field 𝔽𝑞 for the entirety of this post.

What the hell is

𝔽𝑞?

A finite field 𝔽𝑞 where 𝑞=𝑝𝑘|𝑝∈𝒫︀ (𝑞 is a prime power), is a finite set of elements, on which we can apply our usual additions and multiplications.

The most common finite field is the set of integers modulo 𝑞, ℤ/𝑞ℤ=ℤ𝑞, where all computations are taken mod𝑞, which means that we have:

ℤ𝑞={0,1,2,…,𝑞−1}

In the case of an elliptic curve, 𝑞 is our curve’s order.

The first step is to sample a random polynomial 𝑓(𝑥)=𝑃𝑘−1(𝑥)=𝑎0+𝑎1𝑥+…+𝑎𝑘−1𝑥𝑘−1 of degree 𝑘−1 such that 𝑎0=𝑠. This gives us the property 𝑓(0)=𝑠.

𝑓(𝑥)=𝑃2(𝑥)=42+5𝑥+3𝑥2

Our splits, also called shares, are in fact just points of our polynomial. We can generate them by evaluating 𝑓(𝑥) for 𝑥∈𝑆={1,2,3,4,5}. Do not evaluate for 𝑥=0 as this would obviously just give away the secret.

𝑧1=𝑓(1)=42+5+3=50𝑧2=𝑓(2)=42+10+12=64𝑧3=𝑓(3)=42+15+27=84𝑧4=𝑓(4)=42+20+48=110𝑧5=𝑓(5)=42+25+75=142

Thus, our shares are 𝑍1(1,50), 𝑍2(2,64), 𝑍3(3,84), 𝑍4(4,110) and 𝑍5(5,142).

Let’s now plot the polynomial 𝑓(𝑥):

Reconstructing the Secret

We know that 𝑛+1 points 𝑍𝑖(𝑥𝑖,𝑦𝑖)|𝑖∈𝑆 will suffice to construct the polynonial 𝑃𝑛(𝑥) of degree 𝑛.

In our case, deg(𝑓(𝑥))=𝑘−1, so we need (𝑘−1)+1=𝑘 points to restore 𝑓(𝑥), just as described in the beginning.

Based on the shares we generated earlier, let’s take 𝑍1(1,50), 𝑍3(3,84) and 𝑍5(5,142) (our recovery group 𝑅={1,3,5}) to reconstruct the polynomial 𝑓(𝑥) using Lagrange interpolation:

[!TIP] If you’re curious about Lagrange interpolation, I have written a quick explaination for you to read.

𝑓(𝑥)=∑𝑖∈𝑅𝑦𝑖⋅∏𝑗∈𝑅,𝑗≠𝑖𝑥−𝑥𝑖𝑥𝑖−𝑥𝑗⏞𝑙𝑖(𝑥)
𝑓(𝑥)=50⋅(𝑥−3)(𝑥−5)(1−3)(1−5)+84⋅(𝑥−1)(𝑥−5)(3−1)(3−5)+142⋅(𝑥−1)(𝑥−3)(5−1)(5−3)=254(𝑥−5)(𝑥−3)+714(𝑥−1)(𝑥−3)−21(𝑥−5)(𝑥−1)=42+5𝑥+3𝑥2

It’s even cooler when represented graphically:

Commitments, Proofs and Verifications

In a perfect world where everyone is honest and where there are no transmission errors caused by cosmic rays, we could just send the shares to the participants and call it a day. But guess what? Sh*t happens.

We need a way to check that the share we receive as a shareholder after the secret has been split is actually a valid one. You could gather with other bearers and collectively verify if the recovered secret is correct, but that is just too much hassle for such a simple task.

Instead, let’s take advantage of the properties of elliptic curves to create a commitment scheme. After we have generated our polynomial 𝑓(𝑥), we can take each coefficient 𝑎𝑖 and multiply it by the generator point 𝐺 of the curve. This gives us a few values 𝐶={𝜙0,𝜙1,…,𝜙𝑘−1}|𝜙𝑖=𝑎𝑖⋅𝐺 that we can send to the shareholders.

[!TIP] If you are not familiar with basic elliptic curve stuff, I recommend that you read my post on the subject or the references listed at the end of this article.

When a shareholder wants to verify their share 𝑍𝑖=(𝑖,𝑓(𝑖)), they can check with the following equation:

𝑓(𝑖)⋅𝐺=∑𝑗=0𝑘−1(𝜙𝑗⋅𝑖𝑗)=𝜙0+𝜙1𝑖+𝜙2𝑖2+…+𝜙𝑘−1𝑖𝑘−1=𝑎0⋅𝐺+(𝑎1⋅𝐺)𝑖+(𝑎2⋅𝐺)𝑖2+…+(𝑎𝑘−1⋅𝐺)𝑖𝑘−1=(𝑎0+𝑎1𝑖+𝑎2𝑖2+…+𝑎𝑘−1𝑖𝑘−1)⋅𝐺=∑𝑗=0𝑘−1(𝑎𝑗𝑖𝑗)⋅𝐺=𝑓(𝑖)⋅𝐺

You could see this procedure as computing the “public keys” of the coefficients. This method is also called “Feldman’s Verifiable Secret Sharing”.

One may argue that disclosing 𝑎0⋅𝐺=𝑠⋅𝐺 could give information about the polynomial, but if we suppose that 𝑠 is an EC secret key, the public key 𝑠⋅𝐺 is supposed public and may be shared. Finding 𝑠 with 𝑠⋅𝐺 comes down to solving the discrete logarithm problem, which is supposed really hard here.

Verifying that 𝑓(0) is a private key

We know some public key 𝑃=𝑝⋅𝐺 and we want to verify that the secret being shared is actually the private key 𝑝. This can be done by first checking if the commitments 𝐶={𝜙0,𝜙1,…,𝜙𝑘−1} are valid, and then verifying that 𝜙0=𝑝⋅𝐺=𝑃.

∧{𝑓(𝑗)⋅𝐺=?∑𝑖=0𝑘−1𝜙𝑖⋅𝑗𝑖𝜙0=𝑝⋅𝐺=𝑃⟺The secret is𝑝

Pedersen’s Verifiable Secret Sharing (PVSS)

Another way the dealer could commit to the polynomial he generated without directly sharing 𝑠⋅𝐺, is to add a so-called “blinding polynomial”, a pretty common concept in cryptography.

Let’s now instead take 𝜙𝑖=𝑎𝑖⋅𝐺+𝑏𝑖⋅𝐻 where 𝑏𝑖 comes from a randomly generated polynomial 𝑔(𝑥)=𝑏0+𝑏1𝑥+…+𝑏𝑘−1𝑥𝑘−1, our blinding polynomial. 𝐻≠𝐺 is just another generator point on the curve. The dealer will now needs to distribute slightly different shares 𝑍𝑖=(𝑖,𝑓(𝑖),𝑔(𝑖)).

Shareholders may now verify their shares with:

𝑓(𝑖)⋅𝐺+𝑔(𝑖)⋅𝐻=∑𝑗=0𝑘−1(𝜙𝑗⋅𝑖𝑗)=∑𝑗=0𝑘−1((𝑎𝑖⋅𝐺+𝑏𝑖⋅𝐻)⋅𝑖𝑗)=∑𝑗=0𝑘−1(𝑎𝑗𝑖𝑗)⋅𝐺+∑𝑗=0𝑘−1(𝑏𝑗𝑖𝑗)⋅𝐻=𝑓(𝑖)⋅𝐺+𝑔(𝑖)⋅𝐻

This second method is known as “Pedersen’s Verifiable Secret Sharing”.

Bob just got hit by a bus, what now?

Our good old friend disappeared along with his share, and now other bearers are scared of losing too many shares until they can’t recover the secret. They could reiterate the dealing procedure by all sending their shares to a single person which then redistributes the new ones. However this is not feasible in the case where everyone distrusts each other. We need a multi-computational way of re-issuing a new share without someone ever recovering the secret.

We will need 𝑘 shareholders, denoted 𝑅 to re-issue a new share 𝑍ℓ=(ℓ,𝑓(ℓ))=(ℓ,𝑧ℓ).

Each shareholder begins by computing their Lagrange multiplier:

𝑙𝑖(ℓ)=∏𝑗∈𝑅,𝑗≠𝑖ℓ−𝑗𝑖−𝑗

After multiplying with their share 𝑧𝑖=𝑓(𝑖), they randomly split it into 𝑘 so-called Lagrange-parts 𝜕𝑖,𝑗 in order to distribute them to other bearers 𝑗:

𝑧𝑖⋅𝑙𝑖=𝜕𝑖,1+𝜕𝑖,2+…+𝜕𝑖,𝑘

The exchange matrix 𝐸 can be represented as:

𝐸𝑘×𝑘=(𝜕1,1𝜕1,2⋯𝜕1,𝑘𝜕2,1𝜕2,2⋯𝜕2,𝑘⋮⋮⋱⋮𝜕𝑘,1𝜕𝑘,2⋯𝜕𝑘,𝑘)

Where the 𝑖th row corresponds to the Lagrange-parts that the shareholder 𝑖 will send and the 𝑗th column to the Lagrange-parts the shareholder 𝑗 will receive.

Each shareholder 𝑗 computes the partial-share:

𝜎𝑗=∑𝑖∈𝑅𝜕𝑖,𝑗

Where 𝜕𝑖,𝑗 is the 𝑗th Lagrange-part of 𝑖. They respectively send 𝜎𝑗 to the new bearer ℓ, which finally computes his share:

𝑧ℓ=∑𝑖∈𝑅𝜎𝑗

This can be rewritten as:

∑𝑗∈𝑅𝜎𝑗=∑𝑗∈𝑅∑𝑖∈𝑅𝜕𝑗,𝑖=∑𝑖∈𝑅(∑𝑗∈𝑅𝜕𝑗,𝑖)=∑𝑖∈𝑅(𝜕1,𝑖+𝜕2,𝑖+…+𝜕3,𝑖)=∑𝑖∈𝑅𝑧𝑖⋅𝑙𝑖=𝑓(ℓ)

Inception

Another angle to tackle this problem from is to re-use Secret Sharing inside our Secret Sharing scheme (Inception, anyone?).

Let’s say we have our recovery group 𝑅, our new shareholders 𝑁 and 𝐴=𝑅∪𝑁 for convenience.

  1. Each shareholder 𝑖∈𝑅 generates a random polynomial 𝑔𝑖(𝑥) of degree 𝑘−1.
  2. They each compute the auxiliary shares 𝑑𝑖,𝑗=𝑔𝑖(𝑗) for 𝑗∈𝐴.
  3. Every shareholder 𝑗∈𝐴 receives the auxiliary shares 𝑑𝑖,𝑗 from the recovery group.
  4. Each shareholder 𝑗∈𝑅 computes the aggregated share 𝐻(𝑗)=𝑢𝑗=𝑧𝑗+∑𝑖∈𝑅𝑑𝑖,𝑗 and shares it to everyone in 𝑁.
  5. Each future bearer ℓ∈𝑁 can interpolate the polynomial 𝐻(𝑥) from the shares 𝑢𝑗|𝑗∈𝑅 and compute their share
    𝑧ℓ=𝐻(ℓ)−∑𝑖∈𝑅𝑑𝑖,ℓ=𝑢ℓ−∑𝑖∈𝑅𝑑𝑖,ℓ

Let’s take a look at the math:

𝑧ℓ=(𝐻(ℓ)−∑𝑖∈𝑅𝑑𝑖,ℓ)|ℓ∈𝑁=∑𝑖∈𝑅(𝑧𝑖+∑𝑘∈𝑅𝑔𝑘(𝑖))⋅∏𝑗∈𝑅,𝑗≠𝑖ℓ−𝑗𝑖−𝑗⏟𝐻(ℓ)−∑𝑖∈𝑅𝑔𝑖(ℓ)=∑𝑖∈𝑅(𝑧𝑖⋅∏𝑗∈𝑅,𝑗≠𝑖ℓ−𝑗𝑖−𝑗)⏟𝑓(ℓ)+∑𝑖∈𝑅(∑𝑘∈𝑅𝑔𝑘(𝑖)⋅∏𝑗∈𝑅,𝑗≠𝑖ℓ−𝑗𝑖−𝑗)−∑𝑖∈𝑅𝑔𝑖(ℓ)=𝑓(ℓ)+∑𝑘∈𝑅∑𝑖∈𝑅𝑔𝑘(𝑖)⋅∏𝑗∈𝑅,𝑗≠𝑖ℓ−𝑗𝑖−𝑗⏟𝑔𝑘(ℓ)−∑𝑖∈𝑅𝑔𝑖(ℓ)=𝑓(ℓ)+∑𝑘∈𝑅𝑔𝑘(ℓ)−∑𝑖∈𝑅𝑔𝑖(ℓ)⏟= 0=𝑓(ℓ)

But wait! We just learnt how to implement a secure, verifiable secret sharing scheme and we aren’t even using it!

Verifiable Inception

Let’s review the protocol, this time including relevant checks to ensure the data we’re receiving is genuine. We assume the original dealer was a good guy and already used Feldman’s VSS, providing the commitments 𝐶={𝜙0,𝜙1,…,𝜙𝑘−1}|𝜙𝑖=𝑎𝑖⋅𝐺 for the OG polynomial 𝑓(𝑥)=𝑎0+𝑎1𝑥+…+𝑎𝑘−1𝑥𝑘−1 to everyone.

  1. Each shareholder 𝑖∈𝑅 generates a random polynomial 𝑔𝑖(𝑥)=𝑏𝑖,0+𝑏𝑖,1𝑥+…+𝑏𝑖,𝑘−1𝑥𝑘−1 of degree 𝑘−1.
  2. They also compute and share for 𝑗∈𝑅 to see their commitments:
    Γ𝑖={𝜓𝑖,0,𝜓𝑖,1,…,𝜓𝑖,𝑘−1}|𝜓𝑖,𝑗=𝑏𝑖,𝑗⋅𝐺
  3. They each compute the auxiliary shares 𝑑𝑖,𝑗=𝑔𝑖(𝑗) for 𝑗∈𝐴, and shares them once they have received all other Γ𝑖|𝑖∈𝑅
  4. Every shareholder 𝑗∈𝐴 receives the auxiliary shares 𝑑𝑖,𝑗 from 𝑖∈𝑅 and checks whether they match Γ𝑖
    𝑑𝑖,𝑗⋅𝐺=∑𝑚=0𝑘−1𝜓𝑖,𝑚⋅𝑗𝑚=∑𝑚=0𝑘−1𝑏𝑖,𝑚⋅𝐺⋅𝑗𝑚=∑𝑚=0𝑘−1(𝑏𝑖,𝑚⋅𝑗𝑚),𝑔𝑖(𝑗)⋅𝐺=𝑔𝑖(𝑗)⋅𝐺
  5. Before computing anything else, each shareholder 𝑗∈𝑅 commits to the upcoming 𝐻(𝑥) polynomial and sends it to 𝑖∈𝐴:
    𝑇={𝜃𝑖}𝑖∈𝑅|𝜃𝑖=∑𝑘∈𝑅𝜓𝑖,𝑘
  6. Each shareholder 𝑗∈𝑅 computes the aggregated share 𝐻(𝑗)=𝑢𝑗=𝑧𝑗+∑𝑖∈𝑅𝑑𝑖,𝑗.
  7. Each inductee 𝑖∈𝑁 first waits to receive all 𝑇, checks that they are the same from everyone, and then receives 𝑢𝑗|𝑗∈𝑅.
  8. Each future shareholder 𝑖∈𝑁 checks whether each given 𝑢𝑗|𝑗∈𝑅 is genuine:
    𝑢𝑗⋅𝐺=∑𝑖=0𝑘−1𝜙𝑖+∑𝑖∈𝑅𝜃𝑖=∑𝑖=0𝑘−1𝑎𝑖𝑗𝑖⋅𝐺+∑𝑖∈𝑅∑𝑚∈𝑅𝜓𝑖,𝑚=∑𝑖=0𝑘−1𝑎𝑖𝑗𝑖⋅𝐺+∑𝑖∈𝑅∑𝑚∈𝑅𝑏𝑖,𝑚𝑗𝑚⋅𝐺=(∑𝑖=0𝑘−1𝑎𝑖𝑗𝑖+∑𝑖∈𝑅∑𝑚∈𝑅𝑏𝑖,𝑚𝑗𝑚)⋅𝐺=(𝑓(𝑗)+∑𝑖∈𝑅𝑔𝑖(𝑗))⋅𝐺=(𝑧𝑗+∑𝑖∈𝑅𝑑𝑖,𝑗)⋅𝐺=𝐻(𝑗)⋅𝐺=𝑢𝑗⋅𝐺
  9. Each future bearer 𝑗∈𝑁 can interpolate the polynomial 𝐻(𝑥) from the shares 𝑢𝑗 and compute their share
    𝑧𝑗=𝐻(𝑗)−∑𝑖∈𝑅𝑑𝑖,𝑗=𝑢𝑗−∑𝑖∈𝑅𝑑𝑖,𝑗

Single share issuing

In the case where we only want to issue a single share, conduition proposed a clever way to remove the subtracting step at the end by adding a root at ℓ|{ℓ}=𝑁 to the blinding polynomial. This way, we have:

𝑔𝑖(𝑥)=(𝑥−ℓ)⋅𝑃𝑘−2(𝑥)|𝑖∈𝑆, 𝑃𝑘−2(𝑥)←𝔽𝑞[𝑥]

When interpolating 𝐻(ℓ), the blinding polynomials 𝑔𝑖(ℓ)|𝑖∈𝑆 cancel out and we directly get 𝑧ℓ:

𝑧ℓ=𝐻(ℓ)=∑𝑖∈𝑆(𝑧𝑖+𝑢𝑖)⋅∏𝑗∈𝑆,𝑗≠𝑖ℓ−𝑗𝑖−𝑗=∑𝑖∈𝑆(𝑧𝑖+∑𝑚∈𝑆𝑔𝑚(𝑖))⋅∏𝑗∈𝑆,𝑗≠𝑖ℓ−𝑗𝑖−𝑗=∑𝑖∈𝑆(𝑧𝑖⋅∏𝑗∈𝑆,𝑗≠𝑖ℓ−𝑗𝑖−𝑗)+∑𝑖∈𝑆(∑𝑚∈𝑆𝑔𝑚(𝑖)⋅∏𝑗∈𝑆,𝑗≠𝑖ℓ−𝑗𝑖−𝑗)=𝑧ℓ+∑𝑚∈𝑆𝑔𝑚(ℓ)⏟= 0=𝑧ℓ

Note that we could try to add multiple roots: (𝑥−ℓ1)(𝑥−ℓ2)⋅𝑔𝑖(𝑥), but then all the new shareholders would have access to the new shares.

You could also apply the same verifying scheme as before to this method.

We have a problem

When recovering the secret, we need to trust a single recoverer to do so and all send him all of our shares. But what if we all wanted to recover the secret at the same time?

One may naively try to implement a simple broadcast or pairwise exchange protocol, but if a single malicious actor 𝑃𝑚 wanted to prevent the others from also recovering the secret, he could just wait for everyone to send their share, and never send his. He will have all the shares needed, while the others can’t do anything.

If everyone distrusts each other, we will have this strange situation where no one wants to send their share first. One may prove that they own a valid share with a Zero-Knowledge Proof (ZKP), but will never be able to prove that he’s actually going to send it to the others.

One “solution” to this problem (not the best though) is to set a pre-defined order in which shareholders need to reveal their shares, after which it is verified each time by the others. If the share is invalid or the bearer fails to send it within a given time, the others can post a complaint against this user and abort the process.

[!WARNING] All the methods I describe below are purely experimental, and I have no idea if they are actually secure or not. If you have any feedback, please let me know!

Commitments-based ordering

After each shareholder has shared his commitment 𝐶𝑖=𝑦𝑖⋅𝐺 and it has been verified by everyone else, the order of reveal is defined by the value of each commitment. Let’s recall our commitments for 𝑓(𝑥)=𝑎0+𝑎1𝑥+…+𝑎𝑘−1𝑥𝑘−1:

𝐶={𝜙0,𝜙1,…,𝜙𝑘−1}|𝜙𝑖=𝑎𝑖⋅𝐺

One cannot manipulate the value of 𝑦𝑖⋅𝐺 as it is verifiable by the others with

𝑦𝑖⋅𝐺=∑𝑖=0𝑘−1𝜙𝑖

The probability of a malicious actor being placed last in the queue and thus fool everyone is 1𝑘 for 𝑘 recoverers if we suppose that 𝑦𝑖⋅𝐺 is pseudorandom. Not that good.

Incremental recovery

Let’s instead require each bearer to first send their share to everyone placed before them in the pre-defined order.

We have a single shared state 𝑅 that needs to be kept up-to-date for everyone at each round. This is to keep track of who has and who hasn’t sent their share yet. The state 𝑆 consisting of every sent share does not need to be shared as everyone can keep track of the broadcasts to 𝑅 received.

This way, a single malicious shareholder cannot dupe the rest of the group. But what if two malicious actors 𝑃𝑚 and 𝑃𝑚′ tried hijacking the recovery ?

  1. 𝑃1 initiates 𝑆={𝑦1}, 𝑅={𝑃1}
  2. 𝑃2 sends 𝑦2 to 𝑅, and gets accepted: 𝑆={𝑦1,𝑦2}, 𝑅={𝑃1}
  3. 𝑃𝑚 joins normally as well, he gets access to 𝑆
  4. 𝑃3 joins, and so on for other 𝑃𝑖
  5. 𝑃𝑚′ only sends his share to 𝑃𝑚, which sends him 𝑆 back (or not)

In this case, 𝑃𝑚 (and 𝑃𝑚′) are the only ones able to recover the secret. This isn’t of any good either…

Inception, again

To prevent a single actor from hijacking the recovery, we will leverage once again an Inception-like scheme. Here, our new scheme will be 2-out-of-𝑘.

Each shareholder 𝑖∈𝑅 generates a random polynomial 𝑔𝑖(𝑥)=𝑧𝑖+𝑏𝑖,1𝑥 of degree 1, where 𝑧𝑖 is their respective share.

The commitment and sharing phase of 𝑔𝑖(𝑗)|𝑖,𝑗∈𝑅 continues as usual, and before recovering the secret, two shareholders 𝑃𝑚 and 𝑃𝑚′ are chosen to reveal their shares. This way, when 𝑃𝑚 broadcasts his shares 𝑔𝑖(𝑚)|𝑖∈𝑅, everyone is instantly able to recover the secret.

The last step is to verify that 𝑃𝑚′ also sends his shares to 𝑃𝑚. If he does not, every other shareholder can post a complaint against him and optionally send his shares to 𝑃𝑚, who can then recover the secret.

We now have a pretty good guarantee that the secret will be recovered by everyone, except if that very person was being explicitly targeted by the whole recovery group (𝑘−1 people). Please also note that this method doesn’t work really well with a small number of shareholders, e.g. 3:

𝑃1 and 𝑃2 are chosen to reveal their intermediate shares, but 𝑃2 and 𝑃3 are malicious.

  1. Each shareholder 𝑖∈𝑅={1,2,3} splits his share 𝑧𝑖 into 𝑔𝑖(𝑥)=𝑧𝑖+𝑏𝑖,1𝑥 and sends 𝑔𝑖(𝑗)|𝑖,𝑗∈𝑅 to everyone.
  2. 𝑃1 reveals his shares as expected, but 𝑃2 and 𝑃3 do not.
  3. 𝑃2 and 𝑃3 are the only ones able to recover the secret, and 𝑃1 is left out.

References and Suggested readings

  • Issuing New Shamir Secret Shares Using Multi-Party Computation conduition.io

  • Novel Secret Sharing and Commitment Schemes for Cryptographic Applications Mehrdad Nojoumian dspacemainprd01.lib.uwaterloo.ca [PDF]

  • A Share-Correctable Protocol for the Shamir Threshold Scheme and Its Application to Participant Enrollment Raylin Tso, Ying Miao, Takeshi Okamoto and Eiji Okamoto citeseerx.ist.psu.edu [PDF]

  • Feldman’s Verifiable Secret Sharing for a Dishonest Majority Yi-Hsiu Chen and Yehuda Lindell eprint.iacr.org [PDF]

  • Adaptively Secure Feldman VSS and Applications to Universally-Composable Threshold Cryptography Masayuki Abe and Serge Fehr eprint.iacr.org [PDF]