1 /*
2  * Most of this is from FiSH, adapted for ScrollZ by flier
3  *
4  * $Id: dh1080.c,v 1.2 2009-12-21 14:14:17 f Exp $
5  */
6 
7 /* New Diffie-Hellman 1080bit Key-exchange */
8 
9 /* For Diffie-Hellman key-exchange a 1080bit germain prime is used, the
10    generator g=2 renders a field Fp from 1 to p-1. Therefore breaking it
11    means to solve a discrete logarithm problem with no less than 1080bit.
12 
13    Base64 format is used to send the public keys over IRC.
14 
15    The calculated secret key is hashed with SHA-256, the result is converted
16    to base64 for final use with blowfish. */
17 
18 #include <string.h>
19 #include <time.h>
20 #include "irc.h"
21 
22 #ifdef HAVE_GMP
23 
24 #include "dh1080.h"
25 
26 #define ZeroMemory(x,y) memset(&x, 0, y);
27 
28 extern char *OpenCreateFile(char *, int);
29 
30 static const char prime1080[135] =
31 {
32     0xFB, 0xE1, 0x02, 0x2E, 0x23, 0xD2, 0x13, 0xE8, 0xAC, 0xFA, 0x9A, 0xE8, 0xB9, 0xDF,
33     0xAD, 0xA3, 0xEA, 0x6B, 0x7A, 0xC7, 0xA7, 0xB7, 0xE9, 0x5A, 0xB5, 0xEB, 0x2D, 0xF8,
34     0x58, 0x92, 0x1F, 0xEA, 0xDE, 0x95, 0xE6, 0xAC, 0x7B, 0xE7, 0xDE, 0x6A, 0xDB, 0xAB,
35     0x8A, 0x78, 0x3E, 0x7A, 0xF7, 0xA7, 0xFA, 0x6A, 0x2B, 0x7B, 0xEB, 0x1E, 0x72, 0xEA,
36     0xE2, 0xB7, 0x2F, 0x9F, 0xA2, 0xBF, 0xB2, 0xA2, 0xEF, 0xBE, 0xFA, 0xC8, 0x68, 0xBA,
37     0xDB, 0x3E, 0x82, 0x8F, 0xA8, 0xBA, 0xDF, 0xAD, 0xA3, 0xE4, 0xCC, 0x1B, 0xE7, 0xE8,
38     0xAF, 0xE8, 0x5E, 0x96, 0x98, 0xA7, 0x83, 0xEB, 0x68, 0xFA, 0x07, 0xA7, 0x7A, 0xB6,
39     0xAD, 0x7B, 0xEB, 0x61, 0x8A, 0xCF, 0x9C, 0xA2, 0x89, 0x7E, 0xB2, 0x8A, 0x61, 0x89,
40     0xEF, 0xA0, 0x7A, 0xB9, 0x9A, 0x8A, 0x7F, 0xA9, 0xAE, 0x29, 0x9E, 0xFA, 0x7B, 0xA6,
41     0x6D, 0xEA, 0xFE, 0xFB, 0xEF, 0xBF, 0x0B, 0x7D, 0x8B
42 };
43 
44 /* Input:  priv_key = buffer of 200 bytes
45            pub_key  = buffer of 200 bytes
46    Output: priv_key = Your private key
47            pub_key  = Your public key */
DH1080_gen(char * priv_key,char * pub_key)48 void DH1080_gen(char *priv_key, char *pub_key)
49 {
50     unsigned char raw_buf[160], iniHash[33];
51     char *filepath;
52     FILE *hRnd;
53     size_t len;
54 
55     mpz_t b_privkey, b_prime1080, b_pubkey, b_base;
56 
57     memset(priv_key, 0, 200);
58     memset(pub_key, 0, 200);
59 
60     hRnd = fopen("/dev/urandom", "r"); /* don't use /dev/random, it's a blocking device */
61     if (!hRnd) return;
62 
63     initb64();
64 
65     mpz_init(b_prime1080);
66     mpz_import(b_prime1080, 135, 1, 1, 0, 0, prime1080);
67     mpz_init(b_privkey);
68     mpz_init(b_pubkey);
69     mpz_init_set_ui(b_base, 2);
70 
71     do {
72         unsigned char temp[135];
73         fread(temp, 1, sizeof(temp), hRnd);
74         mpz_import(b_privkey, 135, 1, 1, 0, 0, temp);
75         mpz_mod(b_privkey, b_privkey, b_prime1080); /* [2, prime1080-1] */
76     } while( mpz_cmp_ui(b_privkey, 1) != 1); /* while smaller than 2 */
77     fclose(hRnd);
78 
79     mpz_powm(b_pubkey, b_base, b_privkey, b_prime1080);
80 
81     mpz_export(raw_buf, &len, 1, 1, 0, 0, b_privkey);
82     mpz_clear(b_privkey);
83     htob64(raw_buf, priv_key, len);
84 
85     mpz_export(raw_buf, &len, 1, 1, 0, 0, b_pubkey);
86     htob64(raw_buf, pub_key, len);
87     mpz_clear(b_pubkey);
88     mpz_clear(b_base);
89     mpz_clear(b_prime1080);
90 }
91 
92 
93 
94 /* Input:  MyPrivKey = Your private key
95            HisPubKey = Someones public key
96    Output: MyPrivKey has been destroyed for security reasons
97            HisPubKey = the secret key */
DH1080_comp(char * MyPrivKey,char * HisPubKey)98 int DH1080_comp(char *MyPrivKey, char *HisPubKey)
99 {
100     int i = 0;
101     size_t len;
102     unsigned char SHA256digest[35], base64_tmp[160];
103     mpz_t b_myPrivkey, b_HisPubkey, b_prime1080, b_theKey;
104 
105     /* Verify base64 strings */
106     if ((strspn(MyPrivKey, B64ABC) != strlen(MyPrivKey)) || (strspn(HisPubKey, B64ABC) != strlen(HisPubKey)))
107     {
108         memset(MyPrivKey, 0x20, strlen(MyPrivKey));
109         memset(HisPubKey, 0x20, strlen(HisPubKey));
110         return 0;
111     }
112 
113     mpz_init(b_prime1080);
114     mpz_import(b_prime1080, 135, 1, 1, 0, 0, prime1080);
115 
116     mpz_init(b_myPrivkey);
117     mpz_init(b_HisPubkey);
118     mpz_init(b_theKey);
119 
120     len=b64toh(HisPubKey, base64_tmp);
121     mpz_import(b_HisPubkey, len, 1, 1, 0, 0, base64_tmp);
122 
123     len=b64toh(MyPrivKey, base64_tmp);
124     mpz_import(b_myPrivkey, len, 1, 1, 0, 0, base64_tmp);
125     memset(MyPrivKey, 0x20, strlen(MyPrivKey));
126 
127     mpz_powm(b_theKey, b_HisPubkey, b_myPrivkey, b_prime1080);
128     mpz_clear(b_myPrivkey);
129 
130     mpz_export(base64_tmp, &len, 1, 1, 0, 0, b_theKey);
131     SHA256_memory(base64_tmp, len, SHA256digest);
132     htob64(SHA256digest, HisPubKey, 32);
133 
134     ZeroMemory(base64_tmp, sizeof(base64_tmp));
135     ZeroMemory(SHA256digest, sizeof(SHA256digest));
136 
137     mpz_clear(b_theKey);
138     mpz_clear(b_HisPubkey);
139 
140     return 1;
141 }
142 
143 #endif /* HAVE_GMP */
144