Giter Club home page Giter Club logo

x25519-dalek's People

Contributors

debugsteven avatar dignifiedquire avatar dlblv avatar eaon avatar exfalso avatar hdevalence avatar huitseeker avatar isislovecruft avatar jack-michaud avatar mcginty avatar newpavlov avatar oblazy avatar oleganza avatar paulgrandperrin avatar peat avatar pinkforest avatar rozbb avatar striezel avatar tarcieri avatar untoldwind avatar zer0x64 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

x25519-dalek's Issues

Reexport rand_core

There are issues with conflicting versions of rand_core since x25519 does not use the latest version. It would be helpful if rand_core was exported to avoid conflicts

Types with Drop to hold the secret keys (and others if needed)

libsodium provides a mem-zeroing functionality which gets called from the rust versions (e.g. rust_sodium) for at-least all the secret keys which are user-defined types with Drop. There is no such management in dalek. Just wandering on what the opinions are on this:

  • It is important and we need it and dalek is ready to provide it
  • It is important but the user is expected to do the wrapping but dalek wouldn't see this as its goal
  • It's not needed (if so any reasons would be good to know)

Consider adding support for serde

It would be nice if the PublicKey would derive serde::Serialize and serde::Deserialize. Serde is the most used serialization library for Rust, and is presumably used a lot in network communication.

Serde support would change the following code:

enum NetworkPacket {
    SendPublicKey([u8; 32])
}

// sender
let key: PublicKey = ...;
let bytes = bincode::serialize(&NetworkPacket::SendPublicKey(key.as_bytes().clone())).unwrap();
// receiver
let buffer: &[u8] = ..;
let packet: NetworkPacket = bincode::deserialize(buffer).unwrap();
match packet {
    NetworkPacket::SendPublicKey(key) => {
        let key: PublicKey = key.into();
    }
}

To:

enum NetworkPacket {
    SendPublicKey(PublicKey)
}

// sender
let key: PublicKey = ...;
let bytes = bincode::serialize(&NetworkPacket::SendPublicKey(key)).unwrap();
// receiver
let buffer: &[u8] = ..;
let packet: NetworkPacket = bincode::deserialize(buffer).unwrap();
match packet {
    NetworkPacket::SendPublicKey(key) => {
        // key is already of type `PublicKey`
    }
}

Which is slightly nicer to work with.

This could also be implemented for StaticSecret, as this is intended to be able to be saved and loaded.

I'd suggest adding a feature called serde, which enables/disables the serde dependency and is disabled by default. When this feature is enabled, PublicKey implements serde::Serialize and serde::Deserialize.

I can implement this if you want me to.

`x25519_dalek::PublicKey::from` generates a different public key compared to OpenSSL when using the same private key

I am testing this crate (v1.2.0) using a ED25519 key pair generated by OpenSSL 1.1.1o FIPS 3 May 2022, and checking for correct DH shared secret generation against a x25519_dalek::EphemeralSecret based key pair.

The issue I am seeing is that starting from the private key generated by OpenSSL, the pubic key generated by PublicKey::from for that private key is different from what OpenSSL generated. Am I using the APIs correctly? What is the correct way to use existing key pairs?

// Parse existing private key
let alice_priv_key = pkcs8::KeypairBytes::from_pkcs8_pem(PRIV_KEY).unwrap();
// Parse existing public key
let alice_pub_key = pkcs8::PublicKeyBytes::from_public_key_pem(PUB_KEY).unwrap();

// Define Alice's ed25519 pair
let alice_secret = StaticSecret::from(alice_priv_key.secret_key);
let alice_public = PublicKey::from(&alice_secret);

let parsed_existing_public = PublicKey::from(alice_pub_key.to_bytes());
// This should not fail
assert_eq!(alice_public.to_bytes()[..], parsed_existing_public.to_bytes()[..]);

The complete test code

#[cfg(test)]
mod tests {
    fn init() {
        let _ = env_logger::builder().is_test(true).try_init();
    }

    /* Creating the ED25519 key pairs
    $ openssl genpkey -algorithm ED25519 > private.pem
    $ openssl pkey -outform PEM -pubout -in private.pem > public.pem
    */

