Esempio n. 1
0
bool rsa_ssh1_encrypt(unsigned char *data, int length, RSAKey *key)
{
    mp_int *b1, *b2;
    int i;
    unsigned char *p;

    if (key->bytes < length + 4)
	return false;                  /* RSA key too short! */

    memmove(data + key->bytes - length, data, length);
    data[0] = 0;
    data[1] = 2;

    size_t npad = key->bytes - length - 3;
    /*
     * Generate a sequence of nonzero padding bytes. We do this in a
     * reasonably uniform way and without having to loop round
     * retrying the random number generation, by first generating an
     * integer in [0,2^n) for an appropriately large n; then we
     * repeatedly multiply by 255 to give an integer in [0,255*2^n),
     * extract the top 8 bits to give an integer in [0,255), and mask
     * those bits off before multiplying up again for the next digit.
     * This gives us a sequence of numbers in [0,255), and of course
     * adding 1 to each of them gives numbers in [1,256) as we wanted.
     *
     * (You could imagine this being a sort of fixed-point operation:
     * given a uniformly random binary _fraction_, multiplying it by k
     * and subtracting off the integer part will yield you a sequence
     * of integers each in [0,k). I'm just doing that scaled up by a
     * power of 2 to avoid the fractions.)
     */
    size_t random_bits = (npad + 16) * 8;
    mp_int *randval = mp_new(random_bits + 8);
    mp_int *tmp = mp_random_bits(random_bits);
    mp_copy_into(randval, tmp);
    mp_free(tmp);
    for (i = 2; i < key->bytes - length - 1; i++) {
        mp_mul_integer_into(randval, randval, 255);
        uint8_t byte = mp_get_byte(randval, random_bits / 8);
        assert(byte != 255);
        data[i] = byte + 1;
        mp_reduce_mod_2to(randval, random_bits);
    }
    mp_free(randval);
    data[key->bytes - length - 1] = 0;

    b1 = mp_from_bytes_be(make_ptrlen(data, key->bytes));

    b2 = mp_modpow(b1, key->exponent, key->modulus);

    p = data;
    for (i = key->bytes; i--;) {
	*p++ = mp_get_byte(b2, i);
    }

    mp_free(b1);
    mp_free(b2);

    return true;
}
Esempio n. 2
0
static mp_int *eddsa_exponent_from_hash(
    ptrlen hash, const struct ec_curve *curve)
{
    /*
     * Make an integer out of the hash data, little-endian.
     */
    assert(hash.len >= curve->fieldBytes);
    mp_int *e = mp_from_bytes_le(make_ptrlen(hash.ptr, curve->fieldBytes));

    /*
     * Set the highest bit that fits in the modulus, and clear any
     * above that.
     */
    mp_set_bit(e, curve->fieldBits - 1, 1);
    mp_reduce_mod_2to(e, curve->fieldBits);

    /*
     * Clear exactly three low bits.
     */
    for (size_t bit = 0; bit < 3; bit++)
        mp_set_bit(e, bit, 0);

    return e;
}