github.com/decred/dcrlnd@v0.7.6/lnwire/signature.go (about)

     1  package lnwire
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  
     7  	"github.com/decred/dcrd/dcrec/secp256k1/v4/ecdsa"
     8  	"github.com/decred/dcrlnd/input"
     9  )
    10  
    11  const minEcdsaSigLen = 8
    12  
    13  // Sig is a fixed-sized ECDSA signature. Unlike Bitcoin, we use fixed sized
    14  // signatures on the wire, instead of DER encoded signatures. This type
    15  // provides several methods to convert to/from a regular Bitcoin DER encoded
    16  // signature (raw bytes and *ecdsa.Signature).
    17  type Sig [64]byte
    18  
    19  var (
    20  	errSigTooShort = errors.New("malformed signature: too short")
    21  	errBadLength   = errors.New("malformed signature: bad length")
    22  	errBadRLength  = errors.New("malformed signature: bogus R length")
    23  	errBadSLength  = errors.New("malformed signature: bogus S length")
    24  	errRTooLong    = errors.New("element R is over 32 bytes long without " +
    25  		"padding")
    26  	errSTooLong = errors.New("element S is over 32 bytes long without " +
    27  		"padding")
    28  )
    29  
    30  // NewSigFromRawSignature returns a Sig from a Bitcoin raw signature encoded in
    31  // the canonical DER encoding.
    32  func NewSigFromRawSignature(sig []byte) (Sig, error) {
    33  	var b Sig
    34  
    35  	// Check the total length is above the minimal.
    36  	if len(sig) < minEcdsaSigLen {
    37  		return b, errSigTooShort
    38  	}
    39  
    40  	// The DER representation is laid out as:
    41  	//   0x30 <length> 0x02 <length r> r 0x02 <length s> s
    42  	// which means the length of R is the 4th byte and the length of S is
    43  	// the second byte after R ends. 0x02 signifies a length-prefixed,
    44  	// zero-padded, big-endian bigint. 0x30 signifies a DER signature.
    45  	// See the Serialize() method for ecdsa.Signature for details.
    46  
    47  	// Reading <length>, remaining: [0x02 <length r> r 0x02 <length s> s]
    48  	sigLen := int(sig[1])
    49  
    50  	// siglen should be less than the entire message and greater than
    51  	// the minimal message size.
    52  	if sigLen+2 > len(sig) || sigLen+2 < minEcdsaSigLen {
    53  		return b, errBadLength
    54  	}
    55  
    56  	// Reading <length r>, remaining: [r 0x02 <length s> s]
    57  	rLen := int(sig[3])
    58  
    59  	// rLen must be positive and must be able to fit in other elements.
    60  	// Assuming s is one byte, then we have 0x30, <length>, 0x20,
    61  	// <length r>, 0x20, <length s>, s, a total of 7 bytes.
    62  	if rLen <= 0 || rLen+7 > len(sig) {
    63  		return b, errBadRLength
    64  	}
    65  
    66  	// Reading <length s>, remaining: [s]
    67  	sLen := int(sig[5+rLen])
    68  
    69  	// S should be the rest of the string.
    70  	// sLen must be positive and must be able to fit in other elements.
    71  	// We know r is rLen bytes, and we have 0x30, <length>, 0x20,
    72  	// <length r>, 0x20, <length s>, a total of rLen+6 bytes.
    73  	if sLen <= 0 || sLen+rLen+6 > len(sig) {
    74  		return b, errBadSLength
    75  	}
    76  
    77  	// Check to make sure R and S can both fit into their intended buffers.
    78  	// We check S first because these code blocks decrement sLen and rLen
    79  	// in the case of a 33-byte 0-padded integer returned from Serialize()
    80  	// and rLen is used in calculating array indices for S. We can track
    81  	// this with additional variables, but it's more efficient to just
    82  	// check S first.
    83  	if sLen > 32 {
    84  		if (sLen > 33) || (sig[6+rLen] != 0x00) {
    85  			return b, errSTooLong
    86  		}
    87  		sLen--
    88  		copy(b[64-sLen:], sig[7+rLen:])
    89  	} else {
    90  		copy(b[64-sLen:], sig[6+rLen:])
    91  	}
    92  
    93  	// Do the same for R as we did for S
    94  	if rLen > 32 {
    95  		if (rLen > 33) || (sig[4] != 0x00) {
    96  			return b, errRTooLong
    97  		}
    98  		rLen--
    99  		copy(b[32-rLen:], sig[5:5+rLen])
   100  	} else {
   101  		copy(b[32-rLen:], sig[4:4+rLen])
   102  	}
   103  
   104  	return b, nil
   105  }
   106  
   107  // NewSigFromSignature creates a new signature as used on the wire, from an
   108  // existing ecdsa.Signature.
   109  func NewSigFromSignature(e input.Signature) (Sig, error) {
   110  	if e == nil {
   111  		return Sig{}, fmt.Errorf("cannot decode empty signature")
   112  	}
   113  
   114  	// Nil is still a valid interface, apparently. So we need a more
   115  	// explicit check here.
   116  	if ecsig, ok := e.(*ecdsa.Signature); ok && ecsig == nil {
   117  		return Sig{}, fmt.Errorf("cannot decode empty signature")
   118  	}
   119  
   120  	// Serialize the signature with all the checks that entails.
   121  	return NewSigFromRawSignature(e.Serialize())
   122  }
   123  
   124  // ToSignature converts the fixed-sized signature to a ecdsa.Signature objects
   125  // which can be used for signature validation checks.
   126  func (b *Sig) ToSignature() (*ecdsa.Signature, error) {
   127  	// Parse the signature with strict checks.
   128  	sigBytes := b.ToSignatureBytes()
   129  	sig, err := ecdsa.ParseDERSignature(sigBytes)
   130  	if err != nil {
   131  		return nil, err
   132  	}
   133  
   134  	return sig, nil
   135  }
   136  
   137  // ToSignatureBytes serializes the target fixed-sized signature into the raw
   138  // bytes of a DER encoding.
   139  func (b *Sig) ToSignatureBytes() []byte {
   140  	// Extract canonically-padded bigint representations from buffer
   141  	r := extractCanonicalPadding(b[0:32])
   142  	s := extractCanonicalPadding(b[32:64])
   143  	rLen := uint8(len(r))
   144  	sLen := uint8(len(s))
   145  
   146  	// Create a canonical serialized signature. DER format is:
   147  	// 0x30 <length> 0x02 <length r> r 0x02 <length s> s
   148  	sigBytes := make([]byte, 6+rLen+sLen)
   149  	sigBytes[0] = 0x30            // DER signature magic value
   150  	sigBytes[1] = 4 + rLen + sLen // Length of rest of signature
   151  	sigBytes[2] = 0x02            // Big integer magic value
   152  	sigBytes[3] = rLen            // Length of R
   153  	sigBytes[rLen+4] = 0x02       // Big integer magic value
   154  	sigBytes[rLen+5] = sLen       // Length of S
   155  	copy(sigBytes[4:], r)         // Copy R
   156  	copy(sigBytes[rLen+6:], s)    // Copy S
   157  
   158  	return sigBytes
   159  }
   160  
   161  // extractCanonicalPadding is a utility function to extract the canonical
   162  // padding of a big-endian integer from the wire encoding (a 0-padded
   163  // big-endian integer) such that it passes secp256k1.canonicalPadding test.
   164  func extractCanonicalPadding(b []byte) []byte {
   165  	for i := 0; i < len(b); i++ {
   166  		// Found first non-zero byte.
   167  		if b[i] > 0 {
   168  			// If the MSB is set, we need zero padding.
   169  			if b[i]&0x80 == 0x80 {
   170  				return append([]byte{0x00}, b[i:]...)
   171  			}
   172  			return b[i:]
   173  		}
   174  	}
   175  	return []byte{0x00}
   176  }