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.ansiBrightWhite": "#ffffff",
},
"python.testing.pyTestEnabled": false,
"python.testing.pytestEnabled": false,
"python.testing.nosetestsEnabled": false,
"python.testing.unittestEnabled": true,
"python.testing.unittestArgs": [

View file

@ -37,20 +37,60 @@ window.onerror = function (msg, url, lineNo, columnNo, error) {
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) {
return document.getElementById(id);
}
(function () {
// hide basic uploader
o('up2k').style.display = 'block';
o('bup').style.display = 'none';
// show modal message
function showmodal(msg) {
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
o('u2tgl').onclick = function (e) {
e.preventDefault();
o('u2tgl').style.display = 'none';
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
@ -123,10 +163,13 @@ function o(id) {
};
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)
return un2k("this is the basic uploader; the good one needs at least<br />chrome 37 // firefox 34 // edge 12 // opera 24 // safari 7");
if (!bobslice || !window.FileReader || !window.FileList)
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() {
o('file' + fdom_ctr).click();
@ -157,6 +200,7 @@ function o(id) {
var fobj = files[a];
var entry = {
"n": parseInt(st.files.length.toString()),
"t0": new Date().getTime(), // TODO remove probably
"fobj": fobj,
"name": fobj.name,
"size": fobj.size,
@ -317,8 +361,25 @@ function o(id) {
};
var segm_load = async function (ev) {
const hashbuf = await crypto.subtle.digest('SHA-256', ev.target.result);
t.hash.push(buf2b64(hashbuf));
var filebuf = ev.target.result;
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);
if (++nchunk < nchunks) {
@ -347,6 +408,10 @@ function o(id) {
var t = st.todo.handshake.shift();
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();
xhr.onload = function (ev) {
if (xhr.status == 200) {

View file

@ -14,6 +14,16 @@
display: none;
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 {
color: #f87;
padding: .5em;
@ -24,7 +34,7 @@
}
#u2body {
display: none;
padding-bottom: 2em;
padding-bottom: 1em;
}
#u2form {
width: 2px;
@ -50,6 +60,12 @@
cursor: pointer;
box-shadow: .4em .4em 0 #111;
}
#u2notbtn {
display: none;
text-align: center;
background: #333;
padding-top: 1em;
}
#u2tab {
margin: 3em auto;
width: calc(100% - 2em);

View file

@ -9,8 +9,8 @@
<div id="up2k">
<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">
<form id="u2form" method="POST" enctype="multipart/form-data" onsubmit="return false;"></form>
<table id="u2conf">
<tr>
@ -31,6 +31,8 @@
</tr>
</table>
<div id="u2notbtn"></div>
<div id="u2btn">
drop files here<br />
(or click me)
@ -44,6 +46,7 @@
</tr>
</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>

View file

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