Xor bit a bit mais rápido entre duas variáveis de dados binários multibyte

Qual é a maneira mais rápida de implementar a seguinte lógica:

def xor(data, key):
    l = len(key)

    buff = ""
    for i in range(0, len(data)):
        buff += chr(ord(data[i]) ^ ord(key[i % l]))
    return buff

No meu casochav é um resumo sha1 de 20 bytes edado são alguns dados binários entre 20 bytes e poucos (1, 2, 3) megabytes de comprimento

ATUALIZAR

Ok pessoal. Aqui está uma implementação 3,5 vezes mais rápida, que divide dados e chaves em pedaços de 4, 2 ou 1 bytes (no meu caso, na maioria das vezes é um número inteiro de 4 bytes):

def xor(data, key):
    index = len(data) % 4
    size = (4, 1, 2, 1)[index]
    type = ('L', 'B', 'H', 'B')[index]
    key_len = len(key)/size
    data_len = len(data)/size
    key_fmt = "<" + str(key_len) + type;
    data_fmt = "<" + str(data_len) + type;

    key_list = struct.unpack(key_fmt, key)
    data_list = struct.unpack(data_fmt, data)

    result = []
    for i in range(data_len):
        result.append (key_list[i % key_len] ^ data_list[i])

    return struct.pack(data_fmt, *result)

Usa muita memória, mas no meu caso não é grande cois

Alguma idéia de como aumentar a velocidade mais algumas vezes? : -)

FINAL UPDATE:

OK, ok ... numpy fez o trabalho. Isso é muito rápido:

def xor(data, key):
    import numpy, math

    # key multiplication in order to match the data length
    key = (key*int(math.ceil(float(len(data))/float(len(key)))))[:len(data)]

    # Select the type size in bytes       
    for i in (8,4,2,1):
        if not len(data) % i: break

    if i == 8: dt = numpy.dtype('<Q8');
    elif i == 4: dt = numpy.dtype('<L4');
    elif i == 2: dt = numpy.dtype('<H2');
    else: dt = numpy.dtype('B');

    return numpy.bitwise_xor(numpy.fromstring(key, dtype=dt), numpy.fromstring(data, dtype=dt)).tostring()

implementação inicial precisou de 8 minutos e 50 segundos para processar um gigabyte, o segundo - cerca de 2 minutos e 30 segundos e o último apenas .... 0 minutos e 10 segundo

Obrigado a todos que contribuíram com idéias e código. Vocês são ótimos!

questionAnswers(6)

yourAnswerToTheQuestion