95 lines
2.4 KiB
Go
95 lines
2.4 KiB
Go
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")
|
|
}
|
|
}
|