How to use libraries

Hello,
I am new to Rust and trying to understand how to use external libraries. This is a noob question!
For example I want to use this library for an elliptic curve
https://github.com/RustCrypto/elliptic-curves/tree/master/p256
So I cloned the repo I want to use in my disk and then I created a new folder somewhere else named "myproject".
I run then cargo init and edit the Cargo.toml by adding p256 = { path = "/Users/user/elliptic-curves/p256" } under [dependencies].
The main.rs in myproject/src is as follows:

use crate::p256;
fn main() {
    println!("Hello, world!");
}

But I get an error

error: failed to select a version for the requirement `elliptic-curve = "=0.5.0-pre"`
  candidate versions found which didn't match: 0.4.0, 0.3.0, 0.2.0, ...
  location searched: crates.io index
required by package `p256 v0.3.0 (/Users/user/elliptic-curves/p256)`
    ... which is depended on by `myproject v0.1.0 (/Users/user/myproject)`

Can someone tell me what I'm doing wrong?

The book describes how to get dependencies for your project. It only takes another line on your Cargo.toml file, that's all you need to do.

Yes I read it but I can't find this particular library version in crates.io...
The latest version is indeed 0.4.0 but it looks for 0.5.0-pre..
Am I missing something?

Adding p256 = "0.3" just works on my machine. Can you share your current source code and Cargo.toml?

First, why do you want to use your local copy and not the published version?
Second, if you really want to, set Cargo.toml entry as such:

p256 = { version = "version", path = "path" }

where path is, as you already know, a path to your local copy, and version is the version set in the Cargo.toml file inside this copy.

p256 v0.5 is not yet published on crates.io. The latest version on both crates.io and in the repository is v0.3, so it looks like you've confused versions from a different crate, e.g. elliptic-curve which defines traits implemented by p256. You could use the version directly from git like this:

p256 = { git = "https://github.com/RustCrypto/elliptic-curves" }

But if you are new to Rust, just use v0.3. Also p256 is not an easy crate to start with, you will have to understand a broader context, which includes crates like elliptic-curve, ecdsa and signature, so I would recommend to chose a simpler crate for practice. If you are interested in cryptography crates, it would be better to start with hash functions or stream ciphers.

Got it, I just added elliptic-curve = "0.4.0" and works.. Thanks!

My (one more newb) question now: How do I access internal methods?
E.g. here is my sample code:

use elliptic_curve;
fn main() {
    const UNCOMPRESSED_BASEPOINT: &str =
        "046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5";
    let pubkey = PublicKey::from_bytes(&hex::decode(UNCOMPRESSED_BASEPOINT).unwrap()).unwrap();
    let point = AffinePoint::from_pubkey(&pubkey).unwrap();
}

These are in here https://github.com/RustCrypto/elliptic-curves/blob/master/p256/src/arithmetic.rs

However I get error
use of undeclared type or module PublicKey
use of undeclared type or module hex
use of undeclared type or module AffinePoint

You need to pull in specifics to use them without a qualifier.

Either add to your use statement:

use elliptic_curve::PublicKey;

// PublicKey is now in scope and points to elliptic_curve::PublicKey

Or type the fully qualified name:

use elliptic_curve;

...

// elliptic_curve::PublicKey

If there are lots of commonly needed items the crate might include a prelude for convenience:

use elliptic_curve::prelude::*;

// PublicKey

Or failing that, you could just use everything:

use elliptic_curve::*;

// PublicKey

Try not to over use this though. What types are and where they were defined is useful info for anyone reading your code (including you :stuck_out_tongue:)

1 Like

Note that p256 re-exports elliptic-curve, so you don't need specify it in Cargo toml and you can import it like this:

use p256::elliptic_curve;

Your have to import types and crates first. Your example can be written like this.

Cargo.toml:

[dependencies]
p256 = "0.3"
hex = "0.4"

src/main.rs:

use p256::PublicKey;
use p256::arithmetic::AffinePoint;
use hex;

fn main() {
    const UNCOMPRESSED_BASEPOINT: &str =
        "046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5";
    let pubkey = PublicKey::from_bytes(&hex::decode(UNCOMPRESSED_BASEPOINT).unwrap()).unwrap();
    let point = AffinePoint::from_pubkey(&pubkey).unwrap();
}

Note that the arithmetic module is feature-gated behind an enabled by default feature with the same name.

1 Like

Got it, thank you all so much for your help!

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.