// Copyright 2024 The BoringSSL Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! ML-DSA
//!
//! ML-DSA is a post-quantum key signature scheme, specified in
//! [FIPS 204](https://csrc.nist.gov/pubs/fips/204/final).
//!
//! ```
//! use bssl_crypto::mldsa;
//!
//! // Generate a key pair.
//! let (serialized_public_key, private_key, _private_seed) = mldsa::PrivateKey65::generate();
//!
//! // Send `serialized_public_key` to the verifier. The verifier parses it:
//! let public_key = mldsa::PublicKey65::parse(&serialized_public_key).unwrap();
//!
//! // The signer signs a message.
//! let message = &[0u8, 1, 2, 3];
//! let signature = private_key.sign(message);
//!
//! // Send `message` and `signature` to the verifier. The verifier checks the signature.
//! assert!(public_key.verify(message, &signature).is_ok());
//! ```

use crate::{
    as_cbs, cbb_to_vec, initialized_boxed_struct, initialized_boxed_struct_fallible,
    initialized_struct, with_output_vec, with_output_vec_fallible, FfiMutSlice, FfiSlice,
    InvalidSignatureError,
};
use alloc::{boxed::Box, vec::Vec};
use core::mem::MaybeUninit;

/// An ML-DSA-65 private key.
pub struct PrivateKey65(Box<bssl_sys::MLDSA65_private_key>);

/// An ML-DSA-65 public key.
pub struct PublicKey65(Box<bssl_sys::MLDSA65_public_key>);

/// The number of bytes in an encoded ML-DSA-65 public key.
pub const PUBLIC_KEY_BYTES_65: usize = bssl_sys::MLDSA65_PUBLIC_KEY_BYTES as usize;

/// The number of bytes in an encoded ML-DSA-65 signature.
pub const SIGNATURE_BYTES_65: usize = bssl_sys::MLDSA65_SIGNATURE_BYTES as usize;

/// An ML-DSA-87 private key.
pub struct PrivateKey87(Box<bssl_sys::MLDSA87_private_key>);

/// An ML-DSA-87 public key.
pub struct PublicKey87(Box<bssl_sys::MLDSA87_public_key>);

/// The number of bytes in an encoded ML-DSA-87 public key.
pub const PUBLIC_KEY_BYTES_87: usize = bssl_sys::MLDSA87_PUBLIC_KEY_BYTES as usize;

/// The number of bytes in an encoded ML-DSA-87 signature.
pub const SIGNATURE_BYTES_87: usize = bssl_sys::MLDSA87_SIGNATURE_BYTES as usize;

/// The number of bytes in an ML-DSA seed value.
pub const SEED_BYTES: usize = bssl_sys::MLDSA_SEED_BYTES as usize;

/// The number of bytes in an ML-DSA external mu.
pub const MU_BYTES: usize = bssl_sys::MLDSA_MU_BYTES as usize;

impl PrivateKey65 {
    /// Generates a random public/private key pair returning a serialized public
    /// key, a private key, and a private seed value that can be used to
    /// regenerate the same private key in the future.
    pub fn generate() -> (Vec<u8>, Self, [u8; SEED_BYTES]) {
        let mut public_key_bytes = Box::new_uninit_slice(PUBLIC_KEY_BYTES_65);
        let mut seed = MaybeUninit::<[u8; SEED_BYTES]>::uninit();

        let private_key = unsafe {
            // Safety: the buffers are the sizes that the FFI code requires.
            initialized_boxed_struct(|priv_key| {
                let ok = bssl_sys::MLDSA65_generate_key(
                    public_key_bytes.as_mut_ptr() as *mut u8,
                    seed.as_mut_ptr() as *mut u8,
                    priv_key,
                );
                // This function can only fail if out of memory, which is not a
                // case that this crate handles.
                assert_eq!(ok, 1);
            })
        };

        unsafe {
            (
                // Safety: the buffers are always fully initialized by
                // `MLDSA65_generate_key`.
                public_key_bytes.assume_init().into(),
                Self(private_key),
                seed.assume_init(),
            )
        }
    }

