def weakrandom_bytearray(self, buf, start, end): assert end <= len(buf) assert start <= end nbytes = end - start if nbytes < 128: nwords = nbytes/4 for i in range(nwords): buf[start + 4*i : start + 4*(i + 1)] = \ struct.pack('<I', self.weakrandom32()) nextra = nbytes - 4*nwords if 0 < nextra: buf[start + 4*nwords : start + 4*nwords + nextra] = \ struct.pack('<I', self.weakrandom32())[0 : nextra] else: subkey = [self.weakrandom32() for i in range(8)] const32 = self.const32 ctr = [0,0,0,0] out = [0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0] nblocks = nbytes/64 for i in range(nblocks): chacha.core(8, out, ctr, subkey, const32) # Overflows after 2^64 blocks. Not worth carrying. t = ctr[0] + 1; ctr[0] = t & 0xffffffff; ctr[1] += t buf[start + 64*i : start + 64*(i + 1)] = \ struct.pack('<IIIIIIIIIIIIIIII', *out) nextra = nbytes - 64*nblocks if 0 < nextra: chacha.core(8, out, ctr, subkey, const32) buf[start + 64*nblocks : start + 64*nblocks + nextra] = \ struct.pack('<IIIIIIIIIIIIIIII', *out)[0 : nextra] subkey[0:8] = out[0:8] = out[8:16] = self.zero
def weakrandom_bytearray(self, buf, start, end): assert end <= len(buf) assert start <= end nbytes = end - start if nbytes < 128: nwords = nbytes / 4 for i in range(nwords): buf[start + 4*i : start + 4*(i + 1)] = \ struct.pack('<I', self.weakrandom32()) nextra = nbytes - 4 * nwords if 0 < nextra: buf[start + 4*nwords : start + 4*nwords + nextra] = \ struct.pack('<I', self.weakrandom32())[0 : nextra] else: subkey = [self.weakrandom32() for i in range(8)] const32 = self.const32 ctr = [0, 0, 0, 0] out = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] nblocks = nbytes / 64 for i in range(nblocks): chacha.core(8, out, ctr, subkey, const32) # Overflows after 2^64 blocks. Not worth carrying. t = ctr[0] + 1 ctr[0] = t & 0xffffffff ctr[1] += t buf[start + 64*i : start + 64*(i + 1)] = \ struct.pack('<IIIIIIIIIIIIIIII', *out) nextra = nbytes - 64 * nblocks if 0 < nextra: chacha.core(8, out, ctr, subkey, const32) buf[start + 64*nblocks : start + 64*nblocks + nextra] = \ struct.pack('<IIIIIIIIIIIIIIII', *out)[0 : nextra] subkey[0:8] = out[0:8] = out[8:16] = self.zero
def weakrandom32(self): # We abuse buf[15] as a decrementing counter for the number # 32-bit words remaining to be yielded, since we refill the # buffer only when we need at least one word. buf = self.buf if buf[15] == 0: ctr = self.ctr chacha.core(8, buf, ctr, self.key, self.const32) t = 1 for i in range(4): # 4 is overkill t = ctr[i] + t ctr[i] = t & 0xffffffff t >>= 32 r = buf[15] buf[15] = 15 return r buf[15] -= 1 return buf[buf[15]]