OTExtSender.java 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. // Copyright (C) 2013 by Yan Huang <yhuang@cs.umd.edu>
  2. // Improved by Xiao Shaun Wang <wangxiao@cs.umd.edu>
  3. package com.oblivm.backend.ot;
  4. import java.io.IOException;
  5. import java.math.BigInteger;
  6. import java.security.NoSuchAlgorithmException;
  7. import java.security.SecureRandom;
  8. import java.security.Security;
  9. import com.oblivm.backend.flexsc.Flag;
  10. import com.oblivm.backend.gc.GCSignal;
  11. import com.oblivm.backend.network.Network;
  12. import com.oblivm.backend.rand.ISAACProvider;
  13. public class OTExtSender extends OTSender {
  14. static class SecurityParameter {
  15. public static final int k1 = 80; // number of columns in T
  16. }
  17. private static SecureRandom rnd;
  18. static {
  19. Security.addProvider(new ISAACProvider());
  20. try {
  21. rnd = SecureRandom.getInstance("ISAACRandom");
  22. } catch (NoSuchAlgorithmException e) {
  23. e.printStackTrace();
  24. }
  25. }
  26. private OTReceiver rcver;
  27. private boolean[] s;
  28. private GCSignal[] keys;
  29. Cipher cipher;
  30. public OTExtSender(int msgBitLength, Network channel) {
  31. super(msgBitLength, channel);
  32. cipher = new Cipher();
  33. try {
  34. initialize();
  35. } catch (Exception e) {
  36. e.printStackTrace();
  37. }
  38. }
  39. int poolIndex = 0;
  40. @Override
  41. public void send(GCSignal[] m) {
  42. try {
  43. throw new Exception("It doesn't make sense to do single OT with OT extension!");
  44. } catch (Exception e) {
  45. e.printStackTrace();
  46. }
  47. }
  48. /*
  49. * Everything in msgPairs are effective Sender's messages.
  50. */
  51. GCSignal[][] keyPairs = new GCSignal[SecurityParameter.k1][2];
  52. public void send(GCSignal[][] msgPairs) throws IOException {
  53. GCSignal[][] pairs = new GCSignal[SecurityParameter.k1 + msgPairs.length][2];
  54. for (int i = 0; i < SecurityParameter.k1; i++) {
  55. pairs[i][0] = GCSignal.freshLabel(rnd);
  56. pairs[i][1] = GCSignal.freshLabel(rnd);
  57. }
  58. for (int i = SecurityParameter.k1; i < pairs.length; i++) {
  59. pairs[i][0] = msgPairs[i - SecurityParameter.k1][0];
  60. pairs[i][1] = msgPairs[i - SecurityParameter.k1][1];
  61. }
  62. reverseAndExtend(s, keys, msgBitLength, pairs, channel, cipher);
  63. for (int i = 0; i < SecurityParameter.k1; i++) {
  64. keyPairs[i][0] = pairs[i][0];
  65. keyPairs[i][1] = pairs[i][1];
  66. }
  67. for (int i = 0; i < s.length; i++)
  68. s[i] = rnd.nextBoolean();
  69. keys = OTExtReceiver.reverseAndExtend(keyPairs, s, SecurityParameter.k1, channel, cipher);
  70. }
  71. // Given s and keys, obliviously sends msgPairs which contains 'numOfPairs'
  72. // pairs of strings, each of length 'msgBitLength' bits.
  73. static void reverseAndExtend(boolean[] s, GCSignal[] keys, int msgBitLength, GCSignal[][] msgPairs, Network channel,
  74. Cipher cipher) throws IOException {
  75. BigInteger[][] cphPairs = new BigInteger[SecurityParameter.k1][2];
  76. Flag.sw.startOTIO();
  77. for (int i = 0; i < SecurityParameter.k1; i++) {
  78. cphPairs[i][0] = channel.readBI();
  79. cphPairs[i][1] = channel.readBI();
  80. }
  81. Flag.sw.stopOTIO();
  82. int numOfPairs = msgPairs.length;
  83. BitMatrix Q = new BitMatrix(numOfPairs, SecurityParameter.k1);
  84. for (int i = 0; i < SecurityParameter.k1; i++) {
  85. if (s[i])
  86. Q.data[i] = cipher.decrypt(keys[i].bytes, cphPairs[i][1], numOfPairs);
  87. else
  88. Q.data[i] = cipher.decrypt(keys[i].bytes, cphPairs[i][0], numOfPairs);
  89. }
  90. BitMatrix tQ = Q.transpose();
  91. BigInteger biS = fromBoolArray(s);
  92. GCSignal[][] y = new GCSignal[numOfPairs][2];
  93. for (int i = 0; i < numOfPairs; i++) {
  94. y[i][0] = cipher.enc(GCSignal.newInstance(tQ.data[i].toByteArray()), msgPairs[i][0], i);
  95. y[i][1] = cipher.enc(GCSignal.newInstance(tQ.data[i].xor(biS).toByteArray()), msgPairs[i][1], i);
  96. y[i][0].send(channel);
  97. y[i][1].send(channel);
  98. }
  99. Flag.sw.startOTIO();
  100. channel.flush();
  101. Flag.sw.stopOTIO();
  102. }
  103. private void initialize() throws Exception {
  104. Flag.sw.startOTIO();
  105. channel.writeInt(msgBitLength);
  106. channel.flush();
  107. Flag.sw.stopOTIO();
  108. rcver = new NPOTReceiver(channel);
  109. s = new boolean[SecurityParameter.k1];
  110. for (int i = 0; i < s.length; i++)
  111. s[i] = rnd.nextBoolean();
  112. keys = rcver.receive(s);
  113. }
  114. public static BigInteger fromBoolArray(boolean[] a) {
  115. BigInteger res = BigInteger.ZERO;
  116. for (int i = 0; i < a.length; i++)
  117. if (a[i])
  118. res = res.setBit(i);
  119. return res;
  120. }
  121. }