# EdDSA (Edwards-curve Digital Signature Algorithm)

📌 Classificação

* **Categoria:** Criptografia Assimétrica / Assinaturas Digitais
* **Criado por:** Daniel J. Bernstein, Niels Duif, Tanja Lange, Peter Schwabe, Bo-Yin Yang (2011)
* **Padrões:** RFC 8032, FIPS 186-5 (em adoção)
* **Base Matemática:** Curvas de Edwards (Curve25519, Curve448)
* **Status:** ✅ Moderno, rápido, seguro (recomendado)

***

### 🎯 Descrição Geral

**EdDSA (Edwards-curve Digital Signature Algorithm)** é um algoritmo de assinatura digital moderno baseado em **curvas de Edwards** (uma família específica de curvas elípticas). Ele foi projetado para ser **mais rápido, mais seguro e mais simples** que o ECDSA, evitando muitas das armadilhas comuns de implementação.

```
┌─────────────────────────────────────────────────────────────┐
│                         EdDSA                                │
│                                                              │
│   Mensagem + Chave Privada ──► EdDSA ──► Assinatura (R, S)  │
│                                                              │
│   Mensagem + Chave Pública + Assinatura ──► Válido/Inválido │
└─────────────────────────────────────────────────────────────┘
```

#### Analogia

> *"Se ECDSA é um carro manual (poderoso, mas fácil de errar), EdDSA é um carro automático (faz a mesma coisa, mas é muito mais difícil fazer algo errado)."*

***

### ⚙️ Características Únicas do EdDSA

#### Vantagens sobre ECDSA

| Característica                   | ECDSA                    | EdDSA                   |
| -------------------------------- | ------------------------ | ----------------------- |
| **Aleatoriedade necessária**     | ✅ Sim (k aleatório)      | ❌ Não (determinístico)  |
| **Vulnerável a RNG fraco**       | ✅ Sim (crítico)          | ❌ Não                   |
| **Implementação constante**      | Difícil (requer cuidado) | ✅ Fácil (design nativo) |
| **Proteção contra side-channel** | Opcional                 | ✅ Nativa                |
| **Velocidade**                   | Rápida                   | ✅ Muito mais rápida     |
| **Tamanho da assinatura**        | 64 bytes                 | 64 bytes (mesmo)        |
| **Verificação em lote**          | Não                      | ✅ Sim                   |

#### Principais Características

1. **Determinística:** Não usa gerador de números aleatórios (evita o erro fatal de repetir `k`)
2. **Implementação de tempo constante:** Resistente a timing attacks por design
3. **Verificação em lote:** Verificar múltiplas assinaturas simultaneamente (mais rápido)
4. **Sem patentes:** Domínio público
5. **Curvas específicas:** Curve25519, Curve448 (otimizadas para segurança e velocidade)

***

### 📐 Curvas Edwards

#### O que são Curvas de Edwards?

Curvas de Edwards são uma família de curvas elípticas da forma:

```
x² + y² = 1 + dx²y²
```

**Vantagem:** A operação de adição de pontos é **unificada** (mesma fórmula para dobrar e adicionar), o que simplifica implementações seguras.

#### Curvas Padrão EdDSA

| Curva       | Tamanho  | Segurança | Uso                       |
| ----------- | -------- | --------- | ------------------------- |
| **Ed25519** | 256 bits | 128 bits  | ✅ Padrão (recomendado)    |
| **Ed448**   | 448 bits | 224 bits  | ✅ Alto nível (mais lento) |

#### Comparação: Ed25519 vs ECDSA P-256

| Aspecto                     | Ed25519          | ECDSA P-256   |
| --------------------------- | ---------------- | ------------- |
| **Bits de segurança**       | 128              | 128           |
| **Velocidade (assinar)**    | \~100k ops/s     | \~50k ops/s   |
| **Velocidade (verificar)**  | \~50k ops/s      | \~40k ops/s   |
| **Verificação em lote**     | 3-5x mais rápida | Não suporta   |
| **Tamanho chave privada**   | 32 bytes         | 32 bytes      |
| **Tamanho chave pública**   | 32 bytes         | 33-65 bytes   |
| **Tamanho assinatura**      | 64 bytes         | 64 bytes      |
| **Implementação constante** | ✅ Sim            | ❌ Difícil     |
| **Aleatoriedade**           | ❌ Não            | ✅ Sim (risco) |

