From c1659228945e594400a2c97f26fc0cd07ca9c6ae Mon Sep 17 00:00:00 2001 From: www-git-cn <102035872+www-git-cn@users.noreply.github.com> Date: Wed, 1 May 2024 16:55:49 +0800 Subject: [PATCH] add implementation of go --- README.md | 7 +- go_test/.idea/.gitignore | 8 ++ go_test/.idea/.name | 1 + go_test/.idea/go_test.iml | 9 ++ go_test/.idea/modules.xml | 8 ++ go_test/cert/pkpub.txt | 1 + go_test/cert/prikey.txt | 1 + go_test/cert/pubkey.txt | 1 + go_test/go.mod | 3 + go_test/gofunc.go | 293 ++++++++++++++++++++++++++++++++++++++ go_test/main.go | 79 ++++++++++ 11 files changed, 408 insertions(+), 3 deletions(-) create mode 100644 go_test/.idea/.gitignore create mode 100644 go_test/.idea/.name create mode 100644 go_test/.idea/go_test.iml create mode 100644 go_test/.idea/modules.xml create mode 100644 go_test/cert/pkpub.txt create mode 100644 go_test/cert/prikey.txt create mode 100644 go_test/cert/pubkey.txt create mode 100644 go_test/go.mod create mode 100644 go_test/gofunc.go create mode 100644 go_test/main.go diff --git a/README.md b/README.md index 266fe2f..47dc757 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ # KGC_TEST(狠狠感谢ljn) -#### 1.调用Miracl库,基本实现了密钥生成 +### 1.调用Miracl库,基本实现了密钥生成 -#### 2.实现了Go语言调用C静态库,完成了大数、点和Go语言字节切片的相互转换 +### 2.实现了Go语言调用C静态库,完成了大数、点和Go语言字节切片的相互转换 + +### 3.实现了基本的无证书的签名验签功能(Go语言实现和C语言实现) -#### 3.实现了基本的无证书的签名验签功能 \ No newline at end of file diff --git a/go_test/.idea/.gitignore b/go_test/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/go_test/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/go_test/.idea/.name b/go_test/.idea/.name new file mode 100644 index 0000000..30de634 --- /dev/null +++ b/go_test/.idea/.name @@ -0,0 +1 @@ +main.go \ No newline at end of file diff --git a/go_test/.idea/go_test.iml b/go_test/.idea/go_test.iml new file mode 100644 index 0000000..5e764c4 --- /dev/null +++ b/go_test/.idea/go_test.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/go_test/.idea/modules.xml b/go_test/.idea/modules.xml new file mode 100644 index 0000000..3b69742 --- /dev/null +++ b/go_test/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/go_test/cert/pkpub.txt b/go_test/cert/pkpub.txt new file mode 100644 index 0000000..462ddf4 --- /dev/null +++ b/go_test/cert/pkpub.txt @@ -0,0 +1 @@ +7196e9722d561a0fea21485fc16140096cc9b88f7174aec7508f14a7b85b61ba299292c726367bbcbf8f00b977849164bf9d3fd6260e55dd6498517bc0dec541 \ No newline at end of file diff --git a/go_test/cert/prikey.txt b/go_test/cert/prikey.txt new file mode 100644 index 0000000..101ec7b --- /dev/null +++ b/go_test/cert/prikey.txt @@ -0,0 +1 @@ +6d0770e05a3ce79a32e2aea78fcda3bcb4054b86df8369e50a5ab4b7e26f1d38 \ No newline at end of file diff --git a/go_test/cert/pubkey.txt b/go_test/cert/pubkey.txt new file mode 100644 index 0000000..77a951d --- /dev/null +++ b/go_test/cert/pubkey.txt @@ -0,0 +1 @@ +226383fbed07e3841affd83f7681f90602ad08e57bd27d6cad9a666d81b8b7ef17672b52cbc215c51d308299a1b640d6c0229bf761364cca3eae31d16c13da29 \ No newline at end of file diff --git a/go_test/go.mod b/go_test/go.mod new file mode 100644 index 0000000..e26fe90 --- /dev/null +++ b/go_test/go.mod @@ -0,0 +1,3 @@ +module example.com/m/v2 + +go 1.20 diff --git a/go_test/gofunc.go b/go_test/gofunc.go new file mode 100644 index 0000000..29fe98c --- /dev/null +++ b/go_test/gofunc.go @@ -0,0 +1,293 @@ +package main + +import ( + "crypto/elliptic" + "crypto/rand" + "crypto/sha256" + "errors" + "fmt" + "math/big" + "os" + "path/filepath" +) + +func hash1(curve elliptic.Curve, ID []byte, Qx, Qy, PKx, PKy *big.Int) *big.Int { + // 创建 SHA-256 散列器 + h := sha256.New() + + // 更新散列器以包含字符串 ID 的内容 + h.Write(ID) + + // 更新散列器以包含点 Q 的坐标信息 + h.Write(Qx.Bytes()) + h.Write(Qy.Bytes()) + + // 更新散列器以包含公钥 PK_pub 的坐标信息 + h.Write(PKx.Bytes()) + h.Write(PKy.Bytes()) + + // 计算 SHA-256 散列值 + hash := h.Sum(nil) + + // 将散列值转换为大整数 + hBig := new(big.Int).SetBytes(hash) + + // 对大整数 hBig 进行幂运算,幂为 1,模数为 n + hBig.Mod(hBig, curve.Params().N) + + return hBig +} + +func hash2(curve elliptic.Curve, ID []byte, Xx, Xy *big.Int) *big.Int { + // 计算 hash 值 H_2(ID, X) + hash := sha256.New() + + hash.Write(ID) + + hash.Write(Xx.Bytes()) + hash.Write(Xy.Bytes()) + + // 计算 SHA-256 散列值 + h2 := hash.Sum(nil) + + // 转换为大整数 + h2Big := new(big.Int).SetBytes(h2) + + // 对大整数 h2Big 进行幂运算,幂为 1,模数为 n + h2Big.Mod(h2Big, curve.Params().N) + + return h2Big +} + +func hash3(curve elliptic.Curve, ID, msg []byte, Qx, Qy, Ux, Uy, PKx, PKy *big.Int) *big.Int { + // 创建 SHA-256 散列器 + h := sha256.New() + + // 更新散列器以包含字符串 ID 的内容 + h.Write(ID) + + // 更新散列器以包含字符串 msg 的内容 + h.Write(msg) + + // 更新散列器以包含点 Q 的坐标信息 + h.Write(Qx.Bytes()) + h.Write(Qy.Bytes()) + + // 更新散列器以包含点 U 的坐标信息 + h.Write(Ux.Bytes()) + h.Write(Uy.Bytes()) + + // 更新散列器以包含公钥 PK_pub 的坐标信息 + h.Write(PKx.Bytes()) + h.Write(PKy.Bytes()) + + // 计算 SHA-256 散列值 + hash := h.Sum(nil) + + // 将散列值转换为大整数 + hBig := new(big.Int).SetBytes(hash) + hBig.Mod(hBig, curve.Params().N) + + return hBig +} + +func equal(lx, ly, rx, ry *big.Int) error { + if lx.Cmp(rx) == 0 && ly.Cmp(ry) == 0 { + return nil + } + return errors.New("point compare failed ") + +} + +func genKGCKey(curve elliptic.Curve) (*big.Int, *big.Int, *big.Int) { + // 随机生成 msk + msk, _ := rand.Int(rand.Reader, curve.Params().N) + PKx, PKy := curve.ScalarBaseMult(msk.Bytes()) + return PKx, PKy, msk +} + +func genSecret(curve elliptic.Curve) (*big.Int, *big.Int, *big.Int) { + // 随机生成 x + x, _ := rand.Int(rand.Reader, curve.Params().N) + Xx, Xy := curve.ScalarBaseMult(x.Bytes()) + return Xx, Xy, x +} + +func genPartialKey(curve elliptic.Curve, ID []byte, msk, Xx, Xy, PKx, PKy *big.Int) (*big.Int, *big.Int, *big.Int) { + // 随机生成 r + r, _ := rand.Int(rand.Reader, curve.Params().N) + Rx, Ry := curve.ScalarBaseMult(r.Bytes()) + + //计算h2的hash值 + h2Big := hash2(curve, ID, Xx, Xy) + + //计算 h2Big * X + tx, ty := curve.ScalarMult(Xx, Xy, h2Big.Bytes()) + + //计算 Q = R + h2 * X + Qx, Qy := curve.Add(Rx, Ry, tx, ty) + + //计算hash1的值 + h1Big := hash1(curve, ID, Qx, Qy, PKx, PKy) + + //计算 d = r + msk * h1 mod n + temp := new(big.Int).Mul(msk, h1Big) + d := new(big.Int).Add(r, temp) + d.Mod(d, curve.Params().N) + return d, Qx, Qy + +} + +func VerifyEquation(curve elliptic.Curve, ID []byte, d, Qx, Qy, Xx, Xy, PKx, PKy *big.Int) error { + //计算等式左值 + h2 * X + lx, ly := curve.ScalarBaseMult(d.Bytes()) + h2Big := hash2(curve, ID, Xx, Xy) + h2Xx, h2Xy := curve.ScalarMult(Xx, Xy, h2Big.Bytes()) + lx, ly = curve.Add(lx, ly, h2Xx, h2Xy) + + //计算 Q + h1 * PK(t) + h1Big := hash1(curve, ID, Qx, Qy, PKx, PKy) + tx, ty := curve.ScalarMult(PKx, PKy, h1Big.Bytes()) + + rx, ry := curve.Add(Qx, Qy, tx, ty) + + err := equal(lx, ly, rx, ry) + if err != nil { + return err + } + + return nil +} + +func genPriKey(curve elliptic.Curve, ID []byte, x, d, Xx, Xy *big.Int) *big.Int { + //计算h2Big + h2Big := hash2(curve, ID, Xx, Xy) + + //计算s = d + h2Big * x + temp := new(big.Int).Mul(h2Big, x) + sUser := new(big.Int).Add(d, temp) + + //s = s mod n + sUser = sUser.Mod(sUser, curve.Params().N) + + return sUser +} + +func SignThumb(curve elliptic.Curve, ID, msg []byte, s, Qx, Qy, PKx, PKy *big.Int) (*big.Int, *big.Int, *big.Int) { + // 生成小于素数 的随机数 u + u, _ := rand.Int(rand.Reader, curve.Params().N) + + // 生成点U + Ux, Uy := curve.ScalarMult(curve.Params().Gx, curve.Params().Gy, u.Bytes()) + + //计算h3 + h3 := hash3(curve, ID, msg, Qx, Qy, Ux, Uy, PKx, PKy) + + // 计算 v = u + h3 * s mod n + // 计算 tmp = sa * h_3_big + tmp := new(big.Int).Mul(h3, s) + + // 计算 v = u + tmp + v := new(big.Int).Add(u, tmp) + + // 计算 v = v mod N + v.Mod(v, curve.Params().N) + + return Ux, Uy, v +} + +func VerifyThumb(curve elliptic.Curve, ID, msg []byte, Qx, Qy, PKx, PKy, Ux, Uy, v *big.Int) error { + //计算h1和h3 + h1Big := hash1(curve, ID, Qx, Qy, PKx, PKy) + h3Big := hash3(curve, ID, msg, Qx, Qy, Ux, Uy, PKx, PKy) + + //验证等式 v*P = U + h_3(Q + h_1 * PK_pub) + //等式左边 + lx, ly := curve.ScalarBaseMult(v.Bytes()) + + // 计算 t = h_1_big * PK_pub + tx, ty := curve.ScalarMult(PKx, PKy, h1Big.Bytes()) + + // 计算 out = Q + t + tx, ty = curve.Add(Qx, Qy, tx, ty) + + // 计算 t = h_3_big * t + tx, ty = curve.ScalarMult(tx, ty, h3Big.Bytes()) + + // 计算 t = U + tmp_p + rx, ry := curve.Add(Ux, Uy, tx, ty) + + //比较等式左右两值是否相等 + err := equal(lx, ly, rx, ry) + if err != nil { + fmt.Println("invalid!") + return err + } + fmt.Println("valid!") + return nil +} + +func writeToFolder(directory, filename string, data []byte) error { + // 检查 cert 文件夹是否存在 + if _, err := os.Stat(directory); os.IsNotExist(err) { + // 如果文件夹不存在,则创建它 + err := os.Mkdir(directory, 0755) + if err != nil { + return fmt.Errorf("创建文件夹时出错: %v", err) + } + } + + // 构造文件的完整路径 + filePath := filepath.Join(directory, filename) + + err := os.WriteFile(filePath, []byte(data), 0644) + if err != nil { + return fmt.Errorf("写入文件时出错: %v", err) + } + fmt.Println("字符串已成功写入文件:", filePath) + return nil +} + +func mergeBigInts(bigInts ...*big.Int) []byte { + var mergedBytes []byte + + for _, num := range bigInts { + numBytes := []byte(num.Text(16)) + mergedBytes = append(mergedBytes, numBytes...) + } + + return mergedBytes +} + +func readFileFromDirectory(directory, filename string) ([]byte, error) { + // 构造文件的完整路径 + filePath := filepath.Join(directory, filename) + + // 读取文件内容 + data, err := os.ReadFile(filePath) + if err != nil { + return nil, err + } + + return data, nil +} + +func BytesToBig(bytes []byte) *big.Int { + //不能直接转为big,转为字符串后用16进制解码 + big := new(big.Int) + big.SetString(string(bytes), 16) + return big +} + +func bytes_halve(slice []byte) ([]byte, []byte) { + length := len(slice) + + // 计算每个部分的长度 + halfLength := length / 2 + + // 切分切片 + part1 := slice[:halfLength] + part2 := slice[halfLength:] + + return part1, part2 +} diff --git a/go_test/main.go b/go_test/main.go new file mode 100644 index 0000000..bc926ff --- /dev/null +++ b/go_test/main.go @@ -0,0 +1,79 @@ +package main + +import ( + "crypto/elliptic" + "fmt" +) + +func main() { + + // 创建 P256 曲线 + curve := elliptic.P256() + + //初始化用户id 和消息 + ID := []byte("1234567890111213141516171819202122232425") + msg := []byte("DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD") + + //生成KGC公私钥 + PKx, PKy, msk := genKGCKey(curve) + + //用户生成秘密值,后经过运算返回点 + Xx, Xy, x := genSecret(curve) + + //KGC生成用户的部分私钥d和全部公钥Q + d, Qx, Qy := genPartialKey(curve, ID, msk, Xx, Xy, PKx, PKy) + + //用户验证生成的部分私钥和全部公钥是否有效 + err := VerifyEquation(curve, ID, d, Qx, Qy, Xx, Xy, PKx, PKy) + if err != nil { + fmt.Println("KGC生成的私钥无效!!!") + return + } + fmt.Println("生成的私钥有效!") + + //用户生成全部私钥 + s := genPriKey(curve, ID, x, d, Xx, Xy) + + //用户对消息签名 + Ux, Uy, v := SignThumb(curve, ID, msg, s, Qx, Qy, PKx, PKy) + + //接收方对消息进行验证 + err = VerifyThumb(curve, ID, msg, Qx, Qy, PKx, PKy, Ux, Uy, v) + if err != nil { + fmt.Println("签名验证失败!") + } + + //fmt.Printf("KGC基点为:\nP_x:%s\nP_y:%s\n", curve.Params().Gx, curve.Params().Gy) + //fmt.Printf("用户的公钥为:\nPK_pub_s:%x\nPK_pub_s:%x\n", PKx, PKy) + + //fmt.Println(append([]byte(PKx.Text(16)), []byte(PKy.Text(16))...)) + + pubdata := mergeBigInts(Qx, Qy) + kgcpub := mergeBigInts(PKx, PKy) + pridata := mergeBigInts(s) + + fmt.Printf("KGC公钥为:%s\n", kgcpub) + fmt.Printf("用户公钥为:%s\n", pubdata) + fmt.Printf("用户私钥为:%s\n", pridata) + //fmt.Printf("用户ID为:\nID:%s\n", ID) + writeToFolder("./cert", "pkpub.txt", kgcpub) + writeToFolder("./cert", "prikey.txt", pridata) + writeToFolder("./cert", "pubkey.txt", pubdata) + + data, _ := readFileFromDirectory("./cert", "pubkey.txt") + fmt.Println(data) + dax, day := bytes_halve(data) + + Dx := BytesToBig(dax) + Dy := BytesToBig(day) + fmt.Println(Dx, Dy) + onCurve := curve.IsOnCurve(Dx, Dy) + + if onCurve { + fmt.Println("点在椭圆曲线上") + } else { + fmt.Println("点不在椭圆曲线上") + } + + //return +}