O Go traz sua criptografia na biblioteca padrão, e desde o Go 1.24 as primitivas centrais ficam no Go Cryptographic Module, construído para o FIPS 140-3. crypto/ecdsa assina e verifica, crypto/x509 lê chaves e certificados, e o Go 1.27.3 acrescenta crypto/mlkem (ML-KEM-768/1024) e crypto/mldsa (ML-DSA-44/65/87) ao lado de crypto/ed25519. Não há secp256k1: código de Ethereum e Bitcoin usa os pacotes do go-ethereum ou do decred.
Tudo em crypto/ecdsa opera sobre um digest calculado por você — o pacote nunca calcula hashes. Pior do que uma assinatura errada: uma entrada longa é truncada silenciosamente para o tamanho da curva, e uma assinatura sobre uma entrada de 46 bytes foi verificada para outra entrada com os mesmos 32 primeiros bytes. Calcule sempre o hash antes, como faz o exemplo. SignASN1, VerifyASN1 e a interface crypto.Signer falam ASN.1 DER; WebCrypto, JWS e outras contrapartes que usam r‖s bruto precisam de Sign/Verify com os inteiros preenchidos por FillBytes — Bytes() descarta bytes zero à esquerda, então todo r ou s que por acaso comece com um byte zero sai com um byte a menos.
As assinaturas são aleatorizadas e, desde o Go 1.26, o io.Reader que você passa é ignorado, a menos que GODEBUG=cryptocustomrand=1 esteja definido: duas assinaturas feitas com um Reader só de zeros foram diferentes. Testes que dependiam de um Reader fixo para obter assinaturas reproduzíveis pararam de funcionar; a substituição documentada é testing/cryptotest.SetGlobalRandom. O s não é normalizado e VerifyASN1 aceita as duas metades, então assinaturas destinadas a verificadores low-S estritos precisam ter o s substituído por n − s.
A leitura de chaves parte do DER. x509.ParsePKIXPublicKey falha com asn1: structure error: tags don't match quando recebe texto PEM — chame pem.Decode antes. ecdsa.ParseUncompressedPublicKey e ecdsa.ParseRawPrivateKey leem o ponto SEC1 e o escalar puros; pontos comprimidos são recusados, e não há leitor para PKCS#8 criptografado com senha. Uma assinatura malformada faz VerifyASN1 retornar false, nunca um erro.
Para comparar uma assinatura do Go com a de outra pilha, converta-a no conversor DER ⇄ bruto e confira-a no verificador de assinaturas; problemas na leitura de certificados ficam mais fáceis de ver no decodificador de certificados.