source: trunk/CrypPlugins/QuadraticSieve/msieve/build.vc9/msieve.dll/wrapper.cpp @ 1372

Last change on this file since 1372 was 1372, checked in by Sven Rech, 12 years ago

some modifications for msieve

File size: 11.6 KB
Line 
1/**
2* This .Net msieve wrapper was written by Sven Rech (rech@cryptool.org)
3**/
4
5#include <msieve.h>
6extern "C" {
7#include "wrapper.h"
8#include "../../mpqs/mpqs.h"
9}
10
11using namespace System;
12using namespace System::Collections;
13
14//From demo.c:
15extern "C" msieve_factor* factor(char *number, char *savefile_name);
16extern "C" char* getNextFactor(msieve_factor** factor);
17extern "C" void stop_msieve(msieve_obj *obj);
18extern "C" void get_random_seeds(uint32 *seed1, uint32 *seed2);
19//From sieve.c:
20extern "C" void collect_relations(sieve_conf_t *conf, uint32 target_relations, qs_core_sieve_fcn core_sieve_fcn);
21//From relation.c:
22extern "C" void save_relation(sieve_conf_t *conf, uint32 sieve_offset,
23                uint32 *fb_offsets, uint32 num_factors, 
24                uint32 poly_index, uint32 large_prime1, uint32 large_prime2);
25
26
27//Copy a sieve configuration that can be used in a different thread:
28sieve_conf_t *copy_sieve_conf(sieve_conf_t *conf) {
29        sieve_conf_t *copy = (sieve_conf_t*)malloc(sizeof(sieve_conf_t));
30        msieve_obj *objcopy = (msieve_obj*)malloc(sizeof(msieve_obj));
31
32        *copy = *conf;
33        *objcopy = *(conf->obj);
34        copy->obj = objcopy;
35        copy->slave = 1;        //we are a slave
36
37        //threads shouldn't be allowed to access files or the factor list:
38        objcopy->logfile_name = 0;
39        objcopy->savefile.file_handle = 0;
40        objcopy->factors = 0;
41       
42        //threads shouldn't be allowed to access these fields:
43        copy->poly_a_list = 0;
44        copy->poly_list = 0;   
45        copy->relation_list = 0;
46        copy->num_relations = 0;
47        copy->cycle_list = 0;
48        copy->num_cycles = 0;
49        copy->cycle_table = 0;
50        copy->cycle_hashtable = 0;
51        copy->cycle_table_size = 0;
52        copy->cycle_table_alloc = 0;
53        copy->components = 0;
54        copy->vertices = 0;
55
56        //deep copies:
57        copy->sieve_array = (uint8 *)aligned_malloc(
58                                (size_t)copy->sieve_block_size, 64);
59        for (uint32 i = 0; i < copy->sieve_block_size; i++)
60                copy->sieve_array[i] = conf->sieve_array[i];
61
62        copy->factor_base = (fb_t *)xmalloc(objcopy->fb_size * sizeof(fb_t));
63        for (uint32 i = 0; i < objcopy->fb_size; i++)
64                copy->factor_base[i] = conf->factor_base[i];
65
66        copy->packed_fb = (packed_fb_t *)xmalloc(conf->tf_large_cutoff * sizeof(packed_fb_t));
67        for (uint32 i = 0; i < conf->tf_large_cutoff; i++)
68                copy->packed_fb[i] = conf->packed_fb[i];
69
70        copy->buckets = (bucket_t *)xcalloc((size_t)(copy->poly_block *
71                                                copy->num_sieve_blocks), 
72                                                sizeof(bucket_t));
73        for (uint32 i = 0; i < copy->poly_block * copy->num_sieve_blocks; i++) {
74                copy->buckets[i].num_alloc = 1000;
75                copy->buckets[i].list = (bucket_entry_t *)
76                                xmalloc(1000 * sizeof(bucket_entry_t));
77        }
78
79        copy->modsqrt_array = (uint32 *)xmalloc(objcopy->fb_size * sizeof(uint32));
80        for (uint32 i = 0; i < objcopy->fb_size; i++)
81                copy->modsqrt_array[i] = conf->modsqrt_array[i];
82
83        //we need new seeds:
84        uint32 seed1, seed2;
85        get_random_seeds(&seed1, &seed2);
86        copy->obj->seed1 = seed1;
87        copy->obj->seed2 = seed2;
88
89        poly_init(copy, copy->num_sieve_blocks * copy->sieve_block_size / 2);
90
91        return copy;
92}
93
94namespace Msieve
95{
96        public delegate void showProgressDelegate(IntPtr conf, int num_relations, int max_relations);
97        public delegate void prepareSievingDelegate(IntPtr conf, int update, IntPtr core_sieve_fcn);
98        public delegate void factorListChangedDelegate(IntPtr list);
99
100        public ref struct callback_struct
101        {
102        public:
103                showProgressDelegate^ showProgress;
104                prepareSievingDelegate^ prepareSieving;
105                factorListChangedDelegate^ factorListChanged;
106        };
107
108        public ref class msieve 
109        {
110        private:
111                static char* stringToCharA(String^ str)
112                {
113                        if (!str)
114                                return 0;
115                        char* ch = (char*)malloc(str->Length + 1);
116                        for (int i = 0; i < str->Length; i++)
117                                ch[i] = (char)str[i];
118                        ch[str->Length] = 0;
119                        return ch;
120                }
121
122                static void copyIntToArray(array<unsigned char>^ arr, int pos, int theInt)
123                {
124                        //We always use 4 bytes
125                        arr[pos] = theInt & 255;
126                        arr[pos+1] = (theInt >> 8) & 255;
127                        arr[pos+2] = (theInt >> 16) & 255;
128                        arr[pos+3] = (theInt >> 24) & 255;
129                }
130
131                static int getIntFromArray(array<unsigned char>^ arr, int pos)
132                {
133                        //We always use 4 bytes
134                        int res = arr[pos];
135                        res |= arr[pos+1]<<8;
136                        res |= arr[pos+2]<<16;
137                        res |= arr[pos+3]<<24;
138                       
139                        return res;
140                }
141
142        public:
143                static callback_struct^ callbacks;
144
145                //initialize msieve with callback functions:
146                static void initMsieve(callback_struct^ cb)
147                {
148                        callbacks = cb;
149                }
150
151                //factorize the number:
152                static ArrayList^ factorize(String^ number, String^ savefile)
153                {
154                        ArrayList^ factor_list = gcnew ArrayList;
155                        char* num = stringToCharA(number);     
156                        char* save = stringToCharA(savefile);
157                        msieve_factor* factors = factor(num, save);
158
159                        while (factors != 0)
160                        {
161                                char* f = getNextFactor(&factors);
162                                String^ fa = gcnew String(f);
163                                free(f);
164                                factor_list->Add(fa);
165                        }
166
167                        free(num);
168                        return factor_list;
169                }
170
171                //stop msieve:
172                static void stop(IntPtr obj)
173                {
174                        stop_msieve((msieve_obj*)obj.ToPointer());
175                }
176
177                //clone this conf (the clone can be used to run the sieving in a different thread):
178                static IntPtr cloneSieveConf(IntPtr conf)
179                {
180                        return IntPtr(copy_sieve_conf((sieve_conf_t*)conf.ToPointer()));
181                }
182
183                //free this conf (shouldn't be the conf file that belongs to the main thread):
184                static void freeSieveConf(IntPtr conf)
185                {
186                        sieve_conf_t* c = (sieve_conf_t*)conf.ToPointer();
187                        if (!c->slave)
188                                return;
189                        free(c->obj);
190                        free(c->next_poly_action);
191                        free(c->curr_b);
192                        free(c->poly_b_small[0]);
193                        free(c->poly_b_array);
194                        aligned_free(c->sieve_array);
195                        free(c->factor_base);
196                        free(c->packed_fb);
197                        for (uint32 i = 0; i < c->poly_block * c->num_sieve_blocks; i++)
198                                free(c->buckets[i].list);
199                        free(c->buckets);
200                        free(c->modsqrt_array);
201                        if (c->yield != 0)
202                        {
203                                for (int j = 0; j < c->yield->yield_count; j++)                 
204                                        if (c->yield->yield_array[j].type == 0)
205                                                free(c->yield->yield_array->rel.fb_offsets);
206                                free(c->yield->yield_array);
207                                free(c->yield);
208                        }
209                        free(c);
210                }
211
212                static void collectRelations(IntPtr conf, int target_relations, IntPtr core_sieve_fcn)
213                {
214                        collect_relations((sieve_conf_t*)conf.ToPointer(), target_relations, (qs_core_sieve_fcn)core_sieve_fcn.ToPointer());
215                }
216               
217                //get the yield in the thread of "conf" (shoudn't be the main thread):
218                static IntPtr getYield(IntPtr conf)
219                {
220                        sieve_conf_t* c = (sieve_conf_t*)conf.ToPointer();
221                        if (!c->slave)
222                                return IntPtr::Zero;
223                        relationYield* yield = c->yield;
224                        c->yield = 0;
225                        return IntPtr((void*)yield);
226                }
227
228                //stores the yield in the thread of "conf" (should be the main thread), and destroys the yield:
229                static void saveYield(IntPtr conf, IntPtr yield)
230                {
231                        sieve_conf_t* c = (sieve_conf_t*)conf.ToPointer();
232                        if (c->slave)
233                                return;                 
234                        relationYield* y = (relationYield*)yield.ToPointer();
235
236                        for (int j = 0; j < y->yield_count; j++)
237                        {
238                                if (y->yield_array[j].type == 1)
239                                        savefile_write_line(&c->obj->savefile, y->yield_array[j].polybuf);
240                                else
241                                {
242                                        relation* rel = &y->yield_array[j].rel;
243                                        save_relation(c, rel->sieve_offset, rel->fb_offsets, rel->num_factors, rel->poly_index, rel->large_prime1, rel->large_prime2);
244                                        free(rel->fb_offsets);
245                                }
246                        }
247
248                        free(y->yield_array);
249                        free(y);
250                }
251
252                static IntPtr getObjFromConf(IntPtr conf)
253                {
254                        sieve_conf_t* c = (sieve_conf_t*)conf.ToPointer();
255                        return IntPtr(c->obj);
256                }
257
258                static ArrayList^ getPrimeFactors(IntPtr factorList)
259                {
260                        char buf[929];
261                        ArrayList^ factors = gcnew ArrayList;
262                        factor_list_t * factor_list = (factor_list_t *)factorList.ToPointer();
263                        for (int c = 0; c < factor_list->num_factors; c++)
264                        {
265                                if (factor_list->final_factors[c]->type != MSIEVE_COMPOSITE)
266                                {
267                                        char* factor = mp_sprintf(&factor_list->final_factors[c]->factor, 10, buf);
268                                        factors->Add(gcnew String(factor));
269                                }
270                        }
271
272                        return factors;
273                }
274
275                static ArrayList^ getCompositeFactors(IntPtr factorList)
276                {
277                        char buf[929];
278                        ArrayList^ factors = gcnew ArrayList;
279                        factor_list_t * factor_list = (factor_list_t *)factorList.ToPointer();
280                        for (int c = 0; c < factor_list->num_factors; c++)
281                        {
282                                if (factor_list->final_factors[c]->type == MSIEVE_COMPOSITE)
283                                {
284                                        char* factor = mp_sprintf(&factor_list->final_factors[c]->factor, 10, buf);
285                                        factors->Add(gcnew String(factor));
286                                }
287                        }
288
289                        return factors;
290                }
291
292                //get's the current factor on which we are sieving:
293                static String^ getCurrentFactor(IntPtr conf)
294                {
295                        char buf[929];
296                        sieve_conf_t* c = (sieve_conf_t*)conf.ToPointer();
297                        mp_t mult;
298                        *((uint32*)(&mult.val[0])) = c->multiplier;
299                        mult.nwords = 4;
300                        mp_t n;
301                        mp_div(c->n, &mult, &n);
302                        char* nchar = mp_sprintf(&n, 10, buf);
303                        return gcnew String(nchar);
304                }
305
306                //serialize the yield, so that you can send it over the net:
307                static array<unsigned char>^ serializeYield(IntPtr yield)
308                {
309                        relationYield* y = (relationYield*)yield.ToPointer();
310                        array<unsigned char>^ out = gcnew array<unsigned char>((y->yield_count)*257 + 4);
311                        copyIntToArray(out, 0, y->yield_count);
312
313                        for (int c = 0; c < y->yield_count; c++)
314                        {
315                                out[4 + c*257] = (char)(y->yield_array[c].type);
316                                if (y->yield_array[c].type == 1)        //poly
317                                {
318                                        for (int i = 0; i < 256; i++)
319                                                out[4 + c*257 + 1 + i] = y->yield_array[c].polybuf[i];
320                                }
321                                else                                                            //relation
322                                {
323                                        copyIntToArray(out, 4+c*257 + 1, y->yield_array[c].rel.sieve_offset);
324                                        copyIntToArray(out, 4+c*257 + 1 + 4, y->yield_array[c].rel.num_factors);
325                                        copyIntToArray(out, 4+c*257 + 1 + 8, y->yield_array[c].rel.poly_index);
326                                        copyIntToArray(out, 4+c*257 + 1 + 12, y->yield_array[c].rel.large_prime1);
327                                        copyIntToArray(out, 4+c*257 + 1 + 16, y->yield_array[c].rel.large_prime2);
328                                        for (int i = 0; i < 232; i++)
329                                                copyIntToArray(out, 4+c*257 + 1 + 20 + i*4, y->yield_array[c].rel.fb_offsets[i]);
330                                }
331                        }
332
333                        return out;
334                }
335
336                static IntPtr deserializeYield(array<unsigned char>^ yield)
337                {
338                        relationYield* y = (relationYield*)malloc(sizeof(relationYield));
339                        y->yield_count = getIntFromArray(yield, 0);
340                        y->yield_array = (yield_element*)malloc(sizeof(yield_element)*y->yield_count);
341                       
342                        for (int c = 0; c < y->yield_count; c++)
343                        {
344                                y->yield_array[c].type = yield[4+c*257];
345                                if (y->yield_array[c].type == 1)        //poly
346                                {
347                                        for (int i = 0; i < 256; i++)
348                                                y->yield_array[c].polybuf[i] = yield[4 + c*257 + 1 + i];
349                                }
350                                else                                                            //relation
351                                {
352                                        y->yield_array[c].rel.sieve_offset = getIntFromArray(yield, 4+c*257 + 1);
353                                        y->yield_array[c].rel.num_factors = getIntFromArray(yield, 4+c*257 + 1 + 4);
354                                        y->yield_array[c].rel.poly_index = getIntFromArray(yield, 4+c*257 + 1 + 8);
355                                        y->yield_array[c].rel.large_prime1 = getIntFromArray(yield, 4+c*257 + 1 + 12);
356                                        y->yield_array[c].rel.large_prime2 = getIntFromArray(yield, 4+c*257 + 1 + 16);
357                                        for (int i = 0; i < 232; i++)
358                                                y->yield_array[c].rel.fb_offsets[i] = getIntFromArray(yield, 4+c*257 + 1 + 20 + i*4);
359                                }
360                        }
361                       
362                        return IntPtr((void*)y);
363                }
364        };
365
366}
367
368extern "C" void showProgress(void* conf, int num_relations, int max_relations)
369{       
370        Msieve::msieve::callbacks->showProgress(IntPtr(conf), num_relations, max_relations);
371}
372
373extern "C" void prepare_sieving(void* conf, int update, void* core_sieve_fcn)
374{
375        Msieve::msieve::callbacks->prepareSieving(IntPtr(conf), update, IntPtr(core_sieve_fcn));
376}
377
378extern "C" void throwException(char* message)
379{
380        throw gcnew Exception(gcnew String(message));
381}
382
383extern "C" void factor_list_changed(factor_list_t * factor_list)
384{
385        Msieve::msieve::callbacks->factorListChanged(IntPtr(factor_list));
386}
Note: See TracBrowser for help on using the repository browser.