    /// Regenerates a private key from a seed value.
    pub fn from_seed(seed: &[u8; SEED_BYTES]) -> Self {
        Self(unsafe {
            // Safety: `priv_key` is the correct size via the type system and
            // is always fully written.
            initialized_boxed_struct(|priv_key| {
                let ok = bssl_sys::MLDSA65_private_key_from_seed(
                    priv_key,
                    seed.as_ffi_ptr(),
                    seed.len(),
                );
                // Since the seed value has the correct length, this function can
                // never fail.
                assert_eq!(ok, 1);
            })
        })
    }

    /// Derives the public key corresponding to this private key.
    pub fn to_public_key(&self) -> PublicKey65 {
        PublicKey65(unsafe {
            // Safety: `pub_key` is the correct size via the type system and
            // is always fully written.
            initialized_boxed_struct(|pub_key| {
                bssl_sys::MLDSA65_public_from_private(pub_key, &*self.0);
            })
        })
    }

    /// Signs a message using this private key.
    pub fn sign(&self, msg: &[u8]) -> Vec<u8> {
        unsafe {
            // Safety: `signature` is the correct size via the type system and
            // is always fully written.
            with_output_vec(SIGNATURE_BYTES_65, |signature| {
                let ok = bssl_sys::MLDSA65_sign(
                    signature,
                    &*self.0,
                    msg.as_ffi_ptr(),
                    msg.len(),
                    core::ptr::null(),
                    0,
                );
                // This function can only fail if out of memory, which is not a
                // case that this crate handles.
                assert_eq!(ok, 1);
                SIGNATURE_BYTES_65
            })
        }
    }

    /// Signs a message using this private key and the given context.
    ///
    /// This function returns None if `context` is longer than 255 bytes.
    pub fn sign_with_context(&self, msg: &[u8], context: &[u8]) -> Option<Vec<u8>> {
        unsafe {
            // Safety: `signature` is the correct size via the type system and
            // is always fully written.
            with_output_vec_fallible(SIGNATURE_BYTES_65, |signature| {
                if bssl_sys::MLDSA65_sign(
                    signature,
                    &*self.0,
                    msg.as_ffi_ptr(),
                    msg.len(),
                    context.as_ffi_ptr(),
                    context.len(),
                ) == 1
                {
                    Some(SIGNATURE_BYTES_65)
                } else {
                    None
                }
            })
        }
    }

    /// Sign pre-hashed data.
    pub fn sign_prehashed(&self, prehash: Prehash65) -> Vec<u8> {
        let representative = prehash.finalize();
        unsafe {
            // Safety: `signature` is the correct size via the type system and
            // is always fully written; `representative` is an array of the
            // correct size.
            with_output_vec(SIGNATURE_BYTES_65, |signature| {
                let ok = bssl_sys::MLDSA65_sign_message_representative(
                    signature,
                    &*self.0,
                    representative.as_ffi_ptr(),
                );
                // This function can only fail if out of memory, which is not a
                // case that this crate handles.
                assert_eq!(ok, 1);
                SIGNATURE_BYTES_65
            })
        }
    }
}

impl PublicKey65 {
    /// Parses a public key from a byte slice.
    pub fn parse(encoded: &[u8]) -> Option<Self> {
        let mut cbs = as_cbs(encoded);
        unsafe {
            // Safety: `pub_key` is the correct size via the type system and
            // is fully written if this function returns 1.
            initialized_boxed_struct_fallible(|pub_key| {
                bssl_sys::MLDSA65_parse_public_key(pub_key, &mut cbs) == 1 && cbs.len == 0
            })
        }
        .map(Self)
    }

    /// Return the serialization of this public key.
    pub fn to_bytes(&self) -> Vec<u8> {
        unsafe {
            cbb_to_vec(PUBLIC_KEY_BYTES_65, |buf| {
                let ok = bssl_sys::MLDSA65_marshal_public_key(buf, &*self.0);
                // `MLDSA65_marshal_public_key` only fails if it cannot
                // allocate memory, but `cbb_to_vec` allocates a fixed
                // amount of memory.
                assert_eq!(ok, 1);
            })
        }
    }

