273 lines
5.9 KiB
Go
273 lines
5.9 KiB
Go
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(¶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.")
|
||
}
|
||
|
||
}
|