good morning!!!!

Skip to content
Snippets Groups Projects
Commit d9b37b6d authored by Gustav Simonsson's avatar Gustav Simonsson
Browse files

Update Go wrapper around libbsecp256k1

parent f4d4f1cc
No related branches found
No related tags found
No related merge requests found
package secp256k1
// TODO: set USE_SCALAR_4X64 depending on platform?
/*
#cgo CFLAGS: -std=gnu99 -Wno-error
#cgo darwin CFLAGS: -I/usr/local/include
#cgo LDFLAGS: -lgmp
#cgo darwin LDFLAGS: -L/usr/local/lib
#define USE_FIELD_10X26
#cgo CFLAGS: -I./secp256k1
#define USE_NUM_GMP
#define USE_FIELD_10X26
#define USE_FIELD_INV_BUILTIN
#define USE_SCALAR_8X32
#define USE_SCALAR_INV_BUILTIN
#include "./secp256k1/src/secp256k1.c"
*/
import "C"
......@@ -38,32 +39,14 @@ import (
*/
func init() {
C.secp256k1_start() //takes 10ms to 100ms
//takes 10ms to 100ms
C.secp256k1_start(3) // SECP256K1_START_SIGN | SECP256K1_START_VERIFY
}
func Stop() {
C.secp256k1_stop()
}
/*
int secp256k1_ecdsa_pubkey_create(
unsigned char *pubkey, int *pubkeylen,
const unsigned char *seckey, int compressed);
*/
/** Compute the public key for a secret key.
* In: compressed: whether the computed public key should be compressed
* seckey: pointer to a 32-byte private key.
* Out: pubkey: pointer to a 33-byte (if compressed) or 65-byte (if uncompressed)
* area to store the public key.
* pubkeylen: pointer to int that will be updated to contains the pubkey's
* length.
* Returns: 1: secret was valid, public key stores
* 0: secret was invalid, try again.
*/
//pubkey, seckey
func GenerateKeyPair() ([]byte, []byte) {
pubkey_len := C.int(65)
......@@ -75,7 +58,7 @@ func GenerateKeyPair() ([]byte, []byte) {
var pubkey_ptr *C.uchar = (*C.uchar)(unsafe.Pointer(&pubkey[0]))
var seckey_ptr *C.uchar = (*C.uchar)(unsafe.Pointer(&seckey[0]))
ret := C.secp256k1_ecdsa_pubkey_create(
ret := C.secp256k1_ec_pubkey_create(
pubkey_ptr, &pubkey_len,
seckey_ptr, 0)
......@@ -98,7 +81,7 @@ func GeneratePubKey(seckey []byte) ([]byte, error) {
var pubkey_ptr *C.uchar = (*C.uchar)(unsafe.Pointer(&pubkey[0]))
var seckey_ptr *C.uchar = (*C.uchar)(unsafe.Pointer(&seckey[0]))
ret := C.secp256k1_ecdsa_pubkey_create(
ret := C.secp256k1_ec_pubkey_create(
pubkey_ptr, &pubkey_len,
seckey_ptr, 0)
......@@ -109,26 +92,6 @@ func GeneratePubKey(seckey []byte) ([]byte, error) {
return pubkey, nil
}
/*
* Create a compact ECDSA signature (64 byte + recovery id).
* Returns: 1: signature created
* 0: nonce invalid, try another one
* In: msg: the message being signed
* msglen: the length of the message being signed
* seckey: pointer to a 32-byte secret key (assumed to be valid)
* nonce: pointer to a 32-byte nonce (generated with a cryptographic PRNG)
* Out: sig: pointer to a 64-byte array where the signature will be placed.
* recid: pointer to an int, which will be updated to contain the recovery id.
*/
/*
int secp256k1_ecdsa_sign_compact(const unsigned char *msg, int msglen,
unsigned char *sig64,
const unsigned char *seckey,
const unsigned char *nonce,
int *recid);
*/
func Sign(msg []byte, seckey []byte) ([]byte, error) {
nonce := randentropy.GetEntropyMixed(32)
......@@ -136,19 +99,22 @@ func Sign(msg []byte, seckey []byte) ([]byte, error) {
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]))
var seckey_ptr *C.uchar = (*C.uchar)(unsafe.Pointer(&seckey[0]))
var noncefp_ptr = &(*C.secp256k1_nonce_function_default)
var ndata_ptr = unsafe.Pointer(&nonce[0])
if C.secp256k1_ecdsa_seckey_verify(seckey_ptr) != C.int(1) {
if C.secp256k1_ec_seckey_verify(seckey_ptr) != C.int(1) {
return nil, errors.New("Invalid secret key")
}
ret := C.secp256k1_ecdsa_sign_compact(
msg_ptr, C.int(len(msg)),
msg_ptr,
sig_ptr,
seckey_ptr,
nonce_ptr,
noncefp_ptr,
ndata_ptr,
&recid)
sig[64] = byte(int(recid))
......@@ -162,37 +128,24 @@ func Sign(msg []byte, seckey []byte) ([]byte, error) {
}
/*
* Verify an ECDSA secret key.
* Returns: 1: secret key is valid
* 0: secret key is invalid
* In: seckey: pointer to a 32-byte secret key
*/
func VerifySeckeyValidity(seckey []byte) error {
if len(seckey) != 32 {
return errors.New("priv key is not 32 bytes")
}
var seckey_ptr *C.uchar = (*C.uchar)(unsafe.Pointer(&seckey[0]))
ret := C.secp256k1_ecdsa_seckey_verify(seckey_ptr)
ret := C.secp256k1_ec_seckey_verify(seckey_ptr)
if int(ret) != 1 {
return errors.New("invalid seckey")
}
return nil
}
/*
* Validate a public key.
* Returns: 1: valid public key
* 0: invalid public key
*/
func VerifyPubkeyValidity(pubkey []byte) error {
if len(pubkey) != 65 {
return errors.New("pub key is not 65 bytes")
}
var pubkey_ptr *C.uchar = (*C.uchar)(unsafe.Pointer(&pubkey[0]))
ret := C.secp256k1_ecdsa_pubkey_verify(pubkey_ptr, 65)
ret := C.secp256k1_ec_pubkey_verify(pubkey_ptr, 65)
if int(ret) != 1 {
return errors.New("invalid pubkey")
}
......@@ -254,25 +207,6 @@ func VerifySignature(msg []byte, sig []byte, pubkey1 []byte) error {
return nil
}
/*
int secp256k1_ecdsa_recover_compact(const unsigned char *msg, int msglen,
const unsigned char *sig64,
unsigned char *pubkey, int *pubkeylen,
int compressed, int recid);
*/
/*
* Recover an ECDSA public key from a compact signature.
* Returns: 1: public key succesfully recovered (which guarantees a correct signature).
* 0: otherwise.
* In: msg: the message assumed to be signed
* msglen: the length of the message
* compressed: whether to recover a compressed or uncompressed pubkey
* recid: the recovery id (as returned by ecdsa_sign_compact)
* Out: pubkey: pointer to a 33 or 65 byte array to put the pubkey.
* pubkeylen: pointer to an int that will contain the pubkey length.
*/
//recovers the public key from the signature
//recovery of pubkey means correct signature
func RecoverPubkey(msg []byte, sig []byte) ([]byte, error) {
......@@ -289,10 +223,12 @@ func RecoverPubkey(msg []byte, sig []byte) ([]byte, error) {
var pubkeylen C.int
ret := C.secp256k1_ecdsa_recover_compact(
msg_ptr, C.int(len(msg)),
msg_ptr,
sig_ptr,
pubkey_ptr, &pubkeylen,
C.int(0), C.int(sig[64]),
pubkey_ptr,
&pubkeylen,
C.int(0),
C.int(sig[64]),
)
if ret == C.int(0) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment