-
Notifications
You must be signed in to change notification settings - Fork 0
/
shamir.go
104 lines (85 loc) · 2.28 KB
/
shamir.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
package main
import (
"github.com/consensys/gnark-crypto/ecc/bn254/fr"
)
// p = 21888242871839275222246405745257275088548364400416034343698204186575808495617
type Polynomial struct {
Coefficients []fr.Element
Degree int
}
type Point struct {
X fr.Element
Y fr.Element
}
// return result after evaluation polynomial at x = xval
func (p Polynomial) Eval(x fr.Element) fr.Element {
var res, xval, temp fr.Element
res.SetZero()
xval.SetOne()
for _, coeff := range p.Coefficients {
temp.Mul(&coeff, &xval)
res.Add(&res, &temp)
xval.Mul(&xval, &x)
}
return res
}
func GenerateSecret() fr.Element {
var s fr.Element
s.SetRandom()
return s
}
func GetSharesSecret(s fr.Element, inputs []uint64, t int) []Point {
// 1. Generate polynomial of degree t
p := CreatePol(s, t)
// 2. Evaluate the polynomial at the given inputs
res := make([]Point, len(inputs))
for i, input := range inputs {
var input_el fr.Element
input_el.SetUint64(input)
y := p.Eval(input_el)
res[i] = Point{X: input_el, Y: y}
}
return res
}
// returns a polynomial of degree t with random coefficients c_i, except for c_0=s
func CreatePol(s fr.Element, t int) Polynomial {
p := Polynomial{Coefficients: make([]fr.Element, t), Degree: t}
// Set the secret at the constant coefficient
p.Coefficients[0].Set(&s)
// Then set the other coefficients with random values
for i := 1; i < t; i++ {
p.Coefficients[i].SetRandom()
}
return p
}
func Interpolate(points []Point) fr.Element {
var result fr.Element
result.SetZero()
for i := 0; i < len(points); i++ {
var term fr.Element
term.Set(&points[i].Y)
for j := 0; j < len(points); j++ {
if i != j {
// Ensure that the x values are distinct
if points[i].X.Equal(&points[j].X) {
panic("Interpolation error: duplicate x values")
}
// Calculate the denominator (xs[i] - xs[j])
var denominator fr.Element
denominator.Sub(&points[i].X, &points[j].X)
// Calculate the inverse of the denominator
var inv fr.Element
inv.Inverse(&denominator)
// Calculate the numerator (-xs[j])
var numerator fr.Element
numerator.Neg(&points[j].X)
// Multiply term by (numerator * inv)
var temp fr.Element
temp.Mul(&numerator, &inv)
term.Mul(&term, &temp)
}
}
result.Add(&result, &term)
}
return result
}