]> pd.if.org Git - zpackage/blob - libtomcrypt/src/pk/dh/dh_shared_secret.c
commit files needed for zpm-fetchurl
[zpackage] / libtomcrypt / src / pk / dh / dh_shared_secret.c
1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
2  *
3  * LibTomCrypt is a library that provides various cryptographic
4  * algorithms in a highly modular and flexible manner.
5  *
6  * The library is free for all purposes without any express
7  * guarantee it works.
8  */
9
10 #include "tomcrypt.h"
11
12 #ifdef LTC_MDH
13
14 /**
15    Create a DH shared secret.
16    @param private_key     The private DH key in the pair
17    @param public_key      The public DH key in the pair
18    @param out             [out] The destination of the shared data
19    @param outlen          [in/out] The max size and resulting size of the shared data.
20    @return CRYPT_OK if successful
21 */
22 int dh_shared_secret(dh_key *private_key, dh_key *public_key,
23                      unsigned char *out, unsigned long *outlen)
24 {
25    void *tmp;
26    unsigned long x;
27    int err;
28
29    LTC_ARGCHK(private_key != NULL);
30    LTC_ARGCHK(public_key  != NULL);
31    LTC_ARGCHK(out         != NULL);
32    LTC_ARGCHK(outlen      != NULL);
33
34    /* types valid? */
35    if (private_key->type != PK_PRIVATE) {
36       return CRYPT_PK_NOT_PRIVATE;
37    }
38
39    /* same DH group? */
40    if (mp_cmp(private_key->prime, public_key->prime) != LTC_MP_EQ) { return CRYPT_PK_TYPE_MISMATCH; }
41    if (mp_cmp(private_key->base, public_key->base) != LTC_MP_EQ)   { return CRYPT_PK_TYPE_MISMATCH; }
42
43    /* init big numbers */
44    if ((err = mp_init(&tmp)) != CRYPT_OK) {
45       return err;
46    }
47
48    /* check public key */
49    if ((err = dh_check_pubkey(public_key)) != CRYPT_OK) {
50       goto error;
51    }
52
53    /* compute tmp = y^x mod p */
54    if ((err = mp_exptmod(public_key->y, private_key->x, private_key->prime, tmp)) != CRYPT_OK)  {
55       goto error;
56    }
57
58    /* enough space for output? */
59    x = (unsigned long)mp_unsigned_bin_size(tmp);
60    if (*outlen < x) {
61       *outlen = x;
62       err = CRYPT_BUFFER_OVERFLOW;
63       goto error;
64    }
65    if ((err = mp_to_unsigned_bin(tmp, out)) != CRYPT_OK) {
66       goto error;
67    }
68    *outlen = x;
69    err = CRYPT_OK;
70
71 error:
72    mp_clear(tmp);
73    return err;
74 }
75
76 #endif /* LTC_MDH */
77
78 /* ref:         $Format:%D$ */
79 /* git commit:  $Format:%H$ */
80 /* commit time: $Format:%ai$ */