dalek-cryptography / x25519-dalek Goto Github PK
View Code? Open in Web Editor NEWX25519 elliptic curve Diffie-Hellman key exchange in pure-Rust, using curve25519-dalek.
License: BSD 3-Clause "New" or "Revised" License
X25519 elliptic curve Diffie-Hellman key exchange in pure-Rust, using curve25519-dalek.
License: BSD 3-Clause "New" or "Revised" License
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
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:
dalek
is ready to provide itdalek
wouldn't see this as its goalI was wondering if there is a specific reason that is currently not proxied through, like it is in ed25519-dalek.
Following #15, the documentation needs to be updated; right now it's duplicated across some markdown files and the source files.
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.
The dependency on rand appears to be out of date. It appears PR #7 addresses this.
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()[..]
);
}
}
}
Line 78 in 53bb1a3
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.
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,
],
),
),
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.
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!
I did not initially notice that this was moved.
Would it make sense to enforce the repository's read-only status from the settings?
In the case this was just forgotten.
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.
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!
Currently, StaticSecret::new
is deprecated with a message saying it will be removed in 2.1.0. Such a change would not be allowed as per semver. (unless 2.1.0 is supposed to be the first proper 2.x release?)
See Travis: https://travis-ci.org/dalek-cryptography/x25519-dalek/jobs/482814498
It appears as though the rand
crate is causing a build failure using Rust nightly.
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)`
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.
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
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;`?
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
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?
It's easy enough to extract it from the crate, but github is certainly easier :).
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:
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.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 !
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?
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
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.
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?)
Feat - Optional Types - Done
Feat - Gate rand_core - Not for 2.0.0
Fix - no_std - Done
Feature - getrandom - Done
Docs - Ok
Chore - Done
Clean-Up on Issues
Check - Not for 2.0.0
Open but were resolved - Needs Close
Questions / Red herrings - Needs Close
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"
new()
, diffie_hellman()
, pubkey computation etc. are all the same. This leads to a bit of an awkward use of the API downstream, as e.g. noise-rust-crypto is basically picking one of the two types arbitrarily to perform diffie hellman, or to compute a pubkey.
It would be great to have a `SecretKey`` that implements all those things, and have the two special secret types just wrap it.
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
Hope this is something you can help me with.
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 buildsx25519-dalek
rc.3
fixed this pin in 53e5d9 but rc.2
remains brokenI 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 ?
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:
Lines 22 to 24 in 65f9412
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.
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?
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))]
| ^^^^^^^^^^^^^^^^^^^
Hey!
I've been implementing Noise with x25519-dalek and I have a few suggestions:
public_key(&self)
operation on private keys would be really handytry_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)
I saw Transform ed25519 secret/public keys into x25519 secret/public keys , but I'm not familiar with cryptography , I don't kown how to do this .
is there any example code for do this ?
Related
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
The sample code in the documentation uses the deprecated rand_os
https://docs.rs/rand_os/0.2.2/rand_os/
Deprecated since 0.2.2: OsRng is now provided by rand_core and rand
Is there a sample that uses rand_core
or rand
?
Here's a snippet that seems to work but I don't know if it's secure
use rand_core::{OsRng};
let mut alice_csprng = OsRng;
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?
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)`
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?
Hey,
The change to zeroize 1.4.0 here breaks builds for anyone using an older Rust version. Any chance to pin zeroize to 1.3.0 to maintain compatibility?
ReusableSecret
is optional feature
Should StaticSecret
be optional that can also make rand_core
optional ?
To that matter should EphemeralSecret
be optional as well ? ๐ค
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
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.