1 /* public key routines */
4 genkeys(char *public, char *secret)
5 common_key(char *secret, char *public, desData *deskey)
6 pk_encode(char *in, *out, DesData *deskey);
7 pk_decode(char *in, *out, DesData *deskey);
9 char public[HEXKEYBYTES + 1];
10 char secret[HEXKEYBYTES + 1];
17 #include <openssl/des.h>
20 #if defined(SOLARIS2) || defined(LINUX)
25 * Choose top 128 bits of the common key to use as our idea key.
28 extractideakey(ck, ideakey)
36 short base = (1 << 8);
42 for (i = 0; i < ((KEYSIZE - 128) / 8); i++) {
46 for (i = 0; i < 16; i++) {
55 * Choose middle 64 bits of the common key to use as our des key, possibly
56 * overwriting the lower order bits by setting parity.
59 extractdeskey(ck, deskey)
67 short base = (1 << 8);
73 for (i = 0; i < ((KEYSIZE - 64) / 2) / 8; i++) {
77 for (i = 0; i < 8; i++) {
86 * get common key from my secret key and his public key
88 void common_key(char *xsecret, char *xpublic, IdeaData *ideakey, DesData *deskey)
93 MINT *modulus = xtom(HEXMODULUS);
95 public = xtom(xpublic);
96 secret = xtom(xsecret);
98 pow(public, secret, modulus, common);
99 extractdeskey(common, deskey);
100 extractideakey(common, ideakey);
102 des_fixup_key_parity(deskey);
104 des_set_odd_parity(deskey);
116 void getseed(seed, seedsize)
125 (void)gettimeofday(&tv, (struct timezone *)NULL);
126 rseed = tv.tv_sec + tv.tv_usec;
127 /* XXX What the hell is this?! */
128 for (i = 0; i < 8; i++) {
129 rseed ^= (rseed << 8);
132 f=open("/dev/random",O_NONBLOCK|O_RDONLY);
135 read(f,&devrand,sizeof(devrand));
138 srand48((long)rseed^devrand);
140 for (i = 0; i < seedsize; i++) {
141 seed[i] = (lrand48() & 0xff);
147 * Generate a random public/secret key pair
149 void genkeys(public, secret)
155 # define BASEBITS (8*sizeof(short) - 1)
156 # define BASE (1 << BASEBITS)
161 MINT *base = itom(BASE);
162 MINT *root = itom(PROOT);
163 MINT *modulus = xtom(HEXMODULUS);
165 unsigned short seed[KEYSIZE/BASEBITS + 1];
168 getseed((char *)seed, sizeof(seed));
169 for (i = 0; i < KEYSIZE/BASEBITS + 1; i++) {
177 mdiv(sk, modulus, tmp, sk);
179 pow(root, sk, modulus, pk);
181 adjust(secret, xkey);
183 adjust(public, xkey);
192 * Adjust the input key so that it is 0-filled on the left
194 adjust(keyout, keyin)
195 char keyout[HEXKEYBYTES+1];
201 for (p = keyin; *p; p++)
203 for (s = keyout + HEXKEYBYTES; p >= keyin; p--, s--) {
206 while (s >= keyout) {
211 static char hextab[17] = "0123456789ABCDEF";
213 /* given a DES key, cbc encrypt and translate input to terminated hex */
214 void pk_encode(in, out, key)
223 memset(&i,0,sizeof(i));
224 memset(buf,0,sizeof(buf));
225 deslen = ((strlen(in) + 7)/8)*8;
226 des_key_sched(key, k);
227 des_cbc_encrypt((des_cblock *)in,(des_cblock *)buf,deslen,
229 for (l=0,op=0;l<deslen;l++) {
230 out[op++] = hextab[(buf[l] & 0xf0) >> 4];
231 out[op++] = hextab[(buf[l] & 0x0f)];
236 /* given a DES key, translate input from hex and decrypt */
237 void pk_decode(in, out, key)
246 memset(&i,0,sizeof(i));
247 memset(buf,0,sizeof(buf));
248 for (l=0,op=0;l<strlen(in)/2;l++,op+=2) {
249 if(in[op] == '0' && in[op+1] == '0') {
254 n1 = in[op] - 'A' + 10;
258 n2 = in[op+1] - 'A' + 10;
263 des_key_sched(key, k);
264 des_cbc_encrypt((des_cblock *)buf,(des_cblock *)out,strlen(in)/2,
266 out[strlen(in)/2] = '\0';