    /// Verifies a signature for a given message using this public key.
    pub fn verify(&self, msg: &[u8], signature: &[u8]) -> Result<(), InvalidSignatureError> {
        unsafe {
            let ok = bssl_sys::MLDSA65_verify(
                &*self.0,
                signature.as_ffi_ptr(),
                signature.len(),
                msg.as_ffi_ptr(),
                msg.len(),
                core::ptr::null(),
                0,
            );
            if ok == 1 {
                Ok(())
            } else {
                Err(InvalidSignatureError)
            }
        }
    }

    /// Verifies a signature for a given message using this public key and the given context.
    pub fn verify_with_context(
        &self,
        msg: &[u8],
        signature: &[u8],
        context: &[u8],
    ) -> Result<(), InvalidSignatureError> {
        unsafe {
            let ok = bssl_sys::MLDSA65_verify(
                &*self.0,
                signature.as_ffi_ptr(),
                signature.len(),
                msg.as_ffi_ptr(),
                msg.len(),
                context.as_ffi_ptr(),
                context.len(),
            );
            if ok == 1 {
                Ok(())
            } else {
                Err(InvalidSignatureError)
            }
        }
    }

    /// Verify pre-hashed data.
    pub fn verify_prehashed(
        &self,
        prehash: Prehash65,
        signature: &[u8],
    ) -> Result<(), InvalidSignatureError> {
        let representative = prehash.finalize();
        unsafe {
            let ok = bssl_sys::MLDSA65_verify_message_representative(
                &*self.0,
                signature.as_ffi_ptr(),
                signature.len(),
                representative.as_ffi_ptr(),
            );
            if ok == 1 {
                Ok(())
            } else {
                Err(InvalidSignatureError)
            }
        }
    }

    /// Start a pre-hashing operation using this public key.
    pub fn prehash(&self) -> Prehash65 {
        unsafe {
            // Safety: `self.0` is the correct size via the type system and
            // is fully written if this function returns 1.
            initialized_struct(|prehash: *mut Prehash65| {
                let ok = bssl_sys::MLDSA65_prehash_init(
                    &mut (*prehash).0,
                    &*self.0,
                    core::ptr::null(),
                    0,
                );
                // This function can only fail if too much context is provided, but no context is
                // used here.
                assert_eq!(ok, 1);
            })
        }
    }
}

/// An in-progress ML-DSA-65 pre-hashing operation.
pub struct Prehash65(bssl_sys::MLDSA65_prehash);

impl Prehash65 {
    /// Add data to the pre-hashing operation.
    pub fn update(&mut self, data: &[u8]) {
        unsafe {
            // Safety: `self.0` is the correct size via the type system and `data`
            // is a valid Rust slice.
            bssl_sys::MLDSA65_prehash_update(&mut self.0, data.as_ffi_ptr(), data.len());
        }
    }

    /// Complete the pre-hashing operation.
    fn finalize(mut self) -> [u8; MU_BYTES] {
        let mut mu = [0u8; MU_BYTES];
        unsafe {
            // Safety: `self.0` is the correct size via the type system, as is `mu`.
            bssl_sys::MLDSA65_prehash_finalize(mu.as_mut_ffi_ptr(), &mut self.0);
        }
        mu
    }
}

#[cfg(feature = "std")]
impl std::io::Write for Prehash65 {
    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
        self.update(buf);
        Ok(buf.len())
    }

    fn flush(&mut self) -> std::io::Result<()> {
        Ok(())
    }
}

impl PrivateKey87 {
    /// Generates a random public/private key pair returning a serialized public
    /// key, a private key, and a private seed value that can be used to
    /// regenerate the same private key in the future.
    pub fn generate() -> (Vec<u8>, Self, [u8; SEED_BYTES]) {
        let mut public_key_bytes = Box::new_uninit_slice(PUBLIC_KEY_BYTES_87);
        let mut seed = MaybeUninit::<[u8; SEED_BYTES]>::uninit();

        let private_key = unsafe {
            // Safety: the buffers are the sizes that the FFI code requires.
            initialized_boxed_struct(|priv_key| {
                let ok = bssl_sys::MLDSA87_generate_key(
                    public_key_bytes.as_mut_ptr() as *mut u8,
                    seed.as_mut_ptr() as *mut u8,
                    priv_key,
                );
                // This function can only fail if out of memory, which is not a
                // case that this crate handles.
                assert_eq!(ok, 1);
            })
        };

        unsafe {
            (
                // Safety: the buffers are always fully initialized by
                // `MLDSA87_generate_key`.
                public_key_bytes.assume_init().into(),
                Self(private_key),
                seed.assume_init(),
            )
        }
    }

