Aller au contenu
ecdsa.com
C

libsodium

libsodium de Frank Denis, le fork portable de NaCl : signatures Ed25519 avec une vérification stricte, X25519, chiffrement authentifié, ainsi que ML-KEM-768 et le KEM hybride X-Wing, mais aucun ECDSA.
Licence
ISC
Version vérifiée
1.0.22 ·
Code source
github.com/jedisct1/libsodium
Documentation
doc.libsodium.org/

Compatibilité en un coup d’œil

EdDSAPost-quantique

EdDSA
Ed25519Ed25519ph
Formats de clé privée
seed-32expanded-64

libsodium propose un petit ensemble de primitives aux choix tranchés, derrière des fonctions difficiles à mal utiliser ; elle est intégrée à PHP, utilisée par de nombreux bindings dans d’autres langages et embarquée dans des applications de messagerie. Les signatures se limitent à Ed25519 : les en-têtes de la 1.0.22 (vérifiés sur le paquet Alpine 3.24.2) ne déclarent aucune fonction ECDSA, si bien que tout ce qui utilise ES256 ou secp256k1 nécessite une autre bibliothèque.

La signature Ed25519 est déterministe, comme le prévoit la RFC 8032 (deux signatures du même message étaient identiques), et les fonctions crypto_sign_*_ph implémentent Ed25519ph, dont les signatures ne sont pas interchangeables avec celles d’Ed25519 simple : lors des essais, le vérificateur simple en a rejeté une. La clé secrète fait 64 octets (la graine de 32 octets suivie de la clé publique), alors que la plupart des autres bibliothèques ne stockent que la graine ; crypto_sign_ed25519_sk_to_seed et crypto_sign_seed_keypair permettent de passer de l’une à l’autre, comme le montre l’exemple.

La vérification est stricte là où les implémentations divergent. Une signature dont S a été remplacé par S + L (la même valeur modulo l’ordre du groupe, ce que la RFC 8032 interdit) a été rejetée, tout comme une signature vérifiée avec l’élément neutre, un point de petit ordre, comme clé publique. Les bibliothèques qui acceptent ces entrées sont en désaccord avec libsodium sur ces cas limites, ce qui compte pour les systèmes de consensus qui doivent s’accorder sur la validité. crypto_sign_verify_detached ne prend pas de longueur de signature et lit exactement 64 octets : vérifiez donc la longueur avant de l’appeler.

Dans la 1.0.22, la prise en charge post-quantique se limite à l’encapsulation de clés : crypto_kem_mlkem768_* (clés publiques de 1184 octets, textes chiffrés de 1088 octets) et le KEM hybride X-Wing (crypto_kem_xwing_*, 1216 et 1120 octets), qui est aussi celui qu’utilisent par défaut les fonctions génériques crypto_kem_*. Il n’y a ni ML-DSA ni aucune autre signature post-quantique. Les clés sont partout des octets bruts (clés publiques et graines de 32 octets), sans prise en charge de PEM, DER ou JWK. Comparez les tailles des KEM dans le bac à sable des KEM post-quantiques.

Les faits et les vérifications qui les fondent

