Beispiel #1
0
FEMessage* FEInitiator::barter(const vector<EncBuffer*>& ctextR, 
							   const vector<hash_t>& ptHashR,
							   const vector<hash_t>& ptHashI) {
	if (ctextR.empty())
		throw CashException(CashException::CE_FE_ERROR,
			"[FEInitiator::barter] No responder ciphertext given");
	
	if (ptHashR.empty())
		throw CashException(CashException::CE_FE_ERROR,
			"[FEInitiator::barter] No initiator plaintext hash given");
	
	ctextB = ctextR;
	
	// create contract
	createContract();
	
	// compute hashes
	hash_t ptHashMerkleI = Hash::hash(ptHashI, verifiablePK->hashAlg, 
									  verifiablePK->hashKey, Hash::TYPE_MERKLE);
	hash_t ptHashMerkleR = Hash::hash(ptHashR, verifiablePK->hashAlg, 
									  verifiablePK->hashKey, Hash::TYPE_MERKLE);
	hash_t ctHashMerkleI = Hash::hash(ctextA, verifiablePK->hashAlg,									  				 verifiablePK->hashKey, Hash::TYPE_MERKLE);
	hash_t ctHashMerkleR = Hash::hash(ctextB, verifiablePK->hashAlg,													 verifiablePK->hashKey, Hash::TYPE_MERKLE);
	
	// set the contract
	contract->setPTHashA(ptHashMerkleI);
	contract->setCTHashA(ctHashMerkleI);
	contract->setPTHashB(ptHashMerkleR);
	contract->setCTHashB(ctHashMerkleR);
	contract->setEncAlgA(ctextA[0]->encAlg);
	contract->setEncAlgB(ctextB[0]->encAlg);
	contract->setPTHashBlocksB(ptHashR.size());
	contract->setCTHashBlocksB(ctextR.size());
	
	// optimization: if all ciphertexts have the same key, just output one key
	// shortcut: if two ciphertexts have the same key, assume all have 
	// the same key
	vector<ZZ> keys;
	if (ctextA.size() > 1 && ctextA[0]->key == ctextA[1]->key)
		keys.push_back(ZZFromBytes(ctextA[0]->key));
	else {
		for (unsigned i = 0; i < ctextA.size(); i++) {
			keys.push_back(ZZFromBytes(ctextA[i]->key));
		}
	}
	
	// now set up signature and escrow
	VEProver prover(regularPK);
	// label is the multicontract
	string label = saveString(*contract);
	vector<ZZ> escrow = prover.encrypt(keys, label, regularPK->hashAlg, stat);
	
	// need to sign on the escrow using our signature key
	string escrowStr = CommonFunctions::vecToString(escrow);
	/* TODO: When we use RSA enc as escrow, we should also sign the contract */
	string sig = Signature::sign(*signKey, escrowStr, regularPK->hashAlg);

	// now output the escrow, signature, and contract (label)
	return new FEMessage(escrow, sig, *contract);
}
Beispiel #2
0
bool Buyer::checkKey(const vector<string>& keys) {
	if (!inProgress)
		throw CashException(CashException::CE_FE_ERROR,
			"[Buyer::pay] Pay called on a buyer not working");
	
	if (keys.empty())
		throw CashException(CashException::CE_FE_ERROR,
			"[Buyer::pay] No key given");
	
	for (unsigned i = 0; i < ctext.size(); i++) {
		// decrypt the ciphertext using key
		unsigned index = (keys.size() == 1) ? 0 : i;
		Buffer* plaintext = ctext[i]->decrypt(keys[index], 
											contract->getEncAlgB());
		ptext.push_back(plaintext);
	}
	
	// compute hashes
	hash_t ptHash = Hash::hash(ptext, contract->getPTHashB().alg, 
							   contract->getPTHashB().key, 
							   contract->getPTHashB().type);
	
	if (ptHash != contract->getPTHashB())
		throw CashException(CashException::CE_FE_ERROR,
				"[Buyer::pay] The decrypted file was not the promised file");
	
	return true;
}
Beispiel #3
0
ProofMessage* CLBlindIssuer::getPartialSignature(const ZZ &C, 
												 const vector<ZZ>& publics, 
												 const ProofMessage &pm, 
												 int stat, 
												 const hashalg_t &hashAlg) {
	// at this point, verifier will know which program it is working with
	variable_map proverPublics = pm.proof.getCommitments();
	variable_map pv = pm.publics;
    verifier.compute(v, proverPublics, pv);

	SigmaProof proof = pm.proof;
	startTimer();
	bool verified = verifier.verify(proof, stat);
	printTimer("[CLBlindIssuer] verified recipient proof");
	if(verified){
		// XXX: should we be checking that public values are in the 
		// proper range? same goes for recipient side of things too...
		if((int)publics.size() != numPublics) 
			throw CashException(CashException::CE_SIZE_ERROR,
			"[CLBlindIssuer::getPartialSignature] Number of public inputs "
			"does not match the number the issuer was constructed with");

		startTimer();
		InterpreterProver prover;
		prover.check("ZKP/examples/cl-issue.txt", inputs, g);

		// want to keep the same inputs and groups, but need a new variable 
		// map for doing issue program
		ZZ lx = v.at("l_x");
		v.clear();
		const GroupRSA* grp = (GroupRSA*) g.at("pkGroup");
		v["l_x"] = lx;
		v["stat"] = grp->getStat();
		v["modSize"] = grp->getModulusLength();
		v["C"] = C;
		for(unsigned i = 0; i < publics.size(); i++)
			v["x_"+lexical_cast<string>(i+numPrivates+1)] = publics[i];
		prover.compute(v);
	
		// set up partial signature to include in message for recipient
		variable_map partialSig;
		variable_map pVars = prover.getEnvironment().variables;
		partialSig["A"] = pVars.at("A");
		partialSig["e"] = pVars.at("e");
		partialSig["vdoubleprime"] = pVars.at("vdoubleprime");
		
		variable_map p = prover.getPublicVariables();
		SigmaProof  pr = prover.computeProof(hashAlg);
		printTimer("[CLBlindIssuer] computed issuer proof");
		return new ProofMessage(partialSig, p, pr);
	} else {
		 throw CashException(CashException::CE_PARSE_ERROR,
                "[CLBlindIssuer::getPartialSignature] Proof did not verify");
	}
}
Beispiel #4
0
vector<ZZ> FEInitiator::pay(const vector<string>& keys) {
	if (TYPE_BUY != exchangeType)
		throw CashException(CashException::CE_FE_ERROR,
			"[FEInitiator::pay] Pay called on an FEInitiator not buying");
	
	if (keys.empty())
		throw CashException(CashException::CE_FE_ERROR,
			"[FEInitiator::pay] No key given");
	
	decryptCheck(keys);
	return endorsement;
}
Beispiel #5
0
ProofMessage* CLBlindRecipient::getC(const vector<SecretValue>& privates,
									 const hashalg_t &hashAlg) {
	if((int)privates.size() != numPrivates) 
		throw CashException(CashException::CE_SIZE_ERROR,
		"[CLBlindRecipient::getC] Number of private inputs does not match "
		"the number the recipient was constructed with");
	
	// add the private messages to the variable map, as well as the
	// randomness used to form their commitments
	for(unsigned i = 0; i < privates.size(); i++){
		string index = lexical_cast<string>(i+1);
		v["x_"+index] = privates[i].first;
		v["r_"+index] = privates[i].second;
	}
	// XXX: what about public messages?
	
	startTimer();
	prover.compute(v);
	variable_map publics = prover.getPublicVariables();
	SigmaProof proof = prover.computeProof(hashAlg);
	printTimer("[CLBlindRecipient] created proof");
	
	variable_map vals;
	variable_map pVars = prover.getEnvironment().variables;
	vals["C"] = pVars.at("C");
	vals["vprime"] = pVars.at("vprime");
	return new ProofMessage(vals, publics, proof);
}
Beispiel #6
0
string ProgramMaker::makeCLObtain(const string &grpPart, const string &comPart,
								  const string &comRelPart) {
	string program = "computation: "
						"given: " + grpPart + " "
							"integers: x[1:l], stat, modSize "
						"compute: "
							"random integer in [0,2^(modSize+stat)): vprime "
							"C := h^vprime * for(i, 1:l, *, g_i^x_i) "
					"proof: "
						"given:" + grpPart + " "
							"element in pkGroup: C " + comPart + " "
							"integer: l_x "
						"prove knowledge of: "
							"integers: x[1:l], r[1:l] "
							"exponent in pkGroup: vprime "
						"such that: "
							"for(i, 1:l, range: (-(2^l_x-1)) <= x_i < 2^l_x) "
							"C = h^vprime * for(i, 1:l, *, g_i^x_i) ";
	program += comRelPart;
	// now write this to file and return the file name
	ofstream writer;
	string fname = "ZKP/examples/cl-obtain-temp.txt";
	writer.open(fname.c_str(), ios::out);
	if (!writer)
		throw CashException(CashException::CE_PARSE_ERROR,
			"[ProgramMaker::makeCLObtain]: Could not write program to file");

	writer << program;
	writer.close();
	return fname;
}
Beispiel #7
0
int Wallet::nextCoinIndex() {
	if(numCoinsUsed >= walletSize) {
		throw CashException(CashException::CE_UNKNOWN_ERROR,
				"Tried to get the next coin from a wallet from which every "
				"coin had already been spent");
	}
	return spendOrder[numCoinsUsed++];
}
Beispiel #8
0
hashalg_t Hash::get_algbyname(const string &name) {
    for (int i=0; i < MAXALG; i++) {
        if (name == alg_names[i]) return (hashalg_t)i;
    }
    throw CashException(CashException::CE_UNKNOWN_ERROR,
                        "[Hash::get_algbyname] Can't find digest for %s", 
                        name.c_str());
}
Beispiel #9
0
BuyMessage* Buyer::buy(const vector<EncBuffer*>& ct, 
					   const vector<hash_t>& ptHash) {
	if (inProgress)
		throw CashException(CashException::CE_FE_ERROR,
			"[Buyer::buy] Buy called on an already working buyer");
	if (ct.empty())
		throw CashException(CashException::CE_FE_ERROR,
			"[Buyer::buy] No ciphertext given");
	if (ptHash.empty())
		throw CashException(CashException::CE_FE_ERROR,
			"[Buyer::buy] No plaintext hash given");
	// store ciphertexts
	ctext = ct;
	
	// compute hashes
	// XXX temporary fix: use regular hashes (size-1 hashes aren't matching)
	startTimer();
	hash_t ptHashMerkle = Hash::hash(ptHash, pk->hashAlg, pk->hashKey, 
									 Hash::TYPE_MERKLE);
	hash_t ctHashMerkle = Hash::hash(ctext, pk->hashAlg, pk->hashKey, 
									 Hash::TYPE_MERKLE);
	
	// create contract
	createContract();
	
	// set up the contract
	contract->setPTHashB(ptHashMerkle);
	contract->setCTHashB(ctHashMerkle);
	contract->setEncAlgB(ctext[0]->encAlg);
	contract->setPTHashBlocksB(ptHash.size());
	contract->setCTHashBlocksB(ctext.size());
	printTimer("[Buyer::buy] created contract");
	
	startTimer();
	// set up the escrow
	VECiphertext* escrow = new VECiphertext(makeEscrow());
	printTimer("[Buyer::buy] created escrow");

	// set inProgress
	inProgress = true;
	
	return new BuyMessage(coin, contract, escrow);
}
Beispiel #10
0
bool FEReceiver::checkSignature(string sig, string label){
    //The function verify is given by the cashlib library
    if (Signature::verify(*initiatorSignPK, sig, label, regularPK->hashAlg)){
        return true;
    }
    else{
        throw CashException(CashException::CE_FE_ERROR, "The signature does not verify");
    }
    return false;
}
Beispiel #11
0
FEMessage* FEInitiator::buy(const vector</*const*/ EncBuffer*>& ctextR,
							const vector</*const*/ hash_t>& ptHashR) {
	if (TYPE_NONE != exchangeType)
		throw CashException(CashException::CE_FE_ERROR,
			"[FEInitiator::buy] Buy called on an already working FEInitiator");
	
	if (ctextR.empty())
		throw CashException(CashException::CE_FE_ERROR,
			"[FEInitiator::buy] No ciphertext given");
	
	if (ptHashR.empty())
		throw CashException(CashException::CE_FE_ERROR,
			"[FEInitiator::buy] No plaintext hash given");
	
	// now decide that we are running a buy protocol
	exchangeType = TYPE_BUY;
	
	// store ciphertexts
	ctextB = ctextR;
	
	// compute hashes
	hash_t ptHashMerkle = Hash::hash(ptHashR, verifiablePK->hashAlg, 
									 verifiablePK->hashKey, 
									 Hash::TYPE_MERKLE);
	hash_t ctHashMerkle = Hash::hash(ctextB, verifiablePK->hashAlg, 
									 verifiablePK->hashKey, 
									 Hash::TYPE_MERKLE);
	
	// create contract
	if (NULL == contract)
		createContract();
	
	// set up the contract
	contract->setPTHashB(ptHashMerkle);
	contract->setCTHashB(ctHashMerkle);
	contract->setEncAlgB(ctextB[0]->encAlg);
	contract->setPTHashBlocksB(ptHashR.size());
	contract->setCTHashBlocksB(ctextR.size());
	
	string signature = signContract();
	return new FEMessage(signature, *contract);
}
Beispiel #12
0
long long elapsedTime() {
	timeval now;
	gettimeofday(&now, NULL);
	if (brownieTimerValue.size() == 0)
		throw CashException(CashException::CE_TIMER_ERROR, 
							"[Timer::printTimer] No running timer found. "
							"Maybe you forgot to start one?");
	long long elapsed = TV_DIFF_US(brownieTimerValue.back(), now);
	brownieTimerValue.pop_back();
	return elapsed;
}
Beispiel #13
0
vector<EncBuffer*> FEInitiator::continueRound(const vector<const Buffer*>& ptextI,
											  const cipher_t& encAlgI) {
	if (TYPE_NONE != exchangeType)
		throw CashException(CashException::CE_FE_ERROR,
							"[FEInitiator::continueRound] Barter called on an "
							"already working FEInitiator");
	
	setInitiatorFiles(ptextI, encrypt(ptextI,encAlgI));
	
	// decide we are running barter
	exchangeType = TYPE_BARTER;
	return ctextA;
}
Beispiel #14
0
vector<EncBuffer*> FEInitiator::encrypt(const vector<const Buffer*>& ptextI, 
										const cipher_t& encAlgI) const {
	if (ptextI.empty())
		throw CashException(CashException::CE_FE_ERROR,
			"[FEInitiator::encrypt] No initiator plaintext given");
	
	string key = Ciphertext::generateKey(encAlgI);
	vector<EncBuffer*> ctexts;
	for (unsigned i = 0; i < ptextI.size(); i++) {
		ctexts.push_back(ptextI[i]->encrypt(encAlgI, key));
	}
	return ctexts;
}
Beispiel #15
0
void UndefinedVariables::apply(ASTNodePtr n){
	// need to do two passes over the tree because things can be declared
	// in 'prove knowledge of' block and used in 'given' block and vice
	// versa
	n->visit(*this);
	n->visit(*this);
	for (def_map::iterator it = definedVars.begin();
						   it != definedVars.end(); ++it) {
			if (!it->second)
				throw CashException(CashException::CE_PARSE_ERROR,
							"%s has not been defined", it->first.c_str());
	}
}
Beispiel #16
0
bool BankTool::isCoinDoubleSpent(const Coin &coin1, const Coin &coin2) const {
	// throw an exception if these coins do not share the same S value
	if(coin1.getSPrime() != coin2.getSPrime())
	{
		throw CashException(CashException::CE_UNKNOWN_ERROR,
			"[BankTool::checkIfCoinDoubleSpent] Coins do not share same serial " 
			"coin point and are not valid candidates for checking double "
			"spending.");
	}
	
	// if contract hashes are same, then both coins were spent in the same 
	// transaction so the coin was not double spent
	return (coin1.getR() != coin2.getR());	 
}
Beispiel #17
0
hash_t Hash::hash(const char* data, size_t len,
                  const alg_t alg, const string &key, const int hashType)
{
	if (hashType == Hash::TYPE_PLAIN) {
		return hash(data, len, alg, key);
	} else if (hashType == Hash::TYPE_MERKLE) {
		MerkleContract contract(key, alg);
		MerkleTree tree(data, len, contract);
		return tree.getRoot();
	} else {
		throw CashException(CashException::CE_HASH_ERROR,
							"[Hash::hash] Unknown hash type used");
	}
}
Beispiel #18
0
vector<string> FEInitiator::giveKeys(const vector<string>& keysR) {
	// first check that we really are in barter
	if (TYPE_BARTER != exchangeType)
		throw CashException(CashException::CE_FE_ERROR, 
							"[FEInitiator::giveKeys] GiveKeys called on an "
							"FEInitiator not bartering");
	
	if (keysR.empty())
		throw CashException(CashException::CE_FE_ERROR,
			"[FEInitiator::giveKeys] No key given");
	
	decryptCheck(keysR);

	vector<string> keys;
	if (ctextA.size() > 1 && ctextA[0]->key == ctextA[1]->key)
		keys.push_back(ctextA[0]->key);
	else {
		for (unsigned i = 0; i < ctextA.size(); i++) {
			keys.push_back(ctextA[i]->key);
		}
	}
	return keys;
}
Beispiel #19
0
VarInfo ASTBinaryOp::getExprType(Environment &env) {
	VarInfo leftInfo;
	VarInfo rightInfo;
	// don't recompute types if we don't have to
	if (env.exprTypes.count(lhs->toString()) == 0) 
		leftInfo = lhs->getExprType(env);
	else 
		leftInfo = env.exprTypes.at(lhs->toString());
	if (env.exprTypes.count(rhs->toString()) == 0)
		rightInfo = rhs->getExprType(env);
	else
		rightInfo = env.exprTypes.at(rhs->toString());
	Type left = leftInfo.type;
	Type right = rightInfo.type;
	string lGrp = leftInfo.group;
	string rGrp = rightInfo.group;

	// integers can be mixed with anything without changing type
	// so can moduli (which are just integers)
	if (left == VarInfo::INTEGER || left == VarInfo::MODULUS) {
		VarInfo info(rGrp, right);
		env.exprTypes[toString()] = info;
		return info;
	}	
	else if (right == VarInfo::INTEGER || right == VarInfo::MODULUS) {
		VarInfo info(lGrp, left);
		env.exprTypes[toString()] = info;
		return info;
	}
	// exponents can be mixed in the same group
	else if (left == right && lGrp == rGrp && 
			 left == VarInfo::EXPONENT) {
		VarInfo info(lGrp, left);
		env.exprTypes[toString()] = info;
		return info;
	}
	// elements in the same group are okay
	else if (left == right && lGrp == rGrp && 
			 left == VarInfo::ELEMENT) {
		VarInfo info(lGrp, VarInfo::ELEMENT);
		env.exprTypes[toString()] = info;
		return info;
	}
	else {
		throw CashException(CashException::CE_PARSE_ERROR,
							"Cannot mix different types of variables");
	}
}
Beispiel #20
0
bool FEInitiator::decryptCheck(const vector<string>& keysR) {
	for (unsigned i = 0; i < ctextB.size(); i++) {
		// decrypt the ciphertext using key
		unsigned index = (keysR.size() == 1) ? 0 : i;
		Buffer* ptext = ctextB[i]->decrypt(keysR[index], contract->getEncAlgB());
		ptextB.push_back(ptext);
	}
	
	// compute hashes
	const hash_t& pt = contract->getPTHashB();
	hash_t ptHash = Hash::hash(ptextB, pt.alg, pt.key, pt.type);
	
	if (ptHash != pt)
		throw CashException(CashException::CE_FE_ERROR,
							"[FEInitiator::decryptCheck] The decrypted file was "
							"not the promised file");
	return true;
}
Beispiel #21
0
vector<ZZ> CommonFunctions::subvector(const vector<ZZ> &vec, unsigned start, 
									  unsigned length) {
	if(length < 1) {
		vector<ZZ> blank;
		return blank;
	}
	if(start >= vec.size() || start+length-1 >= vec.size()) {
		// the 1st check is actually redundant
		throw CashException(CashException::CE_SIZE_ERROR,
				"[CommonFunctions::subvector] Attempt to access elements "
				"beyond the end of the input vector");
	}
	vector<ZZ> result;
	for(unsigned i = 0; i < length; i++) {
		result.push_back(vec[start+i]);
	}
	return result;
}
Beispiel #22
0
VarInfo ASTPow::getExprType(Environment &env) {
	// can raise an element to an exponent, an integer to an exponent, 
	// and an element to an integer, and an integer to an integer
	// also for square stuff can raise an exponent to an integer
	pair<VarInfo,VarInfo> p = getTypes(env);
	VarInfo leftInfo = p.first;
	VarInfo rightInfo = p.second;
	Type left = leftInfo.type;
	Type right = rightInfo.type;
	string lGrp = leftInfo.group;
	string rGrp = rightInfo.group;

	if ((left == VarInfo::ELEMENT && right == VarInfo::EXPONENT) ||
		(left == VarInfo::ELEMENT && right == VarInfo::MODULUS)){
		VarInfo info(lGrp, left);
		env.exprTypes[toString()] = info;
		return info;
	}
	else if (left == VarInfo::EXPONENT && right == VarInfo::INTEGER) {
		VarInfo info(lGrp, left);
		env.exprTypes[toString()] = info;
		return info;
	}
	else if (left == VarInfo::ELEMENT && right == VarInfo::INTEGER) {
		VarInfo info(lGrp, left);
		env.exprTypes[toString()] = info;
		return info;
	}
	else if (left == VarInfo::INTEGER && right == VarInfo::EXPONENT) {
		VarInfo info(rGrp, VarInfo::ELEMENT);
		env.exprTypes[toString()] = info;
		return info;
	}
	else if (left == right && left == VarInfo::INTEGER) {
		VarInfo info(lGrp, left);
		env.exprTypes[toString()] = info;
		return info;
	}
	else {
		throw CashException(CashException::CE_PARSE_ERROR,
							"Cannot perform exponentiation with those variables");
	}
}	
Beispiel #23
0
hash_t Hash::hmac(const char* data, size_t len, const alg_t alg, const string& key)
{
    const EVP_MD *m;
    char digest[EVP_MAX_MD_SIZE];
    unsigned int dlen;

    m = get_MD(alg);

	if(!m)
		throw CashException(CashException::CE_UNKNOWN_ERROR,
							"[Hash::hmac] Can't find digest %s", alg);

    HMAC(m, key.data(), key.length(), 
	 (unsigned char *)data, len, 
	 (unsigned char *)digest, &dlen);

    // return C++ string container of digest
    hash_t ret(digest, dlen, alg, TYPE_PLAIN, key);
    return ret;
}
Beispiel #24
0
ZZ ASTDiv::eval(Environment &env) { 			
	pair<VarInfo,VarInfo> p = getTypes(env);
	VarInfo leftInfo = p.first;
	VarInfo rightInfo = p.second;
	// XXX: this will cause a problem if we ever try to use
	// it during constant propagation/substitution
	const Group* lGroup = env.groups.at(leftInfo.group);
	const Group* rGroup = env.groups.at(rightInfo.group);
	const Group* retGroup = (lGroup != 0 ? lGroup : rGroup);
	// integers can just be divided
	if ((lGroup == 0 && rGroup == 0) 
		|| (leftInfo.type == VarInfo::MODULUS 
			|| rightInfo.type == VarInfo::MODULUS)) {
		return lhs->eval(env) / rhs->eval(env);
	} else if (leftInfo.type == VarInfo::EXPONENT || 
			   rightInfo.type == VarInfo::EXPONENT) {
		// want to get LHS * inv(RHS)
		// this only works if we are in a group with known order
		if (retGroup->getType() == Group::TYPE_PRIME) {
			ZZ ord = retGroup->getOrder();
			ZZ right = InvMod(rhs->eval(env), ord);
			return lhs->eval(env) * right;
			// in an RSA group, only permit computing 1/x if the caller
			// knows the order of the group
		} else if(retGroup->getType() == Group::TYPE_RSA && 
				  (retGroup->getOrder() != 0)) {
			ZZ ord = retGroup->getOrder();
			ZZ right = InvMod(rhs->eval(env), ord);
			return lhs->eval(env) * right;
		} else {
			throw CashException(CashException::CE_PARSE_ERROR,
								"That operation is not permitted in an RSA group");
		}
	} else {
		assert(retGroup);
		ZZ mod = retGroup->getModulus();
		return MulMod(lhs->eval(env), InvMod(rhs->eval(env), mod), mod);
	}
}	
Beispiel #25
0
hash_t Hash::hash(const char *buf, int len, const alg_t alg)
{
	if (_brownie_hash_ctx.get() == 0)
		_brownie_hash_ctx.reset(EVP_MD_CTX_create());
	EVP_MD_CTX *ctx = _brownie_hash_ctx.get();

    const EVP_MD *m;
    char digest[EVP_MAX_MD_SIZE];
    unsigned int dlen;

    m = get_MD(alg);
    if(!m)
        throw CashException(CashException::CE_UNKNOWN_ERROR,
                            "[Hash::hash] Can't find digest %s", alg);

    EVP_DigestInit_ex(ctx, m, NULL);
    EVP_DigestUpdate(ctx, buf, len);
    EVP_DigestFinal_ex(ctx, (unsigned char *)digest, &dlen);

    // return HashVal container of digest
    hash_t ret(digest, dlen, alg, TYPE_PLAIN);
    return ret;
}
Beispiel #26
0
void TypeChecker::applyASTDeclRandExponents(ASTDeclRandExponentsPtr n) {
	
	ASTListDeclPtr exps = n->getExponents();
	string grpname = n->getGroup()->getName();

	ASTDeclIdentifierSubPtr exp;
	ASTDeclIDRangePtr expRange;
	VarInfo info(grpname, VarInfo::EXPONENT);
	for (int i = 0; i < exps->size(); i++) {
		ASTNodePtr ith = exps->get(i);
		if ((exp = dynamic_pointer_cast<ASTDeclIdentifierSub>(ith)) != 0){
			// associate exponent with its group
			env.varTypes[exp->getName()] = info;
		} else if((expRange=dynamic_pointer_cast<ASTDeclIDRange>(ith))!=0){
			for(int j = expRange->getLBound(); j <= expRange->getUBound(); j++){
				env.varTypes[expRange->getName(j)] = info;
			}
		} else { 
			throw CashException(CashException::CE_PARSE_ERROR,
					"Variable %d in list was not a valid exponent name", i);
		}
	}
}
Beispiel #27
0
string ProgramMaker::makeCLProve(const string &grpPart, const string &comPart,
								 const string &comRelPart) {
	string program = "computation: "
						"given:" + grpPart + " "
							"element in pkGroup: A "
							"exponents in pkGroup: e, v "
							"integers: x[1:l], modSize, stat "
						"compute: "
							"random integers in [0,2^(modSize+stat)): r, r_C "
							"vprime := v + r*e "
							"Aprime := A * h^r "
							"C := h^r_C * for(i, 1:l, *, g_i^x_i) "
							"D := for(i, l+1:l+k, *, g_i^x_i) "
					"proof: "
						"given:" + grpPart + " "
							"elements in pkGroup: C, D, Aprime " + comPart + " "
							"integers: l_x, x[l+1:l+k] "
						"prove knowledge of: "
							"integers: x[1:l], r[1:l] "
							"exponents in pkGroup: e, vprime, r_C "
						"such that: "
							"for(i, 1:l, range: (-(2^l_x-1)) <= x_i < 2^l_x) "
							"C = h^r_C * for(i, 1:l, *, g_i^x_i) "
							"f = C^(-1) * D^(-1) * (Aprime^e) * h^(r_C-vprime)";
	program += " " + comRelPart;
	// again, write to file and return filename
	ofstream writer;
	string fname = "ZKP/examples/cl-prove-temp.txt";
	writer.open(fname.c_str(), ios::out);
	if (!writer)
		throw CashException(CashException::CE_PARSE_ERROR,
			"[ProgramMaker::makeCLProve]: Could not write program to file");
	writer << program;
	writer.close();
	return fname;
}