/*
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * FFmpeg is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include "libavformat/avformat.h"
#include "libavformat/rtmpdh.c"

#include <stdio.h>

static int test_random_shared_secret(void)
{
    FF_DH *peer1 = NULL, *peer2 = NULL;
    int ret;
    uint8_t pubkey1[128], pubkey2[128];
    uint8_t sharedkey1[128], sharedkey2[128];

    peer1 = ff_dh_init(1024);
    peer2 = ff_dh_init(1024);
    if (!peer1 || !peer2) {
        ret = AVERROR(ENOMEM);
        goto fail;
    }
    if ((ret = ff_dh_generate_public_key(peer1)) < 0)
        goto fail;
    if ((ret = ff_dh_generate_public_key(peer2)) < 0)
        goto fail;
    if ((ret = ff_dh_write_public_key(peer1, pubkey1, sizeof(pubkey1))) < 0)
        goto fail;
    if ((ret = ff_dh_write_public_key(peer2, pubkey2, sizeof(pubkey2))) < 0)
        goto fail;
    if ((ret = ff_dh_compute_shared_secret_key(peer1, pubkey2, sizeof(pubkey2),
                                               sharedkey1, sizeof(sharedkey1))) < 0)
        goto fail;
    if ((ret = ff_dh_compute_shared_secret_key(peer2, pubkey1, sizeof(pubkey1),
                                               sharedkey2, sizeof(sharedkey2))) < 0)
        goto fail;
    if (memcmp(sharedkey1, sharedkey2, sizeof(sharedkey1))) {
        printf("Mismatched generated shared key\n");
        ret = AVERROR_INVALIDDATA;
    } else {
        printf("Generated shared key ok\n");
    }
fail:
    ff_dh_free(peer1);
    ff_dh_free(peer2);
    return ret;
}

static const char *private_key =
    "976C18FCADC255B456564F74F3EEDA59D28AF6B744D743F2357BFD2404797EF896EF1A"
    "7C1CBEAAA3AB60AF3192D189CFF3F991C9CBBFD78119FCA2181384B94011943B6D6F28"
    "9E1B708E2D1A0C7771169293F03DA27E561F15F16F0AC9BC858C77A80FA98FD088A232"
    "19D08BE6F165DE0B02034B18705829FAD0ACB26A5B75EF";
static const char *public_key =
    "F272ECF8362257C5D2C3CC2229CF9C0A03225BC109B1DBC76A68C394F256ACA3EF5F64"
    "FC270C26382BF315C19E97A76104A716FC998A651E8610A3AE6CF65D8FAE5D3F32EEA0"
    "0B32CB9609B494116A825D7142D17B88E3D20EDD98743DE29CF37A23A9F6A58B960591"
    "3157D5965FCB46DDA73A1F08DD897BAE88DFE6FC937CBA";
static const uint8_t public_key_bin[] = {
    0xf2, 0x72, 0xec, 0xf8, 0x36, 0x22, 0x57, 0xc5, 0xd2, 0xc3, 0xcc, 0x22,
    0x29, 0xcf, 0x9c, 0x0a, 0x03, 0x22, 0x5b, 0xc1, 0x09, 0xb1, 0xdb, 0xc7,
    0x6a, 0x68, 0xc3, 0x94, 0xf2, 0x56, 0xac, 0xa3, 0xef, 0x5f, 0x64, 0xfc,
    0x27, 0x0c, 0x26, 0x38, 0x2b, 0xf3, 0x15, 0xc1, 0x9e, 0x97, 0xa7, 0x61,
    0x04, 0xa7, 0x16, 0xfc, 0x99, 0x8a, 0x65, 0x1e, 0x86, 0x10, 0xa3, 0xae,
    0x6c, 0xf6, 0x5d, 0x8f, 0xae, 0x5d, 0x3f, 0x32, 0xee, 0xa0, 0x0b, 0x32,
    0xcb, 0x96, 0x09, 0xb4, 0x94, 0x11, 0x6a, 0x82, 0x5d, 0x71, 0x42, 0xd1,
    0x7b, 0x88, 0xe3, 0xd2, 0x0e, 0xdd, 0x98, 0x74, 0x3d, 0xe2, 0x9c, 0xf3,
    0x7a, 0x23, 0xa9, 0xf6, 0xa5, 0x8b, 0x96, 0x05, 0x91, 0x31, 0x57, 0xd5,
    0x96, 0x5f, 0xcb, 0x46, 0xdd, 0xa7, 0x3a, 0x1f, 0x08, 0xdd, 0x89, 0x7b,
    0xae, 0x88, 0xdf, 0xe6, 0xfc, 0x93, 0x7c, 0xba
};
static const uint8_t peer_public_key[] = {
    0x58, 0x66, 0x05, 0x49, 0x94, 0x23, 0x2b, 0x66, 0x52, 0x13, 0xff, 0x46,
    0xf2, 0xb3, 0x79, 0xa9, 0xee, 0xae, 0x1a, 0x13, 0xf0, 0x71, 0x52, 0xfb,
    0x93, 0x4e, 0xee, 0x97, 0x05, 0x73, 0x50, 0x7d, 0xaf, 0x02, 0x07, 0x72,
    0xac, 0xdc, 0xa3, 0x95, 0x78, 0xee, 0x9a, 0x19, 0x71, 0x7e, 0x99, 0x9f,
    0x2a, 0xd4, 0xb3, 0xe2, 0x0c, 0x1d, 0x1a, 0x78, 0x4c, 0xde, 0xf1, 0xad,
    0xb4, 0x60, 0xa8, 0x51, 0xac, 0x71, 0xec, 0x86, 0x70, 0xa2, 0x63, 0x36,
    0x92, 0x7c, 0xe3, 0x87, 0xee, 0xe4, 0xf1, 0x62, 0x24, 0x74, 0xb4, 0x04,
    0xfa, 0x5c, 0xdf, 0xba, 0xfa, 0xa3, 0xc2, 0xbb, 0x62, 0x27, 0xd0, 0xf4,
    0xe4, 0x43, 0xda, 0x8a, 0x88, 0x69, 0x60, 0xe2, 0xdb, 0x75, 0x2a, 0x98,
    0x9d, 0xb5, 0x50, 0xe3, 0x99, 0xda, 0xe0, 0xa6, 0x14, 0xc9, 0x80, 0x12,
    0xf9, 0x3c, 0xac, 0x06, 0x02, 0x7a, 0xde, 0x74
};
static const uint8_t shared_secret[] = {
    0xb2, 0xeb, 0xcb, 0x71, 0xf3, 0x61, 0xfb, 0x5b, 0x4e, 0x5c, 0x4c, 0xcf,
    0x5c, 0x08, 0x5f, 0x96, 0x26, 0x77, 0x1d, 0x31, 0xf1, 0xe1, 0xf7, 0x4b,
    0x92, 0xac, 0x82, 0x2a, 0x88, 0xc7, 0x83, 0xe1, 0xc7, 0xf3, 0xd3, 0x1a,
    0x7d, 0xc8, 0x31, 0xe3, 0x97, 0xe4, 0xec, 0x31, 0x0e, 0x8f, 0x73, 0x1a,
    0xe4, 0xf6, 0xd8, 0xc8, 0x94, 0xff, 0xa0, 0x03, 0x84, 0x03, 0x0f, 0xa5,
    0x30, 0x5d, 0x67, 0xe0, 0x7a, 0x3b, 0x5f, 0xed, 0x4c, 0xf5, 0xbc, 0x18,
    0xea, 0xd4, 0x77, 0xa9, 0x07, 0xb3, 0x54, 0x0b, 0x02, 0xd9, 0xc6, 0xb8,
    0x66, 0x5e, 0xec, 0xa4, 0xcd, 0x47, 0xed, 0xc9, 0x38, 0xc6, 0x91, 0x08,
    0xf3, 0x85, 0x9b, 0x69, 0x16, 0x78, 0x0d, 0xb7, 0x74, 0x51, 0xaa, 0x5b,
    0x4d, 0x74, 0xe4, 0x29, 0x2e, 0x9e, 0x8e, 0xf7, 0xe5, 0x42, 0x83, 0xb0,
    0x65, 0xb0, 0xce, 0xc6, 0xb2, 0x8f, 0x5b, 0xb0
};

static int test_ref_data(void)
{
    FF_DH *dh;
    int ret = AVERROR(ENOMEM);
    uint8_t pubkey_test[128];
    uint8_t sharedkey_test[128];

    dh = ff_dh_init(1024);
    if (!dh)
        goto fail;
    bn_hex2bn(dh->priv_key, private_key, ret);
    if (!ret)
        goto fail;
    bn_hex2bn(dh->pub_key, public_key, ret);
    if (!ret)
        goto fail;
    if ((ret = ff_dh_write_public_key(dh, pubkey_test, sizeof(pubkey_test))) < 0)
        goto fail;
    if (memcmp(pubkey_test, public_key_bin, sizeof(pubkey_test))) {
        printf("Mismatched generated public key\n");
        ret = AVERROR_INVALIDDATA;
        goto fail;
    } else {
        printf("Generated public key ok\n");
    }
    if ((ret = ff_dh_compute_shared_secret_key(dh, peer_public_key, sizeof(peer_public_key),
                                               sharedkey_test, sizeof(sharedkey_test))) < 0)
        goto fail;
    if (memcmp(shared_secret, sharedkey_test, sizeof(sharedkey_test))) {
        printf("Mismatched generated shared key\n");
        ret = AVERROR_INVALIDDATA;
    } else {
        printf("Generated shared key ok\n");
    }
fail:
    ff_dh_free(dh);
    return ret;
}

int main(void)
{
    avformat_network_init();
    if (test_random_shared_secret() < 0)
        return 1;
    if (test_ref_data() < 0)
        return 1;
    return 0;
}
