34     "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \ 
   35     "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \ 
   36     "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" \ 
   37     "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \ 
   38     "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381" \ 
   42     "7FFFFFFFFFFFFFFFE487ED5110B4611A62633145C06E0E68" \ 
   43     "948127044533E63A0105DF531D89CD9128A5043CC71A026E" \ 
   44     "F7CA8CD9E69D218D98158536F92F8A1BA7F09AB6B6A8E122" \ 
   45     "F242DABB312F3F637A262174D31BF6B585FFAE5B7A035BF6" \ 
   46     "F71C35FDAD44CFD2D74F9208BE258FF324943328F67329C0" \ 
   49 #if CONFIG_GMP || CONFIG_GCRYPT 
   53         bn = av_malloc(sizeof(*bn));    \ 
   62 #define bn_set_word(bn, w)          mpz_set_ui(bn, w) 
   63 #define bn_cmp(a, b)                mpz_cmp(a, b) 
   64 #define bn_copy(to, from)           mpz_set(to, from) 
   65 #define bn_sub_word(bn, w)          mpz_sub_ui(bn, bn, w) 
   66 #define bn_cmp_1(bn)                mpz_cmp_ui(bn, 1) 
   67 #define bn_num_bytes(bn)            (mpz_sizeinbase(bn, 2) + 7) / 8 
   68 #define bn_bn2bin(bn, buf, len)                     \ 
   70         memset(buf, 0, len);                        \ 
   71         if (bn_num_bytes(bn) <= len)                \ 
   72             mpz_export(buf, NULL, 1, 1, 0, 0, bn);  \ 
   74 #define bn_bin2bn(bn, buf, len)                     \ 
   78             mpz_import(bn, len, 1, 1, 0, 0, buf);   \ 
   80 #define bn_hex2bn(bn, buf, ret)                     \ 
   84             ret = (mpz_set_str(bn, buf, 16) == 0);  \ 
   88 #define bn_modexp(bn, y, q, p)      mpz_powm(bn, y, q, p) 
   89 #define bn_random(bn, num_bits)                       \ 
   91         int bits = num_bits;                          \ 
   93         for (bits = num_bits; bits > 0; bits -= 32) { \ 
   94             mpz_mul_2exp(bn, bn, 32);                 \ 
   95             mpz_add_ui(bn, bn, av_get_random_seed()); \ 
   97         mpz_fdiv_r_2exp(bn, bn, num_bits);            \ 
  102         if (!gcry_control(GCRYCTL_INITIALIZATION_FINISHED_P)) { \ 
  103             if (!gcry_check_version("1.5.4"))                   \ 
  104                 return AVERROR(EINVAL);                         \ 
  105             gcry_control(GCRYCTL_DISABLE_SECMEM, 0);            \ 
  106             gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0);   \ 
  108         bn = gcry_mpi_new(1);                                   \ 
  110 #define bn_free(bn)                 gcry_mpi_release(bn) 
  111 #define bn_set_word(bn, w)          gcry_mpi_set_ui(bn, w) 
  112 #define bn_cmp(a, b)                gcry_mpi_cmp(a, b) 
  113 #define bn_copy(to, from)           gcry_mpi_set(to, from) 
  114 #define bn_sub_word(bn, w)          gcry_mpi_sub_ui(bn, bn, w) 
  115 #define bn_cmp_1(bn)                gcry_mpi_cmp_ui(bn, 1) 
  116 #define bn_num_bytes(bn)            (gcry_mpi_get_nbits(bn) + 7) / 8 
  117 #define bn_bn2bin(bn, buf, len)     gcry_mpi_print(GCRYMPI_FMT_USG, buf, len, NULL, bn) 
  118 #define bn_bin2bn(bn, buf, len)     gcry_mpi_scan(&bn, GCRYMPI_FMT_USG, buf, len, NULL) 
  119 #define bn_hex2bn(bn, buf, ret)     ret = (gcry_mpi_scan(&bn, GCRYMPI_FMT_HEX, buf, 0, 0) == 0) 
  120 #define bn_modexp(bn, y, q, p)      gcry_mpi_powm(bn, y, q, p) 
  121 #define bn_random(bn, num_bits)     gcry_mpi_randomize(bn, num_bits, GCRY_WEAK_RANDOM) 
  124 #define MAX_BYTES 18000 
  126 #define dh_new()                    av_malloc(sizeof(FF_DH)) 
  128 static FFBigNum dh_generate_key(FF_DH *dh)
 
  132     num_bytes = bn_num_bytes(dh->p) - 1;
 
  133     if (num_bytes <= 0 || num_bytes > MAX_BYTES)
 
  136     bn_new(dh->priv_key);
 
  139     bn_random(dh->priv_key, 8 * num_bytes);
 
  143         bn_free(dh->priv_key);
 
  147     bn_modexp(dh->pub_key, dh->g, dh->priv_key, dh->p);
 
  152 static int dh_compute_key(FF_DH *dh, FFBigNum pub_key_bn,
 
  153                           uint32_t secret_key_len, 
uint8_t *secret_key)
 
  161     bn_modexp(k, pub_key_bn, dh->priv_key, dh->p);
 
  162     bn_bn2bin(k, secret_key, secret_key_len);
 
  166     return secret_key_len;
 
  175     bn_free(dh->pub_key);
 
  176     bn_free(dh->priv_key);
 
  180 #define bn_new(bn)                  bn = BN_new() 
  181 #define bn_free(bn)                 BN_free(bn) 
  182 #define bn_set_word(bn, w)          BN_set_word(bn, w) 
  183 #define bn_cmp(a, b)                BN_cmp(a, b) 
  184 #define bn_copy(to, from)           BN_copy(to, from) 
  185 #define bn_sub_word(bn, w)          BN_sub_word(bn, w) 
  186 #define bn_cmp_1(bn)                BN_cmp(bn, BN_value_one()) 
  187 #define bn_num_bytes(bn)            BN_num_bytes(bn) 
  188 #define bn_bn2bin(bn, buf, len)     BN_bn2bin(bn, buf) 
  189 #define bn_bin2bn(bn, buf, len)     bn = BN_bin2bn(buf, len, 0) 
  190 #define bn_hex2bn(bn, buf, ret)     ret = BN_hex2bn(&bn, buf) 
  191 #define bn_modexp(bn, y, q, p)               \ 
  193         BN_CTX *ctx = BN_CTX_new();          \ 
  195             return AVERROR(ENOMEM);          \ 
  196         if (!BN_mod_exp(bn, y, q, p, ctx)) { \ 
  198             return AVERROR(EINVAL);          \ 
  203 #define dh_new()                                DH_new() 
  204 #define dh_generate_key(dh)                     DH_generate_key(dh) 
  206 static int dh_compute_key(FF_DH *dh, FFBigNum pub_key_bn,
 
  207                           uint32_t secret_key_len, 
uint8_t *secret_key)
 
  209     if (secret_key_len < DH_size(dh))
 
  211     return DH_compute_key(secret_key, pub_key_bn, dh);
 
  249     bn_modexp(bn, y, q, p);
 
  266     if (!(dh = dh_new()))
 
  273     bn_hex2bn(dh->p, 
P1024, ret);
 
  277     bn_set_word(dh->g, 2);
 
  278     dh->length = key_len;
 
  295         if (!dh_generate_key(dh))
 
  298         bn_hex2bn(q1, 
Q1024, ret);
 
  319     len = bn_num_bytes(dh->pub_key);
 
  320     if (len <= 0 || len > pub_key_len)
 
  324     memset(pub_key, 0, pub_key_len);
 
  325     bn_bn2bin(dh->pub_key, pub_key + pub_key_len - len, len);
 
  331                                     int pub_key_len, 
uint8_t *secret_key,
 
  338     bn_bin2bn(pub_key_bn, pub_key, pub_key_len);
 
  343     bn_hex2bn(q1, 
Q1024, ret);
 
  352     } 
else if ((ret = dh_compute_key(dh, pub_key_bn, secret_key_len,
 
  366 static int test_random_shared_secret(
void)
 
  370     uint8_t pubkey1[128], pubkey2[128];
 
  371     uint8_t sharedkey1[128], sharedkey2[128];
 
  375     if (!peer1 || !peer2) {
 
  388                                                sharedkey1, 
sizeof(sharedkey1))) < 0)
 
  391                                                sharedkey2, 
sizeof(sharedkey2))) < 0)
 
  393     if (memcmp(sharedkey1, sharedkey2, 
sizeof(sharedkey1))) {
 
  394         printf(
"Mismatched generated shared key\n");
 
  397         printf(
"Generated shared key ok\n");
 
  405 static const char *private_key =
 
  406     "976C18FCADC255B456564F74F3EEDA59D28AF6B744D743F2357BFD2404797EF896EF1A" 
  407     "7C1CBEAAA3AB60AF3192D189CFF3F991C9CBBFD78119FCA2181384B94011943B6D6F28" 
  408     "9E1B708E2D1A0C7771169293F03DA27E561F15F16F0AC9BC858C77A80FA98FD088A232" 
  409     "19D08BE6F165DE0B02034B18705829FAD0ACB26A5B75EF";
 
  410 static const char *public_key =
 
  411     "F272ECF8362257C5D2C3CC2229CF9C0A03225BC109B1DBC76A68C394F256ACA3EF5F64" 
  412     "FC270C26382BF315C19E97A76104A716FC998A651E8610A3AE6CF65D8FAE5D3F32EEA0" 
  413     "0B32CB9609B494116A825D7142D17B88E3D20EDD98743DE29CF37A23A9F6A58B960591" 
  414     "3157D5965FCB46DDA73A1F08DD897BAE88DFE6FC937CBA";
 
  415 static const uint8_t public_key_bin[] = {
 
  416     0xf2, 0x72, 0xec, 0xf8, 0x36, 0x22, 0x57, 0xc5, 0xd2, 0xc3, 0xcc, 0x22,
 
  417     0x29, 0xcf, 0x9c, 0x0a, 0x03, 0x22, 0x5b, 0xc1, 0x09, 0xb1, 0xdb, 0xc7,
 
  418     0x6a, 0x68, 0xc3, 0x94, 0xf2, 0x56, 0xac, 0xa3, 0xef, 0x5f, 0x64, 0xfc,
 
  419     0x27, 0x0c, 0x26, 0x38, 0x2b, 0xf3, 0x15, 0xc1, 0x9e, 0x97, 0xa7, 0x61,
 
  420     0x04, 0xa7, 0x16, 0xfc, 0x99, 0x8a, 0x65, 0x1e, 0x86, 0x10, 0xa3, 0xae,
 
  421     0x6c, 0xf6, 0x5d, 0x8f, 0xae, 0x5d, 0x3f, 0x32, 0xee, 0xa0, 0x0b, 0x32,
 
  422     0xcb, 0x96, 0x09, 0xb4, 0x94, 0x11, 0x6a, 0x82, 0x5d, 0x71, 0x42, 0xd1,
 
  423     0x7b, 0x88, 0xe3, 0xd2, 0x0e, 0xdd, 0x98, 0x74, 0x3d, 0xe2, 0x9c, 0xf3,
 
  424     0x7a, 0x23, 0xa9, 0xf6, 0xa5, 0x8b, 0x96, 0x05, 0x91, 0x31, 0x57, 0xd5,
 
  425     0x96, 0x5f, 0xcb, 0x46, 0xdd, 0xa7, 0x3a, 0x1f, 0x08, 0xdd, 0x89, 0x7b,
 
  426     0xae, 0x88, 0xdf, 0xe6, 0xfc, 0x93, 0x7c, 0xba
 
  428 static const uint8_t peer_public_key[] = {
 
  429     0x58, 0x66, 0x05, 0x49, 0x94, 0x23, 0x2b, 0x66, 0x52, 0x13, 0xff, 0x46,
 
  430     0xf2, 0xb3, 0x79, 0xa9, 0xee, 0xae, 0x1a, 0x13, 0xf0, 0x71, 0x52, 0xfb,
 
  431     0x93, 0x4e, 0xee, 0x97, 0x05, 0x73, 0x50, 0x7d, 0xaf, 0x02, 0x07, 0x72,
 
  432     0xac, 0xdc, 0xa3, 0x95, 0x78, 0xee, 0x9a, 0x19, 0x71, 0x7e, 0x99, 0x9f,
 
  433     0x2a, 0xd4, 0xb3, 0xe2, 0x0c, 0x1d, 0x1a, 0x78, 0x4c, 0xde, 0xf1, 0xad,
 
  434     0xb4, 0x60, 0xa8, 0x51, 0xac, 0x71, 0xec, 0x86, 0x70, 0xa2, 0x63, 0x36,
 
  435     0x92, 0x7c, 0xe3, 0x87, 0xee, 0xe4, 0xf1, 0x62, 0x24, 0x74, 0xb4, 0x04,
 
  436     0xfa, 0x5c, 0xdf, 0xba, 0xfa, 0xa3, 0xc2, 0xbb, 0x62, 0x27, 0xd0, 0xf4,
 
  437     0xe4, 0x43, 0xda, 0x8a, 0x88, 0x69, 0x60, 0xe2, 0xdb, 0x75, 0x2a, 0x98,
 
  438     0x9d, 0xb5, 0x50, 0xe3, 0x99, 0xda, 0xe0, 0xa6, 0x14, 0xc9, 0x80, 0x12,
 
  439     0xf9, 0x3c, 0xac, 0x06, 0x02, 0x7a, 0xde, 0x74
 
  441 static const uint8_t shared_secret[] = {
 
  442     0xb2, 0xeb, 0xcb, 0x71, 0xf3, 0x61, 0xfb, 0x5b, 0x4e, 0x5c, 0x4c, 0xcf,
 
  443     0x5c, 0x08, 0x5f, 0x96, 0x26, 0x77, 0x1d, 0x31, 0xf1, 0xe1, 0xf7, 0x4b,
 
  444     0x92, 0xac, 0x82, 0x2a, 0x88, 0xc7, 0x83, 0xe1, 0xc7, 0xf3, 0xd3, 0x1a,
 
  445     0x7d, 0xc8, 0x31, 0xe3, 0x97, 0xe4, 0xec, 0x31, 0x0e, 0x8f, 0x73, 0x1a,
 
  446     0xe4, 0xf6, 0xd8, 0xc8, 0x94, 0xff, 0xa0, 0x03, 0x84, 0x03, 0x0f, 0xa5,
 
  447     0x30, 0x5d, 0x67, 0xe0, 0x7a, 0x3b, 0x5f, 0xed, 0x4c, 0xf5, 0xbc, 0x18,
 
  448     0xea, 0xd4, 0x77, 0xa9, 0x07, 0xb3, 0x54, 0x0b, 0x02, 0xd9, 0xc6, 0xb8,
 
  449     0x66, 0x5e, 0xec, 0xa4, 0xcd, 0x47, 0xed, 0xc9, 0x38, 0xc6, 0x91, 0x08,
 
  450     0xf3, 0x85, 0x9b, 0x69, 0x16, 0x78, 0x0d, 0xb7, 0x74, 0x51, 0xaa, 0x5b,
 
  451     0x4d, 0x74, 0xe4, 0x29, 0x2e, 0x9e, 0x8e, 0xf7, 0xe5, 0x42, 0x83, 0xb0,
 
  452     0x65, 0xb0, 0xce, 0xc6, 0xb2, 0x8f, 0x5b, 0xb0
 
  455 static int test_ref_data(
void)
 
  465     bn_hex2bn(dh->priv_key, private_key, ret);
 
  468     bn_hex2bn(dh->pub_key, public_key, ret);
 
  473     if (memcmp(pubkey_test, public_key_bin, 
sizeof(pubkey_test))) {
 
  474         printf(
"Mismatched generated public key\n");
 
  478         printf(
"Generated public key ok\n");
 
  481                                                sharedkey_test, 
sizeof(sharedkey_test))) < 0)
 
  483     if (memcmp(shared_secret, sharedkey_test, 
sizeof(sharedkey_test))) {
 
  484         printf(
"Mismatched generated shared key\n");
 
  487         printf(
"Generated shared key ok\n");
 
  496     if (test_random_shared_secret() < 0)
 
  498     if (test_ref_data() < 0)
 
uint32_t p[AV_BF_ROUNDS+2]
#define AVERROR_INVALIDDATA
Invalid data found when processing input. 
int ff_dh_write_public_key(FF_DH *dh, uint8_t *pub_key, int pub_key_len)
Write the public key into the given buffer. 
static int dh_is_valid_public_key(FFBigNum y, FFBigNum p, FFBigNum q)
int ff_dh_compute_shared_secret_key(FF_DH *dh, const uint8_t *pub_key, int pub_key_len, uint8_t *secret_key, int secret_key_len)
Compute the shared secret key from the private FF_DH value and the other party's public value...
static const uint8_t q1[256]
int ff_dh_generate_public_key(FF_DH *dh)
Generate a public key. 
void ff_dh_free(FF_DH *dh)
Free a Diffie-Hellmann context. 
av_cold FF_DH * ff_dh_init(int key_len)
Initialize a Diffie-Hellmann context. 
int main(int argc, char **argv)