    static PUB_KEY: &str = "-----BEGIN PUBLIC KEY-----
MCowBQYDK2VwAyEADOuQ5lqOanpHOtLV2gqqcYuYkJrdpNueHJ7M9ejY3M0=
-----END PUBLIC KEY-----";

    static PRIV_KEY: &str = "-----BEGIN PRIVATE KEY-----
MC4CAQAwBQYDK2VwBCIEINLDN5YuEgo6Z5G+ww0kTv33KyQrPN1O+vdeet74+cVm
-----END PRIVATE KEY-----";

    mod test_ed25519_dh {
        use ed25519::pkcs8;
        use ed25519::pkcs8::{DecodePrivateKey, DecodePublicKey, EncodePublicKey};
        use rand_core::OsRng;
        use x25519_dalek::StaticSecret;
        use x25519_dalek::{EphemeralSecret, PublicKey};

        #[test]
        fn test_ed25519_dh() {
            super::init();

            // Parse existing private key
            let mut alice_priv_key = pkcs8::KeypairBytes::from_pkcs8_pem(super::PRIV_KEY).unwrap();
            // Parse existing public key
            let alice_pub_key = pkcs8::PublicKeyBytes::from_public_key_pem(super::PUB_KEY).unwrap();

            // Define Alice's ed25519 pair
            let alice_secret = StaticSecret::from(alice_priv_key.secret_key);
            let alice_public = PublicKey::from(&alice_secret);

            // Dump the generated public key to stdout
            alice_priv_key.public_key = Some(alice_public.to_bytes());
            let alice_public_other_form = pkcs8::PublicKeyBytes::try_from(&alice_priv_key).unwrap();
            log::debug!(
                "Alice generated public key as PEM:\n{}",
                alice_public_other_form
                    .to_public_key_pem(base64ct::LineEnding::LF)
                    .unwrap()
            );
            /* This is not what OpenSSL generated, shown in PUB_KEY
               -----BEGIN PUBLIC KEY-----
               MCowBQYDK2VwAyEAUSd2eTv0CdgCpnccB3re+kxjo9miMQV9Di9SFHc/PQ4=
               -----END PUBLIC KEY-----
            */

            let parsed_existing_public = PublicKey::from(alice_pub_key.to_bytes());
            // This should not fail
            assert_eq!(
                alice_public.to_bytes()[..],
                parsed_existing_public.to_bytes()[..]
            );

            // Create Bob's ed25519 pair
            let bob_secret = EphemeralSecret::new(OsRng);
            let bob_public = PublicKey::from(&bob_secret);

            // Define the shared secrets
            let alice_shared_secret = alice_secret.diffie_hellman(&bob_public);
            let bob_shared_secret = bob_secret.diffie_hellman(&alice_public);

            assert_eq!(
                alice_shared_secret.as_bytes()[..],
                bob_shared_secret.as_bytes()[..]
            );
        }
    }
}

Do you really need to borrow self here?

