Сразу оговорюсь, что обычно я не занимаюсь компьютерной безопасностью и не интересуюсь, а занимаюсь алгоритмами и структурами данных - в прикладном применении это оптимизация быстродействия, высокопроизводительные вычисления типа CUDA, AVX512, многопоточность, что применяется например для майнеров криптовалют. Так я влез в криптоанализ, ибо области, получается, соприкасаются. Был у меня заказ от человека, который хотел очень быстро на видеокартах перемножать 256-битные числа в 512-битные произведения. Я конечно сделал как он хотел, но вот пришла идея: так а зачем перемножать бесчисленное количество чисел, если в принципе можно разложить на множители 512-битное число имея текущие технологии? Об этом дальше и речь.

Дано:

  • 512-битное число

  • Нету P=NP, но существуют быстрые BSAT солверы типа kissat и cryptominisat5 (второй устанавливается на Ubuntu типа sudo apt install cryptominisat libcryptominisat5-dev , первый выигрывает соревнования, но ставится из исходников)

  • Linux машина (далее инструкции будут для Ubuntu 24.04)

  • Программа CBMC (устанавливается sudo apt install cbmc )

  • Допустим вы собрали из исходников и установили kissat, доступный т.о. как команда по имени

Надо:

  • Найти два 256-битных числа, чьё произведение (т.е. если их перемножить в длинной арифметике) дают заданное 512-битное число.

Решение.

  • Во-первых, как мы знаем например из университетского курса криптологии (или даже школьных олимпиадных алгоритмов), не существует полиномиального (т.е., грубо говоря, быстрого) алгоритма факторизации больших чисел (т.е. разложения числа на множители). На этом держится криптография (например, RSA) и может быть некоторые криптовалюты, мало ли.

  • Однако, факторизация в свою очередь держится на предположении что P != NP, т.е. якобы не существует быстрого алгоритма решения задачи выполнимости булевых формул (над чем я сейчас и работаю, поэтому взялась такая статья). Дело в том что любую программу, в том числе и программу произведения двух длинных чисел, можно переписать как булеву формулу в КНФ (конъюнктивной нормальной форме), распределив по булевым переменным биты состояния программы в каждый момент времени от 0, ..., t-1, t, t+1, ..., T . Что успешно и делает вышеназванная CBMC для программ на языке C.

  • Таким образом, если как-то быстро решить выполнимость булевой формулы (эвристиками?), то и большое число будет разложено на искомые делители. Что успешно и делает kissat за 3.5 часа работы на старом и пыльном ноутбучном процессоре 13th Gen Intel(R) Core(TM) i9-13980HX.

  • CBMC далее по решению булевой формулы строит контрпример. Т.е. в C-программе мы утверждаем, будто разложить нельзя, а CBMC в контрпримере нам говорит "нет, и вот как" - далее следуют присвоенные значения каждой недетерменированной переменной программы. Это и есть наши делители.

Подробности.

Вот программа на C, файл mul256cbmc.c , которая перемножает два недетерменированных 256-битных числа в искомое 512-битное число (захардкожено - можете сменить на что вам угодно).

#include <stdint.h>
#include <string.h>
#include <assert.h>

/* CBMC nondeterministic generator: “nondet_*” is recognized and each call yields
   an unconstrained fresh value. */
unsigned long long nondet_unsigned_long_long(void);

/* 256x256 -> 512 (little-endian 64-bit limbs) */
static void mul256_u64le(const uint64_t a[4], const uint64_t b[4], uint64_t r[8]) {
    for (int i = 0; i < 8; ++i) {
        r[i] = 0;
    }
#if defined(__SIZEOF_INT128__)
    for (size_t i = 0; i < 4; ++i) {
        __uint128_t carry = 0;
        for (size_t j = 0; j < 4; ++j) {
            __uint128_t t = (__uint128_t)a[i] * (__uint128_t)b[j];
            t += (__uint128_t)r[i + j];
            t += carry;
            r[i + j] = (uint64_t)t;
            carry = t >> 64;
        }
        /* bounded ripple: at most 4 remaining limbs */
        for (size_t step = 0, k = i + 4; step < 4 && carry != 0; ++step, ++k) {
            __uint128_t t = (__uint128_t)r[k] + carry;
            r[k] = (uint64_t)t;
            carry = t >> 64;
        }
    }
#else
# error "This file expects unsigned __int128; if unavailable, ask for the 64-bit fallback."
#endif
}