    /// Regenerates a private key from a seed value.
    pub fn from_seed(seed: &[u8; SEED_BYTES]) -> Self {
        Self(unsafe {
            // Safety: `priv_key` is the correct size via the type system and
            // is always fully written.
            initialized_boxed_struct(|priv_key| {
                let ok = bssl_sys::MLDSA87_private_key_from_seed(
                    priv_key,
                    seed.as_ffi_ptr(),
                    seed.len(),
                );
                // Since the seed value has the correct length, this function can
                // never fail.
                assert_eq!(ok, 1);
            })
        })
    }

    /// Derives the public key corresponding to this private key.
    pub fn to_public_key(&self) -> PublicKey87 {
        PublicKey87(unsafe {
            // Safety: `pub_key` is the correct size via the type system and
            // is always fully written.
            initialized_boxed_struct(|pub_key| {
                bssl_sys::MLDSA87_public_from_private(pub_key, &*self.0);
            })
        })
    }

    /// Signs a message using this private key.
    pub fn sign(&self, msg: &[u8]) -> Vec<u8> {
        unsafe {
            // Safety: `signature` is the correct size via the type system and
            // is always fully written.
            with_output_vec(SIGNATURE_BYTES_87, |signature| {
                let ok = bssl_sys::MLDSA87_sign(
                    signature,
                    &*self.0,
                    msg.as_ffi_ptr(),
                    msg.len(),
                    core::ptr::null(),
                    0,
                );
                // This function can only fail if out of memory, which is not a
                // case that this crate handles.
                assert_eq!(ok, 1);
                SIGNATURE_BYTES_87
            })
        }
    }

    /// Signs a message using this private key and the given context.
    ///
    /// This function returns None if `context` is longer than 255 bytes.
    pub fn sign_with_context(&self, msg: &[u8], context: &[u8]) -> Option<Vec<u8>> {
        unsafe {
            // Safety: `signature` is the correct size via the type system and
            // is always fully written.
            with_output_vec_fallible(SIGNATURE_BYTES_87, |signature| {
                if bssl_sys::MLDSA87_sign(
                    signature,
                    &*self.0,
                    msg.as_ffi_ptr(),
                    msg.len(),
                    context.as_ffi_ptr(),
                    context.len(),
                ) == 1
                {
                    Some(SIGNATURE_BYTES_87)
                } else {
                    None
                }
            })
        }
    }

    /// Sign pre-hashed data.
    pub fn sign_prehashed(&self, prehash: Prehash87) -> Vec<u8> {
        let representative = prehash.finalize();
        unsafe {
            // Safety: `signature` is the correct size via the type system and
            // is always fully written; `representative` is an array of the
            // correct size.
            with_output_vec(SIGNATURE_BYTES_87, |signature| {
                let ok = bssl_sys::MLDSA87_sign_message_representative(
                    signature,
                    &*self.0,
                    representative.as_ffi_ptr(),
                );
                // This function can only fail if out of memory, which is not a
                // case that this crate handles.
                assert_eq!(ok, 1);
                SIGNATURE_BYTES_87
            })
        }
    }
}

impl PublicKey87 {
    /// Parses a public key from a byte slice.
    pub fn parse(encoded: &[u8]) -> Option<Self> {
        let mut cbs = as_cbs(encoded);
        unsafe {
            // Safety: `pub_key` is the correct size via the type system and
            // is fully written if this function returns 1.
            initialized_boxed_struct_fallible(|pub_key| {
                bssl_sys::MLDSA87_parse_public_key(pub_key, &mut cbs) == 1 && cbs.len == 0
            })
        }
        .map(Self)
    }

    /// Return the serialization of this public key.
    pub fn to_bytes(&self) -> Vec<u8> {
        unsafe {
            cbb_to_vec(PUBLIC_KEY_BYTES_87, |buf| {
                let ok = bssl_sys::MLDSA87_marshal_public_key(buf, &*self.0);
                // `MLDSA87_marshal_public_key` only fails if it cannot
                // allocate memory, but `cbb_to_vec` allocates a fixed
                // amount of memory.
                assert_eq!(ok, 1);
            })
        }
    }

