216 lines
4.0 KiB
Go
216 lines
4.0 KiB
Go
package ssss
|
|
|
|
import (
|
|
"bytes"
|
|
"crypto/rand"
|
|
"encoding/asn1"
|
|
"fmt"
|
|
"io"
|
|
"math/big"
|
|
"testing"
|
|
|
|
"xdx.jelly/xgcl/gmath"
|
|
)
|
|
|
|
func TestSharingASN1(t *testing.T) {
|
|
threshold := 3
|
|
n := 5
|
|
|
|
// 16字节b需要拆分
|
|
b := make([]byte, 16)
|
|
_, _ = io.ReadFull(rand.Reader, b)
|
|
|
|
// Shares是n个秘密分片
|
|
shares, err := Split(b, threshold, n, 0, rand.Reader)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// recoverdShares 凑齐threshold个秘密分片
|
|
recoverdShares := make([][]byte, 0)
|
|
i := 0
|
|
for _, s := range shares {
|
|
recoverdShares = append(recoverdShares, s)
|
|
i++
|
|
if i == threshold {
|
|
break
|
|
}
|
|
}
|
|
|
|
// recovered是恢复的秘密值
|
|
recovered, err := Restore(recoverdShares)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if !bytes.Equal(b, recovered) {
|
|
t.Fatal("recoverd and secret are different")
|
|
}
|
|
}
|
|
|
|
func TestSharingASN1Fuzz(t *testing.T) {
|
|
b := make([]byte, 16)
|
|
for k := 0; k < 1000; k++ {
|
|
for n := 3; n < 8; n++ {
|
|
for threshold := 1; threshold <= n; threshold++ {
|
|
// 16字节b需要拆分
|
|
_, _ = io.ReadFull(rand.Reader, b)
|
|
shares, err := Split(b, threshold, n, 0, rand.Reader)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
recoverdShares := make([][]byte, 0)
|
|
i := 0
|
|
for _, s := range shares {
|
|
recoverdShares = append(recoverdShares, s)
|
|
i++
|
|
if i == threshold {
|
|
break
|
|
}
|
|
}
|
|
|
|
recovered, err := Restore(recoverdShares)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if !bytes.Equal(b, recovered) {
|
|
t.Fatal("recoverd and secret are different")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestFieldMul(t *testing.T) {
|
|
|
|
f := newGF2x(8)
|
|
var x *big.Int
|
|
y := new(big.Int)
|
|
one := new(big.Int).SetInt64(1)
|
|
|
|
for k := 0; k < 10000; k++ {
|
|
x, _ = f.rand(rand.Reader)
|
|
y.Set(one)
|
|
for i := 0; i < 1<<8-1; i++ {
|
|
f.mul(y, y, x)
|
|
}
|
|
if y.Cmp(one) != 0 {
|
|
t.Log("error x:", x.Text(16))
|
|
t.Fatal("mul error")
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestFieldInvert(t *testing.T) {
|
|
|
|
f := newGF2x(8)
|
|
z := new(big.Int)
|
|
y := new(big.Int)
|
|
one := new(big.Int).SetInt64(1)
|
|
|
|
for k := 0; k < 10000; k++ {
|
|
x, _ := f.rand(rand.Reader)
|
|
if f.invert(z, x) != nil {
|
|
t.Fatal()
|
|
}
|
|
f.mul(y, x, z)
|
|
if y.Cmp(one) != 0 {
|
|
t.Fatal("invert error")
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
func TestHorner(t *testing.T) {
|
|
//f(x) = x^2 + x + 2
|
|
f := newGF2x(64)
|
|
coeff := []*big.Int{
|
|
new(big.Int).SetInt64(2),
|
|
new(big.Int).SetInt64(1),
|
|
}
|
|
|
|
x := new(big.Int).SetInt64(3)
|
|
|
|
y := new(big.Int)
|
|
horner(y, x, coeff, f)
|
|
if y.Cmp(gmath.BigInt4) != 0 {
|
|
t.Fatal()
|
|
}
|
|
}
|
|
|
|
func TestSharing(t *testing.T) {
|
|
b := make([]byte, 16)
|
|
f := newGF2x(128)
|
|
for k := 0; k < 1000; k++ {
|
|
// 16字节b需要拆分
|
|
_, _ = io.ReadFull(rand.Reader, b)
|
|
// secret, _ := f.rand(rand.Reader)
|
|
secret := new(big.Int).SetBytes(b)
|
|
for n := 3; n < 8; n++ {
|
|
for threshold := 1; threshold <= n; threshold++ {
|
|
shares, err := split(rand.Reader, threshold, n, secret, f)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
recovered, err := restore(threshold, shares, f)
|
|
if err != nil || recovered.Cmp(secret) != 0 {
|
|
t.Log("restore secret:", recovered.Text(16))
|
|
t.Log("secret :", secret.Text(16))
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestSigle(t *testing.T) {
|
|
f := newGF2x(64)
|
|
secret, _ := f.rand(rand.Reader)
|
|
threshold := 1
|
|
n := 5
|
|
shares, err := split(rand.Reader, threshold, n, secret, f)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for k, v := range shares {
|
|
t.Logf("%d-%s\n", k, v.Text(16))
|
|
}
|
|
|
|
var v0 big.Int
|
|
for k, v := range shares {
|
|
v0.SetInt64(int64(k))
|
|
f.add(&v0, &v0, v)
|
|
if v0.Cmp(secret) != 0 {
|
|
t.Fatal()
|
|
}
|
|
}
|
|
|
|
recovered, err := restore(threshold, shares, f)
|
|
if err != nil || recovered.Cmp(secret) != 0 {
|
|
t.Log("restore secret:", recovered.Text(16))
|
|
t.Log("secret :", secret.Text(16))
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func TestASN1(t *testing.T) {
|
|
slice := SharedSlice{
|
|
Version: 0,
|
|
Threshold: 3,
|
|
Length: 16,
|
|
X: 1,
|
|
Y: new(big.Int).SetUint64(16),
|
|
Token: make([]byte, 16),
|
|
}
|
|
b, err := asn1.Marshal(slice)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
fmt.Printf("%x\n", b)
|
|
|
|
slice2 := new(SharedSlice)
|
|
_, err = asn1.Unmarshal(b, slice2)
|
|
fmt.Println(err, slice2)
|
|
}
|