use core::cmp::Ord;
use core::cmp::Ordering;
use core::cmp::PartialOrd;
use core::fmt::Debug;
use core::hash::Hash;
use core::hash::Hasher;
use curve25519_dalek::edwards::CompressedEdwardsY;
use curve25519_dalek::scalar::Scalar;
#[cfg(feature = "serde")]
use serde::de::Error as SerdeError;
#[cfg(feature = "serde")]
use serde::de::Visitor;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
#[cfg(feature = "serde")]
use serde::{Deserializer, Serializer};
use crate::constants::*;
use crate::errors::*;
#[allow(non_snake_case)]
#[derive(Copy, Eq, PartialEq)]
pub struct Signature {
pub(crate) R: CompressedEdwardsY,
pub(crate) s: Scalar,
}
impl Clone for Signature {
fn clone(&self) -> Self {
*self
}
}
impl Debug for Signature {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
write!(f, "Signature( R: {:?}, s: {:?} )", &self.R, &self.s)
}
}
impl Hash for Signature {
fn hash<H: Hasher>(&self, state: &mut H) {
self.R.as_bytes().hash(state);
self.s.as_bytes().hash(state);
}
}
impl PartialOrd for Signature {
fn partial_cmp(&self, rhs: &Self) -> Option<Ordering> {
Some(self.cmp(rhs))
}
}
impl Ord for Signature {
fn cmp(&self, rhs: &Self) -> Ordering {
self.R
.as_bytes()
.cmp(rhs.R.as_bytes())
.then_with(|| self.s.as_bytes().cmp(rhs.s.as_bytes()))
}
}
#[cfg(feature = "legacy_compatibility")]
#[inline(always)]
fn check_scalar(bytes: [u8; 32]) -> Result<Scalar, SignatureError> {
if bytes[31] & 224 != 0 {
return Err(SignatureError(InternalError::ScalarFormatError));
}
Ok(Scalar::from_bits(bytes))
}
#[cfg(not(feature = "legacy_compatibility"))]
#[inline(always)]
fn check_scalar(bytes: [u8; 32]) -> Result<Scalar, SignatureError> {
if bytes[31] & 240 == 0 {
return Ok(Scalar::from_bits(bytes));
}
match Scalar::from_canonical_bytes(bytes) {
None => return Err(SignatureError(InternalError::ScalarFormatError)),
Some(x) => return Ok(x),
};
}
impl Signature {
#[inline]
pub fn to_bytes(&self) -> [u8; SIGNATURE_LENGTH] {
let mut signature_bytes: [u8; SIGNATURE_LENGTH] = [0u8; SIGNATURE_LENGTH];
signature_bytes[..32].copy_from_slice(&self.R.as_bytes()[..]);
signature_bytes[32..].copy_from_slice(&self.s.as_bytes()[..]);
signature_bytes
}
#[inline]
pub fn from_bytes(bytes: &[u8]) -> Result<Signature, SignatureError> {
if bytes.len() != SIGNATURE_LENGTH {
return Err(SignatureError(InternalError::BytesLengthError {
name: "Signature",
length: SIGNATURE_LENGTH,
}));
}
let mut lower: [u8; 32] = [0u8; 32];
let mut upper: [u8; 32] = [0u8; 32];
lower.copy_from_slice(&bytes[..32]);
upper.copy_from_slice(&bytes[32..]);
let s: Scalar;
match check_scalar(upper) {
Ok(x) => s = x,
Err(x) => return Err(x),
}
Ok(Signature {
R: CompressedEdwardsY(lower),
s: s,
})
}
}
#[cfg(feature = "serde")]
impl Serialize for Signature {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_bytes(&self.to_bytes()[..])
}
}
#[cfg(feature = "serde")]
impl<'d> Deserialize<'d> for Signature {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'d>,
{
struct SignatureVisitor;
impl<'d> Visitor<'d> for SignatureVisitor {
type Value = Signature;
fn expecting(&self, formatter: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
formatter.write_str("An ed25519 signature as 64 bytes, as specified in RFC8032.")
}
fn visit_bytes<E>(self, bytes: &[u8]) -> Result<Signature, E>
where
E: SerdeError,
{
Signature::from_bytes(bytes).or(Err(SerdeError::invalid_length(bytes.len(), &self)))
}
}
deserializer.deserialize_bytes(SignatureVisitor)
}
}