// 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 }
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) }
// 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") }
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)) }