github.com/decred/dcrlnd@v0.7.6/lnwire/signature_test.go (about) 1 package lnwire 2 3 import ( 4 "math/big" 5 "testing" 6 7 secpv2 "github.com/decred/dcrd/dcrec/secp256k1/v2" 8 "github.com/decred/dcrd/dcrec/secp256k1/v4" 9 "github.com/stretchr/testify/require" 10 ) 11 12 func TestSignatureSerializeDeserialize(t *testing.T) { 13 t.Parallel() 14 15 // Local-scoped closure to serialize and deserialize a Signature and 16 // check for errors as well as check if the results are correct. 17 signatureSerializeDeserialize := func(e secpv2.Signature) error { 18 // NOTE(decred): Instead of using NewSigFromSignature we use 19 // NewSigFromRawSignature due to performing the test with the 20 // v2 secp256k1 lib that allows internal access to R and S and 21 // allows creating invalid encoded sigs. 22 sig, err := NewSigFromRawSignature(e.Serialize()) 23 if err != nil { 24 return err 25 } 26 27 _, err = sig.ToSignature() 28 if err != nil { 29 return err 30 } 31 32 // NOTE(decred) These are commented because the secp256k1/v4 33 // doesn't provide access to the internal R and S. 34 /* 35 if e.R.Cmp(e2.R) != 0 { 36 return fmt.Errorf("Pre/post-serialize Rs don't match"+ 37 ": %s, %s", e.R, e2.R) 38 } 39 if e.S.Cmp(e2.S) != 0 { 40 return fmt.Errorf("Pre/post-serialize Ss don't match"+ 41 ": %s, %s", e.S, e2.S) 42 } 43 */ 44 return nil 45 } 46 47 sig := secpv2.Signature{} 48 49 // Check R = N-1, S = 128. 50 sig.R = big.NewInt(1) // Allocate a big.Int before we call .Sub. 51 sig.R.Sub(secp256k1.S256().N, sig.R) 52 sig.S = big.NewInt(128) 53 err := signatureSerializeDeserialize(sig) 54 if err != nil { 55 t.Fatalf("R = N-1, S = 128: %s", err.Error()) 56 } 57 58 // Check R = N-1, S = 127. 59 sig.S = big.NewInt(127) 60 err = signatureSerializeDeserialize(sig) 61 if err != nil { 62 t.Fatalf("R = N-1, S = 127: %s", err.Error()) 63 } 64 65 // Check R = N-1, S = N>>1. 66 sig.S.Set(secp256k1.S256().N) 67 sig.S.Rsh(sig.S, 1) 68 err = signatureSerializeDeserialize(sig) 69 if err != nil { 70 t.Fatalf("R = N-1, S = N>>1: %s", err.Error()) 71 } 72 73 // Check R = N-1, S = N. 74 sig.S.Set(secp256k1.S256().N) 75 err = signatureSerializeDeserialize(sig) 76 if err.Error() != "invalid signature: S is 0" { 77 t.Fatalf("R = N-1, S = N should become R = N-1, S = 0: %s", 78 err.Error()) 79 } 80 81 // Check R = N-1, S = N-1. 82 sig.S.Sub(sig.S, big.NewInt(1)) 83 // NOTE(decred): this is commented because secp256k1/v4 doesn't provide 84 // access to R and S for the comparison to be performed. 85 /* 86 err = signatureSerializeDeserialize(sig) 87 if err.Error() != "Pre/post-serialize Ss don't match: 115792089237316"+ 88 "195423570985008687907852837564279074904382605163141518161494"+ 89 "336, 1" { 90 t.Fatalf("R = N-1, S = N-1 should become R = N-1, S = 1: %s", 91 err.Error()) 92 } 93 */ 94 95 // Check R = 2N, S = 128 96 sig.R.Mul(secp256k1.S256().N, big.NewInt(2)) 97 sig.S.Set(big.NewInt(127)) 98 err = signatureSerializeDeserialize(sig) 99 if err.Error() != "element R is over 32 bytes long without padding" { 100 t.Fatalf("R = 2N, S = 128, R should be over 32 bytes: %s", 101 err.Error()) 102 } 103 } 104 105 var ( 106 // signatures from bitcoin blockchain tx 107 // 0437cd7f8525ceed2324359c2d0ba26006d92d85. 108 normalSig = []byte{ 109 0x30, 0x44, 0x02, 0x20, 110 // r value 111 0x4e, 0x45, 0xe1, 0x69, 0x32, 0xb8, 0xaf, 0x51, 112 0x49, 0x61, 0xa1, 0xd3, 0xa1, 0xa2, 0x5f, 0xdf, 113 0x3f, 0x4f, 0x77, 0x32, 0xe9, 0xd6, 0x24, 0xc6, 114 0xc6, 0x15, 0x48, 0xab, 0x5f, 0xb8, 0xcd, 0x41, 115 116 0x02, 0x20, 117 // s value 118 0x18, 0x15, 0x22, 0xec, 0x8e, 0xca, 0x07, 0xde, 119 0x48, 0x60, 0xa4, 0xac, 0xdd, 0x12, 0x90, 0x9d, 120 0x83, 0x1c, 0xc5, 0x6c, 0xbb, 0xac, 0x46, 0x22, 121 0x08, 0x22, 0x21, 0xa8, 0x76, 0x8d, 0x1d, 0x09, 122 } 123 124 // minimal length with 1 byte r and 1 byte s. 125 minSig = []byte{ 126 0x30, 0x06, 0x02, 0x01, 0x00, 0x02, 0x01, 0x00, 127 } 128 129 // sig length is below 6. 130 smallLenSig = []byte{ 131 0x30, 0x05, 0x02, 0x01, 0x00, 0x02, 0x01, 0x00, 132 } 133 134 // sig length is above 6. 135 largeLenSig = []byte{ 136 0x30, 0x07, 0x02, 0x01, 0x00, 0x02, 0x01, 0x00, 137 } 138 139 // r length is 2. 140 largeRSig = []byte{ 141 0x30, 0x06, 0x02, 0x02, 0x00, 0x02, 0x01, 0x00, 142 } 143 144 // r length is 0. 145 smallRSig = []byte{ 146 0x30, 0x06, 0x02, 0x00, 0x00, 0x02, 0x01, 0x00, 147 } 148 149 // s length is 2. 150 largeSSig = []byte{ 151 0x30, 0x06, 0x02, 0x01, 0x00, 0x02, 0x02, 0x00, 152 } 153 154 // s length is 0. 155 smallSSig = []byte{ 156 0x30, 0x06, 0x02, 0x01, 0x00, 0x02, 0x00, 0x00, 157 } 158 159 // r length is 33. 160 missPaddingRSig = []byte{ 161 0x30, 0x25, 0x02, 0x21, 162 // r value with a wrong padding. 163 0xff, 164 0x4e, 0x45, 0xe1, 0x69, 0x32, 0xb8, 0xaf, 0x51, 165 0x49, 0x61, 0xa1, 0xd3, 0xa1, 0xa2, 0x5f, 0xdf, 166 0x3f, 0x4f, 0x77, 0x32, 0xe9, 0xd6, 0x24, 0xc6, 167 0xc6, 0x15, 0x48, 0xab, 0x5f, 0xb8, 0xcd, 0x41, 168 // s value is 0. 169 0x02, 0x01, 0x00, 170 } 171 172 // s length is 33. 173 missPaddingSSig = []byte{ 174 // r value is 0. 175 0x30, 0x25, 0x02, 0x01, 0x00, 176 0x02, 0x21, 177 // s value with a wrong padding. 178 0xff, 179 0x18, 0x15, 0x22, 0xec, 0x8e, 0xca, 0x07, 0xde, 180 0x48, 0x60, 0xa4, 0xac, 0xdd, 0x12, 0x90, 0x9d, 181 0x83, 0x1c, 0xc5, 0x6c, 0xbb, 0xac, 0x46, 0x22, 182 0x08, 0x22, 0x21, 0xa8, 0x76, 0x8d, 0x1d, 0x09, 183 } 184 ) 185 186 func TestNewSigFromRawSignature(t *testing.T) { 187 t.Parallel() 188 testCases := []struct { 189 name string 190 rawSig []byte 191 expectedErr error 192 expectedSig Sig 193 }{ 194 { 195 name: "valid signature", 196 rawSig: normalSig, 197 expectedErr: nil, 198 expectedSig: Sig{ 199 // r value 200 0x4e, 0x45, 0xe1, 0x69, 0x32, 0xb8, 0xaf, 0x51, 201 0x49, 0x61, 0xa1, 0xd3, 0xa1, 0xa2, 0x5f, 0xdf, 202 0x3f, 0x4f, 0x77, 0x32, 0xe9, 0xd6, 0x24, 0xc6, 203 0xc6, 0x15, 0x48, 0xab, 0x5f, 0xb8, 0xcd, 0x41, 204 // s value 205 0x18, 0x15, 0x22, 0xec, 0x8e, 0xca, 0x07, 0xde, 206 0x48, 0x60, 0xa4, 0xac, 0xdd, 0x12, 0x90, 0x9d, 207 0x83, 0x1c, 0xc5, 0x6c, 0xbb, 0xac, 0x46, 0x22, 208 0x08, 0x22, 0x21, 0xa8, 0x76, 0x8d, 0x1d, 0x09, 209 }, 210 }, 211 { 212 name: "minimal length signature", 213 rawSig: minSig, 214 expectedErr: nil, 215 // NOTE: r and s are both 0x00 here. 216 expectedSig: Sig{}, 217 }, 218 { 219 name: "signature length too short", 220 rawSig: []byte{0x30}, 221 expectedErr: errSigTooShort, 222 expectedSig: Sig{}, 223 }, 224 { 225 name: "sig length too large", 226 rawSig: largeLenSig, 227 expectedErr: errBadLength, 228 expectedSig: Sig{}, 229 }, 230 { 231 name: "sig length too small", 232 rawSig: smallLenSig, 233 expectedErr: errBadLength, 234 expectedSig: Sig{}, 235 }, 236 { 237 name: "r length too large", 238 rawSig: largeRSig, 239 expectedErr: errBadRLength, 240 expectedSig: Sig{}, 241 }, 242 { 243 name: "r length too small", 244 rawSig: smallRSig, 245 expectedErr: errBadRLength, 246 expectedSig: Sig{}, 247 }, 248 { 249 name: "s length too large", 250 rawSig: largeSSig, 251 expectedErr: errBadSLength, 252 expectedSig: Sig{}, 253 }, 254 { 255 name: "s length too small", 256 rawSig: smallSSig, 257 expectedErr: errBadSLength, 258 expectedSig: Sig{}, 259 }, 260 { 261 name: "missing padding in r", 262 rawSig: missPaddingRSig, 263 expectedErr: errRTooLong, 264 expectedSig: Sig{}, 265 }, 266 { 267 name: "missing padding in s", 268 rawSig: missPaddingSSig, 269 expectedErr: errSTooLong, 270 expectedSig: Sig{}, 271 }, 272 } 273 274 for _, tc := range testCases { 275 tc := tc 276 t.Run(tc.name, func(t *testing.T) { 277 result, err := NewSigFromRawSignature(tc.rawSig) 278 require.Equal(t, tc.expectedErr, err) 279 require.Equal(t, tc.expectedSig, result) 280 }) 281 } 282 }