2 added
2 removed
Original
2026-01-01
Modified
2026-02-21
1
<p><strong>Об авторе</strong></p>
1
<p><strong>Об авторе</strong></p>
2
<p>Доктор Майкл Паунд - исследователь, работающий в Ноттингемском университете, специалист по компьютерной безопасности.</p>
2
<p>Доктор Майкл Паунд - исследователь, работающий в Ноттингемском университете, специалист по компьютерной безопасности.</p>
3
<p><strong>Переводчик</strong></p>
3
<p><strong>Переводчик</strong></p>
4
<p>Марина Демидова</p>
4
<p>Марина Демидова</p>
5
<p>В<a>видео</a>на YouTube-канале Numberphile Мэтт Паркер проверяет, может ли очень большое число быть простым.</p>
5
<p>В<a>видео</a>на YouTube-канале Numberphile Мэтт Паркер проверяет, может ли очень большое число быть простым.</p>
6
<p>В одном месте Мэтт приводит такое выражение:</p>
6
<p>В одном месте Мэтт приводит такое выражение:</p>
7
<p>23373 mod 747 - число 23 возводят в степень 373 и вычисляют результат по модулю 747.</p>
7
<p>23373 mod 747 - число 23 возводят в степень 373 и вычисляют результат по модулю 747.</p>
8
<p>Почему это меня заинтересовало? Дело в том, что подобные вычисления используются при шифровании данных с помощью алгоритма RSA с открытым ключом. Это могут быть, например, электронные подписи или шифрование в<a>S/MIME, TLS/SSL</a>и других приложениях.</p>
8
<p>Почему это меня заинтересовало? Дело в том, что подобные вычисления используются при шифровании данных с помощью алгоритма RSA с открытым ключом. Это могут быть, например, электронные подписи или шифрование в<a>S/MIME, TLS/SSL</a>и других приложениях.</p>
9
Мэтт Паркер<em>Кадр: Computerphile / YouTube</em><p>Этот материал - пересказ<a>видео</a>Майкла Паунда.</p>
9
Мэтт Паркер<em>Кадр: Computerphile / YouTube</em><p>Этот материал - пересказ<a>видео</a>Майкла Паунда.</p>
10
<p>Открытый ключ состоит из двух чисел {e, n}, где e - экспонента (простое число), а n - модуль (произведение двух простых чисел). Данные шифруются следующим образом:</p>
10
<p>Открытый ключ состоит из двух чисел {e, n}, где e - экспонента (простое число), а n - модуль (произведение двух простых чисел). Данные шифруются следующим образом:</p>
11
<p>E = xe mod n</p>
11
<p>E = xe mod n</p>
12
<p>Здесь x - исходное значение, а E - полученный шифр. Мы возводим число x в степень e и вычисляем результат по модулю n.</p>
12
<p>Здесь x - исходное значение, а E - полученный шифр. Мы возводим число x в степень e и вычисляем результат по модулю n.</p>
13
-
<p>Вернёмся к задаче Паркера. Такое вычисление нельзя сделать на карманном калькуляторе, и в видео на Numberphile Мэттью использует программу<a>WolframAlpha</a>, что разумно - я и сам часто провожу вычисления именно в этой программе.</p>
13
+
<p>Вернёмся к задаче Паркера. Такое вычисление нельзя сделать на карманном калькуляторе, и в видео на Numberphile Мэттью использует программу<a>WolframAlpha</a>, что разумно - я и сам часто пров��жу вычисления именно в этой программе.</p>
14
<em>Скриншот: Skillbox Media</em><p>Но мы попробуем применить алгоритм Square & Multiply (возведения в квадрат и умножения). Его можно использовать даже при вычислениях с очень большими числами.</p>
14
<em>Скриншот: Skillbox Media</em><p>Но мы попробуем применить алгоритм Square & Multiply (возведения в квадрат и умножения). Его можно использовать даже при вычислениях с очень большими числами.</p>
15
<p>Например, нам нужно рассчитать результат вычисления некоторого числа, возведённого в степень с показателем из 2000 бит, состоящего из 600 или более цифр, по модулю другого 2000-битного числа.</p>
15
<p>Например, нам нужно рассчитать результат вычисления некоторого числа, возведённого в степень с показателем из 2000 бит, состоящего из 600 или более цифр, по модулю другого 2000-битного числа.</p>
16
<p>Это невероятно большие числа, и если проводить вычисления последовательно: сначала возводить исходное значение в степень, а потом вычислять результат по модулю - то это потребует больших ресурсов процессора и займёт много времени. Но с помощью алгоритма Square & Multiply время вычисления можно значительно сократить.</p>
16
<p>Это невероятно большие числа, и если проводить вычисления последовательно: сначала возводить исходное значение в степень, а потом вычислять результат по модулю - то это потребует больших ресурсов процессора и займёт много времени. Но с помощью алгоритма Square & Multiply время вычисления можно значительно сократить.</p>
17
<p>Напомним, что вычисление по модулю означает, что 23373 нужно последовательно делить на 747, пока остаток не будет меньше 747 (напомню, это всё числа из задачи Паркера). В итоге такая операция похожа на часы.</p>
17
<p>Напомним, что вычисление по модулю означает, что 23373 нужно последовательно делить на 747, пока остаток не будет меньше 747 (напомню, это всё числа из задачи Паркера). В итоге такая операция похожа на часы.</p>
18
<em>Кадр: Computerphile / YouTube</em><p>Вы прокручиваете стрелки до 12, а потом опять начинаете с 1, 2, 3. Но в нашем случае делений на циферблате будет намного больше.</p>
18
<em>Кадр: Computerphile / YouTube</em><p>Вы прокручиваете стрелки до 12, а потом опять начинаете с 1, 2, 3. Но в нашем случае делений на циферблате будет намного больше.</p>
19
<em>Кадр: Computerphile / YouTube</em><p>Даже если не брать операцию с модулем, то возвести 23 в степень 373 очень сложно. Чтобы ускорить вычисление, применим алгоритм Square & Multiply.</p>
19
<em>Кадр: Computerphile / YouTube</em><p>Даже если не брать операцию с модулем, то возвести 23 в степень 373 очень сложно. Чтобы ускорить вычисление, применим алгоритм Square & Multiply.</p>
20
<p>Сначала рассмотрим его на простом примере - вычислим 28.</p>
20
<p>Сначала рассмотрим его на простом примере - вычислим 28.</p>
21
<p>Мы можем произвести семь операций умножения:</p>
21
<p>Мы можем произвести семь операций умножения:</p>
22
<p>2 × 2 × 2 × 2 × 2 × 2 × 2 × 2</p>
22
<p>2 × 2 × 2 × 2 × 2 × 2 × 2 × 2</p>
23
<p>Но можно пойти другим путём:</p>
23
<p>Но можно пойти другим путём:</p>
24
<p>2 × 2 = 22</p>
24
<p>2 × 2 = 22</p>
25
<p>(22) × (22) = 24</p>
25
<p>(22) × (22) = 24</p>
26
<p>(24) × (24) = 28</p>
26
<p>(24) × (24) = 28</p>
27
<p>Прекрасно - на выходе мы получили всего три операции умножения! Здесь мы возводим в квадрат не исходное число, а промежуточные значения.</p>
27
<p>Прекрасно - на выходе мы получили всего три операции умножения! Здесь мы возводим в квадрат не исходное число, а промежуточные значения.</p>
28
<p>Чтобы перейти к большим числам, рассмотрим механизм, который называется "квадрат слева направо".</p>
28
<p>Чтобы перейти к большим числам, рассмотрим механизм, который называется "квадрат слева направо".</p>
29
<p>Идея состоит в том, чтобы представить показатель степени в двоичном формате. Рассмотрим ещё один пример:</p>
29
<p>Идея состоит в том, чтобы представить показатель степени в двоичном формате. Рассмотрим ещё один пример:</p>
30
<p>345 mod 7</p>
30
<p>345 mod 7</p>
31
<p>Пример достаточно необычный. Сначала нужно вычислить огромное промежуточное значение 345, от которого в итоге по mod 7 получим маленькое число от 0 до 6.</p>
31
<p>Пример достаточно необычный. Сначала нужно вычислить огромное промежуточное значение 345, от которого в итоге по mod 7 получим маленькое число от 0 до 6.</p>
32
<p>Переведём показатель степени 45 в двоичную систему счисления:</p>
32
<p>Переведём показатель степени 45 в двоичную систему счисления:</p>
33
<p>101101</p>
33
<p>101101</p>
34
<p>Теперь нам нужно определить, чему равно 3101101.</p>
34
<p>Теперь нам нужно определить, чему равно 3101101.</p>
35
<p>Отвлечёмся от конкретных цифр и представим, что нам нужно возвести в квадрат y1 (показатель степени записан в двоичном формате).</p>
35
<p>Отвлечёмся от конкретных цифр и представим, что нам нужно возвести в квадрат y1 (показатель степени записан в двоичном формате).</p>
36
<p>Получим</p>
36
<p>Получим</p>
37
<p>(y1) × (y1) = y10 (1 + 1 = 10 в двоичной системе)</p>
37
<p>(y1) × (y1) = y10 (1 + 1 = 10 в двоичной системе)</p>
38
<p>Результат снова возведём в квадрат:</p>
38
<p>Результат снова возведём в квадрат:</p>
39
<p>(y10) × (y10) = y100 (10 + 10 = 100 в двоичной системе)</p>
39
<p>(y10) × (y10) = y100 (10 + 10 = 100 в двоичной системе)</p>
40
<p>Мы видим, что каждый раз, когда число возводится в квадрат, показатель степени сдвигается на один бит влево.</p>
40
<p>Мы видим, что каждый раз, когда число возводится в квадрат, показатель степени сдвигается на один бит влево.</p>
41
<p>Умножив результат на исходное число, получим</p>
41
<p>Умножив результат на исходное число, получим</p>
42
<p>(y100) × y = y101</p>
42
<p>(y100) × y = y101</p>
43
<p>Мы получили два правила:</p>
43
<p>Мы получили два правила:</p>
44
<ul><li>если число возводится в квадрат, к показателю степени слева "приписывается" 0;</li>
44
<ul><li>если число возводится в квадрат, к показателю степени слева "приписывается" 0;</li>
45
<li>если результат умножается на исходное число, к показателю степени прибавляется 1.</li>
45
<li>если результат умножается на исходное число, к показателю степени прибавляется 1.</li>
46
</ul><p>Используя эти правила, мы сможем воссоздать показатель степени 101101 за минимальное количество шагов. Цифры показателя будем получать слева.</p>
46
</ul><p>Используя эти правила, мы сможем воссоздать показатель степени 101101 за минимальное количество шагов. Цифры показателя будем получать слева.</p>
47
<p>Сбоку напишем код операции:</p>
47
<p>Сбоку напишем код операции:</p>
48
<ul><li>S (Square) - возведение в квадрат;</li>
48
<ul><li>S (Square) - возведение в квадрат;</li>
49
<li>M (Multiply) - умножение на исходное число.</li>
49
<li>M (Multiply) - умножение на исходное число.</li>
50
</ul>КодВ двоичном форматеВ десятичном форматеS31 × 31 = 31032S310 × 310 = 310034M3100 × 3 = 310135S3101 × 3101 = 31010310M31010 × 3 = 31011311S31011 × 31011 = 310110322S310110 × 310110 = 3101100344M3101100 × 3 = 3101101345<p>Чтобы посчитать остаток 345 mod 7, используем свойство оператора mod:</p>
50
</ul>КодВ двоичном форматеВ десятичном форматеS31 × 31 = 31032S310 × 310 = 310034M3100 × 3 = 310135S3101 × 3101 = 31010310M31010 × 3 = 31011311S31011 × 31011 = 310110322S310110 × 310110 = 3101100344M3101100 × 3 = 3101101345<p>Чтобы посчитать остаток 345 mod 7, используем свойство оператора mod:</p>
51
<p>(a × b) mod n = [(a mod n) × (b mod n)] mod n</p>
51
<p>(a × b) mod n = [(a mod n) × (b mod n)] mod n</p>
52
<p>Это означает, что мы можем не вычислять результат каждой операции S или M, а найти остатки по модулю каждого сомножителя, перемножить их и применить к произведению операцию mod.</p>
52
<p>Это означает, что мы можем не вычислять результат каждой операции S или M, а найти остатки по модулю каждого сомножителя, перемножить их и применить к произведению операцию mod.</p>
53
<p>В результате получим:</p>
53
<p>В результате получим:</p>
54
КодВ двоичном формате<strong>mod 7</strong>S31 × 31 = 3103 × 3 mod 7 = 2S310 × 310 = 31002 × 2 mod 7 = 4M3100 × 3 = 31014 × 3 mod 7 = 5S3101 × 3101 = 310105 × 5 mod 7 = 4M31010 × 3 = 310114 × 3 mod 7 = 5S31011 × 31011 = 3101105 × 5 mod 7 = 4S310110 × 310110 = 31011004 × 4 mod 7 = 2M3101100 × 3 = 31011012 × 3 mod 7 = 6<p>Используя алгоритм Square & Multiply, мы легко посчитали, что 345 mod 7 = 6. Для этого нам не пришлось 45 раз перемножать тройки, чтобы вычислить огромное-огромное промежуточное число - 3 в 45-й степени. Это очень полезно для криптографии.</p>
54
КодВ двоичном формате<strong>mod 7</strong>S31 × 31 = 3103 × 3 mod 7 = 2S310 × 310 = 31002 × 2 mod 7 = 4M3100 × 3 = 31014 × 3 mod 7 = 5S3101 × 3101 = 310105 × 5 mod 7 = 4M31010 × 3 = 310114 × 3 mod 7 = 5S31011 × 31011 = 3101105 × 5 mod 7 = 4S310110 × 310110 = 31011004 × 4 mod 7 = 2M3101100 × 3 = 31011012 × 3 mod 7 = 6<p>Используя алгоритм Square & Multiply, мы легко посчитали, что 345 mod 7 = 6. Для этого нам не пришлось 45 раз перемножать тройки, чтобы вычислить огромное-огромное промежуточное число - 3 в 45-й степени. Это очень полезно для криптографии.</p>
55
<em>Кадр: Computerphile / YouTube</em><p>Вернёмся к нашему первому примеру 23373 mod 747. Показатель степени 373 в двоичном формате будет равен 101110101. Это большое число, и мы не будем применять к нему весь алгоритм Square & Multiply. Распишем коды операций возведения в квадрат и умножения.</p>
55
<em>Кадр: Computerphile / YouTube</em><p>Вернёмся к нашему первому примеру 23373 mod 747. Показатель степени 373 в двоичном формате будет равен 101110101. Это большое число, и мы не будем применять к нему весь алгоритм Square & Multiply. Распишем коды операций возведения в квадрат и умножения.</p>
56
S10232S100234M101235S10102310M10112311S101102322M101112323S1011102346S10111002392M10111012393S1011101023186S10111010023372M10111010123373<p>Если расписать, как в предыдущем примере, все операции S и M и вычислить результаты по mod 747 (без калькулятора здесь не обойтись), то конечный результат будет равен 131.</p>
56
S10232S100234M101235S10102310M10112311S101102322M101112323S1011102346S10111002392M10111012393S1011101023186S10111010023372M10111010123373<p>Если расписать, как в предыдущем примере, все операции S и M и вычислить результаты по mod 747 (без калькулятора здесь не обойтись), то конечный результат будет равен 131.</p>
57
<p>Количество операций здесь - 13. Мы видим, что оно зависит от показателя степени. Для каждого нуля промежуточное значение возводится в квадрат, а для единицы - возводится в квадрат и умножается на исходное значение. Получается, чем больше единиц, тем больше операций.</p>
57
<p>Количество операций здесь - 13. Мы видим, что оно зависит от показателя степени. Для каждого нуля промежуточное значение возводится в квадрат, а для единицы - возводится в квадрат и умножается на исходное значение. Получается, чем больше единиц, тем больше операций.</p>
58
<p>Теперь рассмотрим простое число 65537. Его используют в качестве экспоненты в открытых ключах большинства сертификатов RSA. Например, когда сервер выдаёт вам сертификат, открытый ключ обычно состоит из числа 65537 и какого-то полупростого числа n.</p>
58
<p>Теперь рассмотрим простое число 65537. Его используют в качестве экспоненты в открытых ключах большинства сертификатов RSA. Например, когда сервер выдаёт вам сертификат, открытый ключ обычно состоит из числа 65537 и какого-то полупростого числа n.</p>
59
<p>Почему так? Дело в том, что 65537 - это число Ферма, которое можно представить как 216 + 1. В двоичной системе счисления оно равно:</p>
59
<p>Почему так? Дело в том, что 65537 - это число Ферма, которое можно представить как 216 + 1. В двоичной системе счисления оно равно:</p>
60
<p>100000000000000001 (две единицы, а между ними 16 нулей).</p>
60
<p>100000000000000001 (две единицы, а между ними 16 нулей).</p>
61
-
<p>При проверке электронной подписи, помимо проверки заполнения и множества других веще��, компьютер вычисляет какое-то сообщение, или его хеш, или его представление в таком виде:</p>
61
+
<p>При проверке электронной подписи, помимо проверки заполнения и множества других вещей, компьютер вычисляет какое-то сообщение, или его хеш, или его представление в таком виде:</p>
62
<p>h(m)65537</p>
62
<p>h(m)65537</p>
63
<p>Вычисление будет выполняться достаточно быстро, так как в двоичном представлении числа 65537 почти нет единиц. Вычисляется множество квадратов, и только в конце производится одно умножение. Подобная проверка осуществляется каждый раз, когда вы заходите на веб-сайт.</p>
63
<p>Вычисление будет выполняться достаточно быстро, так как в двоичном представлении числа 65537 почти нет единиц. Вычисляется множество квадратов, и только в конце производится одно умножение. Подобная проверка осуществляется каждый раз, когда вы заходите на веб-сайт.</p>
64
<p>Но здесь я хочу добавить, что скорость проверки зависит не только от открытого, но и от закрытого ключа, который в RSA используется для расшифровки данных. А в нём количество нулей и единиц может быть каким угодно. Тем не менее использование числа 65537 в открытом ключе ускоряет вычисление и экономит ресурсы компьютеров.</p>
64
<p>Но здесь я хочу добавить, что скорость проверки зависит не только от открытого, но и от закрытого ключа, который в RSA используется для расшифровки данных. А в нём количество нулей и единиц может быть каким угодно. Тем не менее использование числа 65537 в открытом ключе ускоряет вычисление и экономит ресурсы компьютеров.</p>