Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add kgc module and write makefile rules #1238

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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)"
Expand All @@ -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)"
Expand Down Expand Up @@ -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

Expand Down
196 changes: 196 additions & 0 deletions kgc/kgc.go
Original file line number Diff line number Diff line change
@@ -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_
}




101 changes: 101 additions & 0 deletions kgc/main/main.go
Original file line number Diff line number Diff line change
@@ -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")
}


}
Loading