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;
- }
- }
|