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 }