lib25519-sys 0.1.1

Rust Bindings for lib25519
Documentation
/// Constant values relevant for Ed25519
pub mod consts {
    /// Private Key Size (64 bytes)
    pub const ED25519_PRIVATE_KEY_BYTELEN: usize = 64;
    /// Public Key Size (32 bytes)
    pub const ED25519_PUBLIC_KEY_BYTELEN: usize = 32;
    /// Signature Size (32 bytes)
    pub const ED25519_SIGNATURE_BYTELEN: usize = 64;
}

pub mod algorithms {
    unsafe extern "C" {
        /// This function generates an Ed25519 keypair.
        /// Parameters:
        /// - pk (Public Key) <- mutable raw pointer to an array of 32 unsigned bytes
        /// - sk (Private Key) <- mutable raw pointer to an array of 64 unsigned bytes
        pub unsafe fn lib25519_sign_ed25519_keypair(pk: *mut u8, sk: *mut u8);

        /// This function signs a message using a private key and stores the output in `sm`.
        /// Parameters:
        /// - sm (Signed Message) <- mutable raw pointer to an array of `smlen` unsigned bytes
        /// - smlen (Signed Message Length) <- mutable reference to a signed 64-bit integer = (`mlen`` + 32)
        /// - m (Message) <- raw pointer to an array of `mlen` unsigned bytes
        /// - mlen (Message Length) <- a 64-bit signed integer
        /// - sk (Private Key) <- raw pointer to an array of 64 unsigned bytes
        pub unsafe fn lib25519_sign_ed25519(
            sm: *mut u8,
            smlen: *mut i64,
            m: *const u8,
            mlen: i64,
            sk: *const u8,
        );

        /// This function verifies the signatures of a message using a public key.
        /// Outputs `0` if a message was verified successfully and `-1`` otherwise.
        /// Parameters:
        /// - m (Message) <- mutable raw pointer to an array of `mlen` unsigned bytes
        /// - mlen (Message Length) <- mutable reference to a signed 64-bit integer
        /// - sm (Signed Message) <- raw pointer to an array of `smlen` unsigned bytes
        /// - smlen (Signed Message Length) <- signed 64-bit integer = (`mlen`` + 32)
        /// - pk (Public Key) <- raw pointer to an array of 32 unsigned bytes
        pub unsafe fn lib25519_sign_ed25519_open(
            m: *mut u8,
            mlen: *mut i64,
            sm: *const u8,
            smlen: i64,
            pk: *const u8,
        ) -> std::ffi::c_int;
    }
}

#[cfg(test)]
mod tests {
    use crate::ed25519::{
        algorithms::{
            lib25519_sign_ed25519, lib25519_sign_ed25519_keypair, lib25519_sign_ed25519_open,
        },
        consts::{
            ED25519_PRIVATE_KEY_BYTELEN, ED25519_PUBLIC_KEY_BYTELEN, ED25519_SIGNATURE_BYTELEN,
        },
    };
    use rand::prelude::*;

    #[test]
    fn test_end_to_end_signature_verification() {
        // Set Message Length
        const MLEN: usize = 1000;
        // Set Signed Message Length
        const SMLEN: usize = MLEN + ED25519_SIGNATURE_BYTELEN;
        // Allocate Memory for Private Key
        let mut sk: [u8; ED25519_PRIVATE_KEY_BYTELEN] = [0; ED25519_PRIVATE_KEY_BYTELEN];
        // Allocate Memory for Public Key
        let mut pk: [u8; ED25519_PUBLIC_KEY_BYTELEN] = [0; ED25519_PUBLIC_KEY_BYTELEN];

        // Allocate Memory for Message
        let mut msg: [u8; MLEN] = [0; MLEN];
        let mut rng = rand::thread_rng();
        // Fill Message with Random Bytes
        rng.fill_bytes(&mut msg);

        // Allocate Memory for Signed Message
        let mut signed_msg: [u8; SMLEN] = [0; SMLEN];

        let mut smlen: i64 = SMLEN as i64;
        let mut mlen: i64 = MLEN as i64;

        let verification_result;

        unsafe {
            // Generate Keypair
            lib25519_sign_ed25519_keypair(pk.as_mut_ptr(), sk.as_mut_ptr());

            // Sign Message
            lib25519_sign_ed25519(
                signed_msg.as_mut_ptr(),
                &mut smlen,
                msg.as_ptr(),
                mlen,
                sk.as_ptr(),
            );

            // Verify Signature
            verification_result = lib25519_sign_ed25519_open(
                msg.as_mut_ptr(),
                &mut mlen,
                signed_msg.as_ptr(),
                smlen,
                pk.as_ptr(),
            )
        };

        // Check Verification Result
        assert_eq!(verification_result, 0)
    }
}