воскресенье, 17 июля 2022 г.

Полезные и эффективные алгоритмы для эллиптической кривой secp256k1

 


В этой статье мы рассмотрим несколько полезных и эффективных алгоритмов для эллиптической кривой E над полем GF(p) , заданной коротким уравнением Вейерштрасса

у^2 = х^3 + Ах + В 

  •  Алгоритм генерации точки на кривой E

  •  Алгоритм добавления точек

  •  Алгоритм удвоения точек

  •  Алгоритм нахождения целой кратной точки

  •  Алгоритм нахождения целой кратной точки (скалярное умножение)

  •  Алгоритм построения делителя D над кривой E с носителем supp(D) заданного размера d

  •  Алгоритм Миллера для вычисления значения функции Вейля n, P по делителю D такому, что supp(D) ∩ {P, O} = ∅

  •  Pairing Weil (Спаривание Вейля)

Модульные операции (целые числа) в конечном поле (или поле Галуа)

  1. x mod n означает «остаток n от деления x». Другими словами, если x = an + b и a, b ∈ integer, а также 0 ≤ b ≤ n − 1, то x mod n = b .

  2. Обратное : если ax = 1 mod n , то a является обратным значением x mod n . Есть два популярных метода решения :• Метод 1 : Попробуйте каждое значение для a < n, пока xa mod n = 1 .• Метод 2 : евклидов метод, который обычно используется для решения обратной задачи больших целых чисел, поэтому рекомендуется использовать метод 1 для решения обратной задачи малых целых чисел.

Операция с точками эллиптической кривой

Точка P(x 0 , y 0 ) на эллиптической кривой E означает: ее координаты 0 и 0 являются элементами поля, а координаты 0 и 0 удовлетворяют уравнению.

  1. Добавление точек на эллиптической кривой : пусть P, Q и R будут тремя точками на эллиптической кривой. Добавление очков P + Q = R.

  2. Удвоение точек на эллиптической кривой : пусть P, Q — две точки на эллиптической кривой. Удвоение очков P + P = 2P = Q

  3. Скалярное умножение : пусть P будет точкой на кривой E , определенной в уравнении

    • Скалярное умножение nP определяется как nP = P + P + P + … + P ( n раз), где n — целое число; nP также является точкой на той же кривой E .

    • Минимальное натуральное число a при aP = O называется порядком P .

    • Скалярное умножение широко требуется в криптосистемах с эллиптическими кривыми.

Делитель

Divisor (Делитель) D на кривой E — это удобный способ обозначить мультимножество точек на E , записанное в виде формальной суммы

  • Множество всех делителей на E обозначается Div F q (E) и образует группу, в которой сложение делителей естественно.

  • Делитель нуля: это делитель для всех n P = 0, делитель нуля 0 ∈ Div F q (E) .

  • Если поле q не является конкретным, его можно опустить и просто записать как Div(E) для обозначения группы делителей.

Делитель функции f на E

Делитель функции f на E используется для обозначения точек пересечения (и их кратностей) функций f и E .

Pairing Weil

Спаривание Вейля, которое обозначается m , принимает на вход пару точек P, Q ∈ E[m] и дает на выходе корень _m из единицы m( P , Q) . Билинейность спаривания Вейля выражается уравнениями

m (P 1 + P 2 , Q) = e m (P 1 , Q) * e m (P2, В),

m (P, Q 1 + Q 2 ) = e m (P, Q 1 ) * e m (P, Q 2 ).

Пара Вейля P и Q — это количество

где S ∈ E — любая точка, удовлетворяющая условию S ∉ {O, P, −Q, P − Q} . (Это гарантирует, что все величины в правой части определены и отличны от нуля.) Можно проверить, что значение m (P,Q) не зависит от выбора P , Q и S .

Эффективный алгоритм вычисления спаривания Вейля

Пусть E — эллиптическая кривая, и пусть P = (x P ,y P ) и Q = (x Q , y Q ) — ненулевые точки на E .

Пусть λ будет наклоном линии, соединяющей P и Q , или наклоном касательной к E в P, если P = Q. (Если линия вертикальна, мы полагаем λ = ∞.) Определим функцию g P, Q на E следующим образом:

затем

div(g P, Q ) = [P] + [Q] — [P + Q] — [ O ].

Алгоритм Миллера

Пусть m ≥ и запишите двоичное расширение m как

m = m 0 + m 1 * 2 + m 2 * 2 2 +···+ m n — 1 2 n — 1

