/* * Copyright (c) 2019, Psiphon Inc. * All rights reserved. * * Released under utls licence: * https://github.com/refraction-networking/utls/blob/master/LICENSE */// This code is a pared down version of:// https://github.com/Psiphon-Labs/psiphon-tunnel-core/blob/158caea562287284cc3fa5fcd1b3c97b1addf659/psiphon/common/prng/prng.gopackage tlsimport (crypto_rand)const (PRNGSeedLength = 32)// PRNGSeed is a PRNG seed.typePRNGSeed [PRNGSeedLength]byte// NewPRNGSeed creates a new PRNG seed using crypto/rand.Read.func () (*PRNGSeed, error) { := new(PRNGSeed) , := crypto_rand.Read([:])if != nil {returnnil, }return , nil}// newSaltedPRNGSeed creates a new seed derived from an existing seed and a// salt. A HKDF is applied to the seed and salt.//// newSaltedPRNGSeed is intended for use cases where a single seed needs to be// used in distinct contexts to produce independent random streams.func ( *PRNGSeed, string) (*PRNGSeed, error) { := new(PRNGSeed) , := io.ReadFull(hkdf.New(sha3.New256, [:], []byte(), nil), [:])if != nil {returnnil, }return , nil}// prng is a seeded, unbiased PRNG based on SHAKE256. that is suitable for use// cases such as obfuscation. Seeding is based on crypto/rand.Read.//// This PRNG is _not_ for security use cases including production cryptographic// key generation.//// It is safe to make concurrent calls to a PRNG instance.//// PRNG conforms to io.Reader and math/rand.Source, with additional helper// functions.typeprngstruct {rand *rand.RandrandomStreamMutexsync.MutexrandomStreamsha3.ShakeHash}// newPRNG generates a seed and creates a PRNG with that seed.func () (*prng, error) { , := NewPRNGSeed()if != nil {returnnil, }returnnewPRNGWithSeed()}// newPRNGWithSeed initializes a new PRNG using an existing seed.func ( *PRNGSeed) (*prng, error) { := sha3.NewShake256() , := .Write([:])if != nil {returnnil, } := &prng{randomStream: , } .rand = rand.New()return , nil}// newPRNGWithSaltedSeed initializes a new PRNG using a seed derived from an// existing seed and a salt with NewSaltedSeed.func ( *PRNGSeed, string) (*prng, error) { , := newSaltedPRNGSeed(, )if != nil {returnnil, }returnnewPRNGWithSeed()}// Read reads random bytes from the PRNG stream into b. Read conforms to// io.Reader and always returns len(p), nil.func ( *prng) ( []byte) (int, error) { .randomStreamMutex.Lock()defer .randomStreamMutex.Unlock()// ShakeHash.Read never returns an error: // https://godoc.org/golang.org/x/crypto/sha3#ShakeHash _, _ = io.ReadFull(.randomStream, )returnlen(), nil}// Int63 is equivalent to math/read.Int63.func ( *prng) () int64 { := .Uint64()returnint64( & (1<<63 - 1))}// Int63 is equivalent to math/read.Uint64.func ( *prng) () uint64 {var [8]byte .Read([:])returnbinary.BigEndian.Uint64([:])}// Seed must exist in order to use a PRNG as a math/rand.Source. This call is// not supported and ignored.func ( *prng) ( int64) {}// FlipWeightedCoin returns the result of a weighted// random coin flip. If the weight is 0.5, the outcome// is equally likely to be true or false. If the weight// is 1.0, the outcome is always true, and if the// weight is 0.0, the outcome is always false.//// Input weights > 1.0 are treated as 1.0.func ( *prng) ( float64) bool {if > 1.0 { = 1.0 } := float64(.Int63()) / float64(math.MaxInt64)return > 1.0-}// Intn is equivalent to math/read.Intn, except it returns 0 if n <= 0// instead of panicking.func ( *prng) ( int) int {if <= 0 {return0 }return .rand.Intn()}// Int63n is equivalent to math/read.Int63n, except it returns 0 if n <= 0// instead of panicking.func ( *prng) ( int64) int64 {if <= 0 {return0 }return .rand.Int63n()}// Intn is equivalent to math/read.Perm.func ( *prng) ( int) []int {return .rand.Perm()}// Range selects a random integer in [min, max].// If min < 0, min is set to 0. If max < min, min is returned.func ( *prng) (, int) int {if < 0 { = 0 }if < {return } := .Intn( - + 1) += return}
The pages are generated with Goldsv0.8.4. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds.