From 6402ad51c756b30707ec22d273eeb4681a2dc1d8 Mon Sep 17 00:00:00 2001 From: Max-zs Date: Thu, 14 Nov 2024 15:00:44 +0800 Subject: [PATCH] Add kgc module and write makefile rules --- Makefile | 10 ++- kgc/kgc.go | 196 +++++++++++++++++++++++++++++++++++++++++++++++ kgc/main/main.go | 101 ++++++++++++++++++++++++ 3 files changed, 306 insertions(+), 1 deletion(-) create mode 100644 kgc/kgc.go create mode 100644 kgc/main/main.go diff --git a/Makefile b/Makefile index 804b915b..3d7abe53 100644 --- a/Makefile +++ b/Makefile @@ -28,7 +28,7 @@ COLOUR_BLUE=\033[0;34m END_COLOUR=\033[0m # Plugins -NHP_PLUGINS = server/plugins +NHP_PLUGINS = server/plugins kgc generate-version-and-build: @echo "$(COLOUR_BLUE)[OpenNHP] Start building... $(END_COLOUR)" @@ -42,6 +42,7 @@ generate-version-and-build: @$(MAKE) serverd @$(MAKE) agentsdk @$(MAKE) devicesdk + @$(MAKE) kgc @$(MAKE) plugins @$(MAKE) archive @echo "$(COLOUR_GREEN)[OpenNHP] Build for platform ${OS_NAME} successfully done!$(END_COLOUR)" @@ -75,6 +76,13 @@ ifeq ($(OS_NAME), linux) # gcc ./core/sdkdemo/nhp-device-demo.c -I ./release/nhp-device -I ./core/main -l:nhpdevice.so -L./release/nhp-device -Wl,-rpath=. -o ./release/nhp-device/nhp-device-demo endif +# kgc module build rules +kgc: + @echo "$(COLOUR_BLUE)[KGC] Building KGC module... $(END_COLOUR)" + @cd kgc/main && go build -trimpath -ldflags ${LD_FLAGS} -v -o ../release/kgc/kgc ./main.go + @cp ./kgc/etc/*.toml ./release/kgc/etc/ + + plugins: @if test -d $(NHP_PLUGINS); then $(MAKE) -C $(NHP_PLUGINS); fi diff --git a/kgc/kgc.go b/kgc/kgc.go new file mode 100644 index 00000000..754cea7a --- /dev/null +++ b/kgc/kgc.go @@ -0,0 +1,196 @@ +package kgc + +import ( + _ "bytes" + _ "crypto/ecdsa" + _ "crypto/elliptic" + "crypto/rand" + _ "crypto/sha256" + _"encoding/base64" + "encoding/binary" + _ "encoding/binary" + "fmt" + "math/big" + + "github.com/emmansun/gmsm/sm2" + "github.com/emmansun/gmsm/sm3" +) + +// GenerateUserKeyPairSM2,Generate user private key dA_ and public key UA based on SM2 +func GenerateUserKeyPairSM2() (*big.Int, *big.Int, *big.Int, error) { + // Using the SM2 Curve + curve := sm2.P256() + // Randomly generate user private key dA_, the range is [1, n-1] + dA_, err := rand.Int(rand.Reader, curve.Params().N) + if err != nil { + return nil, nil, nil, fmt.Errorf("Failed to generate user private key dA_: %v", err) + } + + // Make sure dA_ is not 0 + if dA_.Cmp(big.NewInt(0)) == 0 { + dA_, err = rand.Int(rand.Reader, curve.Params().N) + if err != nil { + return nil, nil, nil, fmt.Errorf("Failed to regenerate user private key: %v", err) + } + } + // Use the curve base point G to calculate the user public key UA = [dA_]G + UAx, UAy := curve.ScalarBaseMult(dA_.Bytes()) + return dA_, UAx, UAy, nil +} + +// GenerateMasterKeyPairSM2,Generate the system's master private key ms and master public key Ppub +func GenerateMasterKeyPairSM2() (*big.Int, *big.Int, *big.Int, error) { + // Using the SM2 Curve + curve := sm2.P256() + + // Generate the system master private key ms, the range is [1, n-1] + ms, err := rand.Int(rand.Reader, curve.Params().N) + if err != nil { + return nil, nil, nil, fmt.Errorf("Failed to generate system master private key ms: %v", err) + } + + // Make sure ms is not 0 + if ms.Cmp(big.NewInt(0)) == 0 { + ms, err = rand.Int(rand.Reader, curve.Params().N) + if err != nil { + return nil, nil, nil, fmt.Errorf("Regeneration of system master private key ms failed: %v", err) + } + } + // Use the curve base point G to calculate the system master public key Ppub = [ms]G + PpubX, PpubY := curve.ScalarBaseMult(ms.Bytes()) + return ms, PpubX, PpubY, nil +} + +// GenerateWA,Calculate WA = [w]G + UA +func GenerateWA(UAx, UAy *big.Int) (*big.Int, *big.Int, *big.Int, error) { + // Using the SM2 curve + curve := sm2.P256() + + // Generate a random number w in the range [1, n-1] + w, err := rand.Int(rand.Reader, curve.Params().N) + if err != nil { + return nil, nil, nil, fmt.Errorf("Failed to generate random number w: %v", err) + } + + // Make sure w is not 0 + if w.Cmp(big.NewInt(0)) == 0 { + w, err = rand.Int(rand.Reader, curve.Params().N) + if err != nil { + return nil, nil, nil, fmt.Errorf("Failed to regenerate random number w: %v", err) + } + } + Wx, Wy := curve.ScalarBaseMult(w.Bytes()) + //fmt.Printf("wx=%x, wy=%x\n", Wx, Wy) + WAx, WAy := curve.Add(Wx, Wy, UAx, UAy) + return WAx, WAy, w, nil +} + +func CalculateHA(entlA int, idA []byte, a, b, xG, yG, xPub, yPub *big.Int) []byte { + // Convert entlA to a 2-byte bit string + entlABytes := make([]byte, 2) + binary.BigEndian.PutUint16(entlABytes, uint16(entlA)) + // Concatenate all parameters + data := append(entlABytes, idA...) + data = append(data, a.Bytes()...) + data = append(data, b.Bytes()...) + data = append(data, xG.Bytes()...) + data = append(data, yG.Bytes()...) + data = append(data, xPub.Bytes()...) + data = append(data, yPub.Bytes()...) + // Calculating SM3 hash value + hash := sm3.New() + hash.Write(data) + HA := hash.Sum(nil) + return HA +} + +// ComputeL l = H256(xWA‖yWA‖HA) mod n +func ComputeL(xWA, yWA *big.Int, HA []byte, n *big.Int) (*big.Int, error) { + // Convert the coordinates of WA to a bit string + xBits := intToBitString(xWA) + yBits := intToBitString(yWA) + // Concatenating bit strings and HA + hashData := append(xBits, yBits...) + hashData = append(hashData, HA...) + // Calculating hashes using SM3 + hash := sm3.Sum(hashData) + // Convert the hash value to a big.Int + l := new(big.Int).SetBytes(hash[:]) + l.Mod(l, n) + if l.Cmp(big.NewInt(0)) < 0 { + return nil, fmt.Errorf("The calculated result l is a negative number") + } + + // Convert l to a byte string + k := (n.BitLen() + 7) / 8 + lBytes := intToBytes(l, k) + + // Convert l to an integer, ensuring compliance with the standard + lInteger := new(big.Int).SetBytes(lBytes) + + return lInteger, nil +} + +// intToBitString +func intToBitString(x *big.Int) []byte { + + bitLen := x.BitLen() + + byteLen := (bitLen + 7) / 8 + + bitString := make([]byte, byteLen) + + xBytes := x.Bytes() + + copy(bitString[byteLen-len(xBytes):], xBytes) + + return bitString +} + +// intToBytes +func intToBytes(x *big.Int, k int) []byte { + m := make([]byte, k) + xBytes := x.Bytes() + copy(m[k-len(xBytes):], xBytes) + return m +} + +// 计算 tA +func ComputeTA(w, lInteger, ms, n *big.Int) *big.Int { + tA := new(big.Int).Set(w) + lMod := new(big.Int).Mod(lInteger, n) + msMod := new(big.Int).Mod(ms, n) + lMulMs := new(big.Int).Mul(lMod, msMod) + lMulMs.Mod(lMulMs, n) + tA.Add(tA, lMulMs) // tA = w + (l * ms) + tA.Mod(tA, n) // tA = (w + (l * ms)) mod n + return tA +} + +// 计算 dA +func ComputeDA(tA, dA_ *big.Int, n *big.Int) *big.Int { + dA := new(big.Int).Set(tA) + dA.Add(dA, dA_) + dA.Mod(dA, n) + return dA +} + +// Calculate PA = WA + [l]Ppub +func ComputePA(WAx, WAy, PpubX, PpubY *big.Int, lInteger *big.Int) (*big.Int, *big.Int) { + curve := sm2.P256() + PpubXl, PpubYl := curve.ScalarMult(PpubX, PpubY, lInteger.Bytes()) + //fmt.Printf("PpubXl=%x, PpubYl=%x\n", PpubXl, PpubYl) + PAx, PAy := curve.Add(WAx, WAy, PpubXl, PpubYl) + return PAx, PAy +} + +// Calculate P'A = [dA]G +func ComputePAPrime(dA *big.Int) (*big.Int, *big.Int) { + curve := sm2.P256() + PAX_, PAY_ := curve.ScalarBaseMult(dA.Bytes()) + return PAX_, PAY_ +} + + + + diff --git a/kgc/main/main.go b/kgc/main/main.go new file mode 100644 index 00000000..039fc086 --- /dev/null +++ b/kgc/main/main.go @@ -0,0 +1,101 @@ +package main + +import ( + _ "crypto/rand" + "fmt" + _ "log" + "math/big" + + _"github.com/OpenNHP/opennhp/core/scheme/curve" + "github.com/OpenNHP/opennhp/kgc" + "github.com/emmansun/gmsm/sm2" +) + +func main() { + idA := []byte("example@163.com") // Example user ID + entlA := len(idA)*8 + //fmt.Print("User ID: ", idA) + //fmt.Printf("User ID length: %d\n", entlA) + curve := sm2.P256() // Use SM2 curves + //n := new(big.Int) + //n.SetString("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC", 16) + n := curve.Params().N + + gx := new(big.Int) + gx.SetString("32C4AE2C1F1981195F9904466A79E36EAA3C8E4B1EAC73D2C2FB7D3290ECF8A5", 16) + + gy := new(big.Int) + gy.SetString("BC3E1A3D1F1694E1A3D1C3E34D35E4C510DC53D6A57E44D2B38C6B8C8AD7C1A1", 16) + /* gx := curve.Params().Gx // x coordinate of base point G + gy := curve.Params().Gy // y coordinate of base point G */ + a := new(big.Int) + a.SetString("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF", 16) + + b := new(big.Int) + b.SetString("28E9FA9E9D9A3E004F2018D6F8C7193A3197D1A9F23A5C24B545C1E3A09F31A4", 16) + /* a :=big.NewInt(0) // a value of the curve + b := curve.Params().B // b value of the curve */ + + + dA_, UAx, UAy, err := kgc.GenerateUserKeyPairSM2() +if err != nil { + fmt.Printf("User partial key pair generation failed: %v\n", err) + return +} +fmt.Printf("User partial key pair generated successfully:\n dA_ = %X \n UAx = %X \n UAy = %X\n", dA_, UAx, UAy) +fmt.Printf("-------------------------------------------------------------------------\n") + + + + // Generate KGC master key pair + ms, XPpub, YPpub, err := kgc.GenerateMasterKeyPairSM2() + if err != nil { + fmt.Printf("Failed to generate kgc master key pair: %v\n", err) + return + } + fmt.Printf("KGC master key pair generated successfully:\n ms = %X \n XPpub = %X \n YPPub = %X\n", ms, XPpub, YPpub) + fmt.Printf("-------------------------------------------------------------------------\n") + + + WAX, WAY, w, err := kgc.GenerateWA(UAx, UAy) + if err != nil { + fmt.Printf("Failed to generate WA: %v\n", err) + return + } + fmt.Printf("WA calculation successful:\n WAX = %X \n WAY = %X \n w = %X\n", WAX, WAY, w) + fmt.Printf("-------------------------------------------------------------------------\n") + ha := kgc.CalculateHA(entlA, idA, a,b,gx, gy, XPpub, YPpub) + fmt.Printf("HA calculation successful:\n ha = %x\n", ha) + fmt.Printf("-------------------------------------------------------------------------\n") + lInteger, err := kgc.ComputeL(WAX, WAY, ha, n) + if err != nil { + fmt.Printf("Failed to calculate L: %v\n", err) + return + } + fmt.Printf("Calculation success: \n L = %X\n", lInteger) + fmt.Printf("-------------------------------------------------------------------------\n") + TA := kgc.ComputeTA(w, lInteger, ms, n) + fmt.Printf("Calculate TA success: \n TA = %X\n",TA ) + fmt.Printf("-------------------------------------------------------------------------\n") + dA := kgc.ComputeDA(TA, dA_, n) + fmt.Printf("User's actual private key: \n dA = %X\n", dA) + fmt.Printf("-------------------------------------------------------------------------\n") + PAX, PAY := kgc.ComputePA(WAX, WAY, XPpub, YPpub, lInteger) + fmt.Printf("User's actual public key: \n PAX = %X \n PAY = %X\n", PAX, PAY) + fmt.Printf("-------------------------------------------------------------------------\n") + PAX_, PAY_ := kgc.ComputePAPrime(dA) + fmt.Printf("Calculate PA' successfully:\n PAX_ = %X \n PAY_ = %X\n", PAX_, PAY_) + fmt.Printf("-------------------------------------------------------------------------\n") + if PAX.Cmp(PAX_) != 0 { + fmt.Printf("Verification of PAX failed\n") + } else { + fmt.Printf("Verify PAX success\n") + } + if PAY.Cmp(PAY_) != 0 { + fmt.Printf("Verification of PAY failed\n") + } else { + fmt.Printf("Verify PAY success\n") + } + + +}