+/* --- @des_expand@ --- *
+ *
+ * Arguments: @const octet *k@ = pointer to key material
+ * @size_t n@ = number of octets of key material (7 or 8)
+ * @uint32 *xx, *yy@ = where to put the results
+ *
+ * Returns: ---
+ *
+ * Use: Extracts 64 bits of key material from the given buffer,
+ * possibly expanding it from 56 to 64 bits on the way.
+ * Parity is set correctly if the key is expanded.
+ */
+
+void des_expand(const octet *k, size_t n, uint32 *xx, uint32 *yy)
+{
+ uint32 x, y, z;
+
+ if (n == 8) {
+ x = LOAD32(k + 0);
+ y = LOAD32(k + 4);
+ } else {
+ x = LOAD32(k + 0);
+ x = (x & 0xfe000000) | ((x & 0x01fffff0) >> 1);
+ x = (x & 0xfffe0000) | ((x & 0x0001fff8) >> 1);
+ x = (x & 0xfffffe00) | ((x & 0x000001fc) >> 1);
+ z = x; z ^= z >> 4; z ^= z >> 2; z ^= z >> 1;
+ x |= (z & 0x01010101) ^ 0x01010101;
+ y = LOAD32(k + 3) << 1; /* Note: misaligned */
+ y = (y & 0x000000fe) | ((y & 0x1fffff00) << 1);
+ y = (y & 0x0000fefe) | ((y & 0x3fff0000) << 1);
+ y = (y & 0x00fefefe) | ((y & 0x7f000000) << 1);
+ z = y; z ^= z >> 4; z ^= z >> 2; z ^= z >> 1;
+ y |= (z & 0x01010101) ^ 0x01010101;
+ }
+ *xx = x; *yy = y;
+}
+