예제 #1
0
 def __init__(self,
              k,
              t,
              nodeid,
              pk,
              pk2,
              participantids,
              group,
              symflag,
              send_function,
              recv_function,
              sid=1,
              reconstruction=True,
              seed=None):
     self.k = k
     self.t = t
     self.nodeid = nodeid
     self.pk = pk
     self.pk2 = pk2
     self.participantids = participantids
     self.group = group
     self.sid = sid
     self.seed = seed
     self.hashcommit = None
     self.commitments = None
     self.mywitnesses = None
     self.myhashwitness = None
     self.sendecho = None
     self.hashpoly = None
     self.share = None
     self.ready = False
     self.recshare = False
     self.finished = False
     self.poly = None
     self.polyhat = None
     self.hashpoly = None
     self.hashpolyhat = None
     self.secret = None
     self.pc = PolyCommitPed(t=t, pk=pk, group=group, symflag=symflag)
     self.pc2 = PolyCommitPed(t=k, pk=pk2, group=group, symflag=symflag)
     self.interpolatedpolyatzero = None
     self.interpolatedpolyhatatzero = None
     self.nosharereadymessages = {}
     self.readymessagequeue = {}
     self.verifiedreadymessages = {}
     self.recsharemessages = {}
     self.send_function = send_function
     #Technically these following two lists will contain hashes of commitments to hashes, as we only need to count how many duplicates we have
     self.echoedhashcommits = {}
     self.readyhashcommits = {}
     if reconstruction:
         while not self.finished:
             sender, msg = recv_function()
             self.receive_msg(msg)
     else:
         while not self.recshare:
             sender, msg = recv_function()
             self.receive_msg(msg)
예제 #2
0
 def __init__(self,
              k,
              t,
              secret,
              sk,
              pk,
              participantids,
              participantkeys,
              group,
              symflag,
              recv_function,
              send_function,
              sid=1,
              seed=None):
     # Random polynomial coefficients constructed in the form
     #[c       x        x^2        ...  x^t]
     # This is structured so that t+1 points are needed to reconstruct the polynomial
     ONE = group.random(ZR) * 0 + 1
     self.witnesses = {}
     self.t = t
     self.k = k
     self.group = group
     self.sid = sid
     self.poly = list(group.random(ZR, count=t + 1, seed=seed))
     self.poly[0] = ONE * secret
     self.polyhat = list(group.random(ZR, count=t + 1, seed=seed))
     self.participantids = participantids
     self.participantkeys = participantkeys
     self.sharedkeys = {}
     for j in participantids:
         self.sharedkeys[j] = self.participantkeys[j]**sk
     self.pc = PolyCommitPed(t=t, pk=pk, group=group, symflag=symflag)
     self.commitment = self.pc.commit(self.poly, self.polyhat)
     self.shares = {}
     self.encryptedshares = {}
     for j in participantids:
         self.shares[j] = f(self.poly, j)
         self.encryptedshares[j] = self.encrypt(self.sharedkeys[j],
                                                self.shares[j])
     #for j in participantids[:t+1]:
     for j in participantids:
         self.witnesses[j] = self.pc.create_witness(self.poly, self.polyhat,
                                                    j)
     message = {}
     message['commit'] = objectToBytes(self.commitment, self.group)
     message['witnesses'] = objectToBytes(self.witnesses, self.group)
     message['shares'] = self.encryptedshares
     message['dealer'] = k
     message['polyhat'] = objectToBytes(self.polyhat, self.group)
     reliablebroadcast(sid,
                       pid=k,
                       N=k + 1,
                       f=t,
                       leader=k,
                       input=str(message),
                       receive=recv_function,
                       send=send_function)
