asm.js polyfill for crypto.subtle.digest

This commit is contained in:
ed 2019-06-27 23:25:49 +00:00
parent 96c6be0ea1
commit 1c7195e555
5 changed files with 109 additions and 27 deletions

View file

@ -22,7 +22,7 @@
"terminal.ansiBrightCyan": "#9cf0ed", "terminal.ansiBrightCyan": "#9cf0ed",
"terminal.ansiBrightWhite": "#ffffff", "terminal.ansiBrightWhite": "#ffffff",
}, },
"python.testing.pyTestEnabled": false, "python.testing.pytestEnabled": false,
"python.testing.nosetestsEnabled": false, "python.testing.nosetestsEnabled": false,
"python.testing.unittestEnabled": true, "python.testing.unittestEnabled": true,
"python.testing.unittestArgs": [ "python.testing.unittestArgs": [

View file

@ -37,20 +37,60 @@ window.onerror = function (msg, url, lineNo, columnNo, error) {
hcroak(html.join('\n')); hcroak(html.join('\n'));
}; };
// https://stackoverflow.com/a/950146
function import_js(url, cb) {
var head = document.head || document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = url;
script.onreadystatechange = cb;
script.onload = cb;
head.appendChild(script);
}
function o(id) { function o(id) {
return document.getElementById(id); return document.getElementById(id);
} }
(function () { (function () {
// hide basic uploader // show modal message
o('up2k').style.display = 'block'; function showmodal(msg) {
o('bup').style.display = 'none'; o('u2notbtn').innerHTML = msg;
o('u2btn').style.display = 'none';
o('u2notbtn').style.display = 'block';
o('u2conf').style.opacity = '0.5';
}
// hide modal message
function unmodal() {
o('u2notbtn').style.display = 'none';
o('u2btn').style.display = 'block';
o('u2conf').style.opacity = '1';
o('u2notbtn').innerHTML = '';
}
// might need sha512 polyfill when non-https (thx webkit (again))
var have_crypto = window.crypto && crypto.subtle && crypto.subtle.digest;
var shame = 'your browser <a href="https://www.chromium.org/blink/webcrypto">disables sha512</a> unless you <a href="' + (window.location + '').replace(':', 's:') + '">use https</a>'
//have_crypto = false;
// upload ui hidden by default, clicking the header shows it // upload ui hidden by default, clicking the header shows it
o('u2tgl').onclick = function (e) { o('u2tgl').onclick = function (e) {
e.preventDefault(); e.preventDefault();
o('u2tgl').style.display = 'none'; o('u2tgl').style.display = 'none';
o('u2body').style.display = 'block'; o('u2body').style.display = 'block';
if (!have_crypto && !window.asmCrypto) {
showmodal('<h1>loading sha512.js</h1><h2>since ' + shame + '</h2><h4>thanks chrome</h4>');
import_js('/.cpr/deps/sha512.js', unmodal);
o('u2foot').innerHTML = 'seems like ' + shame + ' so do that if you want more performance';
}
}; };
// shows or clears an error message in the basic uploader ui // shows or clears an error message in the basic uploader ui
@ -123,10 +163,13 @@ function o(id) {
}; };
var bobslice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice; var bobslice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice;
var have_crypto = window.crypto && crypto.subtle && crypto.subtle.digest;
if (!bobslice || !window.FileReader || !window.FileList || !have_crypto) if (!bobslice || !window.FileReader || !window.FileList)
return un2k("this is the basic uploader; the good one needs at least<br />chrome 37 // firefox 34 // edge 12 // opera 24 // safari 7"); return un2k("this is the basic uploader; up2k needs at least<br />chrome 21 // firefox 13 // edge 12 // opera 12 // safari 5.1");
// probably safe now
o('up2k').style.display = 'block';
o('bup').style.display = 'none';
function nav() { function nav() {
o('file' + fdom_ctr).click(); o('file' + fdom_ctr).click();
@ -157,6 +200,7 @@ function o(id) {
var fobj = files[a]; var fobj = files[a];
var entry = { var entry = {
"n": parseInt(st.files.length.toString()), "n": parseInt(st.files.length.toString()),
"t0": new Date().getTime(), // TODO remove probably
"fobj": fobj, "fobj": fobj,
"name": fobj.name, "name": fobj.name,
"size": fobj.size, "size": fobj.size,
@ -317,8 +361,25 @@ function o(id) {
}; };
var segm_load = async function (ev) { var segm_load = async function (ev) {
const hashbuf = await crypto.subtle.digest('SHA-256', ev.target.result); var filebuf = ev.target.result;
t.hash.push(buf2b64(hashbuf)); var hashbuf;
if (have_crypto)
hashbuf = await crypto.subtle.digest('SHA-512', filebuf);
else {
var ofs = 0;
var eof = filebuf.byteLength;
var hasher = new asmCrypto.Sha512();
//hasher.process(new Uint8Array(filebuf));
while (ofs < eof) {
// saves memory, doesn't affect perf
var ofs2 = Math.min(eof, ofs + 1024 * 1024);
hasher.process(new Uint8Array(filebuf.slice(ofs, ofs2)));
ofs = ofs2;
}
hasher.finish();
hashbuf = hasher.result;
}
t.hash.push(buf2b64(hashbuf).substr(0, 44));
prog(t.n, nchunk, col_hashed); prog(t.n, nchunk, col_hashed);
if (++nchunk < nchunks) { if (++nchunk < nchunks) {
@ -347,6 +408,10 @@ function o(id) {
var t = st.todo.handshake.shift(); var t = st.todo.handshake.shift();
st.busy.handshake.push(t); st.busy.handshake.push(t);
// TODO remove
var ts = new Date().getTime();
alert((ts - t.t0) + '\n' + t.hash.join('\n'));
var xhr = new XMLHttpRequest(); var xhr = new XMLHttpRequest();
xhr.onload = function (ev) { xhr.onload = function (ev) {
if (xhr.status == 200) { if (xhr.status == 200) {

View file

@ -14,6 +14,16 @@
display: none; display: none;
padding: 1.5em 1em 0 1em; padding: 1.5em 1em 0 1em;
} }
#u2form {
position: absolute;
top: 0;
left: 0;
}
#u2form input {
background: #444;
border: 0px solid #444;
outline: none;
}
#u2err.err { #u2err.err {
color: #f87; color: #f87;
padding: .5em; padding: .5em;
@ -24,7 +34,7 @@
} }
#u2body { #u2body {
display: none; display: none;
padding-bottom: 2em; padding-bottom: 1em;
} }
#u2form { #u2form {
width: 2px; width: 2px;
@ -50,6 +60,12 @@
cursor: pointer; cursor: pointer;
box-shadow: .4em .4em 0 #111; box-shadow: .4em .4em 0 #111;
} }
#u2notbtn {
display: none;
text-align: center;
background: #333;
padding-top: 1em;
}
#u2tab { #u2tab {
margin: 3em auto; margin: 3em auto;
width: calc(100% - 2em); width: calc(100% - 2em);

View file

@ -9,8 +9,8 @@
<div id="up2k"> <div id="up2k">
<a href="#" id="u2tgl">you can upload here</a> <a href="#" id="u2tgl">you can upload here</a>
<form id="u2form" method="POST" enctype="multipart/form-data" onsubmit="return false;"></form>
<div id="u2body"> <div id="u2body">
<form id="u2form" method="POST" enctype="multipart/form-data" onsubmit="return false;"></form>
<table id="u2conf"> <table id="u2conf">
<tr> <tr>
@ -31,6 +31,8 @@
</tr> </tr>
</table> </table>
<div id="u2notbtn"></div>
<div id="u2btn"> <div id="u2btn">
drop files here<br /> drop files here<br />
(or click me) (or click me)
@ -44,6 +46,7 @@
</tr> </tr>
</table> </table>
switch to the <a href="#" id="u2nope">basic uploader</a> if you don't need resumable uploads and progress bars <p id="u2foot"></p>
<p>( if you don't need resumable uploads and progress bars just use the <a href="#" id="u2nope" onclick="javascript:un2k();">basic uploader</a>)</p>
</div> </div>
</div> </div>

View file

@ -1,26 +1,24 @@
FROM alpine:3.10 FROM alpine:3.10
WORKDIR /z WORKDIR /z
ENV ver_forge=0.8.5 \ ENV ver_asmcrypto=2821dd1dedd1196c378f5854037dda5c869313f3 \
ver_ogvjs=1.6.1 ver_ogvjs=1.6.1
# download # download
RUN apk add make g++ git bash npm patch wget tar pigz gzip unzip \ RUN apk add make g++ git bash npm patch wget tar pigz gzip unzip \
&& wget https://github.com/digitalbazaar/forge/archive/$ver_forge.tar.gz \
&& wget https://github.com/brion/ogv.js/releases/download/$ver_ogvjs/ogvjs-$ver_ogvjs.zip \ && wget https://github.com/brion/ogv.js/releases/download/$ver_ogvjs/ogvjs-$ver_ogvjs.zip \
&& tar -xf $ver_forge.tar.gz \ && wget https://github.com/asmcrypto/asmcrypto.js/archive/$ver_asmcrypto.tar.gz \
&& unzip ogvjs-$ver_ogvjs.zip \ && unzip ogvjs-$ver_ogvjs.zip \
&& cd forge-$ver_forge \ && tar -xf $ver_asmcrypto.tar.gz \
&& npm install && cd asmcrypto.js-$ver_asmcrypto \
&& npm install \
&& mkdir /z/dist
# customize # build asmcrypto
COPY forge.patch /z RUN cd asmcrypto.js-$ver_asmcrypto \
&& echo "export { Sha512 } from './hash/sha512/sha512';" > src/entry-export_all.ts \
# build forge && node -r esm build.js \
RUN cd forge-$ver_forge \ && mv asmcrypto.all.es5.js /z/dist/sha512.js \
&& patch -p1 < /z/forge.patch \ && mv dist_es5/hash/sha512/sha512.asm.js /z/dist/
&& npm run build \
&& mkdir /z/dist \
&& cp -pv dist/forge.sha512.* /z/dist
# build ogvjs # build ogvjs
RUN cd ogvjs-$ver_ogvjs \ RUN cd ogvjs-$ver_ogvjs \