github.com/gobitfly/go-ethereum@v1.8.12/whisper/whisperv6/message_test.go (about) 1 // Copyright 2016 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package whisperv6 18 19 import ( 20 "bytes" 21 "crypto/aes" 22 "crypto/cipher" 23 mrand "math/rand" 24 "testing" 25 26 "github.com/ethereum/go-ethereum/common/hexutil" 27 "github.com/ethereum/go-ethereum/crypto" 28 "github.com/ethereum/go-ethereum/rlp" 29 ) 30 31 func generateMessageParams() (*MessageParams, error) { 32 // set all the parameters except p.Dst and p.Padding 33 34 buf := make([]byte, 4) 35 mrand.Read(buf) 36 sz := mrand.Intn(400) 37 38 var p MessageParams 39 p.PoW = 0.01 40 p.WorkTime = 1 41 p.TTL = uint32(mrand.Intn(1024)) 42 p.Payload = make([]byte, sz) 43 p.KeySym = make([]byte, aesKeyLength) 44 mrand.Read(p.Payload) 45 mrand.Read(p.KeySym) 46 p.Topic = BytesToTopic(buf) 47 48 var err error 49 p.Src, err = crypto.GenerateKey() 50 if err != nil { 51 return nil, err 52 } 53 54 return &p, nil 55 } 56 57 func singleMessageTest(t *testing.T, symmetric bool) { 58 params, err := generateMessageParams() 59 if err != nil { 60 t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) 61 } 62 63 key, err := crypto.GenerateKey() 64 if err != nil { 65 t.Fatalf("failed GenerateKey with seed %d: %s.", seed, err) 66 } 67 68 if !symmetric { 69 params.KeySym = nil 70 params.Dst = &key.PublicKey 71 } 72 73 text := make([]byte, 0, 512) 74 text = append(text, params.Payload...) 75 76 msg, err := NewSentMessage(params) 77 if err != nil { 78 t.Fatalf("failed to create new message with seed %d: %s.", seed, err) 79 } 80 env, err := msg.Wrap(params) 81 if err != nil { 82 t.Fatalf("failed Wrap with seed %d: %s.", seed, err) 83 } 84 85 var decrypted *ReceivedMessage 86 if symmetric { 87 decrypted, err = env.OpenSymmetric(params.KeySym) 88 } else { 89 decrypted, err = env.OpenAsymmetric(key) 90 } 91 92 if err != nil { 93 t.Fatalf("failed to encrypt with seed %d: %s.", seed, err) 94 } 95 96 if !decrypted.ValidateAndParse() { 97 t.Fatalf("failed to validate with seed %d, symmetric = %v.", seed, symmetric) 98 } 99 100 if !bytes.Equal(text, decrypted.Payload) { 101 t.Fatalf("failed with seed %d: compare payload.", seed) 102 } 103 if !isMessageSigned(decrypted.Raw[0]) { 104 t.Fatalf("failed with seed %d: unsigned.", seed) 105 } 106 if len(decrypted.Signature) != signatureLength { 107 t.Fatalf("failed with seed %d: signature len %d.", seed, len(decrypted.Signature)) 108 } 109 if !IsPubKeyEqual(decrypted.Src, ¶ms.Src.PublicKey) { 110 t.Fatalf("failed with seed %d: signature mismatch.", seed) 111 } 112 } 113 114 func TestMessageEncryption(t *testing.T) { 115 InitSingleTest() 116 117 var symmetric bool 118 for i := 0; i < 256; i++ { 119 singleMessageTest(t, symmetric) 120 symmetric = !symmetric 121 } 122 } 123 124 func TestMessageWrap(t *testing.T) { 125 seed = int64(1777444222) 126 mrand.Seed(seed) 127 target := 128.0 128 129 params, err := generateMessageParams() 130 if err != nil { 131 t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) 132 } 133 134 msg, err := NewSentMessage(params) 135 if err != nil { 136 t.Fatalf("failed to create new message with seed %d: %s.", seed, err) 137 } 138 params.TTL = 1 139 params.WorkTime = 12 140 params.PoW = target 141 env, err := msg.Wrap(params) 142 if err != nil { 143 t.Fatalf("failed Wrap with seed %d: %s.", seed, err) 144 } 145 146 pow := env.PoW() 147 if pow < target { 148 t.Fatalf("failed Wrap with seed %d: pow < target (%f vs. %f).", seed, pow, target) 149 } 150 151 // set PoW target too high, expect error 152 msg2, err := NewSentMessage(params) 153 if err != nil { 154 t.Fatalf("failed to create new message with seed %d: %s.", seed, err) 155 } 156 params.TTL = 1000000 157 params.WorkTime = 1 158 params.PoW = 10000000.0 159 _, err = msg2.Wrap(params) 160 if err == nil { 161 t.Fatalf("unexpectedly reached the PoW target with seed %d.", seed) 162 } 163 } 164 165 func TestMessageSeal(t *testing.T) { 166 // this test depends on deterministic choice of seed (1976726903) 167 seed = int64(1976726903) 168 mrand.Seed(seed) 169 170 params, err := generateMessageParams() 171 if err != nil { 172 t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) 173 } 174 175 msg, err := NewSentMessage(params) 176 if err != nil { 177 t.Fatalf("failed to create new message with seed %d: %s.", seed, err) 178 } 179 params.TTL = 1 180 181 env := NewEnvelope(params.TTL, params.Topic, msg) 182 if err != nil { 183 t.Fatalf("failed Wrap with seed %d: %s.", seed, err) 184 } 185 186 env.Expiry = uint32(seed) // make it deterministic 187 target := 32.0 188 params.WorkTime = 4 189 params.PoW = target 190 env.Seal(params) 191 192 env.calculatePoW(0) 193 pow := env.PoW() 194 if pow < target { 195 t.Fatalf("failed Wrap with seed %d: pow < target (%f vs. %f).", seed, pow, target) 196 } 197 198 params.WorkTime = 1 199 params.PoW = 1000000000.0 200 env.Seal(params) 201 env.calculatePoW(0) 202 pow = env.PoW() 203 if pow < 2*target { 204 t.Fatalf("failed Wrap with seed %d: pow too small %f.", seed, pow) 205 } 206 } 207 208 func TestEnvelopeOpen(t *testing.T) { 209 InitSingleTest() 210 211 var symmetric bool 212 for i := 0; i < 32; i++ { 213 singleEnvelopeOpenTest(t, symmetric) 214 symmetric = !symmetric 215 } 216 } 217 218 func singleEnvelopeOpenTest(t *testing.T, symmetric bool) { 219 params, err := generateMessageParams() 220 if err != nil { 221 t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) 222 } 223 224 key, err := crypto.GenerateKey() 225 if err != nil { 226 t.Fatalf("failed GenerateKey with seed %d: %s.", seed, err) 227 } 228 229 if !symmetric { 230 params.KeySym = nil 231 params.Dst = &key.PublicKey 232 } 233 234 text := make([]byte, 0, 512) 235 text = append(text, params.Payload...) 236 237 msg, err := NewSentMessage(params) 238 if err != nil { 239 t.Fatalf("failed to create new message with seed %d: %s.", seed, err) 240 } 241 env, err := msg.Wrap(params) 242 if err != nil { 243 t.Fatalf("failed Wrap with seed %d: %s.", seed, err) 244 } 245 246 var f Filter 247 if symmetric { 248 f = Filter{KeySym: params.KeySym} 249 } else { 250 f = Filter{KeyAsym: key} 251 } 252 decrypted := env.Open(&f) 253 if decrypted == nil { 254 t.Fatalf("failed to open with seed %d.", seed) 255 } 256 257 if !bytes.Equal(text, decrypted.Payload) { 258 t.Fatalf("failed with seed %d: compare payload.", seed) 259 } 260 if !isMessageSigned(decrypted.Raw[0]) { 261 t.Fatalf("failed with seed %d: unsigned.", seed) 262 } 263 if len(decrypted.Signature) != signatureLength { 264 t.Fatalf("failed with seed %d: signature len %d.", seed, len(decrypted.Signature)) 265 } 266 if !IsPubKeyEqual(decrypted.Src, ¶ms.Src.PublicKey) { 267 t.Fatalf("failed with seed %d: signature mismatch.", seed) 268 } 269 if decrypted.isAsymmetricEncryption() == symmetric { 270 t.Fatalf("failed with seed %d: asymmetric %v vs. %v.", seed, decrypted.isAsymmetricEncryption(), symmetric) 271 } 272 if decrypted.isSymmetricEncryption() != symmetric { 273 t.Fatalf("failed with seed %d: symmetric %v vs. %v.", seed, decrypted.isSymmetricEncryption(), symmetric) 274 } 275 if !symmetric { 276 if decrypted.Dst == nil { 277 t.Fatalf("failed with seed %d: dst is nil.", seed) 278 } 279 if !IsPubKeyEqual(decrypted.Dst, &key.PublicKey) { 280 t.Fatalf("failed with seed %d: Dst.", seed) 281 } 282 } 283 } 284 285 func TestEncryptWithZeroKey(t *testing.T) { 286 InitSingleTest() 287 288 params, err := generateMessageParams() 289 if err != nil { 290 t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) 291 } 292 msg, err := NewSentMessage(params) 293 if err != nil { 294 t.Fatalf("failed to create new message with seed %d: %s.", seed, err) 295 } 296 params.KeySym = make([]byte, aesKeyLength) 297 _, err = msg.Wrap(params) 298 if err == nil { 299 t.Fatalf("wrapped with zero key, seed: %d.", seed) 300 } 301 302 params, err = generateMessageParams() 303 if err != nil { 304 t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) 305 } 306 msg, err = NewSentMessage(params) 307 if err != nil { 308 t.Fatalf("failed to create new message with seed %d: %s.", seed, err) 309 } 310 params.KeySym = make([]byte, 0) 311 _, err = msg.Wrap(params) 312 if err == nil { 313 t.Fatalf("wrapped with empty key, seed: %d.", seed) 314 } 315 316 params, err = generateMessageParams() 317 if err != nil { 318 t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) 319 } 320 msg, err = NewSentMessage(params) 321 if err != nil { 322 t.Fatalf("failed to create new message with seed %d: %s.", seed, err) 323 } 324 params.KeySym = nil 325 _, err = msg.Wrap(params) 326 if err == nil { 327 t.Fatalf("wrapped with nil key, seed: %d.", seed) 328 } 329 } 330 331 func TestRlpEncode(t *testing.T) { 332 InitSingleTest() 333 334 params, err := generateMessageParams() 335 if err != nil { 336 t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) 337 } 338 msg, err := NewSentMessage(params) 339 if err != nil { 340 t.Fatalf("failed to create new message with seed %d: %s.", seed, err) 341 } 342 env, err := msg.Wrap(params) 343 if err != nil { 344 t.Fatalf("wrapped with zero key, seed: %d.", seed) 345 } 346 347 raw, err := rlp.EncodeToBytes(env) 348 if err != nil { 349 t.Fatalf("RLP encode failed: %s.", err) 350 } 351 352 var decoded Envelope 353 rlp.DecodeBytes(raw, &decoded) 354 if err != nil { 355 t.Fatalf("RLP decode failed: %s.", err) 356 } 357 358 he := env.Hash() 359 hd := decoded.Hash() 360 361 if he != hd { 362 t.Fatalf("Hashes are not equal: %x vs. %x", he, hd) 363 } 364 } 365 366 func singlePaddingTest(t *testing.T, padSize int) { 367 params, err := generateMessageParams() 368 if err != nil { 369 t.Fatalf("failed generateMessageParams with seed %d and sz=%d: %s.", seed, padSize, err) 370 } 371 params.Padding = make([]byte, padSize) 372 params.PoW = 0.0000000001 373 pad := make([]byte, padSize) 374 _, err = mrand.Read(pad) 375 if err != nil { 376 t.Fatalf("padding is not generated (seed %d): %s", seed, err) 377 } 378 n := copy(params.Padding, pad) 379 if n != padSize { 380 t.Fatalf("padding is not copied (seed %d): %s", seed, err) 381 } 382 msg, err := NewSentMessage(params) 383 if err != nil { 384 t.Fatalf("failed to create new message with seed %d: %s.", seed, err) 385 } 386 env, err := msg.Wrap(params) 387 if err != nil { 388 t.Fatalf("failed to wrap, seed: %d and sz=%d.", seed, padSize) 389 } 390 f := Filter{KeySym: params.KeySym} 391 decrypted := env.Open(&f) 392 if decrypted == nil { 393 t.Fatalf("failed to open, seed and sz=%d: %d.", seed, padSize) 394 } 395 if !bytes.Equal(pad, decrypted.Padding) { 396 t.Fatalf("padding is not retireved as expected with seed %d and sz=%d:\n[%x]\n[%x].", seed, padSize, pad, decrypted.Padding) 397 } 398 } 399 400 func TestPadding(t *testing.T) { 401 InitSingleTest() 402 403 for i := 1; i < 260; i++ { 404 singlePaddingTest(t, i) 405 } 406 407 lim := 256 * 256 408 for i := lim - 5; i < lim+2; i++ { 409 singlePaddingTest(t, i) 410 } 411 412 for i := 0; i < 256; i++ { 413 n := mrand.Intn(256*254) + 256 414 singlePaddingTest(t, n) 415 } 416 417 for i := 0; i < 256; i++ { 418 n := mrand.Intn(256*1024) + 256*256 419 singlePaddingTest(t, n) 420 } 421 } 422 423 func TestPaddingAppendedToSymMessagesWithSignature(t *testing.T) { 424 params := &MessageParams{ 425 Payload: make([]byte, 246), 426 KeySym: make([]byte, aesKeyLength), 427 } 428 429 pSrc, err := crypto.GenerateKey() 430 431 if err != nil { 432 t.Fatalf("Error creating the signature key %v", err) 433 return 434 } 435 params.Src = pSrc 436 437 // Simulate a message with a payload just under 256 so that 438 // payload + flag + signature > 256. Check that the result 439 // is padded on the next 256 boundary. 440 msg := sentMessage{} 441 const payloadSizeFieldMinSize = 1 442 msg.Raw = make([]byte, flagsLength+payloadSizeFieldMinSize+len(params.Payload)) 443 444 err = msg.appendPadding(params) 445 446 if err != nil { 447 t.Fatalf("Error appending padding to message %v", err) 448 return 449 } 450 451 if len(msg.Raw) != 512-signatureLength { 452 t.Errorf("Invalid size %d != 512", len(msg.Raw)) 453 } 454 } 455 456 func TestAesNonce(t *testing.T) { 457 key := hexutil.MustDecode("0x03ca634cae0d49acb401d8a4c6b6fe8c55b70d115bf400769cc1400f3258cd31") 458 block, err := aes.NewCipher(key) 459 if err != nil { 460 t.Fatalf("NewCipher failed: %s", err) 461 } 462 aesgcm, err := cipher.NewGCM(block) 463 if err != nil { 464 t.Fatalf("NewGCM failed: %s", err) 465 } 466 // This is the most important single test in this package. 467 // If it fails, whisper will not be working. 468 if aesgcm.NonceSize() != aesNonceLength { 469 t.Fatalf("Nonce size is wrong. This is a critical error. Apparently AES nonce size have changed in the new version of AES GCM package. Whisper will not be working until this problem is resolved.") 470 } 471 }