Skip to main content

InternalSignature

Struct InternalSignature 

Source
pub(crate) struct InternalSignature {
    pub(crate) R: CompressedEdwardsY,
    pub(crate) s: Scalar,
}
Expand description

An ed25519 signature.

§Note

These signatures, unlike the ed25519 signature reference implementation, are “detached”—that is, they do not include a copy of the message which has been signed.

Fields§

§R: CompressedEdwardsY

R is an EdwardsPoint, formed by using an hash function with 512-bits output to produce the digest of:

  • the nonce half of the ExpandedSecretKey, and
  • the message to be signed.

This digest is then interpreted as a Scalar and reduced into an element in ℤ/lℤ. The scalar is then multiplied by the distinguished basepoint to produce R, and EdwardsPoint.

§s: Scalar

s is a Scalar, formed by using an hash function with 512-bits output to produce the digest of:

  • the r portion of this Signature,
  • the PublicKey which should be used to verify this Signature, and
  • the message to be signed.

This digest is then interpreted as a Scalar and reduced into an element in ℤ/lℤ.

Implementations§

Source§

impl InternalSignature

Source

pub fn from_bytes(bytes: &[u8; 64]) -> Result<InternalSignature, SignatureError>

Construct a Signature from a slice of bytes.

§Scalar Malleability Checking

As originally specified in the ed25519 paper (cf. the “Malleability” section of the README in this repo), no checks whatsoever were performed for signature malleability.

Later, a semi-functional, hacky check was added to most libraries to “ensure” that the scalar portion, s, of the signature was reduced mod \ell, the order of the basepoint:

if signature.s[31] & 224 != 0 {
    return Err();
}

This bit-twiddling ensures that the most significant three bits of the scalar are not set:

>>> 0b00010000 & 224
0
>>> 0b00100000 & 224
32
>>> 0b01000000 & 224
64
>>> 0b10000000 & 224
128

However, this check is hacky and insufficient to check that the scalar is fully reduced mod \ell = 2^252 + 27742317777372353535851937790883648493 as it leaves us with a guanteed bound of 253 bits. This means that there are 2^253 - 2^252 + 2774231777737235353585193779088364849311 remaining scalars which could cause malleabilllity.

RFC8032 states:

To verify a signature on a message M using public key A, […] first split the signature into two 32-octet halves. Decode the first half as a point R, and the second half as an integer S, in the range 0 <= s < L. Decode the public key A as point A’. If any of the decodings fail (including S being out of range), the signature is invalid.

However, by the time this was standardised, most libraries in use were only checking the most significant three bits. (See also the documentation for crate::VerifyingKey::verify_strict.)

Trait Implementations§

Source§

impl Clone for InternalSignature

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for InternalSignature

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl From<InternalSignature> for Signature

Source§

fn from(sig: InternalSignature) -> Signature

Converts to this type from the input type.
Source§

impl PartialEq for InternalSignature

Source§

fn eq(&self, other: &InternalSignature) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl TryFrom<&Signature> for InternalSignature

Source§

type Error = Error

The type returned in the event of a conversion error.
Source§

fn try_from(sig: &Signature) -> Result<InternalSignature, SignatureError>

Performs the conversion.
Source§

impl Copy for InternalSignature

Source§

impl Eq for InternalSignature

Source§

impl StructuralPartialEq for InternalSignature

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.