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

kgc module (not completed) #1218

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
171 changes: 171 additions & 0 deletions kgc/kgc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
package kgc

import (
"bytes"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/sha256"
"encoding/binary"
"encoding/json"
"fmt"
"math/big"
mathRand "math/rand"
"net/http"

"github.com/emmansun/gmsm/sm2"
"github.com/emmansun/gmsm/sm3"
)

// 定义椭圆曲线参数的固定值
var fixedA, _ = new(big.Int).SetString("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC", 16)
var fixedB, _ = new(big.Int).SetString("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFD", 16)

// HAParams 结构体用于存储计算 HA 所需的参数
type HAParams struct {
UserID string `json:"user_id"` // 用户 ID
EntlenA int `json:"entlen_a"` // entlenA 的长度
Curve elliptic.Curve `json:"-"` // 椭圆曲线
XPub *big.Int `json:"x_pub"` // 公钥的 x 坐标
YPub *big.Int `json:"y_pub"` // 公钥的 y 坐标
UAx *big.Int `json:"u_ax"` // UA x 坐标
UAy *big.Int `json:"u_ay"` // UA y 坐标
}

// 生成 KGC 的主密钥对
func GenerateMasterKeyPair() (*sm2.PrivateKey, *ecdsa.PublicKey, error) {
ms, err := sm2.GenerateKey(rand.Reader)
if err != nil {
return nil, nil, fmt.Errorf("生成主密钥失败: %v", err)
}
curve := sm2.P256()
PpubX, PpubY := curve.ScalarBaseMult(ms.D.Bytes())
Ppub := &ecdsa.PublicKey{Curve: curve, X: PpubX, Y: PpubY}
return ms, Ppub, nil
}

// 计算 HA 值
func CalculateHA(params HAParams) []byte {
entla := make([]byte, 2)
binary.BigEndian.PutUint16(entla, uint16(params.EntlenA))
ida := []byte(params.UserID)
xG := params.Curve.Params().Gx
yG := params.Curve.Params().Gy
a := fixedA.Bytes()
b := fixedB.Bytes()

data := bytes.Join([][]byte{
entla, ida, a, b,
xG.Bytes(), yG.Bytes(),
params.XPub.Bytes(), params.YPub.Bytes(),
}, nil)

hash := sha256.New()
hash.Write(data)
return hash.Sum(nil)
}

// 固定种子初始化随机数生成器
var seededRand2 = mathRand.New(mathRand.NewSource(67890))

// 生成 kgc 随机数 W
func GetRandomW(n *big.Int) (*big.Int, error) {
W := new(big.Int)
nMinusOne := new(big.Int).Sub(n, big.NewInt(1))
for {
W.SetInt64(seededRand2.Int63n(nMinusOne.Int64()-1) + 1)

if W.Cmp(big.NewInt(1)) >= 0 && W.Cmp(n) < 0 {
break
}
}
return W, nil
}

// CalculateWA 计算 WA = [W]G + UA
func CalculateWA(uaX, uaY *big.Int) (*big.Int, *big.Int, error) {
n := sm2.P256().Params().N
W, err := GetRandomW(n)
if err != nil {
return nil, nil, err
}

curve := sm2.P256()
WAx, WAy := curve.ScalarBaseMult(W.Bytes())
WAx, WAy = curve.Add(WAx, WAy, uaX, uaY)

return WAx, WAy, nil
}

// 计算 L 值
func CalculateL(waX, waY *big.Int, ha []byte) *big.Int {
waCoords := append(waX.Bytes(), waY.Bytes()...)
dataForL := append(waCoords, ha...)

hashL := sm3.New()
hashL.Write(dataForL)
hashValue := hashL.Sum(nil)

l := new(big.Int).SetBytes(hashValue)
l.Mod(l, sm2.P256().Params().N)

return l
}

// 计算 tA
func CalculateTA(n *big.Int, ha []byte, waX, waY *big.Int) (*big.Int, error) {
w, err := GetRandomW(n)
if err != nil {
return nil, err
}

ms, _, err := GenerateMasterKeyPair()
if err != nil {
return nil, err
}

l := CalculateL(waX, waY, ha)

lms := new(big.Int).Mul(l, ms.D)
tA := new(big.Int).Add(w, lms)
tA.Mod(tA, n)

return tA, nil
}

// HTTP 处理函数
func HandleRequest(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, "Invalid request method", http.StatusMethodNotAllowed)
return
}

var params HAParams
if err := json.NewDecoder(r.Body).Decode(&params); err != nil {
http.Error(w, "Invalid request payload", http.StatusBadRequest)
return
}
params.Curve = sm2.P256() // 设置曲线

ha := CalculateHA(params)

// 计算 WA
waX, waY, err := CalculateWA(params.UAx, params.UAy)
if err != nil {
http.Error(w, "计算 WA 失败", http.StatusInternalServerError)
return
}

