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