11 MP_INT p
,g
; /* prime modulus and generator */
14 static string_t
dh_makepublic(void *sst
, uint8_t *secret
, uint32_t secretlen
)
18 MP_INT a
, b
; /* a is secret key, b is public key */
23 read_mpbin(&a
, secret
, secretlen
);
25 mpz_powm(&b
, &st
->g
, &a
, &st
->p
);
34 static dh_makeshared_fn dh_makeshared
;
35 static void dh_makeshared(void *sst
, uint8_t *secret
, uint32_t secretlen
,
36 cstring_t rempublic
, uint8_t *sharedsecret
,
46 read_mpbin(&a
, secret
, secretlen
);
47 mpz_set_str(&b
, rempublic
, 16);
49 mpz_powm(&c
, &b
, &a
, &st
->p
);
51 write_mpbin(&c
,sharedsecret
,buflen
);
58 static list_t
*dh_apply(closure_t
*self
, struct cloc loc
, dict_t
*context
,
65 st
=safe_malloc(sizeof(*st
),"dh_apply");
66 st
->cl
.description
="dh";
69 st
->cl
.interface
=&st
->ops
;
71 st
->ops
.makepublic
=dh_makepublic
;
72 st
->ops
.makeshared
=dh_makeshared
;
74 /* We have two string arguments: the first is the modulus, and the
75 second is the generator. Both are in hex. */
78 if (i
->type
!=t_string
) {
79 cfgfatal(i
->loc
,"diffie-hellman","first argument must be a "
83 if (mpz_init_set_str(&st
->p
,p
,16)!=0) {
84 cfgfatal(i
->loc
,"diffie-hellman","\"%s\" is not a hex number "
88 cfgfatal(loc
,"diffie-hellman","you must provide a prime modulus\n");
93 if (i
->type
!=t_string
) {
94 cfgfatal(i
->loc
,"diffie-hellman","second argument must be a "
98 if (mpz_init_set_str(&st
->g
,g
,16)!=0) {
99 cfgfatal(i
->loc
,"diffie-hellman","\"%s\" is not a hex number "
103 cfgfatal(loc
,"diffie-hellman","you must provide a generator\n");
107 if (i
&& i
->type
==t_bool
&& i
->data
.bool==False
) {
108 Message(M_INFO
,"diffie-hellman (%s:%d): skipping modulus "
109 "primality check\n",loc
.file
,loc
.line
);
111 /* Test that the modulus is really prime */
112 if (mpz_probab_prime_p(&st
->p
,5)==0) {
113 cfgfatal(loc
,"diffie-hellman","modulus must be a prime\n");
116 st
->ops
.len
=mpz_sizeinbase(&st
->p
,2)/8;
118 return new_closure(&st
->cl
);
121 void dh_module(dict_t
*dict
)
123 add_closure(dict
,"diffie-hellman",dh_apply
);