+/* --- @mpx_umuln@ --- *
+ *
+ * Arguments: @mpw *dv, *dvl@ = destination vector base and limit
+ * @const mpw *av, *avl@ = multiplicand vector base and limit
+ * @mpw m@ = multiplier
+ *
+ * Returns: ---
+ *
+ * Use: Multiplies a multiprecision integer by a single-word value.
+ * The destination and source may be equal. The destination
+ * is completely cleared after use.
+ */
+
+void mpx_umuln(mpw *dv, mpw *dvl, const mpw *av, const mpw *avl, mpw m)
+{
+ MPX_UMULN(dv, dvl, av, avl, m);
+}
+
+/* --- @mpx_umlan@ --- *
+ *
+ * Arguments: @mpw *dv, *dvl@ = destination/accumulator base and limit
+ * @const mpw *av, *avl@ = multiplicand vector base and limit
+ * @mpw m@ = multiplier
+ *
+ * Returns: ---
+ *
+ * Use: Multiplies a multiprecision integer by a single-word value
+ * and adds the result to an accumulator.
+ */
+
+void mpx_umlan(mpw *dv, mpw *dvl, const mpw *av, const mpw *avl, mpw m)
+{
+ MPX_UMLAN(dv, dvl, av, avl, m);
+}
+
+/* --- @mpx_usqr@ --- *
+ *
+ * Arguments: @mpw *dv, *dvl@ = destination vector base and limit
+ * @const mpw *av, *av@ = source vector base and limit
+ *
+ * Returns: ---
+ *
+ * Use: Performs unsigned integer squaring. The result vector must
+ * not overlap the source vector in any way.
+ */
+
+void mpx_usqr(mpw *dv, mpw *dvl, const mpw *av, const mpw *avl)
+{
+ MPX_ZERO(dv, dvl);
+
+ /* --- Main loop --- */
+
+ while (av < avl) {
+ const mpw *avv = av;
+ mpw *dvv = dv;
+ mpw a = *av;
+ mpd c;
+
+ /* --- Stop if I've run out of destination --- */
+
+ if (dvv >= dvl)
+ break;
+
+ /* --- Work out the square at this point in the proceedings --- */
+
+ {
+ mpd x = (mpd)a * (mpd)a + *dvv;
+ *dvv++ = MPW(x);
+ c = MPW(x >> MPW_BITS);
+ }
+
+ /* --- Now fix up the rest of the vector upwards --- */
+
+ avv++;
+ while (dvv < dvl && avv < avl) {
+ mpd x = (mpd)a * (mpd)*avv++;
+ mpd y = ((x << 1) & MPW_MAX) + c + *dvv;
+ c = (x >> (MPW_BITS - 1)) + (y >> MPW_BITS);
+ *dvv++ = MPW(y);
+ }
+ while (dvv < dvl && c) {
+ mpd x = c + *dvv;
+ *dvv++ = MPW(x);
+ c = x >> MPW_BITS;
+ }
+
+ /* --- Get ready for the next round --- */
+
+ av++;
+ dv += 2;
+ }
+}
+