func benchmarkModPowBig(b *testing.B, base, e, m uint32) { b.StopTimer() bb := big.NewInt(int64(base)) ee := New(e) mm := New(m) runtime.GC() b.StartTimer() for i := 0; i < b.N; i++ { mathutil.ModPowBigInt(bb, ee, mm) } }
func main() { runtime.GOMAXPROCS(2) oClass := flag.Uint64("c", 2, `factor "class" number`) oDuration := flag.Duration("d", time.Second, "duration to spend on one class") flag.Parse() class := *oClass for class&1 != 0 { class >>= 1 } class = mathutil.MaxUint64(class, 2) for { c := time.After(*oDuration) factor := big.NewInt(0) factor.SetUint64(class) exp := big.NewInt(0) oneClass: for { select { case <-c: break oneClass default: } exp.Set(factor) factor.Lsh(factor, 1) factor.Add(factor, _1) if !factor.ProbablyPrime(pp) { continue } if !exp.ProbablyPrime(pp) { continue } if mathutil.ModPowBigInt(_2, exp, factor).Cmp(_1) != 0 { continue } if !factor.ProbablyPrime(pp2) { continue } if !exp.ProbablyPrime(pp2) { continue } fmt.Printf("%d: %s | M%s (%d bits)\n", class, factor, exp, factor.BitLen()) } class += 2 } }
func TestModPow(t *testing.T) { const N = 2e2 data := []struct{ b, e, m, r uint32 }{ {0, 1, 1, 0}, {0, 2, 1, 0}, {0, 3, 1, 0}, {1, 0, 1, 0}, {1, 1, 1, 0}, {1, 2, 1, 0}, {1, 3, 1, 0}, {2, 0, 1, 0}, {2, 1, 1, 0}, {2, 2, 1, 0}, {2, 3, 1, 0}, {2, 3, 4, 8}, {2, 3, 5, 4}, {2, 4, 3, 1}, {3, 3, 3, 3}, {3, 4, 5, 30}, } f := func(b, e, m uint32, expect *big.Int) { got := ModPow(b, e, m) if got.Cmp(expect) != 0 { t.Fatal(b, e, m, got, expect) } } var r big.Int for _, v := range data { r.SetInt64(int64(v.r)) f(v.b, v.e, v.m, &r) } rg, _ := mathutil.NewFC32(2, 1<<10, true) var bb big.Int for i := 0; i < N; i++ { b, e, m := uint32(rg.Next()), uint32(rg.Next()), uint32(rg.Next()) bb.SetInt64(int64(b)) f(b, e, m, mathutil.ModPowBigInt(&bb, New(e), New(m))) } }
// HasFactorBigInt2 returns true if d | Mn, d > 0 func HasFactorBigInt2(d, n *big.Int) bool { return d.Cmp(_1) == 0 || d.Sign() > 0 && d.Bit(0) == 1 && mathutil.ModPowBigInt(_2, n, d).Cmp(_1) == 0 }
// HasFactorBigInt returns true if d | Mn, d > 0. Typical run time for a 128 // bit factor and a 32 bit exponent is < 75 µs. func HasFactorBigInt(d *big.Int, n uint32) bool { return d.Cmp(_1) == 0 || d.Sign() > 0 && d.Bit(0) == 1 && mathutil.ModPowBigInt(_2, big.NewInt(int64(n)), d).Cmp(_1) == 0 }