github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/whisper/whisperv6/message.go (about) 1 2 //此源码被清华学神尹成大魔王专业翻译分析并修改 3 //尹成QQ77025077 4 //尹成微信18510341407 5 //尹成所在QQ群721929980 6 //尹成邮箱 yinc13@mails.tsinghua.edu.cn 7 //尹成毕业于清华大学,微软区块链领域全球最有价值专家 8 //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620 9 // 10 // 11 // 12 // 13 // 14 // 15 // 16 // 17 // 18 // 19 // 20 // 21 // 22 // 23 // 24 25 // 26 27 package whisperv6 28 29 import ( 30 "crypto/aes" 31 "crypto/cipher" 32 "crypto/ecdsa" 33 crand "crypto/rand" 34 "encoding/binary" 35 "errors" 36 mrand "math/rand" 37 "strconv" 38 39 "github.com/ethereum/go-ethereum/common" 40 "github.com/ethereum/go-ethereum/crypto" 41 "github.com/ethereum/go-ethereum/crypto/ecies" 42 "github.com/ethereum/go-ethereum/log" 43 ) 44 45 // 46 // 47 type MessageParams struct { 48 TTL uint32 49 Src *ecdsa.PrivateKey 50 Dst *ecdsa.PublicKey 51 KeySym []byte 52 Topic TopicType 53 WorkTime uint32 54 PoW float64 55 Payload []byte 56 Padding []byte 57 } 58 59 // 60 // 61 // 62 type sentMessage struct { 63 Raw []byte 64 } 65 66 // 67 // 68 type ReceivedMessage struct { 69 Raw []byte 70 71 Payload []byte 72 Padding []byte 73 Signature []byte 74 Salt []byte 75 76 PoW float64 // 77 Sent uint32 // 78 TTL uint32 // 79 Src *ecdsa.PublicKey // 80 Dst *ecdsa.PublicKey // 81 Topic TopicType 82 83 SymKeyHash common.Hash // 84 EnvelopeHash common.Hash // 85 } 86 87 func isMessageSigned(flags byte) bool { 88 return (flags & signatureFlag) != 0 89 } 90 91 func (msg *ReceivedMessage) isSymmetricEncryption() bool { 92 return msg.SymKeyHash != common.Hash{} 93 } 94 95 func (msg *ReceivedMessage) isAsymmetricEncryption() bool { 96 return msg.Dst != nil 97 } 98 99 // 100 func NewSentMessage(params *MessageParams) (*sentMessage, error) { 101 const payloadSizeFieldMaxSize = 4 102 msg := sentMessage{} 103 msg.Raw = make([]byte, 1, 104 flagsLength+payloadSizeFieldMaxSize+len(params.Payload)+len(params.Padding)+signatureLength+padSizeLimit) 105 msg.Raw[0] = 0 // 106 msg.addPayloadSizeField(params.Payload) 107 msg.Raw = append(msg.Raw, params.Payload...) 108 err := msg.appendPadding(params) 109 return &msg, err 110 } 111 112 // 113 func (msg *sentMessage) addPayloadSizeField(payload []byte) { 114 fieldSize := getSizeOfPayloadSizeField(payload) 115 field := make([]byte, 4) 116 binary.LittleEndian.PutUint32(field, uint32(len(payload))) 117 field = field[:fieldSize] 118 msg.Raw = append(msg.Raw, field...) 119 msg.Raw[0] |= byte(fieldSize) 120 } 121 122 // 123 func getSizeOfPayloadSizeField(payload []byte) int { 124 s := 1 125 for i := len(payload); i >= 256; i /= 256 { 126 s++ 127 } 128 return s 129 } 130 131 // 132 // 133 func (msg *sentMessage) appendPadding(params *MessageParams) error { 134 if len(params.Padding) != 0 { 135 // 136 msg.Raw = append(msg.Raw, params.Padding...) 137 return nil 138 } 139 140 rawSize := flagsLength + getSizeOfPayloadSizeField(params.Payload) + len(params.Payload) 141 if params.Src != nil { 142 rawSize += signatureLength 143 } 144 odd := rawSize % padSizeLimit 145 paddingSize := padSizeLimit - odd 146 pad := make([]byte, paddingSize) 147 _, err := crand.Read(pad) 148 if err != nil { 149 return err 150 } 151 if !validateDataIntegrity(pad, paddingSize) { 152 return errors.New("failed to generate random padding of size " + strconv.Itoa(paddingSize)) 153 } 154 msg.Raw = append(msg.Raw, pad...) 155 return nil 156 } 157 158 // 159 // 160 func (msg *sentMessage) sign(key *ecdsa.PrivateKey) error { 161 if isMessageSigned(msg.Raw[0]) { 162 // 163 log.Error("failed to sign the message: already signed") 164 return nil 165 } 166 167 msg.Raw[0] |= signatureFlag // 168 hash := crypto.Keccak256(msg.Raw) 169 signature, err := crypto.Sign(hash, key) 170 if err != nil { 171 msg.Raw[0] &= (0xFF ^ signatureFlag) // 172 return err 173 } 174 msg.Raw = append(msg.Raw, signature...) 175 return nil 176 } 177 178 // 179 func (msg *sentMessage) encryptAsymmetric(key *ecdsa.PublicKey) error { 180 if !ValidatePublicKey(key) { 181 return errors.New("invalid public key provided for asymmetric encryption") 182 } 183 encrypted, err := ecies.Encrypt(crand.Reader, ecies.ImportECDSAPublic(key), msg.Raw, nil, nil) 184 if err == nil { 185 msg.Raw = encrypted 186 } 187 return err 188 } 189 190 // 191 // 192 func (msg *sentMessage) encryptSymmetric(key []byte) (err error) { 193 if !validateDataIntegrity(key, aesKeyLength) { 194 return errors.New("invalid key provided for symmetric encryption, size: " + strconv.Itoa(len(key))) 195 } 196 block, err := aes.NewCipher(key) 197 if err != nil { 198 return err 199 } 200 aesgcm, err := cipher.NewGCM(block) 201 if err != nil { 202 return err 203 } 204 salt, err := generateSecureRandomData(aesNonceLength) // 205 if err != nil { 206 return err 207 } 208 encrypted := aesgcm.Seal(nil, salt, msg.Raw, nil) 209 msg.Raw = append(encrypted, salt...) 210 return nil 211 } 212 213 // 214 // 215 // 216 // 217 // 218 func generateSecureRandomData(length int) ([]byte, error) { 219 x := make([]byte, length) 220 y := make([]byte, length) 221 res := make([]byte, length) 222 223 _, err := crand.Read(x) 224 if err != nil { 225 return nil, err 226 } else if !validateDataIntegrity(x, length) { 227 return nil, errors.New("crypto/rand failed to generate secure random data") 228 } 229 _, err = mrand.Read(y) 230 if err != nil { 231 return nil, err 232 } else if !validateDataIntegrity(y, length) { 233 return nil, errors.New("math/rand failed to generate secure random data") 234 } 235 for i := 0; i < length; i++ { 236 res[i] = x[i] ^ y[i] 237 } 238 if !validateDataIntegrity(res, length) { 239 return nil, errors.New("failed to generate secure random data") 240 } 241 return res, nil 242 } 243 244 // 245 func (msg *sentMessage) Wrap(options *MessageParams) (envelope *Envelope, err error) { 246 if options.TTL == 0 { 247 options.TTL = DefaultTTL 248 } 249 if options.Src != nil { 250 if err = msg.sign(options.Src); err != nil { 251 return nil, err 252 } 253 } 254 if options.Dst != nil { 255 err = msg.encryptAsymmetric(options.Dst) 256 } else if options.KeySym != nil { 257 err = msg.encryptSymmetric(options.KeySym) 258 } else { 259 err = errors.New("unable to encrypt the message: neither symmetric nor assymmetric key provided") 260 } 261 if err != nil { 262 return nil, err 263 } 264 265 envelope = NewEnvelope(options.TTL, options.Topic, msg) 266 if err = envelope.Seal(options); err != nil { 267 return nil, err 268 } 269 return envelope, nil 270 } 271 272 // 273 // 274 func (msg *ReceivedMessage) decryptSymmetric(key []byte) error { 275 // 276 if len(msg.Raw) < aesNonceLength { 277 return errors.New("missing salt or invalid payload in symmetric message") 278 } 279 salt := msg.Raw[len(msg.Raw)-aesNonceLength:] 280 281 block, err := aes.NewCipher(key) 282 if err != nil { 283 return err 284 } 285 aesgcm, err := cipher.NewGCM(block) 286 if err != nil { 287 return err 288 } 289 decrypted, err := aesgcm.Open(nil, salt, msg.Raw[:len(msg.Raw)-aesNonceLength], nil) 290 if err != nil { 291 return err 292 } 293 msg.Raw = decrypted 294 msg.Salt = salt 295 return nil 296 } 297 298 // 299 func (msg *ReceivedMessage) decryptAsymmetric(key *ecdsa.PrivateKey) error { 300 decrypted, err := ecies.ImportECDSA(key).Decrypt(msg.Raw, nil, nil) 301 if err == nil { 302 msg.Raw = decrypted 303 } 304 return err 305 } 306 307 // 308 func (msg *ReceivedMessage) ValidateAndParse() bool { 309 end := len(msg.Raw) 310 if end < 1 { 311 return false 312 } 313 314 if isMessageSigned(msg.Raw[0]) { 315 end -= signatureLength 316 if end <= 1 { 317 return false 318 } 319 msg.Signature = msg.Raw[end : end+signatureLength] 320 msg.Src = msg.SigToPubKey() 321 if msg.Src == nil { 322 return false 323 } 324 } 325 326 beg := 1 327 payloadSize := 0 328 sizeOfPayloadSizeField := int(msg.Raw[0] & SizeMask) // 329 if sizeOfPayloadSizeField != 0 { 330 payloadSize = int(bytesToUintLittleEndian(msg.Raw[beg : beg+sizeOfPayloadSizeField])) 331 if payloadSize+1 > end { 332 return false 333 } 334 beg += sizeOfPayloadSizeField 335 msg.Payload = msg.Raw[beg : beg+payloadSize] 336 } 337 338 beg += payloadSize 339 msg.Padding = msg.Raw[beg:end] 340 return true 341 } 342 343 // 344 // 345 func (msg *ReceivedMessage) SigToPubKey() *ecdsa.PublicKey { 346 defer func() { recover() }() // 347 348 pub, err := crypto.SigToPub(msg.hash(), msg.Signature) 349 if err != nil { 350 log.Error("failed to recover public key from signature", "err", err) 351 return nil 352 } 353 return pub 354 } 355 356 // 357 func (msg *ReceivedMessage) hash() []byte { 358 if isMessageSigned(msg.Raw[0]) { 359 sz := len(msg.Raw) - signatureLength 360 return crypto.Keccak256(msg.Raw[:sz]) 361 } 362 return crypto.Keccak256(msg.Raw) 363 }