Skip to content

Commit

Permalink
feat!: provide hex conversion utilities
Browse files Browse the repository at this point in the history
Implement `from_hex` and `to_hex` functions for the `PublicKey` and `SecretKey` types.

BREAKING CHANGE: the `Eq`, `Serialize` and `Deserialize` derivations are removed from the error type
because the derived hex error doesn't implement these.

I'm finding myself repeating this code several times in places where I'm using the BLS library, so I
thought it would be useful to just have it directly on these types.
  • Loading branch information
jacderida committed Jun 10, 2022
1 parent 710b009 commit 2509f30
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 4 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ version = "5.2.0"
[dependencies]
ff = "0.11.0"
group = "0.11.0"
hex = "0.4.3"
hex_fmt = "0.3.0"
pairing = "0.21.0"
rand = "0.8.5"
Expand Down Expand Up @@ -42,7 +43,6 @@ features = [ "js" ]
bincode = "1.3.3"
criterion = "0.3.1"
eyre = "0.6.5"
hex = "0.4.3"
rand_core = "0.6.3"
rand_xorshift = "0.3.0"

Expand Down
7 changes: 4 additions & 3 deletions src/error.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
//! Crypto errors.
use thiserror::Error;

use serde::{Deserialize, Serialize};

/// A crypto error.
#[derive(Clone, Eq, PartialEq, Debug, Error, Serialize, Deserialize)]
#[derive(Clone, PartialEq, Debug, Error)]
pub enum Error {
/// Not enough signature shares.
#[error("Not enough shares for interpolation")]
Expand All @@ -21,6 +19,9 @@ pub enum Error {
/// The result of Hash To Field is zero which should never happen.
#[error("Hash To Field returned zero")]
HashToFieldIsZero,
/// An error converting to or from a hex representation of a key.
#[error("Failed to convert the key from hex")]
HexConversionFailed(#[from] hex::FromHexError),
}

/// A crypto result.
Expand Down
40 changes: 40 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,18 @@ impl PublicKey {
pub fn to_bytes(self) -> [u8; PK_SIZE] {
self.0.to_compressed()
}

/// Deserialize a hex-encoded representation of a `PublicKey` to a `PublicKey` instance.
pub fn from_hex(hex: &str) -> Result<Self> {
let pk_bytes = hex::decode(hex)?;
let pk_bytes: [u8; PK_SIZE] = pk_bytes.try_into().map_err(|_| Error::InvalidBytes)?;
Self::from_bytes(pk_bytes)
}

/// Serialize this `PublicKey` instance to a hex-encoded `String`.
pub fn to_hex(&self) -> String {
hex::encode(self.to_bytes())
}
}

/// A public key share.
Expand Down Expand Up @@ -430,6 +442,18 @@ impl SecretKey {
Ok(SecretKey::from_mut(&mut fr))
}

/// Deserialize a hex-encoded representation of a `SecretKey` to a `SecretKey` instance.
pub fn from_hex(hex: &str) -> Result<Self> {
let sk_bytes = hex::decode(hex)?;
let sk_bytes: [u8; SK_SIZE] = sk_bytes.try_into().map_err(|_| Error::InvalidBytes)?;
Self::from_bytes(sk_bytes)
}

/// Serialize this `SecretKey` instance to a hex-encoded `String`.
pub fn to_hex(&self) -> String {
hex::encode(self.to_bytes())
}

/// Returns the decrypted text, or `None`, if the ciphertext isn't valid.
pub fn decrypt(&self, ct: &Ciphertext) -> Option<Vec<u8>> {
if !ct.verify() {
Expand Down Expand Up @@ -1198,6 +1222,22 @@ mod tests {
Ok(())
}

#[test]
fn test_from_to_hex() -> Result<()> {
let sk_hex = "4a353be3dac091a0a7e640620372f5e1e2e4401717c1e79cac6ffba8f6905604";
let sk = SecretKey::from_hex(sk_hex)?;
let sk2_hex = sk.to_hex();
let sk2 = SecretKey::from_hex(&sk2_hex)?;
assert_eq!(sk, sk2);
let pk_hex = "85695fcbc06cc4c4c9451f4dce21cbf8de3e5a13bf48f44cdbb18e203\
8ba7b8bb1632d7911ef1e2e08749bddbf165352";
let pk = PublicKey::from_hex(pk_hex)?;
let pk2_hex = pk.to_hex();
let pk2 = PublicKey::from_hex(&pk2_hex)?;
assert_eq!(pk, pk2);
Ok(())
}

#[test]
fn test_serde() -> Result<()> {
let sk = SecretKey::random();
Expand Down

0 comments on commit 2509f30

Please sign in to comment.