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 void dh_makeshared(void *sst
, uint8_t *secret
, uint32_t secretlen
,
35 string_t rempublic
, uint8_t *sharedsecret
,
45 read_mpbin(&a
, secret
, secretlen
);
46 mpz_set_str(&b
, rempublic
, 16);
48 mpz_powm(&c
, &b
, &a
, &st
->p
);
50 write_mpbin(&c
,sharedsecret
,buflen
);
57 static list_t
*dh_apply(closure_t
*self
, struct cloc loc
, dict_t
*context
,
64 st
=safe_malloc(sizeof(*st
),"dh_apply");
65 st
->cl
.description
="dh";
68 st
->cl
.interface
=&st
->ops
;
70 st
->ops
.makepublic
=dh_makepublic
;
71 st
->ops
.makeshared
=dh_makeshared
;
73 /* We have two string arguments: the first is the modulus, and the
74 second is the generator. Both are in hex. */
77 if (i
->type
!=t_string
) {
78 cfgfatal(i
->loc
,"diffie-hellman","first argument must be a "
82 if (mpz_init_set_str(&st
->p
,p
,16)!=0) {
83 cfgfatal(i
->loc
,"diffie-hellman","\"%s\" is not a hex number "
87 cfgfatal(loc
,"diffie-hellman","you must provide a prime modulus\n");
92 if (i
->type
!=t_string
) {
93 cfgfatal(i
->loc
,"diffie-hellman","second argument must be a "
97 if (mpz_init_set_str(&st
->g
,g
,16)!=0) {
98 cfgfatal(i
->loc
,"diffie-hellman","\"%s\" is not a hex number "
102 cfgfatal(loc
,"diffie-hellman","you must provide a generator\n");
106 if (i
&& i
->type
==t_bool
&& i
->data
.bool==False
) {
107 Message(M_INFO
,"diffie-hellman (%s:%d): skipping modulus "
108 "primality check\n",loc
.file
,loc
.line
);
110 /* Test that the modulus is really prime */
111 if (mpz_probab_prime_p(&st
->p
,5)==0) {
112 cfgfatal(loc
,"diffie-hellman","modulus must be a prime\n");
115 st
->ops
.len
=mpz_sizeinbase(&st
->p
,2)/8;
117 return new_closure(&st
->cl
);
120 init_module dh_module
;
121 void dh_module(dict_t
*dict
)
123 add_closure(dict
,"diffie-hellman",dh_apply
);