***

### ⚙️ Como Funciona o EdDSA

#### Geração de Chaves

```python
def ed25519_keygen():
    # 1. Gerar chave privada (32 bytes aleatórios)
    priv_key = secrets.token_bytes(32)
    
    # 2. Calcular hash da chave privada
    h = sha512(priv_key)  # 64 bytes
    
    # 3. Derivar o escalar (clamping)
    #    - Limpar bits inferiores (múltiplo de 8)
    #    - Limpar bits superiores
    #    - Setar o bit mais alto
    a = h[:32]
    a[0] &= 248   # limpar bits inferiores
    a[31] &= 127  # limpar bit superior
    a[31] |= 64   # setar segundo bit mais alto
    
    # 4. Calcular chave pública (A = a × B)
    A = scalar_mult(a, B)  # B é o ponto base
    
    # 5. Chave pública é a codificação do ponto A
    pub_key = encode_point(A)
    
    return priv_key, pub_key
```

#### Algoritmo de Assinatura (Determinístico!)

```python
def ed25519_sign(message, priv_key):
    # 1. Calcular hash da chave privada
    h = sha512(priv_key)
    a = h[:32]  # parte para escalar
    prefix = h[32:]  # parte para determinismo
    
    # 2. Clamping (como na geração)
    a = clamp(a)
    
    # 3. Calcular r = SHA512(prefix + message) (determinístico!)
    r = sha512(prefix + message)
    r = int.from_bytes(r, 'little') % l  # l = ordem da curva
    
    # 4. Calcular R = r × B (ponto efêmero)
    R = scalar_mult(r, B)
    
    # 5. Codificar R
    R_encoded = encode_point(R)
    
    # 6. Calcular k = SHA512(R_encoded + pub_key + message)
    k = sha512(R_encoded + pub_key + message)
    k = int.from_bytes(k, 'little') % l
    
    # 7. Calcular S = (r + k × a) mod l
    S = (r + k * a) % l
    
    # 8. Assinatura é R_encoded + S (64 bytes: 32 + 32)
    return R_encoded + S.to_bytes(32, 'little')
```

#### Algoritmo de Verificação

```python
def ed25519_verify(message, signature, pub_key):
    # 1. Extrair R e S da assinatura
    R_encoded = signature[:32]
    S_bytes = signature[32:]
    S = int.from_bytes(S_bytes, 'little')
    
    # 2. Validar S (0 < S < l)
    if not (0 < S < l):
        return False
    
    # 3. Decodificar R e A (chave pública)
    R = decode_point(R_encoded)
    A = decode_point(pub_key)
    
    # 4. Calcular k = SHA512(R_encoded + pub_key + message)
    k = sha512(R_encoded + pub_key + message)
    k = int.from_bytes(k, 'little') % l
    
    # 5. Verificar equação: S × B = R + k × A
    left = scalar_mult(S, B)
    right = add_points(R, scalar_mult(k, A))
    
    return left == right
```

#### Verificação em Lote (Batch Verification)

```python
def ed25519_batch_verify(messages, signatures, pub_keys):
    """
    Verificar múltiplas assinaturas em lote (mais rápido)
    """
    # Soma aleatória ponderada (usando randômico para segurança)
    z = 1  # número aleatório por segurança
    
    total_R = point_at_infinity
    total_S = 0
    total_A = point_at_infinity
    
    for msg, sig, pub in zip(messages, signatures, pub_keys):
        R_encoded = sig[:32]
        S = int.from_bytes(sig[32:], 'little')
        R = decode_point(R_encoded)
        A = decode_point(pub)
        
        k = sha512(R_encoded + pub + msg)
        k = int.from_bytes(k, 'little') % l
        
        total_R = add_points(total_R, scalar_mult(z, R))
        total_S = (total_S + z * S) % l
        total_A = add_points(total_A, scalar_mult(z * k, A))
    
    # Verificar: total_S × B = total_R + total_A
    left = scalar_mult(total_S, B)
    right = add_points(total_R, total_A)
    
    return left == right
```

