It's funny to watch the proponents of the prefix theory. the point coordinates themselves are hashes, and applying sha256 and rmd160 to them produces a set of bits that is in no way related to the private key. In your theory, the match of the first m bits in the hash should be repeated every 2^m iterations, but this is not at all the case. In a 120-bit field, it will indeed be found approximately 2^(120-m) times, but to understand the pattern in the puzzle range, you need to go through at least half of it, which is impossible. Here is a simple code (m=12) proving that the distance from identical prefixes is unpredictable, although it averages 2^m steps:
from os import urandom
from hashlib import sha256, new
p = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f
n = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141
Gx = 0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798
Gy = 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8
def add(x, y, z, w):
y = (pow(x - z, -1, p) * (y - w) if x != z else pow(y + y, -1, p) * x * x * 3) % p
x = (y * y - x - z) % p
return x, (y * (z - x) - w) % p
def multiply(k, z, w):
x, y = z, w
for i in bin(k % n)[3:]:
x, y = add(x, y, x, y)
if i == '1':
x, y = add(x, y, z, w)
return x, y
def hash160(x, y):
return new('ripemd160', sha256((b'\x03' if y & 1 else b'\x02') + x.to_bytes(32, 'big')).digest()).digest()
def random_key():
return 1 + int.from_bytes(urandom(32), 'little') % ((n - 1) // 2)
x, y = multiply(random_key(), Gx, Gy)
i, s, c = 0, 0, 0
while 1:
h = hash160(x, y)
i += 1
if h[0] == 0 and h[1] >> 4 == 0:
s += i
c += 1
print(h.hex(), i, s / c)
i = 0
x, y = add(x, y, Gx, Gy)