brainpool

package module
v1.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 28, 2026 License: EUPL-1.2 Imports: 17 Imported by: 11

README

brainpool

A Go library for the Brainpool elliptic curves (RFC 5639) as used across the gematik telematics infrastructure (SMC-B, HBA, eGK, IDP-Dienst, ePA): curve definitions, X.509 certificate and key parsing that the Go standard library cannot perform for these curves, a self-contained JOSE layer (JWS/JWE/JWK), and a constant-time, formally-verified core for brainpoolP256r1 covering the secret-scalar operations (ECDSA signing and ECDH).

Security posture

The security-critical design follows the principle that only operations on a secret scalar require constant-time implementations; operations on public data do not. Accordingly:

Operation Secret input Implementation
ECDSA sign (brainpoolP256r1) nonce k, key d Constant-time core (internal/bp256)
ECDH (brainpoolP256r1) key d Constant-time core (internal/bp256)
ECDSA verify none (public) Standard library crypto/ecdsa.Verify
Certificate / key parsing none (public) This package (parser.go)
brainpoolP384r1 / P512r1 sign/verify Standard library crypto/ecdsa over elliptic.Curve
Why a constant-time core for brainpoolP256r1

Go's generic crypto/elliptic custom-curve path (the only path available for non-NIST curves) is deprecated and documented as "not guaranteed to provide any security property." Its scalar multiplication is a variable-time big.Int double-and-add whose timing correlates with the secret scalar — the class of leak exploited by Minerva (2019) and TPM-Fail (2019) to recover ECDSA private keys via lattice attacks. brainpoolP256r1 is the curve gematik uses for software-held signing keys, so it receives the same constant-time treatment the Go standard library already gives the NIST curves.

The constant-time core is built exactly as the Go standard library builds its NIST curve support (crypto/internal/fips140/nistec):

  1. Field arithmetic — machine-checked code generated by Fiat Cryptography (word-by-word Montgomery), committed verbatim. See internal/bp256/fiat/PROVENANCE.md.
  2. Point arithmetic — the exception-free complete addition formulas of Renes–Costello–Batina over homogeneous projective coordinates. brainpoolP256r1 has a ≠ −3, so the general formula (Algorithm 1) is used.
  3. Scalar multiplication — a constant-time Montgomery ladder with no scalar-bit-dependent branches.
  4. Scalar-field arithmetic (mod n, for k⁻¹ and z + r·d) — a second Fiat-Cryptography field; see internal/bp256/fiatn.
  5. Deterministic noncesRFC 6979 (HMAC-SHA256), default for software signing, removing the weak-RNG key-recovery failure mode.
  6. Low-s normalisation — signatures are canonicalised to low-s (SEC 1 §4.1.3 / BIP-0062) to remove signature malleability.
Residual notes
  • brainpoolP384r1 and brainpoolP512r1 remain on the standard library's non-constant-time generic path; they are used for certificate handling and are not the software-signing curves. Hardware-token (HBA/SMC-B) signing is opaque to this library and unaffected.
  • This library has not undergone an independent third-party audit. It is structured to support one: the field layer is machine-checked, the point layer is differentially tested against an independent implementation and OpenSSL, and every algorithm cites its specification.

Validation

The constant-time core is validated by:

  • Differential testing of point addition, doubling, scalar multiplication, ECDSA, and ECDH against the package's independent big.Int curve implementation (the oracle) and against the Go standard library.
  • Project Wycheproof — all 485 ecdsa_brainpoolP256r1_sha256 edge-case vectors (zero/overflow r,s, malformed DER, …).
  • RFC 7027 §A.1 ECDH known-answer vectors (cross-implementation; the expected values are independently confirmed with OpenSSL).
  • Field arithmetic checked against math/big modular arithmetic.
  • OpenSSL cross-tests (build tag openssl_cross): our deterministic signatures verify under OpenSSL, and OpenSSL signatures verify under the standard-library path — bidirectional interoperability.
  • RFC 6979 determinism validated by reproducibility (identical inputs → identical signature; distinct messages → distinct nonces) and by verification under the standard library.

