extern crate alloc;
#[cfg(all(feature = "std", feature = "interop-bytes"))]
use alloc::vec::Vec;
use sm2::dsa::signature::hazmat::PrehashVerifier;
#[cfg(all(feature = "std", feature = "interop-bytes"))]
use sm2::dsa::signature::hazmat::RandomizedPrehashSigner;
#[cfg(all(feature = "std", feature = "interop-bytes"))]
use sm2::dsa::signature::RandomizedSigner;
use sm2::dsa::signature::Verifier;
use sm2::dsa::{Signature, VerifyingKey};
#[cfg(feature = "std")]
use sm2::dsa::SigningKey;
#[cfg(all(feature = "std", feature = "interop-bytes"))]
use super::rng::{CryptoRng, DynCryptoRng};
use crate::crypto::CryptoError;
pub const DEFAULT_DISTINGUISHING_ID: &str = "1234567812345678";
#[cfg(feature = "std")]
fn signing_key_from_secret(secret_key: &[u8]) -> Result<SigningKey, CryptoError> {
let sk = sm2::SecretKey::from_slice(secret_key).map_err(|_| CryptoError::InvalidKey)?;
SigningKey::new(DEFAULT_DISTINGUISHING_ID, &sk).map_err(|_| CryptoError::InternalError)
}
fn verifying_key_from_sec1(public_key_sec1: &[u8]) -> Result<VerifyingKey, CryptoError> {
VerifyingKey::from_sec1_bytes(DEFAULT_DISTINGUISHING_ID, public_key_sec1)
.map_err(|_| CryptoError::InvalidKey)
}
fn parse_signature(signature: &[u8]) -> Result<Signature, CryptoError> {
Signature::from_der(signature).map_err(|_| CryptoError::InvalidInput)
}
#[cfg(all(feature = "std", feature = "interop-bytes"))]
pub fn sm2_sign_message(
secret_key: &[u8],
msg: &[u8],
rng: &mut dyn CryptoRng,
) -> Result<Vec<u8>, CryptoError> {
let signing_key = signing_key_from_secret(secret_key)?;
let mut drng = DynCryptoRng(rng);
let sig = signing_key
.try_sign_with_rng(&mut drng, msg)
.map_err(|_| CryptoError::InternalError)?;
Ok(sig.to_der().as_bytes().to_vec())
}
pub fn sm2_verify_message_sec1(
public_key_sec1: &[u8],
msg: &[u8],
signature: &[u8],
) -> Result<(), CryptoError> {
let verifying_key = verifying_key_from_sec1(public_key_sec1)?;
let sig = parse_signature(signature)?;
verifying_key
.verify(msg, &sig)
.map_err(|_| CryptoError::VerificationFailed)
}
#[cfg(all(feature = "std", feature = "interop-bytes"))]
pub fn sm2_sign_digest(
secret_key: &[u8],
digest: &[u8; 32],
rng: &mut dyn CryptoRng,
) -> Result<Vec<u8>, CryptoError> {
let signing_key = signing_key_from_secret(secret_key)?;
let mut drng = DynCryptoRng(rng);
let sig = signing_key
.sign_prehash_with_rng(&mut drng, digest)
.map_err(|_| CryptoError::InternalError)?;
Ok(sig.to_der().as_bytes().to_vec())
}
#[cfg(feature = "interop-bytes")]
pub fn sm2_verify_digest_sec1(
public_key_sec1: &[u8],
digest: &[u8; 32],
signature: &[u8],
) -> Result<(), CryptoError> {
let verifying_key = verifying_key_from_sec1(public_key_sec1)?;
let sig = parse_signature(signature)?;
verifying_key
.verify_prehash(digest, &sig)
.map_err(|_| CryptoError::VerificationFailed)
}
pub(crate) fn verify_message_with_key(
verifying_key: &VerifyingKey,
msg: &[u8],
signature: &[u8],
) -> Result<(), CryptoError> {
let sig = parse_signature(signature)?;
verifying_key
.verify(msg, &sig)
.map_err(|_| CryptoError::VerificationFailed)
}
pub(crate) fn verify_digest_with_key(
verifying_key: &VerifyingKey,
digest: &[u8; 32],
signature: &[u8],
) -> Result<(), CryptoError> {
let sig = parse_signature(signature)?;
verifying_key
.verify_prehash(digest, &sig)
.map_err(|_| CryptoError::VerificationFailed)
}
#[cfg(feature = "std")]
pub(crate) fn signing_key_from_scalar(secret: &[u8; 32]) -> Result<SigningKey, CryptoError> {
signing_key_from_secret(secret)
}
pub(crate) fn verifying_key_from_sec1_pub(sec1: &[u8]) -> Result<VerifyingKey, CryptoError> {
verifying_key_from_sec1(sec1)
}