Coder Social home page Coder Social logo

jedisct1 / rust-ed25519-compact Goto Github PK

View Code? Open in Web Editor NEW
120.0 8.0 21.0 113 KB

Small, wasm-friendly, zero-dependencies Ed25519 and X25519 implementation for Rust.

License: MIT License

Rust 100.00%
crypto rust ed25519 eddsa curve25519 x25519

rust-ed25519-compact's Introduction

GitHub CI

A compact Ed25519 and X25519 implementation for Rust

  • Formally-verified Curve25519 field arithmetic
  • no_std-friendly
  • WebAssembly-friendly
  • Fastly Compute-friendly
  • Lightweight
  • Zero dependencies if randomness is provided by the application
  • Only one portable dependency (getrandom) if not
  • Supports incremental signatures (streaming API)
  • Safe and simple Rust interface

Example usage

cargo.toml:

[dependencies]
ed25519-compact = "2"

Example code:

// A message to sign and verify.
let message = b"test";

// Generates a new key pair using a random seed.
// A given seed will always produce the same key pair.
let key_pair = KeyPair::from_seed(Seed::default());

// Computes a signature for this message using the secret part of the key pair.
let signature = key_pair.sk.sign(message, Some(Noise::default()));

// Verifies the signature using the public part of the key pair.
key_pair
    .pk
    .verify(message, &signature)
    .expect("Signature didn't verify");

// Verification of a different message using the same signature and public key fails.
key_pair
    .pk
    .verify(b"A different message", &signature)
    .expect_err("Signature shouldn't verify");

// All these structures can be viewed as raw bytes simply by dereferencing them:
let signature_as_bytes: &[u8] = signature.as_ref();
println!("Signature as bytes: {:?}", signature_as_bytes);

Incremental API example usage

Messages can also be supplied as multiple parts (streaming API) in order to handle large messages without using much memory:

/// Creates a new key pair.
let kp = KeyPair::generate();

/// Creates a state for an incremental signer.
let mut st = kp.sk.sign_incremental(Noise::default());

/// Feeds the message as any number of chunks, and sign the concatenation.
st.absorb("mes");
st.absorb("sage");
let signature = st.sign();

/// Creates a state for an incremental verifier.
let mut st = kp.pk.verify_incremental(&signature)?;

/// Feeds the message as any number of chunks, and verify the concatenation.
st.absorb("mess");
st.absorb("age");
st.verify()?;

Cargo features

  • self-verify: after having computed a new signature, verify that is it valid. This is slower, but improves resilience against fault attacks. It is enabled by default on WebAssembly targets.
  • std: disables no_std compatibility in order to make errors implement the standard Error trait.
  • random (enabled by default): adds Default implementations to the Seed and Noise objects, in order to securely create random keys and noise.
  • traits: add support for the traits from the ed25519 and signature crates.
  • pem: add support for importing/exporting keys as OpenSSL-compatible PEM files.
  • blind-keys: add support for key blinding.
  • opt_size: Enable size optimizations (based on benchmarks, 8-15% size reduction at the cost of 6.5-7% performance).
  • x25519: Enable support for the X25519 key exchange system.
  • disable-signatures: Disable support for signatures, and only compile support for X25519.

rust-ed25519-compact's People

Contributors

cr1901 avatar jedisct1 avatar lann avatar raphaelahrens avatar wg avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rust-ed25519-compact's Issues

pem feature for no_std?

Hi there, thank you a lot for the amazing library!

I'm trying to use it in a no_std context with the pem feature, which I think, can work with no_std as ct-codecs is no_std.
But due to Cargo limitations, I cannot pass no_std request to the subdependency in the project.

Is there a way to reflect the no_std for pem feature in this project?

Thank you a lot!

Compiling for release mode with debug info on wasm is unreasonably slow

Compiling hangs when building from my M1 MacBook Pro on macOS 13.0 with the following config. Eventually it does build if I leave it for multiple minutes, but this is an order of magnitude more than any of the other deps, so it's not a reasonable DX for us.

