diff --git a/sdk/src/signature.rs b/sdk/src/signature.rs index 0548d7c2e4..22c21764a7 100644 --- a/sdk/src/signature.rs +++ b/sdk/src/signature.rs @@ -12,7 +12,7 @@ use std::{ use thiserror::Error; // legacy module paths -pub use crate::signer::{keypair::*, *}; +pub use crate::signer::{keypair::*, presigner::*, *}; /// Number of bytes in a signature pub const SIGNATURE_BYTES: usize = 64; @@ -113,50 +113,6 @@ impl FromStr for Signature { } } -#[derive(Clone, Debug, Default)] -pub struct Presigner { - pubkey: Pubkey, - signature: Signature, -} - -impl Presigner { - pub fn new(pubkey: &Pubkey, signature: &Signature) -> Self { - Self { - pubkey: *pubkey, - signature: *signature, - } - } -} - -#[derive(Debug, Error, PartialEq)] -pub enum PresignerError { - #[error("pre-generated signature cannot verify data")] - VerificationFailure, -} - -impl Signer for Presigner { - fn try_pubkey(&self) -> Result { - Ok(self.pubkey) - } - - fn try_sign_message(&self, message: &[u8]) -> Result { - if self.signature.verify(self.pubkey.as_ref(), message) { - Ok(self.signature) - } else { - Err(PresignerError::VerificationFailure.into()) - } - } -} - -impl PartialEq for Presigner -where - T: Signer, -{ - fn eq(&self, other: &T) -> bool { - self.pubkey() == other.pubkey() - } -} - /// NullSigner - A `Signer` implementation that always produces `Signature::default()`. /// Used as a placeholder for absentee signers whose 'Pubkey` is required to construct /// the transaction @@ -237,30 +193,6 @@ mod tests { ); } - #[test] - fn test_presigner() { - let keypair = keypair_from_seed(&[0u8; 32]).unwrap(); - let pubkey = keypair.pubkey(); - let data = [1u8]; - let sig = keypair.sign_message(&data); - - // Signer - let presigner = Presigner::new(&pubkey, &sig); - assert_eq!(presigner.try_pubkey().unwrap(), pubkey); - assert_eq!(presigner.pubkey(), pubkey); - assert_eq!(presigner.try_sign_message(&data).unwrap(), sig); - assert_eq!(presigner.sign_message(&data), sig); - let bad_data = [2u8]; - assert!(presigner.try_sign_message(&bad_data).is_err()); - assert_eq!(presigner.sign_message(&bad_data), Signature::default()); - - // PartialEq - assert_eq!(presigner, keypair); - assert_eq!(keypair, presigner); - let presigner2 = Presigner::new(&pubkey, &sig); - assert_eq!(presigner, presigner2); - } - #[test] fn test_off_curve_pubkey_verify_fails() { // Golden point off the ed25519 curve diff --git a/sdk/src/signer/mod.rs b/sdk/src/signer/mod.rs index dc81d8257f..d240e2d44e 100644 --- a/sdk/src/signer/mod.rs +++ b/sdk/src/signer/mod.rs @@ -11,6 +11,7 @@ use { }; pub mod keypair; +pub mod presigner; #[derive(Debug, Error, PartialEq)] pub enum SignerError { diff --git a/sdk/src/signer/presigner.rs b/sdk/src/signer/presigner.rs new file mode 100644 index 0000000000..4b9c12c11a --- /dev/null +++ b/sdk/src/signer/presigner.rs @@ -0,0 +1,88 @@ +#![cfg(feature = "full")] + +use { + crate::{ + pubkey::Pubkey, + signature::Signature, + signer::{Signer, SignerError}, + }, + thiserror::Error, +}; + +/// A `Signer` implementation that represents a `Signature` that has been +/// constructed externally. Performs a signature verification against the +/// expected message upon `sign()` requests to affirm its relationship to +/// the `message` bytes +#[derive(Clone, Debug, Default)] +pub struct Presigner { + pubkey: Pubkey, + signature: Signature, +} + +impl Presigner { + pub fn new(pubkey: &Pubkey, signature: &Signature) -> Self { + Self { + pubkey: *pubkey, + signature: *signature, + } + } +} + +#[derive(Debug, Error, PartialEq)] +pub enum PresignerError { + #[error("pre-generated signature cannot verify data")] + VerificationFailure, +} + +impl Signer for Presigner { + fn try_pubkey(&self) -> Result { + Ok(self.pubkey) + } + + fn try_sign_message(&self, message: &[u8]) -> Result { + if self.signature.verify(self.pubkey.as_ref(), message) { + Ok(self.signature) + } else { + Err(PresignerError::VerificationFailure.into()) + } + } +} + +impl PartialEq for Presigner +where + T: Signer, +{ + fn eq(&self, other: &T) -> bool { + self.pubkey() == other.pubkey() + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::signer::keypair::keypair_from_seed; + + #[test] + fn test_presigner() { + let keypair = keypair_from_seed(&[0u8; 32]).unwrap(); + let pubkey = keypair.pubkey(); + let data = [1u8]; + let sig = keypair.sign_message(&data); + + // Signer + let presigner = Presigner::new(&pubkey, &sig); + assert_eq!(presigner.try_pubkey().unwrap(), pubkey); + assert_eq!(presigner.pubkey(), pubkey); + assert_eq!(presigner.try_sign_message(&data).unwrap(), sig); + assert_eq!(presigner.sign_message(&data), sig); + let bad_data = [2u8]; + assert!(presigner.try_sign_message(&bad_data).is_err()); + assert_eq!(presigner.sign_message(&bad_data), Signature::default()); + + // PartialEq + assert_eq!(presigner, keypair); + assert_eq!(keypair, presigner); + let presigner2 = Presigner::new(&pubkey, &sig); + assert_eq!(presigner, presigner2); + } +}