static void reverseAndExtend(boolean[] s, GCSignal[] keys, 
    		int msgBitLength, GCSignal[][] msgPairs, InputStream is, OutputStream os, Cipher cipher) throws Exception {
    	BigInteger[][] cphPairs = new BigInteger[SecurityParameter.k1][2];

		Flag.sw.startOTIO();
    	for (int i = 0; i < SecurityParameter.k1; i++) {
    		cphPairs[i][0] = RWBigInteger.readBI(is);
    		cphPairs[i][1] = RWBigInteger.readBI(is);
		}
		Flag.sw.stopOTIO();


    	int numOfPairs = msgPairs.length;

    	BitMatrix Q = new BitMatrix(numOfPairs, SecurityParameter.k1);

		for (int i = 0; i < SecurityParameter.k1; i++) {
		    if (s[i])
				Q.data[i] = cipher.decrypt(keys[i].bytes, cphPairs[i][1], numOfPairs);
			else
				Q.data[i] = cipher.decrypt(keys[i].bytes, cphPairs[i][0], numOfPairs);
		}

		BitMatrix tQ = Q.transpose();
	
		BigInteger biS = fromBoolArray(s);
		
		GCSignal[][] y = new GCSignal[numOfPairs][2];
		for (int i = 0; i < numOfPairs; i++) {
			y[i][0] = cipher.enc(GCSignal.newInstance(tQ.data[i].toByteArray()),  msgPairs[i][0], i);
		    y[i][1] = cipher.enc(GCSignal.newInstance(tQ.data[i].xor(biS).toByteArray()), msgPairs[i][1], i);
		}

		Flag.sw.startOTIO();
		for (int i = 0; i < numOfPairs; i++) {
			y[i][0].send(os);
			y[i][1].send(os);
		}
		os.flush();
		Flag.sw.stopOTIO();
		
    }