при i ∈ {0, 1} и n — 1 ≠ 0 . Следующий алгоритм возвращает функцию P , делитель которой удовлетворяет условию

div( P ) = m [ P ] — [ mP ] — ( m — 1 ) [ O ],

где функции T, T и T, P, используемые алгоритмом, определены в (a).

В частности, если P ∈ E[m] , то div( P ) = m [ P ] − m [ O ].

Требование

  • Python 3.5

  • numpy

git clone https://github.com/demining/CryptoDeepTools.git

cd CryptoDeepTools/04AlgorithmsForSecp256k/

pip3 install numpy
├── Curves.py             <- Набор данных эллиптических кривых
├── Divisor.py            <- Создать делитель
├── EllipticCurve.py      <- Классы эллиптической кривой и точки на эллиптической кривой
├── EuclideanAlg.py       <- Расширенный алгоритм Евклида
├── Helper.py             <- Вспомогательные функции (обратные биты, мощность по модулю) 
├── Pairing.py            <- Спаривания Вейля, а так же Алгоритм Миллера
├── Tests.py              <- Модульные тесты для функций
├── Tonelli_ShanksAlg.py  <- Алгоритм Тонелли – Шенкса
├── main.py               <- main

Исходный код

Telegram: https://t.me/cryptodeeptech

Видеоматериал: https://youtu.be/gFbiBCNPsFk

Источник: https://cryptodeep.ru/algorithms-for-secp256k/


 


вторник, 5 июля 2022 г.

Как конвертировать публичные ключи Bitcoin-PUBKEY HEX в Bitcoin-адрес Base58 и проверить баланс на наличие монет BTC

 



В этой статье мы научимся тому, как в большом количестве данных проверить баланс монет Биткоина используя для этого Python-скрипт bitcoin-checker.py

Результат проверки Python-скрипта bitcoin-checker.py
Результат проверки Python-скрипта bitcoin-checker.py


Так же мы научимся конвертировать публичный ключ Биткоина PUBKEY (HEX) в Биткойн Адрес (Base58) всю эту большую работу делает Python-скрипт pubtoaddr.py

В итоге мы с особой легкостью будем проверять баланс Биткоина, сканируя Блокчейн в терминале Google Colab [TerminalGoogleColab]

Ранее я записывал видеоинструкцию: «TERMINAL в Google Colab создаем все удобства для работ в GITHUB»

Давайте перейдем в репозиторию «CryptoDeepTools» и разберем в детали работу Bash-скрипта:getbalance.sh

Команды
Команды
Файлы
Файлы
Код нашего Bash-скрипта: getbalance.sh
Код нашего Bash-скрипта: getbalance.sh
grep 'PUBKEY = ' signatures.json > pubkeyall.json

Утилита grep собирает все публичные ключи в один общий файл: pubkeyall.json

sort -u pubkeyall.json > pubkey.json

Утилита sort сортирует и удаляет дубли отбирает уникальные публичные ключи и результат сохраняет в файл: pubkey.json

rm pubkeyall.json

Утилита rm удаляет pubkeyall.json

sed -i 's/PUBKEY = //g' pubkey.json

Утилита sed стирает префикс PUBKEY =

python3 pubtoaddr.py

Запускаем Python-скрипт pubtoaddr.py конвертируем из файла pubkey.json где хранятся наши публичные ключи Биткоина PUBKEY (HEX) в файл addresses.json результат сохранится как Биткойн Адреса (Base58)

import hashlib
import base58
 
def hash160(hex_str):
    sha = hashlib.sha256()
    rip = hashlib.new('ripemd160')
    sha.update(hex_str)
    rip.update(sha.digest())
    return rip.hexdigest()  # .hexdigest() is hex ASCII
 
 
pub_keys = open('pubkey.json', 'r', encoding='utf-8')
new_file = open('addresses.json', 'a', encoding='utf-8')
compress_pubkey = False
 
for pub_key in pub_keys:
    pub_key = pub_key.replace('\n', '')
    if compress_pubkey:
        if (ord(bytearray.fromhex(pub_key[-2:])) % 2 == 0):
            pubkey_compressed = '02'
        else:
            pubkey_compressed = '03'
        pubkey_compressed += pub_key[2:66]
        hex_str = bytearray.fromhex(pubkey_compressed)
    else:
        hex_str = bytearray.fromhex(pub_key)
 
 
    key_hash = '00' + hash160(hex_str)
 
 
    sha = hashlib.sha256()
    sha.update(bytearray.fromhex(key_hash))
    checksum = sha.digest()
    sha = hashlib.sha256()
    sha.update(checksum)
    checksum = sha.hexdigest()[0:8]
 