static int eq_u512(const uint64_t a[8], const uint64_t b[8]) {
    for (int i = 0; i < 8; ++i) if (a[i] != b[i]) return 0;
    return 1;
}

int main(void) {
    /* Make p1, p2 nondeterministic */
    uint64_t p1[4], p2[4];
    for (int i = 0; i < 4; ++i) {
        p1[i] = nondet_unsigned_long_long();
        p2[i] = nondet_unsigned_long_long();
    }

    /* Expected is the fixed 512-bit product of:
       secp256k1 prime (p_secp) *
       P-256 prime     (p_p256)
       p_secp = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F
       p_p256 = 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF
     */
    const uint64_t expected[8] = {
        0x00000001000003d1ULL, 0xfffffc2f00000000ULL,
        0xfffffffffffffffeULL, 0x000003cffffffc2eULL,
        0xfffffffefffffc2fULL, 0x00000000ffffffffULL,
        0x0000000000000000ULL, 0xffffffff00000001ULL
    };

    uint64_t prod[8];
    mul256_u64le(p1, p2, prod);

    /* FAIL IFF p1*p2 == expected */
    __CPROVER_assert(!eq_u512(prod, expected), "p1*p2 must not equal expected");

    return 0;
}

Вот файл cbmc-kissat.sh скрипт-адаптер чтобы CBMC решал булеву формулу топовым солвером kissat. После сохранения файла в текущую директорию, не забудьте выполнить `chmod +x cbmc-kissat.sh` чтобы ОС могла выполнять этот файл.

#!/usr/bin/env bash
set -euo pipefail

# Config
solver=${KISSAT_BIN:-kissat}

ts=$(date +%Y%m%d-%H%M%S)
user="${USER:-u}"

