dixon.c 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. /**
  2. * \file dixon.c
  3. * \brief An implementation of Dixon's Attack using bignums.
  4. *
  5. * Given a non-empty set B of primes, called factor-base, and
  6. * given a non-empty set of random numbers R, s.t. ∀ r ∈ R, s ≡ r² (mod N) is B-smooth.
  7. *
  8. * Try to find
  9. * U ⊂ R | (Πᵤ rᵢ)² ≡ Π s (mod N) and by defining x ≝ Πᵤ rᵢ, y ≝ √(Π s)
  10. * x² ≡ y² (mod N)
  11. * Asserting that x ≢ y (mod N) we claim to have found the two non-trivial
  12. * factors of N by computing gcd(x+y, N) and gcd(x-y, N).
  13. *
  14. * \note N = pq is assumed to be the public modulus,
  15. * while e, d . ed ≡ 1 (mod φ(N)) are respectively the public and the private
  16. * exponent.
  17. */
  18. #include <stdint.h>
  19. #include <strings.h>
  20. #include <openssl/bn.h>
  21. #include "qa/questions/questions.h"
  22. #include "qa/questions/qstrings.h"
  23. #include "qa/questions/qdixon.h"
  24. matrix_t*
  25. identity_matrix_new(int d)
  26. {
  27. size_t i;
  28. matrix_t *m = matrix_new(d, d);
  29. for (i=0; i!=d; i++) {
  30. bzero(m->M[i], sizeof(**(m->M)) * d);
  31. m->M[i][i] = 1;
  32. }
  33. return m;
  34. }
  35. matrix_t*
  36. matrix_new(int r, int c)
  37. {
  38. matrix_t *m;
  39. size_t i;
  40. m = malloc(sizeof(matrix_t));
  41. m->f = r;
  42. m->r = c;
  43. m->M = malloc(sizeof(BIGNUM **) * m->f);
  44. for (i=0; i!=r; i++)
  45. m->M[i] = malloc(sizeof(BIGNUM*) * m->r);
  46. return m;
  47. }
  48. void
  49. matrix_free(matrix_t *m)
  50. {
  51. size_t i;
  52. for (i=0; i!= m->f; i++)
  53. free(m->M[i]);
  54. free(m->M);
  55. free(m);
  56. }
  57. /*
  58. * \ref Kernel into a binary matrix.
  59. *
  60. * Discover linear dependencies using a refined version of the Gauss-Jordan
  61. * algorithm, from Brillhart and Morrison.
  62. *
  63. * \return h, the history matrix
  64. *
  65. */
  66. matrix_t *
  67. kernel(matrix_t *m)
  68. {
  69. int i, j, k;
  70. matrix_t *h = identity_matrix_new(m->f);
  71. for (j=0; j!=m->r; j++)
  72. for (i=0; i != m->f; i++)
  73. if (m->M[i][j]) {
  74. for (k=i+1; k != m->f; k++)
  75. if (m->M[k][j]) {
  76. vxor(m->M[k], m->M[k], m->M[i], m->r);
  77. vxor(h->M[k], h->M[k], h->M[i], h->r);
  78. }
  79. break;
  80. }
  81. return h;
  82. }
  83. qa_question_t DixonQuestion = {
  84. .name = "dixon",
  85. .pretty_name = "Dixon's Factorization"
  86. };