    /// Verifies a signature for a given message using this public key.
    pub fn verify(&self, msg: &[u8], signature: &[u8]) -> Result<(), InvalidSignatureError> {
        unsafe {
            let ok = bssl_sys::MLDSA87_verify(
                &*self.0,
                signature.as_ffi_ptr(),
                signature.len(),
                msg.as_ffi_ptr(),
                msg.len(),
                core::ptr::null(),
                0,
            );
            if ok == 1 {
                Ok(())
            } else {
                Err(InvalidSignatureError)
            }
        }
    }

    /// Verifies a signature for a given message using this public key and the given context.
    pub fn verify_with_context(
        &self,
        msg: &[u8],
        signature: &[u8],
        context: &[u8],
    ) -> Result<(), InvalidSignatureError> {
        unsafe {
            let ok = bssl_sys::MLDSA87_verify(
                &*self.0,
                signature.as_ffi_ptr(),
                signature.len(),
                msg.as_ffi_ptr(),
                msg.len(),
                context.as_ffi_ptr(),
                context.len(),
            );
            if ok == 1 {
                Ok(())
            } else {
                Err(InvalidSignatureError)
            }
        }
    }

    /// Verify pre-hashed data.
    pub fn verify_prehashed(
        &self,
        prehash: Prehash87,
        signature: &[u8],
    ) -> Result<(), InvalidSignatureError> {
        let representative = prehash.finalize();
        unsafe {
            let ok = bssl_sys::MLDSA87_verify_message_representative(
                &*self.0,
                signature.as_ffi_ptr(),
                signature.len(),
                representative.as_ffi_ptr(),
            );
            if ok == 1 {
                Ok(())
            } else {
                Err(InvalidSignatureError)
            }
        }
    }

    /// Start a pre-hashing operation using this public key.
    pub fn prehash(&self) -> Prehash87 {
        unsafe {
            // Safety: `self.0` is the correct size via the type system and
            // is fully written if this function returns 1.
            initialized_struct(|prehash: *mut Prehash87| {
                let ok = bssl_sys::MLDSA87_prehash_init(
                    &mut (*prehash).0,
                    &*self.0,
                    core::ptr::null(),
                    0,
                );
                // This function can only fail if too much context is provided, but no context is
                // used here.
                assert_eq!(ok, 1);
            })
        }
    }
}

/// An in-progress ML-DSA-87 pre-hashing operation.
pub struct Prehash87(bssl_sys::MLDSA87_prehash);

impl Prehash87 {
    /// Add data to the pre-hashing operation.
    pub fn update(&mut self, data: &[u8]) {
        unsafe {
            // Safety: `self.0` is the correct size via the type system and `data`
            // is a valid Rust slice.
            bssl_sys::MLDSA87_prehash_update(&mut self.0, data.as_ffi_ptr(), data.len());
        }
    }

    /// Complete the pre-hashing operation.
    fn finalize(mut self) -> [u8; MU_BYTES] {
        let mut mu = [0u8; MU_BYTES];
        unsafe {
            // Safety: `self.0` is the correct size via the type system, as is `mu`.
            bssl_sys::MLDSA87_prehash_finalize(mu.as_mut_ffi_ptr(), &mut self.0);
        }
        mu
    }
}

