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