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); }
ZZ Decryer::genHash(const ZZ sec, const ZZ ranZ){ unsigned char * secStr, ranZStr; BytesFromZZ(secStr, sec, _strLen); BytesFromZZ(ranZStr, ranZ, _strLen); unsigned char * shaSrc = strcat(secStr, ranZStr); unsigned char[SHA512_DIGEST_LENGTH] shaRes; SHA512(shaSrc, 2*_strLen, shaRes); return ZZFromBytes(shaRes, _strLen); }
void ZZFromHex(ZZ &a, char s[]) { byte bt[MAXB]; long num; long slen = strlen(s); num = slen%2 ? slen/2+1 : slen/2; BytesFromHex(bt, s); ZZFromBytes(a, bt, num); }
void PaillierParty::receiveZZFrom(ZZ& element, const boost::shared_ptr<CSocket> &socket) { int numBytes; socket->Receive(&numBytes,sizeof(int)); vector<uint8_t> arr(numBytes); socket->Receive(arr.data(),numBytes); ZZFromBytes(element, arr.data(),numBytes); }
/* Copies the mpz_t into the ZZ AUTHOR: Joel B. Mohler (2007-03-15) */ static void mpz_to_ZZ(struct ZZ* output, mpz_srcptr x) { unsigned char stack_bytes[4096]; size_t size = (mpz_sizeinbase(x, 2) + 7) / 8; int use_heap = (size > sizeof(stack_bytes)); void* bytes = use_heap ? malloc(size) : stack_bytes; size_t words_written; mpz_export(bytes, &words_written, -1, 1, 0, 0, x); clear(*output); ZZFromBytes(*output, (unsigned char *)bytes, words_written); if (mpz_sgn(x) < 0) NTL::negate(*output, *output); if (use_heap) free(bytes); }
//Функция приёма ZZ числа int MPI_NTL_Recv(ZZ& x, int process_id) { MPI_Status status; unsigned char * buf; ntl_params def_data; MPI_Recv(&def_data,sizeof(ntl_params),MPI_CHAR,process_id,MPI_NTL_SIGN,MPI_COMM_WORLD,&status); if (def_data.size>0) { buf = new unsigned char [def_data.size]; MPI_Recv(buf,def_data.size,MPI_CHAR,process_id,MPI_NTL_DATA,MPI_COMM_WORLD,&status); ZZFromBytes(x,buf,def_data.size); x*=def_data.sign; delete [] buf; } else { x=0; } return 0; };
bool NTL_Unpack(ZZ& x, unsigned char * buf, int& buf_ub, int buf_size) { if (buf_ub>=buf_size) return false; ntl_params def_data; memcpy(&def_data,&(buf[buf_ub]),sizeof(def_data)); buf_ub+=sizeof(def_data); if (def_data.size>0) { unsigned char * temp_buf = new unsigned char [def_data.size]; memcpy(temp_buf,&(buf[buf_ub]),def_data.size); ZZFromBytes(x,temp_buf,def_data.size); buf_ub+=def_data.size; delete [] temp_buf; } else { x=0; } x*=def_data.sign; return true; };
//Функция широковещательной рассылки ZZ числа int MPI_NTL_Bcast(ZZ& x, int process_id) { unsigned char * buf; ntl_params def_data; def_data.size = NumBytes(x); def_data.sign = x>=0?1:-1; MPI_Bcast(&def_data,sizeof(ntl_params),MPI_CHAR,process_id,MPI_COMM_WORLD); if (def_data.size >0) { buf = new unsigned char [def_data.size]; BytesFromZZ(buf,x,def_data.size); MPI_Bcast(buf,def_data.size,MPI_CHAR,process_id,MPI_COMM_WORLD); ZZFromBytes(x,buf,def_data.size); x*=def_data.sign; delete [] buf; } else { x=0; } return 0; };
static void seed(void) { int fd; unsigned char randbuf[RANDBYTES]; if ( (fd = open("/dev/urandom", O_RDONLY, 0)) < 0) { cerr << "Error: Can't open /dev/urandom." << endl; exit(1); } if (read(fd, randbuf, RANDBYTES) != RANDBYTES) { cerr << "Error: Can't read from /dev/urandom." << endl; exit(1); } if (close(fd) < 0) { cerr << "Error: Can't close /dev/urandom." << endl; exit(1); } SetSeed(ZZFromBytes(randbuf, RANDBYTES)); }
void CServer::RunOTThread() { cout << "\not thread started\n" << flush; // IKNP-first step: receiver of Naor-Pinkas ZZ& p = CConfig::GetInstance()->GetPrime(); ZZ q = p/2 - 1; ZZ& g = CConfig::GetInstance()->GetGenerator(); // NP receiver: receive Cs int nBufSize = NUM_EXECS_NAOR_PINKAS * FIELD_SIZE_IN_BYTES; BYTE* pBuf = new BYTE[nBufSize]; m_sockOT.Receive(pBuf, nBufSize); ZZ* pC = new ZZ[NUM_EXECS_NAOR_PINKAS]; BYTE* pBufIdx = pBuf; for(int i=0, idx=0; i<NUM_EXECS_NAOR_PINKAS; i++) { ZZFromBytes(pC[i], pBufIdx, FIELD_SIZE_IN_BYTES); pBufIdx += FIELD_SIZE_IN_BYTES; #ifdef _DEBUG cout << "pC[" << i <<"]: " << pC[i] << endl; #endif } // compute pk0, pk1 CBitVector rnd; rnd.Create(NUM_EXECS_NAOR_PINKAS*FIELD_SIZE_IN_BITS, m_aSeed, m_nCounter); BYTE* pBufRnd = rnd.GetArr(); ZZ* pK = new ZZ[NUM_EXECS_NAOR_PINKAS]; ZZ ztmp; for(int i=0, idx=0; !m_bStop && i<NUM_EXECS_NAOR_PINKAS; i++) { ZZFromBytes(ztmp, pBufRnd, FIELD_SIZE_IN_BYTES); pBufRnd += FIELD_SIZE_IN_BYTES; rem(pK[i], ztmp, q); } pBufIdx = pBuf; ZZ pk0, pk1; for(int i=0, idx=0; !m_bStop && i<NUM_EXECS_NAOR_PINKAS; i++) { // compute pk0, pk1 if( !m_S.GetBit(i) ) { PowerMod(pk0, g, pK[i], p); } else { PowerMod(pk1, g, pK[i], p); //pk0 = pC[i]/pk1; InvMod(ztmp, pk1, p); MulMod(pk0, pC[i], ztmp, p); } #ifdef _DEBUG cout << "pk0[" << i << "]: " << pk0 << endl; #endif // put pk0 BytesFromZZ(pBufIdx, pk0, FIELD_SIZE_IN_BYTES); pBufIdx += FIELD_SIZE_IN_BYTES; } m_sockOT.Send(pBuf, nBufSize); delete [] pC; delete [] pBuf; if( m_bStop ) return; // NP receiver: get the g^r0, Enc(M0), g^r2, Enc(M1) int nInputStart = m_pCircuit->GetInputStart(ID_CLIENT); int nInputEnd = m_pCircuit->GetInputEnd(ID_CLIENT); int nMsgSize = (nInputEnd-nInputStart)/SHA1_BITS + 1; // in sha1 scale int nMsginOT = FIELD_SIZE_IN_BYTES + nMsgSize*SHA1_BYTES; int nBufSize2 = NUM_EXECS_NAOR_PINKAS * nMsginOT * 2; BYTE* pBuf2 = new BYTE[nBufSize2]; m_sockOT.Receive(pBuf2, nBufSize2); ZZ w; ZZ key; BYTE tmp[FIELD_SIZE_IN_BYTES]; sha1_context sha; SHA_BUFFER buf_key; BYTE** ppMat = new BYTE*[NUM_EXECS_NAOR_PINKAS]; BYTE* pBufToRead; BYTE* pBufMatIdx; pBufIdx = pBuf2; for(int i=0, idx=0; !m_bStop && i<NUM_EXECS_NAOR_PINKAS; i++) { ppMat[i] = new BYTE[nMsgSize*SHA1_BYTES]; if( !m_S.GetBit(i)) { pBufToRead = pBufIdx; pBufIdx += nMsginOT + nMsginOT; } else { pBufIdx += nMsginOT; pBufToRead = pBufIdx; pBufIdx += nMsginOT; } ZZFromBytes(w, pBufToRead, FIELD_SIZE_IN_BYTES); pBufToRead += FIELD_SIZE_IN_BYTES; PowerMod(key, w, pK[i], p); BytesFromZZ(tmp, key, FIELD_SIZE_IN_BYTES); sha1_starts(&sha); sha1_update(&sha, tmp, FIELD_SIZE_IN_BYTES); sha1_finish(&sha, (BYTE*) &buf_key); pBufMatIdx=ppMat[i]; for(int j=0; j<nMsgSize; j++) { sha1_starts(&sha); sha1_update(&sha, (BYTE*) &buf_key, sizeof(buf_key)); sha1_update(&sha, (BYTE*) &j, sizeof(int)); sha1_finish(&sha, tmp); for(int x=0; x<SHA1_BYTES; x++, pBufMatIdx++, pBufToRead++ ) { *(pBufMatIdx) = *(pBufToRead) ^ tmp[x]; } } } delete [] pK; if( m_bStop ) return; // IKNP-second step: send the keys for client inputs int nInputSize = nInputEnd - nInputStart + 1; KEY* pKeys = new KEY[nInputSize*2]; YAO_WIRE* wire; KEY* wirekey; CBitVector qj; qj.Create(NUM_EXECS_NAOR_PINKAS); int j=0; // 0-starting index KEY* pKeyIdx = pKeys; for(int i=nInputStart; !m_bStop && i<=nInputEnd; i++,j++) { while( m_nGatesDone < i ) { SleepMiliSec(100); } // compute qj for(int r=0; r<NUM_EXECS_NAOR_PINKAS; r++) { qj.SetBit( r, ppMat[r][j/8] & bitmask[j & 0x7] ); } // compute hash sha1_starts(&sha); sha1_update(&sha, qj.GetArr(), NUM_EXECS_NAOR_PINKAS/8); sha1_update(&sha, (BYTE*)&j, sizeof(int)); sha1_finish(&sha, (BYTE*)&buf_key); // y0 wire = m_pYaoWires+i; wirekey = wire->keys + wire->b; XOR_KEYP3( pKeyIdx, (&buf_key), wirekey ); pKeyIdx++; // compute qj xor s for(int x=0; x<NUM_EXECS_NAOR_PINKAS/8; x++ ) qj.GetArr()[x] ^= m_S.GetByte(x); /* #ifdef _DEBUG cout << "qj xor s = "; for(int z=0; z<NUM_EXECS_NAOR_PINKAS; z++) cout << (int) qj.GetBit(z); cout << endl; #endif */ // y1 sha1_starts(&sha); sha1_update(&sha, qj.GetArr(), NUM_EXECS_NAOR_PINKAS/8); sha1_update(&sha, (BYTE*)&j, sizeof(int)); sha1_finish(&sha, (BYTE*)&buf_key); wirekey = wire->keys + (wire->b^1); XOR_KEYP3( pKeyIdx, (&buf_key), wirekey ); pKeyIdx++; } m_sockOT.Send( pKeys, nInputSize*sizeof(KEY)*2); // clean-up delete [] pBuf2; for(int i=0; i<NUM_EXECS_NAOR_PINKAS; i++) { delete [] ppMat[i]; } delete [] ppMat; delete [] pKeys; cout << "\not thread ended \n" << flush; }