Ed25519
Ed25519¶
\[-x^{2} + y^{2} = 1 - (121665 / 121666) * x^{2} * y^{2} (mod 2^{255} - 19) \]
生成密钥对¶
import base64
from cryptography.exceptions import InvalidSignature
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import ed25519
def generate_ed25519_key_pair(format_type=None):
private_key_obj = ed25519.Ed25519PrivateKey.generate()
pubkey_obj = private_key_obj.public_key()
if not format_type:
return private_key_obj, pubkey_obj
private_bytes = private_key_obj.private_bytes(
encoding=serialization.Encoding.Raw,
format=serialization.PrivateFormat.Raw,
encryption_algorithm=serialization.NoEncryption()
)
public_bytes = pubkey_obj.public_bytes(
encoding=serialization.Encoding.Raw,
format=serialization.PublicFormat.Raw
)
if format_type == "hex":
return private_bytes.hex(), public_bytes.hex()
elif format_type == "base64":
private_key = base64.b64encode(private_bytes).decode()
pubkey = base64.b64encode(public_bytes).decode()
return private_key, pubkey
elif format_type == "bytes":
return private_bytes, public_bytes
else:
raise Exception("Invalid format type")
private_key, public_key = generate_ed25519_key_pair("hex")
import * as ed from '@noble/ed25519';
const Uint8ToBase64String = (u8a: any) => {
return btoa(String.fromCharCode.apply(null, u8a));
};
const GenerateEd25519KeyPair = async (exportType: string) => {
let privateObj = ed.utils.randomPrivateKey();
let pubkeyObj = await ed.getPublicKey(privateObj);
let PrivateKey = '',
PublicKey = '';
if (exportType == 'base64') {
PrivateKey = Uint8ToBase64String(privateObj);
PublicKey = Uint8ToBase64String(pubkeyObj);
} else if ((exportType = 'hex')) {
PrivateKey = ed.utils.bytesToHex(privateObj);
PublicKey = ed.utils.bytesToHex(pubkeyObj);
}
return {
PrivateKey,
PublicKey,
};
};
签名¶
import base64
from cryptography.exceptions import InvalidSignature
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import ed25519
def load_ed25519_private_key_from_hex(private_key_hex: str):
return ed25519.Ed25519PrivateKey.from_private_bytes(bytes.fromhex(private_key_hex))
def ed25519_sign(private_key_hex: str, plain_text: str):
private_key = load_ed25519_private_key_from_hex(private_key_hex)
signature = private_key.sign(plain_text.encode('utf-8'))
return signature
import (
"crypto/ed25519"
"crypto/rand"
"encoding/hex"
)
func GenerateEd25519Signature(privateHex string, data string) (string, error) {
keySeed, err := hex.DecodeString(privateHex)
if err != nil {
return "", err
}
resultByte := ed25519.Sign(ed25519.NewKeyFromSeed(keySeed), []byte(data))
return hex.EncodeToString(resultByte)
}
验证签名¶
from cryptography.exceptions import InvalidSignature
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import ed25519
def load_ed25519_pubkey_from_hex(pubkey_hex: str):
return ed25519.Ed25519PublicKey.from_public_bytes(bytes.fromhex(pubkey_hex))
def ed25519_verify(pub_key_hex: str, signature: bytes, plain_text: str):
pubkey = load_ed25519_pubkey_from_hex(pub_key_hex)
try:
pubkey.verify(signature, plain_text.encode('utf-8'))
except InvalidSignature:
return False
else:
return True
func Ed25519Verify(keyFormat string, pubkey string, msg string, signatureStr string) (bool, error) {
msgByte := []byte(msg)
if pubkey == "" {
return false, errors.New("invalid pubkey")
}
pubKey, err := hex.DecodeString(pubkey)
if err != nil {
return false, err
}
var signature string
var err error
if keyFormat == "hex" {
signature, err = hex.DecodeString(signatureStr)
if err != nil {
return false, err
}
} else if keyFormat == "base64" {
signature, err = base64.StdEncoding.DecodeString(signatureStr)
if err != nil {
return false, err
}
}
isValid := ed25519.Verify(pubKey, msgByte, signature)
return isValid, nil
}