Nano Hash - криптовалюты, майнинг, программирование

Как это решить с помощью z3?

Я только недавно начал писать сценарии с использованием z3 , только для задач CTF.

for ( i = 0; i <= 7; ++i )
{
   s2[i] += s2[i] % 10;
   if ( s2[i] > 123 )
     s2[i] = -100 - s2[i];
}
strcmp("H0Tf00D:<", s2)

Это довольно простая логика, которую можно сделать даже вручную. Но так как я изучаю z3 , то я задумался, можно ли это сделать с помощью z3 или нет.

Я проделал некоторую домашнюю работу по условиям if с использованием z3 и немногое нашел о .

Вот некоторые из вещей, которые я изучил:

  1. Z3 Prover Github
  2. rise4fun — руководство
  3. z3-how-to-encode-if-the- еще-в-z3-питоне
  4. z3py-tutorial - ericpony Github

P.S. Мне не нужно решение, я просто хочу знать, можно ли это сделать с помощью z3 или нет, и если да, то укажите мне правильное направление.

Обновление1

Я продвинулся так много (хотя это ничего):

from z3 import *

s1 = Int('s[1]')
s2 = Int('s[2]')
s3 = Int('s[3]')
s4 = Int('s[4]')
s5 = Int('s[5]')
s6 = Int('s[6]')
s7 = Int('s[7]')

s = Solver()

a = "H0Tf00D:<"
24.10.2017

  • В общем, подход заключается в выполнении полного loop unrolling, а затем для каждого присвоения значения переменной location объявляйте новую новую переменную, которая принимает новое значение, например, var = var + 1; var += 2 становится var_1 = var_0 + 1 && var_2 = var_1 + 2. Однако, глядя на операции со строками в z3, это похоже на переход от String в Int и обратно излишне сложно (?). Поэтому я бы закодировал проблему, используя либо Array of Ints, либо просто набор Ints, интерпретируемых как ячейки памяти. 24.10.2017

Ответы:


1

Учитывая, что прошло некоторое время, я предполагаю, что уместно опубликовать (одно потенциальное) решение на случай, если люди найдут это в будущем:

from z3 import *

def get_decoded(target):
    """
    Helper function to "decode" a target string using Z3
    """

    #
    # We create a Z3 array for the contents of the string (this saves
    # needing have multiple copies of the "s[i]" variables.
    #
    # However, this could be less efficient, but this isn't a concern for this
    # puzzle
    #
    string = Array("string", BitVecSort(32), BitVecSort(32))

    #
    # We save a copy of the string as the "initial" string, as we need to
    # interrogate the string _before_ the updates are made
    #    
    initial_string = string

    #
    # Create a Z3 solver
    #
    s = Solver()

    #
    # We now iterate over the length of the "target" string, and construct the
    # encoding as per the CTF instance
    #
    for idx in range(len(target)):
        #
        # Extract the single character at "idx" from the target string
        #
        single_c = target[idx]

        #
        # Find its ASCII value
        #
        ord_val = ord(single_c)

        #
        # Generate the corresponding Z3 constant
        #
        ord_const = BitVecVal(ord_val, 32)

        #
        # Generate the cell position as a Z3 constant
        #
        cell_pos = BitVecVal(idx, 32)

        #
        # Calculate the non-conditional part of the update
        #
        add_rem = string[cell_pos] + SRem(string[cell_pos], 10)

        #
        # Calculate the conditional part of the update using a Z3 If
        #
        to_store = If(add_rem > 123, -100 - add_rem, add_rem)

        #
        # Update the string with our calculated value
        #
        string = Store(string, idx, to_store)

        #
        # Assert that our calculated position is equal to the input value
        #
        s.add(string[cell_pos] == BitVecVal(ord_val, 32))

    #
    # Check the SMT instance and obtain the model
    #
    assert s.check() == sat
    model = s.model()

    #
    # We now interrogate the model to find out what the "original" string was
    #
    output = []

    #
    # Output string is the same length as the input string
    #
    for idx in range(len(target)):
        #
        # As before, calculate the cell position
        #
        cell_pos = BitVecVal(idx, 32)

        #
        # Extract the value for the index in the string
        #
        model_val = model.eval(initial_string[cell_pos]).as_signed_long()

        #
        # Get the ASCII value (we've stored the ASCII integer value, not the
        # char!)
        #
        model_char = chr(model_val)

        #
        # Append it to our output string
        #
        output.append(model_char)

    #
    # Return the joined string
    #
    return "".join(output)


def get_encoded(value):
    """
    Helper function to "encode" a string using Python
    """

    output = []

    #
    # Iterate over the input string
    #
    for idx in range(len(value)):
        #
        # Value at position (as ASCII int)
        #
        ord_val = ord(value[idx])

        #
        # Value we're going to store
        #  
        to_store = ord_val + ord_val % 10

        #
        # Conditional check
        #
        if to_store > 123:

            #
            # As per the CTF
            #
            to_store = -100 - to_store

        #
        # Add it to the output string
        #
        output.append(chr(to_store))

    #
    # Return it
    #
    return "".join(output)


if __name__ == "__main__":
    """
    Entry point
    """

    #
    # String we're aiming for
    #
    target = "H0Tf00D:<"
    print "Target:                   \"{:s}\"".format(target)

    #
    # Calculate the "reverse" using Z3
    #
    decoded = get_decoded(target)
    print "Decoded (via z3):         \"{:s}\"".format(decoded)

    #
    # We now re-encode
    #
    encoded = get_encoded(decoded)
    print "Encoded (via Python):     \"{:s}\"".format(encoded)

    #
    # Both strings should be equal
    #
    assert encoded == target

# EOF
17.02.2018
Новые материалы

Кластеризация: более глубокий взгляд
Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

Как написать эффективное резюме
Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

Частный метод Python: улучшение инкапсуляции и безопасности
Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

Как я автоматизирую тестирование с помощью Jest
Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..


© 2024 nano-hash.ru, Nano Hash - криптовалюты, майнинг, программирование