github.com/twelsh-aw/go/src@v0.0.0-20230516233729-a56fe86a7c81/math/big/prime_test.go (about) 1 // Copyright 2016 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 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 // https://golang.org/issue/638 27 "18699199384836356663", 28 29 "98920366548084643601728869055592650835572950932266967461790948584315647051443", 30 "94560208308847015747498523884063394671606671904944666360068158221458669711639", 31 32 // https://primes.utm.edu/lists/small/small3.html 33 "449417999055441493994709297093108513015373787049558499205492347871729927573118262811508386655998299074566974373711472560655026288668094291699357843464363003144674940345912431129144354948751003607115263071543163", 34 "230975859993204150666423538988557839555560243929065415434980904258310530753006723857139742334640122533598517597674807096648905501653461687601339782814316124971547968912893214002992086353183070342498989426570593", 35 "5521712099665906221540423207019333379125265462121169655563495403888449493493629943498064604536961775110765377745550377067893607246020694972959780839151452457728855382113555867743022746090187341871655890805971735385789993", 36 "203956878356401977405765866929034577280193993314348263094772646453283062722701277632936616063144088173312372882677123879538709400158306567338328279154499698366071906766440037074217117805690872792848149112022286332144876183376326512083574821647933992961249917319836219304274280243803104015000563790123", 37 38 // ECC primes: https://tools.ietf.org/html/draft-ladd-safecurves-02 39 "3618502788666131106986593281521497120414687020801267626233049500247285301239", // Curve1174: 2^251-9 40 "57896044618658097711785492504343953926634992332820282019728792003956564819949", // Curve25519: 2^255-19 41 "9850501549098619803069760025035903451269934817616361666987073351061430442874302652853566563721228910201656997576599", // E-382: 2^382-105 42 "42307582002575910332922579714097346549017899709713998034217522897561970639123926132812109468141778230245837569601494931472367", // Curve41417: 2^414-17 43 "6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151", // E-521: 2^521-1 44 } 45 46 var composites = []string{ 47 "0", 48 "1", 49 "21284175091214687912771199898307297748211672914763848041968395774954376176754", 50 "6084766654921918907427900243509372380954290099172559290432744450051395395951", 51 "84594350493221918389213352992032324280367711247940675652888030554255915464401", 52 "82793403787388584738507275144194252681", 53 54 // Arnault, "Rabin-Miller Primality Test: Composite Numbers Which Pass It", 55 // Mathematics of Computation, 64(209) (January 1995), pp. 335-361. 56 "1195068768795265792518361315725116351898245581", // strong pseudoprime to prime bases 2 through 29 57 // strong pseudoprime to all prime bases up to 200 58 ` 59 80383745745363949125707961434194210813883768828755814583748891752229 60 74273765333652186502336163960045457915042023603208766569966760987284 61 0439654082329287387918508691668573282677617710293896977394701670823 62 0428687109997439976544144845341155872450633409279022275296229414984 63 2306881685404326457534018329786111298960644845216191652872597534901`, 64 65 // Extra-strong Lucas pseudoprimes. https://oeis.org/A217719 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 // check that ProbablyPrime panics if n <= 0 146 c := NewInt(11) // a prime 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 // https://oeis.org/A001262 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 // https://oeis.org/A217719 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 }