Exemple #1
0
func setupUPnP(r rand.Source) int {
	var externalPort = 0
	if len(cfg.Options.ListenAddress) == 1 {
		_, portStr, err := net.SplitHostPort(cfg.Options.ListenAddress[0])
		if err != nil {
			l.Warnln(err)
		} else {
			// Set up incoming port forwarding, if necessary and possible
			port, _ := strconv.Atoi(portStr)
			igd, err := upnp.Discover()
			if err == nil {
				for i := 0; i < 10; i++ {
					r := 1024 + int(r.Int63()%(65535-1024))
					err := igd.AddPortMapping(upnp.TCP, r, port, "syncthing", 0)
					if err == nil {
						externalPort = r
						l.Infoln("Created UPnP port mapping - external port", externalPort)
						break
					}
				}
				if externalPort == 0 {
					l.Warnln("Failed to create UPnP port mapping")
				}
			} else {
				l.Infof("No UPnP gateway detected")
				if debugNet {
					l.Debugf("UPnP: %v", err)
				}
			}
		}
	} else {
		l.Warnln("Multiple listening addresses; not attempting UPnP port mapping")
	}
	return externalPort
}
Exemple #2
0
// The Hamming distances between the nth values of one RNG seeded with two
// values with Hamming distance 1 should be binomially distributed. This test
// derives its name from the bit avalanche effect.
//
// NOTE: ReaderSource RNGs (e.g. crypto-reader) will be incorrect.
func Avalanche(r rand.Source) float64 {
	// hax teh copypasta from popcount
	counts := [64]int64{}
	v := r.Int63()
	var a, b int64
	for i := 0; i < avalancheN; i++ {
		for j := uint(0); j < 63; j++ {
			r.Seed(v)
			for k := 0; k < avalancheFuse; k++ {
				r.Int63()
			}
			a = r.Int63()
			r.Seed(v ^ (1 << j))
			for k := 0; k < avalancheFuse; k++ {
				r.Int63()
			}
			b = r.Int63()
			// Hamming distance from a to b is equal to popcount(a^b)
			x := a ^ b
			// popcount_3() from http://en.wikipedia.org/wiki/Hamming_weight
			x -= x >> 1 & 0x5555555555555555
			x = x&0x3333333333333333 + x>>2&0x3333333333333333
			x = (x + x>>4) & 0x0f0f0f0f0f0f0f0f
			x = x * 0x0101010101010101 >> 56 // popcount
			counts[x]++
		}
		v = b // silly to use a^b because that depends upon what we're testing
	}
	var chi2 float64
	for i, v := range counts {
		d := float64(v)*binomialBitScale - binomialBitPMF[i]
		chi2 += d * d / binomialBitPMF[i]
	}
	return 1 - LowerGamma(30, chi2/2)*1.13099628864477e-31
}
Exemple #3
0
// randHash generates a "random" hash using a deterministic source.
func randHash(r rand.Source) *chainhash.Hash {
	hash := new(chainhash.Hash)
	for i := 0; i < chainhash.HashSize/2; i++ {
		random := uint64(r.Int63())
		randByte1 := random % 255
		randByte2 := (random >> 8) % 255
		hash[i] = uint8(randByte1)
		hash[i+1] = uint8(randByte2)
	}

	return hash
}
Exemple #4
0
// pickRandWinners picks tickets per block many random "winners" and returns
// their indexes.
func pickRandWinners(sz int, r rand.Source) []int {
	if sz == 0 {
		panic("bad sz!")
	}

	perBlock := int(chaincfg.MainNetParams.TicketsPerBlock)
	winners := make([]int, perBlock)
	for i := 0; i < perBlock; i++ {
		winners[i] = int(r.Int63() % int64(sz))
	}

	return winners
}
Exemple #5
0
func newNodeWithSource(b *tierBase, others []*node, idSource rand.Source) *node {
	// The ids should be unique, non-zero, and random so others don't base
	// their node references on indexes.
	var id uint64
	for id == 0 {
		id = (uint64(idSource.Int63()) << 63) | uint64(idSource.Int63())
		for _, n := range others {
			if n.id == id {
				id = 0
				break
			}
		}
	}
	return &node{tierBase: b, id: id}
}
func randString(n int, src rand.Source) string {
	b := make([]byte, n)
	// A rand.Int63() generates 63 random bits, enough for letterIdxMax letters!
	for i, cache, remain := n-1, src.Int63(), letterIdxMax; i >= 0; {
		if remain == 0 {
			cache, remain = src.Int63(), letterIdxMax
		}
		if idx := int(cache & letterIdxMask); idx < len(letterBytes) {
			b[i] = letterBytes[idx]
			i--
		}
		cache >>= letterIdxBits
		remain--
	}
	return string(b[0:30])
}
Exemple #7
0
// RandStringBytesMaskImprSrc source: http://stackoverflow.com/a/31832326
func randStringBytesMaskImprSrc(n int, src rand.Source) string {
	b := make([]byte, n)
	for i, cache, remain := n-1, src.Int63(), letterIdxMax; i >= 0; {
		if remain == 0 {
			cache, remain = src.Int63(), letterIdxMax
		}
		if idx := int(cache & letterIdxMask); idx < len(letterBytes) {
			b[i] = letterBytes[idx]
			i--
		}
		cache >>= letterIdxBits
		remain--
	}

	return string(b)
}
Exemple #8
0
// The probability that k out of n random integers have popcount x follows a
// binomial distribution.
func Popcount(r rand.Source) float64 {
	counts := [64]int64{}
	for i := 0; i < popcountN; i++ {
		x := r.Int63()
		// popcount_3() from http://en.wikipedia.org/wiki/Hamming_weight
		x -= x >> 1 & 0x5555555555555555
		x = x&0x3333333333333333 + x>>2&0x3333333333333333
		x = (x + x>>4) & 0x0f0f0f0f0f0f0f0f
		x = x * 0x0101010101010101 >> 56 // popcount
		counts[x]++
	}
	var chi2 float64
	for i, v := range counts {
		d := float64(v)*binomialBitScale - binomialBitPMF[i]
		chi2 += d * d / binomialBitPMF[i]
	}
	println(chi2)
	return 1 - LowerGamma(30, chi2/2)*1.13099628864477e-31
}
// The lagged survival test applies the survival test to an RNG, skipping N
// iterates between each sample.
func LaggedSurvival(r rand.Source, N int) float64 {
	// hax teh copypasta
	//TODO: prevent first iteration from matching
	consec := [63]int{}
	bits := [63]bool{}
	counts := make(map[int]int)
	for i := 0; i < laggedSurvN; i++ {
		x := r.Int63()
		for b := 0; b < 63; b++ {
			if ((x & (1 << uint(b))) != 0) == bits[b] { // bit survived
				consec[b]++
			} else { // bit changed
				bits[b] = !bits[b]
				counts[consec[b]] = counts[consec[b]] + 1
				consec[b] = 0
			}
		}
		for n := 0; n < N; n++ {
			r.Int63()
		}
	}
	maximum := len(counts)
	for i := range counts {
		if i > maximum {
			maximum = i
		}
	}
	// If the source is truly random, then there should be half as many hits
	// for counts[n] as there were for counts[n-1], with counts[0] being the
	// maximum.
	//TODO: E should be calculated from the median
	E := float64(counts[0])
	var chi2 float64
	for i := 1; i < maximum; i++ {
		E /= 2
		d := float64(counts[i]) - E
		chi2 += d * d / E
	}
	k_2 := float64(maximum-2) / 2
	return 1 - LowerGamma(k_2, chi2/2)/math.Gamma(k_2)
}
Exemple #10
0
// Survival Parity applies Survival to the parity of the random values.
func SurvivalParity(r rand.Source) float64 {
	consec := 0
	var parity int64 = -1 // prevent the first iteration from matching
	counts := map[int]int{0: -1}
	for i := 0; i < survivalParityN; i++ {
		// software parity because I do not enjoy setting up asm to be used
		// http://www-graphics.stanford.edu/~seander/bithacks.html#ParityMultiply
		x := r.Int63()
		x ^= x >> 1
		x ^= x >> 2
		x = (x & 0x1111111111111111) * 0x1111111111111111
		x = x >> 60 & 1 // parity complete
		if x == parity {
			consec++
		} else {
			parity = x
			counts[consec] = counts[consec] + 1
			consec = 0
		}
	}
	// copypasta
	var maximum int
	for i := range counts {
		if i > maximum {
			maximum = i
		}
	}
	// If the source is truly random, then there should be half as many hits
	// for counts[n] as there were for counts[n-1], with counts[0] being the
	// maximum.
	//TODO: E should be calculated from the median. This is causing crc64-ecma to NaN.
	E := float64(counts[0])
	var chi2 float64
	for i := 1; i < maximum; i++ {
		E /= 2
		d := float64(counts[i]) - E
		chi2 += d * d / E
	}
	k_2 := float64(maximum-2) / 2
	return 1 - LowerGamma(k_2, chi2/2)/math.Gamma(k_2)
}
Exemple #11
0
// Generates a random string given the random source and the fixed length
func NextString(src rand.Source, length int) string {
	const alphabet = "azertyuiopqsdfghjklmwxcvbn"

	result := make([]byte, length)
	offset := 0

	for {
		val := src.Int63()
		for i := 0; i < 8; i++ {
			result[offset] = alphabet[val%int64(len(alphabet))]
			length--
			if length == 0 {
				return string(result)
			}
			offset++
			val >>= 8
		}
	}

	panic("unreachable")
}
Exemple #12
0
func newNodeWithSource(b *Builder, tb *tierBase, others []*node, idSource rand.Source) (*node, error) {
	mask := uint64(math.MaxUint64)
	if b != nil {
		mask = (uint64(1) << uint64(b.idBits)) - 1
		if uint64(len(others)) >= mask {
			return nil, fmt.Errorf("no more ID space; bits %d, nodes %d", b.idBits, len(others))
		}
	}
	// The ids should be unique, non-zero, and random so others don't base
	// their node references on indexes.
	var id uint64
	if mask == math.MaxUint64 {
		id = (uint64(idSource.Int63()) << 63) | uint64(idSource.Int63())
	} else {
		id = uint64(idSource.Int63()) & mask
	}
	if id == 0 {
		id = 1
	}
	sid := id
L:
	for _, n := range others {
		if n.id == id {
			id++
			if id == sid {
				// This shouldn't happen because the top of the func should've
				// caught that the ID space was used up; but, just in case.
				return nil, fmt.Errorf("no more ID space; bits %d, nodes %d, wrapped scan", b.idBits, len(others))
			}
			if id > mask {
				id = 1
			}
			goto L
		}
	}
	return &node{builder: b, tierBase: tb, id: id}, nil
}