예제 #3
0
 def __init__(self,
              k,
              t,
              nodeid,
              sk,
              pk,
              participantids,
              participantkeys,
              group,
              symflag,
              send_function,
              recv_function,
              sid=1,
              reconstruction=True,
              seed=None):
     self.group = group
     self.send_function = send_function
     self.participantids = participantids
     #TODO: Code assumes ReliableBroadcast will complete before receiving other messages. This may not be the case
     message = ast.literal_eval(
         reliablebroadcast(sid,
                           nodeid,
                           k + 1,
                           f=t,
                           leader=k,
                           input=None,
                           receive=recv_function,
                           send=send_function))
     self.sharedkey = participantkeys[k]**sk
     self.finished = False
     self.okcount = 0
     self.output = None
     self.encshares = message['shares']
     self.pc = PolyCommitPed(t=t, pk=pk, group=group, symflag=symflag)
     self.share = self.decrypt(self.sharedkey, message['shares'][nodeid])
     self.commit = bytesToObject(message['commit'], self.group)
     self.witnesses = bytesToObject(message['witnesses'], self.group)
     fixedwitnesses = {}
     for key, value in self.witnesses.iteritems():
         fixedwitnesses[int(key)] = self.witnesses[key]
     self.witnesses = fixedwitnesses
     #interpolate the rest of the witnesses
     coords = []
     for key, value in self.witnesses.iteritems():
         coords.append([key, value])
     for i in range(t + 1, k):
         self.witnesses[i] = interpolate_at_x(coords, i, group)
     polyhat = bytesToObject(message['polyhat'], self.group)
     if self.pc.verify_eval(self.commit, nodeid, self.share,
                            f(polyhat, nodeid), self.witnesses[nodeid]):
         self.send_ok_msgs()
     else:
         self.send_implicate_msgs()
     while not self.finished:
         sender, msg = recv_function()
         #msg = ast.literal_eval(msg)
         if msg[0] == "ok":
             #TODO: Enforce one OK message per participant
             self.okcount += 1
             if self.okcount == 2 * t + 1:
                 self.output = self.share
                 print "Share:", self.share
             if self.okcount == k:
                 self.finished = True
         elif msg[0] == 'implicate':
             print "Wowzers!"
예제 #4
0
class HBVssRecipient:
    def __init__(self,
                 k,
                 t,
                 nodeid,
                 sk,
                 pk,
                 participantids,
                 participantkeys,
                 group,
                 symflag,
                 send_function,
                 recv_function,
                 sid=1,
                 reconstruction=True,
                 seed=None):
        self.group = group
        self.send_function = send_function
        self.participantids = participantids
        #TODO: Code assumes ReliableBroadcast will complete before receiving other messages. This may not be the case
        message = ast.literal_eval(
            reliablebroadcast(sid,
                              nodeid,
                              k + 1,
                              f=t,
                              leader=k,
                              input=None,
                              receive=recv_function,
                              send=send_function))
        self.sharedkey = participantkeys[k]**sk
        self.finished = False
        self.okcount = 0
        self.output = None
        self.encshares = message['shares']
        self.pc = PolyCommitPed(t=t, pk=pk, group=group, symflag=symflag)
        self.share = self.decrypt(self.sharedkey, message['shares'][nodeid])
        self.commit = bytesToObject(message['commit'], self.group)
        self.witnesses = bytesToObject(message['witnesses'], self.group)
        fixedwitnesses = {}
        for key, value in self.witnesses.iteritems():
            fixedwitnesses[int(key)] = self.witnesses[key]
        self.witnesses = fixedwitnesses
        #interpolate the rest of the witnesses
        coords = []
        for key, value in self.witnesses.iteritems():
            coords.append([key, value])
        for i in range(t + 1, k):
            self.witnesses[i] = interpolate_at_x(coords, i, group)
        polyhat = bytesToObject(message['polyhat'], self.group)
        if self.pc.verify_eval(self.commit, nodeid, self.share,
                               f(polyhat, nodeid), self.witnesses[nodeid]):
            self.send_ok_msgs()
        else:
            self.send_implicate_msgs()
        while not self.finished:
            sender, msg = recv_function()
            #msg = ast.literal_eval(msg)
            if msg[0] == "ok":
                #TODO: Enforce one OK message per participant
                self.okcount += 1
                if self.okcount == 2 * t + 1:
                    self.output = self.share
                    print "Share:", self.share
                if self.okcount == k:
                    self.finished = True
            elif msg[0] == 'implicate':
                print "Wowzers!"

    def decrypt(self, key, ciphertext):
        decryptor = AES.new(
            objectToBytes(key, self.group)[:32], AES.MODE_CBC,
            'This is an IV456')
        plaintext_bytes = decryptor.decrypt(ciphertext)
        #now we need to strip the padding off the end
        #if it's stupid but it works...
        elementsize = len(objectToBytes(self.group.random(ZR), self.group))
        paddingsize = (16 - elementsize % 16) % 16
        #print len(plaintext_bytes)
        #plaintext_bytes = plaintext_bytes[:len(plaintext_bytes) - paddingsize]
        #print len(plaintext_bytes)
        return bytesToObject(plaintext_bytes, self.group)

    def check_implication(key, implicatorid):
        share = self.decrypt(key, self.encshares[implicatorid])

    def send_ok_msgs(self):
        msg = []
        msg.append("ok")
        for j in self.participantids:
            self.send_function(j, msg)

    def send_implicate_msgs(self):
        msg = []
        msg.append("implicate")
        msg.append(self.sharedkey)
        for j in self.participantids:
            self.send_function(j, msg)
