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

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

lots of quadratic sieve plugin changes affecting the time approximation and peer2peer representation.

File size: 12.1 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 getTrivialFactorlistDelegate(IntPtr list, IntPtr obj);
100
101        public ref struct callback_struct
102        {
103        public:
104                prepareSievingDelegate^ prepareSieving;
105                getTrivialFactorlistDelegate^ getTrivialFactorlist;
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->yield != 0)
190                        {
191                                for (int j = 0; j < c->yield->yield_count; j++)                 
192                                        if (c->yield->yield_array[j].type == 0)
193                                                free(c->yield->yield_array->rel.fb_offsets);
194                                free(c->yield->yield_array);
195                                free(c->yield);
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 yield in the thread of "conf" (shoudn't be the main thread):
206                static IntPtr getYield(IntPtr conf)
207                {
208                        sieve_conf_t* c = (sieve_conf_t*)conf.ToPointer();
209                        if (!c->slave)
210                                return IntPtr::Zero;
211                        relationYield* yield = c->yield;
212                        c->yield = 0;
213                        return IntPtr((void*)yield);
214                }
215
216                //stores the yield in the thread of "conf" (should be the main thread), and destroys the yield:
217                static void saveYield(IntPtr conf, IntPtr yield)
218                {
219                        sieve_conf_t* c = (sieve_conf_t*)conf.ToPointer();
220                        if (c->slave)
221                                return;                 
222                        relationYield* y = (relationYield*)yield.ToPointer();
223
224                        for (int j = 0; j < y->yield_count; j++)
225                        {
226                                if (y->yield_array[j].type == 1)
227                                        savefile_write_line(&c->obj->savefile, y->yield_array[j].polybuf);
228                                else
229                                {
230                                        relation* rel = &y->yield_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->yield_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 yield, so that you can send it over the net:
281                static array<unsigned char>^ serializeYield(IntPtr yield)
282                {
283                        relationYield* y = (relationYield*)yield.ToPointer();
284
285                        //calculate needed size:
286                        int size = 0;
287                        for (int c = 0; c < y->yield_count; c++)
288                        {
289                                size++; //type information
290                                if (y->yield_array[c].type == 1)        //poly  (256 bytes)
291                                        size += 256;
292                                else                                                            //relation      ((5+num_factors)*4 bytes)
293                                        size += (5 + y->yield_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->yield_count);
299                        int pos = 4;
300
301                        for (int c = 0; c < y->yield_count; c++)
302                        {
303                                out[pos++] = (char)(y->yield_array[c].type);
304                                if (y->yield_array[c].type == 1)        //poly  (256 bytes)
305                                {
306                                        for (int i = 0; i < 256; i++)
307                                                out[pos++] = y->yield_array[c].polybuf[i];
308                                }
309                                else                                                            //relation      ((5+num_factors)*4 bytes)
310                                {
311                                        copyIntToArray(out, pos, y->yield_array[c].rel.sieve_offset);
312                                        copyIntToArray(out, pos + 4, y->yield_array[c].rel.num_factors);
313                                        copyIntToArray(out, pos + 8, y->yield_array[c].rel.poly_index);
314                                        copyIntToArray(out, pos + 12, y->yield_array[c].rel.large_prime1);
315                                        copyIntToArray(out, pos + 16, y->yield_array[c].rel.large_prime2);
316                                        pos += 20;
317                                        for (int i = 0; i < y->yield_array[c].rel.num_factors; i++)
318                                        {
319                                                copyIntToArray(out, pos, y->yield_array[c].rel.fb_offsets[i]);
320                                                pos += 4;
321                                        }
322                                }
323                        }
324
325                        return out;
326                }
327
328                static IntPtr deserializeYield(array<unsigned char>^ yield)
329                {
330                        relationYield* y = (relationYield*)malloc(sizeof(relationYield));
331                        y->yield_count = getIntFromArray(yield, 0);
332                        y->yield_array = (yield_element*)malloc(sizeof(yield_element)*y->yield_count);
333                        int pos = 4;
334                       
335                        for (int c = 0; c < y->yield_count; c++)
336                        {
337                                y->yield_array[c].type = yield[pos++];
338                                if (y->yield_array[c].type == 1)        //poly  (256 bytes)
339                                {
340                                        for (int i = 0; i < 256; i++)
341                                                y->yield_array[c].polybuf[i] = yield[pos++];
342                                }
343                                else                                                            //relation      ((5+num_factors)*4 bytes)
344                                {
345                                        y->yield_array[c].rel.sieve_offset = getIntFromArray(yield, pos);
346                                        y->yield_array[c].rel.num_factors = getIntFromArray(yield, pos + 4);
347                                        y->yield_array[c].rel.poly_index = getIntFromArray(yield, pos + 8);
348                                        y->yield_array[c].rel.large_prime1 = getIntFromArray(yield, pos + 12);
349                                        y->yield_array[c].rel.large_prime2 = getIntFromArray(yield, pos + 16);
350                                        pos += 20;
351                                        y->yield_array[c].rel.fb_offsets = (uint32*)malloc(sizeof(uint32) * y->yield_array[c].rel.num_factors);
352                                        for (int i = 0; i < y->yield_array[c].rel.num_factors; i++)
353                                        {
354                                                y->yield_array[c].rel.fb_offsets[i] = getIntFromArray(yield, pos);
355                                                pos += 4;
356                                        }
357                                }
358                        }
359                       
360                        return IntPtr((void*)y);
361                }
362
363                static int getAmountOfRelationsInYield(IntPtr yield)
364                {
365                        relationYield* y = (relationYield*)yield.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                        mp_t N;
380                        msieve_obj* o = (msieve_obj*)obj.ToPointer();
381                        evaluate_expression(stringToCharA(n), &N);
382                        factor_list_t* factor_list = new factor_list_t;
383                        factor_list_init(factor_list);
384                        factor_list_add(o, factor_list, &N);
385                        ::msieve_run_core(o, &N, factor_list);
386                        return IntPtr(factor_list);
387                }
388        };
389
390}
391
392extern "C" void prepare_sieving(void* conf, int update, void* core_sieve_fcn, int max_relations)
393{
394        Msieve::msieve::callbacks->prepareSieving(IntPtr(conf), update, IntPtr(core_sieve_fcn), max_relations);
395}
396
397extern "C" void throwException(char* message)
398{
399        throw gcnew Exception(gcnew String(message));
400}
401
402extern "C" void get_trivial_factorlist(factor_list_t * factor_list, msieve_obj *obj)
403{
404        Msieve::msieve::callbacks->getTrivialFactorlist(IntPtr(factor_list), IntPtr(obj));
405}
Note: See TracBrowser for help on using the repository browser.