{"id":246235,"date":"2025-05-28T04:37:33","date_gmt":"2025-05-28T09:37:33","guid":{"rendered":"https:\/\/www.johndcook.com\/blog\/?p=246235"},"modified":"2025-05-28T04:38:13","modified_gmt":"2025-05-28T09:38:13","slug":"lucas-lehmer-test","status":"publish","type":"post","link":"https:\/\/www.johndcook.com\/blog\/2025\/05\/28\/lucas-lehmer-test\/","title":{"rendered":"The bad version of a good test"},"content":{"rendered":"<p>Ever since 1952, the largest known primes have all had the form 2<sup><em>n<\/em><\/sup> \u2212 1, with one exception in 1989. The reason the largest known primes have this form is that it is easier to test whether these numbers are prime than other numbers.<\/p>\n<p>A number of the form 2<sup><em>n<\/em><\/sup> \u2212 1 is called a Mersenne number, denoted <em>M<\/em><sub><em>n<\/em><\/sub>. A Mersenne prime is a Mersenne number that is also prime. There is a theorem that says that if <em>M<\/em><sub><em>n<\/em><\/sub>\u00a0is prime then <em>n<\/em> must be prime.<\/p>\n<h2>Lehmer&#8217;s theorem<\/h2>\n<p>Derrick Henry Lehmer proved in 1930 that <em>M<\/em><sub><em>p<\/em> <\/sub>is prime if\u00a0<em>p<\/em> is an odd prime and <em>M<\/em><sub><em>p<\/em><\/sub> divides\u00a0<em>s<\/em><sub><em>p<\/em>\u22122<\/sub> where the\u00a0<em>s<\/em> terms are defined recursively as follows. Define <em>s<\/em><sub>0<\/sub> = 4 and <em>s<\/em><sub><em>n<\/em><\/sub> = <em>s<\/em><sub><em>n<\/em>\u22121<\/sub>\u00b2 \u2212 2 for <em>n<\/em> &gt; 0. This is the Lucas-Lehmer primality test for Mersenne numbers, the test alluded to above.<\/p>\n<p>Let&#8217;s try this out on <em>M<\/em><sub>7<\/sub> = 2<sup>7<\/sup> \u2212 1 = 127. We need to test whether 127 divides <em>s<\/em><sub>5<\/sub>. The first six values of <em>s<\/em><sub><em>n<\/em><\/sub> are<\/p>\n<p style=\"padding-left: 40px;\">4, 14, 194, 37634, 1416317954, 2005956546822746114<\/p>\n<p>and indeed 127 does divide 2005956546822746114. As you may have noticed, <em>s<\/em><sub>5<\/sub> is a big number, and <em>s<\/em><sub>6<\/sub> will be a lot bigger. It doesn&#8217;t look like Lehmer&#8217;s theorem is going to be very useful.<\/p>\n<h2>The missing piece<\/h2>\n<p>Here&#8217;s the idea that makes the Lucas-Lehmer [1] test practical. We don&#8217;t need to know \u00a0<em>s<\/em><sub><em>p<\/em>\u22122<\/sub> per se; we only need to know whether it is divisible by <em>M<\/em><sub><em>p<\/em><\/sub>. So we can carry out all our calculations mod <em>M<\/em><sub><em>p<\/em><\/sub>. In our example, we only need to calculate the values of <em>s<\/em><sub><em>n<\/em><\/sub> mod 127:<\/p>\n<p style=\"padding-left: 40px;\">4, 14, 67, 42, 111, 0<\/p>\n<p>Much better.<\/p>\n<p>Lucas-Lehmer test takes the remainder by <em>M<\/em><sub><em>p<\/em><\/sub> at every step along the way when computing the recursion for the\u00a0<em>s<\/em> terms. The naive version does not, but computes the <em>s<\/em> terms directly.<\/p>\n<p>To make the two versions of the test explicit, here are Python implementations.<\/p>\n<h3>Naive code<\/h3>\n<pre>def lucas_lehmer_naive(p):\r\n    M = 2**p - 1\r\n    s = 4\r\n    for _ in range(p-2):\r\n        s = (s*s - 2) \r\n    return s % M  == 0\r\n<\/pre>\n<h3>Good code<\/h3>\n<pre>def lucas_lehmer(p):\r\n    M = 2**p - 1\r\n    s = 4\r\n    for _ in range(p-2):\r\n        s = (s*s - 2) % M\r\n    return s == 0\r\n<\/pre>\n<h2>The bad version<\/h2>\n<p>How bad is the naive version of the Lucas-Lehmer test?<\/p>\n<p>The OEIS sequence <a href=\"https:\/\/oeis.org\/A003010\">A003010<\/a> consists of the <em>s<\/em><sub><em>n<\/em><\/sub>. OEIS gives the following formula:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" style=\"background-color: white;\" src=\"https:\/\/www.johndcook.com\/lucaslehmer1.svg\" alt=\"s_n = \\left\\lceil (2 + \\sqrt{3})^{2^n}\\right\\rceil\" width=\"139\" height=\"36\" \/><\/p>\n<p>This shows that the <em>s<\/em><sub><em>n<\/em><\/sub> grow extremely rapidly, which suggests the naive algorithm will hit a wall fairly quickly<\/p>\n<p>When I used the two versions of the test above to verify that the first few Mersenne primes <em>M<\/em><sub><em>p<\/em><\/sub> really are prime, the naive version gets stuck after <em>p<\/em> = 19. The better version immediately works through\u00a0<em>p<\/em> = 9689 before slowing down noticeably.<\/p>\n<h3>Historical example<\/h3>\n<p>Let&#8217;s look at <em>M<\/em><sub>521<\/sub>. This was the first Mersenne number verified by a computer to be prime. This was done on the vacuum tube-based SWAC computer in 1952 using the smart version of the Lucas-Lehmer test.<\/p>\n<p>Carrying out the Lucas-Lehmer test to show that this number is prime requires doing modular arithmetic with 521-bit numbers, which was well within the 9472 bits of memory in the vacuum tube-based SWAC computer that proved <em>M<\/em><sub>521<\/sub> was prime.<\/p>\n<p>But it would not be possible now, or ever, to verify that <em>M<\/em><sub>521<\/sub> is prime using the naive version of the Lucas-Lehmer test because we could not store, much less compute, <em>s<\/em><sub>519<\/sub>.<\/p>\n<p>Since<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" style=\"background-color: white;\" src=\"https:\/\/www.johndcook.com\/lucaslehmer2.svg\" alt=\"\\log_{2} s_{519} = 2^{519} \\log_{2} (2 + \\sqrt{3}) \\approx 2^{520}\" width=\"285\" height=\"23\" \/><\/p>\n<p>we&#8217;d need around 2<sup>520<\/sup> bits to store <em>s<\/em><sub>519<\/sub>. The number of bits we&#8217;d need is itself a 157-digit number. We&#8217;d need more bits than there are particles in the universe, which has been estimated to be on the order of 10<sup>80<\/sup>.<\/p>\n<p>The largest Mersenne prime that the SWAC could verify using the naive Lucas-Lehmer test would have been <em>M<\/em><sub>13 <\/sub>= 8191, which was found to be prime in the Middle Ages.<\/p>\n<h2>Related posts<\/h2>\n<ul>\n<li class=\"link\"><a href=\"https:\/\/www.johndcook.com\/blog\/2024\/10\/21\/new-mersenne-prime-found\/\">Largest known prime as of 2024<\/a><\/li>\n<li class=\"link\"><a href=\"https:\/\/www.johndcook.com\/blog\/2010\/10\/13\/googol\/\">There isn&#8217;t a googol of anything<\/a><\/li>\n<li class=\"link\"><a href=\"https:\/\/www.johndcook.com\/blog\/2011\/09\/09\/five-interesting-things-about-mersenne-primes\/\">Five things about Mersenne primes<\/a><\/li>\n<\/ul>\n<p>[1] \u00c9douard Lucas conjectured in 1878 the theorem that Lehmer proved in 1930.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Ever since 1952, the largest known primes have all had the form 2n \u2212 1, with one exception in 1989. The reason the largest known primes have this form is that it is easier to test whether these numbers are prime than other numbers. A number of the form 2n \u2212 1 is called a [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[5],"tags":[94],"class_list":["post-246235","post","type-post","status-publish","format-standard","hentry","category-computing","tag-number-theory"],"acf":[],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.0.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"How bad is the naive version of the Lucas-Lehmer test, the test used to find Mersenne primes? One little idea makes all the difference.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"John\"\/>\n\t<meta name=\"keywords\" content=\"number theory\" \/>\n\t<link rel=\"canonical\" href=\"https:\/\/www.johndcook.com\/blog\/2025\/05\/28\/lucas-lehmer-test\/\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.0.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"en_US\" \/>\n\t\t<meta property=\"og:site_name\" content=\"John D. Cook | Applied Mathematics Consulting\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"Naive version of the Lucas-Lehmer test for Mersenne primes\" \/>\n\t\t<meta property=\"og:description\" content=\"How bad is the naive version of the Lucas-Lehmer test, the test used to find Mersenne primes? One little idea makes all the difference.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/www.johndcook.com\/blog\/2025\/05\/28\/lucas-lehmer-test\/\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2025-05-28T09:37:33+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2025-05-28T09:38:13+00:00\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary\" \/>\n\t\t<meta name=\"twitter:title\" content=\"Naive version of the Lucas-Lehmer test for Mersenne primes\" \/>\n\t\t<meta name=\"twitter:description\" content=\"How bad is the naive version of the Lucas-Lehmer test, the test used to find Mersenne primes? One little idea makes all the difference.\" \/>\n\t\t<meta name=\"twitter:image\" content=\"https:\/\/www.johndcook.com\/blog\/wp-content\/uploads\/2022\/05\/twittercard.png\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"Naive version of the Lucas-Lehmer test for Mersenne primes","description":"How bad is the naive version of the Lucas-Lehmer test, the test used to find Mersenne primes? One little idea makes all the difference.","canonical_url":"https:\/\/www.johndcook.com\/blog\/2025\/05\/28\/lucas-lehmer-test\/","robots":"max-image-preview:large","keywords":"number theory","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"en_US","og:site_name":"John D. Cook | Applied Mathematics Consulting","og:type":"article","og:title":"Naive version of the Lucas-Lehmer test for Mersenne primes","og:description":"How bad is the naive version of the Lucas-Lehmer test, the test used to find Mersenne primes? One little idea makes all the difference.","og:url":"https:\/\/www.johndcook.com\/blog\/2025\/05\/28\/lucas-lehmer-test\/","article:published_time":"2025-05-28T09:37:33+00:00","article:modified_time":"2025-05-28T09:38:13+00:00","twitter:card":"summary","twitter:title":"Naive version of the Lucas-Lehmer test for Mersenne primes","twitter:description":"How bad is the naive version of the Lucas-Lehmer test, the test used to find Mersenne primes? One little idea makes all the difference.","twitter:image":"https:\/\/www.johndcook.com\/blog\/wp-content\/uploads\/2022\/05\/twittercard.png"},"aioseo_meta_data":{"post_id":"246235","title":"Naive version of the Lucas-Lehmer test for Mersenne primes","description":"How bad is the naive version of the Lucas-Lehmer test, the test used to find Mersenne primes? One little idea makes all the difference.","keywords":null,"keyphrases":{"focus":{"keyphrase":"","score":0,"analysis":{"keyphraseInTitle":{"score":0,"maxScore":9,"error":1}}},"additional":[]},"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":"","og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"Article","isEnabled":true},"graphs":[]},"schema_type":"default","schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":"-1","robots_max_videopreview":"-1","robots_max_imagepreview":"large","priority":null,"frequency":"default","location":null,"local_seo":null,"breadcrumb_settings":null,"limit_modified_date":false,"created":"2025-05-28 01:18:50","updated":"2025-06-04 04:26:12","ai":null,"seo_analyzer_scan_date":null},"aioseo_breadcrumb":"<div class=\"aioseo-breadcrumbs\"><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/www.johndcook.com\/blog\" title=\"Home\">Home<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/www.johndcook.com\/blog\/category\/computing\/\" title=\"Computing\">Computing<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\tThe bad version of a good test\n\t\t<\/span><\/div>","aioseo_breadcrumb_json":[{"label":"Home","link":"https:\/\/www.johndcook.com\/blog"},{"label":"Computing","link":"https:\/\/www.johndcook.com\/blog\/category\/computing\/"},{"label":"The bad version of a good test","link":"https:\/\/www.johndcook.com\/blog\/2025\/05\/28\/lucas-lehmer-test\/"}],"_links":{"self":[{"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/posts\/246235","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/comments?post=246235"}],"version-history":[{"count":0,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/posts\/246235\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/media?parent=246235"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/categories?post=246235"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/tags?post=246235"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}