xeddsa 1.1.0

Implementation of the XEdDSA signature algorithm designed for Signal by Trevor Perrin, et al
Documentation
// SPDX-FileCopyrightText: 2023 Dominik George <nik@naturalnet.de>
//
// SPDX-License-Identifier: Apache-2.0

use crate::xed25519::*;
use crate::xeddsa::*;

const PRIV_IN: [u8; 32] = [
    0xf8, 0xce, 0xd4, 0x2b, 0x07, 0xe7, 0x81, 0x0a, 0x04, 0xcc, 0x85, 0x4b, 0x03, 0x57, 0x6d, 0xf1,
    0xe4, 0xc0, 0xfe, 0xb1, 0x6d, 0x68, 0x5e, 0x0a, 0xc0, 0x42, 0x5e, 0x1c, 0x3c, 0x5e, 0xb2, 0x47,
];
const TEST_MSG: &[u8] = b"Das Pferd frisst keinen Gurkensalat.";

#[test]
fn test_calculate_key_pair() {
    let private_key = PrivateKey::from(&PRIV_IN);

    let (signing_key_unset, verifying_key_unset) = private_key.calculate_key_pair(0);
    assert_eq!(
        signing_key_unset,
        [
            0xF8, 0xCE, 0xD4, 0x2B, 0x07, 0xE7, 0x81, 0x0A, 0x04, 0xCC, 0x85, 0x4B, 0x03, 0x57,
            0x6D, 0xF1, 0xE4, 0xC0, 0xFE, 0xB1, 0x6D, 0x68, 0x5E, 0x0A, 0xC0, 0x42, 0x5E, 0x1C,
            0x3C, 0x5E, 0xB2, 0x47
        ]
    );
    assert_eq!(
        verifying_key_unset,
        [
            0xD7, 0x6D, 0x40, 0x33, 0x2E, 0xD1, 0x13, 0x88, 0xCA, 0xA6, 0x9B, 0x50, 0x67, 0x6D,
            0x63, 0x08, 0x25, 0xCD, 0xDA, 0xD0, 0x32, 0x46, 0xED, 0xD6, 0x1E, 0xD3, 0xCA, 0x72,
            0xE6, 0xCB, 0x2C, 0x2E
        ]
    );

    let (signing_key_set, verifying_key_set) = private_key.calculate_key_pair(1);
    assert_eq!(
        signing_key_set,
        [
            0xA9, 0x54, 0xF8, 0xA4, 0x7C, 0x08, 0xDA, 0xAD, 0x2B, 0x44, 0x50, 0xE3, 0x55, 0x8A,
            0xED, 0x76, 0x1B, 0x3F, 0x01, 0x4E, 0x92, 0x97, 0xA1, 0xF5, 0x3F, 0xBD, 0xA1, 0xE3,
            0xC3, 0xA1, 0x4D, 0x08
        ]
    );
    assert_eq!(
        verifying_key_set,
        [
            0xD7, 0x6D, 0x40, 0x33, 0x2E, 0xD1, 0x13, 0x88, 0xCA, 0xA6, 0x9B, 0x50, 0x67, 0x6D,
            0x63, 0x08, 0x25, 0xCD, 0xDA, 0xD0, 0x32, 0x46, 0xED, 0xD6, 0x1E, 0xD3, 0xCA, 0x72,
            0xE6, 0xCB, 0x2C, 0xAE
        ]
    );
}

#[test]
fn test_sign_verify() {
    let private_key = PrivateKey::from(&PRIV_IN);
    let public_key = PublicKey::from(&x25519_dalek::PublicKey::from(
        &x25519_dalek::StaticSecret::from(PRIV_IN),
    ));

    let signature: [u8; 64] = private_key.sign(TEST_MSG, rand::rng());
    let valid = public_key.verify(TEST_MSG, &signature);

    assert!(valid.is_ok());
}