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

Add Conversion from Affine to PublicKey #80

Merged
merged 4 commits into from
Sep 15, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions core/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ pub enum Error {
InvalidMessage,
InvalidInputLength,
TweakOutOfRange,
InvalidAffine
}

#[cfg(feature = "std")]
Expand All @@ -22,6 +23,7 @@ impl core::fmt::Display for Error {
Error::InvalidMessage => write!(f, "Invalid message"),
Error::InvalidInputLength => write!(f, "Invalid input length"),
Error::TweakOutOfRange => write!(f, "Tweak out of range"),
Error::InvalidAffine => write!(f, "Invalid Affine"),
}
}
}
62 changes: 39 additions & 23 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
//! Ethereum-alike cryptocurrencies.

#![deny(
unused_import_braces,
unused_imports,
unused_comparisons,
unused_must_use,
unused_variables,
non_shorthand_field_patterns,
unreachable_code,
unused_parens
unused_import_braces,
unused_imports,
unused_comparisons,
unused_must_use,
unused_variables,
non_shorthand_field_patterns,
unreachable_code,
unused_parens
)]

pub use libsecp256k1_core::*;
Expand Down Expand Up @@ -51,31 +51,35 @@ pub static ECMULT_GEN_CONTEXT: ECMultGenContext =
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
/// Public key on a secp256k1 curve.
pub struct PublicKey(Affine);

#[derive(Debug, Clone, Copy, Eq, PartialEq)]
/// Secret key (256-bit) on a secp256k1 curve.
pub struct SecretKey(Scalar);

#[derive(Debug, Clone, Copy, Eq, PartialEq)]
/// An ECDSA signature.
pub struct Signature {
pub r: Scalar,
pub s: Scalar,
}

#[derive(Debug, Clone, Copy, Eq, PartialEq)]
/// Tag used for public key recovery from signatures.
pub struct RecoveryId(u8);

#[derive(Debug, Clone, Copy, Eq, PartialEq)]
/// Hashed message input to an ECDSA signature.
pub struct Message(pub Scalar);

#[derive(Debug, Clone, Eq, PartialEq)]
/// Shared secret using ECDH.
pub struct SharedSecret<D: Digest>(GenericArray<u8, D::OutputSize>);

impl<D> Copy for SharedSecret<D>
where
D: Copy + Digest,
GenericArray<u8, D::OutputSize>: Copy,
{
}
where
D: Copy + Digest,
GenericArray<u8, D::OutputSize>: Copy,
{}

/// Format for public key parsing.
pub enum PublicKeyFormat {
Expand Down Expand Up @@ -303,11 +307,23 @@ impl Into<Affine> for PublicKey {
}
}

impl TryFrom<Affine> for PublicKey {
type Error = Error;

fn try_from(value: Affine) -> Result<Self, Self::Error> {
if value.is_infinity() | !value.is_valid_var() {
Gauthamastro marked this conversation as resolved.
Show resolved Hide resolved
Err(Error::InvalidAffine)
} else {
Ok(PublicKey(value))
}
}
}

#[cfg(feature = "std")]
impl Serialize for PublicKey {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
where
S: Serializer,
{
if serializer.is_human_readable() {
serializer.serialize_str(&base64::encode(&self.serialize()[..]))
Expand All @@ -330,8 +346,8 @@ impl<'de> de::Visitor<'de> for PublicKeyVisitor {
}

fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: de::Error,
where
E: de::Error,
{
let value: &[u8] = &base64::decode(value).unwrap();
let key_format = match value.len() {
Expand All @@ -348,8 +364,8 @@ impl<'de> de::Visitor<'de> for PublicKeyVisitor {
#[cfg(feature = "std")]
impl<'de> Deserialize<'de> for PublicKey {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: de::Deserializer<'de>,
where
D: de::Deserializer<'de>,
{
if deserializer.is_human_readable() {
deserializer.deserialize_str(PublicKeyVisitor)
Expand Down Expand Up @@ -784,9 +800,9 @@ pub fn sign_with_context(
}

#[allow(unused_assignments)]
{
nonce = Scalar::default();
}
{
nonce = Scalar::default();
}
let (sigr, sigs, recid) = result;

(Signature { r: sigr, s: sigs }, RecoveryId(recid))
Expand Down Expand Up @@ -815,7 +831,7 @@ mod tests {
SecretKey::parse(&hex!(
"1536f1d756d1abf83aaf173bc5ee3fc487c93010f18624d80bd6d4038fadd59e"
))
.unwrap()
.unwrap()
)
}
}