You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: good_key.go
    path of file: ./repos/podman/vendor/github.com/letsencrypt/boulder/goodkey
    
    the code of the file until where you have to start completion: package goodkey

import (
	"context"
	"crypto"
	"crypto/ecdsa"
	"crypto/elliptic"
	"crypto/rsa"
	"errors"
	"fmt"
	"math/big"
	"sync"

	"github.com/letsencrypt/boulder/core"

	"github.com/titanous/rocacheck"
)

// To generate, run: primes 2 752 | tr '\n' ,
var smallPrimeInts = []int64{
	2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47,
	53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107,
	109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167,
	173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229,
	233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283,
	293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359,
	367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431,
	433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491,
	499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571,
	577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641,
	643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709,
	719, 727, 733, 739, 743, 751,
}

// singleton defines the object of a Singleton pattern
var (
	smallPrimesSingleton sync.Once
	smallPrimesProduct   *big.Int
)

type Config struct {
	// WeakKeyFile is the path to a JSON file containing truncated modulus hashes
	// of known weak RSA keys. If this config value is empty, then RSA modulus
	// hash checking will be disabled.
	WeakKeyFile string
	// BlockedKeyFile is the path to a YAML file containing base64-encoded SHA256
	// hashes of PKIX Subject Public Keys that should be blocked. If this config
	// value is e
    
func checkPrimeFactorsTooClose(n *big.Int, rounds int) error {
	// Pre-allocate some big numbers that we'll use a lot down below.
	one := big.NewInt(1)
	bb := new(big.Int)

	// Any odd integer is equal to a difference of squares of integers:
	//   n = a^2 - b^2 = (a + b)(a - b)
	// Any RSA public key modulus is equal to a product of two primes:
	//   n = pq
	// Here we try to find values for a and b, since doing so also gives us the
	// prime factors p = (a + b) and q = (a - b).

	// We start with a close to the square root of the modulus n, to start with
	// two candidate prime factors that are as close together as possible and
	// work our way out from there. Specifically, we set a = ceil(sqrt(n)), the
	// first integer greater than the square root of n. Unfortunately, big.Int's
	// built-in square root function takes the floor, so we have to add one to get
	// the ceil.
	a := new(big.Int)
	a.Sqrt(n).Add(a, one)

	// We calculate b2 to see if it is a perfect square (i.e. b^2), and therefore
	// b is an integer. Specifically, b2 = a^2 - n.
	b2 := new(big.Int)
	b2.Mul(a, a).Sub(b2, n)

	for i := 0; i < rounds; i++ {
		// To see if b2 is a perfect square, we take its square root, square that,
		// and check to see if we got the same result back.
		bb.Sqrt(b2).Mul(bb, bb)
		if b2.Cmp(bb) == 0 {
			// b2 is a perfect square, so we've found integer values of a and b,
			// and can easily compute p and q as their sum and difference.
			bb.Sqrt(bb)
			p := new(big.Int).Add(a, bb)
			q := new(big.Int).Sub(a, bb)
			return fmt.Errorf("public modulus n = pq factored into p: %s; q: %s", p, q)
		}

		// Set up the next iteration by incrementing a by one and recalculating b2.
		a.Add(a, one)
		b2.Mul(a, a).Sub(b2, n)
	}
	return nil
}