cncs-sm2-kit 0.1.0

Chinese National Cryptography Standard - SM2 Kit
Documentation
use std::{error, fmt};

use num_bigint::{BigUint, ParseBigIntError};
use num_traits::Num as _;

#[derive(Clone)]
pub struct Signature {
    pub r: BigUint,
    pub s: BigUint,
}
impl fmt::Display for Signature {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(
            f,
            "Signature(r: {} s: {})",
            &self.r.to_str_radix(16).to_uppercase(),
            &self.s.to_str_radix(16).to_uppercase()
        )
    }
}

impl Signature {
    pub fn new(r: BigUint, s: BigUint) -> Self {
        Self { r, s }
    }

    pub fn from_bytes(r_bytes: &[u8], s_bytes: &[u8]) -> Self {
        let r = BigUint::from_bytes_be(r_bytes);
        let s = BigUint::from_bytes_be(s_bytes);
        Self { r, s }
    }

    pub fn from_hex_str(r_hex_str: &str, s_hex_str: &str) -> Result<Self, ParseBigIntError> {
        let r = BigUint::from_str_radix(r_hex_str, 16)?;
        let s = BigUint::from_str_radix(s_hex_str, 16)?;
        Ok(Self { r, s })
    }

    pub fn from_concated_hex_str(hex_str: &str) -> Result<Self, SignatureFromConcatedHexStrError> {
        match hex_str.len() {
            128 => Self::from_hex_str(&hex_str[..64], &hex_str[64..])
                .map_err(SignatureFromConcatedHexStrError::ParseBigIntError),
            _ => Err(SignatureFromConcatedHexStrError::Invalid),
        }
    }

    pub fn to_concated_bytes(&self) -> Vec<u8> {
        let mut bytes = vec![];
        bytes.extend_from_slice(&self.r.to_bytes_be()[..]);
        bytes.extend_from_slice(&self.s.to_bytes_be()[..]);
        bytes
    }

    pub fn to_concated_hex_str(&self) -> String {
        format!(
            "{}{}",
            &self.r.to_str_radix(16).to_uppercase(),
            &self.s.to_str_radix(16).to_uppercase()
        )
    }
}

#[derive(Debug)]
pub enum SignatureFromConcatedHexStrError {
    Invalid,
    ParseBigIntError(ParseBigIntError),
}
impl fmt::Display for SignatureFromConcatedHexStrError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{:?}", self)
    }
}
impl error::Error for SignatureFromConcatedHexStrError {}

//
//
//
impl From<&Signature> for libsm::sm2::signature::Signature {
    fn from(s: &Signature) -> Self {
        Self::new(s.r.to_bytes_be().as_ref(), s.s.to_bytes_be().as_ref())
    }
}

impl From<&libsm::sm2::signature::Signature> for Signature {
    fn from(s: &libsm::sm2::signature::Signature) -> Self {
        Self::new(s.get_r().to_owned(), s.get_s().to_owned())
    }
}