KGC_TEST/SIG_AND_VERIFY/main.go

273 lines
5.9 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package main
/*
#cgo CFLAGS: -I${SRCDIR}/include
#cgo LDFLAGS: -L${SRCDIR}/lib -lKGCAll
#include "miracl.h"
#include "mirdef.h"
#include "hash.h"
#include "kgc.h"
#include "utils.h"
#include "ecurve.h"
#include "sign.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
char* IDA = "1234567890111213141516171819202122232425"; // 发送者ID
char* M = "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD";
char* PRI = "pri_big";
char* PUB = "pub_point";
char* PKPUB = "pk_point";
*/
import "C"
import (
"fmt"
"io/ioutil"
"unsafe"
)
func string_halve(str string) (string, string) {
// 计算字符串长度
length := len(str)
// 将字符串分成两部分
mid := length / 2
part1 := str[:mid]
part2 := str[mid:]
//fmt.Println("第一部分:", part1)
//fmt.Println("第二部分:", part2)
return part1, part2
}
func string_trisect(str string) (string, string, string) {
length := len(str)
// 计算每个子字符串的长度
subStrLen := length / 3
// 切分字符串
part1 := str[:subStrLen]
part2 := str[subStrLen : 2*subStrLen]
part3 := str[2*subStrLen:]
return part1, part2, part3
}
func bytes_halve(slice []byte) ([]byte, []byte) {
length := len(slice)
// 计算每个部分的长度
halfLength := length / 2
// 切分切片
part1 := slice[:halfLength]
part2 := slice[halfLength:]
return part1, part2
}
func bytes_trisect(slice []byte) ([]byte, []byte, []byte) {
length := len(slice)
// 计算每个部分的长度
partLength := length / 3
// 切分切片
part1 := slice[:partLength]
part2 := slice[partLength : 2*partLength]
part3 := slice[2*partLength:]
return part1, part2, part3
}
// 实现C语言char字符串转Go语言string
func CharToString(cString *C.char) string {
goString := C.GoString(cString)
defer C.free(unsafe.Pointer(cString))
return goString
}
// ReadFileToBytes 从文件中读取内容,并返回字节数组和可能的错误
func ReadFileToBytes(filename string) ([]byte, error) {
// 读取文件内容
data, err := ioutil.ReadFile(filename)
if err != nil {
return nil, err
}
return data, nil
}
func BigToBytes(x C.big) []byte {
cString := C.malloc(257)
defer C.free(cString)
// 调用 cotstr 函数将 big 类型的整数转换为字符串
C.cotstr(x, (*C.char)(cString))
str := C.GoString((*C.char)(cString))
bytes := []byte(str)
return bytes
}
func PointToBytes(p *C.epoint) []byte {
p_x := C.mirvar(0)
defer C.mirkill(p_x)
p_y := C.mirvar(0)
defer C.mirkill(p_y)
C.epoint_get(p, p_x, p_y)
x := BigToBytes(p_x)
y := BigToBytes(p_y)
return append(x, y...)
}
func BytesToBig(bytes []byte) C.big {
big := C.mirvar(0)
str := C.CString(string(bytes))
C.cinstr(big, str)
defer C.free(unsafe.Pointer(str))
return big
}
func BytesToPoint(bytes []byte) *C.epoint {
bytes1, bytes2 := bytes_halve(bytes)
big1 := BytesToBig(bytes1)
defer C.mirkill(big1)
big2 := BytesToBig(bytes2)
defer C.mirkill(big2)
point := C.epoint_init()
C.epoint_set(big1, big2, 0, point)
return point
}
func SigToBytes(U *C.epoint, v C.big) []byte {
U_bytes := PointToBytes(U)
val_bytes := BigToBytes(v)
signature := append(U_bytes, val_bytes...)
return signature
}
func BytesToSig(sig []byte) (U *C.epoint, val C.big) {
U_x := C.mirvar(0)
U_y := C.mirvar(0)
defer C.mirkill(U_x)
defer C.mirkill(U_y)
v_test := C.mirvar(0)
U_test := C.epoint_init()
U_x_bytes, U_y_bytes, v_bytes := bytes_trisect(sig)
Ux := C.CString(string(U_x_bytes))
Uy := C.CString(string(U_y_bytes))
v := C.CString(string(v_bytes))
C.cinstr(U_x, Ux)
C.cinstr(U_y, Uy)
C.cinstr(v_test, v)
defer C.free(unsafe.Pointer(Ux))
defer C.free(unsafe.Pointer(Uy))
defer C.free(unsafe.Pointer(v))
C.epoint_set(U_x, U_y, 0, U_test)
return U_test, v_test
}
func main() {
mip := C.mirsys(512, 16) // 初始化MIRACL系统512位16进制数
mip.IOBASE = 16 // 设置大整数为16进制
defer C.mirexit()
C.setRandSeed() // 随机数种子
// 建立椭圆曲线
var params C.ECC_PARAMS
if !C.setupEcurve(&params) {
fmt.Println("ecurve setup failed")
C.mirexit()
panic("椭圆曲线建立失败!")
}
defer C.freeEcurve(&params)
//初始化参数
PK_pub := C.epoint_init() //公钥
defer C.epoint_free(PK_pub)
val := C.mirvar(0) //用户返回的签名值
defer C.mirkill(val)
U := C.epoint_init() //随机点值
defer C.epoint_free(U)
//读取配置文件
pk, _ := ReadFileToBytes("./cert/pkpub.txt")
prikey, _ := ReadFileToBytes("./cert/prikey.txt")
pubkey, _ := ReadFileToBytes("./cert/pubkey.txt")
//prikey := "A83FADCF99E5F576F9E3C93022BDE2C9A1DCFA9CAE78AEC06FA166BEE4B2DB06"
//pubkey := "ADB8A74356BB524EE4BCB37E990062007565A563C9C66A6CB9D503B4B9F008EE33D21F33EC4A52C1BBA230C0839EF660D0EA2B3040FE3320F250E1C905FB6D57"
p1, p2 := bytes_halve(pubkey)
p1_big := BytesToBig(p1)
defer C.mirkill(p1_big)
p2_big := BytesToBig(p2)
defer C.mirkill(p2_big)
pri_big := BytesToBig(prikey)
defer C.mirkill(pri_big)
//将两个big大数转成点
pub_point := C.epoint_init()
defer C.epoint_free(pub_point)
C.epoint_set(p1_big, p2_big, 0, pub_point)
//pk := "1980F6B7C93CE23B6D54F7116A11A700DEEDB355FD7F0CF518CC43CADEB92D33DE17316AC929C6DA20117C60AF924CBA98F102D054B34EC0F657CE616590E222"
//将导入的kgc公钥字节流转为椭圆曲线上的点
PK_pub = BytesToPoint(pk)
//打印重要参数
C.outbig(pri_big, C.PRI)
C.outpoint(pub_point, C.PUB)
C.outpoint(PK_pub, C.PKPUB)
// 签名Gowri Thumbur方案
C.sign_Thumbur(&params, C.IDA, C.M, pri_big, pub_point, U, PK_pub, val)
// 把签名消息转为byte切片放入
signature := SigToBytes(U, val)
fmt.Println("\n签名的消息为", signature)
//从signatrue中解析U和val
U_test, v_test := BytesToSig(signature)
defer C.epoint_free(U_test)
defer C.mirkill(v_test)
// 验签
if C.verify_Thumbur(&params, C.IDA, C.M, pub_point, PK_pub, U_test, v_test) {
fmt.Println("\nsignature valid.")
} else {
fmt.Println("\nverify failed.")
}
}