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