Який можливий випадок використання .isProbablePrime () від BigInteger?


84

МетодBigInteger.isProbablePrime() досить дивний; з документації це покаже, чи число є простим з імовірністю 1 - 1 / 2^arg, де argцілий аргумент.

Він присутній у JDK досить довгий час, тому це означає, що він повинен мати застосування. Мої обмежені знання в галузі інформатики та алгоритмів (і математики) говорять мені, що насправді не має сенсу знати, чи є число "ймовірно" простим, але не зовсім простим.

Отже, який можливий сценарій, коли хотілося б використовувати цей метод? Криптографія?



6
Також тест на первинність Міллера-Рабіна . Головна перевага - швидкість . Наприклад, коли ви хочете перевірити наявність факторів, ви можете зробити такий тест, щоб пришвидшити процес факторингу. Ви можете тримати "ймовірно" його частину досить низькою, і це корисно на практиці. Але я погоджуюсь, що це трохи хитко і дивно, як поплавки.
keyser

2
@ maxx777 це дано - я прошу фактичного випадку використання
fge

4
Я б на самому справі , як downvoters пояснити причини , що лежать в downvotes, будь ласка
FGE

17
"Він присутній у JDK досить довгий час, тому це означає, що він повинен мати застосування". - або він був доданий з марної причини, а потім не видалений, оскільки ніколи нічого не видаляється.
user253751

Відповіді:


67

Так, цей метод можна використовувати в криптографії. Шифрування RSA передбачає знаходження величезних простих чисел, іноді близько 1024 біт (близько 300 цифр). Безпека RSA залежить від того, що множення числа, яке складається з 2 із цих простих чисел, помножених разом, надзвичайно складно і вимагає багато часу. Але щоб це спрацювало, вони повинні бути головними.

Виявляється, довести ці числа простими теж важко. Але тест на первинність Міллера-Рабіна , один із тестів на первинність, який використовує isProbablePrime, або виявляє, що число є складеним, або не дає висновку. Виконання цього тестового nчасу дозволяє зробити висновок, що існує 1 до 2 п шансів, що це число дійсно складене. Побіг у 100рази дає прийнятний ризик 1 із 2 100, що це число є складовим.


3
@ Mr.777 Я бачив Рабіна-Міллера один-два рази, але Міллер-Рабін був десятки разів. Я не впевнений, що існує офіційна назва.
keyser

3
@ Mr.777 Сторінка Вікіпедії, на яку я посилався вище, спочатку вказує "Міллер-Рабін", але визнає обидві назви: "Тест первинності Міллера – Рабіна або Тест первинності Рабіна – Міллера".
rgettman

5
Реалізація isProbablyPrimeє (наскільки я можу зрозуміти) повністю детермінованою. Як запуск тестового nчасу покращить шанси на правильний результат? (Навіть якби це був елемент випадковості, потрібно було б, щоб випадковість кількох дзвінків була незалежною, щоб впливати на ризик у способі, який ви описуєте.)
Тед Хопп,

11
@TedHopp Реалізація використовує генератор випадкових випадків, і кожен раунд з новими випадковими числами дає 3/4 шансу виявити композит. Генератором за замовчуванням є SecureRandom, із потужними гарантіями випадковості.
той інший хлопець

4
Це може бути важко, однак пам'ятайте, що PRIMES знаходиться в P. Тест AKS може бути повільнішим, ніж Міллер-Рабін, але між ними немає експоненціальної різниці або полінома. Ви можете використовувати Міллер-Рабін, щоб знайти купу ймовірних простих чисел, а за допомогою AKS однозначно довести, що вони є простими.
Бакуріу

20

Якщо тест показує, що ціле число не є простим , ви можете впевнитися, що це 100%.

Це лише інша сторона питання, якщо тест показує, що ціле число є "ймовірним простим числом", ви можете викликати сумнів. Повторення тесту з різними "основами" дозволяє зменшити ймовірність помилкового успіху "імітації" простого числа (будучи сильним псевдопростим відносно декількох основ).

Корисність тесту полягає в його швидкості та простоті. Не обов’язково, щоб остаточна відповідь була задоволена статусом "ймовірного простого", але, безумовно, уникала б витрачати час майже на всі складені числа, використовуючи цю процедуру, перш ніж залучати великі гармати перевірки первинності .

