// createFilter creates a message filter to check against installed handlers. func createFilter(message *Message, topics []Topic) filter.Filter { matcher := make([][]Topic, len(topics)) for i, topic := range topics { matcher[i] = []Topic{topic} } return filterer{ to: string(crypto.FromECDSAPub(message.To)), from: string(crypto.FromECDSAPub(message.Recover())), matcher: newTopicMatcher(matcher...), } }
// Watch installs a new message handler to run in case a matching packet arrives // from the whisper network. func (self *Whisper) Watch(options Filter) int { filter := filterer{ to: string(crypto.FromECDSAPub(options.To)), from: string(crypto.FromECDSAPub(options.From)), matcher: newTopicMatcher(options.Topics...), fn: func(data interface{}) { options.Fn(data.(*Message)) }, } return self.filters.Install(filter) }
// NewWhisperMessage converts an internal message into an API version. func NewWhisperMessage(message *Message) WhisperMessage { return WhisperMessage{ ref: message, Payload: common.ToHex(message.Payload), From: common.ToHex(crypto.FromECDSAPub(message.Recover())), To: common.ToHex(crypto.FromECDSAPub(message.To)), Sent: message.Sent.Unix(), TTL: int64(message.TTL / time.Second), Hash: common.ToHex(message.Hash.Bytes()), } }
// NewIdentity generates a new cryptographic identity for the client, and injects // it into the known identities for message decryption. func (s *PublicWhisperAPI) NewIdentity() (string, error) { if s.w == nil { return "", whisperOffLineErr } identity := s.w.NewIdentity() return common.ToHex(crypto.FromECDSAPub(&identity.PublicKey)), nil }
// NewIdentity generates a new cryptographic identity for the client, and injects // it into the known identities for message decryption. func (self *Whisper) NewIdentity() *ecdsa.PrivateKey { key, err := crypto.GenerateKey() if err != nil { panic(err) } self.keys[string(crypto.FromECDSAPub(&key.PublicKey))] = key return key }
// authMsg creates an encrypted initiator handshake message. func (h *encHandshake) authMsg(prv *ecdsa.PrivateKey, token []byte) ([]byte, error) { var tokenFlag byte if token == nil { // no session token found means we need to generate shared secret. // ecies shared secret is used as initial session token for new peers // generate shared key from prv and remote pubkey var err error if token, err = h.ecdhShared(prv); err != nil { return nil, err } } else { // for known peers, we use stored token from the previous session tokenFlag = 0x01 } // sign known message: // ecdh-shared-secret^nonce for new peers // token^nonce for old peers signed := xor(token, h.initNonce) signature, err := crypto.Sign(signed, h.randomPrivKey.ExportECDSA()) if err != nil { return nil, err } // encode auth message // signature || sha3(ecdhe-random-pubk) || pubk || nonce || token-flag msg := make([]byte, authMsgLen) n := copy(msg, signature) n += copy(msg[n:], crypto.Sha3(exportPubkey(&h.randomPrivKey.PublicKey))) n += copy(msg[n:], crypto.FromECDSAPub(&prv.PublicKey)[1:]) n += copy(msg[n:], h.initNonce) msg[n] = tokenFlag // encrypt auth message using remote-pubk return ecies.Encrypt(rand.Reader, h.remotePub, msg, nil, nil) }
// GetIdentity retrieves the private key of the specified public identity. func (self *Whisper) GetIdentity(key *ecdsa.PublicKey) *ecdsa.PrivateKey { return self.keys[string(crypto.FromECDSAPub(key))] }
// HasIdentity checks if the the whisper node is configured with the private key // of the specified public pair. func (self *Whisper) HasIdentity(key *ecdsa.PublicKey) bool { return self.keys[string(crypto.FromECDSAPub(key))] != nil }