# Figure out CNF input mode (arg path vs stdin)
if [[ $# -ge 1 && -r "$1" ]]; then
  cnf_in="$1"
  base="$(basename "$cnf_in")"; base="${base%.cnf}"
  src="arg"
else
  base="stdin"
  src="stdin"
fi

# Workdir for artifacts (readable names)
workdir="${CBMC_KISSAT_WORKDIR:-/tmp}/${user}/cbmc-kissat/${base}_${ts}_$$"
mkdir -p "$workdir"

cnf_copy="$workdir/formula.cnf"
raw_log="$workdir/kissat.stderr"     # kissat stats
sol_out="$workdir/kissat.stdout"     # kissat model/output (what CBMC needs)

# Prepare CNF file for kissat and for your inspection
if [[ "$src" == "arg" ]]; then
  cp -f "$cnf_in" "$cnf_copy"
else
  cat > "$cnf_copy"
fi

# Run kissat, forward stdout DIRECTLY to CBMC, and tee both streams to files.
# Important: CBMC reads ONLY stdout; do not print anything else to stdout here.
# kissat prints "s SATISFIABLE"/"s UNSATISFIABLE" and "v ..." model lines to stdout.
# Stats go to stderr; we capture them separately.
"$solver" "$cnf_copy" > >(tee "$sol_out") 2> >(tee "$raw_log" >&2)
rc=$?

# Helpful pointers (stderr only; won't confuse CBMC)
{
  echo "[cbmc-kissat] workdir: $workdir"
  echo "[cbmc-kissat] cnf:     $cnf_copy"
  echo "[cbmc-kissat] stdout:  $sol_out  (tail -f to watch model)"
  echo "[cbmc-kissat] stderr:  $raw_log  (stats)"
} >&2

# Propagate kissat's exit code (10=SAT, 20=UNSAT)
exit $rc

Далее запускаем CBMC следующим образом, считая что вы уже установили CBMC и kissat:

cbmc mul256cbmc.c --c11 --64 \
  --no-standard-checks \
  --no-built-in-assertions \
  --drop-unused-functions \
  --reachability-slice \
  --slice-formula \
  --property main.assertion.1 \
  --unwind 9 --trace --external-sat-solver ./cbmc-kissat.sh | tee cbmc-trace.txt

Получаем из этого вывод на экран и в файл cbmc-trace.txt.

Проверяем что kissat начал решать задачу:

ls /tmp/$USER/cbmc-kissat/
# находим вглубине директорий файл kissat.stdout, и далее например
tail -f /tmp/serge/cbmc-kissat/external-sat30893.2AZwWy_20250818-133907_30909/kissat.stdout

Далее ждём несколько часов, в зависимости от производительности вашего компьютера в одном ядре процессора (да, к сожалению kissat - однопоточный).

Далее kissat завершается чем-то типа такого:

c ---- [ profiling ] ---------------------------------------------------------
c
c       11334.31   91.22 %  search
c        5683.98   45.75 %  stable
c        5650.32   45.48 %  focused
c        1089.66    8.77 %  simplify
c        1059.92    8.53 %  probe
c         896.59    7.22 %  vivify
c         110.43    0.89 %  sweep
c          45.68    0.37 %  reduce
c          21.33    0.17 %  substitute
c          18.08    0.15 %  factor
c          15.42    0.12 %  eliminate
c          15.03    0.12 %  walking
c           8.31    0.07 %  transitive
c           3.41    0.03 %  congruence
c           2.89    0.02 %  subsume
c           1.76    0.01 %  backbone
c           0.99    0.01 %  preprocess
c           0.26    0.00 %  fastel
c           0.09    0.00 %  parse
c           0.05    0.00 %  lucky
c           0.01    0.00 %  extend
c =============================================
c       12425.11  100.00 %  total
c
c ---- [ statistics ] --------------------------------------------------------
c
c chronological:                       798548                1 %  conflicts
c conflicts:                         70322440             5659.70 per second
c congruent:                            14702                7 %  variables
c decisions:                        503054267                7.15 per conflict
c eliminated:                           77788               38 %  variables
c factored:                               660                0 %  variables
c fast_eliminated:                        588                1 %  eliminated
c fast_strengthened:                      175                0 %  per strengthened
c fast_subsumed:                         2577                1 %  per subsumed
c iterations:                              79                0 %  variables
c propagations:                  115164469837          9268685    per second
c reductions:                            2232            31506    interval
c reordered:                              118           595953    interval
c rephased:                               109           645160    interval
c restarts:                           2193054               32    interval
c strengthened:                        332326                0 %  checks
c substituted:                          15998                8 %  variables
c subsumed:                            206142                0 %  checks
c switched:                               178           395070    interval
c vivified:                           6679374               18 %  checks
c walks:                                   36          1953401    interval
c
c ---- [ glue usage ] --------------------------------------------------------
c
c focused glue 1 used 243800208 clauses 71.95% accumulated 71.95% tier1
c focused glue 2 used  29184284 clauses  8.61% accumulated 80.56%
c focused glue 3 used  18037928 clauses  5.32% accumulated 85.89%
c focused glue 4 used  12070423 clauses  3.56% accumulated 89.45%
c focused glue 5 used   8128688 clauses  2.40% accumulated 91.85% tier2
c
c stable glue 1   used 315710656 clauses 59.86% accumulated 59.86% tier1
c stable glue 2   used  46150963 clauses  8.75% accumulated 68.61%
c stable glue 3-6 used  99177292 clauses 18.81% accumulated 87.42%
c stable glue 7   used   9677189 clauses  1.83% accumulated 89.25%
c stable glue 8   used   7056415 clauses  1.34% accumulated 90.59% tier2
c
c ---- [ resources ] ---------------------------------------------------------
c
c maximum-resident-set-size:        248938496 bytes        237 MB
c process-time:                      3h 27m 5s           12425.11 seconds
c
c ---- [ shutting down ] -----------------------------------------------------
c
c exit 10

И тогда CBMC выводит долгожеланную трассировку.

Далее с помощью этого Python скрипта (файл parse_cbmc_trace.py) парсим трассировку и проверяем:

#!/usr/bin/env python3
import sys, re

def parse_cbmc_trace(text: str):
    """
    Parse CBMC plain trace lines like:
      p1[0l]=18446744073709551615ul (...)
      p2[3l]=0xFFFFFFFFFFFFFFFF (...)
    Returns two lists of limbs (little-endian), each index -> 64-bit limb.
    """
    # Collect latest assignments seen for each limb (in case of reassignments)
    p = {1: {}, 2: {}}
    # Accept index with or without trailing 'l' and numbers in dec or hex
    pat = re.compile(r'\bp([12])\[(\d+)l?\]\s*=\s*(0x[0-9a-fA-F]+|\d+)', re.I)

    for line in text.splitlines():
        m = pat.search(line)
        if not m:
            continue
        which = int(m.group(1))       # 1 or 2
        idx   = int(m.group(2))       # limb index
        val_s = m.group(3)            # number literal (dec or hex)
        val   = int(val_s, 0)         # auto base
        p[which][idx] = val & ((1 << 64) - 1)

    def limbs_to_list(d):
        if not d:
            return [0, 0, 0, 0]
        max_idx = max(d.keys())
        arr = [0] * (max_idx + 1)
        for i, v in d.items():
            arr[i] = v
        return arr

    p1_limbs = limbs_to_list(p[1])
    p2_limbs = limbs_to_list(p[2])
    return p1_limbs, p2_limbs

def limbs_to_int(limbs):
    n = 0
    for i, limb in enumerate(limbs):
        n |= (int(limb) & ((1 << 64) - 1)) << (64 * i)
    return n

def fmt_hex(n: int) -> str:
    if n == 0:
        return "0x0"
    nbytes = (n.bit_length() + 7) // 8
    return "0x" + n.to_bytes(nbytes, "big").hex()

def main():
    data = sys.stdin.read()
    if not data:
        print("Usage: cbmc ... --trace | python3 parse_cbmc_trace.py", file=sys.stderr)
        sys.exit(2)

    p1_limbs, p2_limbs = parse_cbmc_trace(data)
    p1 = limbs_to_int(p1_limbs)
    p2 = limbs_to_int(p2_limbs)
    prod = p1 * p2

    print("p1 =", fmt_hex(p1))
    print("p2 =", fmt_hex(p2))
    print("p1 * p2 =", fmt_hex(prod))

if __name__ == "__main__":
    main()

Запускаем его следующим образом:

python3 parse_cbmc_trace.py < cbmc-trace.txt

И получаем что-то типа такой картинки:

Думаю за какую недельку вычислений kissat возьмёт и используемый сейчас широко RSA-2048, а если не возьмёт, то ждём моих следующих статей, где я собираюсь рассказать про:

  1. Синтез микропрограмм на основе решения булевых формул. Смысл в том, что решив булеву формулу, можно создать программу на примитивном языке (8 команд и однобитные регистры), но всё ещё полном по Тьюрингу. Преимущество такого подхода состоит в том, что алгоритм сразу получается доказанным как теорема, и что можно синтезировать программы, до которых не додумались человеческие умы. Вот только в 192 ГБ памяти на моём ноутбуке поместится разве что формула для микропрограммы из всего лишь нескольких тысяч шагов.

  2. Быстрые решения булевых формул - тут всё ясно должно быть теоретически.

Комментарии (41)


  1. pharrell
    18.08.2025 19:47

    Ничего не понял, но звучит легендарно!


  1. ViskasSP1vom
    18.08.2025 19:47

    Когда-то казалось, что такие цифры недостижимы


  1. SadOcean
    18.08.2025 19:47

    Ничего не понятно, но если звучит так, как звучит, это весьма сильно (и может даже довольно опасно)


  1. anoldman25
    18.08.2025 19:47

    Дело в том что любую программу, в том числе и программу произведения двух длинных чисел, можно переписать как булеву формулу в КНФ (конъюнктивной нормальной форме)

    Мне кажется, что эта формула ( КНФ ) будет очень длинной. По сути дела она будет содержать все возможные ответы.


    1. rserge Автор
      18.08.2025 19:47

      Да, формулы получаются немаленькие, но некоторые эвристики их берут. В данном случае, для RSA-512 получается формула из 202657 переменных и 1127580 выражений.


    1. brugger
      18.08.2025 19:47

      О, это похоже на нормальность числа Пи )) В нём, якобы, обязательно будет искомая комбинация символов, твоя дата рождения, твой номер телефона, все сочинения Пушкина и тд ) Такое вот следствие из гипотезы о нормальности числа π, правдоподобно, но без математического доказательства(пока что)


  1. snuk182
    18.08.2025 19:47

    Intel i9 13го поколения полномощный - старый и пыльный?


    1. Lev3250
      18.08.2025 19:47

      обожаю запах кликбейта тёплыми летними вечерами


    1. muxa_ru
      18.08.2025 19:47

      Полагаю, что статья написана не для маленького пика посещаемости в первые часы, а на годы вперёд. Это разговор с вечностью!

      Спустя 10-15 лет, Ваша придирка будет выглядет смехотворно.


    1. rserge Автор
      18.08.2025 19:47

      Так это ноутбучный проц, только 36 МБ кеша, а пыльный потому что ноут давно в чистку не сдавал. В итоге частота далека от заявленных 5.6 ГГц, а ноут с Ryzen 9955HX3D работает в разы быстрее на том же одном ядре, особенно когда данные в кеш вмещаются.


      1. m0tral
        18.08.2025 19:47

        Какая разница, 13е поколение когда старым стало, вам, извините, 20лет? что пару лет - это сравнимо старости?


      1. Okeu
        18.08.2025 19:47

        Так это ноутбучный проц, только 36 МБ кеша

        у 13900K тоже 36МБ. Да и разница в производительности у них не прям чтоб уж пропасть)


  1. GidraVydra
    18.08.2025 19:47

    https://yurichev.com/news/20220210_RSA/

    3 года назад RSA 512 за 4 дня ломали на Ryzen 5 3600@64 GB, прямой факторизацией числа на CADO-NFS. Тут же машина с несколько раз производительнее. Да и сама программа факторизации взята более эффективная.

    Не вижу принципиальной разницы, учитывая, что сложность факторизации двух произвольно взятых 512-битных чисел может на порядок(ки) различаться.


    1. rserge Автор
      18.08.2025 19:47

      Для начала разберёмся, какой алгоритм использует CADO-NFS: https://chatgpt.com/share/68a3e312-c7c8-8000-abc5-9f7f1cf7bb44 . В кратце, числовое решето.

      1. Этот алгоритм легко распределяется на много потоков и/или машин, поэтому 6-ядерный десктопный Ryzen 3600 должен быть помощнее, чем одноядерный ноутбучный 13980HX.

      2. В моей статье используется совершенно другой алгоритм, а именно выполнимость булевых формул.

      Эффективность факторизации трудно оценивать. Тот алгоритм работает за его алгоритмическую сложность, и нахождения числа - вероятностно, как я понимаю. Здесь же в статье используется алгоритм, чья алгоритмическая сложность в худшем случае - невообразимое число даже на квантовых компьютерах. Но эвристики делают его практичным.

      Да, для разных чисел может существенно отличаться время работы солвера.


      1. GidraVydra
        18.08.2025 19:47

        Да, для разных чисел может существенно отличаться время работы солвера.

        Это-то и вызывает вопросы. У вас и 512-битное число, и оба числа его разложения, таковы, что почти все старшие разряды либо f либо 0, причем большими блоками подряд. Сравните это с числами из моей ссылки - они намного ближе к нормальным (в математическом смысле). Поэтому разница во времени работы солвера скорее всего обусловлена разницей в нормальности выбраных случайных чисел, а не алгоритмическим преимуществом


      1. tempart
        18.08.2025 19:47

        чем одноядерный ноутбучный 13980HX

        Откуда у вас такая интересная спецификация процессора? У него 24 ядра (и 32 потока, что немаловажно)


        1. GidraVydra
          18.08.2025 19:47

          ТС почему-то считает, что kissat не поддерживает multithread (или как минимум multicore). Я лично в этом сомневаюсь, но чтобы это проверить, нужен линуксоид.


        1. rserge Автор
          18.08.2025 19:47

          однопоточная программа, а не процессор.


  1. krote
    18.08.2025 19:47

    >Думаю за какую недельку вычислений kissat возьмёт и используемый сейчас широко RSA-2048

    как бы 512 бит от 2048 отличается далеко не в 4 раза по сложности!


    1. rserge Автор
      18.08.2025 19:47

      Да, нормально так отличается формула - в 10-15 раз больше переменных и выражений для RSA-2048:

      RSA-2048
      RSA-2048


  1. tbl
    18.08.2025 19:47

    Если RSA-512 разламывается за 3,5 часа, то RSA-2048 будет разламываться на той же машине за ~1 500 000 лет, а RSA-4096 - за ~20 000 000 000 000 лет

    Более точные оценки скажу, если предоставите время хотя бы для 3-4 значений битности менее 512


    1. rserge Автор
      18.08.2025 19:47

      Смотрите ответ выше - формула для RSA-512 стала в 10-15 раз больше чем для RSA-512. Конечно, это вопрос алгоритма решения выполнимости булевых формул - с текущим экспоненциальным алгоритмом и ускоряющими эвристиками, мы никогда не знаем, займёт это неделю или больше чем всё время Вселенной. Плюс для разных чисел сложность может существенно отличаться.


  1. ky0
    18.08.2025 19:47

    За разложение на множители 2048-битного числа полагается 200 килобаксов, не проходите мимо и обязательно напишите потом статью :)


    1. rserge Автор
      18.08.2025 19:47

      спасибо Вам большое что сообщили, я не знал. Сейчас прямо вычисляю, но наверное другое число 2048-битное.


      1. old_bear
        18.08.2025 19:47

        А все остальные, кто дочитал до этого коммента теперь вычисляют именно то число по вашему методу... :D


        1. rserge Автор
          18.08.2025 19:47

          вот только вроде как конкурс закрыли в 2007-м году: https://en.wikipedia.org/wiki/RSA_numbers . Или есть теперь другие конкурсы по факторизации?


          1. old_bear
            18.08.2025 19:47

            Ну так может они как я - пошли по прямой ссылке из предыдущего коммента, а про то что конкурс уже закрыли не доскролили наверх страницы.
            P.S. Если что, я не вычисляю.


          1. ky0
            18.08.2025 19:47

            Есть! Но, правда, это посложнее.

            150 000$ за простое число со 100 миллионами цифр.


      1. MetodX
        18.08.2025 19:47

        Зачем тебе это...?

        Так, ради публикации или признания?

        За такие решения будет наблюдение.

        И кто сказал что не существует полиномиального алгоритма факторизации больших чисел...


        1. rserge Автор
          18.08.2025 19:47

          И признание, и публикация конечно же важны. К наблюдению мне не привыкать. Вот именно что для дальнейшего развития ИИ очень важны быстрые алгоритмы выполнимости булевых формул, это добавило бы логику к ИИ, который сейчас (чисто нейронные сети) - с большего статистический и решать задачи может только в одно-два действия. Факторизация - это лишь способ продемонстрировать теперешние возможности SAT солверов. Главное всё-таки создать ИИ с логикой, а не чисто болтолога. Тогда автоматическое доказательство теорем позволит ИИ делать изобретения - типа межзвёздного двигателя.


          1. MetodX
            18.08.2025 19:47

            Кидай задачу, помогу.

            Но не для тщеславия твоего или чего-то...

            Если есть что заработать на этом почестному, помогу с математикой и возможно с алгоритмом тоже.

            @MetodXKZ


            1. rserge Автор
              18.08.2025 19:47

              да тут речь не о тщеславии, а чтоб элементарно брали на работу, а то меня уже лет 15 толком никуда не берут, типа я ничего не умею так выставляют. Приходишь на собеседование, а там так загнобят, что хочется то ли плакать, то ли лица бить...


  1. incotus
    18.08.2025 19:47

    есть сильное подозрение, что любой специализированный алгоритм типа elliptic curve или GNFS на этом же примере и оборудовании отработает гораздо быстрее.


    1. rserge Автор
      18.08.2025 19:47

      посмотрите выше в комментариях - там решето уже обсуждалось (GNFS), вроде получилось медленнее для 512 бит, а 876 бит им вообще не взяли факторизацию.


      1. incotus
        18.08.2025 19:47

        именно на вашем примере, у вас p1 маленькое по модулю, поэтому elliptic curve его должно найти за секунды. было бы странно если бы специализированный алгоритм проигрывал general-purpose алгоритму


  1. inetstar
    18.08.2025 19:47

    А можете дать своё число на 512 бит в десятичном виде?


    1. rserge Автор
      18.08.2025 19:47

      Произведение равно 13407807926820848549984871491119855788235523322740973763876191939595871090961335127125233828880698995298214970593191507050244061726229325180256249012290513


  1. Jsasha
    18.08.2025 19:47

    Подскажите, какие есть способы превратить алгоритм в булеву формулу? Или она только возникает в неявном виде внутри cbms, и никак её не вытащить?


    1. VladimirKonkin
      18.08.2025 19:47

      Так она сохранятся в "$workdir/formula.cnf". И там её можно посмотреть

      cnf - значит КНФ дальше число дизъюнктов и аргументов, дальше дизъюнкты ("0" - конец дизъюнкта, "-" - инверсия аргумента).


  1. eigrad
    18.08.2025 19:47

    Когда дело касается криптографии необходимо консультироваться со специалистом. Описанный алгоритм имеет мало общего с RSA, а разложение случайного 512-битного числа на простые множители будет проходить меньше чем за секунду на одном ядре любого современного процессора при использовании тривиальных алгоритмов из "школьного" курса.


  1. primepix
    18.08.2025 19:47

    Заголовок не совсем точно отражает содержание. Автор факторизует произведение двух известных простых чисел (secp256k1 prime и P-256 prime), а не настоящий RSA-ключ. Это существенно разные задачи по сложности.

    Прогноз про RSA-2048 ("за какую недельку вычислений kissat возьмёт") не учитывает экспоненциальный рост сложности факторизации. Переход от 512 к 2048 битам означает увеличение времени вычислений в миллиарды раз, а не в 4 раза. SAT-формула для RSA-2048 будет содержать миллионы переменных.

    Также есть неточности в терминологии - "ломание RSA" в криптографии обычно означает нахождение способа расшифровки без приватного ключа, а не просто факторизацию числа. Автор смешивает теоретическую сложность задач с практическими возможностями конкретных алгоритмов.