Where exactly is the "off-by-one" difficulty bug? I read through How is difficulty calculated? and want to understand where the "off-by-one" bug is in calculating difficulty. Here is a Matlab snipet I wrote to calculate difficulty. What are the correct block step intervals that I should use? Note: minv and maxv are the block heights (plus 1) of the interval. Thus, time stamps from block heights 0 and 2015 are used in the first difficulty calculation.

% Calculate difficulty
num = floor(length(block_chain)/2016);
minv = 1;
maxv = 2016;
target = 1209600;
difficulty = ones(num,4);
delta = zeros(num,1);
timedif = delta;

for i = 1:num
    if i == 1
        difficulty(1,3) = 1;
        timedif(i) = block_chain(maxv,2) - block_chain(minv,2);
    else
        timedif(i) = block_chain(maxv,2) - block_chain(minv,2);
        delta(i) = max(0.25,min(target/timedif(i),4));
        difficulty(i,3) = max(1,difficulty(i-1,3)*delta(i));
    end
    difficulty(i,:) = [block_chain(minv,1), block_chain(maxv,1),...
        difficulty(i,3), timedif(i)];
    minv = maxv + 1;
    maxv = maxv + 2016;
end
From Litecoin wiki:


  Time warp bug[14]: the Bitcoin difficulty calculation is off by one block, so an attacker can repeatedly try to generate the last block of each retarget window, and use a fabricated timestamp of 2 hours into the future in order to make the time difference from the first block in the retarget window high, thus lowering the difficulty by 0.5%. Because of the bug, the bogus timestamp isn't used as the first block in the next retarget window, and therefore the 2 extra hours aren't being compensated for in the next difficulty calculation. Once the difficulty is low, the attacker can mine many fast coins, or in the case of a small chain, an attacker with 51% hash power could reduce the difficulty to 1 and mine a new fork from the genesis block. This isn't a feasible attack on Bitcoin, because the probability of repeatedly generating the last block once every 2 weeks at such high difficulties is negligible. Although fixing this issue in Bitcoin is possible, it should be done carefully (by adding rules that encourage nodes to upgrade over time) so to avoid a chain fork, i.e. old clients who didn't upgrade might operate with another difficulty and therefore disagree regarding which blocks are valid. In Litecoin this bug is fixed


The "off-by-one" or Time Warp Bug is caused because the difficulty calculation algorithm is not using overlapping periods, for the first recalc it uses blocks 1 up to 2016 and for the second it uses blocks 2017 up to 4032.

This alone is not a problem at all, but as the protocol has some allowance for time differences between the nodes this makes possible to lower the difficulty forging blocks with resolution time in the future.

The algorithm uses T(2016) - T(1) to calculate the speed of the network if block 2016 is created with a timestamp 2 hours in the future (max allowed by the protocol) then the difficulty will be a 0.5% lower of what it should be.

If then block 2017 is found and the time is real (T(2017) can be less than T(2016)) then the extra time added to block 2016 will not be compensated in the next recalculation as it would be if for block 2 used T(4032) - T(2016) to find the speed.

A more detailed attack scheme can be found at: https://bitcointalk.org/index.php?topic=43692.msg521772#msg521772