Source file
src/math/big/prime_test.go
1
2
3
4
5 package big
6
7 import (
8 "fmt"
9 "strings"
10 "testing"
11 "unicode"
12 )
13
14 var primes = []string{
15 "2",
16 "3",
17 "5",
18 "7",
19 "11",
20
21 "13756265695458089029",
22 "13496181268022124907",
23 "10953742525620032441",
24 "17908251027575790097",
25
26
27 "18699199384836356663",
28
29 "98920366548084643601728869055592650835572950932266967461790948584315647051443",
30 "94560208308847015747498523884063394671606671904944666360068158221458669711639",
31
32
33 "449417999055441493994709297093108513015373787049558499205492347871729927573118262811508386655998299074566974373711472560655026288668094291699357843464363003144674940345912431129144354948751003607115263071543163",
34 "230975859993204150666423538988557839555560243929065415434980904258310530753006723857139742334640122533598517597674807096648905501653461687601339782814316124971547968912893214002992086353183070342498989426570593",
35 "5521712099665906221540423207019333379125265462121169655563495403888449493493629943498064604536961775110765377745550377067893607246020694972959780839151452457728855382113555867743022746090187341871655890805971735385789993",
36 "203956878356401977405765866929034577280193993314348263094772646453283062722701277632936616063144088173312372882677123879538709400158306567338328279154499698366071906766440037074217117805690872792848149112022286332144876183376326512083574821647933992961249917319836219304274280243803104015000563790123",
37
38
39 "3618502788666131106986593281521497120414687020801267626233049500247285301239",
40 "57896044618658097711785492504343953926634992332820282019728792003956564819949",
41 "9850501549098619803069760025035903451269934817616361666987073351061430442874302652853566563721228910201656997576599",
42 "42307582002575910332922579714097346549017899709713998034217522897561970639123926132812109468141778230245837569601494931472367",
43 "6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151",
44 }
45
46 var composites = []string{
47 "0",
48 "1",
49 "21284175091214687912771199898307297748211672914763848041968395774954376176754",
50 "6084766654921918907427900243509372380954290099172559290432744450051395395951",
51 "84594350493221918389213352992032324280367711247940675652888030554255915464401",
52 "82793403787388584738507275144194252681",
53
54
55
56 "1195068768795265792518361315725116351898245581",
57
58 `
59 80383745745363949125707961434194210813883768828755814583748891752229
60 74273765333652186502336163960045457915042023603208766569966760987284
61 0439654082329287387918508691668573282677617710293896977394701670823
62 0428687109997439976544144845341155872450633409279022275296229414984
63 2306881685404326457534018329786111298960644845216191652872597534901`,
64
65
66 "989",
67 "3239",
68 "5777",
69 "10877",
70 "27971",
71 "29681",
72 "30739",
73 "31631",
74 "39059",
75 "72389",
76 "73919",
77 "75077",
78 "100127",
79 "113573",
80 "125249",
81 "137549",
82 "137801",
83 "153931",
84 "155819",
85 "161027",
86 "162133",
87 "189419",
88 "218321",
89 "231703",
90 "249331",
91 "370229",
92 "429479",
93 "430127",
94 "459191",
95 "473891",
96 "480689",
97 "600059",
98 "621781",
99 "632249",
100 "635627",
101
102 "3673744903",
103 "3281593591",
104 "2385076987",
105 "2738053141",
106 "2009621503",
107 "1502682721",
108 "255866131",
109 "117987841",
110 "587861",
111
112 "6368689",
113 "8725753",
114 "80579735209",
115 "105919633",
116 }
117
118 func cutSpace(r rune) rune {
119 if unicode.IsSpace(r) {
120 return -1
121 }
122 return r
123 }
124
125 func TestProbablyPrime(t *testing.T) {
126 nreps := 20
127 if testing.Short() {
128 nreps = 1
129 }
130 for i, s := range primes {
131 p, _ := new(Int).SetString(s, 10)
132 if !p.ProbablyPrime(nreps) || nreps != 1 && !p.ProbablyPrime(1) || !p.ProbablyPrime(0) {
133 t.Errorf("#%d prime found to be non-prime (%s)", i, s)
134 }
135 }
136
137 for i, s := range composites {
138 s = strings.Map(cutSpace, s)
139 c, _ := new(Int).SetString(s, 10)
140 if c.ProbablyPrime(nreps) || nreps != 1 && c.ProbablyPrime(1) || c.ProbablyPrime(0) {
141 t.Errorf("#%d composite found to be prime (%s)", i, s)
142 }
143 }
144
145
146 c := NewInt(11)
147 for _, n := range []int{-1, 0, 1} {
148 func() {
149 defer func() {
150 if n < 0 && recover() == nil {
151 t.Fatalf("expected panic from ProbablyPrime(%d)", n)
152 }
153 }()
154 if !c.ProbablyPrime(n) {
155 t.Fatalf("%v should be a prime", c)
156 }
157 }()
158 }
159 }
160
161 func BenchmarkProbablyPrime(b *testing.B) {
162 p, _ := new(Int).SetString("203956878356401977405765866929034577280193993314348263094772646453283062722701277632936616063144088173312372882677123879538709400158306567338328279154499698366071906766440037074217117805690872792848149112022286332144876183376326512083574821647933992961249917319836219304274280243803104015000563790123", 10)
163 for _, n := range []int{0, 1, 5, 10, 20} {
164 b.Run(fmt.Sprintf("n=%d", n), func(b *testing.B) {
165 for i := 0; i < b.N; i++ {
166 p.ProbablyPrime(n)
167 }
168 })
169 }
170
171 b.Run("Lucas", func(b *testing.B) {
172 for i := 0; i < b.N; i++ {
173 p.abs.probablyPrimeLucas()
174 }
175 })
176 b.Run("MillerRabinBase2", func(b *testing.B) {
177 for i := 0; i < b.N; i++ {
178 p.abs.probablyPrimeMillerRabin(1, true)
179 }
180 })
181 }
182
183 func TestMillerRabinPseudoprimes(t *testing.T) {
184 testPseudoprimes(t, "probablyPrimeMillerRabin",
185 func(n nat) bool { return n.probablyPrimeMillerRabin(1, true) && !n.probablyPrimeLucas() },
186
187 []int{2047, 3277, 4033, 4681, 8321, 15841, 29341, 42799, 49141, 52633, 65281, 74665, 80581, 85489, 88357, 90751})
188 }
189
190 func TestLucasPseudoprimes(t *testing.T) {
191 testPseudoprimes(t, "probablyPrimeLucas",
192 func(n nat) bool { return n.probablyPrimeLucas() && !n.probablyPrimeMillerRabin(1, true) },
193
194 []int{989, 3239, 5777, 10877, 27971, 29681, 30739, 31631, 39059, 72389, 73919, 75077})
195 }
196
197 func testPseudoprimes(t *testing.T, name string, cond func(nat) bool, want []int) {
198 n := nat{1}
199 for i := 3; i < 100000; i += 2 {
200 if testing.Short() {
201 if len(want) == 0 {
202 break
203 }
204 if i < want[0]-2 {
205 i = want[0] - 2
206 }
207 }
208 n[0] = Word(i)
209 pseudo := cond(n)
210 if pseudo && (len(want) == 0 || i != want[0]) {
211 t.Errorf("%s(%v, base=2) = true, want false", name, i)
212 } else if !pseudo && len(want) >= 1 && i == want[0] {
213 t.Errorf("%s(%v, base=2) = false, want true", name, i)
214 }
215 if len(want) > 0 && i == want[0] {
216 want = want[1:]
217 }
218 }
219 if len(want) > 0 {
220 t.Fatalf("forgot to test %v", want)
221 }
222 }
223
View as plain text