#   new_file.write("" + (base58.b58encode(bytes(bytearray.fromhex(key_hash + checksum)))).decode('utf-8'))
    new_file.write((base58.b58encode(bytes(bytearray.fromhex(key_hash + checksum)))).decode('utf-8') + "\n")
pub_keys.close()
new_file.close()

Мы получили файл addresses.json теперь проверим баланс монет Биткоина используя для этого Python-скрипт bitcoin-checker.py

Запускаем Python-скриптpython2 bitcoin-checker.py

import sys
import re
from time import sleep

try:    # if is python3
    from urllib.request import urlopen
except: # if is python2
    from urllib2 import urlopen


def check_balance(address):

    #Modify the value of the variable below to False if you do not want Bell Sound when the Software finds balance.
    SONG_BELL = True

    #Add time different of 0 if you need more security on the checks
    WARN_WAIT_TIME = 0

    blockchain_tags_json = [ 
        'total_received',
        'final_balance',
        ]

    SATOSHIS_PER_BTC = 1e+8

    check_address = address

    parse_address_structure = re.match(r' *([a-zA-Z1-9]{1,34})', check_address)
    if ( parse_address_structure is not None ):
        check_address = parse_address_structure.group(1)
    else:
        print( "\nThis Bitcoin Address is invalid" + check_address )
        exit(1)

    #Read info from Blockchain about the Address
    reading_state=1
    while (reading_state):
        try:
            htmlfile = urlopen("https://blockchain.info/address/%s?format=json" % check_address, timeout = 10)
            htmltext = htmlfile.read().decode('utf-8')
            reading_state  = 0
        except:
            reading_state+=1
            print( "Checking... " + str(reading_state) )
            sleep(60*reading_state)

    print( "\nBitcoin Address = " + check_address )

    blockchain_info_array = []
    tag = ''
    try:
        for tag in blockchain_tags_json:
            blockchain_info_array.append (
                float( re.search( r'%s":(\d+),' % tag, htmltext ).group(1) ) )
    except:
        print( "Error '%s'." % tag );
        exit(1)

    for i, btc_tokens in enumerate(blockchain_info_array):

        sys.stdout.write ("%s \t= " % blockchain_tags_json[i])
        if btc_tokens > 0.0:
            print( "%.8f Bitcoin" % (btc_tokens/SATOSHIS_PER_BTC) );
        else:
            print( "0 Bitcoin" );

        if (SONG_BELL and blockchain_tags_json[i] == 'final_balance' and btc_tokens > 0.0): 
            
            #If you have a balance greater than 0 you will hear the bell
            sys.stdout.write ('\a\a\a')
            sys.stdout.flush()

            arq1.write("Bitcoin Address: %s" % check_address)
            arq1.write("\t Balance: %.8f Bitcoin" % (btc_tokens/SATOSHIS_PER_BTC))
            arq1.write("\n")
            arq1.close()
            if (WARN_WAIT_TIME > 0):
                sleep(WARN_WAIT_TIME)

#Add the filename of your list of Bitcoin Addresses for check all.
with open("addresses.json") as file:
    for line in file:

    	arq1 = open('balance.json', 'a')
        address = str.strip(line)
        print ("__________________________________________________\n")
        
        check_balance(address)
print "__________________________________________________\n"
arq1.close()

В итоге результат сохранится в файле: balance.json

Файл: balance.json
Файл: balance.json

Теперь мы научились:

  • Конвертировать публичные ключи Биткоина PUBKEY (HEX) в Биткойн Адрес (Base58)

  • Проверять все Биткойн Адреса (Base58) на наличие монет Биткоина

  • Применить это для криптоанализа

Исходный код: https://github.com/demining/CryptoDeepTools/tree/main/03CheckBitcoinAddressBalance

Telegram: https://t.me/cryptodeeptech

Видеоматериал: https://youtu.be/Hsk6QIzb7oY

Источник: https://cryptodeep.ru/check-bitcoin-address-balance

Структурные аномалии базовых точек эллиптических кривых secpXXXk1: криптоанализ Биткоина и практическое моделирование в Google Colab

  Crypto Deep Tech В данной статье в качестве криптоанализа Биткоина разберём вычислительный научный эксперимент, воспроизводящий и расширяю...