Порівняння зі складністю розкладання цілих чисел - це щось на зразок червоної оселедця. Відомо, що первинність цілого числа може бути визначена за поліноміальний час, і справді є доказ того, що розширення тесту Міллера-Рабіна на достатню кількість основ є остаточним (при виявленні простих чисел, на відміну від ймовірних простих чисел), але це передбачає узагальнену гіпотезу Рімана, тому вона не є настільки певною, як (більш дорогий) тест на первинність AKS .


4
Варто зазначити, що AKS було відкрито лише в серпні 2002 року, тоді як цей метод був у JDK з лютого 2002 року
James_pic

3
Ні, почекайте, це було в JDK з лютого 1997 року (я дивився на probablePrimeметод, а не на isProbablePrimeметод)
James_pic

1
Дійсно, заголовок у роботі Аграваля, Каяла та Саксени 2002 р. "PRIMES is in P" є першим беззастережним доказом поліноміальної (у бітовій довжині n ) складності для детермінованого (загального цілого) тестування первинності. Міллер (1975) показав, що, припускаючи GRH , первинність цілого числа може бути перевірена детерміновано з кроками, пропорційними четвертому степеню довжини біта, набагато кращим показником, ніж відомий в даний час для AKS або його варіантів.
hardmath

Хоча AKS асимптотично швидший, такі методи, як ECPP, були б набагато ефективнішими для `` криптографічних '' або `` промислових '' простих чисел.
Бретт Хейл

2
AKS шалено повільний і не буде швидшим за APR-CL для будь-якого числа, обчислюваного в геологічному масштабі, а тим більше людського масштабу. APR-CL та ECPP існували вже в 1997 році. Як зазначає Бретт, ECPP є хорошим вибором, якщо ми хочемо підтвердження. Усі вони є повільними порівняно з можливими простими методами (наприклад, MR, BPSW, Frobenius).
DanaJ

19

Стандартним варіантом використання BigInteger.isProbablePrime(int)є криптографія. Зокрема, певні криптографічні алгоритми, такі як RSA , вимагають випадково вибраних великих простих чисел. Однак важливо, що ці алгоритми насправді не вимагають, щоб ці числа були гарантованими як прості - вони просто повинні бути простими з дуже високою ймовірністю.

Наскільки висока дуже висока? Ну, у криптопрограмі, як правило, можна було б зателефонувати .isProbablePrime()з аргументом десь між 128 і 256. Таким чином, ймовірність того, що непросте число пройде такий тест, менше, ніж одиниця в 2 128 або 2 256 .

Давайте покладемо , що в перспективі: якщо ви мали 10 мільярдів комп'ютерів, кожен з яких генерує 10 млрд ймовірними простих чисел в секунду (що означало б менше , ніж один тактовий цикл кожного номера на будь-який сучасний CPU) і простоти цих чисел була протестована .isProbablePrime(128), ви в середньому очікував би, що одне непросте число підскочить раз на 100 мільярдів років .

Тобто це було б так, якби ці 10 мільярдів комп’ютерів могли якимось чином працювати сотні мільярдів років, не зазнаючи жодних апаратних збоїв. На практиці, однак, це набагато більш імовірно , для випадкового космічних променів , щоб вдарити ваш комп'ютер в потрібний час і місце , щоб перевертати повертається значення з .isProbablePrime(128)від помилкового до істини, не викликаючи жодних інших виявляються ефектів, ніж для НЕ -просте число, щоб насправді пройти імовірнісний тест на первинність на цьому рівні визначеності.

Звичайно, той самий ризик випадкових космічних променів та інших апаратних несправностей стосується і детермінованих тестів на первинність, таких як AKS . Таким чином, на практиці навіть ці тести мають (дуже малий) вихідний показник хибнопозитивних результатів через випадкові збої обладнання (не кажучи вже про всі інші можливі джерела помилок, такі як помилки реалізації).

Оскільки неважко відхилити власний хибнопозитивний показник тесту на первинність Міллера – Рабіна, що використовується .isProbablePrime()набагато нижче цього базового рівня, просто повторивши тест досить багато разів, і оскільки, навіть повторений стільки разів, тест Міллера – Рабіна все ще залишається набагато швидше на практиці, ніж найвідоміші детерміновані тести на первинність, такі як AKS, він залишається стандартним тестом на первинність для криптографічних додатків.

