Sign In With QoreChain (SIWQ), versiunea 1
Stare: stabilă pentru versiunea 1 a formatului mesajului. Sursa:
spec/siwq-v1.md.
SIWQ permite unui cont QoreChain să dovedească unui serviciu din afara lanțului
că își controlează cheile. Mesajul urmează structura
EIP-4361 și a Sign In With Solana,
adaptată la adresele și id-urile de lanț ale QoreChain. Semnătura are două
părți: o semnătură secp256k1 ADR-36, pe care o poate produce orice portofel
compatibil Keplr cu signArbitrary, și o semnătură ML-DSA-87 (FIPS 204) a
cheii post-cuantice înregistrate a contului.
Mesaj
${scheme://}${domain} wants you to sign in with your QoreChain account:
${address}
${statement}
URI: ${uri}
Version: 1
Chain ID: ${chain-id}
Nonce: ${nonce}
Issued At: ${issued-at}
Expiration Time: ${expiration-time}
Not Before: ${not-before}
Request ID: ${request-id}
Resources:
- ${resources[0]}
- ${resources[1]}
...
- Liniile sunt separate printr-un singur
\n; nu există newline la final. scheme://este opțional.domaineste autoritatea RFC 3986 a site-ului care face cererea (host și port opțional).addresseste forma bech32qor1a contului.- Linia de statement este opțională. Fără ea, adresa este urmată de două linii goale, ca în EIP-4361.
Versioneste1.Chain IDeste un id de lanț QoreChain, precumqorechain-vladi.Nonceare cel puțin 8 caractere alfanumerice alese de server, de unică folosință.- Marcajele de timp sunt RFC 3339 / ISO 8601.
Expiration Time,Not Before,Request IDșiResourcessunt opționale și apar în această ordine.
Un verificator trebuie să randeze din nou câmpurile parsate și să refuze un mesaj care nu se potrivește octet cu octet.
Semnături
{
"signatureType": "ml-dsa-87-hybrid",
"classical": { "keyType": "secp256k1", "publicKey": "<base64>", "signature": "<base64>" },
"pq": { "algorithmId": 1, "signature": "<base64>" }
}
Partea clasică (ADR-36)
Cheia secp256k1 a contului semnează documentul de semnare amino JSON de mai
jos, serializat cu chei sortate și fără spații, unde data este base64 al
mesajului UTF-8, iar signer adresa qor1:
{"account_number":"0","chain_id":"","fee":{"amount":[],"gas":"0"},"memo":"","msgs":[{"type":"sign/MsgSignData","value":{"data":"...","signer":"qor1..."}}],"sequence":"0"}
Digestul este SHA-256 pentru conturile secp256k1 și KECCAK-256 pentru conturile
eth_secp256k1; semnătura are 64 de octeți r || s, low-S. publicKey este
cheia comprimată de 33 de octeți, care trebuie să se deriveze în address
conform keyType.
Partea post-cuantică
pq.signature = ML-DSA-87.Sign(sk, UTF-8("qorechain-siwq-v1|" + message))
Prefixul de domeniu împiedică folosirea unei semnături de sign-in ca semnătură de tranzacție și invers (vezi Separarea domeniilor).
signatureType este secp256k1 când partea pq lipsește. Verificatorii ar
trebui să refuze astfel de sign-in-uri, cu excepția cazului în care acceptă
explicit conturi doar cu cheie clasică.
Verificare
Un verificator trebuie să controleze, în această ordine:
- mesajul se parsează și este în formă canonică;
domaineste egal cu domeniul de la care a venit cererea;nonceeste egal cu nonce-ul emis de server pentru această sesiune, iar nonce-ul nu a mai fost folosit;Chain IDeste rețeaua așteptată;Expiration Timeeste în viitor, iarNot BeforeșiIssued Atnu sunt în viitor (permițând o mică abatere de ceas);- cheia publică clasică se derivă în
address, iar semnătura ADR-36 se verifică; - semnătura ML-DSA-87 se verifică față de cheia publică înregistrată pe
lanț pentru
address(/qorechain/pqc/v1/account/{address}), nu față de o cheie furnizată de client.
Vectori de test
vectors/qoresign-v1.json, câmpul siwq. Vezi Vectori de test.