***

### 💻 Exemplos Práticos

#### Exemplo 1 – Gerar Chaves Ed25519 (OpenSSL)

```bash
# Gerar chave privada Ed25519
openssl genpkey -algorithm ED25519 -out ed25519_private.pem

# Extrair chave pública
openssl pkey -in ed25519_private.pem -pubout -out ed25519_public.pem

# Verificar chaves
openssl pkey -in ed25519_private.pem -text -noout
openssl pkey -pubin -in ed25519_public.pem -text -noout

# Output exemplo:
# ED25519 Private-Key: 256 bits
# priv: 00:11:22:33:...
# pub: 44:55:66:77:...
```

#### Exemplo 2 – Assinar e Verificar (OpenSSL)

```bash
# Criar arquivo
echo "Documento importante assinado com Ed25519" > documento.txt

# Assinar
openssl pkeyutl -sign -inkey ed25519_private.pem -rawin -in documento.txt -out signature.bin

# Verificar
openssl pkeyutl -verify -pubin -inkey ed25519_public.pem -rawin -in documento.txt -sigfile signature.bin

# Output: Signature Verified Successfully
```

#### Exemplo 3 – Ed25519 em Python (cryptography)

```python
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
from cryptography.hazmat.primitives.serialization import Encoding, PrivateFormat, PublicFormat, NoEncryption

# Gerar chave
private_key = Ed25519PrivateKey.generate()
public_key = private_key.public_key()

print(f"Chave privada: {private_key.private_bytes(Encoding.Raw, PrivateFormat.Raw, NoEncryption()).hex()}")
print(f"Chave pública: {public_key.public_bytes(Encoding.Raw, PublicFormat.Raw).hex()}")

# Assinar mensagem
message = b"Mensagem secreta para assinar"
signature = private_key.sign(message)
print(f"Assinatura (64 bytes): {signature.hex()}")

# Verificar assinatura
try:
    public_key.verify(signature, message)
    print("✅ Assinatura Ed25519 VÁLIDA!")
except:
    print("❌ Assinatura INVÁLIDA!")

# Serializar para PEM
pem_private = private_key.private_bytes(
    Encoding.PEM,
    PrivateFormat.PKCS8,
    NoEncryption()
)

pem_public = public_key.public_bytes(
    Encoding.PEM,
    PublicFormat.SubjectPublicKeyInfo
)

with open("ed25519.pem", "wb") as f:
    f.write(pem_private)
```

#### Exemplo 4 – Ed25519 com PyNaCl (recomendado)

```python
# pip install pynacl
import nacl.signing
import nacl.encoding

# Gerar chave
signing_key = nacl.signing.SigningKey.generate()
verify_key = signing_key.verify_key

print(f"Chave privada (hex): {signing_key.encode(encoder=nacl.encoding.HexEncoder).decode()}")
print(f"Chave pública (hex): {verify_key.encode(encoder=nacl.encoding.HexEncoder).decode()}")

# Assinar mensagem
message = b"Mensagem para assinar com NaCl"
signed = signing_key.sign(message)

print(f"Assinatura (64 bytes): {signed.signature.hex()}")
print(f"Mensagem + assinatura: {signed.hex()}")

# Verificar (extrai a mensagem e verifica)
try:
    verified = verify_key.verify(signed)
    print(f"✅ Mensagem verificada: {verified.decode()}")
except:
    print("❌ Assinatura inválida!")

# Serializar
with open("ed25519_private.key", "wb") as f:
    f.write(signing_key.encode())

with open("ed25519_public.key", "wb") as f:
    f.write(verify_key.encode())
```

#### Exemplo 5 – Ed448 (High Security)

