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

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

quadratic sieve fix

File size: 12.7 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//From driver.c:
26extern "C" uint32 msieve_run_core(msieve_obj *obj, mp_t *n, 
27                                factor_list_t *factor_list);
28
29//Copy a sieve configuration that can be used in a different thread:
30sieve_conf_t *copy_sieve_conf(sieve_conf_t *conf) {
31        sieve_conf_t *copy = (sieve_conf_t*)malloc(sizeof(sieve_conf_t));
32        msieve_obj *objcopy = (msieve_obj*)malloc(sizeof(msieve_obj));
33
34        *copy = *conf;
35        *objcopy = *(conf->obj);
36        copy->obj = objcopy;
37        copy->slave = 1;        //we are a slave
38
39        //threads shouldn't be allowed to access files or the factor list:
40        objcopy->logfile_name = 0;
41        objcopy->savefile.file_handle = 0;
42        objcopy->factors = 0;
43       
44        //threads shouldn't be allowed to access these fields:
45        copy->poly_a_list = 0;
46        copy->poly_list = 0;   
47        copy->relation_list = 0;
48        copy->num_relations = 0;
49        copy->cycle_list = 0;
50        copy->num_cycles = 0;
51        copy->cycle_table = 0;
52        copy->cycle_hashtable = 0;
53        copy->cycle_table_size = 0;
54        copy->cycle_table_alloc = 0;
55        copy->components = 0;
56        copy->vertices = 0;
57
58        //deep copies:
59        copy->sieve_array = (uint8 *)aligned_malloc(
60                                (size_t)copy->sieve_block_size, 64);
61        for (uint32 i = 0; i < copy->sieve_block_size; i++)
62                copy->sieve_array[i] = conf->sieve_array[i];
63
64        copy->factor_base = (fb_t *)xmalloc(objcopy->fb_size * sizeof(fb_t));
65        for (uint32 i = 0; i < objcopy->fb_size; i++)
66                copy->factor_base[i] = conf->factor_base[i];
67
68        copy->packed_fb = (packed_fb_t *)xmalloc(conf->tf_large_cutoff * sizeof(packed_fb_t));
69        for (uint32 i = 0; i < conf->tf_large_cutoff; i++)
70                copy->packed_fb[i] = conf->packed_fb[i];
71
72        copy->buckets = (bucket_t *)xcalloc((size_t)(copy->poly_block *
73                                                copy->num_sieve_blocks), 
74                                                sizeof(bucket_t));
75        for (uint32 i = 0; i < copy->poly_block * copy->num_sieve_blocks; i++) {
76                copy->buckets[i].num_alloc = 1000;
77                copy->buckets[i].list = (bucket_entry_t *)
78                                xmalloc(1000 * sizeof(bucket_entry_t));
79        }
80
81        copy->modsqrt_array = (uint32 *)xmalloc(objcopy->fb_size * sizeof(uint32));
82        for (uint32 i = 0; i < objcopy->fb_size; i++)
83                copy->modsqrt_array[i] = conf->modsqrt_array[i];
84
85        //we need new seeds:
86        uint32 seed1, seed2;
87        get_random_seeds(&seed1, &seed2);
88        copy->obj->seed1 = seed1;
89        copy->obj->seed2 = seed2;
90
91        poly_init(copy, copy->num_sieve_blocks * copy->sieve_block_size / 2);
92
93        return copy;
94}
95
96namespace Msieve
97{
98        public delegate void prepareSievingDelegate(IntPtr conf, int update, IntPtr core_sieve_fcn, int max_relations);
99        public delegate void putTrivialFactorlistDelegate(IntPtr list, IntPtr obj);
100
101        public ref struct callback_struct
102        {
103        public:
104                prepareSievingDelegate^ prepareSieving;
105                putTrivialFactorlistDelegate^ putTrivialFactorlist;
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                //start the factorization process:
152                static void start(String^ number, String^ savefile)
153                {
154                        char* num = stringToCharA(number);     
155                        char* save = stringToCharA(savefile);
156                        factor(num, save);
157                }
158
159                //stop msieve:
160                static void stop(IntPtr obj)
161                {
162                        stop_msieve((msieve_obj*)obj.ToPointer());
163                }
164
165                //clone this conf (the clone can be used to run the sieving in a different thread):
166                static IntPtr cloneSieveConf(IntPtr conf)
167                {
168                        return IntPtr(copy_sieve_conf((sieve_conf_t*)conf.ToPointer()));
169                }
170
171                //free this conf (shouldn't be the conf file that belongs to the main thread):
172                static void freeSieveConf(IntPtr conf)
173                {
174                        sieve_conf_t* c = (sieve_conf_t*)conf.ToPointer();
175                        if (!c->slave)
176                                return;
177                        free(c->obj);
178                        free(c->next_poly_action);
179                        free(c->curr_b);
180                        free(c->poly_b_small[0]);
181                        free(c->poly_b_array);
182                        aligned_free(c->sieve_array);
183                        free(c->factor_base);
184                        free(c->packed_fb);
185                        for (uint32 i = 0; i < c->poly_block * c->num_sieve_blocks; i++)
186                                free(c->buckets[i].list);
187                        free(c->buckets);
188                        free(c->modsqrt_array);
189                        if (c->relationPackage != 0)
190                        {
191                                for (int j = 0; j < c->relationPackage->package_count; j++)                     
192                                        if (c->relationPackage->package_array[j].type == 0)
193                                                free(c->relationPackage->package_array->rel.fb_offsets);
194                                free(c->relationPackage->package_array);
195                                free(c->relationPackage);
196                        }
197                        free(c);
198                }
199
200                static void collectRelations(IntPtr conf, int target_relations, IntPtr core_sieve_fcn)
201                {
202                        collect_relations((sieve_conf_t*)conf.ToPointer(), target_relations, (qs_core_sieve_fcn)core_sieve_fcn.ToPointer());
203                }
204               
205                //get the relation package in the thread of "conf" (shoudn't be the main thread):
206                static IntPtr getRelationPackage(IntPtr conf)
207                {
208                        sieve_conf_t* c = (sieve_conf_t*)conf.ToPointer();
209                        if (!c->slave)
210                                return IntPtr::Zero;
211                        RelationPackage* relationPackage = c->relationPackage;
212                        c->relationPackage = 0;
213                        return IntPtr((void*)relationPackage);
214                }
215
216                //stores the relation package in the thread of "conf" (should be the main thread), and destroys the relation package:
217                static void saveRelationPackage(IntPtr conf, IntPtr relationPackage)
218                {
219                        sieve_conf_t* c = (sieve_conf_t*)conf.ToPointer();
220                        if (c->slave)
221                                return;                 
222                        RelationPackage* y = (RelationPackage*)relationPackage.ToPointer();
223
224                        for (int j = 0; j < y->package_count; j++)
225                        {
226                                if (y->package_array[j].type == 1)
227                                        savefile_write_line(&c->obj->savefile, y->package_array[j].polybuf);
228                                else
229                                {
230                                        relation* rel = &y->package_array[j].rel;
231                                        save_relation(c, rel->sieve_offset, rel->fb_offsets, rel->num_factors, rel->poly_index, rel->large_prime1, rel->large_prime2);
232                                        free(rel->fb_offsets);
233                                }
234                        }
235
236                        free(y->package_array);
237                        free(y);
238                }
239
240                static IntPtr getObjFromConf(IntPtr conf)
241                {
242                        sieve_conf_t* c = (sieve_conf_t*)conf.ToPointer();
243                        return IntPtr(c->obj);
244                }
245
246                static ArrayList^ getPrimeFactors(IntPtr factorList)
247                {
248                        char buf[929];
249                        ArrayList^ factors = gcnew ArrayList;
250                        factor_list_t * factor_list = (factor_list_t *)factorList.ToPointer();
251                        for (int c = 0; c < factor_list->num_factors; c++)
252                        {
253                                if (factor_list->final_factors[c]->type != MSIEVE_COMPOSITE)
254                                {
255                                        char* factor = mp_sprintf(&factor_list->final_factors[c]->factor, 10, buf);
256                                        factors->Add(gcnew String(factor));
257                                }
258                        }
259
260                        return factors;
261                }
262
263                static ArrayList^ getCompositeFactors(IntPtr factorList)
264                {
265                        char buf[929];
266                        ArrayList^ factors = gcnew ArrayList;
267                        factor_list_t * factor_list = (factor_list_t *)factorList.ToPointer();
268                        for (int c = 0; c < factor_list->num_factors; c++)
269                        {
270                                if (factor_list->final_factors[c]->type == MSIEVE_COMPOSITE)
271                                {
272                                        char* factor = mp_sprintf(&factor_list->final_factors[c]->factor, 10, buf);
273                                        factors->Add(gcnew String(factor));
274                                }
275                        }
276
277                        return factors;
278                }
279
280                //serialize the relation package, so that you can send it over the net:
281                static array<unsigned char>^ serializeRelationPackage(IntPtr relationPackage)
282                {
283                        RelationPackage* y = (RelationPackage*)relationPackage.ToPointer();
284
285                        //calculate needed size:
286                        int size = 0;
287                        for (int c = 0; c < y->package_count; c++)
288                        {
289                                size++; //type information
290                                if (y->package_array[c].type == 1)      //poly  (256 bytes)
291                                        size += 256;
292                                else                                                            //relation      ((5+num_factors)*4 bytes)
293                                        size += (5 + y->package_array[c].rel.num_factors)*4;
294                        }
295
296                        //serialize:                   
297                        array<unsigned char>^ out = gcnew array<unsigned char>(size + 4);
298                        copyIntToArray(out, 0, y->package_count);
299                        int pos = 4;
300
301                        for (int c = 0; c < y->package_count; c++)
302                        {
303                                out[pos++] = (char)(y->package_array[c].type);
304                                if (y->package_array[c].type == 1)      //poly  (256 bytes)
305                                {
306                                        for (int i = 0; i < 256; i++)
307                                                out[pos++] = y->package_array[c].polybuf[i];
308                                }
309                                else                                                            //relation      ((5+num_factors)*4 bytes)
310                                {
311                                        copyIntToArray(out, pos, y->package_array[c].rel.sieve_offset);
312                                        copyIntToArray(out, pos + 4, y->package_array[c].rel.num_factors);
313                                        copyIntToArray(out, pos + 8, y->package_array[c].rel.poly_index);
314                                        copyIntToArray(out, pos + 12, y->package_array[c].rel.large_prime1);
315                                        copyIntToArray(out, pos + 16, y->package_array[c].rel.large_prime2);
316                                        pos += 20;
317                                        for (int i = 0; i < y->package_array[c].rel.num_factors; i++)
318                                        {
319                                                copyIntToArray(out, pos, y->package_array[c].rel.fb_offsets[i]);
320                                                pos += 4;
321                                        }
322                                }
323                        }
324
325                        return out;
326                }
327
328                static IntPtr deserializeRelationPackage(array<unsigned char>^ relationPackage)
329                {
330                        RelationPackage* y = (RelationPackage*)malloc(sizeof(relationPackage));
331                        y->package_count = getIntFromArray(relationPackage, 0);
332                        y->package_array = (package_element*)malloc(sizeof(package_element)*y->package_count);
333                        int pos = 4;
334                       
335                        for (int c = 0; c < y->package_count; c++)
336                        {
337                                y->package_array[c].type = relationPackage[pos++];
338                                if (y->package_array[c].type == 1)      //poly  (256 bytes)
339                                {
340                                        for (int i = 0; i < 256; i++)
341                                                y->package_array[c].polybuf[i] = relationPackage[pos++];
342                                }
343                                else                                                            //relation      ((5+num_factors)*4 bytes)
344                                {
345                                        y->package_array[c].rel.sieve_offset = getIntFromArray(relationPackage, pos);
346                                        y->package_array[c].rel.num_factors = getIntFromArray(relationPackage, pos + 4);
347                                        y->package_array[c].rel.poly_index = getIntFromArray(relationPackage, pos + 8);
348                                        y->package_array[c].rel.large_prime1 = getIntFromArray(relationPackage, pos + 12);
349                                        y->package_array[c].rel.large_prime2 = getIntFromArray(relationPackage, pos + 16);
350                                        pos += 20;
351                                        y->package_array[c].rel.fb_offsets = (uint32*)malloc(sizeof(uint32) * y->package_array[c].rel.num_factors);
352                                        for (int i = 0; i < y->package_array[c].rel.num_factors; i++)
353                                        {
354                                                y->package_array[c].rel.fb_offsets[i] = getIntFromArray(relationPackage, pos);
355                                                pos += 4;
356                                        }
357                                }
358                        }
359                       
360                        return IntPtr((void*)y);
361                }
362
363                static int getAmountOfRelationsInRelationPackage(IntPtr relationPackage)
364                {
365                        RelationPackage* y = (RelationPackage*)relationPackage.ToPointer();
366                        return y->num_relations;
367                }
368
369                static int getNumRelations(IntPtr conf)
370                {
371                        sieve_conf_t* c = (sieve_conf_t*)conf.ToPointer();
372                        return c->num_relations + 
373                                c->num_cycles +
374                                c->components - c->vertices;
375                }
376
377                static IntPtr msieve_run_core(IntPtr obj, String^ n)
378                {
379                        try
380                        {
381                                mp_t N;
382                                msieve_obj* o = (msieve_obj*)obj.ToPointer();
383                                evaluate_expression(stringToCharA(n), &N);
384                                factor_list_t* factor_list = new factor_list_t;
385                                factor_list_init(factor_list);
386                                factor_list_add(o, factor_list, &N);
387                                ::msieve_run_core(o, &N, factor_list);
388                                return IntPtr(factor_list);
389                        }
390                        catch (...)
391                        {
392                                return IntPtr::Zero;
393                        }
394                }
395        };
396
397}
398
399extern "C" void prepare_sieving(void* conf, int update, void* core_sieve_fcn, int max_relations)
400{
401        Msieve::msieve::callbacks->prepareSieving(IntPtr(conf), update, IntPtr(core_sieve_fcn), max_relations);
402}
403
404extern "C" void throwException(char* message)
405{
406        throw gcnew Exception(gcnew String(message));
407}
408
409extern "C" void put_trivial_factorlist(factor_list_t * factor_list, msieve_obj *obj)
410{
411        Msieve::msieve::callbacks->putTrivialFactorlist(IntPtr(factor_list), IntPtr(obj));
412}
Note: See TracBrowser for help on using the repository browser.