예제 #5
0
 def __init__(self,
              k,
              t,
              secret,
              pk,
              pk2,
              participantids,
              group,
              symflag,
              send_function,
              sid=1,
              seed=None):
     # Random polynomial coefficients constructed in the form
     #[c       x        x^2        ...  x^t
     # y       xy       x^2y       ...  x^t*y
     # y^2     x*y^2    x^2*y^2    ...  x^t*y^2
     # ...     ...      ...        ...  ...
     # y^t     x*y^t    x^2*y^t    ...  x^t*y^t]
     # This is structured so that t+1 points are needed to reconstruct the polynomial
     self.commitments = {}
     self.witnessvectors = {}
     self.projas = {}
     self.projahats = {}
     self.hashpoly = []
     self.t = t
     self.k = k
     self.group = group
     self.sid = sid
     self.a = [
         list(group.random(ZR, count=t + 1, seed=seed))
         for i in range(t + 1)
     ]
     self.ahat = [
         list(group.random(ZR, count=t + 1, seed=seed))
         for i in range(t + 1)
     ]
     self.participantids = participantids
     ZERO = group.random(ZR, seed=59) * 0
     ONE = group.random(ZR, seed=60) * 0 + 1
     #if type(secret) is list:
     if isinstance(secret, collections.Iterable):
         secretpoints = []
         for i in range(t + 1):
             if i < len(secret):
                 secretpoints.append([i, secret[i] * ONE])
             else:
                 secretpoints.append([i, ZERO])
         self.a[0] = interpolate_poly(secretpoints)
     else:
         self.a[0][0] = secret
     #make the polynomials symmetric
     for i in range(t + 1):
         for j in range(i):
             self.a[i][j] = self.a[j][i]
             self.ahat[i][j] = self.ahat[j][i]
     self.pc = PolyCommitPed(t=t, pk=pk, group=group, symflag=symflag)
     self.pc2 = PolyCommitPed(t=k, pk=pk2, group=group, symflag=symflag)
     time2 = os.times()
     for j in participantids + [0]:
         #Create lists of polynomial projections at different points for ease of use
         self.projas[j] = projf(self.a, j)
         self.projahats[j] = projf(self.ahat, j)
         #Create commitments for each of these projections
         self.commitments[j] = self.pc.commit(self.projas[j],
                                              self.projahats[j])
     print "Commitments and Projections Elapsed Time: " + str(
         os.times()[4] - time2[4])
     time2 = os.times()
     #A different loop is needed for witnesses so that all projections are already calculated
     for j in participantids:
         witnesses = {}
         for i in participantids:
             #for i in participantids[:t+1]:
             witnesses[i] = self.pc.create_witness(self.projas[i],
                                                   self.projahats[i], j)
             #witnesses[i].initPP()
         #coords = []
         #for key,value in witnesses.iteritems():
         #    coords.append([key, value])
         #witnesspoly = interpolate_poly(coords, self.group)
         #print witnesspoly
         #witnesspoly2 = interpolate_poly(coords)
         #print witnesspoly2
         #for i in participantids[t+1:]:
         #witnesses[i] = interpolate_commitment_at_x(coords, i, self.group)
         #witnesses[i] = interpolate_at_x(coords, i, self.group)
         #    witnesses[i] = f(witnesspoly, i)
         #print witnesses[participantids[7]]
         #print interpolate_at_x(coords, participantids[7], self.group)
         #print f(witnesspoly,participantids[0])
         self.witnessvectors[j] = witnesses
     print "Witnesses Elapsed Time: " + str(os.times()[4] - time2[4])
     time2 = os.times()
     #Create the polynomial of hashes of commitments and commit to it
     hashpolypoints = []
     for i in participantids + [0]:
         #not sure if there's an agreed upon way to hash a pairing element to something outside the group
         #so I SHA256 hash the bitstring representation of the element
         hashpolypoints.append([
             ONE * i,
             hexstring_to_ZR(
                 hashlib.sha256(str(self.commitments[i])).hexdigest(),
                 group)
         ])
     self.hashpoly = interpolate_poly(hashpolypoints)
     self.hashpolyhat = list(group.random(ZR, count=k + 1, seed=seed))
     self.hashcommit = self.pc2.commit(self.hashpoly, self.hashpolyhat)
     print "The Rest Elapsed Time: " + str(os.times()[4] - time2[4])
     time2 = os.times()
     for j in participantids:
         send_function(j, self.send_sendmsg(j))
