--- /dev/null
+/* -*-c-*-
+ *
+ * Barrett modular reduction
+ *
+ * (c) 1999 Straylight/Edgeware
+ */
+
+/*----- Licensing notice --------------------------------------------------*
+ *
+ * This file is part of Catacomb.
+ *
+ * Catacomb is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * Catacomb is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with Catacomb; if not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+/*----- Notes on Barrett reduction ----------------------------------------*
+ *
+ * Barrett reduction is a technique for computing modular residues. Unlike
+ * Montgomery reduction, it doesn't have restrictions on the modulus (except
+ * that it be positive) and doesn't confuse matters by putting an extra
+ * factor all the way through your computation.
+ *
+ * It's useful for slightly less heavy-duty work than Montgomery reduction
+ * because the precomputation phase is rather simpler, involving a single
+ * division operation.
+ *
+ * Sometimes it's useful to exponentiate modulo an even number, so there's a
+ * modexp routine provided which uses Barrett reduction rather than
+ * Montgomery reduction. This is handy when you're working on indices in an
+ * even-order cyclic group or something.
+ */
+
+#ifndef CATACOMB_MPBARRETT_H
+#define CATACOMB_MPBARRETT_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/*----- Header files ------------------------------------------------------*/
+
+#ifndef CATACOMB_MP_H
+# include "mp.h"
+#endif
+
+/*----- Data structures ---------------------------------------------------*/
+
+typedef struct mpbarrett {
+ mp *m;
+ mp *mu;
+ size_t k;
+} mpbarrett;
+
+/*----- Functions provided ------------------------------------------------*/
+
+/* --- @mpbarrett_create@ --- *
+ *
+ * Arguments: @mpbarrett *mb@ = pointer to Barrett reduction context
+ * @mp *m@ = modulus to work to
+ *
+ * Returns: Zero on success, nonzero on error.
+ *
+ * Use: Initializes a Barrett reduction context ready for use.
+ */
+
+extern int mpbarrett_create(mpbarrett */*mb*/, mp */*m*/);
+
+/* --- @mpbarrett_destroy@ --- *
+ *
+ * Arguments: @mpbarrett *mb@ = pointer to Barrett reduction context
+ *
+ * Returns: ---
+ *
+ * Use: Destroys a Barrett reduction context releasing any resources
+ * claimed.
+ */
+
+extern void mpbarrett_destroy(mpbarrett */*mb*/);
+
+/* --- @mpbarrett_reduce@ --- *
+ *
+ * Arguments: @mpbarrett *mb@ = pointer to Barrett reduction context
+ * @mp *d@ = destination for result
+ * @mp *m@ = number to reduce
+ *
+ * Returns: The residue of @m@ modulo the number in the reduction
+ * context.
+ *
+ * Use: Performs an efficient modular reduction.
+ */
+
+extern mp *mpbarrett_reduce(mpbarrett */*mb*/, mp */*d*/, mp */*m*/);
+
+/* --- @mpbarrett_exp@ --- *
+ *
+ * Arguments: @mpbarrett *mb@ = pointer to Barrett reduction context
+ * @mp *d@ = fake destination
+ * @mp *a@ = base
+ * @mp *e@ = exponent
+ *
+ * Returns: Result, %$a^e \bmod m$%.
+ */
+
+extern mp *mpbarrett_exp(mpbarrett */*mb*/, mp */*d*/, mp */*a*/, mp */*e*/);
+
+/* --- @mpbarrett_mexp@ --- *
+ *
+ * Arguments: @mpbarrett *mb@ = pointer to Barrett reduction context
+ * @mp *d@ = fake destination
+ * @const mp_expfactor *f@ = pointer to array of factors
+ * @size_t n@ = number of factors supplied
+ *
+ * Returns: If the bases are %$g_0, g_1, \ldots, g_{n-1}$% and the
+ * exponents are %$e_0, e_1, \ldots, e_{n-1}$% then the result
+ * is:
+ *
+ * %$g_0^{e_0} g_1^{e_1} \ldots g_{n-1}^{e_{n-1}} \bmod m$%
+ */
+
+extern mp *mpbarrett_mexp(mpbarrett */*mb*/, mp */*d*/,
+ const mp_expfactor */*f*/, size_t /*n*/);
+
+/*----- That's all, folks -------------------------------------------------*/
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif