-#ifdef TESTMODE
-
-#ifndef NODDY
-#define p1 10007
-#define p2 10069
-#define p3 10177
-#else
-#define p1 3
-#define p2 7
-#define p3 13
-#endif
-
-unsigned short P1[2] = { 1, p1 };
-unsigned short P2[2] = { 1, p2 };
-unsigned short P3[2] = { 1, p3 };
-unsigned short bigmod[5] = { 4, 0, 0, 0, 32768U };
-unsigned short mod[5] = { 4, 0, 0, 0, 0 };
-unsigned short a[5] = { 4, 0, 0, 0, 0 };
-unsigned short b[5] = { 4, 0, 0, 0, 0 };
-unsigned short c[5] = { 4, 0, 0, 0, 0 };
-unsigned short One[2] = { 1, 1 };
-unsigned short Two[2] = { 1, 2 };
+void ssh_rsakex_encrypt(const struct ssh_hash *h, unsigned char *in, int inlen,
+ unsigned char *out, int outlen,
+ void *key)
+{
+ Bignum b1, b2;
+ struct RSAKey *rsa = (struct RSAKey *) key;
+ int k, i;
+ char *p;
+ const int HLEN = h->hlen;
+
+ /*
+ * Here we encrypt using RSAES-OAEP. Essentially this means:
+ *
+ * - we have a SHA-based `mask generation function' which
+ * creates a pseudo-random stream of mask data
+ * deterministically from an input chunk of data.
+ *
+ * - we have a random chunk of data called a seed.
+ *
+ * - we use the seed to generate a mask which we XOR with our
+ * plaintext.
+ *
+ * - then we use _the masked plaintext_ to generate a mask
+ * which we XOR with the seed.
+ *
+ * - then we concatenate the masked seed and the masked
+ * plaintext, and RSA-encrypt that lot.
+ *
+ * The result is that the data input to the encryption function
+ * is random-looking and (hopefully) contains no exploitable
+ * structure such as PKCS1-v1_5 does.
+ *
+ * For a precise specification, see RFC 3447, section 7.1.1.
+ * Some of the variable names below are derived from that, so
+ * it'd probably help to read it anyway.
+ */
+
+ /* k denotes the length in octets of the RSA modulus. */
+ k = (7 + bignum_bitcount(rsa->modulus)) / 8;
+
+ /* The length of the input data must be at most k - 2hLen - 2. */
+ assert(inlen > 0 && inlen <= k - 2*HLEN - 2);
+
+ /* The length of the output data wants to be precisely k. */
+ assert(outlen == k);
+
+ /*
+ * Now perform EME-OAEP encoding. First set up all the unmasked
+ * output data.
+ */
+ /* Leading byte zero. */
+ out[0] = 0;
+ /* At position 1, the seed: HLEN bytes of random data. */
+ for (i = 0; i < HLEN; i++)
+ out[i + 1] = random_byte();
+ /* At position 1+HLEN, the data block DB, consisting of: */
+ /* The hash of the label (we only support an empty label here) */
+ h->final(h->init(), out + HLEN + 1);
+ /* A bunch of zero octets */
+ memset(out + 2*HLEN + 1, 0, outlen - (2*HLEN + 1));
+ /* A single 1 octet, followed by the input message data. */
+ out[outlen - inlen - 1] = 1;
+ memcpy(out + outlen - inlen, in, inlen);
+
+ /*
+ * Now use the seed data to mask the block DB.
+ */
+ oaep_mask(h, out+1, HLEN, out+HLEN+1, outlen-HLEN-1);
+
+ /*
+ * And now use the masked DB to mask the seed itself.
+ */
+ oaep_mask(h, out+HLEN+1, outlen-HLEN-1, out+1, HLEN);
+
+ /*
+ * Now `out' contains precisely the data we want to
+ * RSA-encrypt.
+ */
+ b1 = bignum_from_bytes(out, outlen);
+ b2 = modpow(b1, rsa->exponent, rsa->modulus);
+ p = (char *)out;
+ for (i = outlen; i--;) {
+ *p++ = bignum_byte(b2, i);
+ }
+ freebn(b1);
+ freebn(b2);