算法原理参考:shamir 秘密共享
-
大素数p的选取,这里选取的是128bit大素数
func prime128Bit() *big.Int { p := big.NewInt(2) p.Exp(p, big.NewInt(127), nil) p.Sub(p, big.NewInt(1)) return p }
-
Share和Polynomial 结构体定义,Share结构体定义了参与者拥有的秘密(x,y), Polynomial结构体定义了多项式,多项式的「知识」即该多项式的系数,知道多项式的系数,也就知道该多项式
type Share struct { x, y *big.Int } type Polynomial struct { coefficients []*big.Int modulus *big.Int }
-
拉格朗日插值算法实现:对定点shares,计算该多项式在x处的值,对于sss算法 ,秘密在x=0处,需要注意的是拉格朗日插值算法中有模除,需要转为乘以这个数的逆元
func Lagrange(x, modulus *big.Int, shares ...Share) *big.Int { xs := make([]*big.Int, len(shares)) ys := make([]*big.Int, len(shares)) for i := range shares { xs[i] = shares[i].x ys[i] = shares[i].y } numerators := make([]*big.Int, len(xs)) denominators := make([]*big.Int, len(ys)) for i := range xs { numerators[i] = cal(xs, x, i) denominators[i] = cal(xs, xs[i], i) } result := big.NewInt(0) for i := range numerators { numerators[i].Mul(numerators[i], ys[i]) numerators[i].Mod(numerators[i], modulus) v := (&big.Int{}).Set(numerators[i].Mul(numerators[i], denominators[i].ModInverse(denominators[i],modulus))) result.Add(result, v) } return result.Mod(result, modulus) }
-
秘密分发:生成t-1次对多项式,若提供secret,则使用提供的秘密,否则随机生成秘密,随后计算n个参与者的秘密shares
func SecretDistribute(secret, modulus *big.Int, t, n int64) ([]Share, *big.Int) { if t > n { panic("t has to be less than n") } p := NewPolynomial(t, modulus) if secret != nil { p.coefficients[0] = secret } secret = p.coefficients[0] shares := make([]Share, n) for i := int64(0); i < n; i++ { x, _ := rand.Int(rand.Reader, modulus) y := p.valueAt(x) shares[i] = Share{x, y} } return shares, secret }
-
验证
func main() { prime := prime128Bit() //secret := big.NewInt(12345678987654321) shares, secret1 := SecretDistribute(nil, prime, 5, 8) respect := Lagrange(big.NewInt(0), prime, shares[0], shares[5], shares[4], shares[1],shares[7]) fmt.Println(secret1,respect) }