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 stk := getStack()
163 defer stk.free()
164
165 p, _ := new(Int).SetString("203956878356401977405765866929034577280193993314348263094772646453283062722701277632936616063144088173312372882677123879538709400158306567338328279154499698366071906766440037074217117805690872792848149112022286332144876183376326512083574821647933992961249917319836219304274280243803104015000563790123", 10)
166 for _, n := range []int{0, 1, 5, 10, 20} {
167 b.Run(fmt.Sprintf("n=%d", n), func(b *testing.B) {
168 for i := 0; i < b.N; i++ {
169 p.ProbablyPrime(n)
170 }
171 })
172 }
173
174 b.Run("Lucas", func(b *testing.B) {
175 for i := 0; i < b.N; i++ {
176 p.abs.probablyPrimeLucas(stk)
177 }
178 })
179 b.Run("MillerRabinBase2", func(b *testing.B) {
180 for i := 0; i < b.N; i++ {
181 p.abs.probablyPrimeMillerRabin(stk, 1, true)
182 }
183 })
184 }
185
186 func TestMillerRabinPseudoprimes(t *testing.T) {
187 stk := getStack()
188 defer stk.free()
189
190 testPseudoprimes(t, "probablyPrimeMillerRabin",
191 func(n nat) bool { return n.probablyPrimeMillerRabin(stk, 1, true) && !n.probablyPrimeLucas(stk) },
192
193 []int{2047, 3277, 4033, 4681, 8321, 15841, 29341, 42799, 49141, 52633, 65281, 74665, 80581, 85489, 88357, 90751})
194 }
195
196 func TestLucasPseudoprimes(t *testing.T) {
197 stk := getStack()
198 defer stk.free()
199
200 testPseudoprimes(t, "probablyPrimeLucas",
201 func(n nat) bool { return n.probablyPrimeLucas(stk) && !n.probablyPrimeMillerRabin(stk, 1, true) },
202
203 []int{989, 3239, 5777, 10877, 27971, 29681, 30739, 31631, 39059, 72389, 73919, 75077})
204 }
205
206 func testPseudoprimes(t *testing.T, name string, cond func(nat) bool, want []int) {
207 n := nat{1}
208 for i := 3; i < 100000; i += 2 {
209 if testing.Short() {
210 if len(want) == 0 {
211 break
212 }
213 if i < want[0]-2 {
214 i = want[0] - 2
215 }
216 }
217 n[0] = Word(i)
218 pseudo := cond(n)
219 if pseudo && (len(want) == 0 || i != want[0]) {
220 t.Errorf("%s(%v, base=2) = true, want false", name, i)
221 } else if !pseudo && len(want) >= 1 && i == want[0] {
222 t.Errorf("%s(%v, base=2) = false, want true", name, i)
223 }
224 if len(want) > 0 && i == want[0] {
225 want = want[1:]
226 }
227 }
228 if len(want) > 0 {
229 t.Fatalf("forgot to test %v", want)
230 }
231 }
232
View as plain text