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