PageRenderTime 98ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/projects/sandmark-3.4/src/sandmark/util/splitint/CRTSplitter.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Java | 331 lines | 291 code | 40 blank | 0 comment | 59 complexity | 8fc60cf683e3834ac6fffb7bffb378a9 MD5 | raw file
  1. package sandmark.util.splitint;
  2. public abstract class CRTSplitter extends ResidueSplitter {
  3. public boolean orderMatters() {
  4. return false;
  5. }
  6. private long p[];
  7. private javax.crypto.Cipher c;
  8. private javax.crypto.SecretKey w;
  9. private sandmark.util.newgraph.Graph splittingGraph;
  10. private static java.math.BigInteger MAX_LONG =
  11. java.math.BigInteger.valueOf(Long.MAX_VALUE);
  12. public CRTSplitter(int bits, int minModuli, int maxparts,
  13. javax.crypto.SecretKey w) {
  14. java.math.BigInteger bigmod =
  15. java.math.BigInteger.ONE.shiftLeft(bits);
  16. int pbits = 31;
  17. java.math.BigInteger pmod;
  18. do {
  19. p = findmods(pbits--);
  20. pmod = java.math.BigInteger.ONE;
  21. for (int i = 0; i < p.length; i++)
  22. pmod = pmod.multiply(java.math.BigInteger.valueOf(p[i]));
  23. } while (p.length < minModuli || bigmod.compareTo(pmod) > 0);
  24. try {
  25. c =
  26. javax.crypto.Cipher.getInstance(getAlgorithm() + "/ECB/NoPadding");
  27. }
  28. catch (java.security.NoSuchAlgorithmException e) {
  29. throw new RuntimeException("algorithm " + getAlgorithm()
  30. + " not found");
  31. }
  32. catch (javax.crypto.NoSuchPaddingException e) {
  33. throw new RuntimeException("padding NoPadding not found");
  34. }
  35. this.w = w;
  36. if (maxparts <= 0)
  37. splittingGraph = null;
  38. else {
  39. if (maxparts < p.length - 1)
  40. throw new RuntimeException("maxparts must be at least " +
  41. (p.length-1));
  42. Integer ia[] = new Integer[p.length];
  43. for (int i = 0; i < p.length; i++)
  44. ia[i] = new Integer(i);
  45. java.util.Iterator ii = java.util.Arrays.asList(ia).iterator();
  46. sandmark.util.newgraph.Graph g =
  47. sandmark.util.newgraph.Graphs.createGraph(ii, null);
  48. int diff = 1;
  49. int maxedges = 2*maxparts;
  50. while (g.edgeCount() < maxedges && diff <= p.length/2) {
  51. for (int i = 0; g.edgeCount() < maxedges && i < p.length; i++) {
  52. Integer other = ia[(i+diff) % p.length];
  53. g = g.addEdge(ia[i], other).addEdge(other, ia[i]);
  54. }
  55. diff++;
  56. }
  57. splittingGraph = g;
  58. }
  59. }
  60. public CRTSplitter(int bits, int maxparts, javax.crypto.SecretKey w) {
  61. this(bits, 0, maxparts, w);
  62. }
  63. public static String getAlgorithm() {
  64. return "Blowfish";
  65. }
  66. private static byte[] convert(long l) {
  67. byte b[] = new byte[8];
  68. for (int j = 0; j < 8; j++)
  69. b[j] = (byte)(l >> (j*8));
  70. return b;
  71. }
  72. private static long convert(byte b[]) {
  73. long l = 0;
  74. for (int j = 0; j < 8; j++)
  75. l |= (255 & (long)b[j]) << (j*8);
  76. return l;
  77. }
  78. public java.math.BigInteger[] split(java.math.BigInteger value) {
  79. int parts = p.length*(p.length-1)/2;
  80. if (splittingGraph != null)
  81. parts = splittingGraph.edgeCount() / 2;
  82. long rval[] = new long[parts];
  83. int index = 0;
  84. long base = 0;
  85. for (int i = 0; i < p.length - 1; i++)
  86. for (int j = i + 1; j < p.length; j++) {
  87. long modulo = p[i]*p[j];
  88. java.math.BigInteger residue =
  89. value.mod(java.math.BigInteger.valueOf(modulo));
  90. java.math.BigInteger part =
  91. residue.add(java.math.BigInteger.valueOf(base));
  92. if (part.compareTo(MAX_LONG) > 0
  93. || part.compareTo(java.math.BigInteger.ZERO) < 0)
  94. throw new RuntimeException("unexpected value");
  95. if (splittingGraph == null
  96. || splittingGraph.hasEdge(new Integer(i), new Integer(j)))
  97. rval[index++] = part.longValue();
  98. base += modulo;
  99. }
  100. synchronized(c) {
  101. try {
  102. c.init(javax.crypto.Cipher.ENCRYPT_MODE, w);
  103. }
  104. catch (java.security.InvalidKeyException e) {
  105. throw new RuntimeException("bad key");
  106. }
  107. java.math.BigInteger r[] = new java.math.BigInteger[rval.length];
  108. java.util.Vector indices = new java.util.Vector();
  109. java.util.Random rand = sandmark.util.Random.getRandom();
  110. for (int i = 0; i < r.length; i++)
  111. indices.add(new Integer(i));
  112. for (int i = 0; i < r.length; i++) {
  113. java.io.ByteArrayOutputStream bos =
  114. new java.io.ByteArrayOutputStream(8);
  115. byte b[] = convert(rval[i]);
  116. javax.crypto.CipherOutputStream cos =
  117. new javax.crypto.CipherOutputStream(bos, c);
  118. try {
  119. cos.write(b);
  120. }
  121. catch (java.io.IOException e) {
  122. throw new RuntimeException("shouldn't happen");
  123. }
  124. Integer rindex =
  125. ((Integer)indices.remove(rand.nextInt(indices.size())));
  126. r[rindex.intValue()] =
  127. java.math.BigInteger.valueOf(convert(bos.toByteArray()));
  128. }
  129. return r;
  130. }
  131. }
  132. protected class Congruence {
  133. public long residue;
  134. public int prime1, prime2;
  135. public int hashCode() {
  136. int p1 = Math.min(prime1, prime2);
  137. int p2 = Math.max(prime1, prime2);
  138. return p1 ^ (p2 << 16) ^ ((int)residue);
  139. }
  140. public String toString() {
  141. long modulo = p[prime1] * p[prime2];
  142. return "" + residue + " mod " + modulo;
  143. }
  144. public boolean equals(Object o) {
  145. if (!(o instanceof Congruence))
  146. return false;
  147. Congruence c = (Congruence)o;
  148. if (residue != c.residue)
  149. return false;
  150. if (prime1 == c.prime1 && prime2 == c.prime2)
  151. return true;
  152. else if (prime1 == c.prime2 && prime2 == c.prime1)
  153. return true;
  154. else
  155. return false;
  156. }
  157. }
  158. protected int numModuli() {
  159. return p.length;
  160. }
  161. protected long modulo(int i) {
  162. return p[i];
  163. }
  164. abstract protected java.util.Iterator filter(Congruence cs[]);
  165. public java.math.BigInteger[] combineRes(java.math.BigInteger parts[]) {
  166. java.util.HashSet seen = new java.util.HashSet();
  167. synchronized(c) {
  168. try {
  169. c.init(javax.crypto.Cipher.DECRYPT_MODE, w);
  170. }
  171. catch (java.security.InvalidKeyException e) {
  172. throw new RuntimeException("bad key");
  173. }
  174. for (int k = 0; k < parts.length; k++) {
  175. java.io.ByteArrayOutputStream bos =
  176. new java.io.ByteArrayOutputStream(8);
  177. javax.crypto.CipherOutputStream cos =
  178. new javax.crypto.CipherOutputStream(bos, c);
  179. try {
  180. cos.write(convert(parts[k].longValue()));
  181. }
  182. catch (java.io.IOException e) {
  183. throw new RuntimeException("shouldn't happen");
  184. }
  185. long piece = convert(bos.toByteArray());
  186. if (piece >= 0) {
  187. Congruence c = new Congruence();
  188. boolean done = false;
  189. for (int i = 0; !done && i < p.length - 1; i++)
  190. for (int j = i + 1; !done && j < p.length; j++) {
  191. long modulo = p[i]*p[j];
  192. if (piece >= modulo)
  193. piece -= modulo;
  194. else {
  195. done = true;
  196. c.prime1 = i;
  197. c.prime2 = j;
  198. c.residue = piece;
  199. seen.add(c);
  200. }
  201. }
  202. }
  203. }
  204. }
  205. Congruence ca[] = new Congruence[seen.size()];
  206. java.util.Iterator j = seen.iterator();
  207. for ( int k = 0; j.hasNext(); k++)
  208. ca[k] = (Congruence)j.next();
  209. java.util.Iterator i = filter(ca);
  210. java.math.BigInteger residue = java.math.BigInteger.ZERO;
  211. java.math.BigInteger modulo = java.math.BigInteger.ONE;
  212. while (i.hasNext()) {
  213. Congruence c = (Congruence)i.next();
  214. java.math.BigInteger m =
  215. java.math.BigInteger.valueOf(p[c.prime1])
  216. .multiply(java.math.BigInteger.valueOf(p[c.prime2]));
  217. java.math.BigInteger tmp[] = chinese(residue, modulo,
  218. java.math.BigInteger.valueOf(c.residue), m);
  219. residue = tmp[0];
  220. modulo = tmp[1];
  221. }
  222. java.math.BigInteger rval[] = new java.math.BigInteger[2];
  223. rval[0] = residue;
  224. rval[1] = modulo;
  225. return rval;
  226. }
  227. private static java.math.BigInteger[] chinese(java.math.BigInteger a,
  228. java.math.BigInteger m,
  229. java.math.BigInteger b,
  230. java.math.BigInteger n) {
  231. java.math.BigInteger g[] = euclid(m, n);
  232. java.math.BigInteger diff = a.subtract(b);
  233. java.math.BigInteger d[] = diff.divideAndRemainder(g[2]);
  234. if (!d[1].equals(java.math.BigInteger.ZERO))
  235. return null;
  236. java.math.BigInteger rval[] = new java.math.BigInteger[2];
  237. rval[1] = m.multiply(n).divide(g[2]);
  238. rval[0] = n.multiply(g[1]).multiply(d[0]).add(b).mod(rval[1]);
  239. return rval;
  240. }
  241. private static java.math.BigInteger[] euclid(java.math.BigInteger m,
  242. java.math.BigInteger n) {
  243. java.math.BigInteger rval[] = new java.math.BigInteger[3];
  244. if (m.equals(java.math.BigInteger.ZERO)) {
  245. rval[0] = java.math.BigInteger.ZERO;
  246. rval[1] = java.math.BigInteger.ONE;
  247. rval[2] = n;
  248. }
  249. else {
  250. java.math.BigInteger d[] = n.divideAndRemainder(m);
  251. java.math.BigInteger r[] = euclid(d[1], m);
  252. rval[0] = r[1].subtract(r[0].multiply(d[0]));
  253. rval[1] = r[0];
  254. rval[2] = r[2];
  255. }
  256. return rval;
  257. }
  258. private static long gcd(long a, long b) {
  259. if (a == 0)
  260. return b;
  261. else
  262. return gcd(b % a, a);
  263. }
  264. private static long[] findmods(int bits) {
  265. long tmp[] = new long[2];
  266. long modulo = ((long)1) << bits;
  267. tmp[0] = modulo;
  268. long sum = 0;
  269. int index = 1;
  270. while (sum >= 0) {
  271. modulo--;
  272. boolean good = true;
  273. for (int i = 0; i < index && good; i++)
  274. if (gcd(modulo, tmp[i]) > 1)
  275. good = false;
  276. if (good) {
  277. for (int i = 0; i < index && sum >= 0; i++)
  278. sum += modulo * tmp[i];
  279. if (index >= tmp.length) {
  280. long tmp2[] = new long[tmp.length * 2];
  281. System.arraycopy(tmp, 0, tmp2, 0, index);
  282. tmp = tmp2;
  283. }
  284. tmp[index++] = modulo;
  285. }
  286. }
  287. long rval[] = new long[index-1];
  288. System.arraycopy(tmp, 0, rval, 0, index-1);
  289. return rval;
  290. }
  291. }