#[cfg(feature = "std")]
impl std::io::Write for Prehash87 {
    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
        self.update(buf);
        Ok(buf.len())
    }

    fn flush(&mut self) -> std::io::Result<()> {
        Ok(())
    }
}

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn basic65() {
        let (serialized_public_key, private_key, private_seed) = PrivateKey65::generate();
        let public_key = PublicKey65::parse(&serialized_public_key).unwrap();
        let message = &[0u8, 1, 2, 3];
        let signature = private_key.sign(message);
        let private_key2 = PrivateKey65::from_seed(&private_seed);
        let mut signature2 = private_key2.sign(message);
        assert!(public_key.verify(message, &signature).is_ok());
        assert!(public_key.verify(message, &signature2).is_ok());

        signature2[5] ^= 1;
        assert!(public_key.verify(message, &signature2).is_err());

        let context = b"context";
        let signature3 = private_key.sign_with_context(message, context).unwrap();
        assert!(public_key.verify(message, &signature3).is_err());
        assert!(public_key
            .verify_with_context(message, &signature3, context)
            .is_ok());
    }

    #[test]
    fn sign_prehashed65() {
        let (serialized_public_key, private_key, _private_seed) = PrivateKey65::generate();
        let public_key = PublicKey65::parse(&serialized_public_key).unwrap();
        let message = &[0u8, 1, 2, 3, 4, 5, 6];

        let mut prehash = public_key.prehash();
        prehash.update(&message[0..2]);
        prehash.update(&message[2..4]);
        prehash.update(&message[4..]);
        let mut signature = private_key.sign_prehashed(prehash);

        assert!(public_key.verify(message, &signature).is_ok());
        signature[5] ^= 1;
        assert!(public_key.verify(message, &signature).is_err());
    }

    #[cfg(feature = "std")]
    #[test]
    fn sign_prehashed65_write() {
        use std::io::Write;
        let (serialized_public_key, private_key, _private_seed) = PrivateKey65::generate();
        let public_key = PublicKey65::parse(&serialized_public_key).unwrap();
        let message = &[0u8, 1, 2, 3, 4, 5, 6];

        let mut prehash = public_key.prehash();
        prehash.write(&message[0..2]).unwrap();
        prehash.write(&message[2..4]).unwrap();
        prehash.write(&message[4..]).unwrap();
        prehash.flush().unwrap();
        let mut signature = private_key.sign_prehashed(prehash);

        assert!(public_key.verify(message, &signature).is_ok());
        signature[5] ^= 1;
        assert!(public_key.verify(message, &signature).is_err());
    }

    #[test]
    fn verify_prehashed65() {
        let (serialized_public_key, private_key, _private_seed) = PrivateKey65::generate();
        let public_key = PublicKey65::parse(&serialized_public_key).unwrap();
        let message = &[0u8, 1, 2, 3, 4, 5, 6];

        let signature = private_key.sign(message);

        let mut prehash = public_key.prehash();
        prehash.update(&message[0..2]);
        prehash.update(&message[2..4]);
        assert!(public_key.verify_prehashed(prehash, &signature).is_err());

        let mut prehash = public_key.prehash();
        prehash.update(&message[0..2]);
        prehash.update(&message[2..4]);
        prehash.update(&message[4..]);
        assert!(public_key.verify_prehashed(prehash, &signature).is_ok());
    }

    #[cfg(feature = "std")]
    #[test]
    fn verify_prehashed65_write() {
        use std::io::Write;
        let (serialized_public_key, private_key, _private_seed) = PrivateKey65::generate();
        let public_key = PublicKey65::parse(&serialized_public_key).unwrap();
        let message = &[0u8, 1, 2, 3, 4, 5, 6];

        let signature = private_key.sign(message);

        let mut prehash = public_key.prehash();
        prehash.write(&message[0..2]).unwrap();
        prehash.write(&message[2..4]).unwrap();
        prehash.flush().unwrap();
        assert!(public_key.verify_prehashed(prehash, &signature).is_err());

        let mut prehash = public_key.prehash();
        prehash.write(&message[0..2]).unwrap();
        prehash.write(&message[2..4]).unwrap();
        prehash.write(&message[4..]).unwrap();
        prehash.flush().unwrap();
        assert!(public_key.verify_prehashed(prehash, &signature).is_ok());
    }

    #[test]
    fn marshal_public_key65() {
        let (serialized_public_key, private_key, _) = PrivateKey65::generate();
        let public_key = PublicKey65::parse(&serialized_public_key).unwrap();
        assert_eq!(serialized_public_key, public_key.to_bytes());
        assert_eq!(
            serialized_public_key,
            private_key.to_public_key().to_bytes()
        );
    }

    #[test]
    fn basic87() {
        let (serialized_public_key, private_key, private_seed) = PrivateKey87::generate();
        let public_key = PublicKey87::parse(&serialized_public_key).unwrap();
        let message = &[0u8, 1, 2, 3];
        let signature = private_key.sign(message);
        let private_key2 = PrivateKey87::from_seed(&private_seed);
        let mut signature2 = private_key2.sign(message);
        assert!(public_key.verify(message, &signature).is_ok());
        assert!(public_key.verify(message, &signature2).is_ok());

        signature2[5] ^= 1;
        assert!(public_key.verify(message, &signature2).is_err());

        let context = b"context";
        let signature3 = private_key.sign_with_context(message, context).unwrap();
        assert!(public_key.verify(message, &signature3).is_err());
        assert!(public_key
            .verify_with_context(message, &signature3, context)
            .is_ok());
    }

    #[test]
    fn sign_prehashed87() {
        let (serialized_public_key, private_key, _private_seed) = PrivateKey87::generate();
        let public_key = PublicKey87::parse(&serialized_public_key).unwrap();
        let message = &[0u8, 1, 2, 3, 4, 5, 6];

        let mut prehash = public_key.prehash();
        prehash.update(&message[0..2]);
        prehash.update(&message[2..4]);
        prehash.update(&message[4..]);
        let mut signature = private_key.sign_prehashed(prehash);

        assert!(public_key.verify(message, &signature).is_ok());
        signature[5] ^= 1;
        assert!(public_key.verify(message, &signature).is_err());
    }

    #[cfg(feature = "std")]
    #[test]
    fn sign_prehashed87_write() {
        use std::io::Write;
        let (serialized_public_key, private_key, _private_seed) = PrivateKey87::generate();
        let public_key = PublicKey87::parse(&serialized_public_key).unwrap();
        let message = &[0u8, 1, 2, 3, 4, 5, 6];

        let mut prehash = public_key.prehash();
        prehash.write(&message[0..2]).unwrap();
        prehash.write(&message[2..4]).unwrap();
        prehash.write(&message[4..]).unwrap();
        prehash.flush().unwrap();
        let mut signature = private_key.sign_prehashed(prehash);

        assert!(public_key.verify(message, &signature).is_ok());
        signature[5] ^= 1;
        assert!(public_key.verify(message, &signature).is_err());
    }

    #[test]
    fn verify_prehashed87() {
        let (serialized_public_key, private_key, _private_seed) = PrivateKey87::generate();
        let public_key = PublicKey87::parse(&serialized_public_key).unwrap();
        let message = &[0u8, 1, 2, 3, 4, 5, 6];

        let signature = private_key.sign(message);

        let mut prehash = public_key.prehash();
        prehash.update(&message[0..2]);
        prehash.update(&message[2..4]);
        assert!(public_key.verify_prehashed(prehash, &signature).is_err());

        let mut prehash = public_key.prehash();
        prehash.update(&message[0..2]);
        prehash.update(&message[2..4]);
        prehash.update(&message[4..]);
        assert!(public_key.verify_prehashed(prehash, &signature).is_ok());
    }

    #[cfg(feature = "std")]
    #[test]
    fn verify_prehashed87_write() {
        use std::io::Write;
        let (serialized_public_key, private_key, _private_seed) = PrivateKey87::generate();
        let public_key = PublicKey87::parse(&serialized_public_key).unwrap();
        let message = &[0u8, 1, 2, 3, 4, 5, 6];

        let signature = private_key.sign(message);

        let mut prehash = public_key.prehash();
        prehash.write(&message[0..2]).unwrap();
        prehash.write(&message[2..4]).unwrap();
        prehash.flush().unwrap();
        assert!(public_key.verify_prehashed(prehash, &signature).is_err());

        let mut prehash = public_key.prehash();
        prehash.write(&message[0..2]).unwrap();
        prehash.write(&message[2..4]).unwrap();
        prehash.write(&message[4..]).unwrap();
        prehash.flush().unwrap();
        assert!(public_key.verify_prehashed(prehash, &signature).is_ok());
    }

    #[test]
    fn marshal_public_key87() {
        let (serialized_public_key, private_key, _) = PrivateKey87::generate();
        let public_key = PublicKey87::parse(&serialized_public_key).unwrap();
        assert_eq!(serialized_public_key, public_key.to_bytes());
        assert_eq!(
            serialized_public_key,
            private_key.to_public_key().to_bytes()
        );
    }
}
