dsa_verify_key.c 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. /* LibTomCrypt, modular cryptographic library -- Tom St Denis
  2. *
  3. * LibTomCrypt is a library that provides various cryptographic
  4. * algorithms in a highly modular and flexible manner.
  5. *
  6. * The library is free for all purposes without any express
  7. * guarantee it works.
  8. *
  9. * Tom St Denis, [email protected], http://libtomcrypt.org
  10. */
  11. #include "mycrypt.h"
  12. #ifdef MDSA
  13. int dsa_verify_key(dsa_key *key, int *stat)
  14. {
  15. mp_int tmp, tmp2;
  16. int res, err;
  17. _ARGCHK(key != NULL);
  18. _ARGCHK(stat != NULL);
  19. *stat = 0;
  20. /* first make sure key->q and key->p are prime */
  21. if ((err = is_prime(&key->q, &res)) != CRYPT_OK) {
  22. return err;
  23. }
  24. if (res == 0) {
  25. return CRYPT_OK;
  26. }
  27. if ((err = is_prime(&key->p, &res)) != CRYPT_OK) {
  28. return err;
  29. }
  30. if (res == 0) {
  31. return CRYPT_OK;
  32. }
  33. /* now make sure that g is not -1, 0 or 1 and <p */
  34. if (mp_cmp_d(&key->g, 0) == MP_EQ || mp_cmp_d(&key->g, 1) == MP_EQ) {
  35. return CRYPT_OK;
  36. }
  37. if ((err = mp_init_multi(&tmp, &tmp2, NULL)) != MP_OKAY) { goto error; }
  38. if ((err = mp_sub_d(&key->p, 1, &tmp)) != MP_OKAY) { goto error; }
  39. if (mp_cmp(&tmp, &key->g) == MP_EQ || mp_cmp(&key->g, &key->p) != MP_LT) {
  40. err = CRYPT_OK;
  41. goto done;
  42. }
  43. /* 1 < y < p-1 */
  44. if (!(mp_cmp_d(&key->y, 1) == MP_GT && mp_cmp(&key->y, &tmp) == MP_LT)) {
  45. err = CRYPT_OK;
  46. goto done;
  47. }
  48. /* now we have to make sure that g^q = 1, and that p-1/q gives 0 remainder */
  49. if ((err = mp_div(&tmp, &key->q, &tmp, &tmp2)) != MP_OKAY) { goto error; }
  50. if (mp_iszero(&tmp2) != MP_YES) {
  51. err = CRYPT_OK;
  52. goto done;
  53. }
  54. if ((err = mp_exptmod(&key->g, &key->q, &key->p, &tmp)) != MP_OKAY) { goto error; }
  55. if (mp_cmp_d(&tmp, 1) != MP_EQ) {
  56. err = CRYPT_OK;
  57. goto done;
  58. }
  59. /* now we have to make sure that y^q = 1, this makes sure y \in g^x mod p */
  60. if ((err = mp_exptmod(&key->y, &key->q, &key->p, &tmp)) != MP_OKAY) { goto error; }
  61. if (mp_cmp_d(&tmp, 1) != MP_EQ) {
  62. err = CRYPT_OK;
  63. goto done;
  64. }
  65. /* at this point we are out of tests ;-( */
  66. err = CRYPT_OK;
  67. *stat = 1;
  68. goto done;
  69. error: err = mpi_to_ltc_error(err);
  70. done : mp_clear_multi(&tmp, &tmp2, NULL);
  71. return err;
  72. }
  73. #endif