(Крім того, навіть якщо ви випадково вибрали сильний псевдозлочинність як один із факторів вашого модуля RSA, це, як правило, не призведе до катастрофічного зриву. Як правило, такі псевдозалежності будуть продуктом двох (або рідко більше) простих чисел приблизно половина довжини, а це означає, що у вас вийшов би мультипростий ключ RSA . Поки жоден з факторів не був занадто малим (а якщо і був, тест на первинність мав би їх схопити), алгоритм RSA буде як і раніше працюють нормально, і ключ, хоч і дещо слабший проти певних типів атак, ніж звичайні ключі RSA тієї ж довжини, все одно повинен бути достатньо захищеним, якщо ви не витрачали без потреби на довжину ключа.)


Проблема несправності - одна з причин, чому AKS насправді не використовується (дивовижно низька швидкість - інша), а ECPP є більш поширеною. Як ви зазначаєте, помилки реалізації в алгоритмах цілком можливі, тому корисно мати сертифікат, перевірений незалежним кодом.
DanaJ

8

Можливим варіантом використання є тестування первинності заданого числа (на тесті, який сам по собі має багато застосувань). isProbablePrimeАлгоритм буде працювати набагато швидше , ніж точний алгоритм, тому , якщо номер не вдається isProbablePrime, то одна потреба не йти в рахунок запуску дорожчий алгоритм.


То що це для практичності? А через те, що розкладання простих чисел є проблемою NP?
fge

@fge - Так, я запропонував варіант використання для практичності. Я не знаю, що це допомагає з простим розкладанням на факторизацію, що є значно складнішою проблемою, ніж перевірка первинності. Для останнього існує алгоритм поліноміального часу: тест на первинність AKS .
Тед Хопп,

5
@fge: факторизация дійсно в НП, але я підозрюю , що ви мали в виду «NP-повної», що факторизація НЕ відомо , щоб бути. Навпаки, існує велика підозра, що вона не є NP-жорсткою.
hmakholm залишив Моніку

6

Пошук ймовірних простих чисел є важливою проблемою криптографії. Виявляється, розумною стратегією для пошуку ймовірного k-бітового простого є багаторазовий вибір випадкового k-бітового числа та перевірка його на ймовірну первинність за допомогою такого методу isProbablePrime().

Для подальшого обговорення див. Розділ 4.4.1 Довідника з прикладної криптографії .

Також див. Про генерування ймовірних простих чисел шляхом покрокового пошуку Брандта та Дамгарда.


5

Такі алгоритми, як генерація ключа RSA, покладаються на можливість визначити, чи є число простим чи ні.

Однак на той час, коли isProbablePrimeметод був доданий до JDK (лютий 1997 р.), Не було перевіреного способу детерміновано вирішити, чи є число простим за розумний проміжок часу. Найвідомішим підходом на той час був алгоритм Міллера-Рабіна - імовірнісний алгоритм, який іноді давав помилкові спрацьовування (тобто повідомляв непрості числа як прості числа), але міг бути налаштований на зменшення ймовірності помилкових спрацьовувань за рахунок помірного збільшення часу роботи.

З тих пір були виявлені алгоритми, які можуть детерміновано вирішити, чи є число простим досить швидко, наприклад, алгоритм AKS, який був виявлений у серпні 2002 р. Однак слід зазначити, що ці алгоритми все ще не такі швидкі, як Міллер-Рабін.

Можливо, кращим питанням є те, чому жоден isPrimeметод не був доданий до JDK з 2002 року.


Дякую за історичну перспективу! Схоже, @immibis був на правильному шляху зі своїм коментарем про "в JDK, але ніколи не вилучався", тоді? :)
fge

1
Я знаю, що Java чудово ніколи не видаляє речі зі стандартної бібліотеки, але я не впевнений, що вони б їх видалили, навіть якби могли. Для деяких додатків, будучи впевненим на 99,999999999%, щось найкраще є достатнім, і набагато швидше, ніж на 100%.
James_pic
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.