shamir秘密共享 go语言实现

算法原理参考:shamir 秘密共享

  1. 大素数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
    }
    
  2. Share和Polynomial 结构体定义,Share结构体定义了参与者拥有的秘密(x,y), Polynomial结构体定义了多项式,多项式的「知识」即该多项式的系数,知道多项式的系数,也就知道该多项式

    type Share struct {
    	x, y *big.Int
    }
    
    type Polynomial struct {
    	coefficients []*big.Int
    	modulus      *big.Int
    }
    
  3. 拉格朗日插值算法实现:对定点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)
    }
    
  4. 秘密分发:生成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
    }
    
  5. 验证

    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)
    }
    
    

shamir秘密共享 go语言实现

上一篇:树莓派修改菜单图标


下一篇:双人成行出现重新安装的问题