pub fn diffie_hellman(self, their_public: &PublicKey) -> SharedSecret {

I am trying to use this function however my ephemeral key is a pointer and it has to be that way due to some other packages I am using. Is there a reason that the self on this line of code can't just be &self?

P.S, I am sorry if I did something wrong here. This is my first time submitting an issue on GitHub.

Show byte arrays as a hex string in Debug impls, not an expanded array

When a debug-format x25519::PublicKey, I get some very long output (see below). But it would be much easier to read and copy shorter hex-encoded output.

Expected output:

ephemeral_key: PublicKey(
    MontgomeryPoint("ed...")
)

Actual output:

ephemeral_key: PublicKey(
    MontgomeryPoint(
        [
            237,
            202,
            200,
            4,
            252,
            109,
            173,
            91,
            83,
            6,
            112,
            86,
            76,
            54,
            29,
            134,
            199,
            218,
            161,
            12,
            26,
            129,
            61,
            228,
            212,
            40,
            55,
            96,
            130,
            233,
            89,
            70,
        ],
    ),
),

Serializing EphemeralPublic

We need to serialize EphemeralPublic (over here) to an array of bytes so we can share it between network participants.

I see that the underlying MontgomeryPoint has a to_bytes() function, but this is inaccessible due to the fact that EphemeralPublic doesn't expose any such function, and the underlying MontgomeryPoint in the EphemeralPublic tuple is private outside of its crate.

Is there some other way to access a to_bytes() function for the EphemeralPublic struct that has the same effect?

This was easier in older versions of x25519-dalek, but the older subtle dependency being yanked (as per #19) prevents us from continuing to use the older version of the package.

Functions that generate secrets should take &mut arguments rather than returning secret data on the stack.

I'm trying to build a crypto library that uses dalek and I'd like to avoid copying secret data around as much as possible. Ideally, functions like generate_secret should take a &mut [u8; 32] so that the data can be written to the exact place I want to keep it and so that I can zero the data after use.

This would be a very trivial change to the API and I'm happy to do a PR if you're down with it.

Thanks for the great library btw!

Document what you're supposed to do with the SharedSecret

I recently implemented (thankfully only for a school project) an E2E chat system that directly took the SharedSecret from x25519-dalek and used it as a (chacha20poly1305) key. I've now come across this SE answer which claims that such a construction is risky, and I should really have some sort of hashing step between the DH exchange and the actual cipher key.

Right, ok, rolled my own crypto and got bitten in the ass. Lesson learned, thank god it wasn't for anything real.

That being said, the docs for SharedSecret currently don't provide any guidance for what one should do with the result. In the spirit of building misuse-resistant tools, it'd be great if there was a little more detail in the docs about what properties it's expected to have, and what it is and isn't safe to be used for.

Documentation and example on bare bytes API

I checked out the bare-bytes API for use with FFI. The API is easy enough for people who knows a bit about Elliptic Curves and Diffie-Hellman, but can be pretty confusing for people with limited knowledge.
Without any modification to the code itself, I suggest to add a usage example to the x25519() function in the docs.
I can write the example, test it and make a PR, but I just wanted to know your input about it before doing it!

Non-semver pin on `zeroize =1.3` leads to incompatibility with any crate that requires `zeroize >1.4`

Cargo normally lets you install and use two concurrent versions of a crate, but only if they are not semver compatible (rust-lang/cargo#6584).
Therefore the current hard requirement on zeroize =1.3 is inconvenient as it prevents using any crates that depend on newer versions of that crate.

Please would it be possible to lift this requirement so that later versions of the zeroize crate can be used? As far as I know semver compatibility means that should be OK โ€” am I missing something (does zeroize not follow semver?).

error: failed to select a version for `zeroize`.
    ... required by package `elliptic-curve v0.12.3`
    ... which satisfies dependency `elliptic-curve = "^0.12"` of package `ecdsa v0.14.8`
    ... which satisfies dependency `ecdsa-core = "^0.14"` of package `p256 v0.11.1`
    ... which satisfies dependency `p256 = "^0.11.1"` of package `webrtc-dtls v0.6.0`
    ... which satisfies dependency `dtls = "^0.6.0"` of package `webrtc v0.5.1`
    ... which satisfies dependency `webrtc = "^0.5.1"` of package `matrix_voip_echo v0.1.0 (/home/rei/repo/utils/matrix_voip_echo)`
versions that meet the requirements `^1.5` are: 1.5.7, 1.5.6, 1.5.5, 1.5.4, 1.5.3

all possible versions conflict with previously selected packages.

  previously selected package `zeroize v1.3.0`
    ... which satisfies dependency `zeroize = "=1.3"` of package `x25519-dalek v1.2.0`
    ... which satisfies dependency `x25519-dalek = "^1.2.0"` of package `vodozemac v0.3.0`
    ... which satisfies dependency `vodozemac = "^0.3.0"` of package `matrix-sdk-crypto v0.6.0`
    ... which satisfies dependency `matrix-sdk-crypto = "^0.6.0"` of package `matrix-sdk-base v0.6.1`
    ... which satisfies dependency `matrix-sdk-base = "^0.6.1"` of package `matrix-sdk v0.6.2`
    ... which satisfies dependency `matrix-sdk = "^0.6.2"` of package `matrix_voip_echo v0.1.0 (/home/rei/repo/utils/matrix_voip_echo)`

Add `StaticSecret::as_bytes`

At the moment (in v1.2.0) there is the to_bytes for PublicKey, StaticSecret and SharedSecret, thus allowing one to convert that key into [u8; _]. However there is also as_bytes available (allowing one to borrow the bytes and perhaps use them), but that is only available for PublicKey and SharedSecret, but not for StaticSecret.

Thus, I'm proposing to also add as_bytes to StaticSecret.

I don't think this violates in any manner the current API philosophy, because there is already to_bytes that allows exporting the underlying key.

Crate doesn't compile with recent nightly

With a fairly recent nightly

$ rustc --version
rustc 1.55.0-nightly (24bdc6d73 2021-06-12)

compilation fails with

error[E0557]: feature has been removed
  --> /nix/store/ynad3bw5igvv4yfnipqfcpzw74y4vv1w-crates-io/x25519-dalek-1.1.1/src/lib.rs:19:42
   |
19 | #![cfg_attr(feature = "nightly", feature(external_doc))]
   |                                          ^^^^^^^^^^^^ feature has been removed
   |
   = note: use #[doc = include_str!("filename")] instead, which handles macro invocations


error: aborting due to previous error

Unable to build docs with nightly flag

When building with no-default-feautures, u64_backend std and nightly

    Checking x25519-dalek v0.5.2
error[E0432]: unresolved import `packed_simd`
  --> /Users/dignifiedquire/.cargo/registry/src/github.com-1ecc6299db9ec823/curve25519-dalek-1.1.4/src/backend/vector/avx2/field.rs:43:5
   |
43 | use packed_simd::{i32x8, u32x8, u64x4, IntoBits};
   |     ^^^^^^^^^^^ maybe a missing `extern crate packed_simd;`?

Bump MSRV in `2.0.0` instead of requiring `zeroize =1.3.0`

Hello, I saw you released the first pre-release for 2.0 but I couldn't find the branch to send the PR myself, so I'll write this here:
could version 2 bump it's MSRV instead of requiring zeroize =1.3.0 ? This will break compiling with other crates that require zeroize >1.3.0

Ephemral secret keys seem to be too ephemeral.

As of version 0.4, there's no way to construct a secret key from bytes. As such, it's not possible to serialize a secret key. In our use case, the key exchange is considered to be expensive, so we'd like to serialize the private key to disk and read it from disk at a later time. So it'd be nice to be able to still construct an x25519 private key from bytes.

Now, since you have introduced the Ephemeral{Secret,Public}Key, I understand that you wouldn't want them to be serialized. Would there be any chance of having non-ephemeral x25519 key types, or just a plain fn generate_public(private_key: [u8;32]) -> [u8; 32] exposed in this library?

Re-using x25519 Public Key with different peers

Hi, Since contributors here deal a lot with implementation of the cryptographic primitives, I was wondering if some of you also have an opinion on the question posted here.

To expand that link here:


In X25519 (ECDH over Curve25519) Peer A and B exchange their Public Keys PkA and PkB and then calculate a shared-secret SecAB using combinationOf(SkA, PkB) == combinationOf(SkB, PkA).

For forward secrecy, I think it's recommended for A and B to re-negotiate a new shared-secret regularly (thus advertise new Public Keys).

Leaving that aside is there any other disadvantage if A uses the same Public Key that they have with everyone to get corresponding shared-secret VS if they use new Public Key with each new peer ?

In other words:

  1. Peer A gives PkA to all, B, C, D ..., and as usual calculates shared-secret using PkB, PkC, PkD as SecAB, SecAC, SecAD and so on and uses those to encrypt/decrypt messages to the corresponding peers.
  2. Peer A gives new Public Keys to each. So PkAB to B, PkAC to C, PkAD to D and so on. Then, just like before, calculate the shared-secret after using Public Keys of the corresponding peers as SecAB, SecAC, SecAD and so on.

Is 1. above less secure in context of how X25519 (and its maths) works than 2. ? Or is it just wasteful to do 2. and 1. is equally good ?


Thanks !

On the usage os OsRng

Hi, this is more of a question than a issue.

In the example that you give of creating keypairs, you use the rand_core Osrng:


use rand_core::OsRng;
use x25519_dalek::{EphemeralSecret, PublicKey};

let alice_secret = EphemeralSecret::new(OsRng);
let alice_public = PublicKey::from(&alice_secret);

After reading a bit up on the osrng, I read that it was not a cryptographically secure source of randomness, and that I should use a resource that specifcally had a focus on that.

The most common option for a csprg, seems to be the StdRng in the rand crate. That I was advised to use.

Is it possible to use use rand::{rngs::StdRng}; to create keypairs in your crate? or is the use of osrng completely unproblematic?

Version 1.2.0 doesn't compile (method cannot be called on `MontgomeryPoint` due to unsatisfied trait bounds)

Please, see this PR checks: https://github.com/Revertron/Alfis/pull/163/checks?check_run_id=3716024097
And here is a copy:

   Compiling x25519-dalek v1.2.0
     Running `rustc --crate-name x25519_dalek --edition=2018 /home/runner/.cargo/registry/src/github.com-1ecc6299db9ec823/x25519-dalek-1.2.0/src/lib.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts --crate-type lib --emit=dep-info,metadata,link -C opt-level=2 -C embed-bitcode=no -C debuginfo=2 -C debug-assertions=on --cfg 'feature="default"' --cfg 'feature="std"' --cfg 'feature="u64_backend"' -C metadata=baaddb637a5d6d32 -C extra-filename=-baaddb637a5d6d32 --out-dir /home/runner/work/Alfis/Alfis/target/debug/deps -L dependency=/home/runner/work/Alfis/Alfis/target/debug/deps --extern curve25519_dalek=/home/runner/work/Alfis/Alfis/target/debug/deps/libcurve25519_dalek-8ade5031273b1cae.rmeta --extern rand_core=/home/runner/work/Alfis/Alfis/target/debug/deps/librand_core-b12315593518f00b.rmeta --extern zeroize=/home/runner/work/Alfis/Alfis/target/debug/deps/libzeroize-bc125cf8446a0177.rmeta --cap-lints allow`
error[E0599]: the method `is_identity` exists for struct `MontgomeryPoint`, but its trait bounds were not satisfied
   --> /home/runner/.cargo/registry/src/github.com-1ecc6299db9ec823/x25519-dalek-1.2.0/src/x25519.rs:265:17
    |
265 |         !self.0.is_identity()
    |                 ^^^^^^^^^^^ method cannot be called on `MontgomeryPoint` due to unsatisfied trait bounds
    | 
   ::: /home/runner/.cargo/registry/src/github.com-1ecc6299db9ec823/curve25519-dalek-3.1.0/src/montgomery.rs:71:1
    |
71  | pub struct MontgomeryPoint(pub [u8; 32]);
    | -----------------------------------------
    | |
    | doesn't satisfy `MontgomeryPoint: Identity`
    | doesn't satisfy `MontgomeryPoint: IsIdentity`
    |
    = note: the following trait bounds were not satisfied:
            `MontgomeryPoint: Identity`
            which is required by `MontgomeryPoint: IsIdentity`

For more information about this error, try `rustc --explain E0599`.
error: could not compile `x25519-dalek` due to previous error

Caused by:
  process didn't exit successfully: `rustc --crate-name x25519_dalek --edition=2018 /home/runner/.cargo/registry/src/github.com-1ecc6299db9ec823/x25519-dalek-1.2.0/src/lib.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts --crate-type lib --emit=dep-info,metadata,link -C opt-level=2 -C embed-bitcode=no -C debuginfo=2 -C debug-assertions=on --cfg 'feature="default"' --cfg 'feature="std"' --cfg 'feature="u64_backend"' -C metadata=baaddb637a5d6d32 -C extra-filename=-baaddb637a5d6d32 --out-dir /home/runner/work/Alfis/Alfis/target/debug/deps -L dependency=/home/runner/work/Alfis/Alfis/target/debug/deps --extern curve25519_dalek=/home/runner/work/Alfis/Alfis/target/debug/deps/libcurve25519_dalek-8ade5031273b1cae.rmeta --extern rand_core=/home/runner/work/Alfis/Alfis/target/debug/deps/librand_core-b12315593518f00b.rmeta --extern zeroize=/home/runner/work/Alfis/Alfis/target/debug/deps/libzeroize-bc125cf8446a0177.rmeta --cap-lints allow` (exit status: 1)
warning: build failed, waiting for other jobs to finish...
error: build failed

Consider zeroize on drop for PublicKey

Would you consider adding the zeroize on drop feature for the PublicKey type?
This feature implies not auto deriving the Copy trait for PublicKey which might break compatibility for some projects using this crate.

I think this is an important feature and unfortunately it's a very common belief that it's only important to zeroize private key materials. Whereas we would like to achieve the plausibly deniability properties that come from destroying public keys as well.

The context for this request is steeped in the slow crypto train movement: a slow messaging system, similar to agl's Pond in some ways, should have a "panic button" that removes all ciphertext, public and private key materials and so on. People in high risk situations might like to press such a panic button when the secret police show up.

What do you think? I'm more than happy to submit a pull request if this is something you'd merge.

Create a prerelease using `curve25519-dalek 4.0.0-rc`

The latest prerelease of ed25519-dalek has been updated to curve25519-dalek 4.0.0-rc, and using both prereleases (of it and this crate) would cause dependency redundance.
The reason for using prereleases is that the ed25519-dalek and curve25519-dalek prereleases use digest API version 0.10, which does not force the hash algorithm to implement resetting state, which is different from the three-year-old version 0.9 used by current stable versions. And I need to replace the SHA2 algorithm in Ed25519 with cSHAKE256 provided by tiny-keccak crate (I know this makes it not specification-compliant) and the public API of tiny-keccak does not support resetting state.
For now I'm using this crate on git main to solve this problem temporarily. (Is there a security risk with this?)

Release 2.0 Tracking

Feat - Optional Types - Done

Feat - Gate rand_core - Not for 2.0.0

Fix - no_std - Done

Feature - getrandom - Done

Docs - Ok

  • #115
  • README bump - Needs doing

Chore - Done

Clean-Up on Issues

Check - Not for 2.0.0

Open but were resolved - Needs Close

  • #92 - zeroize was relaxed
  • #86 - rand_core was bumped

Questions / Red herrings - Needs Close

Optional `rand_core` with `StaticSecret`

Given if we make all Secret types optional via

And since StaticSecret can import key material -

Perhaps rand_core can be marked in this case optional when only StaticSecret is used ?

ReusableSecret and EphemeralSecret features would enable rand_core given #114

Broken with rand_core 0.6.1

It seems rand_core 0.6.1 breaks this lib

Here is my usage and then the error I get

use rand_core::OsRng;
let local_diffie_secret = EphemeralSecret::new(OsRng);
error[E0277]: the trait bound `OsRng: rand_core::RngCore` is not satisfied
   --> src\main.rs:406:49
    |
406 |     let local_diffie_secret = EphemeralSecret::new(OsRng);
    |                                                    ^^^^^ the trait `rand_core::RngCore` is not implemented for `OsRng`
    |
   ::: C:\Users\laptopuser\.cargo\registry\src\github.com-1ecc6299db9ec823\x25519-dalek-1.1.0\src\x25519.rs:76:19
    |
76  |     pub fn new<T: RngCore + CryptoRng>(mut csprng: T) -> Self {
    |                   ------- required by this bound in `EphemeralSecret::new`

error[E0277]: the trait bound `OsRng: rand_core::CryptoRng` is not satisfied
   --> src\main.rs:406:49
    |
406 |     let local_diffie_secret = EphemeralSecret::new(OsRng);
    |                                                    ^^^^^ the trait `rand_core::CryptoRng` is not implemented for `OsRng`
Windows 10 20H2 19042.746

rustup 1.23.1 (3df2264a9 2020-11-30)
info: This is the version for the rustup toolchain manager, not the rustc compiler.
info: The currently active `rustc` version is `rustc 1.49.0 (e1884a8e3 2020-12-29)`

[dependencies.x25519-dalek]
version = "1.1.0"

[dependencies]
rand = "0.8.3"
rand_core = "0.6.1"
------# Full dependencies
[dependencies]
sciter-rs = "0.5.53"
libc = "0.2"
lazy_static = "1.4"

serde = { version = "1.0.117", features = ["derive", "rc"] }
serde_json = "1.0.59"
rand = "0.8.3"
rand_core = "0.6.1"
aes-gcm = { version = "0.8.0", features = ["heapless"]}
ring = "0.16.5"
base64 = "0.13.0"

[dependencies.x25519-dalek]
version = "1.1.0"

Build for ESP32 microcontroller

Hello.

I am currently trying to use this library for a project that needs to run on a ESP32. This means that we have no operating system and no STD. But the library should be in the category "No standard library" which should be fine for me in this case.

I am using the ESP32 build chain and this project to set it up, which is this: https://github.com/esp-rs/rust-build

But when attempting to build it I recieve the following error:

error: linking with `ldproxy` failed: exit status: 1
...
  = note: Running ldproxy
          Error: Linker /home/carl/.espressif/tools/xtensa-esp32-elf-clang/esp-13.0.0-20211203-x86_64-unknown-linux-gnu/bin/xtensa-esp32-elf-gcc failed: exit status: 1
          STDERR OUTPUT:
          /home/carl/.espressif/tools/xtensa-esp32-elf-clang/esp-13.0.0-20211203-x86_64-unknown-linux-gnu/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: /home/carl/Documents/git/github/esp-rs/esp32-build/target/xtensa-esp32-espidf/debug/deps/libclear_on_drop-7f6bb154f7984c2b.rlib: error adding symbols: file format not recognized
          collect2: error: ld returned 1 exit status

full log here

Hope this is something you can help me with.

Broken curve pin via rc.2

This results in incompat API between x/curve.

  • x25519-dalek rc.2 did not pin to curve25519-dalek rc.2
  • x25519-dalek rc.2 is now picking up curve25519-dalek rc.3 and breaks some builds
  • x25519-dalek rc.3 fixed this pin in 53e5d9 but rc.2 remains broken

I think the only action that could be taken is to yank x25519-dalek rc.2 with the broken non-pinned curve dependency.

This should not as far as I remember break anyone using --locked in dependency bin which may have old rc.2 in lock ?

This makes it so nobody new will use it and instead use x25519-dalek rc.3 or pre.1

Unless the Scalar API changes #120 between rc.2/3 would be reverted and leave it for next major - which I would not recommend.

Another option would be to release new set of release candidates w/o Scalar #120 change and then Scalar #120 change on top but this could be highly confusing with the versions and could create even a bigger mess.

Could also release "fixup" rc.2 but dunno how that would work with SemVer ?

If someone needs a patch release that is not rc.3 -

e.g. could 2.0.0-rc.2+fixup1 work that utilizes the "build" construct in SemVer ?

Rendering API docs on docs.rs

I noticed the API docs for x25519 & curve25519 aren't rendering properly on doc.rs.
The docs.rs build fails on

error: error reading `.cargo/registry/src/github.com-1ecc6299db9ec823/curve25519-dalek-0.13.2/rustdoc-include-katex-header.html`: No such file or directory (os error 2)

You can see the full error log here: https://docs.rs/crate/x25519-dalek/0.4.2/builds/137497

The file it can't find was referenced here:

x25519-dalek/Cargo.toml

Lines 22 to 24 in 65f9412

[package.metadata.docs.rs]
rustdoc-args = ["--html-in-header", ".cargo/registry/src/github.com-1ecc6299db9ec823/curve25519-dalek-0.13.2/rustdoc-include-katex-header.html"]
features = ["nightly"]

The reason for this error is because docs.rs recently moved servers & the cargo cache was lost.

To fix this for x25519 & curve25519 the name of the file for
.cargo/registry/src/github.com-1ecc6299db9ec823/curve25519-dalek-1.0.1/docs/assets/rustdoc-include-katex-header.html needs to be changed & then republish the crate.

Transform ed25519 secret/public keys into x25519 secret/public keys

According to this blog post, public and private ed25519 keys used for signing can be transformed into public and private x25519 keys for DH exchange, allowing for encrypted communications. This conversion would be quite useful in the case where one needs to do sometimes signing operations and sometimes encryption operations, as a single public key could be transmitted for both uses.

It looks like the underlying curve25519_dalek library could handle this conversion, however it is not exposed in either ed25519_dalek's or x25519_dalek's data types. Do you think such functionality could be added?

subtle is outdated?

Looks like this is pulling in an outdated version of subtle through pulling in an outdated version of curve25519-dalek ?

error[E0554]: #![feature] may not be used on the stable release channel
  --> /home/aep/.cargo/registry/src/github.com-1ecc6299db9ec823/subtle-0.3.0/src/lib.rs:20:34
   |
20 | #![cfg_attr(feature = "nightly", feature(i128_type))]
   |                                  ^^^^^^^^^^^^^^^^^^^

Feedback/Suggestion

Hey!

I've been implementing Noise with x25519-dalek and I have a few suggestions:

  • for ephemeral keys, the diffie-hellman operation consumes the private key, which doesn't work if I need to use the ephemeral keys in more than one Diffie-Hellman operation (common with Noise)
  • a public_key(&self) operation on private keys would be really handy
  • a try_from<&[u8]> operation for private and public keys would be really handy

(happy to take a stab at a PR if you want me to)

no_std Support

Related

  • #88 - Red herring - not this crate

rand_core?/getrandom

It seems getrandom is brought by rand_core which isn't optional - that stops thumb building

    --> /home/runner/.cargo/registry/src/index.crates.io-6f17d22bba15001f/getrandom-0.2.8/src/lib.rs:268:9
    |
268 | /         compile_error!("target is not supported, for more information see: \
269 | |                         https://docs.rs/getrandom/#unsupported-targets");

https://github.com/pinkforest/x25519-dalek/actions/runs/4395315721/jobs/7697018808

Maybe we can make the get_random weak and gate via getrandom feature ?

This ofc requires some work around API re: providing randomness

Scalar type VS bit-fiddling

I've noticed that curve25519_dalek::Scalar is used as a bag of bytes to store both random 32-bytes (when you use diffie_hellman() function) and fiddled 32-bytes (the output of decode_scalar()). In both cases the type Scalar does not store a "proper" scalar modulo curve order.

While technically it works, this makes me feel uneasy. E.g. what if curve25519_dalek library later (if not already) assumes that its Scalar type is always properly reduced, and I use the same scalar with x25519 library and with some custom crypto protocol? Does it make sense maybe to introduce a x25519-specific "SecretKey" type or something like that, which does not pretend to be a scalar mod L? Or maybe I'm overthinking this and it's fine as is?

subtl dependency broken again

subtle 0.7 was yanked, but x25519-dalek requires exactly curve25519-dalek 0.19, which depends on exactly subtle 0.7

    Updating git repository `https://github.com/quininer/rust-hacl-star.git`
    Updating crates.io index
error: failed to select a version for the requirement `subtle = "^0.7"`
  candidate versions found which didn't match: 2.0.0, 1.0.0
  location searched: crates.io index
required by package `curve25519-dalek v0.19.0`
    ... which is depended on by `x25519-dalek v0.3.0`
    ... which is depended on by `carrier v0.8.0 (/home/aep/proj/devguard/carrier2)`

Alternating values when creating a StaticSecret

Perhaps I am missing something but I am getting what for me is unexpected behaviour

let pk1 = StaticSecret::from(avalue);
let pk2 = StaticSecret::from(avalue);

etc, etc... you can create more pks

I would expect pk1 to be equal to pk2, as I invoke the creation of StaticSecret twice with the same value

What I am getting is that the 1st, 3rd, 5th calls give one output, and the 2nd, 4th and 6th, etc, give a slightly different output the difference being in the first bytes.

Is this expected behaviour?

Optional `Secret` types via features

ReusableSecret is optional feature

Should StaticSecret be optional that can also make rand_core optional ?

To that matter should EphemeralSecret be optional as well ? ๐Ÿค”

secret from bytes / x25519_dalek::generate_public

with x25519_dalek::generate_public gone, there is no way to construct a secret anymore except from randomness. How is serializtion/deserialization supposed to work?

Unfortunately we have to upgrade to 0.4, since 0.3 has yanked dependencies

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.