#ed25519 #signature #ed25519-key #curve25519 #ecc

no-std noah-ed25519-dalek

使用纯Rust实现的快速高效的ed25519 EdDSA密钥生成、签名和验证

1个稳定版本

4.0.0 2022年12月29日

#2488加密

Download history 37/week @ 2024-03-12 24/week @ 2024-03-19 33/week @ 2024-03-26 48/week @ 2024-04-02 20/week @ 2024-04-09 46/week @ 2024-04-16 38/week @ 2024-04-23 34/week @ 2024-04-30 31/week @ 2024-05-07 34/week @ 2024-05-14 30/week @ 2024-05-21 35/week @ 2024-05-28 31/week @ 2024-06-04 39/week @ 2024-06-11 39/week @ 2024-06-18 18/week @ 2024-06-25

138 每月下载量
4 个crate中使用 (3个直接使用)

BSD-3-Clause

105KB
1.5K SLoC

Noah中的ed25519-dalek分支

此crate是ed25519-dalek的分支,包含一些依赖更新。

有关更多信息,请参阅原始仓库。我们计划在ed25519-dalek 4.0准备就绪时切换。


lib.rs:

ed25519密钥生成、签名和验证的Rust实现。

示例

在消息上创建ed25519签名很简单。

首先,我们需要生成一个Keypair,它包含非对称密钥的公共和私钥部分。为此,我们需要一个加密安全的伪随机数生成器(CSPRNG)。在这个示例中,我们将使用操作系统的内置PRNG

extern crate rand;
extern crate noah_ed25519_dalek;

use rand::rngs::OsRng;
use noah_ed25519_dalek::Keypair;
use noah_ed25519_dalek::Signature;

let mut csprng = OsRng{};
let keypair: Keypair = Keypair::generate(&mut csprng);
#

现在我们可以使用这个keypair来签名一个消息

use noah_ed25519_dalek::{Signature, Signer};
let message: &[u8] = b"This is a test of the tsunami alert system.";
let signature: Signature = keypair.sign(message);

同时,验证这确实是在该message上的有效签名

use noah_ed25519_dalek::Verifier;
assert!(keypair.verify(message, &signature).is_ok());

任何人,只要有了keypair的公共部分,都可以轻松验证此签名

use noah_ed25519_dalek::{PublicKey, Verifier};

let public_key: PublicKey = keypair.public_key();
assert!(public_key.verify(message, &signature).is_ok());

序列化

PublicKeySecretKeyKeypairSignature可以通过调用.to_bytes()序列化为字节数组。将这些字节传输和/或存储是完全可以接受和安全的。(当然,永远不要将您的私钥转交给其他人,因为验证您的签名只需要公钥!)

use noah_ed25519_dalek::{PUBLIC_KEY_LENGTH, SECRET_KEY_LENGTH, KEYPAIR_LENGTH, SIGNATURE_LENGTH};

let public_key_bytes: [u8; PUBLIC_KEY_LENGTH] = keypair.public_key().to_bytes();
let secret_key_bytes: [u8; SECRET_KEY_LENGTH] = keypair.secret_key().to_bytes();
let keypair_bytes:    [u8; KEYPAIR_LENGTH]    = keypair.to_bytes();
let signature_bytes:  [u8; SIGNATURE_LENGTH]  = signature.to_bytes();

同样,可以使用::from_bytes()从字节中解码

#
let public_key: PublicKey = PublicKey::from_bytes(&public_key_bytes)?;
let secret_key: SecretKey = SecretKey::from_bytes(&secret_key_bytes)?;
let keypair:    Keypair   = Keypair::from_bytes(&keypair_bytes)?;
let signature:  Signature = Signature::try_from(&signature_bytes[..])?;
#

使用Serde

如果您更喜欢将字节封装在另一种序列化格式中,所有类型都通过构建ed25519-dalek通过内置serde支持。

$ cargo build --features="serde"

它们可以被序列化为serde支持的所有线格式之一。例如,使用bincode


use bincode::serialize;

let encoded_public_key: Vec<u8> = serialize(&public_key).unwrap();
let encoded_signature: Vec<u8> = serialize(&signature).unwrap();

在发送encoded_public_keyencoded_signature之后,接收方可以反序列化它们并进行验证

#
use bincode::deserialize;

let message: &[u8] = b"This is a test of the tsunami alert system.";
let decoded_public_key: PublicKey = deserialize(&encoded_public_key).unwrap();
let decoded_signature: Signature = deserialize(&encoded_signature).unwrap();

#
let verified: bool = decoded_public_key.verify(&message, &decoded_signature).is_ok();

assert!(verified);

依赖项

~5MB
~106K SLoC