Skip to content

Commit 715190f

Browse files
authored
Add Example for Shamir's Secret Sharing (#1287)
1 parent 4482f1f commit 715190f

File tree

2 files changed

+101
-1
lines changed

2 files changed

+101
-1
lines changed

examples/_data.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -696,7 +696,7 @@ export const sidebar = [
696696
],
697697
},
698698
{
699-
title: "Crypotography",
699+
title: "Cryptography",
700700
items: [
701701
{
702702
label: "Generating & validating UUIDs",

examples/scripts/sss.ts

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/**
2+
* @title Shamir's Secret Sharing Implementation
3+
* @difficulty intermediate
4+
* @tags cli
5+
* @run <url>
6+
* @group Cryptography
7+
*
8+
* This example demonstrates Shamir's Secret Sharing, where a secret, split into shares, allows its
9+
* reconstruction only when a sufficient number of shares are combined.
10+
*/
11+
12+
// Random Number Generation within a range
13+
async function getSecureRandom(min: number, max: number): Promise<number> {
14+
const range = max - min;
15+
const buffer = new Uint8Array(4);
16+
crypto.getRandomValues(buffer);
17+
const randomValue = new DataView(buffer.buffer).getUint32(0);
18+
return min + (randomValue % range);
19+
}
20+
21+
// Finding the value of the polynomial at x
22+
function evaluatePolynomial(coefficients: number[], x: number): number {
23+
return coefficients.reduce(
24+
(result, coeff, power) => result + coeff * Math.pow(x, power),
25+
0,
26+
);
27+
}
28+
29+
// Generates shares based on the secret and threshold
30+
async function generateShares(
31+
secret: number,
32+
totalShares: number,
33+
threshold: number,
34+
) {
35+
// Generate random coefficients for the polynomial
36+
const coefficients = [secret];
37+
for (let i = 1; i < threshold; i++) {
38+
coefficients.push(await getSecureRandom(1, 1000));
39+
}
40+
41+
const usedXValues = new Set<number>();
42+
const shares = [];
43+
44+
// Generate unique random x values for shares
45+
while (shares.length < totalShares) {
46+
const x = await getSecureRandom(1, 1000);
47+
if (!usedXValues.has(x)) {
48+
usedXValues.add(x);
49+
shares.push({
50+
x,
51+
y: evaluatePolynomial(coefficients, x),
52+
});
53+
}
54+
}
55+
56+
return { shares, coefficients };
57+
}
58+
59+
// Secret Reconstuction from a subset of shares using Lagrange interpolation
60+
function reconstructSecret(shares: Array<{ x: number; y: number }>): number {
61+
const secret = shares.reduce((sum, share, i) => {
62+
let product = share.y;
63+
for (let j = 0; j < shares.length; j++) {
64+
if (i !== j) {
65+
product *= shares[j].x / (shares[j].x - share.x);
66+
}
67+
}
68+
return sum + product;
69+
}, 0);
70+
71+
return Math.round(secret);
72+
}
73+
74+
const secret = 12345;
75+
const totalShares = 5;
76+
const threshold = 3;
77+
78+
// Generate shares
79+
const { shares, coefficients } = await generateShares(
80+
secret,
81+
totalShares,
82+
threshold,
83+
);
84+
console.log("Generated Shares:", shares);
85+
86+
// Select random subset of shares to reconstruct the secret
87+
const selectedIndices = new Set<number>();
88+
while (selectedIndices.size < threshold) {
89+
selectedIndices.add(await getSecureRandom(0, totalShares));
90+
}
91+
92+
const selectedShares = Array.from(selectedIndices).map((index) =>
93+
shares[index]
94+
);
95+
console.log("Selected Shares for Reconstruction:", selectedShares);
96+
97+
// Reconstruct the secret
98+
const reconstructedSecret = reconstructSecret(selectedShares);
99+
console.log("Original Secret:", secret);
100+
console.log("Reconstructed Secret:", reconstructedSecret);

0 commit comments

Comments
 (0)