github.com/decred/dcrlnd@v0.7.6/channeldb/migration/lnwire21/signature.go (about)

     1  package lnwire
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/decred/dcrd/dcrec/secp256k1/v4/ecdsa"
     7  	"github.com/decred/dcrlnd/input"
     8  )
     9  
    10  // Sig is a fixed-sized ECDSA signature. Unlike Bitcoin, we use fixed sized
    11  // signatures on the wire, instead of DER encoded signatures. This type
    12  // provides several methods to convert to/from a regular Bitcoin DER encoded
    13  // signature (raw bytes and *ecdsa.Signature).
    14  type Sig [64]byte
    15  
    16  // NewSigFromRawSignature returns a Sig from a Bitcoin raw signature encoded in
    17  // the canonical DER encoding.
    18  func NewSigFromRawSignature(sig []byte) (Sig, error) {
    19  	var b Sig
    20  
    21  	if len(sig) == 0 {
    22  		return b, fmt.Errorf("cannot decode empty signature")
    23  	}
    24  
    25  	// Extract lengths of R and S. The DER representation is laid out as
    26  	// 0x30 <length> 0x02 <length r> r 0x02 <length s> s
    27  	// which means the length of R is the 4th byte and the length of S
    28  	// is the second byte after R ends. 0x02 signifies a length-prefixed,
    29  	// zero-padded, big-endian bigint. 0x30 signifies a DER signature.  See
    30  	// the Serialize() method for ecdsa.Signature for details.
    31  	rLen := sig[3]
    32  	sLen := sig[5+rLen]
    33  
    34  	// Check to make sure R and S can both fit into their intended buffers.
    35  	// We check S first because these code blocks decrement sLen and rLen
    36  	// in the case of a 33-byte 0-padded integer returned from Serialize()
    37  	// and rLen is used in calculating array indices for S. We can track
    38  	// this with additional variables, but it's more efficient to just
    39  	// check S first.
    40  	if sLen > 32 {
    41  		if (sLen > 33) || (sig[6+rLen] != 0x00) {
    42  			return b, fmt.Errorf("S is over 32 bytes long " +
    43  				"without padding")
    44  		}
    45  		sLen--
    46  		copy(b[64-sLen:], sig[7+rLen:])
    47  	} else {
    48  		copy(b[64-sLen:], sig[6+rLen:])
    49  	}
    50  
    51  	// Do the same for R as we did for S
    52  	if rLen > 32 {
    53  		if (rLen > 33) || (sig[4] != 0x00) {
    54  			return b, fmt.Errorf("R is over 32 bytes long " +
    55  				"without padding")
    56  		}
    57  		rLen--
    58  		copy(b[32-rLen:], sig[5:5+rLen])
    59  	} else {
    60  		copy(b[32-rLen:], sig[4:4+rLen])
    61  	}
    62  
    63  	return b, nil
    64  }
    65  
    66  // NewSigFromSignature creates a new signature as used on the wire, from an
    67  // existing ecdsa.Signature.
    68  func NewSigFromSignature(e input.Signature) (Sig, error) {
    69  	if e == nil {
    70  		return Sig{}, fmt.Errorf("cannot decode empty signature")
    71  	}
    72  
    73  	// Serialize the signature with all the checks that entails.
    74  	return NewSigFromRawSignature(e.Serialize())
    75  }
    76  
    77  // ToSignature converts the fixed-sized signature to a ecdsa.Signature objects
    78  // which can be used for signature validation checks.
    79  func (b *Sig) ToSignature() (*ecdsa.Signature, error) {
    80  	// Parse the signature with strict checks.
    81  	sigBytes := b.ToSignatureBytes()
    82  	sig, err := ecdsa.ParseDERSignature(sigBytes)
    83  	if err != nil {
    84  		return nil, err
    85  	}
    86  
    87  	return sig, nil
    88  }
    89  
    90  // ToSignatureBytes serializes the target fixed-sized signature into the raw
    91  // bytes of a DER encoding.
    92  func (b *Sig) ToSignatureBytes() []byte {
    93  	// Extract canonically-padded bigint representations from buffer
    94  	r := extractCanonicalPadding(b[0:32])
    95  	s := extractCanonicalPadding(b[32:64])
    96  	rLen := uint8(len(r))
    97  	sLen := uint8(len(s))
    98  
    99  	// Create a canonical serialized signature. DER format is:
   100  	// 0x30 <length> 0x02 <length r> r 0x02 <length s> s
   101  	sigBytes := make([]byte, 6+rLen+sLen)
   102  	sigBytes[0] = 0x30            // DER signature magic value
   103  	sigBytes[1] = 4 + rLen + sLen // Length of rest of signature
   104  	sigBytes[2] = 0x02            // Big integer magic value
   105  	sigBytes[3] = rLen            // Length of R
   106  	sigBytes[rLen+4] = 0x02       // Big integer magic value
   107  	sigBytes[rLen+5] = sLen       // Length of S
   108  	copy(sigBytes[4:], r)         // Copy R
   109  	copy(sigBytes[rLen+6:], s)    // Copy S
   110  
   111  	return sigBytes
   112  }
   113  
   114  // extractCanonicalPadding is a utility function to extract the canonical
   115  // padding of a big-endian integer from the wire encoding (a 0-padded
   116  // big-endian integer) such that it passes secp256k1.canonicalPadding test.
   117  func extractCanonicalPadding(b []byte) []byte {
   118  	for i := 0; i < len(b); i++ {
   119  		// Found first non-zero byte.
   120  		if b[i] > 0 {
   121  			// If the MSB is set, we need zero padding.
   122  			if b[i]&0x80 == 0x80 {
   123  				return append([]byte{0x00}, b[i:]...)
   124  			}
   125  			return b[i:]
   126  		}
   127  	}
   128  	return []byte{0x00}
   129  }