Conturi și semnare PQC
Conturile QoreChain sunt derivate dintr-o singură frază mnemonică BIP-39. Există două modele de conturi, ambele complet suportate:
- Derivare HD per-lane (legacy/implicit) — aceeași frază mnemonică produce un cont nativ (coin type 118), unul EVM (coin type 60) și unul SVM (coin type 501) prin căi de derivare independente. Trei chei, trei adrese.
- Conturi unificate eth-native (SDK 0.6.0, chain v3.1.83) — O SINGURĂ cheie
eth_secp256k1este O SINGURĂ identitate de 20 de octeți redată ca toate cele trei codificări de adresă, cu un singur sold partajat. Vezi Conturi unificate.
Derivare HD (legacy/implicit, coin type 118)
import {
generateMnemonic,
validateMnemonic,
deriveNativeAccount,
deriveEvmAccount,
deriveSvmAccount,
} from "@qorechain/sdk";
const mnemonic = generateMnemonic(); // 12 words; pass 256 for 24 words
const native = await deriveNativeAccount(mnemonic);
console.log(native.address); // "qor1..." (secp256k1, bech32)
const evm = await deriveEvmAccount(mnemonic);
console.log(evm.address); // "0x..." (EIP-55 checksummed)
const svm = await deriveSvmAccount(mnemonic);
console.log(svm.address); // base58 ed25519 public key
Fraza mnemonică este validată (cuvintele și suma de control) înainte ca vreo
cheie să fie derivată, astfel încât o greșeală de tastare ridică o eroare în loc
să producă în tăcere un cont greșit. Poți valida explicit cu
validateMnemonic(mnemonic).
Scheme de derivare
| Tip | Curbă | Cale | Adresă |
|---|---|---|---|
| native | secp256k1 | m/44'/118'/0'/0/{i} | bech32 qor din ripemd160(sha256(pubkey)) |
| evm | secp256k1 | m/44'/60'/0'/0/{i} | 0x + keccak256(pubkey)[-20:], EIP-55 |
| svm | ed25519 | m/44'/501'/{i}'/0' | base58 al cheii publice de 32 de octeți |
Transmite un index de cont pentru a deriva conturi suplimentare. În TypeScript:
const second = await deriveNativeAccount(mnemonic, { accountIndex: 1 });
În Python/Go/Rust indexul este un argument pozițional
(derive_native_account(mnemonic, 1) / DeriveNativeAccount(mnemonic, 1) /
derive_native_account(&mnemonic, 1)).
Notă despre testele known-answer
Schemele de derivare sunt deterministe și acoperite de teste known-answer în toate cele patru SDK-uri, astfel încât aceeași frază mnemonică produce adrese identice în TypeScript, Python, Go și Rust. Acest lucru îți permite să derivezi într-un limbaj și să verifici în altul.
Această derivare per-lane (
deriveNativeAccountla coin type 118, plusderiveEvmAccount/deriveSvmAccount) este modelul legacy/implicit și rămâne suportată și neschimbată. Conturile unificate de mai jos sunt un model de identitate suplimentar, opt-in.
Conturi unificate (eth-native)
Începând cu SDK 0.6.0 (chain v3.1.83), deriveUnifiedAccount(mnemonic, index = 0)
derivă O SINGURĂ cheie eth_secp256k1 pe calea HD Ethereum m/44'/60'/0'/0/{index},
ai cărei 20 de octeți de adresă (keccak256(pubkey)[12:]) sunt ACEEAȘI identitate
redată în trei moduri:
| Lane | Codificare |
|---|---|
| Native | bech32 cu prefixul qor (qor1…) |
| EVM | 0x + hex cu sumă de control EIP-55 (litere mixte) |
| SVM | base58 al celor 20 de octeți completați la dreapta cu 12 octeți zero (32 de octeți) |
O depunere către oricare dintre cele trei ajunge într-un singur sold, iar cheia poate cheltui pe fiecare lane:
import {
deriveUnifiedAccount,
qoreAddresses,
addressesFrom20,
} from "@qorechain/sdk";
const account = await deriveUnifiedAccount(mnemonic);
account.cosmos; // "qor1…" bech32, Native lane
account.evm; // "0x…" EIP-55 hex, EVM lane
account.svm; // "<base58>" 32-byte SVM address (addr20 + 12 zero bytes)
account.addressBytes; // the raw 20 bytes shared by all three
account.publicKey; // 33-byte compressed secp256k1 public key
account.pqc; // { publicKey, secretKey } — ML-DSA-87, derived below
// Decode any ONE encoding into all three:
const all = qoreAddresses({ evm: account.evm });
all.cosmos; // qor1…
all.svm; // base58
// or straight from the raw 20 bytes:
const same = addressesFrom20(account.addressBytes);
unifiedAccountFromSeed(seed32) face același lucru pornind de la o cheie privată
secp256k1 brută de 32 de octeți.
Derivarea seed-ului PQC
Perechea de chei ML-DSA-87 a contului este derivată determinist și este legată de adresă:
pqcSeed = shake256("qorechain:pqc:v1|" + cosmosAddress + "|" + mnemonic, 32)
astfel încât este recuperabilă din { address, mnemonic } și identică în toate
SDK-urile de limbaj ale QoreChain. (Pentru unifiedAccountFromSeed, locul frazei
mnemonice este ocupat de "seed:" + hex(seed32).)
Trimiterea pe lane-ul Native cu cheia eth
Un cont unificat semnează tranzacțiile pe calea Native cu schema
eth_secp256k1: semnătura clasică este secp256k1 peste keccak256 al
octeților SignDoc (nu sha256), iar cheia publică din SignerInfo folosește
type URL-ul /cosmos.evm.crypto.v1.ethsecp256k1.PubKey. Calea hibridă
(signHybridEth) atașează suplimentar extensia ML-DSA-87
PQCHybridSignature — obligatorie pe rețelele live:
import { EthNativeSigner, deriveUnifiedAccount } from "@qorechain/sdk";
const account = await deriveUnifiedAccount(mnemonic);
const signer = new EthNativeSigner(account); // signMode: "hybrid" by default
// `transport` is anything with broadcastTx (e.g. a connected client).
await signer.bankSend(
transport,
"qor1recipient…",
[{ denom: "uqor", amount: "1000000" }], // 1 QOR
{ chainId: "qorechain-vladi", accountNumber, sequence, fee },
);
Pentru control la nivel mai jos, signHybridEth(params) / signClassicalEth(params)
returnează octeții TxRaw asamblați și artefactele de semnare, iar
accountAuthInfo(baseAccount) citește account_number / sequence dintr-un
cont a cărui cheie publică on-chain folosește type URL-ul eth_secp256k1. Calea
exclusiv clasică este destinată mesajului unic, exceptat la bootstrap,
MsgRegisterPQCKeyV2; folosește hibrid pentru orice altceva.
SDK 0.6.1 a corectat un bug de codificare critic pentru consens: extensia
tx-body /qorechain.pqc.v1.PQCHybridSignature era serializată ca JSON în
Any.value, iar lanțul respingea acele tranzacții la CheckTx
(o eroare de parsare a tranzacției). Acum este codificată protobuf (valoarea
extensiei începe cu 0x08) în toate cele cinci limbaje. Orice tranzacție
hibridă — inclusiv pe lane-ul eth-native — construită cu SDK ≤ 0.6.0 este
respinsă on-chain: actualizează la 0.6.1 sau mai nou.
Phantom (P1a): un cont unificat fără a exporta o cheie
connectPhantomUnified() (TypeScript) derivă un cont unificat canonic,
non-custodial, dintr-o semnătură Phantom deterministă: utilizatorul semnează
un mesaj fix, separat pe domeniu, cu cheia ed25519 a Phantom, iar
shake256(signature, 32) servește drept seed pentru cont.
import {
connectPhantomUnified,
unifiedAccountFromPhantomSignature,
} from "@qorechain/sdk";
// In the browser (uses window.solana):
const account = await connectPhantomUnified();
// Or, given a raw signature you already have:
const same = unifiedAccountFromPhantomSignature(signatureBytes);
Contul derivat este o cheie canonică separată de cheia ed25519 a Phantom — Phantom nu vede niciodată secretele derivate secp256k1/PQC. Pentru a permite cheii Phantom în sine să cheltuiască din cont sub limite, vezi Authenticators și cheltuieli delegate.
Criptografie post-cuantică (PQC)
QoreChain suportă semnături ML-DSA-87 (Dilithium-5, FIPS 204). SDK-ul expune primitivele direct.
import {
generatePqcKeypair,
pqcSign,
pqcVerify,
ML_DSA_87_PUBLIC_KEY_LENGTH,
ML_DSA_87_SIGNATURE_LENGTH,
} from "@qorechain/sdk";
const keypair = generatePqcKeypair();
const message = new TextEncoder().encode("hello");
const signature = pqcSign(keypair.secretKey, message);
const ok = pqcVerify(keypair.publicKey, message, signature);
Constantele de lungime exportate (ML_DSA_87_PUBLIC_KEY_LENGTH,
ML_DSA_87_SECRET_KEY_LENGTH, ML_DSA_87_SIGNATURE_LENGTH,
ML_DSA_87_SEED_LENGTH) îți permit să validezi dimensiunile bufferelor.
La bază, primitivele PQC provin din qorechain-pqc — biblioteca open-source, bazată exclusiv pe standarde, care încapsulează implementări auditate FIPS-204/203/202 în spatele unui API consecvent în șase limbaje (JavaScript/TypeScript, Rust, Go, C, Python, Java). Apelează la ea direct atunci când ai nevoie de primitivele brute sau de framing-ul
hybridSignBytesîn afara SDK-ului.
Semnatari interschimbabili
Pentru compoziție, SDK-ul oferă o abstracție Signer plus implementările
PqcSigner și HybridSigner, precum și un enum SignatureMode. Folosește-le
atunci când vrei să integrezi semnarea PQC în propriul tău flux, în loc să
apelezi primitivele direct.
Semnare hibridă
O tranzacție hibridă poartă atât o semnătură clasică secp256k1, cât și o
semnătură ML-DSA-87, astfel încât rămâne validă sub verificarea clasică în timp
ce câștigă protecție post-cuantică. Partea post-cuantică circulă ca o extensie
PQCHybridSignature pe tranzacție.
Începând cu versiunea curentă a lanțului (v3.1.85), setarea implicită a
rețelei este hybrid_signature_mode = required cu
allow_classical_fallback = false. Semnarea hibridă prin buildHybridTx
(cu includePqcPublicKey) — sau signHybridEth pentru conturile unificate
eth-native — este obligatorie pentru tranzacțiile pe calea Native;
tranzacțiile Native exclusiv clasice sunt respinse on-chain. Tranzacțiile EVM
folosesc o cale eth_secp256k1 separată și nu sunt afectate.
Versiunea 0.6.1 a corectat codificarea extensiei PQCHybridSignature
(JSON → protobuf, critic pentru consens). Tranzacțiile hibride construite cu
SDK 0.6.0 sau mai vechi eșuează la CheckTx cu o eroare de parsare a
tranzacției — actualizează la 0.6.1+.
import {
buildHybridTx,
deriveNativeAccount,
directSignerFromPrivateKey,
} from "@qorechain/sdk";
const account = await deriveNativeAccount(mnemonic);
const signer = await directSignerFromPrivateKey(account.privateKey, "qor");
// buildHybridTx assembles a tx with BOTH a classical signature and an
// ML-DSA-87 signature attached as a PQCHybridSignature extension.
// (See packages/ts and the pqc-hybrid-sign example for the full call.)
Condiție prealabilă on-chain
Înainte ca o tranzacție hibridă să treacă verificarea PQC on-chain, cheia
publică PQC a semnatarului trebuie să fie înregistrată prin
MsgRegisterPQCKey al lanțului — cu excepția cazului în care setezi
includePqcPublicKey: true, care încorporează cheia în extensie, astfel încât
lanțul o poate auto-înregistra la prima utilizare.
Contractul tranzacției hibride (nivel înalt)
Tranzacția este semnată clasic peste octeții de semnare standard (care
exclud extensia PQC), iar semnătura ML-DSA-87 este calculată și atașată ca
extensia PQCHybridSignature. Deoarece octeții de semnare clasici exclud
extensia, semnătura clasică rămâne validă indiferent dacă un verificator
înțelege sau nu partea PQC. Helper-ele de nivel mai jos
(encodeHybridExtension, attachHybridExtension,
buildHybridSignatureExtension, HYBRID_SIG_TYPE_URL) și constructorii
end-to-end (buildHybridTx, signAndBroadcastHybrid) sunt exportați pentru
utilizare avansată.
Trimiterea tranzacțiilor hibride este calea obligatorie pe rețeaua live pentru tranzacțiile cosmos. Primitivele locale de semnare/verificare și helper-ele de construire a tranzacțiilor sunt disponibile astăzi.
Rotația cheii PQC
Începând cu SDK 0.7.0, un cont își poate roti cheia ML-DSA-87 către o cheie nouă
de același algoritm — migrând canonic o cheie legacy shake256(mnemonic)
către cheia legată de adresă shake256("qorechain:pqc:v1|addr|mnemonic") — prin
rotatePqcKeyMsgFromMnemonic (ambele chei semnează dual octeții de rotație).
Vezi Rotația cheii în ghidul
Authenticators pentru un exemplu complet.
Identificatori de algoritm
SDK-ul exportă ID-uri de algoritm și helpere pentru lucrul la nivel de protocol:
AlgorithmUnspecified, AlgorithmDilithium5, AlgorithmMLKEM1024,
algorithmName(id) și isSignatureAlgorithm(id).