/*
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 */

package amcl

import (
	"sync"
)

//import "fmt"

const rand_NK int = 21
const rand_NJ int = 6
const rand_NV int = 8

type RAND struct {
	sync.Mutex
	ira      [rand_NK]uint32 /* random number...   */
	rndptr   int
	borrow   uint32
	pool_ptr int
	pool     [32]byte
}

/* Terminate and clean up */
func (R *RAND) Clean() { /* kill internal state */
	R.pool_ptr = 0
	R.rndptr = 0
	for i := 0; i < 32; i++ {
		R.pool[i] = 0
	}
	for i := 0; i < rand_NK; i++ {
		R.ira[i] = 0
	}
	R.borrow = 0
}

func NewRAND() *RAND {
	R := new(RAND)
	R.Clean()
	return R
}

func (R *RAND) sbrand() uint32 { /* Marsaglia & Zaman random number generator */
	R.rndptr++
	if R.rndptr < rand_NK {
		return R.ira[R.rndptr]
	}
	R.rndptr = 0
	k := rand_NK - rand_NJ
	for i := 0; i < rand_NK; i++ { /* calculate next NK values */
		if k == rand_NK {
			k = 0
		}
		t := R.ira[k]
		pdiff := t - R.ira[i] - R.borrow
		if pdiff < t {
			R.borrow = 0
		}
		if pdiff > t {
			R.borrow = 1
		}
		R.ira[i] = pdiff
		k++
	}

	return R.ira[0]
}

func (R *RAND) sirand(seed uint32) {
	var m uint32 = 1
	R.borrow = 0
	R.rndptr = 0
	R.ira[0] ^= seed
	for i := 1; i < rand_NK; i++ { /* fill initialisation vector */
		in := (rand_NV * i) % rand_NK
		R.ira[in] ^= m /* note XOR */
		t := m
		m = seed - m
		seed = t
	}

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

func (R *RAND) fill_pool() {

	sh := NewHASH()
	for i := 0; i < 128; i++ {
		sh.Process(byte(R.sbrand() & 0xff))
	}
	R.pool = sh.Hash()
	R.pool_ptr = 0
}

func pack(b [4]byte) uint32 { /* pack 4 bytes into a 32-bit Word */
	return (((uint32(b[3])) & 0xff) << 24) | ((uint32(b[2]) & 0xff) << 16) | ((uint32(b[1]) & 0xff) << 8) | (uint32(b[0]) & 0xff)
}

/* Initialize RNG with some real entropy from some external source */
func (R *RAND) Seed(rawlen int, raw []byte) { /* initialise from at least 128 byte string of raw random entropy */
	var b [4]byte
	sh := NewHASH()
	R.pool_ptr = 0

	for i := 0; i < rand_NK; i++ {
		R.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]
			R.sirand(pack(b))
		}
	}
	R.fill_pool()
}

/* get random byte */
func (R *RAND) GetByte() byte {
	R.Lock()
	defer R.Unlock()

	r := R.pool[R.pool_ptr]
	R.pool_ptr++

	if R.pool_ptr >= 32 {
		R.fill_pool()
	}
	return byte(r & 0xff)
}

/* test main program */
/*
func main() {
	var raw [100]byte
	rng:=NewRAND()

	rng.Clean()
	for i:=0;i<100;i++ {raw[i]=byte(i)}

	rng.Seed(100,raw[:])

	for i:=0;i<1000;i++ {
		fmt.Printf("%03d ",rng.GetByte())
	}
}
*/
