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

[Question] PublicKey as_bytes and from_bytes #136

Closed
roynalnaruto opened this issue Aug 12, 2020 · 1 comment
Closed

[Question] PublicKey as_bytes and from_bytes #136

roynalnaruto opened this issue Aug 12, 2020 · 1 comment

Comments

@roynalnaruto
Copy link

Hello, thank you for the wonderful work that has been put into building this library!

As I understand, a PublicKey by default is stored in the compressed form (33 bytes).

On obtaining a byte array for the public key, I get an array of length 33

let mut rng = rand::thread_rng();
let secret_key = SecretKey::generate(rng);
let public_key = PublicKey::from_secret_key(&secret_key, true)
    .expect("invalid secret key");

// length 33 (compressed form)
let public_key_bytes = public_key.as_bytes()

When I try to construct the publicKey back from these bytes:

let public_key = PublicKey::from_bytes(&public_key_bytes);

I get an error:

error[E0277]: arrays only have std trait implementations for lengths 0..=32
   --> ethers-core/src/types/crypto/keys.rs:308:60
    |
308 |                 let public_key = PublicKey::from_bytes(&public_key_bytes)
    |                                                            ^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[u8; 33]`
    |
    = note: required because of the requirements on the impl of `std::convert::AsRef<[u8]>` for `[u8; 33]`
    = note: required because of the requirements on the impl of `std::convert::AsRef<[u8]>` for `&[u8; 33]`
    = note: required by `elliptic_curve::weierstrass::public_key::PublicKey::<C>::from_bytes`

Basically, the from_bytes expects a byte array of length 32.

What am I missing here? Any help would be appreciated.

@tarcieri
Copy link
Member

This is a (recently removed) limitation of the Rust standard library: common trait impls used to be special cased for [T; 0] -> [T; 32] because Rust's type system didn't used to support const generics. But now it does and this restriction was recently removed in the nightly compiler.

In the meantime you'll need to explicitly slice the array to get &[u8]:

let public_key = PublicKey::from_bytes(&public_key_bytes[..]);

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

No branches or pull requests

2 participants