```python
from cryptography.hazmat.primitives.asymmetric.ed448 import Ed448PrivateKey

# Gerar chave Ed448 (224 bits de segurança)
private_key = Ed448PrivateKey.generate()
public_key = private_key.public_key()

# Assinar
message = b"Mensagem ultra secreta"
signature = private_key.sign(message)
print(f"Assinatura Ed448 (114 bytes): {signature.hex()}")

# Verificar
try:
    public_key.verify(signature, message)
    print("✅ Assinatura Ed448 VÁLIDA!")
except:
    print("❌ Assinatura INVÁLIDA!")
```

#### Exemplo 6 – SSH com Ed25519

```bash
# Gerar chave SSH Ed25519 (recomendado)
ssh-keygen -t ed25519 -C "seu_email@exemplo.com"

# Output:
# Generating public/private ed25519 key pair.
# Your identification has been saved in ~/.ssh/id_ed25519
# Your public key has been saved in ~/.ssh/id_ed25519.pub

# Visualizar chave pública
cat ~/.ssh/id_ed25519.pub
# ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... seu_email@exemplo.com

# Comparar com RSA (muito menor!)
ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa_test
ls -lh ~/.ssh/id_*
# -rw------- id_ed25519 (411 bytes)
# -rw-r--r-- id_ed25519.pub (95 bytes)
# -rw------- id_rsa_test (3.2K)
# -rw-r--r-- id_rsa_test.pub (746 bytes)
```

***

### ⚠️ Segurança e Vantagens

#### Por que EdDSA é mais seguro que ECDSA?

| Aspecto                 | ECDSA                | EdDSA                 | Por que EdDSA vence                                   |
| ----------------------- | -------------------- | --------------------- | ----------------------------------------------------- |
| **Aleatoriedade**       | Necessita RNG seguro | Determinístico        | Remove classe inteira de vulnerabilidades (RNG fraco) |
| **Tempo constante**     | Difícil implementar  | Fácil (design)        | Resistente a timing attacks                           |
| **Validação de pontos** | Necessária           | Parte do algoritmo    | Evita invalid curve attacks                           |
| **Vazamento de bits**   | Possível             | Resistente por design | Protege contra side-channel                           |
| **Verificação em lote** | Não suporta          | ✅ Sim                 | 3-5x mais rápida                                      |

#### Ataques Prevenidos por Design

1. **RNG Attack (k repetido)** → **Impossível** (EdDSA é determinístico)
2. **Timing Attack** → **Prevenido** (operação de tempo constante)
3. **Invalid Curve Attack** → **Prevenido** (codificação única)
4. **Fault Attack** → **Prevenido** (verificação embutida)
5. **Side-channel (cache)** → **Resistente** (implementação simples)

***

### 🚀 Performance Comparativa

#### Velocidade (operações por segundo)

| Operação                  | Ed25519 | ECDSA P-256 | RSA-3072 |
| ------------------------- | ------- | ----------- | -------- |
| **Gerar chave**           | 150k    | 100k        | 10k      |
| **Assinar**               | 120k    | 50k         | 8k       |
| **Verificar (único)**     | 60k     | 40k         | 15k      |
| **Verificar (lote, 100)** | 300k    | N/A         | N/A      |

#### Tamanhos

| Item              | Ed25519  | ECDSA P-256 | RSA-3072    |
| ----------------- | -------- | ----------- | ----------- |
| **Chave privada** | 32 bytes | 32 bytes    | \~1.2KB     |
| **Chave pública** | 32 bytes | 33-65 bytes | \~384 bytes |
| **Assinatura**    | 64 bytes | 64 bytes    | 256 bytes   |

***

### 📋 Aplicações do EdDSA

| Aplicação             | Curva          | Uso                                    |
| --------------------- | -------------- | -------------------------------------- |
| **OpenSSH**           | Ed25519        | Autenticação de usuários (recomendado) |
| **Signal**            | Ed25519        | Assinatura de mensagens                |
| **WireGuard**         | Ed25519        | Autenticação da VPN                    |
| **TLS 1.3**           | Ed25519, Ed448 | Assinatura de certificados (opcional)  |
| **GnuPG (GPG)**       | Ed25519        | Assinatura de chaves e emails          |
| **Tor**               | Ed25519        | Assinatura de consensos de rede        |
| **Bitcoin (Taproot)** | Ed25519        | Schnorr signatures (variante)          |
| **OpenBSD**           | Ed25519        | Assinatura de pacotes base             |
| **Android**           | Ed25519        | Keystore (Android 11+)                 |

