github.com/ylsgit/go-ethereum@v1.6.5/whisper/whisperv5/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 whisperv5 18 19 import ( 20 "bytes" 21 mrand "math/rand" 22 "testing" 23 24 "github.com/ethereum/go-ethereum/crypto" 25 "github.com/ethereum/go-ethereum/rlp" 26 ) 27 28 func copyFromBuf(dst []byte, src []byte, beg int) int { 29 copy(dst, src[beg:]) 30 return beg + len(dst) 31 } 32 33 func generateMessageParams() (*MessageParams, error) { 34 // set all the parameters except p.Dst and p.Padding 35 36 buf := make([]byte, 4) 37 mrand.Read(buf) 38 sz := mrand.Intn(400) 39 40 var p MessageParams 41 p.PoW = 0.01 42 p.WorkTime = 1 43 p.TTL = uint32(mrand.Intn(1024)) 44 p.Payload = make([]byte, sz) 45 p.KeySym = make([]byte, aesKeyLength) 46 mrand.Read(p.Payload) 47 mrand.Read(p.KeySym) 48 p.Topic = BytesToTopic(buf) 49 50 var err error 51 p.Src, err = crypto.GenerateKey() 52 if err != nil { 53 return nil, err 54 } 55 56 return &p, nil 57 } 58 59 func singleMessageTest(t *testing.T, symmetric bool) { 60 params, err := generateMessageParams() 61 if err != nil { 62 t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) 63 } 64 65 key, err := crypto.GenerateKey() 66 if err != nil { 67 t.Fatalf("failed GenerateKey with seed %d: %s.", seed, err) 68 } 69 70 if !symmetric { 71 params.KeySym = nil 72 params.Dst = &key.PublicKey 73 } 74 75 text := make([]byte, 0, 512) 76 text = append(text, params.Payload...) 77 78 msg, err := NewSentMessage(params) 79 if err != nil { 80 t.Fatalf("failed to create new message with seed %d: %s.", seed, err) 81 } 82 env, err := msg.Wrap(params) 83 if err != nil { 84 t.Fatalf("failed Wrap with seed %d: %s.", seed, err) 85 } 86 87 var decrypted *ReceivedMessage 88 if symmetric { 89 decrypted, err = env.OpenSymmetric(params.KeySym) 90 } else { 91 decrypted, err = env.OpenAsymmetric(key) 92 } 93 94 if err != nil { 95 t.Fatalf("failed to encrypt with seed %d: %s.", seed, err) 96 } 97 98 if !decrypted.Validate() { 99 t.Fatalf("failed to validate with seed %d.", seed) 100 } 101 102 if !bytes.Equal(text, decrypted.Payload) { 103 t.Fatalf("failed with seed %d: compare payload.", seed) 104 } 105 if !isMessageSigned(decrypted.Raw[0]) { 106 t.Fatalf("failed with seed %d: unsigned.", seed) 107 } 108 if len(decrypted.Signature) != signatureLength { 109 t.Fatalf("failed with seed %d: signature len %d.", seed, len(decrypted.Signature)) 110 } 111 if !IsPubKeyEqual(decrypted.Src, ¶ms.Src.PublicKey) { 112 t.Fatalf("failed with seed %d: signature mismatch.", seed) 113 } 114 } 115 116 func TestMessageEncryption(t *testing.T) { 117 InitSingleTest() 118 119 var symmetric bool 120 for i := 0; i < 256; i++ { 121 singleMessageTest(t, symmetric) 122 symmetric = !symmetric 123 } 124 } 125 126 func TestMessageWrap(t *testing.T) { 127 seed = int64(1777444222) 128 mrand.Seed(seed) 129 target := 128.0 130 131 params, err := generateMessageParams() 132 if err != nil { 133 t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) 134 } 135 136 msg, err := NewSentMessage(params) 137 if err != nil { 138 t.Fatalf("failed to create new message with seed %d: %s.", seed, err) 139 } 140 params.TTL = 1 141 params.WorkTime = 12 142 params.PoW = target 143 env, err := msg.Wrap(params) 144 if err != nil { 145 t.Fatalf("failed Wrap with seed %d: %s.", seed, err) 146 } 147 148 pow := env.PoW() 149 if pow < target { 150 t.Fatalf("failed Wrap with seed %d: pow < target (%f vs. %f).", seed, pow, target) 151 } 152 153 // set PoW target too high, expect error 154 msg2, err := NewSentMessage(params) 155 if err != nil { 156 t.Fatalf("failed to create new message with seed %d: %s.", seed, err) 157 } 158 params.TTL = 1000000 159 params.WorkTime = 1 160 params.PoW = 10000000.0 161 env, err = msg2.Wrap(params) 162 if err == nil { 163 t.Fatalf("unexpectedly reached the PoW target with seed %d.", seed) 164 } 165 } 166 167 func TestMessageSeal(t *testing.T) { 168 // this test depends on deterministic choice of seed (1976726903) 169 seed = int64(1976726903) 170 mrand.Seed(seed) 171 172 params, err := generateMessageParams() 173 if err != nil { 174 t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) 175 } 176 177 msg, err := NewSentMessage(params) 178 if err != nil { 179 t.Fatalf("failed to create new message with seed %d: %s.", seed, err) 180 } 181 params.TTL = 1 182 aesnonce := make([]byte, 12) 183 mrand.Read(aesnonce) 184 185 env := NewEnvelope(params.TTL, params.Topic, aesnonce, msg) 186 if err != nil { 187 t.Fatalf("failed Wrap with seed %d: %s.", seed, err) 188 } 189 190 env.Expiry = uint32(seed) // make it deterministic 191 target := 32.0 192 params.WorkTime = 4 193 params.PoW = target 194 env.Seal(params) 195 196 env.calculatePoW(0) 197 pow := env.PoW() 198 if pow < target { 199 t.Fatalf("failed Wrap with seed %d: pow < target (%f vs. %f).", seed, pow, target) 200 } 201 202 params.WorkTime = 1 203 params.PoW = 1000000000.0 204 env.Seal(params) 205 env.calculatePoW(0) 206 pow = env.PoW() 207 if pow < 2*target { 208 t.Fatalf("failed Wrap with seed %d: pow too small %f.", seed, pow) 209 } 210 } 211 212 func TestEnvelopeOpen(t *testing.T) { 213 InitSingleTest() 214 215 var symmetric bool 216 for i := 0; i < 256; i++ { 217 singleEnvelopeOpenTest(t, symmetric) 218 symmetric = !symmetric 219 } 220 } 221 222 func singleEnvelopeOpenTest(t *testing.T, symmetric bool) { 223 params, err := generateMessageParams() 224 if err != nil { 225 t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) 226 } 227 228 key, err := crypto.GenerateKey() 229 if err != nil { 230 t.Fatalf("failed GenerateKey with seed %d: %s.", seed, err) 231 } 232 233 if !symmetric { 234 params.KeySym = nil 235 params.Dst = &key.PublicKey 236 } 237 238 text := make([]byte, 0, 512) 239 text = append(text, params.Payload...) 240 241 msg, err := NewSentMessage(params) 242 if err != nil { 243 t.Fatalf("failed to create new message with seed %d: %s.", seed, err) 244 } 245 env, err := msg.Wrap(params) 246 if err != nil { 247 t.Fatalf("failed Wrap with seed %d: %s.", seed, err) 248 } 249 250 f := Filter{KeyAsym: key, KeySym: params.KeySym} 251 decrypted := env.Open(&f) 252 if decrypted == nil { 253 t.Fatalf("failed to open with seed %d.", seed) 254 } 255 256 if !bytes.Equal(text, decrypted.Payload) { 257 t.Fatalf("failed with seed %d: compare payload.", seed) 258 } 259 if !isMessageSigned(decrypted.Raw[0]) { 260 t.Fatalf("failed with seed %d: unsigned.", seed) 261 } 262 if len(decrypted.Signature) != signatureLength { 263 t.Fatalf("failed with seed %d: signature len %d.", seed, len(decrypted.Signature)) 264 } 265 if !IsPubKeyEqual(decrypted.Src, ¶ms.Src.PublicKey) { 266 t.Fatalf("failed with seed %d: signature mismatch.", seed) 267 } 268 if decrypted.isAsymmetricEncryption() == symmetric { 269 t.Fatalf("failed with seed %d: asymmetric %v vs. %v.", seed, decrypted.isAsymmetricEncryption(), symmetric) 270 } 271 if decrypted.isSymmetricEncryption() != symmetric { 272 t.Fatalf("failed with seed %d: symmetric %v vs. %v.", seed, decrypted.isSymmetricEncryption(), symmetric) 273 } 274 if !symmetric { 275 if decrypted.Dst == nil { 276 t.Fatalf("failed with seed %d: dst is nil.", seed) 277 } 278 if !IsPubKeyEqual(decrypted.Dst, &key.PublicKey) { 279 t.Fatalf("failed with seed %d: Dst.", seed) 280 } 281 } 282 } 283 284 func TestEncryptWithZeroKey(t *testing.T) { 285 InitSingleTest() 286 287 params, err := generateMessageParams() 288 if err != nil { 289 t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) 290 } 291 msg, err := NewSentMessage(params) 292 if err != nil { 293 t.Fatalf("failed to create new message with seed %d: %s.", seed, err) 294 } 295 params.KeySym = make([]byte, aesKeyLength) 296 _, err = msg.Wrap(params) 297 if err == nil { 298 t.Fatalf("wrapped with zero key, seed: %d.", seed) 299 } 300 301 params, err = generateMessageParams() 302 if err != nil { 303 t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) 304 } 305 msg, err = NewSentMessage(params) 306 if err != nil { 307 t.Fatalf("failed to create new message with seed %d: %s.", seed, err) 308 } 309 params.KeySym = make([]byte, 0) 310 _, err = msg.Wrap(params) 311 if err == nil { 312 t.Fatalf("wrapped with empty key, seed: %d.", seed) 313 } 314 315 params, err = generateMessageParams() 316 if err != nil { 317 t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) 318 } 319 msg, err = NewSentMessage(params) 320 if err != nil { 321 t.Fatalf("failed to create new message with seed %d: %s.", seed, err) 322 } 323 params.KeySym = nil 324 _, err = msg.Wrap(params) 325 if err == nil { 326 t.Fatalf("wrapped with nil key, seed: %d.", seed) 327 } 328 } 329 330 func TestRlpEncode(t *testing.T) { 331 InitSingleTest() 332 333 params, err := generateMessageParams() 334 if err != nil { 335 t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) 336 } 337 msg, err := NewSentMessage(params) 338 if err != nil { 339 t.Fatalf("failed to create new message with seed %d: %s.", seed, err) 340 } 341 env, err := msg.Wrap(params) 342 if err != nil { 343 t.Fatalf("wrapped with zero key, seed: %d.", seed) 344 } 345 346 raw, err := rlp.EncodeToBytes(env) 347 if err != nil { 348 t.Fatalf("RLP encode failed: %s.", err) 349 } 350 351 var decoded Envelope 352 rlp.DecodeBytes(raw, &decoded) 353 if err != nil { 354 t.Fatalf("RLP decode failed: %s.", err) 355 } 356 357 he := env.Hash() 358 hd := decoded.Hash() 359 360 if he != hd { 361 t.Fatalf("Hashes are not equal: %x vs. %x", he, hd) 362 } 363 } 364 365 func singlePaddingTest(t *testing.T, padSize int) { 366 params, err := generateMessageParams() 367 if err != nil { 368 t.Fatalf("failed generateMessageParams with seed %d and sz=%d: %s.", seed, padSize, err) 369 } 370 params.Padding = make([]byte, padSize) 371 params.PoW = 0.0000000001 372 pad := make([]byte, padSize) 373 _, err = mrand.Read(pad) 374 if err != nil { 375 t.Fatalf("padding is not generated (seed %d): %s", seed, err) 376 } 377 n := copy(params.Padding, pad) 378 if n != padSize { 379 t.Fatalf("padding is not copied (seed %d): %s", seed, err) 380 } 381 msg, err := NewSentMessage(params) 382 if err != nil { 383 t.Fatalf("failed to create new message with seed %d: %s.", seed, err) 384 } 385 env, err := msg.Wrap(params) 386 if err != nil { 387 t.Fatalf("failed to wrap, seed: %d and sz=%d.", seed, padSize) 388 } 389 f := Filter{KeySym: params.KeySym} 390 decrypted := env.Open(&f) 391 if decrypted == nil { 392 t.Fatalf("failed to open, seed and sz=%d: %d.", seed, padSize) 393 } 394 if !bytes.Equal(pad, decrypted.Padding) { 395 t.Fatalf("padding is not retireved as expected with seed %d and sz=%d:\n[%x]\n[%x].", seed, padSize, pad, decrypted.Padding) 396 } 397 } 398 399 func TestPadding(t *testing.T) { 400 InitSingleTest() 401 402 for i := 1; i < 260; i++ { 403 singlePaddingTest(t, i) 404 } 405 406 lim := 256 * 256 407 for i := lim - 5; i < lim+2; i++ { 408 singlePaddingTest(t, i) 409 } 410 411 for i := 0; i < 256; i++ { 412 n := mrand.Intn(256*254) + 256 413 singlePaddingTest(t, n) 414 } 415 416 for i := 0; i < 256; i++ { 417 n := mrand.Intn(256*1024) + 256*256 418 singlePaddingTest(t, n) 419 } 420 }