Domain parameters (brainpoolP256r1, RFC 5639 §3.4)

p  = A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377
a  = 7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9
b  = 26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6
Gx = 8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262
Gy = 547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997
n  = A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7
h  = 1
OID = 1.3.36.3.3.2.8.1.1.7  (brainpoolP256r1)

References

Curves and elliptic-curve cryptography
  • RFC 5639Elliptic Curve Cryptography (ECC) Brainpool Standard Curves and Curve Generation (M. Lochter, J. Merkle), March 2010. Domain parameters.
  • RFC 7027Elliptic Curve Cryptography (ECC) Brainpool Curves for Transport Layer Security (TLS) (J. Merkle, M. Lochter), October 2013. ECDH test vectors (Appendix A).
  • SEC 1: Elliptic Curve Cryptography, Version 2.0 (Certicom Research, 2009). Point encodings (§2.3), public-key validation (§3.2.2), signature encoding and low-s (§4.1.3).
  • Renes, Costello, Batina, Complete addition formulas for prime order elliptic curves, EUROCRYPT 2016 (IACR ePrint 2015/1060). Algorithm 1 (general a) is used for point addition.
Signatures and key agreement
  • FIPS 186-5Digital Signature Standard (DSS) (NIST, February 2023). ECDSA signing (§6.4.1) and verification (§6.4.2).
  • RFC 6979Deterministic Usage of the DSA and ECDSA (T. Pornin), August 2013. Deterministic nonce generation (§3.2).
  • BIP-0062 — low-s signature canonicalisation (malleability).
BSI Technical Guidelines
  • BSI TR-03111Elliptic Curve Cryptography, Version 2.10 (Bundesamt für Sicherheit in der Informationstechnik). Point encoding (§3.1), public-key validation (§3.2.2), ECDH (§3.5.1), ECDSA plain signatures (§5.2.1).
  • BSI TR-03110Advanced Security Mechanisms for Machine Readable Travel Documents and eIDAS Token (PACE / Chip Authentication context for eGK/eMRTD).
JOSE (the josebp subpackage)
  • RFC 7515 — JSON Web Signature (JWS).
  • RFC 7516 — JSON Web Encryption (JWE).
  • RFC 7517 — JSON Web Key (JWK).
  • RFC 7518 — JSON Web Algorithms (JWA); raw r‖s signatures (§3.4), ECDH-ES + Concat KDF (§4.6).
  • RFC 7519 — JSON Web Token (JWT).
Formal verification and code generation
  • Fiat Cryptography — A. Erbsen, J. Philipoom, J. Gross, R. Sloan, A. Chlipala, Simple High-Level Code for Cryptographic Arithmetic — With Proofs, Without Compromises, IEEE S&P 2019. https://github.com/mit-plv/fiat-crypto. The field arithmetic in internal/bp256/fiat and internal/bp256/fiatn is generated by Fiat Cryptography and is machine-checked in Coq. Provenance (pinned image, commit, exact invocation) is recorded in internal/bp256/fiat/PROVENANCE.md.
  • addchain — M. McLoughlin, https://github.com/mmcloughlin/addchain. Generates the constant-time field-inversion addition chains.
Test corpora
Standard library precedent
  • Go crypto/internal/fips140/nistec — the NIST-curve implementation whose structure (Fiat field + projective complete formulas + constant-time ladder) this library mirrors for brainpoolP256r1.

Package layout

brainpool/                 Curves, X.509 parser, helpers, signing entry points
  josebp/                  JOSE: JWS/JWE/JWK over Brainpool
  internal/bp256/          Constant-time brainpoolP256r1 core
    fiat/                  Generated field arithmetic mod p (Fiat Cryptography)
    fiatn/                 Generated scalar arithmetic mod n (Fiat Cryptography)
    testdata/wycheproof/   Vendored Wycheproof vectors

License and provenance of generated code