It's also at least an order of magnitude slower than building for, e.g. macOS arm64 with the same configuration.
Compiling without debug = true works fine, but I'd like to keep debug info for my Fastly configuration.

Reproduction

mkdir repro && cd repro
cargo init

# replace Cargo.toml with the config below

# hangs (host: macOS arm64):
cargo build --target wasm32-wasi --release

Cargo.toml

# Cargo.toml
[package]
name = "repro"
version = "0.1.0"
authors = []
edition = "2021"

[profile.release]
debug = true

[dependencies]
ed25519-compact = "= 2.0.4"

Error instead of panic if `KeyPair::from_seed()` receives all-zero input

I wanted to ask before potentially opening a PR that I have halfways done. Would you be open the changing the signature of the KeyPair::from_seed() function to return an error instead of panicking on all-zero seed, @jedisct1? This would constitute a semver breaking-change.

I'd like it to, because I'm using KeyPair::from_seed() to check the public key supplied, in order to remove a possible misuse avenue in terms of a public key oracle.

very long compile time when targeting WASM

Hello ๐Ÿ‘‹ this is more of a question: When targeting WASM and including full debug info, building this package is taking multiple minutes. Is there any chance this can be speed up?

To reproduce, running the following takes 3min 20sec on my MacBook Pro M1 Max:

cargo rustc --release --target wasm32-wasi -- -g

Add opt_size feature for embedded environments.

Tracking issue/continuation from jedisct1/rust-hmac-sha256#2.

