/*
    Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements.  See the NOTICE file
    distributed with this work for additional information
    regarding copyright ownership.  The ASF licenses this file
    to you under the Apache License, Version 2.0 (the
    "License"); you may not use this file except in compliance
    with the License.  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing,
    software distributed under the License is distributed on an
    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    KIND, either express or implied.  See the License for the
    specific language governing permissions and limitations
    under the License.
*/

/*
 *   Cryptographic strong random number generator
 *
 *   Unguessable seed -> SHA -> PRNG internal state -> SHA -> random numbers
 *   Slow - but secure
 *
 *   See ftp://ftp.rsasecurity.com/pub/pdfs/bull-1.pdf for a justification
 */

/* Marsaglia & Zaman Random number generator constants */

var RAND = function(ctx) {
    "use strict";

    var RAND = function() {
        /* Cryptographically strong pseudo-random number generator */
        this.ira = []; /* random number...   */
        this.rndptr = 0; /* ...array & pointer */
        this.borrow = 0;
        this.pool_ptr = 0;
        this.pool = []; /* random pool */
        this.clean();
    };

    RAND.prototype = {
        NK: 21,
        NJ: 6,
        NV: 8,

        /* Terminate and clean up */
        clean: function() {
            var i;

            for (i = 0; i < 32; i++) {
                this.pool[i] = 0;
            }

            for (i = 0; i < this.NK; i++) {
                this.ira[i] = 0;
            }

            this.rndptr = 0;
            this.borrow = 0;
            this.pool_ptr = 0;
        },

        sbrand: function() { /* Marsaglia & Zaman random number generator */
            var i, k, pdiff, t;

            this.rndptr++;
            if (this.rndptr < this.NK) {
                return this.ira[this.rndptr];
            }

            this.rndptr = 0;

            for (i = 0, k = this.NK - this.NJ; i < this.NK; i++, k++) { /* calculate next NK values */
                if (k == this.NK) {
                    k = 0;
                }

                t = this.ira[k] >>> 0;
                pdiff = (t - this.ira[i] - this.borrow) | 0;
                pdiff >>>= 0; /* This is seriously weird shit. I got to do this to get a proper unsigned comparison... */

                if (pdiff < t) {
                    this.borrow = 0;
                }

                if (pdiff > t) {
                    this.borrow = 1;
                }

                this.ira[i] = (pdiff | 0);
            }

            return this.ira[0];
        },

        sirand: function(seed) {
            var m = 1,
                i, inn, t;

            this.borrow = 0;
            this.rndptr = 0;
            seed >>>= 0;
            this.ira[0] ^= seed;

            for (i = 1; i < this.NK; i++) { /* fill initialisation vector */
                inn = (this.NV * i) % this.NK;
                this.ira[inn] ^= m; /* note XOR */
                t = m;
                m = (seed - m) | 0;
                seed = t;
            }

            /* "warm-up" & stir the generator */
            for (i = 0; i < 10000; i++) {
                this.sbrand();
            }
        },

        fill_pool: function() {
            var sh = new ctx.HASH256(),
                i;

            for (i = 0; i < 128; i++) {
                sh.process(this.sbrand());
            }

            this.pool = sh.hash();
            this.pool_ptr = 0;
        },

        /* Initialize RNG with some real entropy from some external source */
        seed: function(rawlen, raw) { /* initialise from at least 128 byte string of raw random entropy */
            var sh = new ctx.HASH256(),
                digest = [],
                b = [],
                i;

            this.pool_ptr = 0;

            for (i = 0; i < this.NK; i++) {
                this.ira[i] = 0;
            }

            if (rawlen > 0) {
                for (i = 0; i < rawlen; i++) {
                    sh.process(raw[i]);
                }

                digest = sh.hash();

                /* initialise PRNG from distilled randomness */
                for (i = 0; i < 8; i++) {
                    b[0] = digest[4 * i];
                    b[1] = digest[4 * i + 1];
                    b[2] = digest[4 * i + 2];
                    b[3] = digest[4 * i + 3];
                    this.sirand(RAND.pack(b));
                }
            }

            this.fill_pool();
        },

        /* get random byte */
        getByte: function() {
            var r = this.pool[this.pool_ptr++];

            if (this.pool_ptr >= 32) {
                this.fill_pool();
            }

            return (r & 0xff);
        }
    };

    RAND.pack = function(b) { /* pack 4 bytes into a 32-bit Word */
        return (((b[3]) & 0xff) << 24) | ((b[2] & 0xff) << 16) | ((b[1] & 0xff) << 8) | (b[0] & 0xff);
    };

    return RAND;
};