Generated files (*_fiat64.go, *_invert.go) carry a DO NOT EDIT header and are reproducible from the pinned toolchain described in the PROVENANCE.md files. Do not hand-edit them; regenerate with the documented commands.

Documentation

Overview

Package brainpool implements the Brainpool elliptic curves (RFC 5639) used by the gematik telematics infrastructure, together with X.509 certificate/key parsing for these curves and the signing entry points used by the josebp JOSE layer.

Constant-time posture is per curve:

  • brainpoolP256r1 secret-scalar operations (ECDSA signing via SignFuncPrivateKey, ECDH via ECDHP256r1) are routed through a constant-time, formally-verified core (see internal/bp256) using RFC 6979 deterministic nonces and low-s normalisation. Signature verification uses the standard library, which is appropriate because it processes only public data.
  • brainpoolP384r1, brainpoolP512r1 and the twisted (t1) curves use the standard library's generic, non-constant-time crypto/elliptic implementation (the rcurve isomorphism is adapted from github.com/ebfe/brainpool). They are used for certificate handling, not as software-signing curves.

See README.md for the full security posture and references.

Index

Constants

This section is empty.

Variables

View Source
var OIDNamedCurveP256r1 = asn1.ObjectIdentifier{1, 3, 36, 3, 3, 2, 8, 1, 1, 7}
View Source
var OIDNamedCurveP384r1 = asn1.ObjectIdentifier{1, 3, 36, 3, 3, 2, 8, 1, 1, 11}
View Source
var OIDNamedCurveP512r1 = asn1.ObjectIdentifier{1, 3, 36, 3, 3, 2, 8, 1, 1, 13}

Functions

func CurveFromOID

func CurveFromOID(oid asn1.ObjectIdentifier) (bool, elliptic.Curve)

func ECDHP256r1 added in v1.0.0

func ECDHP256r1(priv *ecdsa.PrivateKey, pubX, pubY *big.Int) ([]byte, error)

ECDHP256r1 computes the brainpoolP256r1 ECDH shared secret (the x-coordinate of priv·peer, BSI TR-03111 §3.5.1) using the constant-time core. The peer point (pubX, pubY) is validated (on-curve, in range) before use.

func IsBrainpoolCertificate

func IsBrainpoolCertificate(cert *x509.Certificate) bool

IsBrainpoolCertificate checks if the given certificate uses elliptic curve cryptography with a brainpool curve.

func IsBrainpoolCurve

func IsBrainpoolCurve(curve elliptic.Curve) bool

IsBrainpoolCurve checks if the given elliptic curve is one of the brainpool curves.

func IsBrainpoolPublicKey

func IsBrainpoolPublicKey(pub any) bool

IsBrainpoolPublicKey checks if the given public key uses elliptic curve cryptography with a brainpool curve.

func MarshalPKIXPublicKey

func MarshalPKIXPublicKey(pub any) ([]byte, error)

func P256r1

func P256r1() elliptic.Curve

P256r1 returns a Curve which implements Brainpool P256r1 (see RFC 5639, section 3.4)

func P256t1

func P256t1() elliptic.Curve

P256t1 returns a Curve which implements Brainpool P256t1 (see RFC 5639, section 3.4)

func P384r1

func P384r1() elliptic.Curve

P384r1 returns a Curve which implements Brainpool P384r1 (see RFC 5639, section 3.6)

func P384t1

func P384t1() elliptic.Curve

P384t1 returns a Curve which implements Brainpool P384t1 (see RFC 5639, section 3.6)

func P512r1

func P512r1() elliptic.Curve

P512r1 returns a Curve which implements Brainpool P512r1 (see RFC 5639, section 3.7)

func P512t1

func P512t1() elliptic.Curve

P512t1 returns a Curve which implements Brainpool P512t1 (see RFC 5639, section 3.7)

func ParseCertificate

func ParseCertificate(der []byte) (*x509.Certificate, error)

func ParseCertificatePEM

func ParseCertificatePEM(pemBytes []byte) (*x509.Certificate, error)

