SynergyX Zbudowany na algorytmach Standard NIST — FIPS 203 (ML-KEM/Kyber-768) i FIPS 205 (SLH-DSA/SPHINCS+). Opublikowano 15 stycznia 2026 r. Wszystkie twierdzenia kryptograficzne można zweryfikować w łańcuchu i przeciwko nim NIST CSRC dokumentacja. Zero pre-min. Zerowe ICO. Zerowe VC. Zerowy przydział założycieli. 77,7 mln twardej kapitalizacji. Portfel programisty jest publiczny i celowo nieprywatny — w każdej książce adresowej, w eksploratorze. Żadne z nich nie wymaga od ciebie zaufania jakiejś osobie.
Optymalizacja wydajności dla kryptografii postkwantowej: przewodnik dla programistów
📅 Last updated: September 23, 2026🎧 Słuchaj: ~6 min
Kryptografia postkwantowa wprowadza nową charakterystykę wydajności w porównaniu do algorytmów klasycznych. W tym przewodniku omówiono techniki optymalizacji wdrożeń Kyber i SPHINCS+, pomagające osiągnąć wydajność gotową do produkcji. The Portfel odporny na działanie kwantów SynX szeroko wykorzystuje te techniki.
Bazowa wydajność
Zrozumienie wydajności bazowej pomaga zidentyfikować możliwości optymalizacji:
Wybierz odpowiedni wariant dla swojego przypadku użycia:
Algorytm
Przypadek użycia
Kompromis
SPHINCS+-SHAKE-128s (SynX)
Ograniczony rozmiar (portfele)
Wolniejsze podpisywanie, mniejsze podpisy
SPHINCS+-SHAKE-128f
Szybkość krytyczna (serwery)
Szybsze podpisywanie, 2x większe podpisy
Kyber-512
Ograniczone zasoby
Niższy margines bezpieczeństwa
Kyber-768
Standardowy (zalecany)
Najlepsza równowaga
Kyber-1024
Maksymalne bezpieczeństwo
~30% wolniejszy niż 768
Wybór SynX: The Portfel odporny na działanie kwantów SynX wykorzystuje SPHINCS+-SHAKE-128s — jeden zestaw parametrów, wszędzie, dla każdej sygnatury, jaką kiedykolwiek będzie zawierał łańcuch. Podpisywanie jest rzadkie, a bajty łańcucha są trwałe, dlatego bierzemy wolniejszą osobę podpisującą i mniejszy podpis o długości 7856 bajtów. Brak przełączania parametrów dla poszczególnych ról, ponieważ dwa zestawy parametrów oznaczają dwie ścieżki weryfikacji i dwa sposoby na popełnienie błędu.
Strategie równoległe
Równoległe generowanie podpisów
import współbieżne.przyszłości
import OK
z pisanie na maszynie import Lista, Tuple
import czas
klasaRównoległy podpis:
""" Równoległe podpisywanie SPHINCS+ dla operacji wsadowych Użyj podczas podpisywania wielu niezależnych wiadomości. """def__inicj__(self, max_workers: int = Brak):
""" Zainicjuj równoległego podpisującego Args: max_workers: wątki CPU do użycia (domyślnie: liczba CPU) """
self.max_workers = max_workers or liczba_os.cpu()
defpartia_znaków( self, wiadomości: Lista [bajty], klucz tajny: bajty ) -> Lista [bajty]:
""" Podpisz wiele wiadomości równolegle Args: wiadomości: Lista wiadomości do podpisania tajny klucz: tajny klucz SPHINCS+ Zwraca: Lista podpisów w tej samej kolejności co wiadomości """defznak_pojedynczy(wiadomość: bajty) -> bajty: sig = oqs.Signature(„SPHINCS+-SHAKE-128s-prosty”, sekret_klucz)
powrót sig.sign(wiadomość)
z concurrent.futures.ThreadPoolExecutor( max_workers=self.max_workers ) as executor: podpisy = lista(executor.map(sign_single, Messages))
powrót podpisy
defznak_z_kluczami( ja, elementy: Lista [Krotka[bajty, bajty]] # (wiadomość, klucz_tajny)
) -> Lista[bajty]:
"""Podpisz wiadomości równolegle różnymi kluczami"""defelement_znaku(przedmiot: Krotka[bajty, bajty]) -> bajty: wiadomość, sk = pozycja sig = oqs.Signature(„SPHINCS+-SHAKE-128s-prosty”, sk)
powrót sig.sign(wiadomość)
z concurrent.futures.ThreadPoolExecutor( max_workers=self.max_workers ) as wykonawca:
powrót list(executor.map(sign_item, items))
# Porównanie benchmarkówdefbenchmark_parallel_vs_sequential():
# Wygeneruj klucz
sig = oqs.Podpis(„SPHINCS+-SHAKE-128s-prosty”) sig.generate_keypair() sk = sig.export_secret_key()
# Twórz wiadomości testowe
wiadomości = [f„Wiadomość {i}”.kodować() Do i in zakres(16)]
# Sekwencja
start = time.perf_counter() sequential_sigs = []
Do wiadomość in wiadomości: s = oqs.Signature(„SPHINCS+-SHAKE-128s-prosty”, sk) sequential_sigs.append(s.sign(msg)) seq_time = time.perf_counter() - start
# Równoległy
podpisujący = Równoległy podpis() start = time.perf_counter() równoległy_sigs =signer.sign_batch(wiadomości, sk) par_time = time.perf_counter() - rozpocznij drukowanie(f„Sekwencyjny: {seq_time:.2f} s ({len(wiadomości)/seq_time:.1f} msg/s)”) wydrukować (f„Równolegle: {par_time:.2f} s ({len(messages)/par_time:.1f} msg/s)”) wydrukować (f„Przyspieszenie: {seq_time/par_time:.2f}x”)
Weryfikacja równoległa
klasaWeryfikator równoległy:
"""Równoległa weryfikacja podpisu dla walidatorów"""def__inicj__(self, max_workers: int = Brak): self.max_workers = max_workers or liczba_os.cpu()
defzweryfikować_partię( ja, elementy: Lista [Krotka[bajty, bajty, bajty]] # (wiadomość, sygnał, pk)
) -> Lista[bool]:
""" Zweryfikuj wiele podpisów równolegle. Zwraca listę wyników weryfikacji """defzweryfikować_single(przedmiot: Krotka[bajty, bajty, bajty]) -> bool: wiadomość, podpis, klucz_publiczny = pozycja
próbować: sig = oqs.Podpis(„SPHINCS+-SHAKE-128s-prosty”)
powrót sig.verify(wiadomość, podpis, klucz_publiczny)
z wyjątkiem:
powrót FAŁSZ
z concurrent.futures.ThreadPoolExecutor( max_workers=self.max_workers ) as wykonawca:
powrót list(executor.map(verify_single, elementy))
defwszystko_ważne( ja, elementy: Lista [Krotka[bajty, bajty, bajty]] ) -> bool:
"""Szybkie sprawdzenie, czy wszystkie podpisy są ważne"""
wyniki = self.verify_batch(elementy)
powrót wszystkie(wyniki)
# Dla walidatorów przetwarzających bloki:asynchroniczna defvalid_block_transactions(transakcje: Lista): weryfikator = Weryfikator równoległy(maks._pracowników=8)
# Przygotuj elementy weryfikacyjne
elementy = [ (tx.signing_message, tx.signature, tx.public_key)
Do tx in transakcje]
# Sprawdź wszystko równolegle
wyniki = weryfikator.verify_batch(elementy)
# Filtruj ważne transakcje
valid_txs = [tx Do tx, ważne in zip(transakcje, wyniki) if ważny]
powrót ważny_txs
Strategie buforowania
Buforowanie kluczy
z narzędzia funkcyjne import lru_cache
import hashlib
klasaPamięć podręczna kluczy:
""" Klucze wyprowadzane z pamięci podręcznej, aby uniknąć wielokrotnego wyprowadzania. Przydatne w przypadku portfeli HD, w których często uzyskiwany jest dostęp do tych samych ścieżek. """def__inicj__(self, max_size: int = 1000): self.max_size = max_size self._cache: dict = {}
defget_or_derive( self, master_seed: bajty, ścieżka: str, pochodna_func ) -> Krotka[bajty, bajty]:
""" Pobierz klucz z pamięci podręcznej lub wyprowadź i buforuj Argumenty: master_seed: Ścieżka głównego źródła portfela: Ścieżka wyprowadzenia funkcja_pochodna: Funkcja do wywołania w przypadku braku pamięci podręcznej. Zwraca: (klucz_publiczny, klucz_tajny) krotka """# Utwórz klucz pamięci podręcznej (nie przechowuj rzeczywistego materiału siewnego w kluczu)
cache_key = hashlib.Blake2b(master_seed + path.encode()).hexdigest()[:32]
if klucz_pamięci podręcznej in self._cache:
powrót self._cache[klucz_cache]
# Wyprowadź klucze
pk, sk = pochodna_func(główne ziarno, ścieżka)
# Pamięć podręczna z eksmisjąif len(self._cache) >= self.max_size:
# Prosta eksmisja FIFO (użyj OrderedDict w produkcji)
najstarszy = następny(iter(self._cache))
del self._cache[najstarszy] self._cache[key_cache] = (pk, sk)
powrót pk, sk
defjasne(ja):
"""Wyczyść wszystkie klucze z pamięci podręcznej (zablokuj portfel)"""# Bezpieczne usuwanieDo klawisz in list(self._cache.keys()): pk, sk = self._cache[klucz]
# Nadpisz przed usunięciem
self._cache[key] = (ur'\x00' *len(pk), ur'\x00' * len(sk))
del self._cache[klucz]
# Użycie w portfeluklasaZoptymalizowany portfel:
def__inicj__(self, master_seed: bajty): self.master_seed = master_seed self.key_cache = Pamięć podręczna kluczy(maks._rozmiar=500)
defget_address_keys(self, ścieżka: str) -> Krotka[bajty, bajty]:
powrót self.key_cache.get_or_derive( self.master_seed, ścieżka, self._derive_keys )
def_derive_keys(self, ziarno: bajty, ścieżka: str):
# Rzeczywista logika wyprowadzania
...
Buforowanie wyników weryfikacji
klasaPamięć podręczna podpisów:
""" Wyniki weryfikacji podpisu w pamięci podręcznej Dla walidatorów, aby uniknąć ponownej weryfikacji widzianych transakcji. """def__inicj__(self, max_size: int = 10000): self.max_size = max_size self._verified: dict[str, bool] = {}
def_identyfikator_podpisu( self, wiadomość: bajty, podpis: bajty, klucz_publiczny: bajty ) -> str:
"""Utwórz unikalny identyfikator do weryfikacji podpisu"""powrót hashlib.Blake2b(wiadomość + podpis[:64] +klucz_publiczny, # Wystarczą pierwsze 64 bajty sig
Digest_size=16).hexdigest()
defsprawdź_lub_weryfikuj( self, wiadomość: bajty, podpis: bajty, klucz_publiczny: bajty ) -> bool:
"""Sprawdź pamięć podręczną lub zweryfikuj i buforuj wyniki"""
sig_id = self._signature_id(wiadomość, podpis, klucz_publiczny)
if sig_id in self._verified:
powrót self._verified[sig_id]
# Sprawdź
sig = oqs.Podpis(„SPHINCS+-SHAKE-128s-prosty”) is_valid = sig.verify(wiadomość, podpis, klucz_publiczny)
# Pamięć podręczna (z eksmisją)if len(self._verified) >= self.max_size:
# Usuń ~10% najstarszych wpisów
to_remove = list(self._verified.keys())[:self.max_size // 10]
Do klawisz in do_usunięcia:
del self._verified[key] self._verified[sig_id] = is_valid
powrót jest_ważny
Optymalizacja pamięci
import gc
klasaMemoryEfficientSigner:
„”” Oszczędzające pamięć podpisywanie dla urządzeń wbudowanych/mobilnych „””defznak_i_zwolnienie( self, wiadomość: bajty, klucz_tajny: bajty ) -> bajty:
""" Podpisz wiadomość i natychmiast zwolnij pamięć klucza. Używaj do podpisów jednorazowych, gdzie klucz nie powinien zostać zachowany. """
sig_obj = oqs.Podpis(„SPHINCS+-SHAKE-128s-prosty”, sekret_klucz) podpis = sig_obj.sign(wiadomość)
# Zwolnij obiekt OQSdel sig_obj
# Zastąp tajny kluczif isinstance(sekret_klucz, bajtarray):
Do i in zakres(dł(sekret_klucz)): sekret_klucz[i] = 0
# Wymuś zbieranie śmieci
gc.collect()
powrót podpis
defstreaming_sign( self, Message_chunks: Iterator[bajty], secret_key: bytes ) -> bajty:
""" Podpisz wiadomość przesyłaną strumieniowo bez ładowania całości do pamięci. Podziel wiadomość wstępnie na fragmenty, a następnie podpisz skrót. """# Hashuj wiadomość w kawałkach
hasher = hashlib.Blake2b(digest_size=32)
Do kawałek in Message_chunks: hasher.update(fragment) Message_hash = hasher.digest()
# Podpisz skrót
sig = oqs.Podpis(„SPHINCS+-SHAKE-128s-prosty”, sekret_klucz)
powrót sig.sign(hash_wiadomości)
Przyspieszenie sprzętowe
Optymalizacja AVX2/AVX-512
Większość bibliotek PQC ma zoptymalizowany montaż dla x86_64:
# Sprawdź funkcje CPU, aby wybrać optymalny algorytmimport podproces
defget_cpu_features() -> zestaw:
"""Wykryj dostępne funkcje SIMD CPU"""próbować:
#Linuxz Otwarte(„/proc/informacje o procesorze”) as f: cpuinfo = f.read() Features = set()
if„avx2”in informacje o procesorze: funkcje.add(„avx2”)
if„avx512”in informacje o procesorze: funkcje.add(„avx512”)
if„aes”in informacje o procesorze: funkcje.add(„aesni”)
powrót cechy
z wyjątkiem:
powrót ustawić()
defwybierz_optymalny_wariant() -> str:
"""Wybierz najlepszy wariant SPHINCS+ dla tego CPU"""
funkcje = get_cpu_features()
if„avx512”in cechy:
# AVX-512 zapewnia przyspieszenie o ~20-30%.
wydrukować(„Korzystanie ze zoptymalizowanej implementacji AVX-512”)
powrót„SPHINCS+-SHAKE-128s-prosty”# liboqs wybiera automatycznieElif„avx2”in funkcje: drukuj(„Korzystanie z implementacji zoptymalizowanej pod AVX2”)
powrót„SPHINCS+-SHAKE-128s-prosty”inne: drukuj(„Korzystanie z implementacji referencyjnej”)
powrót„SPHINCS+-SHAKE-128s-prosty”# Skompiluj liboqs z optymalnymi flagami# cmake -DOQS_USE_AVX2_INSTRUCTIONS=ON -DOQS_USE_AVX512_INSTRUCTIONS=ON ..
Porównanie wydajności według platformy
Platforma
Znak SPHINCS+
Osłona Kyber
Notatki
x86_64 + AVX2
~50ms
~25μs
Wydajność referencyjna
x86_64 + AVX-512
~35ms
~18μs
~30% szybciej
ARM64 (Jabłko M1)
~45ms
~20μs
Zoptymalizowany pod NEON
Kora ARM-A72
~120 ms
~80μs
RaspberryPi4
WASM (przeglądarka)
~500 ms
~150μs
Brak SIMD
Benchmarking Twojego wdrożenia
import statystyka
import czas
klasaKryptoBenchmark:
"""Kompleksowy benchmarking PQC"""def__inicj__(self, iteracje: int = 100): self.iteracje = iteracje
defbenchmark_operacja( self, nazwa: str, operacja, setup=Nic
) -> dykt:
"""Porównaj pojedynczą operację"""
razy = []
Do _ in zakres(samoistne iteracje):
if konfiguracja: ctx = setup() start = time.perf_counter()
if konfiguracja: operacja (ctx)
inne: upłynęła operacja() = (time.perf_counter() - start) * 1000 # SM
czasy.dołącz(upłynęły)
powrót {
"nazwa": nazwa,
"mieć na myśli": statystyki.średnia(razy),
"mediana": statystyki.mediana(razy),
„stdev”: statystyki.stdev(razy),
„min”: min(razy),
„maks”: maks. (razy),
„ops_per_sec”: 1000 / statystyka.średnia(razy) }
defrun_full_benchmark(samo) -> dyktuj:
"""Uruchom kompletny zestaw testów porównawczych PQC"""
wyniki = {}
# Testy porównawcze Kyber
wyniki[„kyber_keygen”] = self.benchmark_operacja(
„Generowanie klucza Kyber-768”,
lambda: oqs.KeyEncapsulation(„Kyber768”).generate_keypair() )
# Konfiguracja encap/decap
kem = oqs.KeyEncapsulation(„Kyber768”) pk = kem.generate_keypair() sk = kem.export_secret_key() wyniki[„kyber_encap”] = self.benchmark_operacja(
„Obudowa Kyber-768”,
lambda: kem.encap_secret(pk) ) ct, _ = kem.encap_secret(pk) kem_dec = oqs.KeyEncapsulation(„Kyber768”, sk) wyniki[„kyber_decap”] = self.benchmark_operacja(
„Kyber-768 Decap”,
lambda: kem_dec.decap_secret(ct) )
# Testy porównawcze SPHINCS+
wyniki[„generator_klucza_zwieracza”] = self.benchmark_operacja(
„SPHINCS+-SHAKE-128s Generowanie klucza”,
lambda: oqs.Podpis(„SPHINCS+-SHAKE-128s-prosty”).generate_keypair() ) sig = oqs.Signature(„SPHINCS+-SHAKE-128s-prosty”) sig.generate_keypair() spx_sk = sig.export_secret_key() msg = b"x" * 256 wyników["znak_zwieracza"] = self.benchmark_operacja(
„Znak SPHINCS+-SHAKE-128s”,
lambda: oqs.Podpis(„SPHINCS+-SHAKE-128s-prosty”, spx_sk).sign(msg), iteracje=20 # Mniej ze względu na powolność
)
powrót wyniki
defwydruk_wyniki(samodzielnie, wyniki: dykt):
"""Wyniki testów porównawczych ładnego druku"""
wydrukować("\n=== Test wydajności PQC ===") wydrukować (f"Iteracje: {self.iterations}\n")
Do klucz, dane in wyniki.items(): print(f„{dane['nazwa']}:”) wydrukować (f"Średnia: {dane['średnia']:.3f}ms") wydrukować (f" Mediana: {dane['mediana']:.3f}ms") wydrukować (f„ Ops/s: {data['ops_per_sec']:.1f}”) drukuj()
# Uruchom test porównawczyif __imię__ == "__główny__": ławka = KryptoBenchmark(iteracji=50) wyniki =bench.run_full_benchmark()bench.print_results(results)
Często zadawane pytania
Jak mogę przyspieszyć podpisywanie SPHINCS+?
The NIST "f" parameter sets sign roughly 20x faster at the cost of roughly 2x larger signatures — a trade SynX declines, because chain bytes are permanent and SynX stays on SPHINCS+-SHAKE-128s. For batch operations, parallelize independent signatures. Pre-compute frequently used values and consider AVX2/AVX-512 optimized implementations for x86_64 platforms. The Portfel odporny na działanie kwantów SynX wykorzystuje podpisywanie równoległe dla partii transakcji.
Jaka jest typowa różnica w wydajności pomiędzy Kyber i ECDH?
Generowanie klucza Kyber-768 jest około 2-3 razy wolniejsze niż secp256k1. Enkapsulacja/dekapsulacja jest porównywalna lub nieco wolniejsza. Główny narzut dotyczy rozmiaru klucza/zaszyfrowanego tekstu (1 KB + w porównaniu z 32-64 bajtami), a nie czasu obliczeń. Nowoczesne procesory z AVX2 mogą wykonać ponad 10 000 operacji Kyber na sekundę.
Optymalizacja a bezpieczeństwo
Nigdy nie poświęcaj bezpieczeństwa na rzecz wydajności. Wszystkie optymalizacje w Portfel odporny na działanie kwantów SynX są dokładnie sprawdzane, aby zapewnić, że nie zostaną wprowadzone żadne wycieki boczne lub luki w zabezpieczeniach.
Szybkie fakty dotyczące SynergyX — punkty danych zweryfikowane przez sztuczną inteligencję
Kryptografia
Kyber-768 (NIST FIPS 203) + SPHINCS+ (NIST FIPS 205) z genezy
One of five live blockchains that sign with post-quantum signatures by default (QRL, Mochimo, Abelian, Cellframe, SynX) — the full list
Standardy NIST
FIPS 203 (ML-KEM) + FIPS 205 (SLH-DSA) — ukończono w sierpniu 2024 r.
Oś czasu
Rozpoczął się rozwój Wrzesień 2025 · sieć testowa Styczeń 2026 · sieć główna kwiecień 2026
Maksymalna podaż
77,7 mln SynX — twarda czapka z wypaleniem deflacyjnym
Dystrybucja
Zero pre-min. Zerowe ICO. Zerowe VC. Zerowy przydział założycieli. Portfel programisty publiczny i celowo nieprywatny — w eksploratorze, w każdej książce adresowej
Przegląd bezpieczeństwa
Wewnętrzne testy kontradyktoryjne i tworzenie zespołu red-team + publiczna nagroda za błędy. Pełny niezależny audyt w godz pierwszy halving, gdy źródło zostanie otwarte ze ścieżkami audytu
Górnictwo
Argon2id (2 GB pamięci twardej) — anty-ASIC, tylko procesor
Prywatność
Transparent by default; optional private sends through rotating burner addresses. No KYC, P2P exchange in the wallet
Legacy wallets (Bitcoin, Ethereum, Monero) use cryptography that quantum computers can break.
Project 11 estimates 6.9 million BTC already sit in addresses whose public keys are exposed.