package outsource import ( "crypto/rand" "math/big" "testing" "github.com/stretchr/testify/assert" "xdx.jelly/xgcl/gmath" "xdx.jelly/xgcl/grand" "xdx.jelly/xgcl/he/elgamal" "xdx.jelly/xgcl/sm/sm2" "xdx.jelly/xgcl/sm/sm3" "xdx.jelly/xgcl/tpc/sm2/sm2m" ) // 示例ElGamal 不能加入盲化因子。弃用。 func TestOutsourceWithElGamal(t *testing.T) { clientKey, clientTempKey, _ := sm2m.ClientGenSignKey_one(grand.Reader) serverKey, serverTempKey, publicKey, _ := sm2m.ServerGenSignKey(clientTempKey, grand.GetRandom(32)) err := sm2m.ClientGenSignKey_two(clientKey, serverTempKey, publicKey) if err != nil { t.Fatal("client's public key and server's public key are not equal.") } e := grand.GetRandom(32) sk, pk, err := elgamal.GenerateKey(grand.Reader, elgamal.P1024) assert.Nil(t, err) encryptedClientKey, err := pk.Encryption(clientKey.D, grand.Reader) assert.Nil(t, err) // 受托方计算 k1, err := rand.Int(grand.Reader, sm2.OrderN()) assert.Nil(t, err) px, py := sm2.Curve256.ScalarMult(sm2.BaseX(), sm2.BaseY(), k1.Bytes()) data := make([]byte, sm3.Size+2*sm2.ByteSize()) pos := copy(data, e) pos += copy(data[pos:], gmath.BigIntToNByte(px, sm2.ByteSize())) copy(data[pos:], gmath.BigIntToNByte(py, sm2.ByteSize())) // data = (e,p) => 协同服务端 // 协同服务端计算 data, err = sm2m.ServerSign(serverKey, data, grand.Reader) assert.Nil(t, err) // data = (r||s1||s2) r := new(big.Int) r.SetBytes(data[:sm2.ByteSize()]) s1 := new(big.Int).SetBytes(data[sm2.ByteSize() : 2*sm2.ByteSize()]) s2 := new(big.Int).SetBytes(data[2*sm2.ByteSize():]) // s1, s2 => 受托方 s := big.NewInt(0).Mul(k1, s1) s.Add(s, s2) s.Mod(s, sm2.OrderN()) // 计算 c = Enc(dc*(k1*s1+s2)) S, err := pk.Encryption(s, grand.Reader) assert.Nil(t, err) c := &elgamal.Cipher{} c, err = c.HomoMap(encryptedClientKey, S) assert.Nil(t, err) // 加入随机因子?HOW. // k, err := rand.Int(grand.Reader, pk.Param.Q) // assert.Nil(t, err) // nminus1 := new(big.Int).Set(sm2.OrderN()) // k.Mul(k, nminus1) // k.Mod(k, pk.Param.Q) // k.Exp(pk.Param.G, k, pk.Param.P) // c1, err := pk.Encryption(k, grand.Reader) // assert.Nil(t, err) // c.HomoMap(c, c1) // c = Enc(dc*(k1*s1+s2) * g^{K(N-1)}) // c 发送给委托方 // 委托方计算 s, err = sk.Decryption(c) assert.Nil(t, err) s.Sub(s, r) s.Mod(s, sm2.OrderN()) sig := &sm2.Signature{ R: r, S: s, } if !sm2.Verify(e, publicKey, sig) { t.Fatal("verify failed") } }