Shamir Secret Sharing
Most of the concepts are clarly explained in this Wikipedia.
Code
The code is mostly inspired from here: https://github.com/sinahab/shamir-secret-sharing
open System
let inline (mod) n d=
((n % d) + d) % d
let order = 39367
let finiteField x = x mod order
let rec pow b e =
match e with
0 -> 1
| (b * pow b (e - 1))
| _ -> finiteField
let rec extendedEuclid a b =
match a with
0 -> b, 0, 1
|
| _ ->let gcd, x, y = extendedEuclid (b mod a) a
(b / a) * x, x
gcd, y -
let modMultInverse a p =
let _, x, _ = extendedEuclid a p
x
let createPolynomial cs x =
cs.mapi (fun i c -> c * (pow x i))
|> List.sum
|> List
let mult xs = List.reduce (fun a b -> finiteField( a * b)) xs
let createShares secret k n =
let f = createPolynomial (secret :: [for _ in [1..k-1] do finiteField (Random.Shared.Next())])
[ for x in [ 1..n ] do (x, finiteField (f x)) ]
let recoverSecret shares =
[ for (xj, yj) in shares do
yield yj * mult [ for (xm, _) in shares do
if xj <> xm then
yield xm * (modMultInverse (finiteField (xm - xj)) order) |> finiteField ] ]
.sum
|> List |> finiteField
Test
let shares = createShares 12344 3 7
let secrets =
shares.windowed 4
|> List.map recoverSecret |> List