diff --git a/cmd/wnode/main.go b/cmd/wnode/main.go
index 175021798abadeae4a54d5fa957ee81d938b9677..d002497fbf73f74e957c7be64b6ac766faad2c82 100644
--- a/cmd/wnode/main.go
+++ b/cmd/wnode/main.go
@@ -22,8 +22,6 @@ package main
 import (
 	"bufio"
 	"crypto/ecdsa"
-	"crypto/sha1"
-	"crypto/sha256"
 	"crypto/sha512"
 	"encoding/binary"
 	"encoding/hex"
@@ -49,6 +47,7 @@ import (
 )
 
 const quitCommand = "~Q"
+const symKeyName = "da919ea33001b04dfc630522e33078ec0df11"
 
 // singletons
 var (
@@ -67,7 +66,8 @@ var (
 	asymKey    *ecdsa.PrivateKey
 	nodeid     *ecdsa.PrivateKey
 	topic      whisper.TopicType
-	filterID   uint32
+	filterID   string
+	symPass    string
 	msPassword string
 )
 
@@ -82,13 +82,13 @@ var (
 	testMode       = flag.Bool("t", false, "use of predefined parameters for diagnostics")
 	generateKey    = flag.Bool("k", false, "generate and show the private key")
 
+	argVerbosity = flag.Int("verbosity", logger.Warn, "log verbosity level")
 	argTTL       = flag.Uint("ttl", 30, "time-to-live for messages in seconds")
 	argWorkTime  = flag.Uint("work", 5, "work time in seconds")
 	argPoW       = flag.Float64("pow", whisper.MinimumPoW, "PoW for normal messages in float format (e.g. 2.7)")
 	argServerPoW = flag.Float64("mspow", whisper.MinimumPoW, "PoW requirement for Mail Server request")
 
 	argIP     = flag.String("ip", "", "IP address and port of this node (e.g. 127.0.0.1:30303)")
-	argSalt   = flag.String("salt", "", "salt (for topic and key derivation)")
 	argPub    = flag.String("pub", "", "public key for asymmetric encryption")
 	argDBPath = flag.String("dbpath", "", "path to the server's DB directory")
 	argIDFile = flag.String("idfile", "", "file name with node id (private key)")
@@ -146,7 +146,6 @@ func echo() {
 	fmt.Printf("pow = %f \n", *argPoW)
 	fmt.Printf("mspow = %f \n", *argServerPoW)
 	fmt.Printf("ip = %s \n", *argIP)
-	fmt.Printf("salt = %s \n", *argSalt)
 	fmt.Printf("pub = %s \n", common.ToHex(crypto.FromECDSAPub(pub)))
 	fmt.Printf("idfile = %s \n", *argIDFile)
 	fmt.Printf("dbpath = %s \n", *argDBPath)
@@ -154,7 +153,7 @@ func echo() {
 }
 
 func initialize() {
-	glog.SetV(logger.Warn)
+	glog.SetV(*argVerbosity)
 	glog.SetToStderr(true)
 
 	done = make(chan struct{})
@@ -172,10 +171,7 @@ func initialize() {
 	}
 
 	if *testMode {
-		password := []byte("test password for symmetric encryption")
-		salt := []byte("test salt for symmetric encryption")
-		symKey = pbkdf2.Key(password, salt, 64, 32, sha256.New)
-		topic = whisper.TopicType{0xFF, 0xFF, 0xFF, 0xFF}
+		symPass = "wwww" // ascii code: 0x77777777
 		msPassword = "mail server test password"
 	}
 
@@ -286,20 +282,18 @@ func configureNode() {
 		}
 	}
 
-	if !*asymmetricMode && !*forwarderMode && !*testMode {
-		pass, err := console.Stdin.PromptPassword("Please enter the password: ")
-		if err != nil {
-			utils.Fatalf("Failed to read passphrase: %v", err)
-		}
-
-		if len(*argSalt) == 0 {
-			argSalt = scanLineA("Please enter the salt: ")
+	if !*asymmetricMode && !*forwarderMode {
+		if len(symPass) == 0 {
+			symPass, err = console.Stdin.PromptPassword("Please enter the password: ")
+			if err != nil {
+				utils.Fatalf("Failed to read passphrase: %v", err)
+			}
 		}
 
-		symKey = pbkdf2.Key([]byte(pass), []byte(*argSalt), 65356, 32, sha256.New)
-
+		shh.AddSymKey(symKeyName, []byte(symPass))
+		symKey = shh.GetSymKey(symKeyName)
 		if len(*argTopic) == 0 {
-			generateTopic([]byte(pass), []byte(*argSalt))
+			generateTopic([]byte(symPass))
 		}
 	}
 
@@ -315,19 +309,17 @@ func configureNode() {
 		Topics:    []whisper.TopicType{topic},
 		AcceptP2P: p2pAccept,
 	}
-	filterID = shh.Watch(&filter)
+	filterID, err = shh.Watch(&filter)
+	if err != nil {
+		utils.Fatalf("Failed to install filter: %s", err)
+	}
 	fmt.Printf("Filter is configured for the topic: %x \n", topic)
 }
 
-func generateTopic(password, salt []byte) {
-	const rounds = 4000
-	const size = 128
-	x1 := pbkdf2.Key(password, salt, rounds, size, sha512.New)
-	x2 := pbkdf2.Key(password, salt, rounds, size, sha1.New)
-	x3 := pbkdf2.Key(x1, x2, rounds, size, sha256.New)
-
-	for i := 0; i < size; i++ {
-		topic[i%whisper.TopicLength] ^= x3[i]
+func generateTopic(password []byte) {
+	x := pbkdf2.Key(password, password, 8196, 128, sha512.New)
+	for i := 0; i < len(x); i++ {
+		topic[i%whisper.TopicLength] ^= x[i]
 	}
 }
 
@@ -379,9 +371,9 @@ func sendLoop() {
 		if *asymmetricMode {
 			// print your own message for convenience,
 			// because in asymmetric mode it is impossible to decrypt it
-			hour, min, sec := time.Now().Clock()
+			timestamp := time.Now().Unix()
 			from := crypto.PubkeyToAddress(asymKey.PublicKey)
-			fmt.Printf("\n%02d:%02d:%02d <%x>: %s\n", hour, min, sec, from, s)
+			fmt.Printf("\n%d <%x>: %s\n", timestamp, from, s)
 		}
 	}
 }
diff --git a/whisper/whisperv5/api.go b/whisper/whisperv5/api.go
index ce41624dfec733afca9b2ae97898b2195785ba41..4d33d232142a5ccf8356faaf8c3ea8174e9112b1 100644
--- a/whisper/whisperv5/api.go
+++ b/whisper/whisperv5/api.go
@@ -123,7 +123,7 @@ func (api *PublicWhisperAPI) GenerateSymKey(name string) error {
 }
 
 // AddSymKey stores the key under the 'name' id.
-func (api *PublicWhisperAPI) AddSymKey(name string, key []byte) error {
+func (api *PublicWhisperAPI) AddSymKey(name string, key hexutil.Bytes) error {
 	if api.whisper == nil {
 		return whisperOffLineErr
 	}
@@ -151,9 +151,9 @@ func (api *PublicWhisperAPI) DeleteSymKey(name string) error {
 
 // NewWhisperFilter creates and registers a new message filter to watch for inbound whisper messages.
 // Returns the ID of the newly created Filter.
-func (api *PublicWhisperAPI) NewFilter(args WhisperFilterArgs) (uint32, error) {
+func (api *PublicWhisperAPI) NewFilter(args WhisperFilterArgs) (string, error) {
 	if api.whisper == nil {
-		return 0, whisperOffLineErr
+		return "", whisperOffLineErr
 	}
 
 	filter := Filter{
@@ -168,28 +168,28 @@ func (api *PublicWhisperAPI) NewFilter(args WhisperFilterArgs) (uint32, error) {
 	}
 	filter.Topics = append(filter.Topics, args.Topics...)
 
-	if len(args.Topics) == 0 {
+	if len(args.Topics) == 0 && len(args.KeyName) != 0 {
 		info := "NewFilter: at least one topic must be specified"
 		glog.V(logger.Error).Infof(info)
-		return 0, errors.New(info)
+		return "", errors.New(info)
 	}
 
 	if len(args.KeyName) != 0 && len(filter.KeySym) == 0 {
 		info := "NewFilter: key was not found by name: " + args.KeyName
 		glog.V(logger.Error).Infof(info)
-		return 0, errors.New(info)
+		return "", errors.New(info)
 	}
 
 	if len(args.To) == 0 && len(filter.KeySym) == 0 {
 		info := "NewFilter: filter must contain either symmetric or asymmetric key"
 		glog.V(logger.Error).Infof(info)
-		return 0, errors.New(info)
+		return "", errors.New(info)
 	}
 
 	if len(args.To) != 0 && len(filter.KeySym) != 0 {
 		info := "NewFilter: filter must not contain both symmetric and asymmetric key"
 		glog.V(logger.Error).Infof(info)
-		return 0, errors.New(info)
+		return "", errors.New(info)
 	}
 
 	if len(args.To) > 0 {
@@ -197,13 +197,13 @@ func (api *PublicWhisperAPI) NewFilter(args WhisperFilterArgs) (uint32, error) {
 		if !ValidatePublicKey(dst) {
 			info := "NewFilter: Invalid 'To' address"
 			glog.V(logger.Error).Infof(info)
-			return 0, errors.New(info)
+			return "", errors.New(info)
 		}
 		filter.KeyAsym = api.whisper.GetIdentity(string(args.To))
 		if filter.KeyAsym == nil {
 			info := "NewFilter: non-existent identity provided"
 			glog.V(logger.Error).Infof(info)
-			return 0, errors.New(info)
+			return "", errors.New(info)
 		}
 	}
 
@@ -211,21 +211,20 @@ func (api *PublicWhisperAPI) NewFilter(args WhisperFilterArgs) (uint32, error) {
 		if !ValidatePublicKey(filter.Src) {
 			info := "NewFilter: Invalid 'From' address"
 			glog.V(logger.Error).Infof(info)
-			return 0, errors.New(info)
+			return "", errors.New(info)
 		}
 	}
 
-	id := api.whisper.Watch(&filter)
-	return id, nil
+	return api.whisper.Watch(&filter)
 }
 
 // UninstallFilter disables and removes an existing filter.
-func (api *PublicWhisperAPI) UninstallFilter(filterId uint32) {
+func (api *PublicWhisperAPI) UninstallFilter(filterId string) {
 	api.whisper.Unwatch(filterId)
 }
 
 // GetFilterChanges retrieves all the new messages matched by a filter since the last retrieval.
-func (api *PublicWhisperAPI) GetFilterChanges(filterId uint32) []WhisperMessage {
+func (api *PublicWhisperAPI) GetFilterChanges(filterId string) []*WhisperMessage {
 	f := api.whisper.GetFilter(filterId)
 	if f != nil {
 		newMail := f.Retrieve()
@@ -235,14 +234,14 @@ func (api *PublicWhisperAPI) GetFilterChanges(filterId uint32) []WhisperMessage
 }
 
 // GetMessages retrieves all the known messages that match a specific filter.
-func (api *PublicWhisperAPI) GetMessages(filterId uint32) []WhisperMessage {
+func (api *PublicWhisperAPI) GetMessages(filterId string) []*WhisperMessage {
 	all := api.whisper.Messages(filterId)
 	return toWhisperMessages(all)
 }
 
 // toWhisperMessages converts a Whisper message to a RPC whisper message.
-func toWhisperMessages(messages []*ReceivedMessage) []WhisperMessage {
-	msgs := make([]WhisperMessage, len(messages))
+func toWhisperMessages(messages []*ReceivedMessage) []*WhisperMessage {
+	msgs := make([]*WhisperMessage, len(messages))
 	for i, msg := range messages {
 		msgs[i] = NewWhisperMessage(msg)
 	}
@@ -282,8 +281,8 @@ func (api *PublicWhisperAPI) Post(args PostArgs) error {
 	}
 
 	filter := api.whisper.GetFilter(args.FilterID)
-	if filter == nil && args.FilterID > 0 {
-		info := fmt.Sprintf("Post: wrong filter id %d", args.FilterID)
+	if filter == nil && len(args.FilterID) > 0 {
+		info := fmt.Sprintf("Post: wrong filter id %s", args.FilterID)
 		glog.V(logger.Error).Infof(info)
 		return errors.New(info)
 	}
@@ -299,7 +298,7 @@ func (api *PublicWhisperAPI) Post(args PostArgs) error {
 		if (params.Topic == TopicType{}) {
 			sz := len(filter.Topics)
 			if sz < 1 {
-				info := fmt.Sprintf("Post: no topics in filter # %d", args.FilterID)
+				info := fmt.Sprintf("Post: no topics in filter # %s", args.FilterID)
 				glog.V(logger.Error).Infof(info)
 				return errors.New(info)
 			} else if sz == 1 {
@@ -374,17 +373,17 @@ type PostArgs struct {
 	Payload  hexutil.Bytes `json:"payload"`
 	WorkTime uint32        `json:"worktime"`
 	PoW      float64       `json:"pow"`
-	FilterID uint32        `json:"filterID"`
+	FilterID string        `json:"filterID"`
 	PeerID   hexutil.Bytes `json:"peerID"`
 }
 
 type WhisperFilterArgs struct {
-	To        string
-	From      string
-	KeyName   string
-	PoW       float64
-	Topics    []TopicType
-	AcceptP2P bool
+	To        string      `json:"to"`
+	From      string      `json:"from"`
+	KeyName   string      `json:"keyname"`
+	PoW       float64     `json:"pow"`
+	Topics    []TopicType `json:"topics"`
+	AcceptP2P bool        `json:"p2p"`
 }
 
 // UnmarshalJSON implements the json.Unmarshaler interface, invoked to convert a
@@ -397,7 +396,7 @@ func (args *WhisperFilterArgs) UnmarshalJSON(b []byte) (err error) {
 		KeyName   string        `json:"keyname"`
 		PoW       float64       `json:"pow"`
 		Topics    []interface{} `json:"topics"`
-		AcceptP2P bool          `json:"acceptP2P"`
+		AcceptP2P bool          `json:"p2p"`
 	}
 	if err := json.Unmarshal(b, &obj); err != nil {
 		return err
@@ -438,6 +437,7 @@ func (args *WhisperFilterArgs) UnmarshalJSON(b []byte) (err error) {
 
 // WhisperMessage is the RPC representation of a whisper message.
 type WhisperMessage struct {
+	Topic   string  `json:"topic"`
 	Payload string  `json:"payload"`
 	Padding string  `json:"padding"`
 	From    string  `json:"from"`
@@ -449,15 +449,22 @@ type WhisperMessage struct {
 }
 
 // NewWhisperMessage converts an internal message into an API version.
-func NewWhisperMessage(message *ReceivedMessage) WhisperMessage {
-	return WhisperMessage{
+func NewWhisperMessage(message *ReceivedMessage) *WhisperMessage {
+	msg := WhisperMessage{
+		Topic:   common.ToHex(message.Topic[:]),
 		Payload: common.ToHex(message.Payload),
 		Padding: common.ToHex(message.Padding),
-		From:    common.ToHex(crypto.FromECDSAPub(message.SigToPubKey())),
-		To:      common.ToHex(crypto.FromECDSAPub(message.Dst)),
 		Sent:    message.Sent,
 		TTL:     message.TTL,
 		PoW:     message.PoW,
 		Hash:    common.ToHex(message.EnvelopeHash.Bytes()),
 	}
+
+	if message.Dst != nil {
+		msg.To = common.ToHex(crypto.FromECDSAPub(message.Dst))
+	}
+	if isMessageSigned(message.Raw[0]) {
+		msg.From = common.ToHex(crypto.FromECDSAPub(message.SigToPubKey()))
+	}
+	return &msg
 }
diff --git a/whisper/whisperv5/api_test.go b/whisper/whisperv5/api_test.go
index f7deab39c4985358101a38de31e51f47eb635419..ea0a2c40bcb870e740f1f1ed36fec50fbb742af4 100644
--- a/whisper/whisperv5/api_test.go
+++ b/whisper/whisperv5/api_test.go
@@ -42,7 +42,7 @@ func TestBasic(t *testing.T) {
 		t.Fatalf("wrong version: %d.", ver)
 	}
 
-	mail := api.GetFilterChanges(1)
+	mail := api.GetFilterChanges("non-existent-id")
 	if len(mail) != 0 {
 		t.Fatalf("failed GetFilterChanges: premature result")
 	}
@@ -152,7 +152,7 @@ func TestUnmarshalFilterArgs(t *testing.T) {
 	"keyname":"testname",
 	"pow":2.34,
 	"topics":["0x00000000", "0x007f80ff", "0xff807f00", "0xf26e7779"],
-	"acceptP2P":true
+	"p2p":true
 	}`)
 
 	var f WhisperFilterArgs
@@ -212,8 +212,8 @@ func TestUnmarshalPostArgs(t *testing.T) {
 	"payload":"0x7061796C6F61642073686F756C642062652070736575646F72616E646F6D",
 	"worktime":777,
 	"pow":3.1416,
-	"filterID":64,
-	"peerID":"0xf26e7779"
+	"filterid":"test-filter-id",
+	"peerid":"0xf26e7779"
 	}`)
 
 	var a PostArgs
@@ -249,15 +249,15 @@ func TestUnmarshalPostArgs(t *testing.T) {
 	if a.PoW != 3.1416 {
 		t.Fatalf("wrong pow: %f.", a.PoW)
 	}
-	if a.FilterID != 64 {
-		t.Fatalf("wrong FilterID: %d.", a.FilterID)
+	if a.FilterID != "test-filter-id" {
+		t.Fatalf("wrong FilterID: %s.", a.FilterID)
 	}
 	if !bytes.Equal(a.PeerID[:], a.Topic[:]) {
 		t.Fatalf("wrong PeerID: %x.", a.PeerID)
 	}
 }
 
-func waitForMessage(api *PublicWhisperAPI, id uint32, target int) bool {
+func waitForMessage(api *PublicWhisperAPI, id string, target int) bool {
 	for i := 0; i < 64; i++ {
 		all := api.GetMessages(id)
 		if len(all) >= target {
diff --git a/whisper/whisperv5/benchmarks_test.go b/whisper/whisperv5/benchmarks_test.go
index f2eef3c4715005fdfd9f9de10a43ea4faceab889..417b2881b810f470fcc4998a239d9aae54572fee 100644
--- a/whisper/whisperv5/benchmarks_test.go
+++ b/whisper/whisperv5/benchmarks_test.go
@@ -34,7 +34,6 @@ func BenchmarkDeriveOneTimeKey(b *testing.B) {
 	}
 }
 
-//func TestEncryptionSym(b *testing.T) {
 func BenchmarkEncryptionSym(b *testing.B) {
 	InitSingleTest()
 
@@ -181,3 +180,33 @@ func BenchmarkDecryptionAsymInvalid(b *testing.B) {
 		}
 	}
 }
+
+func increment(x []byte) {
+	for i := 0; i < len(x); i++ {
+		x[i]++
+		if x[i] != 0 {
+			break
+		}
+	}
+}
+
+func BenchmarkPoW(b *testing.B) {
+	InitSingleTest()
+
+	params, err := generateMessageParams()
+	if err != nil {
+		b.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
+	}
+	params.Payload = make([]byte, 32)
+	params.PoW = 10.0
+	params.TTL = 1
+
+	for i := 0; i < b.N; i++ {
+		increment(params.Payload)
+		msg := NewSentMessage(params)
+		_, err := msg.Wrap(params)
+		if err != nil {
+			b.Fatalf("failed Wrap with seed %d: %s.", seed, err)
+		}
+	}
+}
diff --git a/whisper/whisperv5/doc.go b/whisper/whisperv5/doc.go
index b82a82468bfe491c90b146f9470fafe31cc3a305..70c7008a73c4223496250ae36d0aa73abb62c086 100644
--- a/whisper/whisperv5/doc.go
+++ b/whisper/whisperv5/doc.go
@@ -55,8 +55,8 @@ const (
 	saltLength        = 12
 	AESNonceMaxLength = 12
 
-	MaxMessageLength = 0xFFFF // todo: remove this restriction after testing. this should be regulated by PoW.
-	MinimumPoW       = 1.0    // todo: review after testing.
+	MaxMessageLength = 0x0FFFFF // todo: remove this restriction after testing. this should be regulated by PoW.
+	MinimumPoW       = 10.0     // todo: review after testing.
 
 	padSizeLimitLower = 128 // it can not be less - we don't want to reveal the absence of signature
 	padSizeLimitUpper = 256 // just an arbitrary number, could be changed without losing compatibility
diff --git a/whisper/whisperv5/envelope.go b/whisper/whisperv5/envelope.go
index 1b976705d4240280c7b2a3f6f30dcb32a7f048ce..8812ae207f42177c169827df4efbcc2e569a7146 100644
--- a/whisper/whisperv5/envelope.go
+++ b/whisper/whisperv5/envelope.go
@@ -116,12 +116,16 @@ func (e *Envelope) Seal(options *MessageParams) error {
 	}
 
 	if target > 0 && bestBit < target {
-		return errors.New("Failed to reach the PoW target")
+		return errors.New("Failed to reach the PoW target, insufficient work time")
 	}
 
 	return nil
 }
 
+func (e *Envelope) size() int {
+	return len(e.Data) + len(e.Version) + len(e.AESNonce) + len(e.Salt) + 20
+}
+
 func (e *Envelope) PoW() float64 {
 	if e.pow == 0 {
 		e.calculatePoW(0)
@@ -137,14 +141,14 @@ func (e *Envelope) calculatePoW(diff uint32) {
 	h = crypto.Keccak256(buf)
 	firstBit := common.FirstBitSet(common.BigD(h))
 	x := math.Pow(2, float64(firstBit))
-	x /= float64(len(e.Data)) // we only count e.Data, other variable-sized members are checked in Whisper.add()
+	x /= float64(e.size())
 	x /= float64(e.TTL + diff)
 	e.pow = x
 }
 
 func (e *Envelope) powToFirstBit(pow float64) int {
 	x := pow
-	x *= float64(len(e.Data))
+	x *= float64(e.size())
 	x *= float64(e.TTL)
 	bits := math.Log2(x)
 	bits = math.Ceil(bits)
diff --git a/whisper/whisperv5/filter.go b/whisper/whisperv5/filter.go
index a386aa164684a3cb5601e86769b8e6b7b0382818..832ebe3f6b0962af2e912bcef0431b464cb793ad 100644
--- a/whisper/whisperv5/filter.go
+++ b/whisper/whisperv5/filter.go
@@ -18,6 +18,8 @@ package whisperv5
 
 import (
 	"crypto/ecdsa"
+	crand "crypto/rand"
+	"fmt"
 	"sync"
 
 	"github.com/ethereum/go-ethereum/common"
@@ -39,20 +41,41 @@ type Filter struct {
 }
 
 type Filters struct {
-	id       uint32 // can contain any value except zero
-	watchers map[uint32]*Filter
+	watchers map[string]*Filter
 	whisper  *Whisper
 	mutex    sync.RWMutex
 }
 
 func NewFilters(w *Whisper) *Filters {
 	return &Filters{
-		watchers: make(map[uint32]*Filter),
+		watchers: make(map[string]*Filter),
 		whisper:  w,
 	}
 }
 
-func (fs *Filters) Install(watcher *Filter) uint32 {
+func (fs *Filters) generateRandomID() (id string, err error) {
+	buf := make([]byte, 20)
+	for i := 0; i < 3; i++ {
+		_, err = crand.Read(buf)
+		if err != nil {
+			continue
+		}
+		if !validateSymmetricKey(buf) {
+			err = fmt.Errorf("error in generateRandomID: crypto/rand failed to generate random data")
+			continue
+		}
+		id = common.Bytes2Hex(buf)
+		if fs.watchers[id] != nil {
+			err = fmt.Errorf("error in generateRandomID: generated same ID twice")
+			continue
+		}
+		return id, err
+	}
+
+	return "", err
+}
+
+func (fs *Filters) Install(watcher *Filter) (string, error) {
 	if watcher.Messages == nil {
 		watcher.Messages = make(map[common.Hash]*ReceivedMessage)
 	}
@@ -60,21 +83,23 @@ func (fs *Filters) Install(watcher *Filter) uint32 {
 	fs.mutex.Lock()
 	defer fs.mutex.Unlock()
 
-	fs.id++
-	fs.watchers[fs.id] = watcher
-	return fs.id
+	id, err := fs.generateRandomID()
+	if err == nil {
+		fs.watchers[id] = watcher
+	}
+	return id, err
 }
 
-func (fs *Filters) Uninstall(id uint32) {
+func (fs *Filters) Uninstall(id string) {
 	fs.mutex.Lock()
 	defer fs.mutex.Unlock()
 	delete(fs.watchers, id)
 }
 
-func (fs *Filters) Get(i uint32) *Filter {
+func (fs *Filters) Get(id string) *Filter {
 	fs.mutex.RLock()
 	defer fs.mutex.RUnlock()
-	return fs.watchers[i]
+	return fs.watchers[id]
 }
 
 func (fs *Filters) NotifyWatchers(env *Envelope, p2pMessage bool) {
diff --git a/whisper/whisperv5/filter_test.go b/whisper/whisperv5/filter_test.go
index 5bf607cccf76e7a44e84107f61ac1c47ef8e76f4..d69fb40dbfee43e084e39a501f0ad224864e81f8 100644
--- a/whisper/whisperv5/filter_test.go
+++ b/whisper/whisperv5/filter_test.go
@@ -43,7 +43,7 @@ func InitDebugTest(i int64) {
 
 type FilterTestCase struct {
 	f      *Filter
-	id     uint32
+	id     string
 	alive  bool
 	msgCnt int
 }
@@ -100,14 +100,17 @@ func TestInstallFilters(t *testing.T) {
 	filters := NewFilters(w)
 	tst := generateTestCases(t, SizeTestFilters)
 
-	var j uint32
+	var err error
+	var j string
 	for i := 0; i < SizeTestFilters; i++ {
-		j = filters.Install(tst[i].f)
+		j, err = filters.Install(tst[i].f)
+		if err != nil {
+			t.Fatalf("seed %d: failed to install filter: %s", seed, err)
+		}
 		tst[i].id = j
-	}
-
-	if j < SizeTestFilters-1 {
-		t.Fatalf("seed %d: wrong index %d", seed, j)
+		if len(j) != 40 {
+			t.Fatalf("seed %d: wrong filter id size [%d]", seed, len(j))
+		}
 	}
 
 	for _, testCase := range tst {
@@ -519,17 +522,25 @@ func TestWatchers(t *testing.T) {
 	var i int
 	var j uint32
 	var e *Envelope
+	var x, firstID string
+	var err error
 
 	w := New()
 	filters := NewFilters(w)
 	tst := generateTestCases(t, NumFilters)
 	for i = 0; i < NumFilters; i++ {
 		tst[i].f.Src = nil
-		j = filters.Install(tst[i].f)
-		tst[i].id = j
+		x, err = filters.Install(tst[i].f)
+		if err != nil {
+			t.Fatalf("failed to install filter with seed %d: %s.", seed, err)
+		}
+		tst[i].id = x
+		if len(firstID) == 0 {
+			firstID = x
+		}
 	}
 
-	last := j
+	lastID := x
 
 	var envelopes [NumMessages]*Envelope
 	for i = 0; i < NumMessages; i++ {
@@ -571,9 +582,9 @@ func TestWatchers(t *testing.T) {
 	// another round with a cloned filter
 
 	clone := cloneFilter(tst[0].f)
-	filters.Uninstall(last)
+	filters.Uninstall(lastID)
 	total = 0
-	last = NumFilters - 1
+	last := NumFilters - 1
 	tst[last].f = clone
 	filters.Install(clone)
 	for i = 0; i < NumFilters; i++ {
@@ -640,7 +651,7 @@ func TestWatchers(t *testing.T) {
 		t.Fatalf("failed with seed %d: total: got %d, want 0.", seed, total)
 	}
 
-	f := filters.Get(1)
+	f := filters.Get(firstID)
 	if f == nil {
 		t.Fatalf("failed to get the filter with seed %d.", seed)
 	}
diff --git a/whisper/whisperv5/peer_test.go b/whisper/whisperv5/peer_test.go
index cc98ba2d67e05f9addf1963c05c8a7027b48e211..cce2c92ba6b2ff3074f3d4f9c868d477cc553532 100644
--- a/whisper/whisperv5/peer_test.go
+++ b/whisper/whisperv5/peer_test.go
@@ -79,7 +79,7 @@ type TestNode struct {
 	shh     *Whisper
 	id      *ecdsa.PrivateKey
 	server  *p2p.Server
-	filerId uint32
+	filerId string
 }
 
 var result TestData
@@ -122,7 +122,10 @@ func initialize(t *testing.T) {
 		topics := make([]TopicType, 0)
 		topics = append(topics, sharedTopic)
 		f := Filter{KeySym: sharedKey, Topics: topics}
-		node.filerId = node.shh.Watch(&f)
+		node.filerId, err = node.shh.Watch(&f)
+		if err != nil {
+			t.Fatalf("failed to install the filter: %s.", err)
+		}
 		node.id, err = crypto.HexToECDSA(keys[i])
 		if err != nil {
 			t.Fatalf("failed convert the key: %s.", keys[i])
@@ -187,7 +190,7 @@ func checkPropagation(t *testing.T) {
 		for i := 0; i < NumNodes; i++ {
 			f := nodes[i].shh.GetFilter(nodes[i].filerId)
 			if f == nil {
-				t.Fatalf("failed to get filterId %d from node %d.", nodes[i].filerId, i)
+				t.Fatalf("failed to get filterId %s from node %d.", nodes[i].filerId, i)
 			}
 
 			mail := f.Retrieve()
diff --git a/whisper/whisperv5/whisper.go b/whisper/whisperv5/whisper.go
index a027fd84b3f4cc70b0a8bceac229d12e4f14df06..2a6ff5f409c527896256b2617ad3d39d1083cef9 100644
--- a/whisper/whisperv5/whisper.go
+++ b/whisper/whisperv5/whisper.go
@@ -272,16 +272,16 @@ func (w *Whisper) GetSymKey(name string) []byte {
 
 // Watch installs a new message handler to run in case a matching packet arrives
 // from the whisper network.
-func (w *Whisper) Watch(f *Filter) uint32 {
+func (w *Whisper) Watch(f *Filter) (string, error) {
 	return w.filters.Install(f)
 }
 
-func (w *Whisper) GetFilter(id uint32) *Filter {
+func (w *Whisper) GetFilter(id string) *Filter {
 	return w.filters.Get(id)
 }
 
 // Unwatch removes an installed message handler.
-func (w *Whisper) Unwatch(id uint32) {
+func (w *Whisper) Unwatch(id string) {
 	w.filters.Uninstall(id)
 }
 
@@ -575,7 +575,7 @@ func (w *Whisper) Envelopes() []*Envelope {
 }
 
 // Messages retrieves all the decrypted messages matching a filter id.
-func (w *Whisper) Messages(id uint32) []*ReceivedMessage {
+func (w *Whisper) Messages(id string) []*ReceivedMessage {
 	result := make([]*ReceivedMessage, 0)
 	w.poolMu.RLock()
 	defer w.poolMu.RUnlock()
diff --git a/whisper/whisperv5/whisper_test.go b/whisper/whisperv5/whisper_test.go
index c2ae35a3ee761c67eee43d79fc88d83f611555a1..312dacfc4bfb65cb319f257c29f8e4840f6f2dfe 100644
--- a/whisper/whisperv5/whisper_test.go
+++ b/whisper/whisperv5/whisper_test.go
@@ -44,7 +44,7 @@ func TestWhisperBasic(t *testing.T) {
 	if uint64(w.Version()) != ProtocolVersion {
 		t.Fatalf("failed whisper Version: %v.", shh.Version)
 	}
-	if w.GetFilter(0) != nil {
+	if w.GetFilter("non-existent") != nil {
 		t.Fatalf("failed GetFilter.")
 	}
 
@@ -69,7 +69,7 @@ func TestWhisperBasic(t *testing.T) {
 	if len(mail) != 0 {
 		t.Fatalf("failed w.Envelopes().")
 	}
-	m := w.Messages(0)
+	m := w.Messages("non-existent")
 	if len(m) != 0 {
 		t.Fatalf("failed w.Messages.")
 	}