Things are not going according to plan tonight. Short version; ed25519-compact is very unlikely to fit into the 48kB of easily-accessible flash that I have on my MSP430 part. The microcontroller actually has 128kB of flash (which will barely fit with max size optimizations and the inline changes I've made), but I do not know the linker invocation to accomplish this, nor do I know if LLVM meaningfully supports the 20-bit program counter of MSP430. I'll recompile for an ARM micro I have to test speed at some point soon.

In the meantime, please enjoy this image :D:
image

Zeroizing SecretKey

I believe it is currently impossible to safely zeroize SecretKey since you cannot get mutable access to the underlying array. I'd be happy to write a PR doing one of these, any of which would allow zeroization:

  • Impl zeroize::Zeroize on SecretKey (perhaps behind a feature flag)
  • Impl DerefMut on SecretKey
  • Add SecretKey::into_inner(self) -> [u8; SecretKey::BYTES]

Build failing

I don't know what's the actual issue, but my build of tor-v3-vanity fails due to an issue in this, I think.

$ cargo install --path .
  Installing tor-v3-vanity v0.1.0 (/home/sm/tor-v3-vanity)
    Updating crates.io index
   Compiling ed25519-compact v0.1.8
   Compiling libc v0.2.79
   Compiling miniz_oxide v0.4.3
   Compiling num-traits v0.2.12
   Compiling num-integer v0.1.43
   Compiling crossbeam-utils v0.7.2
   Compiling proc-macro2 v1.0.24
   Compiling syn v1.0.46
   Compiling generic-array v0.14.4
   Compiling typenum v1.12.0
   Compiling getrandom v0.1.15
   Compiling memchr v2.3.3
   Compiling failure_derive v0.1.8
   Compiling serde v1.0.117
   Compiling addr2line v0.13.0
   Compiling regex v0.2.11
   Compiling byteorder v1.3.4
   Compiling regex-syntax v0.5.6
   Compiling semver v0.9.0
   Compiling bitflags v1.2.1
   Compiling maybe-uninit v2.0.0
   Compiling cuda-sys v0.2.0
   Compiling textwrap v0.11.0
   Compiling ed25519 v1.0.3
error[E0432]: unresolved import `std`
 --> /home/sm/.cargo/registry/src/github.com-1ecc6299db9ec823/ed25519-compact-0.1.8/src/ed25519.rs:5:5
  |
5 | use std::fmt;
  |     ^^^ use of undeclared type or module `std`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0432`.
error: could not compile `ed25519-compact`.

To learn more, run the command again with --verbose.
warning: build failed, waiting for other jobs to finish...
error: failed to compile `tor-v3-vanity v0.1.0 (/home/sm/tor-v3-vanity)`, intermediate artifacts can be found at `/home/sm/tor-v3-vanity/target`

Caused by:
  build failed

Related: dr-bonez/tor-v3-vanity#4

Ed25519 ECDH

Hey there, we're using this great library to implement an authenticated handshake between nodes that run on user machines. Users are also able to sign objects with their node key and it's important to be able to authenticate user nodes with the same key as the one they sign objects with. We've identified three potential ways to make this happen:

  1. Do the ECDH using ed25519 -- this would require the functionality be implemented in this library
  2. Move to ristretto255, which has library support for both ECDH and signing.
  3. Use an unauthenticated handshake, eg. Noise_NN with x25519, and do ed25519 authentication by sending certificates on the secure channel

The issue with (2) is that we store private keys in SSH format and make heavy use of ssh-agent, so moving to ristretto255 is not that straightforward. (3) is what we currently have, but it seems sub-optimal to have another roundtrip and protocol just for this, when DH is basically the right tool for the job.

I know it's possible to do ECDH with ed25519, just slower, and was hoping you'd consider adding support to your library, if you think it makes sense!

Cheers

Ability to convert Ed25519 key to X25519

For our use case in radicle, we need nodes to identify with their signing key, but be able to carry out a DH exchange. I know that libsodium has a function to convert between the two key types, and there is also the possibility of doing the DH math with an Ed25519 key.

Would you be open in supporting either of those functions here, or alternatively giving access to the underlying values so that it can be implemented manually?

Possible bug in master/src/ed25519.rs#L241

Hi,

There seems to be a bug in this line that causes the if-else clause to always resolve in the else option:
https://github.com/jedisct1/rust-ed25519-compact/blob/master/src/ed25519.rs#L241

Please, look into it. Transactions that require signatures fail because of this error.

Calling this smart contract function:
https://github.com/XP-NETWORK/xp-casper-integration/blob/production/src/main.rs#L179-L209

Getting this error:
https://testnet.cspr.live/deploy/f5b081d9eaa2a860ea1b593ce65fdd85153539cfbefebe9cedfd0c8386b67680

`--no-default-features` build is broken

Seems we require pub fn from_bytes_vartime(s: &[u8; 32]) -> Option<GeP3> {} in --no-default-features build (since 07db2db), even though it's gated behind #[cfg(any(feature = "x25519", feature = "blind-keys"))]. Not sure if you intended on using something else here @jedisct1, or if the feature-gate can just be removed?

Ability to convert X25519 to Ed25519

You did a very fast and nice job #18

However there is an opposite usecase: at the completion of Noise_XK handshake we know the remote Curve25519 key (used for X25519), but we need to match it against the SSH key of the node, which is Edwards25519 key. Would it be possible to have the opposite direction of the conversion?

Thank you!

Feature-change for `>= 1.0.13` regarding `signatures` imports

This is not a bug per se. I'm not even entirely sure what the correct action is in this case, but I thought I'd mention it anyway. With versions 1.0.13 and onward, a new feature signatures was introduced. AFAIU, this constitutes a minor SemVer version bump, according to API Evolution RFC. I'd have though this would require a 1.1.x version, instead.

Feel free to close this @jedisct1, if this was intentional.

In case anyone else had their ed25519-compact on non-default-features, pulled in signature-related types and their build broke: this can be fixed by adding "signatures" to selected features of this crate.

Feature request: Add `Drop` impl and `DerefMut` for all `PublicKey` types

While PublicKeys are, by definition, public, and leaking them is not that dangerous in theory, in practice finding where a public key is in memory can help find where crypto code is situated more easily and watch for it. It can also confirm which type of crypto is used based on the key length and format.

I'm happy to implement it if you would accept such a feature.

Implementing Drop would need a 3.0.0 because PublicKeys are Copy at the moment. Implementing DerefMut would not, so we could do that in as a first helper ?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.