Продолжил эксперименты. Сделал так:
var bytes = new Uint8Array(3000000);
for (let i = 0; i < 3000000; i++) bytes[i] = 1;
let hash1 = await crypto.subtle.digest('SHA-1', bytes); //!!!!!!!!!!!!!
let hash1_str = Array.prototype.map.call(new Uint8Array(hash1), x => ('00' + x.toString(16)).slice(-2).toUpperCase()).join('');
let hash2 = sha1(bytes);
sha1 это переделанная вчерашняя функция которая выводила неправильный результат.
И о чудо! В данном случае результаты совпали.
Начал разбираться. И оказалось что буфер который возвращает readAsArrayBuffer, не совсем буфер.
Обернув в такую конструкцию:
sha1(new Uint8Array(file_bytes));
Всё заработало.