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 #include #include 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(¶ms) { fmt.Println("ecurve setup failed") C.mirexit() panic("椭圆曲线建立失败!") } defer C.freeEcurve(¶ms) //初始化参数 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(¶ms, 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(¶ms, C.IDA, C.M, pub_point, PK_pub, U_test, v_test) { fmt.Println("\nsignature valid.") } else { fmt.Println("\nverify failed.") } }