예제 #6
0
class HBVssDealer:
    def __init__(self,
                 k,
                 t,
                 secret,
                 sk,
                 pk,
                 participantids,
                 participantkeys,
                 group,
                 symflag,
                 recv_function,
                 send_function,
                 sid=1,
                 seed=None):
        # Random polynomial coefficients constructed in the form
        #[c       x        x^2        ...  x^t]
        # This is structured so that t+1 points are needed to reconstruct the polynomial
        ONE = group.random(ZR) * 0 + 1
        self.witnesses = {}
        self.t = t
        self.k = k
        self.group = group
        self.sid = sid
        self.poly = list(group.random(ZR, count=t + 1, seed=seed))
        self.poly[0] = ONE * secret
        self.polyhat = list(group.random(ZR, count=t + 1, seed=seed))
        self.participantids = participantids
        self.participantkeys = participantkeys
        self.sharedkeys = {}
        for j in participantids:
            self.sharedkeys[j] = self.participantkeys[j]**sk
        self.pc = PolyCommitPed(t=t, pk=pk, group=group, symflag=symflag)
        self.commitment = self.pc.commit(self.poly, self.polyhat)
        self.shares = {}
        self.encryptedshares = {}
        for j in participantids:
            self.shares[j] = f(self.poly, j)
            self.encryptedshares[j] = self.encrypt(self.sharedkeys[j],
                                                   self.shares[j])
        #for j in participantids[:t+1]:
        for j in participantids:
            self.witnesses[j] = self.pc.create_witness(self.poly, self.polyhat,
                                                       j)
        message = {}
        message['commit'] = objectToBytes(self.commitment, self.group)
        message['witnesses'] = objectToBytes(self.witnesses, self.group)
        message['shares'] = self.encryptedshares
        message['dealer'] = k
        message['polyhat'] = objectToBytes(self.polyhat, self.group)
        reliablebroadcast(sid,
                          pid=k,
                          N=k + 1,
                          f=t,
                          leader=k,
                          input=str(message),
                          receive=recv_function,
                          send=send_function)

    #wrapper for encryption that nicely converts crypto-things to something you can encrypt
    def encrypt(self, key, plaintext):
        encryptor = AES.new(
            objectToBytes(key, self.group)[:32], AES.MODE_CBC,
            'This is an IV456')
        plaintext_bytes = objectToBytes(plaintext, self.group)
        #seriously, why do I have to do the padding...
        while len(plaintext_bytes) % 16 != 0:
            plaintext_bytes = plaintext_bytes + b'\x00'
        return encryptor.encrypt(plaintext_bytes)