func ParseECPrivateKey

func ParseECPrivateKey(der []byte) (*ecdsa.PrivateKey, error)

func ParsePKCS8PrivateKey

func ParsePKCS8PrivateKey(der []byte) (any, error)

func ParsePrivateKeyPEM

func ParsePrivateKeyPEM(pemBytes []byte) (*ecdsa.PrivateKey, error)

func SignP256r1 added in v1.0.0

func SignP256r1(priv *ecdsa.PrivateKey, prehash []byte) ([]byte, error)

SignP256r1 signs prehash with priv using the constant-time core: an RFC 6979 deterministic nonce and low-s normalisation. It returns the fixed-width r‖s encoding (RFC 7518 §3.4). priv must be a brainpoolP256r1 key.

func SignP256r1Random added in v1.0.0

func SignP256r1Random(rng io.Reader, priv *ecdsa.PrivateKey, prehash []byte) ([]byte, error)

SignP256r1Random is the opt-out variant of SignP256r1 that draws a random per-message nonce from rng instead of RFC 6979. It still uses the constant-time core and low-s normalisation. Prefer SignP256r1 unless a random nonce is specifically required.

Types

type SignFunc

type SignFunc func(hash []byte) ([]byte, error)

SignFunc signs a digest and returns the raw fixed-width r‖s ECDSA signature (RFC 7518 §3.4). It abstracts over software keys and hardware tokens (smartcards via the gematik connector), where the private key is not extractable. The JOSE layer lives in brainpool/josebp.

func SignFuncPrivateKey

func SignFuncPrivateKey(sigPrK *ecdsa.PrivateKey) SignFunc

SignFuncPrivateKey returns a SignFunc backed by a software ECDSA private key.

For brainpoolP256r1 keys it uses the constant-time core with an RFC 6979 deterministic nonce and low-s normalisation (resisting the timing and weak-RNG key-recovery attacks the deprecated generic crypto/elliptic path is subject to). For the other curves it uses the standard library. Hardware-token signers are opaque SignFunc closures supplied by the caller and are unaffected.

func SignFuncPrivateKeyRandom added in v1.0.0

func SignFuncPrivateKeyRandom(sigPrK *ecdsa.PrivateKey) SignFunc

SignFuncPrivateKeyRandom is the opt-out variant of SignFuncPrivateKey that, for brainpoolP256r1, draws a random per-message nonce instead of the RFC 6979 deterministic one (still constant-time, still low-s). Other curves behave as with SignFuncPrivateKey.

Directories

Path Synopsis
internal
bp256
Package bp256 implements constant-time arithmetic for the brainpoolP256r1 elliptic curve (RFC 5639 §3.4), used by the parent brainpool package for the secret-scalar operations that must resist timing side channels: ECDSA signing and ECDH.
Package bp256 implements constant-time arithmetic for the brainpoolP256r1 elliptic curve (RFC 5639 §3.4), used by the parent brainpool package for the secret-scalar operations that must resist timing side channels: ECDSA signing and ECDH.
bp256/fiat
Package fiat provides constant-time arithmetic in the brainpoolP256r1 base field (integers modulo the field prime p, RFC 5639 §3.4).
Package fiat provides constant-time arithmetic in the brainpoolP256r1 base field (integers modulo the field prime p, RFC 5639 §3.4).
bp256/fiatn
Package fiatn provides constant-time arithmetic in the brainpoolP256r1 scalar field, i.e.
Package fiatn provides constant-time arithmetic in the brainpoolP256r1 scalar field, i.e.
Package josebp is a self-contained JOSE (JWS/JWT/JWK/JWE) implementation for the Brainpool elliptic curves used by the gematik telematik infrastructure (IDP-Dienst, SMC-B, ePA).
Package josebp is a self-contained JOSE (JWS/JWT/JWK/JWE) implementation for the Brainpool elliptic curves used by the gematik telematik infrastructure (IDP-Dienst, SMC-B, ePA).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL