gitlab.com/SiaPrime/SiaPrime@v1.4.1/crypto/signatures_test.go (about) 1 package crypto 2 3 import ( 4 "bytes" 5 "testing" 6 7 "gitlab.com/NebulousLabs/fastrand" 8 "gitlab.com/SiaPrime/SiaPrime/encoding" 9 ) 10 11 // TestUnitSignatureEncoding creates and encodes a public key, and verifies 12 // that it decodes correctly, does the same with a signature. 13 func TestUnitSignatureEncoding(t *testing.T) { 14 // Create a dummy key pair. 15 var sk SecretKey 16 sk[0] = 4 17 sk[32] = 5 18 pk := sk.PublicKey() 19 20 // Marshal and unmarshal the public key. 21 marshalledPK := encoding.Marshal(pk) 22 var unmarshalledPK PublicKey 23 err := encoding.Unmarshal(marshalledPK, &unmarshalledPK) 24 if err != nil { 25 t.Fatal(err) 26 } 27 28 // Test the public keys for equality. 29 if pk != unmarshalledPK { 30 t.Error("pubkey not the same after marshalling and unmarshalling") 31 } 32 33 // Create a signature using the secret key. 34 var signedData Hash 35 fastrand.Read(signedData[:]) 36 sig := SignHash(signedData, sk) 37 38 // Marshal and unmarshal the signature. 39 marshalledSig := encoding.Marshal(sig) 40 var unmarshalledSig Signature 41 err = encoding.Unmarshal(marshalledSig, &unmarshalledSig) 42 if err != nil { 43 t.Fatal(err) 44 } 45 46 // Test signatures for equality. 47 if sig != unmarshalledSig { 48 t.Error("signature not same after marshalling and unmarshalling") 49 } 50 51 } 52 53 // TestUnitSigning creates a bunch of keypairs and signs random data with each of 54 // them. 55 func TestUnitSigning(t *testing.T) { 56 if testing.Short() { 57 t.SkipNow() 58 } 59 60 // Try a bunch of signatures because at one point there was a library that 61 // worked around 98% of the time. Tests would usually pass, but 200 62 // iterations would normally cause a failure. 63 iterations := 200 64 for i := 0; i < iterations; i++ { 65 // Create dummy key pair. 66 sk, pk := GenerateKeyPair() 67 68 // Generate and sign the data. 69 var randData Hash 70 fastrand.Read(randData[:]) 71 sig := SignHash(randData, sk) 72 73 // Verify the signature. 74 err := VerifyHash(randData, pk, sig) 75 if err != nil { 76 t.Fatal(err) 77 } 78 79 // Attempt to verify after the data has been altered. 80 randData[0]++ 81 err = VerifyHash(randData, pk, sig) 82 if err != ErrInvalidSignature { 83 t.Fatal(err) 84 } 85 86 // Restore the data and make sure the signature is valid again. 87 randData[0]-- 88 err = VerifyHash(randData, pk, sig) 89 if err != nil { 90 t.Fatal(err) 91 } 92 93 // Attempt to verify after the signature has been altered. 94 sig[0]++ 95 err = VerifyHash(randData, pk, sig) 96 if err != ErrInvalidSignature { 97 t.Fatal(err) 98 } 99 } 100 } 101 102 // TestIntegrationSigKeyGenerate is an integration test checking that 103 // GenerateKeyPair and GenerateKeyPairDeterminisitc accurately create keys. 104 func TestIntegrationSigKeyGeneration(t *testing.T) { 105 if testing.Short() { 106 t.SkipNow() 107 } 108 message := HashBytes([]byte{'m', 's', 'g'}) 109 110 // Create a random key and use it. 111 randSecKey, randPubKey := GenerateKeyPair() 112 sig := SignHash(message, randSecKey) 113 err := VerifyHash(message, randPubKey, sig) 114 if err != nil { 115 t.Error(err) 116 } 117 // Corrupt the signature 118 sig[0]++ 119 err = VerifyHash(message, randPubKey, sig) 120 if err == nil { 121 t.Error("corruption failed") 122 } 123 124 // Create a deterministic key and use it. 125 var detEntropy [EntropySize]byte 126 detEntropy[0] = 35 127 detSecKey, detPubKey := GenerateKeyPairDeterministic(detEntropy) 128 sig = SignHash(message, detSecKey) 129 err = VerifyHash(message, detPubKey, sig) 130 if err != nil { 131 t.Error(err) 132 } 133 // Corrupt the signature 134 sig[0]++ 135 err = VerifyHash(message, detPubKey, sig) 136 if err == nil { 137 t.Error("corruption failed") 138 } 139 } 140 141 // TestReadWriteSignedObject tests the ReadSignObject and WriteSignedObject 142 // functions, which are inverses of each other. 143 func TestReadWriteSignedObject(t *testing.T) { 144 sk, pk := GenerateKeyPair() 145 146 // Write signed object into buffer. 147 b := new(bytes.Buffer) 148 err := WriteSignedObject(b, "foo", sk) 149 if err != nil { 150 t.Fatal(err) 151 } 152 // Keep a copy of b's bytes. 153 buf := b.Bytes() 154 155 // Read and verify object. 156 var read string 157 err = ReadSignedObject(b, &read, 11, pk) 158 if err != nil { 159 t.Fatal(err) 160 } 161 if read != "foo" { 162 t.Fatal("encode/decode mismatch: expected 'foo', got", []byte(read)) 163 } 164 165 // Check that maxlen is being respected. 166 b = bytes.NewBuffer(buf) // reset b 167 err = ReadSignedObject(b, &read, 10, pk) 168 if err == nil || err.Error() != "length 11 exceeds maxLen of 10" { 169 t.Fatal("expected length error, got", err) 170 } 171 172 // Disrupt the decoding to get coverage on the failure branch. 173 err = ReadSignedObject(b, &read, 11, pk) 174 if err == nil || err.Error() != "could not decode type crypto.Signature: unexpected EOF" { 175 t.Fatal(err) 176 } 177 178 // Try with an invalid signature. 179 buf[0]++ // alter the first byte of the signature, invalidating it. 180 b = bytes.NewBuffer(buf) // reset b 181 err = ReadSignedObject(b, &read, 11, pk) 182 if err != ErrInvalidSignature { 183 t.Fatal(err) 184 } 185 } 186 187 // TestUnitPublicKey tests the PublicKey method 188 func TestUnitPublicKey(t *testing.T) { 189 for i := 0; i < 1000; i++ { 190 sk, pk := GenerateKeyPair() 191 if sk.PublicKey() != pk { 192 t.Error("PublicKey does not match actual public key:", pk, sk.PublicKey()) 193 } 194 } 195 }