Beispiel #1
0
// Validate performs basic sanity checks on the key.
// It returns nil if the key is valid, or else an error describing a problem.
func (priv *PrivateKey) Validate() error {
	// Check that the prime factors are actually prime. Note that this is
	// just a sanity check. Since the random witnesses chosen by
	// ProbablyPrime are deterministic, given the candidate number, it's
	// easy for an attack to generate composites that pass this test.
	for _, prime := range priv.Primes {
		if !big.ProbablyPrime(prime, 20) {
			return errors.New("prime factor is composite")
		}
	}

	// Check that Πprimes == n.
	modulus := new(big.Int).Set(bigOne)
	for _, prime := range priv.Primes {
		modulus.Mul(modulus, prime)
	}
	if modulus.Cmp(priv.N) != 0 {
		return errors.New("invalid modulus")
	}
	// Check that e and totient(Πprimes) are coprime.
	totient := new(big.Int).Set(bigOne)
	for _, prime := range priv.Primes {
		pminus1 := new(big.Int).Sub(prime, bigOne)
		totient.Mul(totient, pminus1)
	}
	e := big.NewInt(int64(priv.E))
	gcd := new(big.Int)
	x := new(big.Int)
	y := new(big.Int)
	big.GcdInt(gcd, x, y, totient, e)
	if gcd.Cmp(bigOne) != 0 {
		return errors.New("invalid public exponent E")
	}
	// Check that de ≡ 1 (mod totient(Πprimes))
	de := new(big.Int).Mul(priv.D, e)
	de.Mod(de, totient)
	if de.Cmp(bigOne) != 0 {
		return errors.New("invalid private exponent D")
	}
	return nil
}
Beispiel #2
0
func main() {
	var (
		ntotal = new(big.Int)
		x      = new(big.Int)
	)
	var misses = []int{}

	fmt.Printf("Working for %d digit primes\n", primesize)
	fmt.Println("dig\tn\tpsum")

	//all these padding digits have soluitons with 9
	for digit := 0; digit < 10; digit++ {
		var (
			psum = new(big.Int)
			n    int
		)
		for j := 0; j < 10; j++ {
			for pos := 0; pos < primesize; pos++ {
				x.SetString(build9(digit, j, pos), 0)
				if len(x.String()) != primesize {
					continue
				}

				if big.ProbablyPrime(x, rabinwork) { //we have a probable prime
					ntotal.Add(x, ntotal)
					psum.Add(x, psum)
					n++
				}
			}
		}
		fmt.Printf("%d\t%d\t%d\n", digit, n, psum)
		if n == 0 {
			misses = append(misses, digit)
		}
	}

	fmt.Println("(n-1)s done...")
	fmt.Println("dig\tn\tpsum")

	//now the misses
	for _, digit := range misses {
		var (
			psum = new(big.Int)
			n    int
		)

		for j1 := 0; j1 < 10; j1++ {
			for pos1 := 0; pos1 < primesize; pos1++ {
				for j2 := 0; j2 < 10; j2++ {
					for pos2 := pos1 + 1; pos2 < primesize; pos2++ {
						x.SetString(build8(digit, j1, pos1, j2, pos2), 0)
						if len(x.String()) != primesize {
							continue
						}

						if big.ProbablyPrime(x, rabinwork) { //we have a probable prime
							ntotal.Add(x, ntotal)
							psum.Add(x, psum)
							n++
						}
					}
				}
			}
		}
		fmt.Printf("%d\t%d\t%d\n", digit, n, psum)
		if n == 0 {
			panic("Won't get the correct result.")
		}
	}

	fmt.Println("(n-2)s done...")
	fmt.Println(ntotal)
}
Beispiel #3
0
// GenerateParameters puts a random, valid set of DSA parameters into params.
// This function takes many seconds, even on fast machines.
func GenerateParameters(params *Parameters, rand io.Reader, sizes ParameterSizes) (err error) {
	// This function doesn't follow FIPS 186-3 exactly in that it doesn't
	// use a verification seed to generate the primes. The verification
	// seed doesn't appear to be exported or used by other code and
	// omitting it makes the code cleaner.

	var L, N int
	switch sizes {
	case L1024N160:
		L = 1024
		N = 160
	case L2048N224:
		L = 2048
		N = 224
	case L2048N256:
		L = 2048
		N = 256
	case L3072N256:
		L = 3072
		N = 256
	default:
		return errors.New("crypto/dsa: invalid ParameterSizes")
	}

	qBytes := make([]byte, N/8)
	pBytes := make([]byte, L/8)

	q := new(big.Int)
	p := new(big.Int)
	rem := new(big.Int)
	one := new(big.Int)
	one.SetInt64(1)

GeneratePrimes:
	for {
		_, err = io.ReadFull(rand, qBytes)
		if err != nil {
			return
		}

		qBytes[len(qBytes)-1] |= 1
		qBytes[0] |= 0x80
		q.SetBytes(qBytes)

		if !big.ProbablyPrime(q, numMRTests) {
			continue
		}

		for i := 0; i < 4*L; i++ {
			_, err = io.ReadFull(rand, pBytes)
			if err != nil {
				return
			}

			pBytes[len(pBytes)-1] |= 1
			pBytes[0] |= 0x80

			p.SetBytes(pBytes)
			rem.Mod(p, q)
			rem.Sub(rem, one)
			p.Sub(p, rem)
			if p.BitLen() < L {
				continue
			}

			if !big.ProbablyPrime(p, numMRTests) {
				continue
			}

			params.P = p
			params.Q = q
			break GeneratePrimes
		}
	}

	h := new(big.Int)
	h.SetInt64(2)
	g := new(big.Int)

	pm1 := new(big.Int).Sub(p, one)
	e := new(big.Int).Div(pm1, q)

	for {
		g.Exp(h, e, p)
		if g.Cmp(one) == 0 {
			h.Add(h, one)
			continue
		}

		params.G = g
		return
	}

	panic("unreachable")
}
Beispiel #4
0
func main() {
	primes := make(map[int][]string)
	x := new(big.Int)

	var y SubSet
	//ignore empty subset
	y.Next()

	data := []byte("123456789")
	for i := 0; i < 1<<9-1; i++ {
		subset := y.On(data)
		pool := make(Pool, len(subset))
		pool.Reset()

		//loop over every permutation
		for j := 0; j < pool.NumCycles(); j++ {
			x.SetString(pool.On(subset), 10)

			//2 throws out the same amount as 100.
			if big.ProbablyPrime(x, 2) {
				primes[len(subset)] = append(primes[len(subset)], x.String())
			}
		}
	}

	fmt.Println("Primes generated.")

	//30 partitions of 9 so just list them!
	partitions := [][]int{
		{9}, {8, 1}, {7, 2}, {7, 1, 1}, {6, 3}, {6, 2, 1}, {6, 1, 1, 1}, {5, 4},
		{5, 3, 1}, {5, 2, 2}, {5, 2, 1, 1}, {5, 1, 1, 1, 1}, {4, 4, 1}, {4, 3, 2},
		{4, 3, 1, 1}, {4, 2, 2, 1}, {4, 2, 1, 1, 1}, {4, 1, 1, 1, 1, 1}, {3, 3, 3},
		{3, 3, 2, 1}, {3, 3, 1, 1, 1}, {3, 2, 2, 2}, {3, 2, 2, 1, 1},
		{3, 2, 1, 1, 1, 1}, {3, 1, 1, 1, 1, 1, 1}, {2, 2, 2, 2, 1},
		{2, 2, 2, 1, 1, 1}, {2, 2, 1, 1, 1, 1, 1}, {2, 1, 1, 1, 1, 1, 1, 1},
		{1, 1, 1, 1, 1, 1, 1, 1, 1},
	}

	//check for typos
	if len(partitions) != 30 {
		panic("Too many/few")
	}

	for _, p := range partitions {
		var acc int
		for _, v := range p {
			acc += v
		}
		if acc != 9 {
			panic("One doesn't sum to 30")
		}
	}

	fmt.Println("Partitions generated.")

	group := new(sync.WaitGroup)
	group.Add(len(partitions))

	//for each partition, we have to find all the sets of primes that satisfy
	for _, p := range partitions {
		//now we have a partition! lets get the number of sets
		go numSets(primes, p, "", nil, group)
	}
	sy := make(chan bool)

	//send a message when the group is finished
	go func() {
		group.Wait()
		sy <- true
	}()

	items := make(map[string]struct{})

collecting:
	for {
		select {
		case set := <-sets:
			//turn the sets into a key and put it into our map
			sort.Strings(set)
			items[strings.Join(set, ",")] = struct{}{}
		case <-sy:
			break collecting
		}
	}

	fmt.Println(len(items))
}