Skip to content

Commit

Permalink
Add Example for Shamir's Secret Sharing (#1287)
Browse files Browse the repository at this point in the history
  • Loading branch information
RDxR10 authored Dec 25, 2024
1 parent 4482f1f commit 715190f
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 1 deletion.
2 changes: 1 addition & 1 deletion examples/_data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -696,7 +696,7 @@ export const sidebar = [
],
},
{
title: "Crypotography",
title: "Cryptography",
items: [
{
label: "Generating & validating UUIDs",
Expand Down
100 changes: 100 additions & 0 deletions examples/scripts/sss.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/**
* @title Shamir's Secret Sharing Implementation
* @difficulty intermediate
* @tags cli
* @run <url>
* @group Cryptography
*
* This example demonstrates Shamir's Secret Sharing, where a secret, split into shares, allows its
* reconstruction only when a sufficient number of shares are combined.
*/

// Random Number Generation within a range
async function getSecureRandom(min: number, max: number): Promise<number> {
const range = max - min;
const buffer = new Uint8Array(4);
crypto.getRandomValues(buffer);
const randomValue = new DataView(buffer.buffer).getUint32(0);
return min + (randomValue % range);
}

// Finding the value of the polynomial at x
function evaluatePolynomial(coefficients: number[], x: number): number {
return coefficients.reduce(
(result, coeff, power) => result + coeff * Math.pow(x, power),
0,
);
}

// Generates shares based on the secret and threshold
async function generateShares(
secret: number,
totalShares: number,
threshold: number,
) {
// Generate random coefficients for the polynomial
const coefficients = [secret];
for (let i = 1; i < threshold; i++) {
coefficients.push(await getSecureRandom(1, 1000));
}

const usedXValues = new Set<number>();
const shares = [];

// Generate unique random x values for shares
while (shares.length < totalShares) {
const x = await getSecureRandom(1, 1000);
if (!usedXValues.has(x)) {
usedXValues.add(x);
shares.push({
x,
y: evaluatePolynomial(coefficients, x),
});
}
}

return { shares, coefficients };
}

// Secret Reconstuction from a subset of shares using Lagrange interpolation
function reconstructSecret(shares: Array<{ x: number; y: number }>): number {
const secret = shares.reduce((sum, share, i) => {
let product = share.y;
for (let j = 0; j < shares.length; j++) {
if (i !== j) {
product *= shares[j].x / (shares[j].x - share.x);
}
}
return sum + product;
}, 0);

return Math.round(secret);
}

const secret = 12345;
const totalShares = 5;
const threshold = 3;

// Generate shares
const { shares, coefficients } = await generateShares(
secret,
totalShares,
threshold,
);
console.log("Generated Shares:", shares);

// Select random subset of shares to reconstruct the secret
const selectedIndices = new Set<number>();
while (selectedIndices.size < threshold) {
selectedIndices.add(await getSecureRandom(0, totalShares));
}

const selectedShares = Array.from(selectedIndices).map((index) =>
shares[index]
);
console.log("Selected Shares for Reconstruction:", selectedShares);

// Reconstruct the secret
const reconstructedSecret = reconstructSecret(selectedShares);
console.log("Original Secret:", secret);
console.log("Reconstructed Secret:", reconstructedSecret);

0 comments on commit 715190f

Please sign in to comment.