fix(nix): update vendorHash and vendor dir for new deps
This commit is contained in:
+188
@@ -0,0 +1,188 @@
|
||||
/*
|
||||
* 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.go
|
||||
|
||||
package tls
|
||||
|
||||
import (
|
||||
crypto_rand "crypto/rand"
|
||||
"encoding/binary"
|
||||
"io"
|
||||
"math"
|
||||
"math/rand"
|
||||
"sync"
|
||||
|
||||
"golang.org/x/crypto/hkdf"
|
||||
"golang.org/x/crypto/sha3"
|
||||
)
|
||||
|
||||
const (
|
||||
PRNGSeedLength = 32
|
||||
)
|
||||
|
||||
// PRNGSeed is a PRNG seed.
|
||||
type PRNGSeed [PRNGSeedLength]byte
|
||||
|
||||
// NewPRNGSeed creates a new PRNG seed using crypto/rand.Read.
|
||||
func NewPRNGSeed() (*PRNGSeed, error) {
|
||||
seed := new(PRNGSeed)
|
||||
_, err := crypto_rand.Read(seed[:])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return seed, 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 newSaltedPRNGSeed(seed *PRNGSeed, salt string) (*PRNGSeed, error) {
|
||||
saltedSeed := new(PRNGSeed)
|
||||
_, err := io.ReadFull(
|
||||
hkdf.New(sha3.New256, seed[:], []byte(salt), nil), saltedSeed[:])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return saltedSeed, 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.
|
||||
type prng struct {
|
||||
rand *rand.Rand
|
||||
randomStreamMutex sync.Mutex
|
||||
randomStream sha3.ShakeHash
|
||||
}
|
||||
|
||||
// newPRNG generates a seed and creates a PRNG with that seed.
|
||||
func newPRNG() (*prng, error) {
|
||||
seed, err := NewPRNGSeed()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return newPRNGWithSeed(seed)
|
||||
}
|
||||
|
||||
// newPRNGWithSeed initializes a new PRNG using an existing seed.
|
||||
func newPRNGWithSeed(seed *PRNGSeed) (*prng, error) {
|
||||
shake := sha3.NewShake256()
|
||||
_, err := shake.Write(seed[:])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p := &prng{
|
||||
randomStream: shake,
|
||||
}
|
||||
p.rand = rand.New(p)
|
||||
return p, nil
|
||||
}
|
||||
|
||||
// newPRNGWithSaltedSeed initializes a new PRNG using a seed derived from an
|
||||
// existing seed and a salt with NewSaltedSeed.
|
||||
func newPRNGWithSaltedSeed(seed *PRNGSeed, salt string) (*prng, error) {
|
||||
saltedSeed, err := newSaltedPRNGSeed(seed, salt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return newPRNGWithSeed(saltedSeed)
|
||||
}
|
||||
|
||||
// Read reads random bytes from the PRNG stream into b. Read conforms to
|
||||
// io.Reader and always returns len(p), nil.
|
||||
func (p *prng) Read(b []byte) (int, error) {
|
||||
p.randomStreamMutex.Lock()
|
||||
defer p.randomStreamMutex.Unlock()
|
||||
|
||||
// ShakeHash.Read never returns an error:
|
||||
// https://godoc.org/golang.org/x/crypto/sha3#ShakeHash
|
||||
_, _ = io.ReadFull(p.randomStream, b)
|
||||
|
||||
return len(b), nil
|
||||
}
|
||||
|
||||
// Int63 is equivalent to math/read.Int63.
|
||||
func (p *prng) Int63() int64 {
|
||||
i := p.Uint64()
|
||||
return int64(i & (1<<63 - 1))
|
||||
}
|
||||
|
||||
// Int63 is equivalent to math/read.Uint64.
|
||||
func (p *prng) Uint64() uint64 {
|
||||
var b [8]byte
|
||||
p.Read(b[:])
|
||||
return binary.BigEndian.Uint64(b[:])
|
||||
}
|
||||
|
||||
// Seed must exist in order to use a PRNG as a math/rand.Source. This call is
|
||||
// not supported and ignored.
|
||||
func (p *prng) Seed(_ 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 (p *prng) FlipWeightedCoin(weight float64) bool {
|
||||
if weight > 1.0 {
|
||||
weight = 1.0
|
||||
}
|
||||
f := float64(p.Int63()) / float64(math.MaxInt64)
|
||||
return f > 1.0-weight
|
||||
}
|
||||
|
||||
// Intn is equivalent to math/read.Intn, except it returns 0 if n <= 0
|
||||
// instead of panicking.
|
||||
func (p *prng) Intn(n int) int {
|
||||
if n <= 0 {
|
||||
return 0
|
||||
}
|
||||
return p.rand.Intn(n)
|
||||
}
|
||||
|
||||
// Int63n is equivalent to math/read.Int63n, except it returns 0 if n <= 0
|
||||
// instead of panicking.
|
||||
func (p *prng) Int63n(n int64) int64 {
|
||||
if n <= 0 {
|
||||
return 0
|
||||
}
|
||||
return p.rand.Int63n(n)
|
||||
}
|
||||
|
||||
// Intn is equivalent to math/read.Perm.
|
||||
func (p *prng) Perm(n int) []int {
|
||||
return p.rand.Perm(n)
|
||||
}
|
||||
|
||||
// Range selects a random integer in [min, max].
|
||||
// If min < 0, min is set to 0. If max < min, min is returned.
|
||||
func (p *prng) Range(min, max int) int {
|
||||
if min < 0 {
|
||||
min = 0
|
||||
}
|
||||
if max < min {
|
||||
return min
|
||||
}
|
||||
n := p.Intn(max - min + 1)
|
||||
n += min
|
||||
return n
|
||||
}
|
||||
Reference in New Issue
Block a user