func LagrangeInterpolation(a *big.Int, points map[*big.Int]*big.Int, prime *big.Int) *big.Int {
	value := big.NewInt(0)
	for key, val := range points {
		numerator := big.NewInt(1)
		denominator := big.NewInt(1)
		t := new(big.Int)
		for key1 := range points {
			if key == key1 {
				continue
			}
			t.Sub(a, key1)
			numerator.Mul(numerator, t)
			numerator.Mod(numerator, prime)
			t.Sub(key, key1)
			denominator.Mul(denominator, t)
			denominator.Mod(denominator, prime)
		}
		t1 := new(big.Int)
		denominator_inv := new(big.Int)
		denominator_inv.ModInverse(denominator, prime)
		t1.Mul(numerator, denominator_inv)
		t1.Mod(t1, prime)
		t2 := new(big.Int)
		t2.Mul(val, t1)
		t2.Add(t2, prime)
		t2.Add(t2, prime)
		value.Add(value, t2)
		value.Add(value, prime)
	}
	value.Mod(value, prime)
	return value
}
Given degree+1 points which are on the polynomial, LagrangeInterpolation computes p(a).
package common
import (
	"math/big"
)
type Polynomial struct {
	coefficients []*big.Int
	degree       int
	prime        *big.Int  
}
func NewRandomPolynomial(degree int, prime *big.Int) (*Polynomial, error) {
	var coefficients []*big.Int
	for i := 0; i <= degree; i++ {
		coef := GetRandomInt(prime)  
		coefficients = append(coefficients, coef)
	}
	polynomial := Polynomial{
		coefficients: coefficients,
		degree:       degree,
		prime:        prime,
	}
	return &polynomial, nil
}
func (polynomial *Polynomial) SetCoefficient(coeff_ind int, coefficient *big.Int) {
	polynomial.coefficients[coeff_ind] = coefficient
}
func (polynomial *Polynomial) GetValues(points []*big.Int) map[*big.Int]*big.Int {
	m := make(map[*big.Int]*big.Int)
	for _, value := range points {
		m[value] = polynomial.GetValue(value)
	}
	return m
}
func (polynomial *Polynomial) GetValue(point *big.Int) *big.Int {
	value := big.NewInt(0)
	for i, coeff := range polynomial.coefficients {
		tmp := new(big.Int).Exp(point, big.NewInt(int64(i)), polynomial.prime)  
		tmp.Mul(coeff, tmp)
		value.Add(value, tmp)
	}
	value.Mod(value, polynomial.prime)
	return value
}