funcEncrypt(secret []byte, n, num int) [][]byte { iflen(secret) == 0 || n <= 0 { panic("illegal input data") }
if num < n { panic("num has to be greater than n") } result := initArray(num, len(secret)) for j := 0; j < len(secret); j++ { f := getPolynomial(n, secret[j]) for i := 0; i < num; i++ { if j == 0 { result[i][0] = byte(i + 1) } result[i][j+1] = f(uint8(i + 1)) } } temp := Decrypt(result, n) for i := 0; i < len(secret); i++ { if temp[i] != secret[i] { return Encrypt(secret, n, num) break } } return result }
funcDecrypt(shares [][]byte, n int) []byte { iflen(shares) == 0 { panic("illegal input data") } x := make([]int64, n) for i := 0; i < n; i++ { x[i] = int64(i + 1) } yss := initInt64Array(len(shares[0])-1, n) for i := 0; i < n; i++ { for j := 1; j < len(shares[i]); j++ { yss[j-1][i] = int64(shares[i][j]) } }
result := make([]byte, 0) for _, ys := range yss { secret := Lagrange(0, x, ys) temp, _ := new(big.Float).SetString(secret.FloatString(0)) secretBigInt := new(big.Int) temp.Int(secretBigInt) secretBigInt.Mod(secretBigInt, big.NewInt(int64(prime))) tempSecret := int(secretBigInt.Int64()) if tempSecret < 0 { tempSecret += prime } result = append(result, byte(tempSecret)) } return result }
funcinitArray(a, b int) [][]byte { result := make([][]byte, 0) for i := 0; i < a; i++ { nums := make([]byte, b+1) result = append(result, nums) } return result } funcgetPolynomial(n int, secretMsg byte)func(x uint8)uint8 { coefficients := make([]uint8, n-1) for i := 0; i < n-1; i++ { fortrue { temp := uint8(rand.Intn(math.MaxInt8)) if temp != 0 { coefficients[i] = temp break } } } returnfunc(x uint8)uint8 { var count = new(big.Int).Set(big.NewInt(0)) for i := 0; i < len(coefficients); i++ { bigCoefficient := new(big.Int).Set(big.NewInt(int64(coefficients[i]))) exponent := new(big.Int).Set(big.NewInt(int64(n - 1 - i))) bigX := new(big.Int).Set(big.NewInt(int64(x))) bigPrime := new(big.Int).Set(big.NewInt(int64(prime))) bigX.Exp(bigX, exponent, bigPrime) bigX.Mul(bigX, bigCoefficient) bigX.Mod(bigX, bigPrime) count.Add(count, bigX) count.Mod(count, bigPrime) } count.Add(count, big.NewInt(int64(secretMsg))) count.Mod(count, big.NewInt(int64(prime))) returnuint8(count.Int64()) } }
funcgetRandIndex(num int) []int { numArr := make([]int, 0) for i := 0; i < 256; i++ { numArr = append(numArr, i+1) } r := rand.New(rand.NewSource(time.Now().UnixNano())) r.Shuffle(len(numArr), func(i, j int) { numArr[i], numArr[j] = numArr[j], numArr[i] }) return numArr[:num]
}
funcLagrange(x int64, xs, ys []int64) *big.Rat { l := big.NewRat(0, 1) for i := 0; i < len(xs); i++ { term := big.NewRat(ys[i], 1) for j := 0; j < len(xs); j++ { if i != j { num := big.NewRat(x-xs[j], 1) den := big.NewRat(xs[i]-xs[j], 1) frac := new(big.Rat).Quo(num, den) term.Mul(term, frac) } } l.Add(l, term) } return l }
funcinitInt64Array(a, b int) [][]int64 { result := make([][]int64, 0) for i := 0; i < a; i++ { nums := make([]int64, b) result = append(result, nums) } return result }