response := map[string]interface{}{
"ha": fmt.Sprintf("%x", ha),
"wa": fmt.Sprintf("%x,%x", waX, waY),
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(response)
}

// 启动 HTTP 服务器
func StartServer() {
http.HandleFunc("/calculate_ha", HandleRequest)
http.ListenAndServe(":8080", nil)
}
156 changes: 156 additions & 0 deletions kgc/main/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
package main

import (
"bufio"
"bytes"
"encoding/json"
"fmt"
"math/big"
mathRand "math/rand"
"net/http"
"os"

"github.com/OpenNHP/opennhp/kgc"
"github.com/emmansun/gmsm/sm2" // 替换为实际路径
)

// 固定种子初始化随机数生成器
var seededRand1 = mathRand.New(mathRand.NewSource(12345)) // 使用固定的种子

// 生成用户随机数 dA_
func GetRandomdA_(n *big.Int) (*big.Int, error) {
dA_ := new(big.Int)
nMinusOne := new(big.Int).Sub(n, big.NewInt(1))
for {
dA_.SetInt64(seededRand1.Int63n(nMinusOne.Int64()-1) + 1)

if dA_.Cmp(big.NewInt(1)) >= 0 && dA_.Cmp(n) < 0 {
break
}
}
return dA_, nil
}

// CalculateUA 计算 UA = [dA_]G
func CalculateUA() (*big.Int, *big.Int, *big.Int, error) {
n := sm2.P256().Params().N
dA_, err := GetRandomdA_(n)
if err != nil {
return nil, nil, nil, err
}

curve := sm2.P256()
UAx, UAy := curve.ScalarBaseMult(dA_.Bytes())

return dA_, UAx, UAy, nil
}

// 计算 dA = (tA + dA_) mod n
func CalculateDA(n *big.Int, ha []byte, waX, waY *big.Int) (*big.Int, error) {
tA, err := kgc.CalculateTA(n, ha, waX, waY)
if err != nil {
return nil, err
}

dA_, err := GetRandomdA_(n)
if err != nil {
return nil, err
}

dA := new(big.Int).Add(tA, dA_)
dA.Mod(dA, n)

fmt.Printf("计算的 dA: %s\n", dA.String())
return dA, nil
}

// CalculatePA 计算 PA = WA + [l]Ppub
func CalculatePA() (*big.Int, *big.Int, error) {
_, Ppub, err := kgc.GenerateMasterKeyPair()
if err != nil {
return nil, nil, err
}

waX, waY, err := kgc.CalculateWA()
if err != nil {
return nil, nil, err
}

l := kgc.CalculateL(waX, waY, nil)

curve := sm2.P256()
PAx, PAy := curve.ScalarBaseMult(l.Bytes())
PAx, PAy = curve.Add(PAx, PAy, Ppub.X, Ppub.Y)

return PAx, PAy, nil
}

// 计算 PA_ = [dA]G
func CalculatePA_() (*big.Int, *big.Int, error) {
curve := sm2.P256()
n := curve.Params().N

var ha []byte
waX, waY, err := kgc.CalculateWA()
if err != nil {
return nil, nil, err
}

dA, err := CalculateDA(n, ha, waX, waY)
if err != nil {
return nil, nil, err
}

PA_X, PA_Y := curve.ScalarBaseMult(dA.Bytes())

return PA_X, PA_Y, nil
}

// 发送 HTTP 请求
func SendHTTPRequest(email string) {
params := kgc.HAParams{
UserID: email,
EntlenA: len(email),
Curve: sm2.P256(),
}

// 设置公钥的 x 和 y 坐标(示例)
// 实际使用中需要替换为计算得到的公钥坐标
params.XPub = big.NewInt(0) // 设置为实际值
params.YPub = big.NewInt(0) // 设置为实际值

jsonData, err := json.Marshal(params)
if err != nil {
fmt.Printf("JSON 编码失败: %v\n", err)
return
}

resp, err := http.Post("http://localhost:8080/calculate_ha", "application/json", bytes.NewBuffer(jsonData))
if err != nil {
fmt.Printf("HTTP 请求失败: %v\n", err)
return
}
defer resp.Body.Close()

if resp.StatusCode != http.StatusOK {
fmt.Printf("请求失败,状态码: %d\n", resp.StatusCode)
return
}

var response map[string]interface{}
if err := json.NewDecoder(resp.Body).Decode(&response); err != nil {
fmt.Printf("响应解析失败: %v\n", err)
return
}

fmt.Printf("计算的 HA: %s\n", response["ha"])
}

func main() {
reader := bufio.NewReader(os.Stdin)
fmt.Print("请输入邮箱: ")
email, _ := reader.ReadString('\n')

// 发送 HTTP 请求
SendHTTPRequest(email)
}
Loading