Exemplo n.º 1
0
bool nnobRevealOblivBit(ProtocolDesc* pd, NnobProtocolDesc* npd, bool* output, 
		OblivBit* input)
{
	bool success = true;
	nnob_key_t inputMac;
	bool inputBit;
	if(pd->thisParty==1)
	{
		osend(pd, 2, input->nnob.shareAndMac.mac, NNOB_KEY_BYTES);
		osend(pd, 2, &input->nnob.shareAndMac.share, 1);

		orecv(pd, 2, inputMac, NNOB_KEY_BYTES);
		orecv(pd, 2, &inputBit, 1);
		if(inputBit) memxor(inputMac, npd->globalDelta, NNOB_KEY_BYTES);
		success&=memcmp(inputMac, input->nnob.key.key,NNOB_KEY_BYTES)==0?true:false;
	}
	else
	{
		orecv(pd, 1, inputMac, NNOB_KEY_BYTES);
		orecv(pd, 1, &inputBit, 1);
		if(inputBit) memxor(inputMac, npd->globalDelta, NNOB_KEY_BYTES);
		success&=memcmp(inputMac, input->nnob.key.key,NNOB_KEY_BYTES)==0?true:false;

		osend(pd, 1, input->nnob.shareAndMac.mac, NNOB_KEY_BYTES);
		osend(pd, 1, &input->nnob.shareAndMac.share, 1);
	}
	*output = inputBit^input->nnob.shareAndMac.share;
	assert(success);
	return success;
}
Exemplo n.º 2
0
void nnobANDGetSKey(ProtocolDesc* pd, 
		NnobKey* s, NnobShareAndMac* r, const NnobShareAndMac* x, const NnobKey* y)
{
	NnobProtocolDesc* npd = pd->extra;
	assert(npd!=NULL);
	NnobShareAndMac u0, u1, f, g;
	bool other_d;
	NnobKey c, w, d;
	int destparty = pd->thisParty==1?1:2;
	getRandomAOTQuadrupleKeyOfZ(npd, &u0, &u1, &c, &w);
	d=c;	
	nnobKeyXOR(&d, y);
	orecv(pd, destparty, &other_d, 1);
	hashMacCheckKey(npd, &d, other_d);

	f=u0;
	nnobShareAndMacXOR(&f, &u1);
	nnobShareAndMacXOR(&f, x);
	g=u0;
	nnobShareAndMacXOR(&g, r);
	if(other_d) nnobShareAndMacXOR(&g, x);
	osend(pd, destparty, &f.share, 1);
	osend(pd, destparty, &g.share, 1);
	hashMacCheckShareAndMac(npd, &f);
	hashMacCheckShareAndMac(npd, &g);

	*s=w;
	if(f.share) nnobKeyXOR(s, &c);
	nnobKeyXORConst(s, g.share, npd->globalDelta);
}
Exemplo n.º 3
0
void LaOTCombineKeyOfZ(ProtocolDesc* pd,  
		NnobShareAndMac* x10, const NnobShareAndMac* x20, 
		NnobShareAndMac* x11, const NnobShareAndMac* x21, 
		NnobKey* c1, const NnobKey* c2, 
		NnobKey* z1, const NnobKey* z2, 
		const unsigned* permutation, int n, int k) {
	bool* d = malloc(n);
	int i,pos,destparty = pd->thisParty==1?1:2;
	for(i=0;i<n;i++) {
		pos = permutation[i+k*n];
		d[i]=x10[i].share^x11[i].share^
			x20[pos].share^x21[pos].share;
	}
	osend(pd, destparty, d, n);
	for(i=0;i<n;i++) {
		pos = permutation[i+k*n];
		nnobKeyXOR(&z1[i], &z2[pos]);
		if(d[i]) nnobKeyXOR(&z1[i], &c1[i]); 
		nnobKeyXOR(&c1[i], &c2[pos]);
		x11[i]=x10[i];
		nnobShareAndMacXOR(&x11[i], &x21[pos]);
		nnobShareAndMacXOR(&x10[i], &x20[pos]);
	}
	free(d);
}
Exemplo n.º 4
0
void nnobANDGetSShareAndMac(ProtocolDesc* pd, 
		NnobShareAndMac* s, NnobKey* r, const NnobKey* x, const NnobShareAndMac* y)
{
	NnobProtocolDesc* npd = pd->extra;
	assert(npd!=NULL);
	NnobKey u0, u1, f, g;
	NnobShareAndMac c, w, d; 
	bool other_f, other_g;
	int destparty = pd->thisParty==1?1:2;
	getRandomAOTQuadrupleShareAndMacOfZ(npd, &u0, &u1, &c, &w);
	d=c;
	nnobShareAndMacXOR(&d, y);
	osend(pd, destparty, &d.share, 1);
	hashMacCheckShareAndMac(npd, &d);
	f=u0;
	nnobKeyXOR(&f, &u1);
	nnobKeyXOR(&f, x);
	g=*r;
	nnobKeyXOR(&g, &u0);
	if(d.share) nnobKeyXOR(&g, x);
	orecv(pd, destparty, &other_f, 1);
	orecv(pd, destparty, &other_g, 1);
	hashMacCheckKey(npd, &f, other_f);
	hashMacCheckKey(npd, &g, other_g);

	*s=w;
	if(other_f) nnobShareAndMacXOR(s, &c);
	nnobShareAndMacXORConst(s, other_g);
}
Exemplo n.º 5
0
void nnobANDGetXYShareAndMac(ProtocolDesc* pd,  
		NnobShareAndMac* xy, const NnobShareAndMac* x, const NnobShareAndMac* y) {
	NnobProtocolDesc* npd = pd->extra;
	assert(npd!=NULL);
	int destparty=pd->thisParty==1?1:2;
	
	NnobShareAndMac u,v,w,f,g;
	getRandomAANDTripleShareAndMac(npd, &u, &v, &w);
	f=u;
	nnobShareAndMacXOR(&f, x);
	g=v;
	nnobShareAndMacXOR(&g, y);
	osend(pd, destparty, &f.share, 1);	
	osend(pd, destparty, &g.share, 1);	
	hashMacCheckShareAndMac(npd, &f);
	hashMacCheckShareAndMac(npd, &g);
	*xy = w;
	if(f.share) nnobShareAndMacXOR(xy, y);
	if(g.share) nnobShareAndMacXOR(xy, x);
	if(f.share&&g.share) nnobShareAndMacXORConst(xy, true);
}
Exemplo n.º 6
0
void LaANDCombineShareAndMac(ProtocolDesc* pd, 
		NnobShareAndMac* x1, const NnobShareAndMac* x2,  
		NnobShareAndMac* y1, const NnobShareAndMac* y2, 
		NnobShareAndMac* z1, const NnobShareAndMac* z2) {

	bool d;	
	int destparty = pd->thisParty==1?1:2;
	d=y1->share^y2->share;	
	osend(pd, destparty, &d, 1);
	nnobShareAndMacXOR(z1, z2);
	if(d) nnobShareAndMacXOR(z1, x2);
	nnobShareAndMacXOR(x1, x2);
}
Exemplo n.º 7
0
bool aOTShareAndMacOfZ(ProtocolDesc *pd, AOTShareAndMacOfZ* sm) {
	NnobProtocolDesc* npd = pd->extra;
	assert(npd!=NULL);
	int i,k, bucketSize = npd->bucketSize, n = sm->n, numLaOTs = sm->n*bucketSize, 
		destparty = pd->thisParty==1?1:2;
	bool success = true;
	unsigned* permutation = malloc(numLaOTs*sizeof(unsigned));
	NnobKey* LaOTx0 = malloc(numLaOTs*sizeof(NnobKey)); 
	NnobKey* LaOTx1 = malloc(numLaOTs*sizeof(NnobKey)); 
	NnobShareAndMac* LaOTc = malloc(numLaOTs*sizeof(NnobShareAndMac)); 
	NnobShareAndMac* LaOTr = malloc(numLaOTs*sizeof(NnobShareAndMac)); 
	NnobShareAndMac* LaOTz = malloc(numLaOTs*sizeof(NnobShareAndMac)); 
	BCipherRandomGen* gen = newBCipherRandomGen();
	BCipherRandomGen* padder = newBCipherRandomGen();
	int nonce = 0;

	for(i=0;i<numLaOTs;i++)
	{
		randomOblivAuthenticationKey(npd, &LaOTx0[i]);
		randomOblivAuthenticationKey(npd, &LaOTx1[i]);
		randomOblivAuthenticationShareAndMac(npd, &LaOTc[i]);
		randomOblivAuthenticationShareAndMac(npd, &LaOTr[i]);
	}
	success &= LaOTShareAndMacOfZ(pd, LaOTx0, LaOTx1, LaOTc, LaOTr, LaOTz,
			padder, gen, &nonce, numLaOTs);	
	bcRandomPermutation(gen, permutation, numLaOTs);	
	osend(pd, destparty, permutation, numLaOTs*sizeof(unsigned));
	for(i=0;i<n;i++) {
		sm->x0[i]=LaOTx0[permutation[i]];
		sm->x1[i]=LaOTx1[permutation[i]];
		sm->c[i]=LaOTc[permutation[i]];
		sm->z[i]=LaOTz[permutation[i]];
	}

	for(k=1;k<bucketSize;k++) {
		LaOTCombineShareAndMacOfZ(pd, sm->x0, LaOTx0,
				sm->x1, LaOTx1,
				sm->c, LaOTc,
				sm->z, LaOTz,
				permutation, n, k);
	}
	free(permutation);
	releaseBCipherRandomGen(gen);
	releaseBCipherRandomGen(padder);
	free(LaOTx0);
	free(LaOTx1);
	free(LaOTc);
	free(LaOTr);
	free(LaOTz);
	return success;
}
Exemplo n.º 8
0
void nnobSendBitOblivInputs(ProtocolDesc* pd, OblivBit* oblivInput, bool b, int destparty)
{
	NnobProtocolDesc* npd = pd->extra;
	bool sendbit;
	char const* globalDelta = npd->globalDelta;
	randomOblivAuthenticationShareAndMac(npd, &oblivInput->nnob.shareAndMac);	
	sendbit = b^oblivInput->nnob.shareAndMac.share;
	osend(pd, destparty, &sendbit, 1);
	memset(oblivInput->nnob.key.key, 0, NNOB_KEY_BYTES);
	nnobKeyXORConst(&oblivInput->nnob.key, sendbit, globalDelta);
	oblivInput->unknown=true;
	debugPrintOblivBit(oblivInput);
	nl();
}
Exemplo n.º 9
0
void debugNnobSendOblivInput(ProtocolDesc* pd, bool* input, OblivBit* oblivInput, 
		int numOblivInput)
{
	NnobProtocolDesc* npd = pd->extra;
	int i, destparty = pd->thisParty==1?1:2; 
	bool* b = malloc(numOblivInput);
	char const* globalDelta = npd->globalDelta;
	for(i=0;i<numOblivInput;i++) {
		randomOblivAuthenticationShareAndMac(npd, &oblivInput[i].nnob.shareAndMac);	
		b[i] = input[i] ^ oblivInput[i].nnob.shareAndMac.share;
		memset(oblivInput[i].nnob.key.key, 0, NNOB_KEY_BYTES);
		nnobKeyXORConst(&oblivInput[i].nnob.key, b[i], globalDelta);
	}
	osend(pd, destparty, b, numOblivInput);
	free(b);
}
Exemplo n.º 10
0
void nnobRevealOblivInputsSend(ProtocolDesc* pd, widest_t* dest,const OblivBit* o,size_t n, bool* share ,int destparty) {
	NnobProtocolDesc* npd = pd->extra;
	int i;
	fprintf(stderr, "B\n");
	for(i=0;i<n;i++) {
		share[i]=o[i].nnob.shareAndMac.share;
		hashMacCheckShareAndMac(npd, &o[i].nnob.shareAndMac);
	}
	osend(pd, destparty, share, n);
	fprintf(stderr, "error? = %d\n", npd->error);
	npd->error |= !ocEqualityCheck(pd, npd->gen, npd->cumulativeHashCheckMac,NNOB_KEY_BYTES, destparty);
	fprintf(stderr, "error? = %d\n", npd->error);
	npd->nonce+=1;
	assert(!npd->error);
	fprintf(stderr, "in nnobRevealOblivInputs\n");
}
Exemplo n.º 11
0
bool aANDShareAndMac(ProtocolDesc *pd, AANDShareAndMac* sm) {
	NnobProtocolDesc* npd = pd->extra;
	assert(npd!=NULL);
	int i,k,n = sm->n,bucketSize = npd->bucketSize, numLaANDs = n*bucketSize,
		nonce = 0, destparty = pd->thisParty==1?1:2;
	bool success = true;
	unsigned* permutation = malloc(numLaANDs*sizeof(unsigned));
	NnobShareAndMac* LaANDx = malloc(numLaANDs*sizeof(NnobShareAndMac)); 
	NnobShareAndMac* LaANDy = malloc(numLaANDs*sizeof(NnobShareAndMac)); 
	NnobShareAndMac* LaANDr = malloc(numLaANDs*sizeof(NnobShareAndMac)); 
	NnobShareAndMac* LaANDz = malloc(numLaANDs*sizeof(NnobShareAndMac)); 
	char dummy[NNOB_HASH_ALGO_KEYBYTES];
	BCipherRandomGen* gen = newBCipherRandomGen();
	BCipherRandomGen* padder = newBCipherRandomGenByAlgoKey(NNOB_HASH_ALGO, dummy);

	for(i=0;i<numLaANDs;i++) {
		randomOblivAuthenticationShareAndMac(npd, &LaANDx[i]);
		randomOblivAuthenticationShareAndMac(npd, &LaANDy[i]);
		randomOblivAuthenticationShareAndMac(npd, &LaANDr[i]);
	}
	success &= LaANDShareAndMac(pd, LaANDx, LaANDy, LaANDr, LaANDz,
			padder, gen, &nonce, numLaANDs);	
	assert(success);

	bcRandomPermutation(gen, permutation, numLaANDs);	
	osend(pd, destparty, permutation, numLaANDs*sizeof(unsigned));

	for(i=0;i<n;i++) {
		sm->x[i]=LaANDx[permutation[i]];
		sm->y[i]=LaANDy[permutation[i]];
		sm->z[i]=LaANDz[permutation[i]];
	}

	for(k=1;k<bucketSize;k++) {
		for(i=0;i<n;i++) {
			LaANDCombineShareAndMac(pd, &sm->x[i], &LaANDx[permutation[i+k*n]],
					&sm->y[i], &LaANDy[permutation[i+k*n]],
					&sm->z[i], &LaANDz[permutation[i+k*n]]);
		}
	}
	free(permutation);
	releaseBCipherRandomGen(gen);
	releaseBCipherRandomGen(padder);
	free(LaANDx); free(LaANDy); free(LaANDr); free(LaANDz);
	return success;
}
Exemplo n.º 12
0
bool LaANDKey(ProtocolDesc* pd, 
		const NnobKey* x, const NnobKey* y, 
		const NnobKey* r, NnobKey* z, 
		BCipherRandomGen* padder, BCipherRandomGen* gen, 
		int* nonce, int numLaANDs) {

	NnobProtocolDesc* npd = pd->extra;
	assert(npd!=NULL);
	int i, destparty = pd->thisParty==1?1:2;
	bool* d = malloc(numLaANDs);
	char (*U)[NNOB_KEY_BYTES] = malloc(numLaANDs*NNOB_KEY_BYTES);
	char (*V)[NNOB_KEY_BYTES] = malloc(numLaANDs*NNOB_KEY_BYTES);
	char temp[2*NNOB_KEY_BYTES];
	char temp2[NNOB_KEY_BYTES];
	char zeroes[NNOB_KEY_BYTES];
	memset(zeroes, 0, NNOB_KEY_BYTES);
	const char* globalDelta = npd->globalDelta;
	bool success = true;
	orecv(pd, destparty, d, numLaANDs);
	for(i=0;i<numLaANDs;i++)
	{
		z[i]=r[i];
		nnobKeyXORConst(&z[i], d[i], globalDelta);
		/*assert(z[i].ShareAndMac.value == (x[i].ShareAndMac.value && y[i].ShareAndMac.value));*/
		memcpy(temp, x[i].key, NNOB_KEY_BYTES);
		memcpy(temp+NNOB_KEY_BYTES, z[i].key, NNOB_KEY_BYTES);
		nnobHash(padder, temp, 2*NNOB_KEY_BYTES, *nonce, temp2, zeroes);

		memcpy(temp, x[i].key, NNOB_KEY_BYTES);
		memxor(temp, globalDelta, NNOB_KEY_BYTES);
		memcpy(temp+NNOB_KEY_BYTES, y[i].key, NNOB_KEY_BYTES);
		memxor(temp+NNOB_KEY_BYTES, z[i].key, NNOB_KEY_BYTES);
		nnobHash(padder, temp, 2*NNOB_KEY_BYTES, *nonce, U[i], temp2);
	}
	osend(pd, destparty, U, NNOB_KEY_BYTES*numLaANDs);
	for(i=0;i<numLaANDs;i++) {
		memcpy(V[i], temp2, NNOB_KEY_BYTES);
		*nonce+=1;
	}
	success &= ocEqualityCheck(pd, gen, V, numLaANDs*NNOB_KEY_BYTES, destparty);
	free(d); free(U); free(V);
	return success;
}
Exemplo n.º 13
0
bool LaANDShareAndMac(ProtocolDesc* pd, 
		const NnobShareAndMac* x, const NnobShareAndMac* y, 
		const NnobShareAndMac* r, NnobShareAndMac* z, 
		BCipherRandomGen* padder, BCipherRandomGen* gen, 
		int* nonce, int numLaANDs) {

	int i, destparty = pd->thisParty==1?1:2;
	bool* d = malloc(numLaANDs);
	char (*U)[NNOB_KEY_BYTES] = malloc(numLaANDs*NNOB_KEY_BYTES);
	char (*V)[NNOB_KEY_BYTES] = malloc(numLaANDs*NNOB_KEY_BYTES);
	char temp[2*NNOB_KEY_BYTES];
	char zeroes[NNOB_KEY_BYTES];
	memset(zeroes, 0, NNOB_KEY_BYTES);
	bool success = true;

	for(i=0;i<numLaANDs;i++) {
		z[i].share = x[i].share && y[i].share;	
		d[i] = z[i].share^r[i].share;
	}
	osend(pd, destparty, d, numLaANDs);
	for(i=0;i<numLaANDs;i++) {
		z[i]=r[i];
		nnobShareAndMacXORConst(&z[i], d[i]);
		/*assert(z[i].ShareAndMac.value == (x[i].ShareAndMac.value && y[i].ShareAndMac.value));*/
	}
	orecv(pd, destparty, U, NNOB_KEY_BYTES*numLaANDs);
	for(i=0;i<numLaANDs;i++) {
		memcpy(temp, x[i].mac, NNOB_KEY_BYTES);
		memcpy(temp+NNOB_KEY_BYTES, z[i].mac, NNOB_KEY_BYTES);
		if(x[i].share) {
			memxor(temp+NNOB_KEY_BYTES, y[i].mac, NNOB_KEY_BYTES);
			nnobHash(padder, temp, 2*NNOB_KEY_BYTES, *nonce, V[i], U[i]);
		}
		else {
			nnobHash(padder, temp, 2*NNOB_KEY_BYTES, *nonce, V[i], zeroes);
		}
		*nonce+=1;
	}
	success &= ocEqualityCheck(pd, gen, V, numLaANDs*NNOB_KEY_BYTES, destparty);
	free(d); free(U); free(V);
	return success;
}
Exemplo n.º 14
0
static int
linux_send(struct proc *p, struct linux_send_args *args, int *retval)
{
    struct linux_send_args linux_args;
    struct osend_args /* {
	int s;
	caddr_t buf;
	int len;
	int flags;
    } */ bsd_args;
    int error;

    if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args))))
	return error;
    bsd_args.s = linux_args.s;
    bsd_args.buf = linux_args.msg;
    bsd_args.len = linux_args.len;
    bsd_args.flags = linux_args.flags;
    return osend(p, &bsd_args, retval);
}
Exemplo n.º 15
0
bool LaOTKeyOfZ(ProtocolDesc* pd, const NnobShareAndMac* x0, 
		const NnobShareAndMac* x1, const NnobKey* c,
		const NnobKey* r, NnobKey* z,  BCipherRandomGen* padder, 
		BCipherRandomGen* gen, int* nonce, int numLaOTs) {

	NnobProtocolDesc* npd = pd->extra;
	assert(npd!=NULL);
	int i, destparty = pd->thisParty==1?1:2;
	bool success = true;
	const int XOTBytes = 1+2*NNOB_KEY_BYTES;
	char (*X0)[XOTBytes] = malloc(numLaOTs*XOTBytes);
	char (*X1)[XOTBytes] = malloc(numLaOTs*XOTBytes);
	char (*I0)[NNOB_KEY_BYTES] = malloc(numLaOTs*NNOB_KEY_BYTES);
	char (*I1)[NNOB_KEY_BYTES] = malloc(numLaOTs*NNOB_KEY_BYTES);
	char (*T0)[NNOB_KEY_BYTES] = malloc(numLaOTs*NNOB_KEY_BYTES);
	char (*T1)[NNOB_KEY_BYTES] = malloc(numLaOTs*NNOB_KEY_BYTES);
	char temp[NNOB_KEY_BYTES];
	char (*mc)[XOTBytes] = malloc(numLaOTs*XOTBytes); 
	bool* d = malloc(numLaOTs);
	const char* globalDelta = npd->globalDelta;
	
	for(i=0;i<numLaOTs;i++) {
		char m0[XOTBytes], m1[XOTBytes];
		randomizeBuffer(gen, T0[i], NNOB_KEY_BYTES);
		randomizeBuffer(gen, T1[i], NNOB_KEY_BYTES);

		m0[0] = x0[i].share;
		memcpy(m0+1, x0[i].mac, NNOB_KEY_BYTES);
		if(x0[i].share) memcpy(m0+1+NNOB_KEY_BYTES, T1[i], NNOB_KEY_BYTES);
		else memcpy(m0+1+NNOB_KEY_BYTES, T0[i], NNOB_KEY_BYTES);

		m1[0] = x1[i].share;
		memcpy(m1+1, x1[i].mac, NNOB_KEY_BYTES);
		if(x1[i].share) memcpy(m1+1+NNOB_KEY_BYTES, T1[i], NNOB_KEY_BYTES);
		else memcpy(m1+1+NNOB_KEY_BYTES, T0[i], NNOB_KEY_BYTES);

		nnobPRG(padder, c[i].key, NNOB_KEY_BYTES, *nonce, X0[i], m0, XOTBytes);	
		memcpy(temp, c[i].key, NNOB_KEY_BYTES);
		memxor(temp, globalDelta, NNOB_KEY_BYTES);
		nnobPRG(padder, temp, NNOB_KEY_BYTES, *nonce, X1[i], m1, XOTBytes);	
		*nonce+=1;
	}
	osend(pd, destparty, X0, numLaOTs*XOTBytes);
	osend(pd, destparty, X1, numLaOTs*XOTBytes);
	orecv(pd, destparty, d, numLaOTs);
	for(i=0;i<numLaOTs;i++) {
		z[i]=r[i];
		nnobKeyXORConst(&z[i], d[i], globalDelta);
		nnobHash(padder, z[i].key, NNOB_KEY_BYTES, *nonce, I0[i], T1[i]);
		memcpy(temp, z[i].key, NNOB_KEY_BYTES);
		memxor(temp, globalDelta, NNOB_KEY_BYTES);
		nnobHash(padder, temp, NNOB_KEY_BYTES, *nonce, I1[i], T0[i]);
		*nonce+=1;
	}
	osend(pd, destparty, I0, numLaOTs*NNOB_KEY_BYTES);
	osend(pd, destparty, I1, numLaOTs*NNOB_KEY_BYTES);
	success &= ocEqualityCheck(pd, gen, T0, numLaOTs*NNOB_KEY_BYTES, destparty);
	success &= ocEqualityCheck(pd, gen, T1, numLaOTs*NNOB_KEY_BYTES, destparty);
	free(X0); free(X1); free(I0); free(I1); free(T0); free(T1); free(mc); free(d);
	return success;
}
Exemplo n.º 16
0
bool LaOTShareAndMacOfZ(ProtocolDesc* pd, const NnobKey* x0, 
		const NnobKey* x1, const NnobShareAndMac* c,
		const NnobShareAndMac* r, NnobShareAndMac* z,  BCipherRandomGen* padder, 
		BCipherRandomGen* gen, int* nonce, int numLaOTs) {

	NnobProtocolDesc* npd = pd->extra;
	assert(npd!=NULL);
	int i, destparty = pd->thisParty==1?1:2;
	bool success = true;
	const int XOTBytes = 1+2*NNOB_KEY_BYTES;
	char (*X0)[XOTBytes] = malloc(numLaOTs*XOTBytes);
	char (*X1)[XOTBytes] = malloc(numLaOTs*XOTBytes);
	char (*I0)[NNOB_KEY_BYTES] = malloc(numLaOTs*NNOB_KEY_BYTES);
	char (*I1)[NNOB_KEY_BYTES] = malloc(numLaOTs*NNOB_KEY_BYTES);
	char (*T0)[NNOB_KEY_BYTES] = malloc(numLaOTs*NNOB_KEY_BYTES);
	char (*T1)[NNOB_KEY_BYTES] = malloc(numLaOTs*NNOB_KEY_BYTES);
	char temp[NNOB_KEY_BYTES];
	char (*mc)[XOTBytes] = malloc(numLaOTs*XOTBytes); 
	bool* d = malloc(numLaOTs);
	const char* globalDelta = npd->globalDelta;

	orecv(pd, destparty, X0, numLaOTs*XOTBytes);
	orecv(pd, destparty, X1, numLaOTs*XOTBytes);
	for(i=0;i<numLaOTs;i++) {
		if(c[i].share) 
			nnobPRG(padder, c[i].mac, NNOB_KEY_BYTES, *nonce, mc[i], X1[i], XOTBytes);
		else nnobPRG(padder, c[i].mac, NNOB_KEY_BYTES, *nonce, mc[i], X0[i], XOTBytes);
		*nonce+=1;
		z[i].share = mc[i][0];
		if(c[i].share) memcpy(temp, x1[i].key, NNOB_KEY_BYTES);	
		else memcpy(temp, x0[i].key, NNOB_KEY_BYTES);	
		if(z[i].share) memxor(temp, globalDelta, NNOB_KEY_BYTES);	
		success &= memcmp(mc[i]+1, temp, NNOB_KEY_BYTES)==0?true:false;
		assert(success);
		d[i] = z[i].share^r[i].share;
	}
	osend(pd, destparty, d, numLaOTs);
	for(i=0;i<numLaOTs;i++) {
		z[i]=r[i];
		nnobShareAndMacXORConst(&z[i], d[i]);
	}
	orecv(pd, destparty, I0, numLaOTs*NNOB_KEY_BYTES);
	orecv(pd, destparty, I1, numLaOTs*NNOB_KEY_BYTES);

	for(i=0;i<numLaOTs;i++) {
		if(z[i].share) {
			memcpy(T1[i], mc[i]+1+NNOB_KEY_BYTES, NNOB_KEY_BYTES);	
			nnobHash(padder, z[i].mac, NNOB_KEY_BYTES, *nonce, 
					T0[i], I1[i]);	
		}
		else {
			memcpy(T0[i], mc[i]+1+NNOB_KEY_BYTES, NNOB_KEY_BYTES);	
			nnobHash(padder, z[i].mac, NNOB_KEY_BYTES, *nonce, 
					T1[i], I0[i]);	
		}
		*nonce+=1;
	}
	success &= ocEqualityCheck(pd, gen, T0, numLaOTs*NNOB_KEY_BYTES, destparty);
	success &= ocEqualityCheck(pd, gen, T1, numLaOTs*NNOB_KEY_BYTES, destparty);
	free(X0); free(X1); free(I0); free(I1); free(T0); free(T1); free(mc); free(d);
	return success;
}