1

I found rust-secp256k1 and it seems to be what I need, but there are no examples in the documentation.

I tried to use this crate in my code:

extern crate secp256k1;

use secp256k1::key::SecretKey;

fn main() {
    let context = secp256k1::Secp256k1::without_caps();

    let private_key: String = String::from("d500266f7d37f0957564e4ce1a1dcc8bb3408383634774a2f4a94a35f4bc53e0");

    let secret_key = SecretKey::new(&context, &mut private_key);

    println!("{:?}", secret_key);
}

I got an error:

error[E0277]: the trait bound `std::string::String: secp256k1::rand::Rng` is not satisfied
  --> src/main.rs:10:22
   |
10 |     let secret_key = SecretKey::new(&context, &mut private_key);
   |                      ^^^^^^^^^^^^^^ the trait `secp256k1::rand::Rng` is not implemented for `std::string::String`
   |
   = note: required by `secp256k1::key::SecretKey::new`
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Roman Frolov
  • 998
  • 11
  • 18
  • 4
    `SecretKey::new` expects a random number generator (as in, it implements `Rng`) as the second parameter. If you make that other string a compatible slice of bytes, you can use [`SecretKey::from_slice`](https://www.wpsoftware.net/rustdoc/secp256k1/key/struct.SecretKey.html#method.from_slice) instead. – E_net4 Dec 10 '18 at 19:08

2 Answers2

4

Just adding to the accepted answer:

The public key you printed in the last line is not the correct form of the uncompressed public key. To display that requires using the method serialize_uncompressed from the secp256k1 crate on the public key, and dropping the leading 04 hex-byte.

More information on the incorrect formatting here.

Isambard_FA
  • 97
  • 13
3

The following code generates a public key from a private key:

extern crate secp256k1;
extern crate hex;

use secp256k1::key::{SecretKey, PublicKey};

fn main() {
    let context = secp256k1::Secp256k1::new();

    let private_key: &[u8] = "d500266f7d37f0957564e4ce1a1dcc8bb3408383634774a2f4a94a35f4bc53e0".as_bytes();

    let secret_key = SecretKey::from_slice(&hex::decode(private_key).unwrap());

    let public_key = PublicKey::from_secret_key(&context, &secret_key.unwrap());

    println!("{:?}", public_key.unwrap()); // PublicKey(a423c05d32e3385bb2930e42ebbf104567215761e166c3ae3dd91d9c8bee0adcfc4f9e4ec43998eae8000de6b166014c5921c6d4545675f4f9205e7bc3d4401e)
}

Instead of using SecretKey::new, which expects a random number generator as the second parameter, I needed to use SecretKey::from_slice. from_slice takes a 32-byte key, which I can parse from my string into a compatible slice of bytes.

CJ42
  • 11
  • 2
  • 4
  • 7
Roman Frolov
  • 998
  • 11
  • 18
  • 1
    You probably want to use `"d500266f7d37f0957564e4ce1a1dcc8bb3408383634774a2f4a94a35f4bc53e0".as_bytes()` in a different way, since this statement will treat the string as text, and not as hex buffer. – brickpop Aug 03 '20 at 18:10