package main import ( "crypto/rand" "fmt" "math/big" "os" "runtime" "strconv" "sync" "time" "xdx.jelly/xgcl/gmath" "xdx.jelly/xgcl/grand" "xdx.jelly/xgcl/he/paillier" "xdx.jelly/xgcl/sm/sm2" "xdx.jelly/xgcl/sm/sm3" "xdx.jelly/xgcl/tpc/sm2/sm2m" "xdx.jelly/xgcl/tpc/sm2/sm2m/outsource" ) type timer struct { totalTime float64 last time.Time isStoped bool } func (t *timer) ResetTimer() { t.last = time.Now() t.totalTime = 0 t.isStoped = false } func (t *timer) StopTimer() { if t.isStoped { return } t.totalTime += time.Since(t.last).Seconds() t.isStoped = true } func (t *timer) StartTimer() { if !t.isStoped { return } t.last = time.Now() t.isStoped = false } func (t *timer) Seconds() float64 { t.StopTimer() return t.totalTime } func testPaillierHomomorphicScalarMul() { _, pk, _ := paillier.GenerateKey(2048, grand.Reader) limit := big.NewInt(1) limit.Lsh(limit, 256) m, _ := rand.Int(grand.Reader, limit) c, _ := paillier.Encrypt(m, pk, grand.Reader) k, _ := rand.Int(grand.Reader, limit) var b timer b.ResetTimer() times := 1000 for i := 0; i < times; i++ { c.HomomorphicScalarMul(c, k, pk) } b.StopTimer() fmt.Printf("HomomorphicScalarMul(single): %.2f per second\n", float64(times)/b.Seconds()) } func testPaillierHomomorphicScalarAdd() { _, pk, _ := paillier.GenerateKey(2048, grand.Reader) m1, _ := rand.Int(grand.Reader, pk.N) c1, _ := pk.Encrypt(m1, grand.Reader) m2, _ := rand.Int(grand.Reader, pk.N) c2, _ := pk.Encrypt(m2, grand.Reader) var c paillier.Cipher times := 1000 var b timer b.ResetTimer() for i := 0; i < times; i++ { c.HomomorphicAdd(c1, c2, pk) } b.StopTimer() fmt.Printf("HomomorphicAdd(single): %.2f per second\n", float64(times)/b.Seconds()) } func testPaillierEnc() { _, pk, _ := paillier.GenerateKey(2048, grand.Reader) m, _ := rand.Int(grand.Reader, pk.N) times := 1000 var b timer b.ResetTimer() for i := 0; i < times; i++ { pk.Encrypt(m, grand.Reader) } b.StopTimer() fmt.Printf("Encrypt(single): %.2f per second\n", float64(times)/b.Seconds()) } func testOS(N int) float64 { // O、客户端生成paillier密钥 salt := grand.GetRandom(16) paiPrivKey, _ := paillier.GenerateKeyFromPassword(2048, []byte("password123"), salt, 1024) paiPubKey := paiPrivKey.Public() // 一、密钥生成 // 1)客户端第一步, a1, a2 发外包服务器 clientKeyGen := &outsource.ClientKeyGenerator{} a1, a2, _ := clientKeyGen.Step1(paiPubKey, grand.Reader) // 2) 外包服务器第一步 // 保存encryptedClientKey1,encryptedClientKey2, // 把 P 发客户端 // encryptedClientKey1 -签名用 // encryptedClientKey2 -解密加密密钥保护结构用 osKenGen := &outsource.OSKeyGenerator{} encryptedClientKey1, _, P, _ := osKenGen.Step1(a1, a2, paiPubKey, grand.Reader) // 3) 客户端第二步 // clientTempKey发协同签名服务端 clientTempKey, _ := clientKeyGen.Step2(P) // 4)协同签名服务器 // serverTempKey 发客户端,保存serverKey-服务端密钥分量 serverKey, serverTempKey, publicKey, _ := sm2m.ServerGenSignKey(clientTempKey, grand.GetRandom(32)) // 5)客户端第三步 // 把(serverTempKey,S)发送给外包服务器 S, _ := clientKeyGen.Step3(serverTempKey) // 6)外包服务器第二步 // 把T, osPublicKey发给客户端。保存osPublicKey为用户签名公钥 T, osPublicKey, _ := osKenGen.Step2(serverTempKey, S) // 7)客户端第四步 // clientPublicKey, 客户端生成的公钥,如果没有返错,则应与ocPublicKey一致。 clientPublicKey, _ := clientKeyGen.Step4(T) clientPublicKey.Equals(osPublicKey) e := grand.GetRandom(32) var b timer // N := 1000 // 签名 b.ResetTimer() for i := 0; i < N; i++ { // 1)客户端发起请求 // 2)外包方计算 b.StartTimer() outsourcintCtx := new(outsource.OSSignContext) PPrime, _ := outsourcintCtx.Step1(grand.Reader) // P' // outsourcintCtx把PPrime发给客户端,保存outsourcintCtx.Marshal() // 3) 客户端组合数据data = (e,p)=e||px||py并发送给协同服务端 b.StopTimer() data := make([]byte, sm3.Size+2*sm2.ByteSize()) pos := copy(data, e) pos += copy(data[pos:], gmath.BigIntToNByte(PPrime.X, sm2.ByteSize())) copy(data[pos:], gmath.BigIntToNByte(PPrime.Y, sm2.ByteSize())) // 4) 协同服务端计算,发回data b.StartTimer() data, _ = sm2m.ServerSign(serverKey, data, grand.Reader) // 5) 客户端解析data = r || s1 || s2, 把s1, s2发给外包服务器。 b.StopTimer() 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():]) // 6) 外包服务器解析data并计算c,把c发送给客户端 b.StartTimer() c, _ := outsourcintCtx.Step2(s1, s2, encryptedClientKey1, paiPubKey) // 7) 客户端计算签名值 b.StopTimer() s, _ := paillier.Decrypt(c, paiPrivKey) s.Sub(s, r) s.Mod(s, sm2.OrderN()) sig := &sm2.Signature{ R: r, S: s, } // 8) 客户端验证签名 sm2.Verify(e, publicKey, sig) } return b.Seconds() // fmt.Printf("used time: %v\n", b.Seconds()) // fmt.Printf("Outsource sign: %.2f per second\n", float64(N)/b.Seconds()) } func multiTestOS(threads int) { N := 100 times := make([]float64, threads) var wg sync.WaitGroup for i := 0; i < threads; i++ { wg.Add(1) go func(i int) { times[i] = testOS(N) wg.Done() }(i) } wg.Wait() avg := 0.0 for _, t := range times { avg += t } avg /= float64(threads) fmt.Printf("Outsource sign: %.2f per second\n", float64(N*threads)/avg) } func main() { testPaillierEnc() testPaillierHomomorphicScalarAdd() testPaillierHomomorphicScalarMul() var threads int if len(os.Args) < 2 { threads = runtime.NumCPU() } else { threads, _ = strconv.Atoi(os.Args[1]) } fmt.Println("Cores:", threads) multiTestOS(threads) }