Sign In With QoreChain: サーバー側の検証
SIWQ は、EIP-4361 形式のサインインメッセージで、アカウントの secp256k1 鍵 (ADR-36)と ML-DSA-87 鍵の両方で署名されます。フォーマット: Sign In With QoreChain v1。
フロー
- サーバーがセッション用の使い捨てナンスを発行します。
- クライアントが
createSiwqMessageでメッセージを作成し、ウォレットがsignSiwqで署名します(または、signArbitraryで従来型の部分を、siwqPqSignBytes(message)に対するpqSignで ML-DSA-87 の部分を生成します)。 - サーバーは
verifySiwqWithChainで検証します。これはメッセージ、ナンス、 ドメイン、時刻、従来型鍵がそのアドレスを制御していること、そして ML-DSA-87 署名 を、そのアドレスに対してチェーン上に登録されている鍵に照らして確認します (検証を参照)。
TypeScript
import { verifySiwqWithChain } from "@qorechain/qoresign/network";
const fields = await verifySiwqWithChain({
rest: "https://api.qore.host",
address: body.address,
message: body.message,
signature: body.signature,
domain: "app.example.com", // the host the request came to
nonce: session.nonce, // single use; delete it now
chainId: "qorechain-vladi",
});
// fields.address is signed in; fields.possessionProven tells whether the key was registered with a proof of possession
Go
import (
qoresign "github.com/qorechain/qoresign/go"
"github.com/qorechain/qoresign/go/network"
)
// The network helpers are methods on a client.
client := network.NewClient("https://api.qore.host")
var sig qoresign.SiwqSignature
if err := json.Unmarshal(signatureJSON, &sig); err != nil {
return err
}
result, err := client.VerifySiwqWithChain(ctx, address, qoresign.VerifySiwqOptions{
Message: message,
Signature: sig,
Domain: "app.example.com", // the host the request came to
Nonce: issuedNonce, // the nonce your server issued
ChainID: "qorechain-vladi",
})
if qoresign.IsCode(err, qoresign.CodeSiwqExpired) {
// ask the user to sign in again
}
// result.Address signed in; result.PossessionProven reports how the key was registered.
従来型のみのアカウント
verifySiwq は、requirePq: false を渡さない限り、ML-DSA-87 の部分がないサイン
インを拒否します。従来型のみのサインインを受け入れるのは、サービスがポスト量子の保証を
必要としない場合に限ってください。
実行可能なサーバーは
examples/siwq-server
にあります。