diff --git a/helios/crypto/electionalgs.py b/helios/crypto/electionalgs.py
index 1f7593b14031ffb397352dcdf52a721e984f52d6..43e3357f3c64a151aad2258ed9368c554eb0a9c5 100644
--- a/helios/crypto/electionalgs.py
+++ b/helios/crypto/electionalgs.py
@@ -6,6 +6,7 @@ Ben Adida
 """
 import datetime
 import uuid
+import logging
 
 from helios.utils import to_json
 from . import algs
@@ -322,17 +323,28 @@ class EncryptedVote(HeliosObject):
     FIELDS = ['encrypted_answers', 'election_hash', 'election_uuid']
 
     def verify(self, election):
-        # right number of answers
-        if len(self.encrypted_answers) != len(election.questions):
+        # correct number of answers
+        # noinspection PyUnresolvedReferences
+        n_answers = len(self.encrypted_answers) if self.encrypted_answers is not None else 0
+        n_questions = len(election.questions) if election.questions is not None else 0
+        if n_answers != n_questions:
+            logging.error(f"Incorrect number of answers ({n_answers}) vs questions ({n_questions})")
             return False
 
         # check hash
-        if self.election_hash != election.hash:
-            # print "%s / %s " % (self.election_hash, election.hash)
+        # noinspection PyUnresolvedReferences
+        our_election_hash = self.election_hash if isinstance(self.election_hash, str) else self.election_hash.decode()
+        actual_election_hash = election.hash if isinstance(election.hash, str) else election.hash.decode()
+        if our_election_hash != actual_election_hash:
+            logging.error(f"Incorrect election_hash {our_election_hash} vs {actual_election_hash} ")
             return False
 
         # check ID
-        if self.election_uuid != election.uuid:
+        # noinspection PyUnresolvedReferences
+        our_election_uuid = self.election_uuid if isinstance(self.election_uuid, str) else self.election_uuid.decode()
+        actual_election_uuid = election.uuid if isinstance(election.uuid, str) else election.uuid.decode()
+        if our_election_uuid != actual_election_uuid:
+            logging.error(f"Incorrect election_uuid {our_election_uuid} vs {actual_election_uuid} ")
             return False
 
         # check proofs on all of answers
diff --git a/helios/models.py b/helios/models.py
index 6babb106610d179f88a282555fb7079ccc2f236d..772559c9520dc94e0d4fce8ddcc930d14dc6a7e4 100644
--- a/helios/models.py
+++ b/helios/models.py
@@ -1044,9 +1044,9 @@ class CastVote(HeliosModel):
     """
     find a tiny version of the hash for a URL slug.
     """
-    safe_hash = self.vote_hash
-    for c in ['/', '+']:
-      safe_hash = safe_hash.replace(c,'')
+    safe_hash = self.vote_hash.decode() if isinstance(self.vote_hash, bytes) else self.vote_hash
+    for c in ['/', '+', '#']:
+      safe_hash = safe_hash.replace(c, '')
     
     length = 8
     while True:
diff --git a/helios/tests.py b/helios/tests.py
index 4b1423e78e05ce5589d2b4b0ca726ad06ad9f34d..5a5f601342d42dbfb8dc25e7df5065e7196d77a8 100644
--- a/helios/tests.py
+++ b/helios/tests.py
@@ -378,7 +378,11 @@ class WebTest(django_webtest.WebTest):
         else:
             t = response.content
 
-        assert text in str(t), "missing text %s" % text
+        if isinstance(text, bytes):
+            text = text.decode()
+        if isinstance(t, bytes):
+            t = t.decode()
+        assert text in t, "missing text %s" % text
 
 
 ##
diff --git a/helios/workflows/homomorphic.py b/helios/workflows/homomorphic.py
index 2f03f50ecc6375be6adcc966e350e5c4a1a84924..9c8039679bff10f9b0178fc16f1b27bafdbc16be 100644
--- a/helios/workflows/homomorphic.py
+++ b/helios/workflows/homomorphic.py
@@ -6,6 +6,7 @@ Ben Adida
 reworked 2011-01-09
 """
 
+import logging
 from helios.crypto import algs
 from . import WorkflowObject
 
@@ -160,7 +161,7 @@ class EncryptedVote(WorkflowObject):
   An encrypted ballot
   """
   def __init__(self):
-    self.encrypted_answers = None
+    self.encrypted_answers = []
 
   @property
   def datatype(self):
@@ -176,19 +177,30 @@ class EncryptedVote(WorkflowObject):
   answers = property(_answers_get, _answers_set)
 
   def verify(self, election):
-    # right number of answers
-    if len(self.encrypted_answers) != len(election.questions):
+    # correct number of answers
+    # noinspection PyUnresolvedReferences
+    n_answers = len(self.encrypted_answers) if self.encrypted_answers is not None else 0
+    n_questions = len(election.questions) if election.questions is not None else 0
+    if n_answers != n_questions:
+      logging.error(f"Incorrect number of answers ({n_answers}) vs questions ({n_questions})")
       return False
-    
+
     # check hash
-    if self.election_hash != election.hash:
-      # print "%s / %s " % (self.election_hash, election.hash)
+    # noinspection PyUnresolvedReferences
+    our_election_hash = self.election_hash if isinstance(self.election_hash, str) else self.election_hash.decode()
+    actual_election_hash = election.hash if isinstance(election.hash, str) else election.hash.decode()
+    if our_election_hash != actual_election_hash:
+      logging.error(f"Incorrect election_hash {our_election_hash} vs {actual_election_hash} ")
       return False
-      
+
     # check ID
-    if self.election_uuid != election.uuid:
+    # noinspection PyUnresolvedReferences
+    our_election_uuid = self.election_uuid if isinstance(self.election_uuid, str) else self.election_uuid.decode()
+    actual_election_uuid = election.uuid if isinstance(election.uuid, str) else election.uuid.decode()
+    if our_election_uuid != actual_election_uuid:
+      logging.error(f"Incorrect election_uuid {our_election_uuid} vs {actual_election_uuid} ")
       return False
-      
+
     # check proofs on all of answers
     for question_num in range(len(election.questions)):
       ea = self.encrypted_answers[question_num]