Od pomysłu do realizacji: modyfikujemy istniejący schemat cyfrowego podpisu na krzywej eliptycznej, aby stał się on deterministyczny, a na jego podstawie zapewniamy funkcje generowania zweryfikowanych w ramach blockchaina pseudolosowych liczb.

Idea
Jesienią 2018 roku w blockchainie Waves zostały , natychmiast pojawiło się pytanie o możliwość uzyskania , którym można ufać.
Zastanawiając się nad tym problemem, doszedłem do ostatecznego wniosku: każdy blockchain to klatka, uzyskanie zaufanego źródła entropii w zamkniętym systemie jest niemożliwe.
Jednak jedna idea przypadła mi do gustu: jeśli będzie podpisywał dane użytkownika w sposób deterministyczny, to użytkownik zawsze będzie mógł zweryfikować taki podpis za pomocą klucza publicznego i będzie pewny, że uzyskana wartość jest unikalna. Oracle przy całym dążeniu nie jest w stanie niczego zmienić, algorytm generuje jednoznaczny wynik. W istocie użytkownik zapisuje wynik, ale nie wie go, dopóki oracle go nie opublikuje. Oznacza to, że można w ogóle nie ufać oracle'owi, ale weryfikować wynik jego pracy. Wtedy, w przypadku pomyślnej weryfikacji, taki podpis można uznać za źródło entropii dla pseudolosowej liczby.
W platformie blockchain Waves używana jest schemat podpisu wariant . W tym schemacie podpis składa się z wartości R i S, gdzie R zależy od wartości losowej, a S obliczane jest na podstawie podpisywanej wiadomości, klucza prywatnego i tej samej wartości losowej, co R. Oznacza to, że nie ma jednoznacznej zależności, dla tej samej wiadomości użytkownika istnieje wiele ważnych podpisów.
Jasne jest, że w czystej postaci taki podpis nie może być używany jako źródło pseudolosowych liczb, ponieważ jest niedeterministyczny i, w konsekwencji, może być łatwo poddany manipulacjom ze strony oracle'a.
Jednak, jak się okazało, można go uczynić deterministycznym.
Pokładałem w nim wielkie nadzieje , ale po zapoznaniu się z materiałem musieliśmy porzucić ten wariant. Choć VRF oferuje deterministyczną wersję podpisu i jego dowodu, w algorytmie występuje dziwny element, który otwiera czarną dziurę dla manipulacji ze strony orakula. Mianowicie, przy obliczaniu wartości k () używany jest klucz prywatny, który pozostaje nieznany użytkownikowi, co oznacza, że użytkownik nie może zweryfikować poprawności obliczenia k, więc orakul może używać dowolnej potrzebnej mu wartości k, prowadząc jednocześnie bazę danych odpowiadających wartości k i podpisywanych danych, aby zawsze móc ponownie obliczyć poprawny według VRF wynik. Jeżeli zobaczycie losowanie oparte na VRF bez ujawnienia klucza prywatnego, możecie się popisać: wskazać na konieczność ujawnienia klucza albo wykluczenia go z obliczenia k, a wtedy klucz prywatny automatycznie ujawni się przy pierwszym podpisie. W ogóle, jak już powiedziano, to dziwna metoda dla losowego orakula.
Po chwili refleksji i wsparciu lokalnych analityków, powstała koncepcja działania VECRO.
VECRO to skrót od Verifiable Elliptic Curve Random Oracle, co po polsku oznacza weryfikowalny losowy orakul na krzywych eliptycznych.
Okazało się, że to dość proste, aby osiągnąć deterministyczność, należy ustalić wartość R przed pojawieniem się podpisywanej wiadomości. Jeśli R jest ustalone i jest częścią podpisywanej wiadomości, co dodatkowo gwarantuje ustalenie R w samej podpisywanej wiadomości, wartość S jest jednoznacznie determinowana przez wiadomość użytkownika i w związku z tym może być użyta jako źródło do generowania pseudolosowych liczb.
W takiej koncepcji nie ma znaczenia, w jaki sposób ustala się R, to pozostaje w gestii orakula. Ważne, że S jest jednoznacznie określona przez użytkownika, ale jej wartość pozostaje nieznana, dopóki orakul jej nie opublikuje. Wszystko tak, jak chcieliśmy!
Mówiąc o ustalonym R, zwróćcie uwagę, że Podczas podpisywania różnych wiadomości zdecydowanie ujawnia klucz prywatny w schemacie EdDSA. Dla właściciela orakula niezwykle ważne jest wykluczenie możliwości ponownego wykorzystania R do podpisywania różnych wiadomości użytkownika. Oznacza to, że przy jakichkolwiek manipulacjach lub zmowach orakul zawsze będzie narażony na utratę swojego klucza prywatnego.
W sumie orakul powinien oferować użytkownikom dwie funkcje: inicjalizację, która rejestruje wartość R, oraz podpis, który zwraca wartość S. Para R, S jest zwykłym weryfikowalnym podpisem wiadomości użytkownika zawierającego ustaloną wartość R i dowolne dane użytkownika.
Można by zaprotestować, że ten schemat dla blockchaina jest niczym innym jak zwykłą . W zasadzie tak, to jest to. Ale istnieje kilka niuansów. Po pierwsze, orakul zawsze działa z tą samą parą kluczy we wszystkich operacjach, na przykład jest to wygodne w użyciu w kontraktach. Po drugie, istnieje ryzyko utraty klucza prywatnego przez orakula przy niewłaściwym zachowaniu, na przykład, jeśli orakul pozwala na próbki wyniku, wystarczy zrobić tylko dwie próbki, aby poznać klucz prywatny i uzyskać pełny dostęp do portfela. Po trzecie, natywnie weryfikowalny w blockchainie podpis, który jest źródłem losowości — to jest piękne.
Pol roku idea realizacji dojrzewała w mojej głowie, aż w końcu pojawiła się motywacja w postaci . Z dużym grantem wiąże się duża odpowiedzialność, oznacza to, że projekt ma być!
Realizacja
Zatem w tym projekcie na blockchainie Waves w trybie zapytanie-odpowiedź za pomocą transakcji transferowych między użytkownikiem a orakulem. Na koncie orakula znajduje się skrypt, który ściśle kontroluje działanie zgodnie z opisaną powyżej logiką. Transakcje orakula są weryfikowane z odzyskaniem całego łańcucha interakcji z użytkownikiem. W weryfikacji finalnej wartości uczestniczą wszystkie cztery transakcje, smart kontrakt łączy je na ściśle weryfikacyjnej nici, krok po kroku sprawdzając wszystkie wartości i nie pozostawiając miejsca na jakiekolwiek manipulacje.
Jeszcze raz, aby zapadło w pamięć i było jaśniejsze. Orakul nie działa po prostu według zaproponowanego schematu. Jego działanie jest całkowicie kontrolowane na poziomie blockchaina. . Krok w lewo, a transakcja po prostu nie przejdzie. Więc jeśli transakcja trafiła do blockchaina, użytkownik nie musi nawet nic sprawdzać, wszystko już zostało zweryfikowane przez setki węzłów w sieci.
Obecnie w głównej sieci Waves uruchomiono jeden VECRO (możesz uruchomić swój, to nie jest trudne, wystarczy ). Aktualny kod działa na PHP (na , o którym ).
Aby skorzystać z usługi orakula, należy:
- Zarejestrować R;
- Wysłać minimum 0.005 Waves na alias orakula init@vecr;
- Otrzymać R-code w polu attachment w transferze 1 R-vecr tokena od orakula do użytkownika;
- Otrzymać podpis;
- Wysłać minimum 0.005 Waves na alias orakula random@vecr oraz KONIECZNIE wskazać wcześniej otrzymany R-code w polu attachment i dodatkowe dane użytkownika;
- Otrzymać S-code w polu attachment w transferze 1 S-vecr tokena od orakula do użytkownika;
- Użyć S-code jako źródła pseudolosowej liczby.
Zasady obecnej realizacji:
- Wysłane do orakula Waves są wykorzystywane jako opłata za zwrotną transakcję do użytkownika, maksymalnie do 1 Waves;
- R-code to konkatencja bajtu znaku 'R' i 32-bajtowej wartości R w kodowaniu base58;
- R-code w załączniku powinien być pierwszy, dane użytkownika idą po R-code;
- S-code to konkatencja bajtu znaku 'S' i 32-bajtowej wartości S w kodowaniu base58;
- S jest wynikiem dzielenia modulo, dlatego nie można używać S jako pełnoprawnej 256-bitowej liczby pseudolosowej (ta liczba może być traktowana maksymalnie jako 252-bitowa liczba pseudolosowa);
- Najprostszą opcją jest użyć hasha S-code jako pseudolosowej liczby.
Przykład uzyskania S-code:
- Inicjalizacja:
- Uzyskiwanie R-code:
- Zapytanie o wynik podpisu R-code i danych użytkownika 'random':
- Uzyskiwanie S-code:
Z technicznego punktu widzenia orakula jest w pełni gotowe do pracy, możesz śmiało z niego korzystać. Z perspektywy zwykłego użytkownika brakuje wygodnego graficznego interfejsu, na to trzeba będzie poczekać.
Chętnie odpowiem na pytania i przyjmę uwagi, dziękuję.
Źródło: habr.com
