| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108 | 
							- // Copyright (C) 2013 by Yan Huang <yhuang@cs.umd.edu>
 
- package com.oblivm.backend.ot;
 
- import java.io.IOException;
 
- import java.math.BigInteger;
 
- import java.security.NoSuchAlgorithmException;
 
- import java.security.SecureRandom;
 
- import java.security.Security;
 
- import com.oblivm.backend.flexsc.Flag;
 
- import com.oblivm.backend.gc.GCSignal;
 
- import com.oblivm.backend.network.Network;
 
- import com.oblivm.backend.rand.ISAACProvider;
 
- public class NPOTReceiver extends OTReceiver {
 
- 	static SecureRandom rnd;
 
- 	static {
 
- 		Security.addProvider(new ISAACProvider());
 
- 		try {
 
- 			rnd = SecureRandom.getInstance("ISAACRandom");
 
- 		} catch (NoSuchAlgorithmException e) {
 
- 			e.printStackTrace();
 
- 		}
 
- 	}
 
- 	private BigInteger p, q, g, C;
 
- 	private BigInteger gr;
 
- 	private BigInteger[][] pk;
 
- 	private BigInteger[] keys;
 
- 	Cipher cipher;
 
- 	public NPOTReceiver(Network channel) throws Exception {
 
- 		super(channel);
 
- 		cipher = new Cipher();
 
- 		initialize();
 
- 	}
 
- 	@Override
 
- 	public GCSignal receive(boolean c) throws IOException {
 
- 		return receive(new boolean[] { c })[0];
 
- 	}
 
- 	public GCSignal[] receive(boolean[] choices) throws IOException {
 
- 		step1(choices);
 
- 		return step2(choices);
 
- 	}
 
- 	private void initialize() throws Exception {
 
- 		Flag.sw.startOTIO();
 
- 		C = channel.readBI();
 
- 		p = channel.readBI();
 
- 		q = channel.readBI();
 
- 		g = channel.readBI();
 
- 		gr = channel.readBI();
 
- 		msgBitLength = channel.readInt();
 
- 		Flag.sw.stopOTIO();
 
- 	}
 
- 	private void step1(boolean[] choices) throws IOException {
 
- 		keys = new BigInteger[choices.length];
 
- 		pk = new BigInteger[choices.length][2];
 
- 		BigInteger[] pk0 = new BigInteger[choices.length];
 
- 		for (int i = 0; i < choices.length; i++) {
 
- 			BigInteger k = (new BigInteger(q.bitLength(), rnd)).mod(q);
 
- 			BigInteger gk = g.modPow(k, p);
 
- 			BigInteger C_over_gk = C.multiply(gk.modInverse(p)).mod(p);
 
- 			keys[i] = gr.modPow(k, p);
 
- 			int sigma = choices[i] ? 1 : 0;
 
- 			pk[i][sigma] = gk;
 
- 			pk[i][1 - sigma] = C_over_gk;
 
- 			pk0[i] = pk[i][0];
 
- 		}
 
- 		Flag.sw.startOTIO();
 
- 		for (int i = 0; i < choices.length; i++)
 
- 			channel.writeBI(pk0[i]);
 
- 		channel.flush();
 
- 		Flag.sw.stopOTIO();
 
- 	}
 
- 	private GCSignal[] step2(boolean[] choices) {
 
- 		BigInteger[][] msg = new BigInteger[choices.length][2];
 
- 		Flag.sw.startOTIO();
 
- 		for (int i = 0; i < choices.length; i++) {
 
- 			msg[i][0] = channel.readBI();
 
- 			msg[i][1] = channel.readBI();
 
- 		}
 
- 		Flag.sw.stopOTIO();
 
- 		GCSignal[] data = new GCSignal[choices.length];
 
- 		for (int i = 0; i < choices.length; i++) {
 
- 			int sigma = choices[i] ? 1 : 0;
 
- 			data[i] = GCSignal
 
- 					.newInstance(cipher.decrypt(keys[i].toByteArray(), msg[i][sigma], msgBitLength).toByteArray());
 
- 		}
 
- 		return data;
 
- 	}
 
- }
 
 
  |