root/lang/perl/Crypt-DH-GMP/trunk/GMP.xs @ 10267

Revision 10267, 4.4 kB (checked in by daisuke, 5 years ago)

Add "base" to mpz2sv_str

Line 
1/* $Id$
2 *
3 * Copyright (c) 2008 Daisuke Maki <daisuke@endeworks.jp>
4 */
5
6#ifndef __CRYPT_DH_GMP_XS__
7#define __CRYPT_DH_GMP_XS__
8
9#include "dh_gmp.h"
10
11#define DH_G(x)       *((x)->g)
12#define DH_P(x)       *((x)->p)
13#define DH_PRIVKEY(x) *((x)->priv_key)
14#define DH_PUBKEY(x)  *((x)->pub_key)
15
16#define DH_G_PTR(x)       (x)->g
17#define DH_P_PTR(x)       (x)->p
18#define DH_PRIVKEY_PTR(x) (x)->priv_key
19#define DH_PUBKEY_PTR(x)  (x)->pub_key
20
21static
22void DH_mpz_rand_set(mpz_t *v, unsigned int bits)
23{
24    gmp_randstate_t state;
25    gmp_randinit_default(state);
26    gmp_randseed_ui(state, (unsigned long) time(NULL));
27    mpz_urandomb(*v, state, bits);
28    gmp_randclear(state);
29}
30
31static inline
32char *DH_mpz2sv_str(mpz_t *v, unsigned int base)
33{
34    STRLEN len = 0;
35    char *buf, *buf_end;
36
37    /* len is always >= 1, and might be off (greater) by one than real len */
38    len = mpz_sizeinbase(*v, base);
39    Newxz(buf, len + 2, char);
40    buf_end = buf + len - 1; /* end of storage (-1) */
41    mpz_get_str(buf, base, *v);
42    if (*buf_end == 0) {
43        Renew(buf, len - 1, char); /* got one shorter than expected */
44    }
45    return buf;
46}
47
48#endif /* __CRYPT_DH_GMP_XS__ */
49
50MODULE = Crypt::DH::GMP       PACKAGE = Crypt::DH::GMP  PREFIX = DH_gmp_
51
52PROTOTYPES: DISABLE
53
54DH_gmp_t *
55DH_gmp__xs_new(class, p, g, priv_key = NULL)
56        char *class;
57        char *p;
58        char *g;
59        char *priv_key;
60    PREINIT:
61        DH_gmp_t *dh;
62    CODE:
63        Newxz(dh, 1, DH_gmp_t);
64        Newxz(DH_P_PTR(dh),       1, mpz_t);
65        Newxz(DH_G_PTR(dh),       1, mpz_t);
66        Newxz(DH_PRIVKEY_PTR(dh), 1, mpz_t);
67        Newxz(DH_PUBKEY_PTR(dh),  1, mpz_t);
68
69        mpz_init(DH_PUBKEY(dh));
70        mpz_init_set_str(DH_P(dh), p, 0);
71        mpz_init_set_str(DH_G(dh), g, 0);
72        if (priv_key != NULL && sv_len(ST(3)) > 0) {
73            mpz_init_set_str(DH_PRIVKEY(dh), priv_key, 10);
74        } else {
75            mpz_init_set_ui(DH_PRIVKEY(dh), 0);
76        }
77
78        RETVAL = dh;
79    OUTPUT:
80        RETVAL
81
82void
83DH_gmp_generate_keys(dh)
84        DH_gmp_t *dh;
85    CODE:
86        if (mpz_cmp_ui(DH_PRIVKEY(dh), 0) == 0) {
87            mpz_t max;
88
89            /* not initialized, eh? */
90            mpz_init(max);
91            mpz_sub_ui(max, DH_P(dh), 1);
92            do {
93                DH_mpz_rand_set(DH_PRIVKEY_PTR(dh), mpz_sizeinbase(DH_P(dh), 2));
94            } while ( mpz_cmp(DH_PRIVKEY(dh), max) > 0 );
95        }
96           
97        mpz_powm( DH_PUBKEY(dh), DH_G(dh), DH_PRIVKEY(dh), DH_P(dh) );
98
99char *
100DH_gmp_compute_key(dh, pub_key)
101        DH_gmp_t *dh;
102        char * pub_key;
103    PREINIT:
104        DH_mpz_t mpz_ret;
105        DH_mpz_t mpz_pub_key;
106    CODE:
107        mpz_init(mpz_ret);
108        mpz_init_set_str(mpz_pub_key, pub_key, 0);
109        mpz_powm(mpz_ret, mpz_pub_key, DH_PRIVKEY(dh), DH_P(dh));
110        RETVAL = DH_mpz2sv_str(&mpz_ret, 10);
111        mpz_clear(mpz_ret);
112        mpz_clear(mpz_pub_key);
113    OUTPUT:
114        RETVAL
115
116char *
117DH_gmp_priv_key(dh)
118        DH_gmp_t *dh;
119    CODE:
120        RETVAL = DH_mpz2sv_str(DH_PRIVKEY_PTR(dh), 10);
121    OUTPUT:
122        RETVAL
123
124char *
125DH_gmp_pub_key(dh)
126        DH_gmp_t *dh;
127    CODE:
128        RETVAL = DH_mpz2sv_str(DH_PUBKEY_PTR(dh), 10);
129    OUTPUT:
130        RETVAL
131
132char *
133DH_gmp_g(dh, ...)
134        DH_gmp_t *dh;
135    PREINIT:
136        STRLEN n_a;
137    CODE:
138        RETVAL = DH_mpz2sv_str(DH_G_PTR(dh), 10);
139        if (items > 1) {
140            mpz_init_set_str( DH_G(dh), (char *) SvPV(ST(1), n_a), 0 );
141        }
142    OUTPUT:
143        RETVAL
144
145char *
146DH_gmp_p(dh, ...)
147        DH_gmp_t *dh;
148    PREINIT:
149        STRLEN n_a;
150    CODE:
151        RETVAL = DH_mpz2sv_str(DH_P_PTR(dh), 10);
152        if (items > 1) {
153            mpz_init_set_str( DH_P(dh), (char *) SvPV(ST(1), n_a), 0 );
154        }
155    OUTPUT:
156        RETVAL
157
158void
159DESTROY(dh)
160        DH_gmp_t *dh;
161    CODE:
162#ifdef VERY_VERBOSE
163        PerlIO_printf(PerlIO_stderr(), "DH->DESTROY called\n" );
164#endif
165        mpz_clear(DH_P(dh));
166        mpz_clear(DH_G(dh));
167        mpz_clear(DH_PUBKEY(dh));
168        mpz_clear(DH_PRIVKEY(dh));
169#ifdef VERY_VERBOSE
170        PerlIO_printf(PerlIO_stderr(), "cleared mpz_t\n" );
171#endif
172        Safefree(DH_P_PTR(dh));
173        Safefree(DH_G_PTR(dh));
174        Safefree(DH_PRIVKEY_PTR(dh));
175        Safefree(DH_PUBKEY_PTR(dh));
176#ifdef VERY_VERBOSE
177        PerlIO_printf(PerlIO_stderr(), "freed mpz_t\n" );
178#endif
179        Safefree(dh);
180#ifdef VERY_VERBOSE
181        PerlIO_printf(PerlIO_stderr(), "DH->DESTROY done\n" );
182#endif
183       
Note: See TracBrowser for help on using the browser.