RecoverPriPoly takes a list of shares and the parameters t and n to reconstruct the secret polynomial completely, i.e., all private coefficients. It is up to the caller to make sure that there are enough shares to correctly re-construct the polynomial. There must be at least t shares.
(g kyber.Group, shares []*PriShare, t, n int)
| 227 | // shares to correctly re-construct the polynomial. There must be at least t |
| 228 | // shares. |
| 229 | func RecoverPriPoly(g kyber.Group, shares []*PriShare, t, n int) (*PriPoly, error) { |
| 230 | x := xScalar(g, shares, t, n) |
| 231 | if len(x) != t { |
| 232 | return nil, errors.New("share: not enough shares to recover private polynomial") |
| 233 | } |
| 234 | |
| 235 | var accPoly *PriPoly |
| 236 | var err error |
| 237 | den := g.Scalar() |
| 238 | // Notations follow the Wikipedia article on Lagrange interpolation |
| 239 | // https://en.wikipedia.org/wiki/Lagrange_polynomial |
| 240 | for j, xj := range x { |
| 241 | var basis = &PriPoly{ |
| 242 | g: g, |
| 243 | coeffs: []kyber.Scalar{g.Scalar().One()}, |
| 244 | } |
| 245 | var acc = g.Scalar().Set(shares[j].V) |
| 246 | // compute lagrange basis l_j |
| 247 | for m, xm := range x { |
| 248 | if j == m { |
| 249 | continue |
| 250 | } |
| 251 | basis = basis.Mul(xMinusConst(g, xm)) // basis = basis * (x - xm) |
| 252 | |
| 253 | den.Sub(xj, xm) // den = xj - xm |
| 254 | den.Inv(den) // den = 1 / den |
| 255 | acc.Mul(acc, den) // acc = acc * den |
| 256 | } |
| 257 | |
| 258 | for i := range basis.coeffs { |
| 259 | basis.coeffs[i] = basis.coeffs[i].Mul(basis.coeffs[i], acc) |
| 260 | } |
| 261 | |
| 262 | if accPoly == nil { |
| 263 | accPoly = basis |
| 264 | continue |
| 265 | } |
| 266 | |
| 267 | // add all L_j * y_j together |
| 268 | accPoly, err = accPoly.Add(basis) |
| 269 | if err != nil { |
| 270 | return nil, err |
| 271 | } |
| 272 | } |
| 273 | return accPoly, nil |
| 274 | } |
| 275 | |
| 276 | func (p *PriPoly) String() string { |
| 277 | var strs = make([]string, len(p.coeffs)) |