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

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

some msieve modifications

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