---
name: wg_keygen
kind: function
lang: go
domain: infra
version: "1.0.0"
purity: impure
signature: "func WGKeygen(withPSK bool) (WGKeys, error)"
description: "Genera par de claves WireGuard (Curve25519 privada+publica) en base64 via `wg genkey`/`wg pubkey`. Opcional preshared key via `wg genpsk` para defensa adicional contra futuro quantum-break."
tags: [wireguard, crypto, infra, mesh]
params:
  - name: withPSK
    desc: "true para incluir preshared key adicional (recomendado en mesh production)"
output: "WGKeys{PrivateKey, PublicKey, PresharedKey} todas base64. PresharedKey vacia si withPSK=false."
uses_functions: []
uses_types: [error_go_core]
returns: [WGKeys_go_infra]
returns_optional: false
error_type: "error_go_core"
imports: ["bytes", "fmt", "os/exec", "strings"]
tested: true
tests: ["genera par de claves sin PSK", "genera par de claves con PSK"]
test_file_path: "functions/infra/wg_keygen_test.go"
file_path: "functions/infra/wg_keygen.go"
---

## Ejemplo

```go
// Sin preshared key (peer-to-peer simple)
keys, err := WGKeygen(false)
if err != nil {
    log.Fatal(err)
}
fmt.Println("PrivateKey:", keys.PrivateKey) // NUNCA loguear en prod
fmt.Println("PublicKey:", keys.PublicKey)

// Con preshared key (recomendado en mesh production)
keys, err = WGKeygen(true)
if err != nil {
    log.Fatal(err)
}
// keys.PresharedKey listo para [Peer] PresharedKey = ...
```

## Cuando usarla

Antes de configurar un nuevo peer WireGuard: genera las claves localmente y usa `PublicKey` para el bloque `[Peer]` del otro extremo. Usar `withPSK=true` en mesh de produccion para proteccion adicional frente a ataques cuanticos futuros.

## Gotchas

- Requiere `wg` binario en PATH (`wg_install` lo instala). Sin el binario retorna error inmediatamente.
- Las claves base64 tienen exactamente 44 caracteres con padding (`=`).
- NUNCA loguear `PrivateKey` ni `PresharedKey` en claro. Guardar en secreto (vault, env var cifrada).
- `PresharedKey` no es lo mismo que `PrivateKey` — es un secreto simetrico compartido entre dos peers, ambos deben configurarlo bajo `[Peer] PresharedKey`.
- Los keys generados son efimeros: si se pierde el `PrivateKey` no hay recuperacion posible.
