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