github.com/murrekatt/go-ethereum@v1.5.8-0.20170123175102-fc52f2c007fb/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 "math/rand" 22 "testing" 23 24 "github.com/ethereum/go-ethereum/crypto" 25 ) 26 27 func copyFromBuf(dst []byte, src []byte, beg int) int { 28 copy(dst, src[beg:]) 29 return beg + len(dst) 30 } 31 32 func generateMessageParams() (*MessageParams, error) { 33 // set all the parameters except p.Dst 34 35 buf := make([]byte, 1024) 36 randomize(buf) 37 sz := rand.Intn(400) 38 39 var p MessageParams 40 p.PoW = 0.01 41 p.WorkTime = 1 42 p.TTL = uint32(rand.Intn(1024)) 43 p.Payload = make([]byte, sz) 44 p.Padding = make([]byte, padSizeLimitUpper) 45 p.KeySym = make([]byte, aesKeyLength) 46 47 var b int 48 b = copyFromBuf(p.Payload, buf, b) 49 b = copyFromBuf(p.Padding, buf, b) 50 b = copyFromBuf(p.KeySym, buf, b) 51 p.Topic = BytesToTopic(buf[b:]) 52 53 var err error 54 p.Src, err = crypto.GenerateKey() 55 if err != nil { 56 return nil, err 57 } 58 59 return &p, nil 60 } 61 62 func singleMessageTest(t *testing.T, symmetric bool) { 63 params, err := generateMessageParams() 64 if err != nil { 65 t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) 66 } 67 68 key, err := crypto.GenerateKey() 69 if err != nil { 70 t.Fatalf("failed GenerateKey with seed %d: %s.", seed, err) 71 } 72 73 if !symmetric { 74 params.KeySym = nil 75 params.Dst = &key.PublicKey 76 } 77 78 text := make([]byte, 0, 512) 79 steg := make([]byte, 0, 512) 80 text = append(text, params.Payload...) 81 steg = append(steg, params.Padding...) 82 83 msg := NewSentMessage(params) 84 env, err := msg.Wrap(params) 85 if err != nil { 86 t.Fatalf("failed Wrap with seed %d: %s.", seed, err) 87 } 88 89 var decrypted *ReceivedMessage 90 if symmetric { 91 decrypted, err = env.OpenSymmetric(params.KeySym) 92 } else { 93 decrypted, err = env.OpenAsymmetric(key) 94 } 95 96 if err != nil { 97 t.Fatalf("failed to encrypt with seed %d: %s.", seed, err) 98 } 99 100 if !decrypted.Validate() { 101 t.Fatalf("failed to validate with seed %d.", seed) 102 } 103 104 padsz := len(decrypted.Padding) 105 if !bytes.Equal(steg[:padsz], decrypted.Padding) { 106 t.Fatalf("failed with seed %d: compare padding.", seed) 107 } 108 if !bytes.Equal(text, decrypted.Payload) { 109 t.Fatalf("failed with seed %d: compare payload.", seed) 110 } 111 if !isMessageSigned(decrypted.Raw[0]) { 112 t.Fatalf("failed with seed %d: unsigned.", seed) 113 } 114 if len(decrypted.Signature) != signatureLength { 115 t.Fatalf("failed with seed %d: signature len %d.", seed, len(decrypted.Signature)) 116 } 117 if !IsPubKeyEqual(decrypted.Src, ¶ms.Src.PublicKey) { 118 t.Fatalf("failed with seed %d: signature mismatch.", seed) 119 } 120 } 121 122 func TestMessageEncryption(t *testing.T) { 123 InitSingleTest() 124 125 var symmetric bool 126 for i := 0; i < 256; i++ { 127 singleMessageTest(t, symmetric) 128 symmetric = !symmetric 129 } 130 } 131 132 func TestMessageWrap(t *testing.T) { 133 seed = int64(1777444222) 134 rand.Seed(seed) 135 target := 128.0 136 137 params, err := generateMessageParams() 138 if err != nil { 139 t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) 140 } 141 142 msg := NewSentMessage(params) 143 params.TTL = 1 144 params.WorkTime = 12 145 params.PoW = target 146 env, err := msg.Wrap(params) 147 if err != nil { 148 t.Fatalf("failed Wrap with seed %d: %s.", seed, err) 149 } 150 151 pow := env.PoW() 152 if pow < target { 153 t.Fatalf("failed Wrap with seed %d: pow < target (%f vs. %f).", seed, pow, target) 154 } 155 156 // set PoW target too high, expect error 157 msg2 := NewSentMessage(params) 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 rand.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 := NewSentMessage(params) 178 params.TTL = 1 179 aesnonce := make([]byte, 12) 180 salt := make([]byte, 12) 181 randomize(aesnonce) 182 randomize(salt) 183 184 env := NewEnvelope(params.TTL, params.Topic, salt, aesnonce, msg) 185 if err != nil { 186 t.Fatalf("failed Wrap with seed %d: %s.", seed, err) 187 } 188 189 env.Expiry = uint32(seed) // make it deterministic 190 target := 32.0 191 params.WorkTime = 4 192 params.PoW = target 193 env.Seal(params) 194 195 env.calculatePoW(0) 196 pow := env.PoW() 197 if pow < target { 198 t.Fatalf("failed Wrap with seed %d: pow < target (%f vs. %f).", seed, pow, target) 199 } 200 201 params.WorkTime = 1 202 params.PoW = 1000000000.0 203 env.Seal(params) 204 env.calculatePoW(0) 205 pow = env.PoW() 206 if pow < 2*target { 207 t.Fatalf("failed Wrap with seed %d: pow too small %f.", seed, pow) 208 } 209 } 210 211 func TestEnvelopeOpen(t *testing.T) { 212 InitSingleTest() 213 214 var symmetric bool 215 for i := 0; i < 256; i++ { 216 singleEnvelopeOpenTest(t, symmetric) 217 symmetric = !symmetric 218 } 219 } 220 221 func singleEnvelopeOpenTest(t *testing.T, symmetric bool) { 222 params, err := generateMessageParams() 223 if err != nil { 224 t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) 225 } 226 227 key, err := crypto.GenerateKey() 228 if err != nil { 229 t.Fatalf("failed GenerateKey with seed %d: %s.", seed, err) 230 } 231 232 if !symmetric { 233 params.KeySym = nil 234 params.Dst = &key.PublicKey 235 } 236 237 text := make([]byte, 0, 512) 238 steg := make([]byte, 0, 512) 239 text = append(text, params.Payload...) 240 steg = append(steg, params.Padding...) 241 242 msg := NewSentMessage(params) 243 env, err := msg.Wrap(params) 244 if err != nil { 245 t.Fatalf("failed Wrap with seed %d: %s.", seed, err) 246 } 247 248 f := Filter{KeyAsym: key, KeySym: params.KeySym} 249 decrypted := env.Open(&f) 250 if decrypted == nil { 251 t.Fatalf("failed to open with seed %d.", seed) 252 } 253 254 padsz := len(decrypted.Padding) 255 if !bytes.Equal(steg[:padsz], decrypted.Padding) { 256 t.Fatalf("failed with seed %d: compare padding.", seed) 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 294 msg := NewSentMessage(params) 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.KeySym = make([]byte, 0) 303 _, err = msg.Wrap(params) 304 if err == nil { 305 t.Fatalf("wrapped with empty key, seed: %d.", seed) 306 } 307 308 params.KeySym = nil 309 _, err = msg.Wrap(params) 310 if err == nil { 311 t.Fatalf("wrapped with nil key, seed: %d.", seed) 312 } 313 }