123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- #include <math.h>
- #include <stdlib.h>
- #include <openssl/x509.h>
- #include <openssl/rsa.h>
- #include <openssl/bn.h>
- #include "qa/questions/questions.h"
- #include "qa/questions/qarith.h"
- #include "qa/questions/qwiener.h"
- static RSA*
- wiener_question_ask_rsa(const RSA *rsa)
- {
-
- RSA *ret = NULL;
- BIGNUM *n, *e, *d, *phi;
-
- cf_t* cf;
- bigfraction_t *it;
- size_t i;
- BIGNUM *t, *tmp, *rem;
-
- BIGNUM *b2, *delta;
- BN_CTX *ctx;
- int bits;
- phi = BN_new();
- tmp = BN_new();
- rem = BN_new();
- n = rsa->n;
- e = rsa->e;
- b2 = BN_new();
- delta = BN_new();
-
- bits = BN_num_bits(n);
- cf = cf_init(NULL, e, n);
- ctx = cf->ctx;
- for (i=0, it = cf_next(cf);
-
- i!=bits && it;
- i++, it = cf_next(cf)) {
- t = it->h;
- d = it->k;
- fprintf(stderr, "[-] Testing continued fractions (%zu/%d)\r", i, bits);
-
- BN_mul(phi, e, d, cf->ctx);
- BN_usub(tmp, phi, BN_value_one());
- BN_div(phi, rem, tmp, t, cf->ctx);
- if (!BN_is_zero(rem)) continue;
-
- if (BN_is_odd(phi) && BN_cmp(n, phi) == 1) continue;
-
- BN_usub(b2, n, phi);
- BN_uadd(b2, b2, BN_value_one());
- BN_rshift(b2, b2, 1);
- if (BN_is_zero(b2)) continue;
-
- BN_sqr(tmp, b2, ctx);
- BN_usub(delta, tmp, n);
- if (!BN_sqrtmod(tmp, rem, delta, ctx)) continue;
-
- ret = RSA_new();
- ret->n = rsa->n;
- ret->e = rsa->e;
- ret->p = BN_new();
- ret->q = BN_new();
- BN_usub(ret->p, b2, tmp);
- BN_uadd(ret->q, b2, tmp);
- break;
- }
- cf_free(cf);
- BN_free(rem);
- BN_free(tmp);
- BN_free(b2);
- BN_free(delta);
- BN_free(phi);
- fprintf(stderr, "\n");
- return ret;
- }
- qa_question_t WienerQuestion = {
- .name = "wiener",
- .pretty_name = "Wiener's Attack",
- .setup = NULL,
- .teardown = NULL,
- .test = NULL,
- .ask_rsa = wiener_question_ask_rsa,
- .ask_crt = NULL,
- };
|