-
Notifications
You must be signed in to change notification settings - Fork 2.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
327 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(¶ms); 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) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | ||
} |