diff --git a/helios/crypto/elgamal.py b/helios/crypto/elgamal.py
index 95e8e28de3d596a859f3c576880b6f341c5acf94..8b3b04794cef1853dbebc256d2fb625d4b768323 100644
--- a/helios/crypto/elgamal.py
+++ b/helios/crypto/elgamal.py
@@ -71,7 +71,7 @@ class KeyPair(object):
       self.sk.x = Utils.random_mpz_lt(p)
       self.pk.y = pow(g, self.sk.x, p)
       
-      self.sk.pk = self.pk
+      self.sk.public_key = self.pk
 
 class PublicKey:
     def __init__(self):
@@ -148,11 +148,11 @@ class PublicKey:
 class SecretKey:
     def __init__(self):
         self.x = None
-        self.pk = None
+        self.public_key = None
 
     @property
-    def public_key(self):
-        return self.pk
+    def pk(self):
+        return self.public_key
 
     def decryption_factor(self, ciphertext):
         """
diff --git a/helios/datatypes/legacy.py b/helios/datatypes/legacy.py
index 7ab6612e0c5ab0319d67fe592f01b152e3f23e2f..c2a89dfefbcfcbbf285fc903af7cab769c8ec40a 100644
--- a/helios/datatypes/legacy.py
+++ b/helios/datatypes/legacy.py
@@ -194,6 +194,10 @@ class Questions(LegacyObject):
 
 class Tally(LegacyObject):
     WRAPPED_OBJ_CLASS = homomorphic.Tally
+    FIELDS = ['tally', 'num_tallied']
+    STRUCTURED_FIELDS = {
+        'tally': arrayOf(arrayOf('legacy/EGCiphertext'))}
+
 
 class Eligibility(LegacyObject):
     pass
diff --git a/helios/models.py b/helios/models.py
index ea93b4829c9db793daed0391ffb46195fa29fdb9..415132824b7d25cda174dcd509feb3f2db7999e7 100644
--- a/helios/models.py
+++ b/helios/models.py
@@ -19,6 +19,7 @@ import helios
 
 from helios import datatypes
 
+
 # useful stuff in auth
 from auth.models import User, AUTH_SYSTEMS
 from auth.jsonfield import JSONField
@@ -443,7 +444,9 @@ class Election(HeliosModel):
     return helios.get_election_url(self)
 
   def init_tally(self):
-    return Tally(election=self)
+    # FIXME: create the right kind of tally
+    from helios.workflows import homomorphic
+    return homomorphic.Tally(election=self)
         
   @property
   def registration_status_pretty(self):
diff --git a/helios/tasks.py b/helios/tasks.py
index 461150f96992ab226f202193b9f5cc444e53e0d2..43ca5f65d652fed41c33b642d5cd634d94dda2b4 100644
--- a/helios/tasks.py
+++ b/helios/tasks.py
@@ -87,7 +87,7 @@ def single_voter_notify(voter_uuid, notification_template, extra_vars={}):
 def election_compute_tally(election_id):
     election = Election.objects.get(id = election_id)
     election.compute_tally()
-    
+
     election_notify_admin.delay(election_id = election_id,
                                 subject = "encrypted tally computed",
                                 body = """
@@ -97,7 +97,6 @@ The encrypted tally for election %s has been computed.
 Helios
 """ % election.name)
                                 
-    
     if election.has_helios_trustee():
         tally_helios_decrypt.delay(election_id = election.id)
 
diff --git a/helios/tests.py b/helios/tests.py
index 464c1839e5c903d9db996e41042973364e14736a..203ff001bd6a5d1597f4c71890ded0499a9d5772 100644
--- a/helios/tests.py
+++ b/helios/tests.py
@@ -455,9 +455,23 @@ class ElectionBlackboxTests(TestCase):
         self.assertRedirects(response, "%s/helios/elections/%s/cast_done" % (settings.URL_HOST, election_id))
 
         # encrypted tally
+        response = self.client.post("/helios/elections/%s/compute_tally" % election_id, {
+                "csrf_token" : self.client.session['csrf_token']                
+                })
+        self.assertRedirects(response, "/helios/elections/%s/view" % election_id)
 
         # should trigger helios decryption automatically
+        self.assertNotEquals(models.Election.objects.get(uuid=election_id).get_helios_trustee().decryption_proofs, None)
 
         # combine decryptions
+        response = self.client.post("/helios/elections/%s/combine_decryptions" % election_id, {
+                "csrf_token" : self.client.session['csrf_token'],
+                "subject" : "tally subject",
+                "body" : "tally body",
+                "send_to" : "all"
+                })
+        self.assertRedirects(response, "/helios/elections/%s/view" % election_id)
 
         # check that tally matches
+        response = self.client.get("/helios/elections/%s/result" % election_id)
+        self.assertEquals(utils.from_json(response.content), [0,1])
diff --git a/helios/workflows/homomorphic.py b/helios/workflows/homomorphic.py
index 4e143520e2e9973b9fe0cf2f486f7fca848b8bc2..7eaea4b614edd37d1cb61cd8256c13089fb8b6b2 100644
--- a/helios/workflows/homomorphic.py
+++ b/helios/workflows/homomorphic.py
@@ -325,25 +325,27 @@ class Tally(WorkflowObject):
   """
   
   def __init__(self, *args, **kwargs):
-    super(Tally, self).__init__(*args, **kwargs)
-
-    self.election = kwargs.get('election',None)
+    super(Tally, self).__init__()
+    
+    election = kwargs.get('election',None)
     self.tally = None
     self.num_tallied = 0    
 
-    if self.election:
-      self.init_election(self.election)
+    if election:
+      self.init_election(election)
+      self.tally = [[0 for a in q['answers']] for q in self.questions]
     else:
       self.questions = None
       self.public_key = None
+      self.tally = None
 
   def init_election(self, election):
     """
     given the election, initialize some params
     """
+    self.election = election
     self.questions = election.questions
     self.public_key = election.public_key
-    self.tally = [[0 for a in q['answers']] for q in self.questions]
     
   def add_vote_batch(self, encrypted_votes, verify_p=True):
     """
@@ -393,8 +395,8 @@ class Tally(WorkflowObject):
 
         # look up appropriate discrete log
         # this is the string conversion
-        question_factors.append(str(dec_factor))
-        question_proof.append(proof.toJSONDict())
+        question_factors.append(dec_factor)
+        question_proof.append(proof)
         
       decryption_factors.append(question_factors)
       decryption_proof.append(question_proof)