Cipher.java 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. // Copyright (C) 2010 by Yan Huang <yhuang@virginia.edu>
  2. package Cipher;
  3. import java.security.*;
  4. import java.math.*;
  5. import sprout.crypto.SR;
  6. import YaoGC.Wire;
  7. public final class Cipher {
  8. private static final int unitLength = 160; // SHA-1 has 160-bit output.
  9. public static final BigInteger mask = BigInteger.ONE.shiftLeft(
  10. Wire.labelBitLength).subtract(BigInteger.ONE);
  11. private static final BigInteger mask128 = BigInteger.ONE.shiftLeft(128)
  12. .subtract(BigInteger.ONE);
  13. private static final BigInteger mask160 = BigInteger.ONE.shiftLeft(160)
  14. .subtract(BigInteger.ONE);
  15. private static MessageDigest sha1 = SR.digest;
  16. public static synchronized BigInteger encrypt(BigInteger lp0,
  17. BigInteger lp1, int k0, int k1, BigInteger m) {
  18. BigInteger ret = getPadding(lp0, lp1, k0, k1);
  19. ret = ret.xor(m);
  20. return ret;
  21. }
  22. public static synchronized BigInteger encrypt(BigInteger lp0,
  23. BigInteger lp1, int k, BigInteger m) {
  24. BigInteger ret = getPadding(lp0, lp1, k);
  25. ret = ret.xor(m);
  26. return ret;
  27. }
  28. public static synchronized BigInteger decrypt(BigInteger lp0,
  29. BigInteger lp1, int k0, int k1, BigInteger c) {
  30. BigInteger ret = getPadding(lp0, lp1, k0, k1);
  31. ret = ret.xor(c);
  32. return ret;
  33. }
  34. public static synchronized BigInteger decrypt(BigInteger lp0,
  35. BigInteger lp1, int k, BigInteger c) {
  36. BigInteger ret = getPadding(lp0, lp1, k);
  37. ret = ret.xor(c);
  38. return ret;
  39. }
  40. public static synchronized BigInteger encrypt(int w, BigInteger key,
  41. int outBit) {
  42. sha1.update(BigInteger.valueOf(w).toByteArray());
  43. sha1.update(key.toByteArray());
  44. return new BigInteger(sha1.digest()).and(mask128).xor(
  45. BigInteger.valueOf(outBit));
  46. }
  47. public static synchronized int decrypt(int w, BigInteger key, BigInteger c) {
  48. sha1.update(BigInteger.valueOf(w).toByteArray());
  49. sha1.update(key.toByteArray());
  50. return new BigInteger(sha1.digest()).and(mask128).xor(c).intValue();
  51. }
  52. // this padding generation function is dedicated for encrypting garbled
  53. // tables.
  54. private static synchronized BigInteger getPadding(BigInteger lp0,
  55. BigInteger lp1, int k) {
  56. sha1.update(lp0.toByteArray());
  57. sha1.update(lp1.toByteArray());
  58. sha1.update(BigInteger.valueOf(k).toByteArray());
  59. return (new BigInteger(sha1.digest())).and(mask);
  60. }
  61. private static synchronized BigInteger getPadding(BigInteger lp0,
  62. BigInteger lp1, int k0, int k1) {
  63. sha1.update(lp0.toByteArray());
  64. sha1.update(lp1.toByteArray());
  65. sha1.update(BigInteger.valueOf(k0).toByteArray());
  66. sha1.update(BigInteger.valueOf(k1).toByteArray());
  67. return (new BigInteger(sha1.digest())).and(mask160);
  68. }
  69. public static synchronized BigInteger encrypt(BigInteger key,
  70. BigInteger msg, int msgLength) {
  71. return msg.xor(getPaddingOfLength(key, msgLength));
  72. }
  73. public static synchronized BigInteger decrypt(BigInteger key,
  74. BigInteger cph, int cphLength) {
  75. return cph.xor(getPaddingOfLength(key, cphLength));
  76. }
  77. private static synchronized BigInteger getPaddingOfLength(BigInteger key,
  78. int padLength) {
  79. sha1.update(key.toByteArray());
  80. BigInteger pad = BigInteger.ZERO;
  81. byte[] tmp = new byte[unitLength / 8];
  82. for (int i = 0; i < padLength / unitLength; i++) {
  83. System.arraycopy(sha1.digest(), 0, tmp, 0, unitLength / 8);
  84. pad = pad.shiftLeft(unitLength).xor(new BigInteger(1, tmp));
  85. sha1.update(tmp);
  86. }
  87. System.arraycopy(sha1.digest(), 0, tmp, 0, unitLength / 8);
  88. pad = pad.shiftLeft(padLength % unitLength).xor(
  89. (new BigInteger(1, tmp)).shiftRight(unitLength
  90. - (padLength % unitLength)));
  91. return pad;
  92. }
  93. public static synchronized BigInteger encrypt(int j, BigInteger key,
  94. BigInteger msg, int msgLength) {
  95. return msg.xor(getPaddingOfLength(j, key, msgLength));
  96. }
  97. public static synchronized BigInteger decrypt(int j, BigInteger key,
  98. BigInteger cph, int cphLength) {
  99. return cph.xor(getPaddingOfLength(j, key, cphLength));
  100. }
  101. private static synchronized BigInteger getPaddingOfLength(int j,
  102. BigInteger key, int padLength) {
  103. sha1.update(BigInteger.valueOf(j).toByteArray());
  104. sha1.update(key.toByteArray());
  105. BigInteger pad = BigInteger.ZERO;
  106. byte[] tmp = new byte[unitLength / 8];
  107. for (int i = 0; i < padLength / unitLength; i++) {
  108. System.arraycopy(sha1.digest(), 0, tmp, 0, unitLength / 8);
  109. pad = pad.shiftLeft(unitLength).xor(new BigInteger(1, tmp));
  110. sha1.update(tmp);
  111. }
  112. System.arraycopy(sha1.digest(), 0, tmp, 0, unitLength / 8);
  113. pad = pad.shiftLeft(padLength % unitLength).xor(
  114. (new BigInteger(1, tmp)).shiftRight(unitLength
  115. - (padLength % unitLength)));
  116. return pad;
  117. }
  118. }