Go は暗号機能を標準ライブラリで提供しており、Go 1.24 以降、中核となるプリミティブは FIPS 140-3 向けにビルドされた Go 暗号モジュール(Go Cryptographic Module)に含まれています。crypto/ecdsa が署名と検証を、crypto/x509 が鍵と証明書の読み込みを担い、Go 1.27.3 では crypto/ed25519 に加えて crypto/mlkem(ML-KEM-768/1024)と crypto/mldsa(ML-DSA-44/65/87)も使えます。secp256k1 はないため、Ethereum や Bitcoin のコードでは go-ethereum か decred のパッケージを使います。
crypto/ecdsa の関数はすべて、自分で計算したダイジェストを対象に動作し、パッケージ自体はハッシュを計算しません。誤った署名よりも厄介なことに、長い入力は警告なしに曲線のサイズに切り詰められます。46 バイトの入力に対する署名が、先頭 32 バイトが同じ別の入力に対しても検証を通りました。サンプルのように、必ず先にハッシュを計算してください。SignASN1、VerifyASN1、crypto.Signer インターフェースは ASN.1 DER を扱います。WebCrypto、JWS など生の r‖s を使う相手には、FillBytes で整数をパディングしたうえで Sign/Verify を使う必要があります。Bytes() は先頭のゼロバイトを落とすため、たまたまゼロバイトで始まる r や s は 1 バイト短くなります。
署名はランダム化されており、Go 1.26 以降は GODEBUG=cryptocustomrand=1 を設定しない限り、渡した io.Reader は無視されます。すべてゼロを返す Reader で作成した 2 つの署名は異なっていました。固定の Reader で再現可能な署名を得ていたテストは動かなくなり、ドキュメントに記載された代替手段は testing/cryptotest.SetGlobalRandom です。s は正規化されず、VerifyASN1 は low-S と high-S のどちらも受け入れるため、low-S を厳格に要求する検証者に渡す署名では s を n − s に置き換える必要があります。
鍵の解析は DER が前提です。x509.ParsePKIXPublicKey に PEM のテキストを渡すと asn1: structure error: tags don't match で失敗するため、先に pem.Decode を呼び出してください。ecdsa.ParseUncompressedPublicKey と ecdsa.ParseRawPrivateKey は、そのままの SEC1 の点とスカラーを読み込みます。圧縮形式の点は拒否され、パスフレーズで暗号化された PKCS#8 を読み込む手段はありません。形式の誤った署名を渡すと、VerifyASN1 はエラーではなく常に false を返します。
Go の署名を他のスタックの署名と比較するには、DER ⇄ 生形式の変換ツールで変換し、署名検証ツールで検証してください。証明書の解析の問題は、証明書デコーダーで見るのが最も簡単です。