***

### 🔄 Ed25519 vs ECDSA vs RSA

```bash
# Comparação prática de tamanhos
echo "Comparação de tamanhos:" > /tmp/compare.txt

# Ed25519
ssh-keygen -t ed25519 -f /tmp/ed25519 -N "" -q
wc -c < /tmp/ed25519 >> /tmp/compare.txt
wc -c < /tmp/ed25519.pub >> /tmp/compare.txt

# ECDSA P-256
ssh-keygen -t ecdsa -b 256 -f /tmp/ecdsa -N "" -q
wc -c < /tmp/ecdsa >> /tmp/compare.txt
wc -c < /tmp/ecdsa.pub >> /tmp/compare.txt

# RSA 3072
ssh-keygen -t rsa -b 3072 -f /tmp/rsa -N "" -q
wc -c < /tmp/rsa >> /tmp/compare.txt
wc -c < /tmp/rsa.pub >> /tmp/compare.txt

# Resultados típicos:
# Ed25519:     411 bytes (priv), 95 bytes (pub)
# ECDSA:       ~500 bytes (priv), ~150 bytes (pub)
# RSA-3072:    ~2.4KB (priv), ~600 bytes (pub)
```

***

### 📜 História do EdDSA

| Ano      | Evento                                                    |
| -------- | --------------------------------------------------------- |
| **2005** | Daniel Bernstein publica Curve25519                       |
| **2006** | Curvas de Edwards propostas para criptografia             |
| **2011** | EdDSA é publicado (Bernstein, Duif, Lange, Schwabe, Yang) |
| **2012** | RFC 6637 adiciona suporte a Ed25519 no OpenPGP            |
| **2014** | OpenSSH 6.5 adiciona suporte a Ed25519                    |
| **2015** | WireGuard usa Ed25519                                     |
| **2017** | RFC 8032 padroniza EdDSA (Ed25519 e Ed448)                |
| **2018** | TLS 1.3 adiciona suporte                                  |
| **2020** | Bitcoin Taproot propõe Schnorr (inspirado em Ed25519)     |
| **2023** | NIST FIPS 186-5 inclui Ed25519                            |

***

### 🎯 Resumo Rápido

| Ponto                           | Resumo                                        |
| ------------------------------- | --------------------------------------------- |
| **Função**                      | Assinatura digital moderna                    |
| **Curva recomendada**           | Ed25519 (128 bits de segurança)               |
| **Tamanho assinatura**          | 64 bytes                                      |
| **Determinístico**              | ✅ Não precisa de RNG                          |
| **Resistente a timing attacks** | ✅ Sim (por design)                            |
| **Verificação em lote**         | ✅ Sim (3-5x mais rápido)                      |
| **Quando usar**                 | **Sempre que possível** (substitui ECDSA/RSA) |
| **SSH**                         | `ssh-keygen -t ed25519`                       |

***

### 🔗 Links Úteis

* [RFC 8032 - EdDSA](https://datatracker.ietf.org/doc/html/rfc8032)
* [Ed25519 - Original Paper](https://ed25519.cr.yp.to/)
* [Curve25519 Official Site](https://cr.yp.to/ecdh.html)
* [NaCl (Networking and Cryptography library)](https://nacl.cr.yp.to/)
* [PyNaCl Documentation](https://pynacl.readthedocs.io/)
* [OpenSSH Ed25519](https://www.openssh.com/txt/release-6.5)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://0xmorte.gitbook.io/bibliadopentestbr/conceitos/criptografia/assimetrica/ecc-elliptic-curve-cryptography/eddsa-edwards-curve-digital-signature-algorithm.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
