aboutsummaryrefslogblamecommitdiffstats
path: root/pow/ar/rnd.go
blob: c62f4e0622bc271857fa80957da5956f730adbd8 (plain) (tree)
1
2
3
4
5
6
7




                  
                                                
                                                 















                                                         
                                                           
                                                  
                                                                   





                                                
                                                                   
































                                                     
package ar

import (
    "math/big"

    "github.com/ethereum/go-ethereum/crypto"
    "github.com/ethereum/go-ethereum/ethutil"
)

var b = big.NewInt

type Node interface {
    Big() *big.Int
}

type ByteNode []byte

func (self ByteNode) Big() *big.Int {
    return ethutil.BigD(ethutil.Encode([]byte(self)))
}

func Sha3(v interface{}) *big.Int {
    if b, ok := v.(*big.Int); ok {
        return ethutil.BigD(crypto.Sha3(b.Bytes()))
    } else if b, ok := v.([]interface{}); ok {
        return ethutil.BigD(crypto.Sha3(ethutil.Encode(b)))
    } else if s, ok := v.([]*big.Int); ok {
        v := make([]interface{}, len(s))
        for i, b := range s {
            v[i] = b
        }

        return ethutil.BigD(crypto.Sha3(ethutil.Encode(v)))
    }

    return nil
}

type NumberGenerator interface {
    rand(r *big.Int) *big.Int
    rand64(r int64) *big.Int
}

type rnd struct {
    seed *big.Int
}

func Rnd(s *big.Int) rnd {
    return rnd{s}
}

func (self rnd) rand(r *big.Int) *big.Int {
    o := b(0).Mod(self.seed, r)

    self.seed.Div(self.seed, r)

    if self.seed.Cmp(ethutil.BigPow(2, 64)) < 0 {
        self.seed = Sha3(self.seed)
    }

    return o
}

func (self rnd) rand64(r int64) *big.Int {
    return self.rand(b(r))
}