package lnwire import ( "fmt" "math/big" "testing" "github.com/roasbeef/btcd/btcec" ) func TestSignatureSerializeDeserialize(t *testing.T) { t.Parallel() // Local-scoped closure to serialize and deserialize a Signature and // check for errors as well as check if the results are correct. signatureSerializeDeserialize := func(e btcec.Signature) error { var b [64]byte err := serializeSigToWire(&b, &e) if err != nil { return err } var e2 *btcec.Signature err = deserializeSigFromWire(&e2, b) if err != nil { return err } if e.R.Cmp(e2.R) != 0 { return fmt.Errorf("Pre/post-serialize Rs don't match"+ ": %s, %s", e.R, e2.R) } if e.S.Cmp(e2.S) != 0 { return fmt.Errorf("Pre/post-serialize Ss don't match"+ ": %s, %s", e.S, e2.S) } return nil } sig := btcec.Signature{} // Check R = N-1, S = 128. sig.R = big.NewInt(1) // Allocate a big.Int before we call .Sub. sig.R.Sub(btcec.S256().N, sig.R) sig.S = big.NewInt(128) err := signatureSerializeDeserialize(sig) if err != nil { t.Fatalf("R = N-1, S = 128: %s", err.Error()) } // Check R = N-1, S = 127. sig.S = big.NewInt(127) err = signatureSerializeDeserialize(sig) if err != nil { t.Fatalf("R = N-1, S = 127: %s", err.Error()) } // Check R = N-1, S = N>>1. sig.S.Set(btcec.S256().N) sig.S.Rsh(sig.S, 1) err = signatureSerializeDeserialize(sig) if err != nil { t.Fatalf("R = N-1, S = N>>1: %s", err.Error()) } // Check R = N-1, S = N. sig.S.Set(btcec.S256().N) err = signatureSerializeDeserialize(sig) if err.Error() != "signature S isn't 1 or more" { t.Fatalf("R = N-1, S = N should become R = N-1, S = 0: %s", err.Error()) } // Check R = N-1, S = N-1. sig.S.Sub(sig.S, big.NewInt(1)) err = signatureSerializeDeserialize(sig) if err.Error() != "Pre/post-serialize Ss don't match: 115792089237316"+ "195423570985008687907852837564279074904382605163141518161494"+ "336, 1" { t.Fatalf("R = N-1, S = N-1 should become R = N-1, S = 1: %s", err.Error()) } // Check R = 2N, S = 128 sig.R.Mul(btcec.S256().N, big.NewInt(2)) sig.S.Set(big.NewInt(127)) err = signatureSerializeDeserialize(sig) if err.Error() != "R is over 32 bytes long without padding" { t.Fatalf("R = 2N, S = 128, R should be over 32 bytes: %s", err.Error()) } }