NPOTReceiver.java 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. // Copyright (C) 2013 by Yan Huang <yhuang@cs.umd.edu>
  2. package com.oblivm.backend.ot;
  3. import java.io.IOException;
  4. import java.math.BigInteger;
  5. import java.security.NoSuchAlgorithmException;
  6. import java.security.SecureRandom;
  7. import java.security.Security;
  8. import com.oblivm.backend.flexsc.Flag;
  9. import com.oblivm.backend.gc.GCSignal;
  10. import com.oblivm.backend.network.Network;
  11. import com.oblivm.backend.rand.ISAACProvider;
  12. public class NPOTReceiver extends OTReceiver {
  13. static SecureRandom rnd;
  14. static {
  15. Security.addProvider(new ISAACProvider());
  16. try {
  17. rnd = SecureRandom.getInstance("ISAACRandom");
  18. } catch (NoSuchAlgorithmException e) {
  19. e.printStackTrace();
  20. }
  21. }
  22. private BigInteger p, q, g, C;
  23. private BigInteger gr;
  24. private BigInteger[][] pk;
  25. private BigInteger[] keys;
  26. Cipher cipher;
  27. public NPOTReceiver(Network channel) throws Exception {
  28. super(channel);
  29. cipher = new Cipher();
  30. initialize();
  31. }
  32. @Override
  33. public GCSignal receive(boolean c) throws IOException {
  34. return receive(new boolean[] { c })[0];
  35. }
  36. public GCSignal[] receive(boolean[] choices) throws IOException {
  37. step1(choices);
  38. return step2(choices);
  39. }
  40. private void initialize() throws Exception {
  41. Flag.sw.startOTIO();
  42. C = channel.readBI();
  43. p = channel.readBI();
  44. q = channel.readBI();
  45. g = channel.readBI();
  46. gr = channel.readBI();
  47. msgBitLength = channel.readInt();
  48. Flag.sw.stopOTIO();
  49. }
  50. private void step1(boolean[] choices) throws IOException {
  51. keys = new BigInteger[choices.length];
  52. pk = new BigInteger[choices.length][2];
  53. BigInteger[] pk0 = new BigInteger[choices.length];
  54. for (int i = 0; i < choices.length; i++) {
  55. BigInteger k = (new BigInteger(q.bitLength(), rnd)).mod(q);
  56. BigInteger gk = g.modPow(k, p);
  57. BigInteger C_over_gk = C.multiply(gk.modInverse(p)).mod(p);
  58. keys[i] = gr.modPow(k, p);
  59. int sigma = choices[i] ? 1 : 0;
  60. pk[i][sigma] = gk;
  61. pk[i][1 - sigma] = C_over_gk;
  62. pk0[i] = pk[i][0];
  63. }
  64. Flag.sw.startOTIO();
  65. for (int i = 0; i < choices.length; i++)
  66. channel.writeBI(pk0[i]);
  67. channel.flush();
  68. Flag.sw.stopOTIO();
  69. }
  70. private GCSignal[] step2(boolean[] choices) {
  71. BigInteger[][] msg = new BigInteger[choices.length][2];
  72. Flag.sw.startOTIO();
  73. for (int i = 0; i < choices.length; i++) {
  74. msg[i][0] = channel.readBI();
  75. msg[i][1] = channel.readBI();
  76. }
  77. Flag.sw.stopOTIO();
  78. GCSignal[] data = new GCSignal[choices.length];
  79. for (int i = 0; i < choices.length; i++) {
  80. int sigma = choices[i] ? 1 : 0;
  81. data[i] = GCSignal
  82. .newInstance(cipher.decrypt(keys[i].toByteArray(), msg[i][sigma], msgBitLength).toByteArray());
  83. }
  84. return data;
  85. }
  86. }