| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291 | <html>    <head>        <title>scrypt-js</title>        <style type="text/css">            body {               background: #f8f8f8;                color: #333;                margin: 40px 0;            }            body > div {                font-family: sans-serif;                margin-left: 50%;            }            body > div > div {                background: #fff;                border: 2px solid #888;                margin-left: -400px;                padding: 30px 20px 0;                width: 800px;            }            h1 {                margin: 0 0 30px 0;                text-align: center;            }            .forms {                float: right;                font-size: 14px;                padding-right: 10px;            }            .forms a {                color: #aaa;                cursor: pointer;            }            .forms b {                padding: 0 15px;            }            .forms .selected {                color: #333;            }            input {                border: 1px solid #aaa;                border-radius: 5px;                font-size: 20px;                padding: 8px 10px;                width: 100%;            }            input[type=submit] {                background-color: #dfd;                cursor: pointer;                margin-top: 40px;            }            input[type=submit]:active {                background-color: #cfc;                color: #040;            }            input[type=submit].cancel {                background-color: #fdd;            }            input[type=submit]:active.cancel {                background-color: #fcc;                color: #400;            }            input {                margin-bottom: 30px;            }            .param:first-child {                 margin-left: 0;            }            .param {                float: left;                margin-left: 66px;                width: 150px;            }            .param input {            }            .clearfix {                clear: both;            }            #result {                margin: 40px 0;            }            .progress {                border: 2px solid #666;                border-radius: 15px;                height: 30px;                position: relative;                width: 100%;            }            #progressBar {                background: #ccf;                border-radius: 15px;                position: absolute;                left: 0;                top: 0;                width: 0;                height: 30px;            }            #progressAmount {                position: absolute;                left: 0;                top: 0;                text-align: center;                line-height: 30px;                width: 100%;                height: 30px;            }        </style>    </head>    <body>        <div>            <div>                <h1>scrypt-js</h1>                <div>                    <div><b>Password</b> <span id="form-password" class="forms"><a class="form selected">UTF-8 (NFKC)</a><b>•</b><a class="form">UTF-8 (NFKD)</a><b>•</b><a class="form">hex</a></span></div>                    <input id="pbkdf-password" type="text" value="password" />                    <div><b>Salt</b> <span id="form-salt" class="forms"><a class="form selected">UTF-8 (NFKC)</a><b>•</b><a class="form">UTF-8 (NFKD)</a><b>•</b><a class="form">hex</a></span></div>                    <input id="pbkdf-salt" type="text" value="salt" />                    <div class="clearfix"></div>                    <div>                        <div class="param">                            <div><b>Nlog2</b> [1, 63]</div>                            <input id="pbkdf-Nlog2" type="text" value="10" />                        </div>                        <div class="param">                            <div><b>r</b></div>                            <input id="pbkdf-r" type="text" value="8" />                        </div>                        <div class="param">                            <div><b>p</b></div>                            <input id="pbkdf-p" type="text" value="1" />                        </div>                        <div class="param">                            <div><b>dkLen</b></div>                            <input id="pbkdf-dkLen" type="text" value="32" />                        </div>                    </div>                    <div class="clearfix"></div>                    <input id="pbkdf-submit" type="submit" value="Compute scrypt" />                    <div class="progress"><div id="progressBar"></div><div id="progressAmount">0%</div></div>                    <div id="result"></div>                </div>            </div>        </div>        <script src="thirdparty/setImmediate.js" type="text/javascript"></script>        <script src="thirdparty/unorm.js" type="text/javascript"></script>        <script src="thirdparty/buffer.js" type="text/javascript"></script>        <script src="scrypt.js" type="text/javascript"></script>        <script type="text/javascript">            function get(id) { return document.getElementById(id); }            function getValue(id) {                var value = get(id).value;                if (value.match(/^[0-9]+$/)) { return parseInt(value); }                return null;            }            function normalized(field) {                var value = get('pbkdf-' + field).value;                var forms = document.getElementById('form-' + field).getElementsByClassName('selected');                if (forms.length !== 1) { throw new Error('missing form'); }                var form = forms[0].innerHTML;                if (form.indexOf('NFKC') >= 0) {                    return new buffer.SlowBuffer(value.normalize('NFKC'), 'utf8');                } else if (form.indexOf('NFKD') >= 0) {                    return new buffer.SlowBuffer(value.normalize('NFKD'), 'utf8');                } else if (form.indexOf('hex') >= 0) {                    if (!value.match(/^([0-9A-F][0-9A-F])*$/i)) {                        throw new Error(field + ': invalid hex string');                    }                    return new buffer.SlowBuffer(value, 'hex');                }                throw new Error('Unknown ');            }            var firstLine = true;            function clearConsole() {                firstLine = true;                get('result').innerHTML = '';            }            function printConsole(message) {                if (!firstLine) { message = '<br /><br />' + message; }                firstLine = false;                get('result').innerHTML += message;            }            (function() {                var forms = document.getElementsByClassName('form');                for (var i = 0; i < forms.length; i++) {                    forms[i].onclick = (function(form) {                        return function() {                            console.log(form);                            var selected = form.parentNode.getElementsByClassName('selected')[0];                            selected.classList.remove('selected');                            form.classList.add('selected');                        };                    })(forms[i]);                }            })();            var submit = get('pbkdf-submit');            var done = null;            submit.onclick = function() {                if (done === null) {                    clearConsole();                    done = false;                    try {                        var password = normalized('password');                        var salt = normalized('salt');                        var N = 1 << getValue('pbkdf-Nlog2');                        var r = getValue('pbkdf-r');                        var p = getValue('pbkdf-p');                        var dkLen = getValue('pbkdf-dkLen');                        console.log(password, salt, N, r, p)                    } catch (error) {                        printConsole(error.message);                        done = null;                        return;                    }                    submit.classList.add('cancel');                    submit.value = "Cancel scrypt";                    printConsole('Started: N=' + N + ', r=' + r + ' p=' + p +                        ', password=0x' + password.toString('hex') + ', salt=0x' + salt.toString('hex'));                    var t0 = (new Date()).getTime();                    scrypt.scrypt(password, salt, N, r, p, dkLen, function(progress) {                        // Cancelled                        if (done) { return true; }                        // Update the progress bar                        get('progressBar').style.width = parseInt(100 * progress) + '%';                        get('progressAmount').innerHTML = parseInt(100 * progress) + '%';                    }).then(function(key) {                        key = new buffer.SlowBuffer(key);                        printConsole("Generated: " + key.toString('hex'));                        printConsole("Complete: " + (((new Date()).getTime() - t0) / 1000) + 's');                    }, function(error) {                        if (error.message === "cancelled") {                            printConsole("Cancelled!");                        } else {                            printConsole("Error: " + error.message);                        }                    }).then(function() {                        submit.classList.remove('cancel');                        submit.value = "Compute scrypt";                        done = null;                        get('progressBar').style.width = '0%';                        get('progressAmount').innerHTML = '0%';                    });                } else if (done === false) {                    done = true;                }            };        </script>    </body></html>
 |