def getIssuerState(sessionid, db): """ This function is called by ACLValidation2 to get the issuer state. Whenever it is used, it is marked as used. """ (conn, cur) = db returnStatus = 0 issuer_state = None try: param = (str(sessionid), ) # IMPORTANT NOTE: # in case we are using two coins, the first one will pass this # and at the end of this function it will be set to 1. # then the next coin will see this and will attach "coin2" # at the end to access the second's coin data. # This is in line with how saving is done. # see service.py @ ### ACL Validation 1 ###. # If this doesn't happen then there is a bug cur.execute( """SELECT * FROM issuer_state WHERE session_id=(?) AND used=1""", param) numRes = len(cur.fetchall()) if numRes > 0: param = (sessionid + "coin2", ) cur.execute( """SELECT u_packed,r1p_packed,r2p_packed,cp_packed FROM issuer_state WHERE session_id=(?) """, param) issuer_state = acl.StateHolder() # TODO check query returns only one thing for r in cur.fetchall(): (u, ) = crypto.unmarshall(r[0]) (r1p, ) = crypto.unmarshall(r[1]) (r2p, ) = crypto.unmarshall(r[2]) (cp, ) = crypto.unmarshall(r[3]) issuer_state.u = u issuer_state.r1p = r1p issuer_state.r2p = r2p issuer_state.cp = cp cur.execute("""UPDATE issuer_state SET used=1 WHERE session_id=(?)""", param) conn.commit() except: conn.rollback() returnStatus = -1 if returnStatus == -1: return -1 else: return issuer_state
def loadAC(id): coinTemp = dbUser.getACById(id) denomination = int(coinTemp[0]) packedData = coinTemp[1] data = crypto.unmarshall(packedData) (issuer_pub, signature, sig) = data secretPacked = coinTemp[2] secretData = crypto.unmarshall(secretPacked) coin = ACL(denomination, issuer_pub, signature, sig, secretData, boolSave=False) return coin
def verifyACL(): """ Spends a coin """ # get a coin (coin_id, coin) = choose_coin() # Get details of the coin in the right format (issuer_pub, numAttr, signature, sig) = coin.getACL() # pack them toPack = [issuer_pub, numAttr, signature, sig] encoded = crypto.marshall(toPack) # send them encoded_rcv = send(None, "verify", encoded) # decode response m = crypto.unmarshall(encoded_rcv) if (m == False): print "Sorry, this coin is no longer valid!" else: print "Coin Spent!" # TODO: ask for coin deletion. The reason is that if something goes wrong # by auto deleting coins then the user might lose coins deleteCoin = raw_input("Delete coin " + str(coin_id) + " ?[y/n]") if deleteCoin == "y": dbUser.invalidateACL(coin_id) return 0
def ACLVerify(params, encoded, db, keys, innerCall=False): """ Verifies a coin. Returns False if verification failed, a value otherwise. """ (issuer_pub, numOfAttributes, signature, sig) = crypto.unmarshall(encoded) m = acl.BL_verify_cred(params, issuer_pub, numOfAttributes, signature, sig, db, keys) if m == False: return False else: encoded = crypto.marshall([m]) return encoded
def ACLValidation2(params, sessionid, encoded, db, keys): # 50 for GID=713, 55 for GID=714, 75 for GID=715, 100 for GID=716 length = 50 if settings.SERVER_GID == 713: length = 50 elif settings.SERVER_GID == 714: length = 55 elif settings.SERVER_GID == 715: length = 75 elif settings.SERVER_GID == 716: length = 100 # This check basically distinguishes if the sender sends 2 things or one # i.e. if we are in a splitACL phase or not if len(encoded) < length: (msg_to_issuer,) = crypto.unmarshall(encoded) issuer_state = database.getIssuerState(sessionid, db) msg_to_user = acl.BL_issuer_validation_2(params, issuer_state, msg_to_issuer, keys) encoded = crypto.marshall([msg_to_user]) return encoded else: # splitACL (msg_to_issuer_p, msg_to_issuer_pp) = crypto.unmarshall(encoded) issuer_state_p = database.getIssuerState(sessionid, db) msg_to_user_p = acl.BL_issuer_validation_2(params, issuer_state_p, msg_to_issuer_p, keys) issuer_state_pp = database.getIssuerState(sessionid, db) msg_to_user_pp = acl.BL_issuer_validation_2(params, issuer_state_pp, msg_to_issuer_pp, keys) encoded = crypto.marshall([msg_to_user_p, msg_to_user_pp]) return encoded
def ACLCombine(params, sessionid, encoded, db, keys): (public, proof) = crypto.unmarshall(encoded) # Verify that indeed the new commitment # is the sum of the 2 given if crypto.verifyCombineCoin(params, public, proof) == False: return "Proof of combineACL failed." ## check that is not the same coin sent two times # Prepare the arguments verifyParams1 = [public["issuer_pub_c1"], public["numAttr_c1"], public["signature_c1"], public["sig_c1"]] verifyParams2 = [public["issuer_pub_c2"], public["numAttr_c2"], public["signature_c2"], public["sig_c2"]] if public["signature_c1"] == public["signature_c2"] or \ public["sig_c1"] == public["sig_c2"]: return "Are you using the same coin?" verifyParams1Encoded = crypto.marshall(verifyParams1) verifyParams2Encoded = crypto.marshall(verifyParams2) # check double spending if ACLVerify(params, verifyParams1Encoded, db, keys, innerCall=True) == False or \ ACLVerify(params, verifyParams2Encoded, db, keys, innerCall=True) == False: return "ACL verification failed due to double spending." # save session if _saveSessionid(sessionid, db) == -1: return -1 userCom = public["C"] issuer_pub = keys[1] # acl.BL_issuer_keys() ### ACL Preparation ### aclPrep = _ACLPreparation(params, sessionid, userCom) if aclPrep == -1: return -1 (rnd, z1, z2) = aclPrep ### ACL Validation 1 ### (a, a1p, a2p) = _ACLValidation1(params, sessionid, z1, z2, db) ### Prepare to return ### ret = [rnd, a, a1p, a2p, issuer_pub] retEncoded = crypto.marshall(ret) return retEncoded
def deposit(testing=False): """ Mints an ACL """ if testing == False: amount = raw_input("Enter the amount to make a coin:") amount = int(amount) timeSent = time.time() else: amount = 10 # get session. Session lasts for a minute session = getSession() ### ACL registration ### # setup user locally user_state = acl.BL_user_setup([amount]) user_commit = user_state.C # pack encoded = crypto.marshall([user_commit]) # send debug_print("len deposit registration = " + str(len(encoded))) encoded_rsp = send(session, "deposit", encoded) debug_print("len prep-val1 (server to client) = " + str(len(encoded_rsp))) if encoded_rsp == "-1": raise ValueError, "Something went wrong in the service." debug_print("deposit received = " + encoded_rsp) decoded_rsp = crypto.unmarshall(encoded_rsp) (rnd, a, a1p, a2p, issuer_pub) = decoded_rsp coin_stuff = (rnd, a, a1p, a2p) # if the code reaches here, then we can do the ACL protocol coin = ACL_protocol(amount, issuer_pub, user_state, session, coin_stuff) if coin == -1: raise ValueError, "Something went wrong while executing the ACL protocol" coin_, amount, alias = coin if settings.TESTING_MODE == False: timeDiff = time.time() - timeSent print "Time diff = ", timeDiff print "Successfully minted a coin" print "Coin %s of value: %d" % (alias, amount) return coin_
def ACL_protocol(amount, issuer_pub, user_state, session, coin_stuff): """ Runs the ACL protocol and creates a credential """ (rnd, a, a1p, a2p) = coin_stuff ### ACL Preparation ### acl.BL_user_preparation(user_state, rnd) ### ACL Validation 1 ### # make epsilon msg_to_issuer = acl.BL_user_validation(user_state, issuer_pub, (a, a1p, a2p)) ### ACL Validation 2 ### encoded = crypto.marshall([msg_to_issuer]) debug_print("len prep-validation1 (client to server)= " + str(len(encoded))) encoded_rcv = send(session, "validation2", encoded) debug_print("len validation2 (servet to client) = " + str(len(encoded_rcv))) debug_print("ACL_protocol response=" + encoded_rcv) (msg_from_issuer, ) = crypto.unmarshall(encoded_rcv) ### Signatures ### signature = acl.BL_user_validation2(user_state, msg_from_issuer) sig = acl.BL_user_prove_cred(user_state) ### Create Coin ### # TODO change to raw_input alias = "time coin" # raw_input("Name/notes for this coin:") R = user_state.R gamma = user_state.gam rnd = user_state.rnd secret_data = (gamma, rnd, R) # Create coin and automatically save it coin = modWallet.ACL(amount, issuer_pub, signature, sig, secret_data, alias, True) return coin, amount, alias
def ACLDeposit(params, sessionid, encoded, db, keys): (userCom,) = crypto.unmarshall(encoded) # since the user has gotten thus far and has began registration # add the session id in the database if _saveSessionid(sessionid, db) == -1: return -1 issuer_pub = keys[1] # acl.BL_issuer_keys() ### ACL Preparation ### aclPrep = _ACLPreparation(params, sessionid, userCom) if aclPrep == -1: return -1 (rnd, z1, z2) = aclPrep ### ACL Validation 1 ### (a, a1p, a2p) = _ACLValidation1(params, sessionid, z1, z2, db) ### Prepare to return ### ret = [rnd, a, a1p, a2p, issuer_pub] retEncoded = crypto.marshall(ret) return retEncoded
def _loadKeys(_keys=settings.SERVER_KEYS): #f = open(filename, 'r') #_keys = f.read() #f.close() keys = crypto.unmarshall(_keys) return keys
def combineACL(coin1, coin2): """ The user combines 2 ACLs to create a new one whose balance will be the sum of the 2. """ timeSent = time.time() ## Get coin denomination, zeta1, gamma, R, and rnd for each coin # For coin 1: coin1Data = {} coin1Data["denomination"] = coin1.getDenomination() coin1Data["zeta1"] = coin1.getZeta1() (gamma, rnd, R) = coin1.getSecretData() coin1Data["gamma"] = gamma coin1Data["rnd"] = rnd coin1Data["R"] = R # For coin 2: coin2Data = {} coin2Data["denomination"] = coin2.getDenomination() coin2Data["zeta1"] = coin2.getZeta1() (gamma, rnd, R) = coin2.getSecretData() coin2Data["gamma"] = gamma coin2Data["rnd"] = rnd coin2Data["R"] = R ## Calculate h0^gamma, h1^gamma, g^gamma (_, o, g, _, _, hs) = pparams h0 = hs[0] h1 = hs[1] # for coin 1 coin1Data["h0gamma"] = coin1Data["gamma"] * h0 coin1Data["h1gamma"] = coin1Data["gamma"] * h1 coin1Data["ggamma"] = coin1Data["gamma"] * g # for coin 2 coin2Data["h0gamma"] = coin2Data["gamma"] * h0 coin2Data["h1gamma"] = coin2Data["gamma"] * h1 coin2Data["ggamma"] = coin2Data["gamma"] * g assert coin1Data["zeta1"] == ( coin1Data["R"] * coin1Data["h0gamma"] + coin1Data["denomination"] * coin1Data["h1gamma"] + coin1Data["rnd"] * coin1Data["ggamma"]) assert coin2Data["zeta1"] == ( coin2Data["R"] * coin2Data["h0gamma"] + coin2Data["denomination"] * coin2Data["h1gamma"] + coin2Data["rnd"] * coin2Data["ggamma"]) Rpp = o.random() C = Rpp * h0 + coin1Data["denomination"] * h1 + coin2Data[ "denomination"] * h1 ## Set Public values nizkPublic = {} # coin 1 public nizkPublic["zeta1_c1"] = coin1Data["zeta1"] nizkPublic["h0gamma_c1"] = coin1Data["h0gamma"] nizkPublic["h1gamma_c1"] = coin1Data["h1gamma"] nizkPublic["ggamma_c1"] = coin1Data["ggamma"] # coin 2 public nizkPublic["zeta1_c2"] = coin2Data["zeta1"] nizkPublic["h0gamma_c2"] = coin2Data["h0gamma"] nizkPublic["h1gamma_c2"] = coin2Data["h1gamma"] nizkPublic["ggamma_c2"] = coin2Data["ggamma"] # add Commitment nizkPublic["C"] = C # nizkPublic["h0"] = h0 # nizkPublic["h1"] = h1 ## Set Secret values nizkSecret = {} # coin 1 secrets nizkSecret["R_c1"] = coin1Data["R"] nizkSecret["gamma_c1"] = coin1Data["gamma"] nizkSecret["x_c1"] = coin1Data["denomination"] nizkSecret["rnd_c1"] = coin1Data["rnd"] # coin 2 secrets nizkSecret["R_c2"] = coin2Data["R"] nizkSecret["gamma_c2"] = coin2Data["gamma"] nizkSecret["y_c2"] = coin2Data["denomination"] nizkSecret["rnd_c2"] = coin2Data["rnd"] # add commitment's R nizkSecret["Rpp"] = Rpp t0 = time.time() proof = crypto.proveCombineCoin(pparams, nizkPublic, nizkSecret) # assert crypto.verifyCombineCoin(nizkPublic, proof) t1 = time.time() - t0 global proofTime proofTime += t1 (issuer_pub, numAttr, signature, sig) = coin1.getACL() nizkPublic["issuer_pub_c1"] = issuer_pub nizkPublic["numAttr_c1"] = numAttr nizkPublic["signature_c1"] = signature nizkPublic["sig_c1"] = sig (issuer_pub, numAttr, signature, sig) = coin2.getACL() nizkPublic["issuer_pub_c2"] = issuer_pub nizkPublic["numAttr_c2"] = numAttr nizkPublic["signature_c2"] = signature nizkPublic["sig_c2"] = sig ### ACL Registration ### newDenomination = coin1Data["denomination"] + coin2Data["denomination"] user_state = acl.StateHolder() user_state.C = C user_state.attributes = [newDenomination] user_state.R = Rpp ### ACLCombine ### session = getSession() # send public stuff to the service encoded = crypto.marshall([nizkPublic, proof]) debug_print("len combine registration = " + str(len(encoded))) encoded_rcv = send(session, "combine", encoded) debug_print("len prep-val1 (Server to client) = " + str(len(encoded_rcv))) if encoded_rcv == "-1": raise ValueError, "An error occurred. The service could not combine the two coins" # decode response debug_print("combine ACL response = " + encoded_rcv) decoded_rcv = crypto.unmarshall(encoded_rcv) (rnd, a, a1p, a2p, issuer_pub) = decoded_rcv coin_stuff = (rnd, a, a1p, a2p) coin = ACL_protocol(newDenomination, issuer_pub, user_state, session, coin_stuff) coin_, _, _ = coin return coin_
def splitACL(coin, split1, split2): """ The user chooses an ACL to split by some amount, and if everything goes well, gets 2 coins of splitted value. """ (_, o, _, _, _, _) = pparams # Get coin denomination, zeta1, gamma, R, and rnd denomination, zeta1, secret_data = _getCoinData(coin) # calculate h0^gamma, h1^gamma, g^gamma (gamma, rnd, R) = secret_data (h0gamma, h1gamma, ggamma) = _getToTheGamma(gamma) assert zeta1 == (R * h0gamma + denomination * h1gamma + rnd * ggamma) t0 = time.time() proofs1 = crypto.proveCommitmentAndPositivity(pparams, split1) (Cp, Rp, proofCp, ComListp, proofListp) = proofs1 proofp = (proofCp, ComListp, proofListp) proofs2 = crypto.proveCommitmentAndPositivity(pparams, split2) (Cpp, Rpp, proofCpp, ComListpp, proofListpp) = proofs2 proofpp = (proofCpp, ComListpp, proofListpp) # Create proof that the two new commitment value adds up to the previous. # i.e. split1+split2 = denomination proof = crypto.proveSplitCoin(pparams, h0gamma, h1gamma, ggamma, R, gamma, Rp, split1, Rpp, split2, rnd, zeta1, Cp, Cpp) t1 = time.time() - t0 global proofTime proofTime += t1 ### ACL Registration ### # Prepate ACL Registration for coin1 user_state_p = acl.StateHolder() user_state_p.C = Cp user_state_p.attributes = [split1] user_state_p.R = Rp # Prepare ACL Registration for coin2 user_state_pp = acl.StateHolder() user_state_pp.C = Cpp user_state_pp.attributes = [split2] user_state_pp.R = Rpp ### ACL Preparation - ACL Validation 1 ### # pack toPack = [ h0gamma, h1gamma, ggamma, zeta1, Cp, Cpp, proof, proofp, proofpp, coin.getACL() ] encoded = crypto.marshall(toPack) debug_print("len splitACL registration = " + str(len(encoded))) # get Session. Session lasts for a minute session = getSession() encoded_response = send(session, "split", encoded) debug_print("len prep-val1 (server to client) = " + str(len(encoded_response))) if encoded_response == "-1": print "splitACL didn't work" return -1 # decode response # In this case a response is 3 things: # rnd, a, a1p, a2p for coin1 # rnd, a, a1p, a2p for coin2 # issuer_pub decoded_rcv = crypto.unmarshall(encoded_response) coin1_stuff = decoded_rcv[0] coin2_stuff = decoded_rcv[1] issuer_pub = decoded_rcv[2] ### ACL Validation 2 - Coin Creation ### (rnd_p, a_p, a1p_p, a2p_p) = coin1_stuff acl.BL_user_preparation(user_state_p, rnd_p) (rnd_pp, a_pp, a1p_pp, a2p_pp) = coin2_stuff acl.BL_user_preparation(user_state_pp, rnd_pp) ### ACL Validation 1 ### # make epsilon msg_to_issuer_p = acl.BL_user_validation(user_state_p, issuer_pub, (a_p, a1p_p, a2p_p)) msg_to_issuer_pp = acl.BL_user_validation(user_state_pp, issuer_pub, (a_pp, a1p_pp, a2p_pp)) ### ACL Validation 2 ### encoded = crypto.marshall([msg_to_issuer_p, msg_to_issuer_pp]) # pack debug_print("len prep - val1. (client to server) = " + str(len(encoded))) encoded_response = send(session, "validation2", encoded) debug_print("len validation2 =" + str(len(encoded_response))) # decode response (msg_from_issuer_p, msg_from_issuer_pp) = crypto.unmarshall(encoded_response) ### Signatures ### signature_p = acl.BL_user_validation2(user_state_p, msg_from_issuer_p) sig_p = acl.BL_user_prove_cred(user_state_p) signature_pp = acl.BL_user_validation2(user_state_pp, msg_from_issuer_pp) sig_pp = acl.BL_user_prove_cred(user_state_pp) ### Create Coin ### # TODO change to raw_input alias = "time coin" # raw_input("Name/notes for this coin:") R_p = user_state_p.R gamma_p = user_state_p.gam rnd_p = user_state_p.rnd secret_data_p = (gamma_p, rnd_p, R_p) R_pp = user_state_pp.R gamma_pp = user_state_pp.gam rnd_pp = user_state_pp.rnd secret_data_pp = (gamma_pp, rnd_pp, R_pp) # Create coin and automatically save it coin1 = modWallet.ACL(split1, issuer_pub, signature_p, sig_p, secret_data_p, alias, True) coin2 = modWallet.ACL(split2, issuer_pub, signature_pp, sig_pp, secret_data_pp, alias, True) return coin1, coin2
def ACLSpend(params, encoded): (h0gamma, h1gamma, ggamma, zeta1, proof, coin) = crypto.unmarshall(encoded) publicParams = (h0gamma, h1gamma, ggamma, zeta1) if crypto.verifySpend(params, publicParams, proof) == False: return "Couldn't verify coin spend" return "coin spend verified!"
def ACLSplit(params, sessionid, encoded, db, keys): """ When a user wants to split two coins, he must call this function. It takes as input: h0^gamma, h1^gamma, g^gamma, zeta1, Cp, Cpp, proof, coin -zeta1 is the blinded coin the user has obtained from the service in the past -Cp, Cpp are the 2 commitments that will be used to register. -proof is a NIZK which proves that what is hidden in the commitments adds up to the values within zeta1 -coin is the coin the user will split. This coin must be verified """ (h0gamma, h1gamma, ggamma, zeta1, Cp, Cpp, proof, proofp, proofpp, coin) = crypto.unmarshall(encoded) (issuer_pub, numAttr, signature, sig) = coin # verify positivity if crypto.verifyCommitmentAndPositivity(params, Cp, proofp) == False: return "Couldn't verify the Cp commitment" if crypto.verifyCommitmentAndPositivity(params, Cpp, proofpp) == False: return "Couldn't verify the Cpp commitment" # Verify the split coin proof verifyParams = (h0gamma, h1gamma, ggamma, zeta1, Cp, Cpp, proof) if crypto.verifySplitCoin(params, verifyParams) == False: return "Couldn't verify proof of SplitCoin" # Verify that there is no double spending and invalidate the coin # so it can't be further used toPack = [issuer_pub, numAttr, signature, sig] encoded_coin = crypto.marshall(toPack) if ACLVerify(params, encoded_coin, db, keys, innerCall=True) == False: return "ACL verification failed due to double spending." # If the code reaches here, the service must create # what is needed by the user to create two coins # save sessionid if _saveSessionid(sessionid, db) == -1: return -1 if _saveSessionid("".join([sessionid, "coin2"]), db) == -1: return -1 issuer_pub = keys[1] # acl.BL_issuer_keys() ### ACL Preparation ### # rndp and rndpp are to be sent to the user # z1, z2 are private, not to be sent rnd_p, z1_p, z2_p = _ACLPreparation(params, sessionid, Cp) rnd_pp, z1_pp, z2_pp = _ACLPreparation(params, sessionid, Cpp) if rnd_p == -1 or rnd_pp == -1: return -1 ### ACL Validation 1 ### (a_p, a1p_p, a2p_p) = _ACLValidation1(params, sessionid, z1_p, z2_p, db) sessionid = "".join([sessionid, "coin2"]) (a_pp, a1p_pp, a2p_pp) = _ACLValidation1(params, sessionid, z1_pp, z2_pp, db) ### Prepare to return ### ret_p = [rnd_p, a_p, a1p_p, a2p_p] ret_pp = [rnd_pp, a_pp, a1p_pp, a2p_pp] ret = [ret_p, ret_pp, issuer_pub] retEncoded = crypto.marshall(ret) return retEncoded