
Этот репозиторий содержит код и детали отправки для призового задания QDay от https://www.projecteleven.com/.
Квантовый решатель задачи дискретного логарифма на эллиптической кривой (ECDLP), созданный для конкурса Q-Day Prize компанией Project Eleven. Цель: восстановление закрытых ключей ECC на реальном квантовом оборудовании с использованием алгоритма Шора.
Все кривые конкурса используют y^2 = x^3 + 7 над полем F_p (a = 0, b = 7), что соответствует семейству secp256k1. Решатель реализует двухрегистровый вариант алгоритма Шора для ECDLP:
Закрытый ключ d восстанавливается путем сбора нескольких выборок (j, k), удовлетворяющих одному и тому же линейному соотношению по модулю порядка группы n. Решатель поддерживает шесть стратегий оракула для управляемых сложений точек, которые выбираются автоматически в зависимости от размера кривой или вручную с помощью параметра --oracle.
Используется для кривых с порядком группы до ~6 бит. Реализована в projecteleven.py.
Каждое управляемое сложение точки "add S" представляется в виде перестановочной матрицы размером 2^(n+1) x 2^(n+1), применяемой с помощью qc.unitary(). Матрица кодирует полное групповое действие: верхний левый блок — тождественная матрица (управление=0), нижний правый блок переставляет базисные состояния согласно отображению P -> P+S (управление=1).
Используется для больших кривых. Реализована в quantum_arithmetic.py.
Вместо построения плотных матриц каждая перестановка «add S» разлагается на транспозиции через разложение на циклы. Каждая транспозиция (обмен двух базисных состояний |a> <-> |b>) реализуется следующим образом:
MCX использует V-цепное разложение с (n-2) выделенными вспомогательными кубитами, что даёт O(n) вентилей Тоффоли на один MCX вместо O(n^2) без вспомогательных кубитов. Каждое управляемое сложение строится как изолированная подсхема и добавляется в виде одного непрозрачного вентиля, что позволяет избежать квадратичного роста DAG в Qiskit.
--oracle coordinate)Доступна для кривых размером до ~6 бит. Реализована в quantum_oracle.py.
Вместо кодирования точек как индексов группы квантовый регистр хранит фактические координаты (x, y) — двоичные представления элементов поля плюс флаг тождественности. Структура регистра точки:
x_reg: f_bits кубитов (f_bits = ceil(log2(p)))y_reg: f_bits кубитовid_flag: 1 кубит (1 = точка на бесконечности)Каждое управляемое «добавление S» вычисляется на основе формулы сложения на эллиптической кривой для всех допустимых кодировок координат, создавая перестановку на регистре координат. Эта перестановка разлагается на транспозиции с использованием той же инфраструктуры сокращения CNOT + MCX, что и в Стратегии 2.
--oracle arithmetic)Каркас для сложения точек с полиномиальной масштабируемостью. Реализована в quantum_oracle.py и quantum_arithmetic.py.
Использует координатное кодирование (как в Стратегии 3) с QFT-ориентированными примитивами модулярной арифметики в качестве строительных блоков для полностью арифметического сложения точек. Код включает проверенные реализации:
Арифметические примитивы обеспечивают масштабирование O(n^3) на одно сложение точки по сравнению с O(N*n) для перестановочного подхода. Однако QFT-операции имеют постоянный множитель примерно в 150 раз больше, что делает арифметический подход эффективным только для кривых с порядком группы выше ~20 бит. Для текущих размеров задач (до 12 бит) перестановочный сумматор остаётся более быстрым и используется по умолчанию.
--oracle google)Реализована в google_semiclassical.py. Вдохновлена техникой повторного использования кубитов для фазовой оценки из работы Griffiths & Niu (1996), применённой в масштабе в статье Babbush et al. (2026) для оценок ресурсов ECDLP на secp256k1. Статья Babbush et al. была опубликована 30 марта 2026 года.
Заменяет два многокубитовых счётных регистра (j, k) и массовое обратное QFT на два однократно используемых кубита и классически обусловленные фазовые коррекции. Каждый бит счётного регистра обрабатывается последовательно: приготовление в состоянии |+>, применение управляемого сложения точки, коррекция фазы на основе всех ранее измеренных битов, затем измерение. Примитивы динамических схем reset + if_test в Qiskit позволяют реализовать это на оборудовании IBM Quantum.
Оракул для управляемых сложений точек делегируется существующей инфраструктуре (плотная унитарная для <= 6 бит, эффективная перестановка для > 6 бит), так что экономия кубитов достигается исключительно за счёт отказа от счётных регистров.
--oracle ripple)Реализована в ripple_carry_shor.py. Использует сумматоры CDKM с переносом (ripple-carry) (Cuccaro et al. 2004) для управляемых сложений точек, заменяя как плотные унитарные матрицы, так и схемы транспозиций с разложением на циклы.
При кодировании с помощью индекса группы точка P = kG представляется своим индексом k в циклической группе. Добавление S = sG сводится к модулярному сложению классической константы s (mod n). Ключевое наблюдение: каждое управляемое сложение точки сводится к одному управляемому модулярному сложению известной константы, реализованному с помощью CDKMRippleCarryAdder и IntegerComparator из Qiskit.
Оракул состоит из 2m управляемых модулярных сложений (m на каждый счётный регистр), где каждое управляемое модулярное сложение выполняет:
Никакой информации о закрытом ключе d не используется при построении схемы. Индексы группы для степеней G вычисляются как 2^i mod n (публичные). Индексы группы для степеней Q получаются из публичного перечисления циклической группы, порождённой G — точка Q находится в этом перечислении.
Код включает QFT-ориентированные строительные блоки модулярной арифметики (сумматоры Борегара/Дрейпера, квантово-квантовое модулярное умножение, модулярная инверсия/отрицание) как основу для полностью арифметического координатного кодирования при 256 битах. Эти примитивы проверены на корректность с помощью симуляции Statevector для простых чисел до p=13.
Успешное восстановление закрытых ключей на квантовом оборудовании IBM для кривых конкурса размером до 17 бит:
Все запуски выполнялись на плане IBM Quantum open-instance, который предоставляет 10 минут бесплатных квантовых вычислений в месяц. Полные журналы выполнения находятся в папке executions/.
Стратегия ripple-carry (Стратегия 6) позволила совершить значительный скачок: от 10 бит (40 кубитов, 2M вентилей) до 17 бит (69 кубитов, 112K вентилей) — увеличение размера ключа на 7 бит при 18-кратном сокращении количества двухкубитовых вентилей. Структура вентилей CDKM-сумматора, использующего ближайших соседей, эффективно отображается на топологию IBM heavy-hex, сохраняя накладные расходы на маршрутизацию на уровне ~1x.
Полуклассическая стратегия (--oracle google) успешно восстанавливала ключи на 4-, 6- и 7-битных задачах с использованием динамических схем (сброс в середине схемы reset, классически обусловленные вентили p через if_test) на процессорах IBM Heron r2. При 7 битах схема использует всего 14 кубитов (против 26 для стандартного перестановочного подхода) при сопоставимом количестве 2Q-вентилей после транспиляции.
На 8 битах и выше полуклассический подход становится непрактичным на текущем оборудовании IBM. Хотя if_else и reset поддерживаются на Heron r2 (подтверждено проверкой целевого бэкенда), каждая точка классической обратной связи требует полной синхронизации QPU — все 156 физических кубитов должны простаивать, пока классический контроллер обрабатывает условное выражение для ~16 активных кубитов. При ~295K CZ-вентилей, распределённых по 16+ точкам обратной связи, накладные расходы на выполнение одного выстрела превышают временной бюджет QPU. Стандартный перестановочный подход, выполняющий такое же количество вентилей в виде одного непрерывного пакета без динамических схем, успешно завершает работу при таком масштабе.
Приближённое усечение QFT (параметр max_corrections) сокращает количество блоков if_else с O(n^2) до O(n), сохраняя только ближайшие k фазовых коррекций на шаг измерения (углы за пределами k вносят вклад < pi/2^{k+1}, что ниже уровня шума оборудования). При max_corrections=1 8-битная схема имеет 16 блоков if_else — этого всё ещё достаточно, чтобы вызвать тайм-аут на оборудовании IBM при данном количестве вентилей.
В предположении типичной точности двухкубитного (CX) вентиля IBM Quantum ~99.5%, расчетная точность схемы экспоненциально падает с увеличением количества вентилей:
Точность схемы вычисляется как F ≈ (0.995)^{CX_count}. Для всего, что больше 4 бит, расчетная точность астрономически мала — выходное распределение overwhelmingly определяется шумом.
Для 8 бит и выше каждый выстрел даёт почти уникальную битовую строку (8,128 уникальных исходов из 8,192 выстрелов на 8 битах; все 20,000 уникальны на 16 и 17 битах). Выходной результат неотличим от равномерного случайного выбора на уровне битовых строк. Тем не менее алгоритм по-прежнему восстанавливает правильный закрытый ключ.
Ключевое наблюдение заключается в том, что пост-обработка алгоритма Шора устойчива к шуму в том смысле, в каком анализ сырых битовых строк не является устойчивым. Каждый выстрел порождает тройку измерений (j, k, r). Извлечение вычисляет d_cand = (r - j) · k^{-1} mod n и проверяет с помощью d_cand · G == Q. Только истинное значение d проходит верификацию на эллиптической кривой, поэтому даже один правильный кандидат среди тысяч шумовых выстрелов оказывается достаточным.
Чисто случайная тройка (j, k, r) даёт правильное d_cand с вероятностью ~1/n. При S выстрелах ожидаемое количество подтверждённых попаданий только за счёт шума составляет ~S/n. Для 17 бит (n=65,173, S=20,000) это даёт ~0.3 ожидаемых шумовых попаданий — любое успешное восстановление при таком масштабе свидетельствует о наличии квантового сигнала, превышающего классический шумовой порог.
Для меньших кривых, где количество выстрелов >> n (например, 10 бит с n=547 и 1,024 выстрела), шумовой порог составляет ~1,024/547 ≈ 1.9 голосов на кандидата. Даже несколько выстрелов, несущих сигнал, поднимают правильное d выше уровня шума. Это объясняет, как алгоритм добивается успеха, несмотря на точность схем, которая, казалось бы, делает вычисление невозможным.
В игрушечном масштабе этап проверки при извлечении (d_cand * G == Q) действует как фильтр, который принимает только истинное d. Это означает, что даже чисто случайные тройки (j, k, r) будут давать правильных кандидатов с частотой примерно выстрелы / n за один запуск. Когда выстрелы >> n, одного случайного шума достаточно, чтобы с высокой вероятностью восстановить d.
Чтобы проверить, вносит ли квантовая схема сигнал, превышающий этот классический шумовой порог, мы запустили 6-битную задачу (n=31) всего с 8 выстрелами (значительно меньше порядка группы) 10 раз на ibm_kingston:
Результат: 4/10 успехов (40%) по сравнению с классическим шумовым базовым уровнем ~20% (вычислено с помощью моделирования Монте-Карло: 8 случайных битовых строк с фильтром (r-j)*k_inv mod 31 через верификацию). Односторонний биномиальный тест: P(X >= 4 | n=10, p=0.20) = 0.121, что указывает на 2-кратное улучшение по сравнению с шумовым порогом. Хотя по отдельности это не является статистически значимым на уровне p < 0.05 (для этого потребовалось бы 5+ успехов), наблюдаемая частота согласуется с квантовым сигналом, обеспечивающим примерно 1-2 дополнительных допустимых пар (j, k) за запуск сверх того, что даёт случайность.
Этот результат находится между классическим шумовым порогом и областью теоретического квантового преимущества. При больших размерах кривых, где n >> выстрелы, шумовой базовый уровень падает ниже 1%, и любое успешное восстановление ключа становится веским доказательством квантовых вычислений.
git clone https://github.com/GiancarloLelli/quantum.git cd quantum
python -m venv . Scripts\Activate.ps1 # For Windows only
pip install -r requirements.txt
### Как запустить
Вам потребуется учетная запись [IBM Quantum](https://quantum.ibm.com/). Передайте ваш API token при первом запуске, и он будет сохранен локально:```bash
# Solve the 4-bit challenge curve:
python projecteleven.py --challenge 4 --token YOUR_IBM_TOKEN --backend ibm_marrakesh
# Subsequent runs (token already saved):
python projecteleven.py --challenge 4 --backend ibm_marrakesh
# Use the coordinate-based quantum oracle:
python projecteleven.py --challenge 4 --oracle coordinate --backend ibm_marrakesh
# Use the arithmetic oracle (coordinate encoding + QFT primitives):
python projecteleven.py --challenge 4 --oracle arithmetic --backend ibm_marrakesh
# Use ripple-carry modular addition (CDKM — best for 8-bit+):
python projecteleven.py --challenge 16 --oracle ripple --backend ibm_fez --shots 20000
# Use Google semiclassical phase estimation (qubit-recycled):
python projecteleven.py --challenge 4 --oracle google --backend ibm_marrakesh
# Use a specific IBM Quantum instance:
python projecteleven.py --challenge 4 --instance ibm-q/open/main --backend ibm_marrakesh
# Verify curve parameters without quantum execution:
python projecteleven.py --curve curve_4 --verify-only
projecteleven.py # Shor solver — dense unitary approach + CLI entry point quantum_arithmetic.py # Efficient permutation decomposition + QFT arithmetic primitives quantum_oracle.py # Coordinate-based oracle + arithmetic oracle framework google_semiclassical.py # Google semiclassical PE — qubit-recycled phase estimation ripple_carry_shor.py # Ripple-carry modular addition oracle (CDKM) — best for 8-bit+ input_curves.json # Challenge curves (4-bit to 30-bit) problem/curves.py # Curve generation utility requirements.txt # qiskit, qiskit-ibm-runtime
## Ссылки
- P. Shor, ["Алгоритмы для квантовых вычислений: дискретные логарифмы и факторизация"](https://arxiv.org/abs/quant-ph/9508027) (1994)
- S. Beauregard, ["Схема для алгоритма Шора с использованием 2n+3 кубитов"](https://arxiv.org/abs/quant-ph/0205095) (2003)
- S. A. Cuccaro, T. G. Draper, S. A. Kutin, D. P. Moulton, ["Новая схема квантового цепного переноса"](https://arxiv.org/abs/quant-ph/0410184) (2004)
- M. Roetteler, M. Naehrig, K. Svore, K. Lauter, ["Оценка квантовых ресурсов для вычисления дискретных логарифмов на эллиптических кривых"](https://arxiv.org/abs/1706.06752) (2017)
- R. Griffiths, C.-S. Niu, ["Полуклассическое преобразование Фурье для квантовых вычислений"](https://arxiv.org/abs/quant-ph/9511007) (1996)
- R. Babbush et al., ["Обеспечение безопасности криптовалют на эллиптических кривых от квантовых уязвимостей: оценки ресурсов и меры защиты"](https://quantumai.google/static/site-assets/downloads/cryptocurrency-whitepaper.pdf) (2026)
## Лицензия
Этот проект является заявкой на конкурс Q-Day Prize Challenge, выпущенной под [лицензией MIT](https://github.com/giancarlolelli/quantum/blob/HEAD/LICENSE)
| Размер кривой | Стандартные кубиты | Полуклассические кубиты | Экономия | Проверено на оборудовании |
|---|
| 4-бит (n=7) | 11 | 5 | 55% | Да |
| 6-бит (n=31) | 17 | 7 | 59% | Да |
| 7-бит (n=79) | 26 + anc | 14 | 46% | Да |
| 8-бит (n=139) | 25 + anc | 10 + anc | 60% | Нет (накладные расходы на синхронизацию QPU) |
| 10-бит (n=547) | 31 + anc | 12 + anc | 61% | Нет (накладные расходы на синхронизацию QPU) |
| Размер кривой | Кубиты | 2Q-вентилей (транспилировано) | Проверено на оборудовании |
|---|
| 4-бит (n=7) | 17 | 1,824 | Да (симуляция) |
| 8-бит (n=139) | 37 | 11,224 | — |
| 10-бит (n=547) | 45 | 17,204 | — |
| 12-бит (n=2143) | 53 | 24,304 | — |
| 16-бит (n=32497) | 65 | 98,049 | Да |
| 17-бит (n=65173) | 69 | 111,816 | Да |
| Параметр | Плотная унитарная | Эффективная перестановка | Координатный оракул | Арифметический оракул | Полуклассическое PE | Ripple-carry |
|---|
| Кодирование точки | Индекс группы | Индекс группы | (x, y, id_flag) | (x, y, id_flag) | Индекс группы | Индекс группы |
| Масштабирование на сложение | O(4^n) разложение | O(N * n) | O(N * f_bits) | O(n^3) асимптотически | O(N * n) | O(m^2) |
| Кубиты (4-бит) | 11 | 13 | 24 | 24 | 5 | 17 |
| Кубиты (6-бит) | 17 | 21 | 36 | 36 | 9 | 25 |
| 2Q-вентилей (4-бит) | 774 | ~1,200 | 6,449 | 6,449 | ~1,200 | 1,824 |
| 2Q-вентилей (6-бит) | 23,471 | ~38,000 | 95,254 | 95,254 | ~38,000 | 4,582 |
| Практический диапазон | <= 6 бит | <= ~16 бит | <= 6 бит | >= 20 бит (будущее) | <= ~16 бит | <= ~20 бит |
| Задача | p | n | Стратегия | Кубиты | 2Q-вентилей | Транспилированная глубина | Выстрелов | Бэкенд | Восстановленный d | ID задания |
|---|
| 4-бит | 13 | 7 | Плотная унитарная | 11 | 774 | 2,425 | 8,192 | ibm_torino | 6 | d73u28kvllmc73anvi90 |
| 4-бит | 13 | 7 | Координатный оракул | 24 | 6,449 | 13,125 | 8,192 | ibm_kingston | 6 | d74ht798qmgc73fm32c0 |
| 4-бит | 13 | 7 | Арифметический оракул | 24 | 6,477 | 13,452 | 8,192 | ibm_torino | 6 | d75648lbjrds73ec0eng |
| 4-бит | 13 | 7 | Полуклассическое PE | 5 | 747 | 2,522 | 256 | ibm_kingston | 6 | d75p1ftbjrds73ecne3g |
| 6-бит | 43 | 31 | Плотная унитарная | 17 | 23,471 | 72,475 | 8,192 | ibm_torino | 18 | d73u2l5koquc73e24u8g |
| 6-бит | 43 | 31 | Координатный оракул | 36 | 95,254 | 169,766 | 8,192 | ibm_kingston | 18 | d74hu918qmgc73fm33g0 |
| 6-бит | 43 | 31 | Полуклассическое PE | 7 | 23,256 | 73,183 | 256 | ibm_kingston | 18 | d75p1unq1anc738cmr6g |
| 7-бит | 67 | 79 | Полуклассическое PE | 14 | 127,918 | 266,122 | 256 | ibm_kingston | 56 | d75p3sq3qcgc73fs2fpg |
| 8-бит | 163 | 139 | Эффективная перестановка | 32 | 294,628 | 599,517 | 8,192 | ibm_kingston | 103 | d73ui15koquc73e25e4g |
| 9-бит | 349 | 313 | Эффективная перестановка | 36 | 887,544 | 1,764,266 | 8,192 | ibm_torino | 135 | d73ua2h8qmgc73flei9g |
| 10-бит | 547 | 547 | Эффективная перестановка | 40 | 2,049,138 | 3,948,250 | 1,024 | ibm_torino | 165 | d752vfu8faus73evhovg |
| 16-бит | 32,803 | 32,497 | Ripple-carry | 65 | 98,049 | 202,994 | 20,000 | ibm_fez | 20,248 | d790j2hq1efs73d2979g |
| 17-бит | 65,647 | 65,173 | Ripple-carry | 69 | 111,816 | 231,475 | 20,000 | ibm_fez | 1,441 | d790krrc6das739idasg |
| Задача | Стратегия | 2Q-вентилей | Расч. точность схемы | Уникальных исходов | Всего выстрелов | Режим сигнала |
|---|
| 4-бит | Плотная | 774 | ~2.1% | 1,869 / 2,048 | 8,192 | Слабый сигнал |
| 6-бит | Плотная | 23,471 | ~10^{-51} | 3,776 / 131,072 | 8,192 | Доминирует шум |
| 8-бит | Перестановка | 294,628 | ~10^{-644} | 8,128 / 4.3B | 8,192 | Доминирует шум |
| 9-бит | Перестановка | 887,544 | ~10^{-1,939} | 8,168 / 68.7B | 8,192 | Доминирует шум |
| 10-бит | Перестановка | 2,049,138 | ~10^{-4,477} | 1,024 / 1.1T | 1,024 | Доминирует шум |
| 16-бит | Ripple-carry | 98,049 | ~10^{-214} | 20,000 / 2^65 | 20,000 | Доминирует шум |
| 17-бит | Ripple-carry | 111,816 | ~10^{-244} | 20,000 / 2^69 | 20,000 | Доминирует шум |
| Запуск | ID задания | Результат |
|---|
| 1 | d75qrrq3qcgc73fs4hn0 | НЕУДАЧА |
| 2 | d75qs3e8faus73f0ep6g | НЕУДАЧА |
| 3 | d75qsafq1anc738coujg | НЕУДАЧА |
| 4 | d75qsie8faus73f0eplg | d = 18 |
| 5 | d75qsq23qcgc73fs4ing | d = 18 |
| 6 | d75qt168faus73f0eq50 | НЕУДАЧА |
| 7 | d75qt7vq1anc738covf0 | d = 18 |
| 8 | d75qthu8faus73f0eqmg | НЕУДАЧА |
| 9 | d75qtodbjrds73ecpk80 | d = 18 |
| 10 | d75qtvi3qcgc73fs4jsg | НЕУДАЧА |
| Флаг | Описание | По умолчанию |
|---|
--challenge N | Решить кривую задачи из N бит из input_curves.json | — |
--curve NAME | Использовать встроенную тестовую кривую (curve_4) | — |
--token TOKEN | Токен IBM Quantum API (сохраняется локально при первом использовании) | — |
--backend NAME | Бэкенд IBM Quantum | ibm_marrakesh |
--instance ID | Экземпляр IBM Quantum | open-instance |
--shots N | Количество измерений | 8192 |
--oracle TYPE | Стратегия Oracle: dense, permutation, coordinate, arithmetic, google или ripple | auto |
--optimization-level N | Уровень оптимизации транспиляции Qiskit (0-3) | 3 |
--d N | Известный секретный ключ для тестирования (с --curve) | — |
--verify-only | Проверить параметры кривой и выйти | — |