+/* --- @smallenough@ --- *
+ *
+ * Arguments: @mp *m@ = integer to test
+ *
+ * Returns: One of the @PGEN@ result codes.
+ *
+ * Use: Assuming that @m@ has been tested by trial division on every
+ * prime in the small-primes array, this function will return
+ * @PGEN_DONE@ if the number is less than the square of the
+ * largest small prime.
+ */
+
+static int smallenough(mp *m)
+{
+ static mp *max = 0;
+ int rc = PGEN_TRY;
+
+ if (!max) {
+ max = mp_fromuint(MP_NEW, MAXPRIME);
+ max = mp_sqr(max, max);
+ max->a->n--; /* Permanent allocation */
+ }
+ if (MP_CMP(m, <, max))
+ rc = PGEN_DONE;
+ return (rc);
+}
+
+/* --- @pfilt_smallfactor@ --- *
+ *
+ * Arguments: @mp *m@ = integer to test
+ *
+ * Returns: One of the @PGEN@ result codes.
+ *
+ * Use: Tests a number by dividing by a number of small primes. This
+ * is a useful first step if you're testing random primes; for
+ * sequential searches, @pfilt_create@ works better.
+ */
+
+int pfilt_smallfactor(mp *m)
+{
+ int rc = PGEN_TRY;
+ int i;
+ size_t sz = MP_LEN(m);
+ mparena *a = m->a ? m->a : MPARENA_GLOBAL;
+ mpw *v = mpalloc(a, sz);
+
+ /* --- Fill in the residues --- */
+
+ for (i = 0; i < NPRIME; i++) {
+ if (!mpx_udivn(v, v + sz, m->v, m->vl, primetab[i])) {
+ if (MP_LEN(m) == 1 && m->v[0] == primetab[i])
+ rc = PGEN_DONE;
+ else
+ rc = PGEN_FAIL;
+ }
+ }
+
+ /* --- Check for small primes --- */
+
+ if (rc == PGEN_TRY)
+ rc = smallenough(m);
+
+ /* --- Done --- */
+
+ mpfree(a, v);
+ return (rc);
+}
+