Package com.frostwire.jlibtorrent
Class Ed25519
java.lang.Object
com.frostwire.jlibtorrent.Ed25519
Ed25519 elliptic curve cryptography for DHT and security operations.
Ed25519 provides a modern elliptic curve public-key signature system used in BitTorrent
for DHT node identification, secure peer communication, and data integrity. Ed25519 is a
variant of the Twisted Edwards curve offering better security and performance than RSA or
traditional ECDSA, with signatures and keys only 32-64 bytes.
Understanding Ed25519:
- Public Key (32 bytes): Shared openly, verifies signatures and receives encrypted messages
- Secret Key (64 bytes): Private key kept secret, used for signing and decryption
- Signature (64 bytes): Proof that a message was signed with a specific secret key
- Seed (32 bytes): Random data that generates a keypair (deterministic)
- Scalar (32 bytes): Parameter for key tweaking operations
Key Generation:
// Create a new random seed
byte[] seed = Ed25519.createSeed(); // 32 random bytes
// Generate keypair from seed
Pair<byte[], byte[]> keypair = Ed25519.createKeypair(seed);
byte[] publicKey = keypair.first; // 32 bytes - can be shared
byte[] secretKey = keypair.second; // 64 bytes - keep private
System.out.println("Public key: " + Hex.encode(publicKey));
System.out.println("Secret key: " + Hex.encode(secretKey));
Digital Signatures:
// Sign a message
byte[] message = "Important data".getBytes();
byte[] signature = Ed25519.sign(message, publicKey, secretKey);
// Verify signature (can be done with public key only)
boolean isValid = Ed25519.verify(signature, message, publicKey);
if (isValid) {
System.out.println("Signature is valid - message is authentic");
} else {
System.out.println("Signature is invalid - message was tampered with or wrong key");
}
// Verification fails if message, signature, or key is changed
byte[] tamperedMessage = "Modified data".getBytes();
Ed25519.verify(signature, tamperedMessage, publicKey); // false
Typical Workflow - DHT Node Identity:
// Node setup (done once, saved for later) byte[] nodeSeed = Ed25519.createSeed(); Pair<byte[], byte[]> nodeKeys = Ed25519.createKeypair(nodeSeed); byte[] nodePublicKey = nodeKeys.first; byte[] nodeSecretKey = nodeKeys.second; // Save these to disk for node persistence // On startup, load the same nodePublicKey and nodeSecretKey // Later: Sign DHT messages byte[] dhtMessage = constructDhtMessage(...); byte[] messageSignature = Ed25519.sign(dhtMessage, nodePublicKey, nodeSecretKey); // Peers verify our identity using nodePublicKey // They can verify without knowing nodeSecretKey
Key Tweaking Operations:
// Scalar operations for advanced key derivation byte[] scalar = ...; // 32-byte scalar parameter // Add scalar to public key (for key derivation) byte[] derivedPublic = Ed25519.addScalarPublic(publicKey, scalar); // Add scalar to secret key (for key derivation) byte[] derivedSecret = Ed25519.addScalarSecret(secretKey, scalar);
Elliptic Curve Diffie-Hellman (ECDH):
// Key exchange to establish shared secret byte[] peerPublicKey = receivePeerPublicKey(); // Both parties can compute the same shared secret byte[] sharedSecret = Ed25519.keyExchange(peerPublicKey, localSecretKey); // Peer does: Ed25519.keyExchange(localPublicKey, peerSecretKey) // Result should be identical (symmetric) // Shared secret can be used as encryption key for further communication
Size Reference:
| Component | Size (bytes) | Bits | Usage |
|---|---|---|---|
| Seed | 32 | 256 | Random data for key generation |
| Public Key | 32 | 256 | Shared openly, for verification/encryption |
| Secret Key | 64 | 512 | Private, for signing/decryption |
| Signature | 64 | 512 | Proof of signing with secret key |
| Scalar | 32 | 256 | Parameter for key operations |
| Shared Secret | 32 | 256 | Symmetric key from ECDH |
Security Properties:
- 256-bit security level (pre-quantum)
- Deterministic signatures (no randomness needed)
- Immune to side-channel timing attacks
- Small key size (32 bytes public key)
- Fast signing and verification
- Used by Signal, WireGuard, and modern protocols
BitTorrent Uses:
- DHT v2 Node IDs: Ed25519 public keys identify nodes (replaces 20-byte SHA-1 IDs)
- Mutable Items: Signed DHT items require Ed25519 signatures
- Peer Authentication: Secure peer verification without certificates
- Protocol Encryption: Key exchange for encrypted peer connections
- See Also:
-
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final intSize of public key: 32 bytes.static final intSize of scalar parameter for key tweaking: 32 bytes.static final intSize of secret (private) key: 64 bytes.static final intSize of the random seed for key generation: 32 bytes.static final intSize of shared secret from key exchange: 32 bytes.static final intSize of signature: 64 bytes. -
Method Summary
Modifier and TypeMethodDescriptionstatic byte[]addScalarPublic(byte[] publicKey, byte[] scalar) static byte[]addScalarSecret(byte[] secretKey, byte[] scalar) static Pair<byte[], byte[]> createKeypair(byte[] seed) static byte[]byte[]keyExchange(byte[] publicKey, byte[] secretKey) static byte[]sign(byte[] message, byte[] publicKey, byte[] secretKey) static booleanverify(byte[] signature, byte[] message, byte[] publicKey)
-
Field Details
-
SEED_SIZE
public static final int SEED_SIZESize of the random seed for key generation: 32 bytes.- See Also:
-
PUBLIC_KEY_SIZE
public static final int PUBLIC_KEY_SIZESize of public key: 32 bytes. This is shared openly.- See Also:
-
SECRET_KEY_SIZE
public static final int SECRET_KEY_SIZESize of secret (private) key: 64 bytes. Keep this private.- See Also:
-
SIGNATURE_SIZE
public static final int SIGNATURE_SIZESize of signature: 64 bytes. Proof of signing with secret key.- See Also:
-
SCALAR_SIZE
public static final int SCALAR_SIZESize of scalar parameter for key tweaking: 32 bytes.- See Also:
-
SHARED_SECRET_SIZE
public static final int SHARED_SECRET_SIZESize of shared secret from key exchange: 32 bytes.- See Also:
-
-
Method Details
-
createSeed
public static byte[] createSeed() -
createKeypair
-
sign
public static byte[] sign(byte[] message, byte[] publicKey, byte[] secretKey) -
verify
public static boolean verify(byte[] signature, byte[] message, byte[] publicKey) -
addScalarPublic
public static byte[] addScalarPublic(byte[] publicKey, byte[] scalar) -
addScalarSecret
public static byte[] addScalarSecret(byte[] secretKey, byte[] scalar) -
keyExchange
public byte[] keyExchange(byte[] publicKey, byte[] secretKey)
-