From 92853e018365c37d532d2c55e26661fafa1e0545 Mon Sep 17 00:00:00 2001 From: Vadim Macagon Date: Fri, 25 Jan 2019 23:51:56 +0700 Subject: [PATCH] Implement NormalizeLaxDERSignature in secp256k1 package NormalizeLaxDERSignature normalizes a Lax DER encoded signature to a "low S" form. See normalize_s in https://github.com/rust-bitcoin/rust-secp256k1 for an explanation. --- .../libsecp256k1/contrib/lax_der_parsing.c | 2 +- .../libsecp256k1/contrib/lax_der_parsing.h | 2 +- crypto/secp256k1/secp256.go | 22 +++++++++++++++++++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/crypto/secp256k1/libsecp256k1/contrib/lax_der_parsing.c b/crypto/secp256k1/libsecp256k1/contrib/lax_der_parsing.c index 5b141a9948..ede8019249 100644 --- a/crypto/secp256k1/libsecp256k1/contrib/lax_der_parsing.c +++ b/crypto/secp256k1/libsecp256k1/contrib/lax_der_parsing.c @@ -5,7 +5,7 @@ **********************************************************************/ #include -#include +#include "include/secp256k1.h" #include "lax_der_parsing.h" diff --git a/crypto/secp256k1/libsecp256k1/contrib/lax_der_parsing.h b/crypto/secp256k1/libsecp256k1/contrib/lax_der_parsing.h index 6d27871a7c..a049f0395e 100644 --- a/crypto/secp256k1/libsecp256k1/contrib/lax_der_parsing.h +++ b/crypto/secp256k1/libsecp256k1/contrib/lax_der_parsing.h @@ -51,7 +51,7 @@ #ifndef _SECP256K1_CONTRIB_LAX_DER_PARSING_H_ #define _SECP256K1_CONTRIB_LAX_DER_PARSING_H_ -#include +#include "include/secp256k1.h" # ifdef __cplusplus extern "C" { diff --git a/crypto/secp256k1/secp256.go b/crypto/secp256k1/secp256.go index 35d0eef34a..ca38cfd9f9 100644 --- a/crypto/secp256k1/secp256.go +++ b/crypto/secp256k1/secp256.go @@ -17,6 +17,7 @@ package secp256k1 #include "./libsecp256k1/src/secp256k1.c" #include "./libsecp256k1/src/modules/recovery/main_impl.h" #include "ext.h" +#include "./libsecp256k1/contrib/lax_der_parsing.c" typedef void (*callbackFunc) (const char* msg, void* data); extern void secp256k1GoPanicIllegal(const char* msg, void* data); @@ -47,6 +48,7 @@ var ( ErrInvalidPubkey = errors.New("invalid public key") ErrSignFailed = errors.New("signing failed") ErrRecoverFailed = errors.New("recovery failed") + ErrInvalidSigEncoding = errors.New("invalid signature encoding") ) // Sign creates a recoverable ECDSA signature. @@ -165,3 +167,23 @@ func checkSignature(sig []byte) error { } return nil } + +// NormalizeLaxDERSignature normalizes a Lax DER encoded signature to a "low S" form. +// See normalize_s in https://github.com/rust-bitcoin/rust-secp256k1 for an explanation. +func NormalizeLaxDERSignature(sig []byte) ([]byte, error) { + var signature C.secp256k1_ecdsa_signature + in := (*C.uchar)(unsafe.Pointer(&sig[0])) + inLen := C.size_t(len(sig)) + + if C.ecdsa_signature_parse_der_lax(context, &signature, in, inLen) == 0 { + return nil, ErrInvalidSigEncoding + } + + var normalizedSig C.secp256k1_ecdsa_signature + C.secp256k1_ecdsa_signature_normalize(context, &normalizedSig, &signature) + + out := make([]byte, 64) + outPtr := (*C.uchar)(unsafe.Pointer(&out[0])) + C.secp256k1_ecdsa_signature_serialize_compact(context, outPtr, &normalizedSig) + return out, nil +}