예제 #7
0
class VssRecipient:
    def __init__(self,
                 k,
                 t,
                 nodeid,
                 pk,
                 pk2,
                 participantids,
                 group,
                 symflag,
                 send_function,
                 recv_function,
                 sid=1,
                 reconstruction=True,
                 seed=None):
        self.k = k
        self.t = t
        self.nodeid = nodeid
        self.pk = pk
        self.pk2 = pk2
        self.participantids = participantids
        self.group = group
        self.sid = sid
        self.seed = seed
        self.hashcommit = None
        self.commitments = None
        self.mywitnesses = None
        self.myhashwitness = None
        self.sendecho = None
        self.hashpoly = None
        self.share = None
        self.ready = False
        self.recshare = False
        self.finished = False
        self.poly = None
        self.polyhat = None
        self.hashpoly = None
        self.hashpolyhat = None
        self.secret = None
        self.pc = PolyCommitPed(t=t, pk=pk, group=group, symflag=symflag)
        self.pc2 = PolyCommitPed(t=k, pk=pk2, group=group, symflag=symflag)
        self.interpolatedpolyatzero = None
        self.interpolatedpolyhatatzero = None
        self.nosharereadymessages = {}
        self.readymessagequeue = {}
        self.verifiedreadymessages = {}
        self.recsharemessages = {}
        self.send_function = send_function
        #Technically these following two lists will contain hashes of commitments to hashes, as we only need to count how many duplicates we have
        self.echoedhashcommits = {}
        self.readyhashcommits = {}
        if reconstruction:
            while not self.finished:
                sender, msg = recv_function()
                self.receive_msg(msg)
        else:
            while not self.recshare:
                sender, msg = recv_function()
                self.receive_msg(msg)

    def get_share(self):
        assert self.recshare
        return ([self.nodeid, self.interpolatedpolyatzero])

    def receive_msg(self, msg):
        if msg is None:
            return
        if type(msg) is not dict:
            msg = json.loads(msg)
        if msg['type'] == 'send':
            for key, value in msg.iteritems():
                if key != 'type' and key != 'sid':
                    msg[key] = bytesToObject(value, self.group)
            fixedcommitments = {}
            for key, value in msg['commitments'].iteritems():
                fixedcommitments[int(key)] = msg['commitments'][key]
            msg['commitments'] = fixedcommitments
            fixedwitnesses = {}
            for key, value in msg['witnesses'].iteritems():
                fixedwitnesses[int(key)] = msg['witnesses'][key]
            msg['witnesses'] = fixedwitnesses
            if self.check_send_correctness(msg):
                self.hashcommit = msg['hashcommit']
                self.hashpolyhat = msg['hashpolyhat']
                self.commitments = msg['commitments']
                self.poly = msg['poly']
                self.polyhat = msg['polyhat']
                self.mywitnesses = {}
                #for j in range(1,self.k+1):
                for j in msg['commitments']:
                    #We don't need a witness at 0. It wouldn't really hurt though
                    if j != 0:
                        self.mywitnesses[j] = self.pc.create_witness(
                            msg['poly'], msg['polyhat'], j)
                self.myhashwitness = self.pc2.create_witness(
                    self.hashpoly, msg['hashpolyhat'], self.nodeid)
                self.sendecho = True
                for j in self.participantids:
                    self.send_function(j, self.send_echomsg())
            else:
                self.sendecho = False
        if msg['type'] == 'echo':
            #This code keeps a tally of how many times each message has been received and checks if it's over the threshold
            #First make sure we haven't received this particular echo message before and that we still care about echo messages
            #if self.echoedhashcommits[msg['id']] == None and not self.ready:
            if msg['id'] not in self.echoedhashcommits and not self.ready:
                msg['hashcommit'] = bytesToObject(msg['hashcommit'],
                                                  self.group)
                #We take a hash of these commitments for the sole purpose of being able to compare them with python tools
                self.echoedhashcommits[msg['id']] = hashlib.sha256(
                    str(msg['hashcommit'])).hexdigest()
                #for key, value in collections.Counter(self.echoedhashcommits).iteritems():
                for key, value in collections.Counter(
                        self.echoedhashcommits.values()).iteritems():
                    if value >= (self.k - self.t) and key != None:
                        self.ready = True
                        #We're sharing the hash polynomial commitment we received iff it's the same one that k - t others gave us
                        self.share = key == hashlib.sha256(str(
                            self.hashcommit)).hexdigest()
                        self.hashcommit = msg['hashcommit']
                        for j in self.participantids:
                            self.send_function(j, self.send_readymsg(j))
        if msg['type'] == 'ready':
            if self.recshare:
                return
            for key, value in msg.iteritems():
                if key not in ['type', 'id', 'share']:
                    msg[key] = bytesToObject(msg[key], self.group)
            #Ignore invalid messages and messages where we have already received a valid message from that sender
            #if msg['id'] in self.readymessages or (msg['share'] and not self.check_ready_correctness(msg)):
            if msg['id'] in self.nosharereadymessages or msg[
                    'id'] in self.readymessagequeue:
                return
            if msg['share']:
                self.readymessagequeue[msg['id']] = msg
            else:
                self.nosharereadymessages[msg['id']] = msg
            if not self.ready:
                #This is very similar to how we receive echo messages. Basically a fallback if we don't get enough echos
                if msg['id'] not in self.readyhashcommits:
                    self.readyhashcommits[msg['id']] = hashlib.sha256(
                        str(msg['hashcommit'])).hexdigest()
                    for key, value in collections.Counter(
                            self.readyhashcommits.values()).iteritems():
                        if value >= (self.t + 1) and key != None:
                            self.ready = True
                            #We're sharing whatever hash polynomial commitment we received t + 1 of
                            self.share = key == hashlib.sha256(
                                str(self.hashcommit)).hexdigest()
                            self.hashcommit = msg['hashcommit']
                            for j in self.participantids:
                                self.send_function(j, self.send_readymsg(j))
            if not self.ready:
                return
            if len(self.verifiedreadymessages) <= self.t + 1 and len(
                    self.verifiedreadymessages) + len(
                        self.readymessagequeue) >= self.t + 1:
                for key in self.readymessagequeue:
                    readymsg = self.readymessagequeue[key]
                    if not self.pc2.verify_eval(readymsg['hashcommit'], readymsg['id'], hexstring_to_ZR(hashlib.sha256(str(readymsg['commitment'])).hexdigest(), self.group), \
                        readymsg['hashpolyhatpoint'], readymsg['hashpolywitness']):
                        del self.readymessagequeue[key]
                cs = []
                polyevals = []
                secretpolyevals = []
                witnesses = []
                for key in self.readymessagequeue:
                    cs.append(self.readymessagequeue[key]['commitment'])
                    polyevals.append(self.readymessagequeue[key]['polypoint'])
                    secretpolyevals.append(
                        self.readymessagequeue[key]['polyhatpoint'])
                    witnesses.append(
                        self.readymessagequeue[key]['polywitness'])
                tfstring = self.pc.find_valid_evals(cs, self.nodeid, polyevals,
                                                    secretpolyevals, witnesses)
                i = 0
                for key in self.readymessagequeue:
                    if tfstring[i]:
                        self.verifiedreadymessages[
                            key] = self.readymessagequeue[key]
                    i += 1
                self.readymessagequeue = {}
            if len(self.verifiedreadymessages.values() +
                   self.readymessagequeue.values() +
                   self.nosharereadymessages.values()) < (self.k - self.t):
                return
            correcthashcommit = str(
                self.verifiedreadymessages.values()[0]['hashcommit'])
            #print correcthashcommit
            correcthashcommitcount = 0
            for message in self.verifiedreadymessages.values(
            ) + self.readymessagequeue.values(
            ) + self.nosharereadymessages.values():
                if str(message['hashcommit']) == correcthashcommit:
                    correcthashcommitcount += 1
            #print correcthashcommitcount
            if correcthashcommitcount >= (self.k - self.t):
                interpolatedpolycoords = []
                interpolatedpolyhatcoords = []
                interpolatedcommitmentcoords = []
                interpolatedwitnesscoords = []
                for key, message in self.verifiedreadymessages.iteritems():
                    if message is None or not message['share'] or message[
                            'hashcommit'] != self.hashcommit:
                        continue
                    interpolatedpolycoords.append(
                        [message['id'], message['polypoint']])
                    interpolatedpolyhatcoords.append(
                        [message['id'], message['polyhatpoint']])
                    interpolatedcommitmentcoords.append(
                        [message['id'], message['commitment']])
                    interpolatedwitnesscoords.append(
                        [message['id'], message['polywitness']])
                    if len(interpolatedpolycoords) == (self.t + 1):
                        break
                self.interpolatedpolyatzero = interpolate_at_x(
                    interpolatedpolycoords, 0, self.group)
                self.interpolatedpolyhatatzero = interpolate_at_x(
                    interpolatedpolyhatcoords, 0, self.group)
                self.interpolatedzerocommitment = interpolate_at_x(
                    interpolatedcommitmentcoords, 0, self.group)
                self.interpolatedzerowitness = interpolate_at_x(
                    interpolatedwitnesscoords, 0, self.group)
                self.recshare = True
                for j in self.participantids:
                    self.send_function(j, self.send_recsharemsg())
                #Check the validity of any recshare messages we may have received before we could have checked them
                #for i in range(len(self.recsharemessages)):
                for i in self.recsharemessages:
                    #if self.recsharemessages[i] is None:
                    #    continue
                    if not self.check_recshare_correctness(
                            self.recsharemessages[i]):
                        del self.recsharemessages[i]
                        #self.recsharemessages[i] = None

        if msg['type'] == 'recshare':
            for key, value in msg.iteritems():
                if key not in ['type', 'id']:
                    msg[key] = bytesToObject(msg[key], self.group)
            #Ignore messages where we have already received a message from that sender
            #Still hold onto messages we receive even if we can't yet validate them
            if msg['id'] in self.recsharemessages:
                return
            if not self.recshare:
                self.recsharemessages[msg['id']] = msg
                return
            if not self.check_recshare_correctness(msg):
                print "Invalid message!"
                return
            self.recsharemessages[msg['id']] = msg
            msgcount = 0
            for key, msg in self.recsharemessages.iteritems():
                if msg is not None:
                    msgcount += 1
            if msgcount == self.t + 1:
                secretcoords = []
                for key, msg in self.recsharemessages.iteritems():
                    if msg is not None:
                        secretcoords.append([msg['id'], msg['polypoint']])
                secrets = []
                for i in range(self.t + 1):
                    secrets.append(
                        interpolate_at_x(secretcoords, i, self.group))
                print "Node " + str(
                    self.nodeid) + ": The secret is " + str(secrets)
                self.secret = secrets[0]
                self.finished = True

    def check_send_correctness(self, sendmsg):
        #verify commitments can be interpolated from each other
        commitmentsvalid = check_commitment_integrity(sendmsg['commitments'],
                                                      self.t, self.group)
        #verify correctness of witnesses
        witnessesvalid = True
        polyevals = []
        secretpolyevals = []
        commitments = []
        witnesses = []
        #i is the key for the dictionary. i.e. a list of ids of all participants
        for i in sendmsg['witnesses']:
            #Taking advantage of the polynomial symmetry, we know points on other polynomials too. f(nodeid, i) == f(i, nodeid)
            #    witnessesvalid = witnessesvalid and \
            #        self.pc.verify_eval(sendmsg['commitments'][i], self.nodeid, f(sendmsg['poly'],i), f(sendmsg['polyhat'],i), sendmsg['witnesses'][i])
            polyevals.append(f(sendmsg['poly'], i))
            secretpolyevals.append(f(sendmsg['polyhat'], i))
            commitments.append(sendmsg['commitments'][i])
            witnesses.append(sendmsg['witnesses'][i])
        witnessesvalid = self.pc.batch_verify_eval(commitments, self.nodeid,
                                                   polyevals, secretpolyevals,
                                                   witnesses)
        #veryify correctness of hash polynomial commitment
        #hashpoly must be generated the same way as in VssDealer
        hashpolypoints = []
        ONE = self.group.random(ZR, seed=60) * 0 + 1
        for i in sendmsg['commitments']:
            hashpolypoints.append([
                ONE * i,
                hexstring_to_ZR(
                    hashlib.sha256(str(sendmsg['commitments'][i])).hexdigest(),
                    self.group)
            ])
        self.hashpoly = interpolate_poly(hashpolypoints)
        hashpolycommitmentvalid = self.pc2.verify_poly(sendmsg['hashcommit'],
                                                       self.hashpoly,
                                                       sendmsg['hashpolyhat'])
        #verify correctness of regular polynomial
        polyvalid = self.pc.verify_poly(sendmsg['commitments'][self.nodeid],
                                        sendmsg['poly'], sendmsg['polyhat'])
        return commitmentsvalid and witnessesvalid and hashpolycommitmentvalid and polyvalid

    def check_ready_correctness(self, readymsg):
        return self.pc.verify_eval(readymsg['commitment'], self.nodeid, readymsg['polypoint'], readymsg['polyhatpoint'], readymsg['polywitness']) and \
            self.pc2.verify_eval(readymsg['hashcommit'], readymsg['id'], hexstring_to_ZR(hashlib.sha256(str(readymsg['commitment'])).hexdigest(), self.group), \
            readymsg['hashpolyhatpoint'], readymsg['hashpolywitness'])

    def check_recshare_correctness(self, recsharemsg):
        return self.pc.verify_eval(self.interpolatedzerocommitment,
                                   recsharemsg['id'], recsharemsg['polypoint'],
                                   recsharemsg['polyhatpoint'],
                                   recsharemsg['polywitness'])

    def send_echomsg(self):
        if type(self.sendecho) is not bool:
            print "Can not send echo, no send message received"
            return None
        elif not self.sendecho:
            print "Invalid send message, can not echo"
            return None
        else:
            echomsg = {}
            echomsg['type'] = 'echo'
            echomsg['hashcommit'] = objectToBytes(self.hashcommit, self.group)
            echomsg['id'] = self.nodeid
            return json.dumps(echomsg)

    #Send a ready message to party j
    def send_readymsg(self, j):
        if not self.ready:
            print "Can not send ready message, I have not received enough echo messages"
            return None
        readymsg = {}
        readymsg['type'] = 'ready'
        readymsg['id'] = self.nodeid
        readymsg['share'] = self.share
        readymsg['hashcommit'] = objectToBytes(self.hashcommit, self.group)
        if self.share:
            readymsg['polypoint'] = objectToBytes(f(self.poly, j), self.group)
            readymsg['polyhatpoint'] = objectToBytes(f(self.polyhat, j),
                                                     self.group)
            readymsg['polywitness'] = objectToBytes(self.mywitnesses[j],
                                                    self.group)
            readymsg['commitment'] = objectToBytes(
                self.commitments[self.nodeid], self.group)
            readymsg['hashpolyhatpoint'] = objectToBytes(
                f(self.hashpolyhat, self.nodeid), self.group)
            readymsg['hashpolywitness'] = objectToBytes(
                self.myhashwitness, self.group)
        return json.dumps(readymsg)

    def send_recsharemsg(self):
        if not self.recshare:
            print "Can not send Rec-Share message, I have not received enough ready messages"
            return None
        recsharemsg = {}
        recsharemsg['type'] = 'recshare'
        recsharemsg['id'] = self.nodeid
        recsharemsg['polypoint'] = objectToBytes(self.interpolatedpolyatzero,
                                                 self.group)
        recsharemsg['polyhatpoint'] = objectToBytes(
            self.interpolatedpolyhatatzero, self.group)
        recsharemsg['polywitness'] = objectToBytes(
            self.interpolatedzerowitness, self.group)
        return json.dumps(recsharemsg)