Skip to content

ED25519 ​

ED25519 is an elliptic curve digital signature algorithm that uses the Curve25519 elliptic curve and Edwards coordinates. dongle supports standard and streaming ED25519 digital signatures, providing fast and secure signing and verification functionality.

ED25519 algorithm features:

  • High Performance: Fast signing and verification speed, better performance than traditional RSA algorithms
  • High Security: Uses 256-bit elliptic curve, providing security strength equivalent to 3072-bit RSA
  • Compact Keys: Public and private key lengths are only 32 bytes, signature length is 64 bytes
  • Side-Channel Attack Resistant: Algorithm design naturally resists timing attacks and other side-channel attacks
  • Deterministic Signatures: Signature results are deterministic for the same data, convenient for testing and debugging

Important Notes:

  • Key Format: Uses PKCS#8 private keys and SPKI/PKIX public keys by default; when setting keys it also accepts raw key material (a 32-byte seed, a 64-byte private key, a 32-byte public key) and base64/hex encoded DER
  • Key Length: ED25519 uses fixed-length keys, no need to choose key length
  • Hash Algorithm: ED25519 internally uses SHA-512 hash, no need to specify additional hash algorithm
  • Private Key Security: Private keys must be properly protected and cannot be leaked, only the private key holder can generate valid signatures
  • Signature Verification: Anyone can use the public key to verify the validity of signatures
  • Compatibility: ED25519 is a modern cryptographic standard with widespread support

Import related modules:

go
import (
    "github.com/dromara/dongle"
    "github.com/dromara/dongle/crypto/keypair"
)

Create key pair ​

go
kp := keypair.NewEd25519KeyPair()

Generate key pair ​

go
// Generate ED25519 key pair
err := kp.GenKeyPair()
if err != nil {
    panic(err)
}

// Get PEM format public key
publicKey := kp.PublicKey  
// Get PEM format private key
privateKey := kp.PrivateKey

Set key pair from existing PEM format keys ​

go
// Set PEM format public key
kp.PublicKey = []byte(`-----BEGIN PUBLIC KEY-----
MCowBQYDK2VwAyEA4rUw82pvYFUDIWmnUKuHTnueHB3OzgAwR3ADXHQh/GQ=
-----END PUBLIC KEY-----`)

// Set PEM format private key
kp.PrivateKey = []byte(`-----BEGIN PRIVATE KEY-----
MC4CAQAwBQYDK2VwBCIEIHZ5DPAF8Gdrkwjp1pPd+aYY+9DqDpTVzHXIllrsdx4l
-----END PRIVATE KEY-----`)

Set key pair from existing DER format keys ​

Besides base64 encoded DER, SetPublicKey / SetPrivateKey also accept hex encoded DER, raw DER, a raw 32-byte public key, a 32-byte seed and a 64-byte private key, and normalize the result to PEM.

go
// Set base64 encoded DER format public key
kp.SetPublicKey([]byte("MCowBQYDK2VwAyEA4rUw82pvYFUDIWmnUKuHTnueHB3OzgAwR3ADXHQh/GQ="))
// Set base64 encoded DER format private key
kp.SetPrivateKey([]byte("MC4CAQAwBQYDK2VwBCIEIHZ5DPAF8Gdrkwjp1pPd+aYY+9DqDpTVzHXIllrsdx4l"))

Format DER format keys to PEM format ​

go
// Format `base64` encoded `DER` format public key to `PEM` format public key
publicKey, err := kp.FormatPublicKey([]byte("MCowBQYDK2VwAyEA4rUw82pvYFUDIWmnUKuHTnueHB3OzgAwR3ADXHQh/GQ="))

// Format `base64` encoded `DER` format private key to `PEM` format private key
privateKey, err := kp.FormatPrivateKey([]byte("MC4CAQAwBQYDK2VwBCIEIHZ5DPAF8Gdrkwjp1pPd+aYY+9DqDpTVzHXIllrsdx4l"))

Compress PEM format keys to DER format ​

go
// Compress PEM format public key to base64 encoded DER format (extract the base64 encoded DER from the PEM block)
publicKey := kp.CompressPublicKey([]byte(`-----BEGIN PUBLIC KEY-----
MCowBQYDK2VwAyEA4rUw82pvYFUDIWmnUKuHTnueHB3OzgAwR3ADXHQh/GQ=
-----END PUBLIC KEY-----`))

// Compress PEM format private key to base64 encoded DER format (extract the base64 encoded DER from the PEM block)
privateKey := kp.CompressPrivateKey([]byte(`-----BEGIN PRIVATE KEY-----
MC4CAQAwBQYDK2VwBCIEIHZ5DPAF8Gdrkwjp1pPd+aYY+9DqDpTVzHXIllrsdx4l
-----END PRIVATE KEY-----`))

Private key signing ​

Input data ​

go
// Input string
signer := dongle.Sign.FromString("hello world").ByEd25519(kp)
// Input byte slice
signer := dongle.Sign.FromBytes([]byte("hello world")).ByEd25519(kp)
// Input file stream
file, _ := os.Open("test.txt")
signer := dongle.Sign.FromFile(file).ByEd25519(kp)

// Check signing error
if signer.Error != nil {
	fmt.Printf("Signing error: %v\n", signer.Error)
	return
}

Output data ​

go
// Output Hex-encoded signature string
hexString := signer.ToHexString() // a1b2c3d4e5f6...
// Output Hex-encoded signature byte slice
hexBytes := signer.ToHexBytes()  // []byte("a1b2c3d4e5f6...")

// Output Base64-encoded signature string
base64String := signer.ToBase64String() // obbD1OX2...
// Output Base64-encoded signature byte slice
base64Bytes := signer.ToBase64Bytes()  // []byte("obbD1OX2...")

// Output raw signature string
rawString := signer.ToRawString()
// Output raw signature byte slice
rawBytes := signer.ToRawBytes()

Public key verification ​

Input data ​

Note: The WithXxxSign method must be called before ByEd25519

go
// Input string
verifier := dongle.Verify.FromString("hello world")
// Input byte slice
verifier := dongle.Verify.FromBytes([]byte("hello world"))
// Input file stream
file, _ := os.Open("test.txt")
verifier := dongle.Verify.FromFile(file)

// Set Hex-encoded signature
verifier.WithHexSign(hexBytes).ByEd25519(kp)
// Set Base64-encoded signature
verifier.WithBase64Sign(base64Bytes).ByEd25519(kp)
// Set raw signature
verifier.WithRawSign(rawBytes).ByEd25519(kp)

// Check verification errors
if verifier.Error != nil {
    fmt.Printf("Verification error: %v\n", verifier.Error)
    return
}

Output data ​

go
// Output verification result
verifier.ToBool() // true or false

Released under the MIT License, unauthorized reproduction is prohibited in any form