//generate signature in repeatable way func SignDeterministic(msg []byte, seckey []byte, nonce_seed []byte) []byte { nonce := SumSHA256(nonce_seed) //deterministicly generate nonce var sig []byte = make([]byte, 65) var recid C.int var msg_ptr *C.uchar = (*C.uchar)(unsafe.Pointer(&msg[0])) var seckey_ptr *C.uchar = (*C.uchar)(unsafe.Pointer(&seckey[0])) var nonce_ptr *C.uchar = (*C.uchar)(unsafe.Pointer(&nonce[0])) var sig_ptr *C.uchar = (*C.uchar)(unsafe.Pointer(&sig[0])) if C.secp256k1_ecdsa_seckey_verify(seckey_ptr) != C.int(1) { log.Panic("Invalid secret key") } ret := C.secp256k1_ecdsa_sign_compact( msg_ptr, C.int(len(msg)), sig_ptr, seckey_ptr, nonce_ptr, &recid) sig[64] = byte(int(recid)) if int(recid) > 4 { log.Panic() } if ret != 1 { return SignDeterministic(msg, seckey, nonce_seed) //nonce invalid,retry } return sig }
func GenerateKeyPair() ([]byte, []byte) { pubkey_len := C.int(33) const seckey_len = 32 var pubkey []byte = make([]byte, pubkey_len) var pubkey_ptr *C.uchar = (*C.uchar)(unsafe.Pointer(&pubkey[0])) var ret C.int new_seckey: var seckey []byte = RandByte(seckey_len) var seckey_ptr *C.uchar = (*C.uchar)(unsafe.Pointer(&seckey[0])) ret = C.secp256k1_ecdsa_seckey_verify(seckey_ptr) if ret != 1 { goto new_seckey } //for C.secp256k1_ecdsa_seckey_verify(seckey_ptr) != 1 { // seckey = RandByte(seckey_len) // seckey_ptr = (*C.uchar)(unsafe.Pointer(&seckey[0])) //} ret = C.secp256k1_ecdsa_pubkey_create( pubkey_ptr, &pubkey_len, seckey_ptr, 1) if ret != 1 { goto new_seckey } return pubkey, seckey }
//generates deterministic keypair with weak SHA256 hash of seed //internal use only //be extremely careful with golang slice semantics func generateDeterministicKeyPair(seed []byte) ([]byte, []byte) { if seed == nil { log.Panic() } pubkey_len := C.int(33) const seckey_len = 32 var pubkey []byte = make([]byte, pubkey_len) var seckey []byte = make([]byte, seckey_len) var pubkey_ptr *C.uchar = (*C.uchar)(unsafe.Pointer(&pubkey[0])) var seckey_ptr *C.uchar = (*C.uchar)(unsafe.Pointer(&seckey[0])) new_seckey: seed = SumSHA256(seed[0:32]) copy(seckey[0:32], seed[0:32]) if C.secp256k1_ecdsa_seckey_verify(seckey_ptr) != 1 { goto new_seckey //rehash seckey until it succeeds, almost never happens } ret := C.secp256k1_ecdsa_pubkey_create( pubkey_ptr, &pubkey_len, seckey_ptr, 1) if ret != 1 { log.Panic("secp256k1-g0, generateDeterministicKeyPair, pubkey generation failing for valid seckey") } return pubkey, seckey }
func Sign(msg []byte, seckey []byte) []byte { var nonce []byte = RandByte(32) var sig []byte = make([]byte, 65) var recid C.int var msg_ptr *C.uchar = (*C.uchar)(unsafe.Pointer(&msg[0])) var seckey_ptr *C.uchar = (*C.uchar)(unsafe.Pointer(&seckey[0])) var nonce_ptr *C.uchar = (*C.uchar)(unsafe.Pointer(&nonce[0])) var sig_ptr *C.uchar = (*C.uchar)(unsafe.Pointer(&sig[0])) if C.secp256k1_ecdsa_seckey_verify(seckey_ptr) != C.int(1) { log.Panic("Invalid secret key") } ret := C.secp256k1_ecdsa_sign_compact( msg_ptr, C.int(len(msg)), sig_ptr, seckey_ptr, nonce_ptr, &recid) sig[64] = byte(int(recid)) if int(recid) > 4 { log.Panic() } if ret != 1 { return Sign(msg, seckey) //nonce invalid,retry } return sig }
//returns nil on error //Does not return same output as generator does func PubkeyFromSeckey(SecKey []byte) []byte { if len(SecKey) != 32 { log.Panic("PubkeyFromSeckey: invalid length") } pubkey_len := C.int(33) const seckey_len = 32 var pubkey []byte = make([]byte, pubkey_len) var seckey []byte = make([]byte, seckey_len) copy(seckey, SecKey) var pubkey_ptr *C.uchar = (*C.uchar)(unsafe.Pointer(&pubkey[0])) var seckey_ptr *C.uchar = (*C.uchar)(unsafe.Pointer(&seckey[0])) //ensure that private key is valid ret := C.secp256k1_ecdsa_seckey_verify(seckey_ptr) if ret != 1 { log.Panic("PubkeyFromSeckey: invalid seckey") } //create public key from seckey ret = C.secp256k1_ecdsa_pubkey_create( pubkey_ptr, &pubkey_len, seckey_ptr, 1) if ret != 1 { return nil } return pubkey }
//Rename ChkSeckeyValidity func VerifySeckey(seckey []byte) int { if len(seckey) != 32 { return 0 } var seckey_ptr *C.uchar = (*C.uchar)(unsafe.Pointer(&seckey[0])) ret := C.secp256k1_ecdsa_seckey_verify(seckey_ptr) return int(ret) }
//Rename SignHash func Sign(msg []byte, seckey []byte) []byte { if len(seckey) != 32 { log.Panic("Sign, Invalid seckey length") } if msg == nil { log.Panic("Sign, message nil") } var nonce []byte = RandByte(32) //going to get bitcoins stolen! var sig []byte = make([]byte, 65) var recid C.int var msg_ptr *C.uchar = (*C.uchar)(unsafe.Pointer(&msg[0])) var seckey_ptr *C.uchar = (*C.uchar)(unsafe.Pointer(&seckey[0])) var nonce_ptr *C.uchar = (*C.uchar)(unsafe.Pointer(&nonce[0])) var sig_ptr *C.uchar = (*C.uchar)(unsafe.Pointer(&sig[0])) if C.secp256k1_ecdsa_seckey_verify(seckey_ptr) != C.int(1) { log.Panic() //invalid seckey } ret := C.secp256k1_ecdsa_sign_compact( msg_ptr, C.int(len(msg)), sig_ptr, seckey_ptr, nonce_ptr, &recid) sig[64] = byte(int(recid)) if int(recid) > 4 { log.Panic() } if ret != 1 { return Sign(msg, seckey) //nonce invalid,retry } return sig }