Rien de ce qui suit n’est copié d’une documentation. La vérification content/libraries/verify/libsodium/run.sh a exécuté libsodium 1.0.22 dans l’image de conteneur alpine:3.24.2 le 20 octobre 2026 ; la page doit correspondre à ce que la vérification a affiché, et chaque fait cite les lignes en question.

  • Courbes ECDSA

    none

    Pas d’ECDSA : crypto_sign_PRIMITIVE vaut ed25519 et aucun en-tête ne déclare de fonction ECDSA.

    Relevé par la vérification
    fact ecdsa-curves = none
    evidence ecdsa-curves: crypto_sign_PRIMITIVE is "ed25519"; the header set declares no ECDSA functions
  • EdDSA

    Ed25519Ed25519ph

    Ed25519 via crypto_sign_* et Ed25519ph via crypto_sign_init, _update et _final_* ; le vérificateur simple rejette les signatures Ed25519ph.

    Relevé par la vérification
    fact eddsa = Ed25519, Ed25519ph
    evidence eddsa: crypto_sign_final_verify (Ed25519ph) accepts its signature: yes; the plain verifier rejects it: yes
  • Signatures Ed25519 déterministes

    yes

    Deux signatures du même message avec la même clé étaient identiques.

    Relevé par la vérification
    fact ed25519-deterministic = yes
  • Structure de la clé privée Ed25519

    expanded-64

    crypto_sign_SECRETKEYBYTES vaut 64 : la graine suivie de la clé publique.

    Relevé par la vérification
    fact ed25519-private-key = expanded-64
    evidence ed25519-private-key: crypto_sign_SECRETKEYBYTES = 64: the 32-byte seed followed by the 32-byte public key (seed matches: yes)
  • Signature Ed25519 avec S non canonique

    rejected

    Une signature dont S a été remplacé par S + L a été rejetée.

    Relevé par la vérification
    fact ed25519-non-canonical-s = rejected
  • Clé publique Ed25519 de petit ordre

    rejected

    Avec l’élément neutre comme clé publique, la vérification a abouti à un rejet.

    Relevé par la vérification
    fact ed25519-small-order-key = rejected
    evidence ed25519-small-order-key: the identity point as public key with R = identity, S = 0
  • Signature Ed25519 mal formée

    rejected

    64 octets de données arbitraires ont fait renvoyer -1 à crypto_sign_verify_detached.

    Relevé par la vérification
    fact ed25519-malformed-signature = rejected
    evidence ed25519-malformed-signature: 64 bytes of 0xab: crypto_sign_verify_detached returned -1; the function takes no length and reads exactly crypto_sign_BYTES = 64 bytes
  • Modes de signature

    detachedcombined

    Les signatures détachées (64 octets) et les messages signés combinés (signature placée avant le message) sont tous deux disponibles.

    Relevé par la vérification
    fact signature-modes = detached, combined
    evidence signature-modes: crypto_sign prepends the 64-byte signature to the message: 82 bytes for a 18-byte message
  • Algorithmes post-quantiques

    ML-KEMX-Wing

    Encapsulation et décapsulation réussies avec ML-KEM-768 (crypto_kem_mlkem768_*) et X-Wing (crypto_kem_xwing_*, l’algorithme par défaut des fonctions génériques crypto_kem_*) ; il n’y a pas de signatures post-quantiques.

    Relevé par la vérification
    fact pqc = ML-KEM, X-Wing
    evidence pqc: crypto_kem_mlkem768: public key 1184 bytes, ciphertext 1088 bytes
    evidence pqc: crypto_kem_xwing: public key 1216 bytes, ciphertext 1120 bytes; generic crypto_kem_primitive() is "xwing"
  • Formats de clé publique

    raw-32

    Les clés publiques font 32 octets bruts ; PEM, DER et JWK ne sont pas pris en charge.

    Relevé par la vérification
    fact public-key-formats = raw-32
  • Formats de clé privée

    seed-32expanded-64

    Les clés dérivent d’une graine de 32 octets (crypto_sign_seed_keypair) et sont stockées sur 64 octets ; crypto_sign_ed25519_sk_to_seed récupère la graine.

    Relevé par la vérification
    fact private-key-formats = seed-32, expanded-64
    evidence private-key-formats: crypto_sign_seed_keypair reproduces the key from the seed: yes; crypto_sign_ed25519_sk_to_seed recovers it: yes

Utilisation

Générer une clé Ed25519, extraire la graine de 32 octets qu’attendent les autres bibliothèques, puis signer et vérifier une signature détachée.
#include <sodium.h>
#include <stdio.h>
#include <string.h>

int main(void) {
    if (sodium_init() < 0) return 1;
    const unsigned char msg[] = "order #1042 approved";
    unsigned char pk[crypto_sign_PUBLICKEYBYTES], sk[crypto_sign_SECRETKEYBYTES];
    unsigned char sig[crypto_sign_BYTES], seed[32];

    crypto_sign_keypair(pk, sk);
    /* Other libraries store the 32-byte seed; libsodium's secret key is seed || public key. */
    crypto_sign_ed25519_sk_to_seed(seed, sk);

    /* Detached signature: 64 bytes, deterministic per RFC 8032. */
    crypto_sign_detached(sig, NULL, msg, sizeof msg - 1, sk);
    int ok = crypto_sign_verify_detached(sig, msg, sizeof msg - 1, pk) == 0;

    printf("secret key %d bytes, seed %zu bytes, signature %d bytes, verified: %d\n",
           crypto_sign_SECRETKEYBYTES, sizeof seed, crypto_sign_BYTES, ok);
    return 0;
}

Le banc de test des extraits de code exécute chaque exemple tel quel dans l’image de conteneur alpine:3.24.2, et l’exécution échoue si la sortie ne correspond pas.

Mise en place
apk add --no-cache -q build-base libsodium-dev=1.0.22-r0 >/dev/null
Commande
cc -o usage usage.c -lsodium && ./usage
La sortie doit correspondre à cette expression régulière
secret key 64 bytes, seed 32 bytes, signature 64 bytes, verified: 1

Bibliothèques