// Generate a new cyclic group and generator of given bits size. func New(random io.Reader, bits int) (*Group, error) { for { // Generate a large prime of size 'bits'-1 q, err := rand.Prime(random, bits-1) if err != nil { return nil, err } // Calculate the safe prime p=2q+1 of order 'bits' p := new(big.Int).Mul(q, big.NewInt(2)) p = new(big.Int).Add(p, big.NewInt(1)) // Probability of p being non-prime is negligible if p.ProbablyPrime(negligibleExp / 2) { for { // Generate a generator of p a, err := rand.Int(random, p) if err != nil { return nil, err } // Ensure generator order is not 2 (efficiency) if b := new(big.Int).Exp(a, big.NewInt(2), p); b.Cmp(big.NewInt(1)) == 0 { continue } // Return if generator order is q if b := new(big.Int).Exp(a, q, p); b.Cmp(big.NewInt(1)) == 0 { return &Group{p, a}, nil } } } } }
func TestSts(t *testing.T) { // Ensure cyclic group is safe-prime and a valid (big) generator negligibleExp := 82 if !StsGroup.ProbablyPrime(negligibleExp / 2) { t.Errorf("config (sts): non-prime cyclic group: %v.", StsGroup) } q := new(big.Int).Sub(StsGroup, big.NewInt(1)) q = new(big.Int).Div(q, big.NewInt(2)) if !q.ProbablyPrime(negligibleExp / 2) { t.Errorf("config (sts): non-safe-prime base: %v = 2*%v + 1.", StsGroup, q) } if new(big.Int).Exp(StsGenerator, q, StsGroup).Cmp(big.NewInt(1)) != 0 { t.Errorf("config (sts): invalid generator: %v.", StsGenerator) } // Ensure the cipher and key size combination is valid key := make([]byte, StsCipherBits/8) if n, err := io.ReadFull(rand.Reader, key); n != len(key) || err != nil { t.Errorf("config (sts): failed to generate random key: %v.", err) } if _, err := StsCipher(key); err != nil { t.Errorf("config (sts): failed to create requested cipher: %v.", err) } // Ensure the hash is linked to the binary if !StsSigHash.Available() { t.Errorf("config (sts): requested hash not linked into binary.") } }
// Returns an Optimus struct which can be used to encode and decode // integers. Usually used for obfuscating internal ids such as database // table rows. Panics if prime is not valid. func New(prime *big.Int, modInverse *big.Int, random *big.Int, bits int) (*Optimus, error) { if prime.ProbablyPrime(MILLER_RABIN) { return &Optimus{prime, modInverse, random, bits, BitsToBig(bits)}, nil } else { accuracy := 1.0 - 1.0/math.Pow(float64(4), float64(MILLER_RABIN)) return nil, errors.New(fmt.Sprintf("Number is not prime %d Miller-Rabin tests done. Accuracy: %f", MILLER_RABIN, accuracy)) } }
//primize makes x a prime number. //Result will be bigger than x. func primize(x *big.Int) *big.Int { var tmp big.Int if x.Bit(0) == 0 { x.Add(x, tmp.SetInt64(1)) } for { if x.ProbablyPrime(sprpTestCount) { return x } x.Add(x, tmp.SetInt64(2)) } }
func nextPrime(p *big.Int) *big.Int { // make sure p is odd if p.Bit(0) == 0 { p = new(big.Int).Add(p, big.NewInt(1)) } step := big.NewInt(2) for { p = new(big.Int).Add(p, step) if p.ProbablyPrime(128) { break } } return p }
func moTest(a, n *big.Int) { if a.BitLen() < 100 { fmt.Printf("ord(%v)", a) } else { fmt.Print("ord([big])") } if n.BitLen() < 100 { fmt.Printf(" mod %v ", n) } else { fmt.Print(" mod [big] ") } if !n.ProbablyPrime(20) { fmt.Println("not computed. modulus must be prime for this algorithm.") return } fmt.Println("=", moBachShallit58(a, n, factor(new(big.Int).Sub(n, one)))) }
func isPrime(p, i *big.Int, tf chan bool) { temp := new(big.Int) zero := new(big.Int) zero.SetInt64(0) if i.ProbablyPrime(10) { if temp.Mod(p, i).Cmp(zero) == 0 { tf <- false } else { tf <- true } } else { tf <- true } runtime.Goexit() }
func main() { flag.Parse() var p = int64(0) var n = 1 if _, err := os.Stat(statePath); err == nil { state, err := os.Open(statePath) check(err) scanner := bufio.NewScanner(state) scanner.Scan() check(scanner.Err()) x := strings.Split(scanner.Text(), ":") p, err = strconv.ParseInt(x[0], 10, 64) check(err) n, err = strconv.Atoi(x[1]) check(err) check(state.Close()) } fmt.Println("starting at", p, "with", n, "tests") sigs := make(chan os.Signal, 1) signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) go func() { sig := <-sigs fmt.Fprintf(os.Stderr, "received %v, saving state and exiting...\n", sig) updateState(p, n) os.Exit(1) }() thresh, err := os.OpenFile(threshPath, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0666) bigInt := new(big.Int) for { if bigInt.SetInt64(p).ProbablyPrime(n) && !primes.IsPrime(p) { fmt.Printf("non-prime %d is ProbablyPrime(%d)\n", p, n) _, err = fmt.Fprintf(thresh, "%d:%d\n", p, n) check(err) n++ // Sanity check: I haven't proven that incrementing tests by one always fixes the guess if bigInt.ProbablyPrime(n) { panic(fmt.Sprintf("%d is ProbablyPrime(%d) and ProbablyPrime(%d)", p, n-1, n)) } } p++ } }
func PMinus1(n *big.Int) (primes, composites []*big.Int) { if n.ProbablyPrime(10) { return []*big.Int{n}, nil } a := big.NewInt(2 * 3 * 5 * 7 * 11) var one big.Int one.SetInt64(1) var bigp big.Int var m big.Int for i, p := range smallPrimes { bigp.SetInt64(p) m.SetInt64(1) for n.Cmp(&m) == 1 { m.Mul(&m, &bigp) } // went one too far m.Div(&m, &bigp) a.Exp(a, &m, n) if i > 0 && i%16 == 0 { var aMinus1 big.Int aMinus1.Sub(a, &one) if newN, newG, ok := checkGCD(n, &aMinus1); ok { pr, co := PMinus1(newN) primes, composites = append(primes, pr...), append(composites, co...) pr, co = PMinus1(newG) primes, composites = append(primes, pr...), append(composites, co...) return primes, composites } } } return nil, []*big.Int{n} }
func choosePrime(bits int, m, s *big.Int, avoidFactors map[int64]bool) (*big.Int, map[int64]bool) { p := new(big.Int) var pFactors map[int64]bool for { p.SetInt64(2) pFactors = make(map[int64]bool) pFactors[2] = true for i := 0; i < bits/14; i++ { f := int64(2) for { f = rnd.Int63n(1 << 16) if ok := avoidFactors[f]; ok { continue } ok := pFactors[f] if !ok && big.NewInt(f).ProbablyPrime(32) { break } } pFactors[f] = true p.Mul(p, big.NewInt(f)) } p.Add(p, big.NewInt(1)) if p.ProbablyPrime(32) { pMinus1 := new(big.Int).Sub(p, big.NewInt(1)) primRoot := true for f, _ := range pFactors { pow := new(big.Int).Div(pMinus1, big.NewInt(f)) check1 := new(big.Int).Exp(m, pow, p) check2 := new(big.Int).Exp(s, pow, p) if check1.Cmp(big.NewInt(1)) == 0 || check2.Cmp(big.NewInt(1)) == 0 { primRoot = false } } if primRoot { return p, pFactors } } } }
func TestCyclic(t *testing.T) { for i, tt := range cyclicTests { group, err := New(rand.Reader, tt) if err != nil { t.Errorf("test %d: error returned: %v.", i, err) } if group.Base.BitLen() < tt { t.Errorf("test %d: insecure base order: have %v, want %v.", i, group.Base.BitLen(), tt) } if !group.Base.ProbablyPrime(negligibleExp / 2) { t.Errorf("test %d: non-prime base: %v.", i, group.Base) } q := new(big.Int).Sub(group.Base, big.NewInt(1)) q = new(big.Int).Div(q, big.NewInt(2)) if !q.ProbablyPrime(negligibleExp / 2) { t.Errorf("test %d: non-safe-prime base: %v = 2*%v + 1.", i, group.Base, q) } if new(big.Int).Exp(group.Generator, q, group.Base).Cmp(big.NewInt(1)) != 0 { t.Errorf("test %d: invalid generator: %v.", i, group.Generator) } } }
// GenRandomShares generates a polynomial and n points // The polynomial can be solved with k points func GenRandomShares(n, k int, q *big.Int) (ps Points, p Poly) { if q.ProbablyPrime(100) == false { ps = nil p = nil return } size := q.BitLen()/8 + 1 p = make([]*big.Int, k) for i := 0; i < k; i++ { coeff := RandomBigInt(size) coeff.Mod(coeff, q) p[i] = coeff } ps = make([]Point, n) for i := 0; i < n; i++ { r := RandomBigInt(size) r.Mod(r, q) var t Point t.x = r t.y = p.Eval(r, q) ps[i] = t } return }
func Trial(n *big.Int) (primes []*big.Int, composites []*big.Int) { var z big.Int var m big.Int bigp := big.NewInt(0) for _, p := range smallPrimes { for { // reuse the existing bigint bigp.SetInt64(p) z.DivMod(n, bigp, &m) if m.Sign() != 0 { break } n.Set(&z) primes = append(primes, bigp) // create a new bigint, since we just stored the one we were using bigp = big.NewInt(0) } if n.Cmp(one) == 0 { break } } if n.Cmp(one) > 0 { if n.ProbablyPrime(10) { primes = append(primes, n) } else { composites = append(composites, n) } } return primes, composites }
func _pollardFactoring(task *Task, toFactor *big.Int) []*big.Int { buffer := make([]*big.Int, 0) quo := new(big.Int) quo.Set(toFactor) //~ f := get_f(task.toFactor) for !quo.ProbablyPrime(prime_precision) { //quo.Cmp(big.NewInt(1)) > 0) { if task.ShouldStop() { return buffer } var factor *big.Int var error bool for i := 0; ; i++ { factor, error = pollardRho(task, quo, int64(i)) if task.ShouldStop() { return buffer } if !error { break } } if !factor.ProbablyPrime(prime_precision) { sub := _pollardFactoring(task, factor) buffer = append(buffer, sub...) } else { buffer = append(buffer, factor) } quo.Quo(quo, factor) } return append(buffer, quo) }
// GenerateParameters puts a random, valid set of DSA parameters into params. // This function can take many seconds, even on fast machines. func GenerateParameters(params *Parameters, rand io.Reader, sizes ParameterSizes) 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 { if _, err := io.ReadFull(rand, qBytes); err != nil { return err } qBytes[len(qBytes)-1] |= 1 qBytes[0] |= 0x80 q.SetBytes(qBytes) if !q.ProbablyPrime(numMRTests) { continue } for i := 0; i < 4*L; i++ { if _, err := io.ReadFull(rand, pBytes); err != nil { return err } 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 !p.ProbablyPrime(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 nil } }
// Probabilistically test whether a big integer is prime. func isPrime(i *big.Int) bool { return i.ProbablyPrime(numMRTests) }
// IsSafePrime returns true, if the prime of the group is // a so called safe-prime. For a group with a safe-prime prime // number the Decisional-Diffie-Hellman-Problem (DDH) is a // 'hard' problem. The n argument is the number of iterations // for the probabilistic prime test. // It's recommend to use DDH-safe groups for DH-exchanges. func IsSafePrimeGroup(g *Group, n int) bool { q := new(big.Int).Sub(g.P, one) q = q.Div(q, two) return q.ProbablyPrime(n) }
func Brent(n *big.Int, start, c int64) (primes, composites []*big.Int) { if n.ProbablyPrime(10) { return []*big.Int{n}, nil } x1 := big.NewInt(start) x2 := big.NewInt(start*start + c) bigc := big.NewInt(c) // try to get off the tail for j := 0; j < 1000; j++ { x2.Exp(x2, two, n) x2.Add(x2, bigc) } limit := 1 product := big.NewInt(1) terms := 0 for terms < (1 << 16) { for j := 0; j < limit; j++ { x2.Exp(x2, two, n) x2.Add(x2, bigc) if x1.Cmp(x2) == 0 { // algorithm fail? break } var tmp big.Int tmp.Sub(x1, x2) product.Mul(product, &tmp) terms++ if terms%16 == 0 { if newN, newG, ok := checkGCD(n, product); ok { pr, co := Brent(newN, start, c) primes, composites = append(primes, pr...), append(composites, co...) pr, co = Brent(newG, start, c) primes, composites = append(primes, pr...), append(composites, co...) return primes, composites } product.SetInt64(1) } } x1.Set(x2) limit *= 2 for j := 0; j < limit; j++ { x2.Exp(x2, two, n) x2.Add(x2, bigc) } } if n.Cmp(one) != 0 { if n.ProbablyPrime(10) { primes = append(primes, n) } else { composites = append(composites, n) } } return primes, composites }
func isPrime(x *big.Int) bool { return x.ProbablyPrime(10) == true }