/* Test whether z is likely to be prime: MP_TRUE means it is probably prime MP_FALSE means it is definitely composite */ mp_result mp_int_is_prime(mp_int z) { int i, rem; mp_result res; /* First check for divisibility by small primes; this eliminates a large number of composite candidates quickly */ for(i = 0; i < s_ptab_size; ++i) { if((res = mp_int_div_value(z, s_ptab[i], NULL, &rem)) != MP_OK) return res; if(rem == 0) return MP_FALSE; } /* Now try Fermat's test for several prime witnesses (since we now know from the above that z is not a multiple of any of them) */ { mpz_t tmp; if((res = mp_int_init(&tmp)) != MP_OK) return res; for(i = 0; i < 10 && i < s_ptab_size; ++i) { if((res = mp_int_exptmod_bvalue(s_ptab[i], z, z, &tmp)) != MP_OK) return res; if(mp_int_compare_value(&tmp, s_ptab[i]) != 0) { mp_int_clear(&tmp); return MP_FALSE; } } mp_int_clear(&tmp); } return MP_TRUE; }
static int ltm_rsa_public_decrypt(int flen, const unsigned char* from, unsigned char* to, RSA* rsa, int padding) { unsigned char *p; int res; size_t size; mp_int s, us, n, e; if (padding != RSA_PKCS1_PADDING) return -1; if (flen > RSA_size(rsa)) return -2; mp_init_multi(&e, &n, &s, &us, NULL); BN2mpz(&n, rsa->n); BN2mpz(&e, rsa->e); #if 0 /* Check that the exponent is larger then 3 */ if (mp_int_compare_value(&e, 3) <= 0) { mp_clear_multi(&e, &n, &s, &us, NULL); return -3; } #endif mp_read_unsigned_bin(&s, rk_UNCONST(from), flen); if (mp_cmp(&s, &n) >= 0) { mp_clear_multi(&e, &n, &s, &us, NULL); return -4; } res = mp_exptmod(&s, &e, &n, &us); mp_clear_multi(&e, &n, &s, NULL); if (res != 0) { mp_clear(&us); return -5; } p = to; size = mp_unsigned_bin_size(&us); assert(size <= RSA_size(rsa)); mp_to_unsigned_bin(&us, p); mp_clear(&us); /* head zero was skipped by mp_to_unsigned_bin */ if (*p == 0) return -6; if (*p != 1) return -7; size--; p++; while (size && *p == 0xff) { size--; p++; } if (size == 0 || *p != 0) return -8; size--; p++; memmove(to, p, size); return size; }
static int gmp_rsa_public_decrypt(int flen, const unsigned char* from, unsigned char* to, RSA* rsa, int padding) { unsigned char *p; size_t size; mpz_t s, us, n, e; if (padding != RSA_PKCS1_PADDING) return -1; if (flen > RSA_size(rsa)) return -2; BN2mpz(n, rsa->n); BN2mpz(e, rsa->e); #if 0 /* Check that the exponent is larger then 3 */ if (mp_int_compare_value(&e, 3) <= 0) { mp_int_clear(&n); mp_int_clear(&e); return -3; } #endif mpz_init(s); mpz_init(us); mpz_import(s, flen, 1, 1, 1, 0, rk_UNCONST(from)); if (mpz_cmp(s, n) >= 0) { mpz_clear(n); mpz_clear(e); return -4; } mpz_powm(us, s, e, n); mpz_clear(s); mpz_clear(n); mpz_clear(e); p = to; mpz_export(p, &size, 1, 1, 1, 0, us); assert(size <= RSA_size(rsa)); mpz_clear(us); /* head zero was skipped by mp_int_to_unsigned */ if (*p == 0) return -6; if (*p != 1) return -7; size--; p++; while (size && *p == 0xff) { size--; p++; } if (size == 0 || *p != 0) return -8; size--; p++; memmove(to, p, size); return size; }