use core::fmt::Debug;
use curve25519_dalek::edwards::CompressedEdwardsY;
use curve25519_dalek::scalar::Scalar;
use crate::constants::*;
use crate::errors::*;
#[allow(non_snake_case)]
#[derive(Copy, Eq, PartialEq)]
pub(crate) struct InternalSignature {
pub(crate) R: CompressedEdwardsY,
pub(crate) s: Scalar,
}
impl Clone for InternalSignature {
fn clone(&self) -> Self {
*self
}
}
impl Debug for InternalSignature {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "Signature( R: {:?}, s: {:?} )", &self.R, &self.s)
}
}
#[cfg(feature = "legacy_compatibility")]
#[inline(always)]
fn check_scalar(bytes: [u8; 32]) -> Result<Scalar, SignatureError> {
if bytes[31] & 224 != 0 {
return Err(InternalError::ScalarFormat.into());
}
#[allow(deprecated)]
Ok(Scalar::from_bits(bytes))
}
#[cfg(not(feature = "legacy_compatibility"))]
#[inline(always)]
fn check_scalar(bytes: [u8; 32]) -> Result<Scalar, SignatureError> {
match Scalar::from_canonical_bytes(bytes).into() {
None => Err(InternalError::ScalarFormat.into()),
Some(x) => Ok(x),
}
}
impl InternalSignature {
#[inline]
#[allow(non_snake_case)]
pub fn from_bytes(bytes: &[u8; SIGNATURE_LENGTH]) -> Result<InternalSignature, SignatureError> {
let mut R_bytes: [u8; 32] = [0u8; 32];
let mut s_bytes: [u8; 32] = [0u8; 32];
R_bytes.copy_from_slice(&bytes[00..32]);
s_bytes.copy_from_slice(&bytes[32..64]);
Ok(InternalSignature {
R: CompressedEdwardsY(R_bytes),
s: check_scalar(s_bytes)?,
})
}
}
impl TryFrom<&ed25519::Signature> for InternalSignature {
type Error = SignatureError;
fn try_from(sig: &ed25519::Signature) -> Result<InternalSignature, SignatureError> {
InternalSignature::from_bytes(&sig.to_bytes())
}
}
impl From<InternalSignature> for ed25519::Signature {
fn from(sig: InternalSignature) -> ed25519::Signature {
ed25519::Signature::from_components(*sig.R.as_bytes(), *sig.s.as_bytes())
}
}