Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to build with pure backend #118

Closed
RastislavKish opened this issue May 8, 2024 · 8 comments · Fixed by #119
Closed

Unable to build with pure backend #118

RastislavKish opened this issue May 8, 2024 · 8 comments · Fixed by #119

Comments

@RastislavKish
Copy link

RastislavKish commented May 8, 2024

Trying to build with default-features=false and features=["pure"] causes error. The OpenSSL backend seems to work fine.

Reproduction steps

  1. Create a new cargo project and add ecies={version="0.2.6", default-features=false, features=["pure"]} to Cargo.toml
  2. cargo build --release the code snippet below

Expected behavior

The build should pass

Actual behavior

The following error is thrown:

error[E0432]: unresolved import `once_cell::sync`
 --> /home/username/.cargo/registry/src/index.crates.io-6f17d22bba15001f/ecies-0.2.6/src/config.rs:1:16
  |
1 | use once_cell::sync::Lazy;
  |                ^^^^ could not find `sync` in `once_cell`

For more information about this error, try `rustc --explain E0432`.
error: could not compile `ecies` (lib) due to 1 previous error

Code

use ecies::{encrypt, decrypt, utils::generate_keypair};

fn main() {
    let msg="Hello, this is a test.";
    let (sk, pk)=generate_keypair();
    let (sk, pk)=(&sk.serialize(), &pk.serialize());

    let encrypted_message=encrypt(pk, msg.as_bytes()).unwrap();

    let original=decrypt(sk, &encrypted_message).unwrap();

    let original=String::from_utf8(original).unwrap();

    println!("{original}");
    }

Environment

* OS: Ubuntu Mate 22.04 64-bit

  • rustc: 1.78.0
    * ecies: 1.2.6
@kigawas
Copy link
Member

kigawas commented May 13, 2024

Cannot reproduce:

$ git checkout v0.2.6

$ cargo test --no-default-features --features pure
    Finished test [unoptimized + debuginfo] target(s) in 0.35s
     Running unittests src/lib.rs (target/debug/deps/ecies-402dbd59fa41c3b5)

running 13 tests
test symmetric::tests::test_attempt_to_decrypt_invalid_message ... ok
test tests::attempts_to_encrypt_with_invalid_key ... ok
test symmetric::tests::test_aes_known_key ... ok
test symmetric::tests::test_random_key ... ok
test tests::attempts_to_decrypt_incorrect_message ... ok
test utils::tests::test_known_hkdf_vector ... ok
test utils::tests::test_valid_secret ... ok
test utils::tests::test_generate_keypair ... ok
test utils::tests::test_known_shared_secret ... ok
test tests::test_compressed_public ... ok
test tests::test_uncompressed_public ... ok
test tests::attempts_to_decrypt_with_another_key ... ok
test tests::test_compressed_public_big_msg ... ok

test result: ok. 13 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.99s

     Running tests/integration.rs (target/debug/deps/integration-11eda8204c121ad2)

running 2 tests
test can_change_behavior_with_config ... ok
test is_compatible_with_python ... ok

test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.51s

   Doc-tests ecies

running 3 tests
test src/lib.rs - (line 83) ... ok
test src/lib.rs - (line 94) ... ok
test src/lib.rs - (line 25) ... ok

test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.65s

You may need to check once_cell's version

@RastislavKish
Copy link
Author

@kigawas thanks for looking into this.

When I run the tests on my machine, everything passes okay. Just inclusion in a project seem to be broken for some reason. There doesn't need to be any reproduction code at all, just doing:

cargo new ecies_test
cd ecies_test

adding:

ecies={version="0.2.6", default-features=false, features=["pure"]}

Under [dependencies] and doing:

cargo build

raises the error.

@RastislavKish
Copy link
Author

Update: I got things to build when I also included once_cell in my dependencies:

ecies={version="0.2.6", default-features=false, features=["pure"]}
once_cell="1.19.0"

This is a non-standard behavior (the crate should be responsible for specifying all its dependencies). I would guess it could be a dependency scoping issue?

My default toolchain is x86_64-unknown-linux-gnu, OS Linux with dual core Intel Core i5-4310U (-MT MCP-) CPU.

@kigawas
Copy link
Member

kigawas commented May 13, 2024

Maybe try once_cell 1.18.0?

@RastislavKish
Copy link
Author

Update2: I think I've found the cause of the issue. The problem is once-cell requires its std feature to be turned on, otherwise the sync module is not available. If I use std feature of ecies like so:

ecies={version="0.2.6", default-features=false, features=["std", "pure"]}

Then everything works as expected. But without including the std feature, it won't compile, because ecies by default (reasonably) depends on once_cell without std.

There are two solutions I can think of, either the pure backend auto-enables std for once_cell (that is the case when wasm is the target architecture), or, another potential solution, if there is a way to make the pure backend work without std, that would solve it as well.

@kigawas
Copy link
Member

kigawas commented May 14, 2024

Thanks for your advice! I'll need some time to bring back no_std because of configuration

@kigawas
Copy link
Member

kigawas commented May 14, 2024

@RastislavKish

pure backend auto-enables std for once_cell (that is the case when wasm is the target architecture)

This is already the default setting, but sometimes it might be some different behaviour because cargo is not that intelligent yet

[target.'cfg(all(target_arch = "wasm32", target_os="unknown"))'.dependencies]
# only for js (browser or node). if it's not js, like substrate, it won't build
getrandom = {version = "0.2.12", default-features = false, features = ["js"]}
once_cell = {version = "1.19.0", default-features = false, features = ["std"]}
wasm-bindgen = {version = "0.2.92", default-features = false}

[target.'cfg(all(target_arch = "wasm32", not(target_os="unknown")))'.dependencies]
# allows wasm32-wasi to build
once_cell = {version = "1.19.0", default-features = false, features = ["std"]}

there is a way to make the pure backend work without std

Perhaps you can try adding once_cell = {version = "1.19.0", default-features = false, features = ["critical-section"]} to overwrite the default setting on no_std platform, but note that std may still be enabled by other dependencies you added

@kigawas
Copy link
Member

kigawas commented May 17, 2024

once_cell = {version = "1.19.0", default-features = false, features = ["critical-section"]} will be default after #119 merged to make it easier build on no_std

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants