tree checksum vpatch file split hunks

all signers: diana_coman

antecedents: smg_comms_raw_types smg_comms_packing_serpent

press order:

smg_comms_genesisdiana_coman
smg_comms_raw_typesdiana_coman
smg_comms_packing_serpentdiana_coman
smg_comms_c_wrappersdiana_coman

patch:

-
+ FB1426A00C38F5C9D94C79071CFD6E8D39343EFEC1FEA43B771F8C96CA53E075339A28A2C2D7AB1A2D42B1AE128E0090F4DC580477F211680742CFD027C958FE
smg_comms/c_wrappers/README
(0 . 0)(1 . 4)
5 --Set of wrapper methods for C code to be easily imported and used from Ada.
6 --Meant to be the ONLY C lib that Ada code directly imports, an interface.
7 --Methods use arrays of octets (char*) and do all and any of the C-mess ops.
8 --S.MG, 2018
-
+ F829705D787E0DE60B165CCD6BE182B11C11BC80E43B3B536A2062A7247B102A9EC8906E3D48C0D7EC71D6757678FD573728D12EF3FD3AE2DA9924B7593BC581
smg_comms/c_wrappers/bin/README
(0 . 0)(1 . 1)
13 S.MG, 2018
-
+ 0BD7662525269421638C3CF0B5013C4E89B3181BE9D081FD6CE4CAC5AFD731AE831EEAE39F854BCBD5D31A134C47D1083F3C92A44F6DDF64D6160DE04E4D561C
smg_comms/c_wrappers/c_wrappers.c
(0 . 0)(1 . 222)
18 //Wrapper methods for C implementations of RSA and MPI.
19 //To be used / called from Ada so that the C part remains well separated.
20 //S.MG, 2018
21
22 #include "c_wrappers.h"
23 #include "mpi.h"
24 #include "smg_rsa.h"
25 #include <assert.h>
26 #include <string.h> //for memmove...
27
28 //Wrapper for comparing the given arrays of octets as MPIs
29 //Steps:
30 //1. allocate space for 2 MPIs u and v
31 //2. set buffer of u to content of a, buffer of v to content of b
32 //3. call mpi_cmp(u,v) and store result
33 //4. de-allocate u and v
34 //5. return result
35 int mpi_cmp_octets(char *a, unsigned int len_a, char *b, unsigned int len_b) {
36 //variable to hold the final result of comparing a to b as MPIs
37 int result;
38
39 //calculate how much space is needed for each MPI
40 unsigned int nlimbs_a = mpi_nlimb_hint_from_nbytes( len_a );
41 unsigned int nlimbs_b = mpi_nlimb_hint_from_nbytes( len_b );
42
43 //allocate space for the 2 MPIs
44 MPI u = mpi_alloc(nlimbs_a);
45 MPI v = mpi_alloc(nlimbs_b);
46
47 //set the given octets as the values of the 2 MPIs
48 //the sign is set to 0 (last parameter).
49 mpi_set_buffer(u, a, len_a, 0);
50 mpi_set_buffer(v, b, len_b, 0);
51
52 //compare the MPIs as numbers and store the result
53 result = mpi_cmp(u, v);
54
55 //tidy up: free the memory allocated for the 2 MPIs
56 mpi_free(u);
57 mpi_free(v);
58
59 //return the result comparing a to b as MPIs
60 return result;
61 }
62
63 //Encryption of given input with a public RSA key: n and e given as octets too.
64 //Steps:
65 //1. create (allocate memory for) MPIs for out and input;
66 //2. set the input as buffer for the corresponding MPI;
67 //3. create and set the public key structure with n,e as contents;
68 //4. call rsa/public_rsa and retrieve the result storing it in out;
69 //5. free allocated memory for all the MPIs.
70 //6. return the actual length of the encrypted result
71 int public_rsa_octets( char *out , unsigned int len_out,
72 char *input, unsigned int len_input,
73 char *n , unsigned int len_n,
74 char *e , unsigned int len_e) {
75
76 // precondition: output has enough memory allocated
77 assert( len_out >= KEY_LENGTH_OCTETS );
78
79 //allocate memory for input and output MPIs
80 unsigned int nlimbs_in = mpi_nlimb_hint_from_nbytes( len_input );
81 unsigned int nlimbs_out = mpi_nlimb_hint_from_nbytes( len_out );
82 MPI in_mpi = mpi_alloc(nlimbs_in);
83 MPI out_mpi = mpi_alloc(nlimbs_out);
84
85 //set input as buffer for in_mpi
86 mpi_set_buffer(in_mpi, input, len_input, 0);
87
88 //create public key structure and set its contents to given n, e
89 RSA_public_key pk;
90 unsigned int nlimbs_n = mpi_nlimb_hint_from_nbytes( len_n );
91 unsigned int nlimbs_e = mpi_nlimb_hint_from_nbytes( len_e );
92 pk.n = mpi_alloc(nlimbs_n);
93 pk.e = mpi_alloc(nlimbs_e);
94 mpi_set_buffer(pk.n, n, len_n, 0);
95 mpi_set_buffer(pk.e, e, len_e, 0);
96
97 //call rsa public_key encryption and retrieve the result, storing it in out
98 public_rsa( out_mpi, in_mpi, &pk);
99 int len = len_out;
100 mpi_to_octets( out, &len, out_mpi );
101
102 //tidy up: free allocated memory for ALL MPIs.
103 mpi_free(in_mpi);
104 mpi_free(out_mpi);
105 mpi_free(pk.n);
106 mpi_free(pk.e);
107
108 //return actual length
109 return len;
110 }
111
112 //Decryption of given input with the private key given through its components.
113 //Steps:
114 //1. create (allocate memory for) MPIs for out and input;
115 //2. set the input as buffer for the corresponding MPI;
116 //3. create and set the private key structure with n,e,d,p,q,u as contents;
117 //4. call rsa/private_rsa and retrieve the result storing it in out;
118 //5. free allocated memory for all the MPIs.
119 //6. return the actual length of the result
120 int private_rsa_octets( char *out, unsigned int len_out,
121 char *input, unsigned int len_input,
122 char *n , unsigned int len_n,
123 char *e , unsigned int len_e,
124 char *d , unsigned int len_d,
125 char *p , unsigned int len_p,
126 char *q , unsigned int len_q,
127 char *u , unsigned int len_u) {
128 // precondition: output has enough memory allocated
129 assert( len_out >= KEY_LENGTH_OCTETS );
130
131 //allocate memory for input and output MPIs
132 unsigned int nlimbs_in = mpi_nlimb_hint_from_nbytes( len_input );
133 unsigned int nlimbs_out = mpi_nlimb_hint_from_nbytes( len_out );
134 MPI in_mpi = mpi_alloc(nlimbs_in);
135 MPI out_mpi = mpi_alloc(nlimbs_out);
136
137 //set input as buffer for in_mpi
138 mpi_set_buffer(in_mpi, input, len_input, 0);
139
140 //create private key structure and set its contents to given n,e,d,p,q,u
141 RSA_secret_key sk;
142 unsigned int nlimbs_n = mpi_nlimb_hint_from_nbytes( len_n );
143 unsigned int nlimbs_e = mpi_nlimb_hint_from_nbytes( len_e );
144 unsigned int nlimbs_d = mpi_nlimb_hint_from_nbytes( len_d );
145 unsigned int nlimbs_p = mpi_nlimb_hint_from_nbytes( len_p );
146 unsigned int nlimbs_q = mpi_nlimb_hint_from_nbytes( len_q );
147 unsigned int nlimbs_u = mpi_nlimb_hint_from_nbytes( len_u );
148 sk.n = mpi_alloc(nlimbs_n);
149 sk.e = mpi_alloc(nlimbs_e);
150 sk.d = mpi_alloc(nlimbs_d);
151 sk.p = mpi_alloc(nlimbs_p);
152 sk.q = mpi_alloc(nlimbs_q);
153 sk.u = mpi_alloc(nlimbs_u);
154 mpi_set_buffer(sk.n, n, len_n, 0);
155 mpi_set_buffer(sk.e, e, len_e, 0);
156 mpi_set_buffer(sk.d, d, len_d, 0);
157 mpi_set_buffer(sk.p, p, len_p, 0);
158 mpi_set_buffer(sk.q, q, len_q, 0);
159 mpi_set_buffer(sk.u, u, len_u, 0);
160
161 //call rsa secret_key encryption and retrieve the result, storing it in out
162 secret_rsa( out_mpi, in_mpi, &sk );
163 int len = len_out;
164 mpi_to_octets( out, &len, out_mpi );
165
166 //tidy up: free memory previously allocated for MPIs
167 mpi_free(in_mpi);
168 mpi_free(out_mpi);
169 mpi_free(sk.n);
170 mpi_free(sk.e);
171 mpi_free(sk.d);
172 mpi_free(sk.p);
173 mpi_free(sk.q);
174 mpi_free(sk.u);
175
176 //return number of octets copied in out - real length of result
177 return len;
178 }
179
180 //Generates a new RSA key and stores its components at the specified locations.
181 void gen_rsa_octets( char *n, unsigned int *len_n,
182 char *e, unsigned int *len_e,
183 char *d, unsigned int *len_d,
184 char *p, unsigned int *len_p,
185 char *q, unsigned int *len_q,
186 char *u, unsigned int *len_u) {
187 // precondition: all pointers have enough memory allocated
188 assert( *len_n >= KEY_LENGTH_OCTETS );
189 assert( *len_e >= KEY_LENGTH_OCTETS );
190 assert( *len_d >= KEY_LENGTH_OCTETS );
191 assert( *len_p >= KEY_LENGTH_OCTETS / 2);
192 assert( *len_q >= KEY_LENGTH_OCTETS / 2);
193 assert( *len_u >= KEY_LENGTH_OCTETS / 2);
194
195 //the secret key structure that will hold generated key components
196 RSA_secret_key sk;
197 int nlimbs = mpi_nlimb_hint_from_nbytes( KEY_LENGTH_OCTETS );
198 int nlimbs_pq = mpi_nlimb_hint_from_nbytes( KEY_LENGTH_OCTETS / 2 );
199
200 sk.n = mpi_alloc(nlimbs);
201 sk.e = mpi_alloc(nlimbs);
202 sk.d = mpi_alloc(nlimbs);
203 sk.p = mpi_alloc(nlimbs_pq);
204 sk.q = mpi_alloc(nlimbs_pq);
205 sk.u = mpi_alloc(nlimbs_pq);
206
207 //generate the rsa key pair - this may take a while!
208 gen_keypair(&sk);
209
210 //copy components to their place
211 mpi_to_octets( n, len_n, sk.n );
212 mpi_to_octets( e, len_e, sk.e );
213 mpi_to_octets( d, len_d, sk.d );
214 mpi_to_octets( p, len_p, sk.p );
215 mpi_to_octets( q, len_q, sk.q );
216 mpi_to_octets( u, len_u, sk.u );
217
218 //tidy up: free ALL MPIs
219 mpi_free(sk.n);
220 mpi_free(sk.e);
221 mpi_free(sk.d);
222 mpi_free(sk.p);
223 mpi_free(sk.q);
224 mpi_free(sk.u);
225 }
226
227 void mpi_to_octets( char *out, unsigned int *len_out, MPI m) {
228 //copy the components as raw octets to the given pointers
229 int len = 0;
230 int sign;
231 unsigned char * buffer = mpi_get_buffer( m, &len, &sign );
232
233 //check and don't copy MORE than there is allocated space in out!
234 assert( len <= *len_out );
235 memmove( out, buffer, len );
236 *len_out = len; //save actual length of the component
237
238 xfree( buffer ); //free the buffer that was allocated by mpi_get_buffer
239 }
-
+ CE32037651DC139757805B3F6B25B73A47015EA87B9D17995F59CF8C0FA856E2D74D552A043DA7D931F579656A9CAC3E4366A0F9FEDA6C2F3B9F61E0166C3A24
smg_comms/c_wrappers/c_wrappers.gpr
(0 . 0)(1 . 16)
244 -- S.MG, 2018
245
246 with "../mpi/mpi.gpr";
247 with "../rsa/rsa.gpr";
248
249 project C_Wrappers is
250 for Languages use ("C");
251 for Library_Name use "C_Wrappers";
252 for Library_Kind use "static";
253
254 for Source_Dirs use (".");
255 for Object_Dir use "obj";
256 for Library_Dir use "bin";
257
258 end C_Wrappers;
259
-
+ C24569926E5388672B1AF9E79B01B55902F2176DE3F2887C978327871820CF1EE19BC9B0B52BA614A90FF197FAC4A91C0975133EC55B38F362BE48E3DEACE1B3
smg_comms/c_wrappers/c_wrappers.h
(0 . 0)(1 . 105)
264 //Wrapper methods for C implementations of RSA and MPI.
265 //To be used / called from Ada so that the C part remains well separated and
266 // can therefore be swapped easily at a later stage for something sane.
267 //S.MG, 2018
268
269 #include "mpi.h"
270
271 //Comparison of 2 arrays of octets interpreted as MPIs.
272 //This method creates 2 MPIs out of the given arrays of octes and then
273 // calls the mpi_cmp method from mpi/mpi-cmp.c, returning its result.
274 // ************************************************************************
275 // ***NB: Make SURE that a and b have indeed allocated at least len_a and
276 // ***** len_b octets respectively! NO CHECKS PERFORMED BY THIS METHOD!
277 // ************************************************************************
278 //@param a An array of octets representing the first MPI.
279 //@param len_a The length of the first array (number of octets).
280 //@param b An array of octets representing the second MPI.
281 //@param len_b The length of the second array (number of octets).
282 //@return 0 when a=b, -1 when a<b, 1 when a>b
283 int mpi_cmp_octets(char *a, unsigned int len_a, char *b, unsigned int len_b);
284
285 //Encryption of given octets with public RSA key: n and e given as octets too.
286 // ************************************************************************
287 // ***Length of output is KEY_LENGTH_OCTETS.
288 // ***NB: Make SURE that out, input, n and e have enough space allocated!!
289 // ***NB: NO MEMORY ALLOCATED for its parameters by this method and
290 // ***** NO CHECKS PERFORMED BY THIS METHOD!
291 // ************************************************************************
292 //@param out Pointer to ALREADY ALLOCATED space for the encrypted data.
293 //@param len_out Length of the allocated space for out (in octets).
294 //@param input Pointer to the data to be encrypted.
295 //@param len_input Length of the allocated space for input (in octets).
296 //@param n Pointer to the public RSA modulus to use for encryption.
297 //@param len_n Length of n (in octets).
298 //@param e Pointer to the public RSA exponent to use for encryption.
299 //@param len_e Length of e (in octets).
300 //@return The actual length of the output i.e. number of chars written to out.
301 int public_rsa_octets( char *out , unsigned int len_out,
302 char *input, unsigned int len_input,
303 char *n , unsigned int len_n,
304 char *e , unsigned int len_e);
305
306
307 //Encryption of given octets with *private* RSA key given as octets.
308 // ************************************************************************
309 // ***Length of output is KEY_LENGTH_OCTETS.
310 // ***NB: Make SURE that ALL pointers have enough space allocated!!
311 // ***NB: NO MEMORY ALLOCATED for its parameters by this method and
312 // ***** NO CHECKS PERFORMED BY THIS METHOD!
313 // ************************************************************************
314 //@param out Pointer to ALREADY ALLOCATED space for the encrypted data.
315 //@param len_out Length of the allocated space for out (in octets).
316 //@param input Pointer to the data to be encrypted.
317 //@param len_input Length of the allocated space for input (in octets).
318 //@param n Pointer to the public RSA modulus of the given key.
319 //@param len_n Length of n (in octets).
320 //@param e Pointer to the public RSA exponent of the given key.
321 //@param len_e Length of e (in octets).
322 //@param d Pointer to the private RSA exponent of the given key.
323 //@param len_d Length of d (in octets).
324 //@param p Pointer to the prime p of the given key.
325 //@param len_p Length of p (in octets).
326 //@param q Pointer to the prime q of the given key.
327 //@param len_q Length of q (in octets).
328 //@param u Pointer to the inverse of p mod q for the given key.
329 //@param len_u Length of u (in octets).
330 //@return The actual length of the output i.e. number of chars written to out.
331 int private_rsa_octets( char *out, unsigned int len_out,
332 char *input, unsigned int len_input,
333 char *n , unsigned int len_n,
334 char *e , unsigned int len_e,
335 char *d , unsigned int len_d,
336 char *p , unsigned int len_p,
337 char *q , unsigned int len_q,
338 char *u , unsigned int len_u);
339
340 //Generates a new RSA key and stores its components at the specified locations.
341 //@param n Pointer to the public RSA modulus of the given key.
342 //@param len_n Length of n (in octets).
343 //@param e Pointer to the public RSA exponent of the given key.
344 //@param len_e Length of e (in octets).
345 //@param d Pointer to the private RSA exponent of the given key.
346 //@param len_d Length of d (in octets).
347 //@param p Pointer to the prime p of the given key.
348 //@param len_p Length of p (in octets).
349 //@param q Pointer to the prime q of the given key.
350 //@param len_q Length of q (in octets).
351 //@param u Pointer to the inverse of p mod q for the given key.
352 //@param len_u Length of u (in octets).
353 void gen_rsa_octets( char *n, unsigned int *len_n,
354 char *e, unsigned int *len_e,
355 char *d, unsigned int *len_d,
356 char *p, unsigned int *len_p,
357 char *q, unsigned int *len_q,
358 char *u, unsigned int *len_u);
359
360 //Copies the buffer of m to the location to which out points.
361 //*****************************************************************
362 //*** This method does NOT allocate memory for out!
363 //*** NB: caller should allocate enough memory!
364 //*****************************************************************
365 //@param out pointer to allocated memory where to copy the MPI's octets
366 //@param len_out size of out; will be replaced by actual number of octets copied
367 //@param m The MPI whose octets are to be retrieved
368 void mpi_to_octets( char *out, unsigned int *len_out, MPI m);
-
+ F829705D787E0DE60B165CCD6BE182B11C11BC80E43B3B536A2062A7247B102A9EC8906E3D48C0D7EC71D6757678FD573728D12EF3FD3AE2DA9924B7593BC581
smg_comms/c_wrappers/obj/README
(0 . 0)(1 . 1)
373 S.MG, 2018
-
+ 579BD4807F3DE9E8A399E942E2401053B5D89A049C257491011456E2ED35D746E190FD642493FD76E8D803D2529EB9F39CAD7BDF0E88AE5AB2CD0638C1A7EC13
smg_comms/c_wrappers/tests/c_wrappers_tests.gpr
(0 . 0)(1 . 14)
378 --Tests for the C wrappers on mpi and rsa methods.
379 --S.MG, 2018
380
381 with "../c_wrappers.gpr";
382
383 project C_Wrappers_Tests is
384 for Languages use("C");
385 for Source_Dirs use (".");
386 for Object_Dir use "obj";
387 for Exec_Dir use ".";
388
389 for Main use ("tests.c");
390 end C_Wrappers_Tests;
391
-
+ F829705D787E0DE60B165CCD6BE182B11C11BC80E43B3B536A2062A7247B102A9EC8906E3D48C0D7EC71D6757678FD573728D12EF3FD3AE2DA9924B7593BC581
smg_comms/c_wrappers/tests/obj/README
(0 . 0)(1 . 1)
396 S.MG, 2018
-
+ C40E451A3093C41C8C5762C284A1E05716C2E429EE7E56C1E93BB2ADBFF0D83FDBA237DC01510891A362EECBF9C908501468A3747C4A735FF90D407504ABE1F8
smg_comms/c_wrappers/tests/tests.c
(0 . 0)(1 . 352)
401 //Basic tests for the C wrappers for rsa and mpi.
402 //S.MG, 2018
403
404 #include "mpi.h"
405 #include "smg_rsa.h"
406
407 #include "c_wrappers.h"
408
409 void test_mpi_cmp() {
410 int result;
411 int i;
412 char a[KEY_LENGTH_OCTETS];
413 char b[KEY_LENGTH_OCTETS];
414
415 //initialize mpis
416 for (i=0;i<KEY_LENGTH_OCTETS;i++) {
417 a[i] = i % 256;
418 b[i] = a[i];
419 }
420
421 //cmp same value mpi
422 result = mpi_cmp_octets(a, KEY_LENGTH_OCTETS, b, KEY_LENGTH_OCTETS);
423 if (result == 0)
424 printf("PASS: mpi_cmp_octets on a == b.\n");
425 else {
426 printf("FAIL: mpi_cmp_octets on a == b ");
427 printf("returned %d instead of 0.\n", result);
428 }
429
430 //cmp a < b
431 b[489] = 234;
432 result = mpi_cmp_octets(a, KEY_LENGTH_OCTETS, b, KEY_LENGTH_OCTETS);
433 if (result == -1)
434 printf("PASS: mpi_cmp_octets on a < b.\n");
435 else {
436 printf("FAIL: mpi_cmp_octets on a < b ");
437 printf("returned %d instead of -1.\n", result);
438 }
439
440 //cmp a > b
441 a[240] = 241;
442 result = mpi_cmp_octets(a, KEY_LENGTH_OCTETS, b, KEY_LENGTH_OCTETS);
443 if (result == 1)
444 printf("PASS: mpi_cmp_octets on a > b.\n");
445 else {
446 printf("FAIL: mpi_cmp_octets on a > b ");
447 printf("returned %d instead of 1.\n", result);
448 }
449 }
450
451 void test_gen_rsa_octets() {
452 RSA_secret_key sk;
453 RSA_public_key pk;
454 int nlimbs = mpi_nlimb_hint_from_nbytes( KEY_LENGTH_OCTETS );
455 int nlimbs_pq = mpi_nlimb_hint_from_nbytes( KEY_LENGTH_OCTETS / 2 );
456
457 //allocate memory
458 sk.n = mpi_alloc(nlimbs);
459 sk.e = mpi_alloc(nlimbs);
460 sk.d = mpi_alloc(nlimbs);
461 sk.p = mpi_alloc(nlimbs_pq);
462 sk.q = mpi_alloc(nlimbs_pq);
463 sk.u = mpi_alloc(nlimbs_pq);
464
465 pk.n = mpi_alloc(nlimbs);
466 pk.e = mpi_alloc(nlimbs);
467
468 //generate key pair
469 int len_n = KEY_LENGTH_OCTETS;
470 int len_e = len_n;
471 int len_d = len_n;
472 int len_p = KEY_LENGTH_OCTETS / 2;
473 int len_q = len_p;
474 int len_u = len_p;
475 char n[KEY_LENGTH_OCTETS];
476 char e[KEY_LENGTH_OCTETS];
477 char d[KEY_LENGTH_OCTETS];
478 char p[KEY_LENGTH_OCTETS / 2];
479 char q[KEY_LENGTH_OCTETS / 2];
480 char u[KEY_LENGTH_OCTETS / 2];
481 gen_rsa_octets(n, &len_n,
482 e, &len_e,
483 d, &len_d,
484 p, &len_p,
485 q, &len_q,
486 u, &len_u);
487
488 //check encryption/decr works
489 mpi_set_buffer(sk.n, n, len_n, 0);
490 mpi_set_buffer(sk.e, e, len_e, 0);
491 mpi_set_buffer(sk.d, d, len_d, 0);
492 mpi_set_buffer(sk.p, p, len_p, 0);
493 mpi_set_buffer(sk.q, q, len_q, 0);
494 mpi_set_buffer(sk.u, u, len_u, 0);
495
496 mpi_set_buffer(pk.n, n, len_n, 0);
497 mpi_set_buffer(pk.e, e, len_e, 0);
498
499 MPI encr = mpi_alloc(0);
500 MPI plain = mpi_alloc(0);
501 MPI out = mpi_alloc(0);
502 mpi_fromstr(plain, "0x\
503 5B6A8A0ACF4F4DB3F82EAC2D20255E4DF3E4B7C799603210766F26EF87C8980E737579\
504 EC08E6505A51D19654C26D806BAF1B62F9C032E0B13D02AF99F7313BFCFD68DA46836E\
505 CA529D7360948550F982C6476C054A97FD01635AB44BFBDBE2A90BE06F7984AC8534C3\
506 28097EF92F6E78CAE0CB97");
507 public_rsa(encr, plain, &pk);
508 secret_rsa(out, encr, &sk);
509
510 if (mpi_cmp(out, plain) != 0)
511 printf("FAIL: test_gen_rsa encr/decr failed.\n");
512 else
513 printf("PASS: test_gen_rsa encr/decr passed.\n");
514
515 //tidy up
516 mpi_free(sk.n);
517 mpi_free(sk.e);
518 mpi_free(sk.d);
519 mpi_free(sk.p);
520 mpi_free(sk.q);
521 mpi_free(sk.u);
522
523 mpi_free(pk.n);
524 mpi_free(pk.e);
525
526 mpi_free(plain);
527 mpi_free(encr);
528 mpi_free(out);
529 }
530
531 void test_rsa_octets() {
532 int noctets = 512;
533 RSA_public_key pk;
534 pk.n = mpi_alloc(0);
535 pk.e = mpi_alloc(0);
536
537 RSA_secret_key sk;
538 sk.n = mpi_alloc(0);
539 sk.e = mpi_alloc(0);
540 sk.d = mpi_alloc(0);
541 sk.p = mpi_alloc(0);
542 sk.q = mpi_alloc(0);
543 sk.u = mpi_alloc(0);
544
545 //key pair previously generated with EuCrypt
546 mpi_fromstr(sk.n, "0x\
547 CD2C025323BEA46FFF2FA8D7A9D39817EA713421F4AE03FA8120641193892A70BFECF5\
548 83101635A432110D3DDE6339E3CC7ECC0AD91C026FCACE832DD3888A6FCA7BCE56C390\
549 5A5AC8C7BC921DA675E4B62489B254EB34659D547D71165BC998983A81937BD251AEE1\
550 2D985EC387D5376F5DCC5EF7EC530FBD6FD2AA7285EE1AF3335EA73163F0954F30402E\
551 D7B374EE84A97B1849B0674B0DA0A2050BD79B71ABB1559F3A9CFDB8557DED7BC90CF2\
552 09E8A847E9C226140845B7D03842162E7DA5DD16326CB1F71A248D841FE9076A09911F\
553 2F4F5E3EA44EA8DE40332BF00406990BCCF61C322A03C456EF3A98B341E0BDBC1088CE\
554 683E78510E76B72C2BCC1EE9AEDD80FFF18ABFC5923B2F36B581C25114AB2DF9F6C2B1\
555 9481703FD19E313DCD7ACE15FA11B27D25BCE5388C180A7E21167FB87750599E1ED7C7\
556 50F4A844E1DC2270C62D19671CF8F4C25B81E366B09FC850AE642136D204A9160AEECE\
557 575B57378AA439E9DD46DC990288CD54BAA35EEE1C02456CD39458A6F1CBF012DCEDF4\
558 27CCF3F3F53645658FC49C9C9D7F2856DB571D92B967AB5845514E0054DDB49099F5DD\
559 04A6F6F5C5CE642276834B932881AEB648D1F25E9223971F56E249EF40CF7D80F22621\
560 CDD0260E9E7D23746960ADB52CF2987584FB1DE95A69A39E5CB12B76E0F5C1A0529C0C\
561 065D2E35720810F7C7983180B9A9EA0E00C11B79DC3D");
562
563 mpi_fromstr(sk.e, "0x\
564 DD4856B4EE3D099A8604AE392D8EFEC094CDF01546A28BE87CB484F999E8E75CDFCD01\
565 D04D455A6A9254C60BD28C0B03611FC3E751CC27EF768C0B401C4FD2B27C092834A6F2\
566 49A145C4EDC47A3B3D363EC352462C945334D160AF9AA72202862912493AC6190AA3A6\
567 149D4D8B9996BA7927D3D0D2AD00D30FD630CF464E6CAF9CF49355B9A70E05DB7AE915\
568 F9F602772F8D11E5FCDFC7709210F248052615967090CC1F43D410C83724AA5912B2F0\
569 52E6B39449A89A97C79C92DC8CB8DEEFCF248C1E1D2FC5BFE85165ECA31839CAA9CEB3\
570 3A92EBDC0EB3BAC0F810938BB173C7DA21DCBB2220D44CBA0FD40A2C868FC93AC5243E\
571 C137C27B0A76D65634EBB3");
572
573 mpi_fromstr(sk.d, "0x\
574 7C8A6FA1199D99DCA45E9BDF567CA49D02B237340D7E999150BC4883AE29DEC5158521\
575 B338F35DC883792356BDDBB3C8B3030A6DD4C6522599A3254E751F9BA1CB1061C5633C\
576 81BBFACF6FCD64502614102DFED3F3FA284066C342D5E00953B415915331E30812E5FB\
577 CD6680ADCCDEE40B8376A3A225F2E160EA59C7566804526D73BB660A648A3EF9802313\
578 B2F841E8458B2AAACE7AACF31083E8F3F630298138393BC88BBD7D4AA4334949651D25\
579 365B10DBF4A4A08E20A6CC74BFDD37C1C38E2ADC2A283DF06590DF06B46F67F6ACA67F\
580 AC464C795261659A2F9558802D0BBAA05FD1E1AF2CDC70654723DF7EFAEA148B8CDBEB\
581 C89EA2320AB9BBB1BC4311475DF3D91446F02EF192368DFEBAC598CCFD4407DEC58FDC\
582 1A94CCDD6E5FBA9C52164ACEA8AEE633E557BCCEACB7A1AF656C379482D784A120A725\
583 32F9B2B35173D505F21D5AD4CB9511BC836DC923730B70291B70290A216CA3B21CFF79\
584 E895C35F4F7AF80E1BD9ED2773BD26919A76E4298D169160593E0335BE2A2A2D2E8516\
585 948F657E1B1260E18808A9D463C108535FB60B3B28F711C81E5DE24F40214134A53CE5\
586 9A952C8970A1D771EBEFFA2F4359DCF157995B3F1950DE3C6EC41B7FF837148F55F323\
587 372AF3F20CE8B8038E750C23D8F5041FA951327859B0E47483F0A47103EF808C72C251\
588 006FA526245291C8C84C12D2EF63FB2301EA3EEDA42B");
589
590 mpi_fromstr(sk.p, "0x\
591 E236732452039C14EC1D3B8095BDDCFB7625CE27B1EA5394CF4ED09D3CEECAA4FC0BF6\
592 2F7CE975E0C8929CE84B0259D773EA038396479BF15DA065BA70E549B248D77B4B23ED\
593 A267308510DBEE2FD44E35D880EE7CFB81E0646AA8630165BD8988C3A8776D9E704C20\
594 AA25CA0A3C32F27F592D5FD363B04DD57D8C61FFDCDFCCC59E2913DE0EE47769180340\
595 E1EA5A803AA2301A010FF553A380F002601F0853FCACDB82D76FE2FACBCD6E5F294439\
596 0799EA5AE9D7880D4E1D4AE146DC1D4E8495B9DD30E57E883923C5FC26682B7142D35C\
597 D8A0FC561FE725A6CF419B15341F40FE0C31132CBD81DD8E50697BD1EBFFA16B522E16\
598 F5B49A03B707218C7DA60B");
599
600 mpi_fromstr(sk.q, "0x\
601 E830482A3C4F5C3A7E59C10FF8BA760DB1C6D55880B796FFDA4A82E0B60E974E81D04B\
602 2A4AD417823EBFB4E8EFB13782943562B19B6C4A680E3BA0C8E37B5023470F4F1AC1F8\
603 A0B10672EF75CD58BCD45E6B14503B8A6A70AFE79F6201AF56E7364A1C742BE1453FD2\
604 24FDC9D66522EAF4466A084BCB9E46D455A2946E94CBF028770F38D0B741C2CC59308F\
605 71D8C2B4B9C928E0AE8D68DEB48A3E9EFD84A10301EBD55F8221CA32FC567B306B2A8E\
606 116350AFB995859FDF4378C5CFD06901494E8CFA5D8FAC564D6531FA8A2E4761F5EFBA\
607 F78750B6F4662BE9EA4C2FAD67AF73EEB36B41FC15CB678810C19A51DF23555695C4C1\
608 546F3FACA39CAA7BB8DBD7");
609
610 mpi_fromstr(sk.u, "0x\
611 846232322775C1CD7D5569DC59E2F3E61A885AE2E9C4A4F8CB3ACBE8C3A5441E5FE348\
612 A2A8AC9C2998FBF282222BF508AA1ECF66A76AEDD2D9C97028BFD3F6CA0542E38A5312\
613 603C70B95650CE73F80FDD729988FBDB5595A5BF8A007EA34E54994A697906CE56354C\
614 E00DF10EB711DEC274A62494E3D350D88736CF67A477FB600AC9F1D6580727585092BF\
615 5EBC092CC4D6CF75769051033A1197103BE269942F372168A53771746FBA18ED6972D5\
616 0B935A9B1D6B5B3DD50CD89A27FE93C10924E9103FACF7B4C5724A046C3D3B50CC1C78\
617 5F5C8E00DBE1D6561F120F5294C170914BC10F978ED4356EED67A9F3A60D70AFE540FC\
618 5373CBAE3D0A7FD1C87273");
619
620 // copy the public key components
621 pk.n = mpi_copy( sk.n );
622 pk.e = mpi_copy( sk.e );
623
624 // some plain text message
625 MPI plain = mpi_alloc(0);
626 mpi_fromstr(plain, "0x\
627 5B6A8A0ACF4F4DB3F82EAC2D20255E4DF3E4B7C799603210766F26EF87C8980E737579\
628 EC08E6505A51D19654C26D806BAF1B62F9C032E0B13D02AF99F7313BFCFD68DA46836E\
629 CA529D7360948550F982C6476C054A97FD01635AB44BFBDBE2A90BE06F7984AC8534C3\
630 28097EF92F6E78CAE0CB97");
631
632 // expected encrypted MPI (via rsa.c directly)
633 MPI encr = mpi_alloc(0);
634 public_rsa( encr, plain, &pk);
635 MPI decr = mpi_alloc(0);
636 secret_rsa( decr, encr, &sk);
637 if (mpi_cmp(decr, plain) != 0)
638 printf("FAIL: decrypted != plain in test_rsa_octets (MPI call)\n");
639
640 //allocate the char arrays for _octets rsa
641 int len_n = noctets;
642 int len_e = len_n;
643 int len_d = len_n;
644 int len_p = noctets / 2;
645 int len_q = len_p;
646 int len_u = len_p;
647 char n[noctets];
648 char e[noctets];
649 char d[noctets];
650 char p[noctets / 2];
651 char q[noctets / 2];
652 char u[noctets / 2];
653
654 //copy the key components into char arrays
655 mpi_to_octets(n, &len_n, sk.n);
656 mpi_to_octets(e, &len_e, sk.e);
657 mpi_to_octets(d, &len_d, sk.d);
658 mpi_to_octets(p, &len_p, sk.p);
659 mpi_to_octets(q, &len_q, sk.q);
660 mpi_to_octets(u, &len_u, sk.u);
661
662 //call _octets rsa and check results
663 int len_encr = noctets;
664 int len_decr = noctets;
665 int len_plain = noctets;
666 char plain_o[noctets];
667 char encr_o[noctets];
668 char expected_encr_o[noctets];
669 char decr_o[noctets];
670 char expected_decr_o[noctets];
671
672 mpi_to_octets(plain_o, &len_plain, plain);
673 mpi_to_octets(expected_encr_o, &len_encr, encr);
674 mpi_to_octets(expected_decr_o, &len_decr, decr);
675 len_decr = noctets;
676
677 int len;
678 len = public_rsa_octets( encr_o, len_encr, plain_o, len_plain,
679 n, len_n, e, len_e);
680 if (len != len_encr)
681 printf("FAIL: actual len of encr is %d; expected %d\n", len, len_encr);
682 else
683 printf("PASS: actual len of encr matches expected: %d\n", len);
684 int errors= 0;
685 int i;
686 for (i=0;i<len;i++)
687 if (encr_o[i] != expected_encr_o[i])
688 errors = errors + 1;
689 if (errors>0)
690 printf("FAIL: found %d errors in public_rsa_octets output\n", errors);
691 else
692 printf("PASS: no errors found in public_rsa_octets output\n");
693
694 len_encr = len;
695 len = private_rsa_octets( decr_o, len_decr, encr_o, len_encr,
696 n, len_n, e, len_e,
697 d, len_d, p, len_p,
698 q, len_q, u, len_u);
699 if (len != len_plain)
700 printf("FAIL: actual len of decr is %d; expected %d\n", len, len_plain);
701 else
702 printf("PASS: actual len of decr matches expected: %d\n", len);
703
704 errors = 0;
705 for (i=0;i<len;i++)
706 if (decr_o[i] != expected_decr_o[i])
707 errors = errors + 1;
708 if (errors>0)
709 printf("FAIL: found %d errors in private_rsa_octets output\n", errors);
710 else printf("PASS: no errors found in private_rsa_octets_output\n");
711
712 //tidy up
713 mpi_free(sk.n);
714 mpi_free(sk.e);
715 mpi_free(sk.d);
716 mpi_free(sk.p);
717 mpi_free(sk.q);
718 mpi_free(sk.u);
719
720 mpi_free(pk.n);
721 mpi_free(pk.e);
722
723 mpi_free(plain);
724 mpi_free(encr);
725 mpi_free(decr);
726 }
727
728 int main(int ac, char **av) {
729 if (ac < 2) {
730 printf("Usage: %s testID\n", av[0]);
731 return -1;
732 }
733
734 int id = atoi(av[1]);
735 switch (id) {
736 case 1:
737 test_mpi_cmp();
738 break;
739 case 2:
740 test_gen_rsa_octets();
741 break;
742 case 3:
743 test_rsa_octets();
744 break;
745 default:
746 printf("Current test ids:\n");
747 printf("1 test of mpi_cmp_octets\n");
748 printf("2 test of gen_rsa_octets (can be very SLOW!)\n");
749 printf("3 test of rsa_octets (can take a few minutes)\n");
750 }
751 return 0;
752 }
- 84F1562E913676358D1BF1A9E6013F92BD61C79E2215EBA0B19959F7166CFDC8A0A73E1E6139B9A467AD060A0F2D243B788986AFF361167FFC7DB5CDEB1FB15E
+ 1D5B032F775B2B59D4BCBAFDDE81D65EFB3E11925C30962717565CD0CB2C2218434DAE770C470DC0A11B70F70B4CD78D37A3534741CFCCB2E002CF4ED4E94008
smg_comms/manifest
(1 . 3)(1 . 4)
757 532398 smg_comms_genesis diana_coman The first seed of an implementation of S.MG's communication protocol for Eulora: definitions for basic types, methods to/from network format, basic client/server test running locally on the same machine.
758 546000 smg_comms_raw_types diana_coman Part of layer 0 - raw types for the updated version of the protocol containing only two types of packets: 1470 octets RSA packet and 1472 octets Serpent packet.
759 546152 smg_comms_packing_serpent diana_coman Packing/Unpacking Serpent messages <-> Serpent packets. Includes Serpent implementation.
760 547275 smg_comms_c_wrappers diana_coman C wrappers for RSA and MPI methods that are needed by SMG Comms (so that they can be called from Ada using only arrays of octets as inputs/outputs).
-
+ 5B77E0898B3B6D0E202C38E9A85DA30C6920C748463247E5ED6F1EFC92C6794CE23ECBB83CDAED5CC79BFFBF197C171B1DE7FB872491B7A34966E1FB4D0E0D0F
smg_comms/mpi/COPYING
(0 . 0)(1 . 676)
765
766 GNU GENERAL PUBLIC LICENSE
767 Version 3, 29 June 2007
768
769 Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
770 Everyone is permitted to copy and distribute verbatim copies
771 of this license document, but changing it is not allowed.
772
773 Preamble
774
775 The GNU General Public License is a free, copyleft license for
776 software and other kinds of works.
777
778 The licenses for most software and other practical works are designed
779 to take away your freedom to share and change the works. By contrast,
780 the GNU General Public License is intended to guarantee your freedom to
781 share and change all versions of a program--to make sure it remains free
782 software for all its users. We, the Free Software Foundation, use the
783 GNU General Public License for most of our software; it applies also to
784 any other work released this way by its authors. You can apply it to
785 your programs, too.
786
787 When we speak of free software, we are referring to freedom, not
788 price. Our General Public Licenses are designed to make sure that you
789 have the freedom to distribute copies of free software (and charge for
790 them if you wish), that you receive source code or can get it if you
791 want it, that you can change the software or use pieces of it in new
792 free programs, and that you know you can do these things.
793
794 To protect your rights, we need to prevent others from denying you
795 these rights or asking you to surrender the rights. Therefore, you have
796 certain responsibilities if you distribute copies of the software, or if
797 you modify it: responsibilities to respect the freedom of others.
798
799 For example, if you distribute copies of such a program, whether
800 gratis or for a fee, you must pass on to the recipients the same
801 freedoms that you received. You must make sure that they, too, receive
802 or can get the source code. And you must show them these terms so they
803 know their rights.
804
805 Developers that use the GNU GPL protect your rights with two steps:
806 (1) assert copyright on the software, and (2) offer you this License
807 giving you legal permission to copy, distribute and/or modify it.
808
809 For the developers' and authors' protection, the GPL clearly explains
810 that there is no warranty for this free software. For both users' and
811 authors' sake, the GPL requires that modified versions be marked as
812 changed, so that their problems will not be attributed erroneously to
813 authors of previous versions.
814
815 Some devices are designed to deny users access to install or run
816 modified versions of the software inside them, although the manufacturer
817 can do so. This is fundamentally incompatible with the aim of
818 protecting users' freedom to change the software. The systematic
819 pattern of such abuse occurs in the area of products for individuals to
820 use, which is precisely where it is most unacceptable. Therefore, we
821 have designed this version of the GPL to prohibit the practice for those
822 products. If such problems arise substantially in other domains, we
823 stand ready to extend this provision to those domains in future versions
824 of the GPL, as needed to protect the freedom of users.
825
826 Finally, every program is threatened constantly by software patents.
827 States should not allow patents to restrict development and use of
828 software on general-purpose computers, but in those that do, we wish to
829 avoid the special danger that patents applied to a free program could
830 make it effectively proprietary. To prevent this, the GPL assures that
831 patents cannot be used to render the program non-free.
832
833 The precise terms and conditions for copying, distribution and
834 modification follow.
835
836 TERMS AND CONDITIONS
837
838 0. Definitions.
839
840 "This License" refers to version 3 of the GNU General Public License.
841
842 "Copyright" also means copyright-like laws that apply to other kinds of
843 works, such as semiconductor masks.
844
845 "The Program" refers to any copyrightable work licensed under this
846 License. Each licensee is addressed as "you". "Licensees" and
847 "recipients" may be individuals or organizations.
848
849 To "modify" a work means to copy from or adapt all or part of the work
850 in a fashion requiring copyright permission, other than the making of an
851 exact copy. The resulting work is called a "modified version" of the
852 earlier work or a work "based on" the earlier work.
853
854 A "covered work" means either the unmodified Program or a work based
855 on the Program.
856
857 To "propagate" a work means to do anything with it that, without
858 permission, would make you directly or secondarily liable for
859 infringement under applicable copyright law, except executing it on a
860 computer or modifying a private copy. Propagation includes copying,
861 distribution (with or without modification), making available to the
862 public, and in some countries other activities as well.
863
864 To "convey" a work means any kind of propagation that enables other
865 parties to make or receive copies. Mere interaction with a user through
866 a computer network, with no transfer of a copy, is not conveying.
867
868 An interactive user interface displays "Appropriate Legal Notices"
869 to the extent that it includes a convenient and prominently visible
870 feature that (1) displays an appropriate copyright notice, and (2)
871 tells the user that there is no warranty for the work (except to the
872 extent that warranties are provided), that licensees may convey the
873 work under this License, and how to view a copy of this License. If
874 the interface presents a list of user commands or options, such as a
875 menu, a prominent item in the list meets this criterion.
876
877 1. Source Code.
878
879 The "source code" for a work means the preferred form of the work
880 for making modifications to it. "Object code" means any non-source
881 form of a work.
882
883 A "Standard Interface" means an interface that either is an official
884 standard defined by a recognized standards body, or, in the case of
885 interfaces specified for a particular programming language, one that
886 is widely used among developers working in that language.
887
888 The "System Libraries" of an executable work include anything, other
889 than the work as a whole, that (a) is included in the normal form of
890 packaging a Major Component, but which is not part of that Major
891 Component, and (b) serves only to enable use of the work with that
892 Major Component, or to implement a Standard Interface for which an
893 implementation is available to the public in source code form. A
894 "Major Component", in this context, means a major essential component
895 (kernel, window system, and so on) of the specific operating system
896 (if any) on which the executable work runs, or a compiler used to
897 produce the work, or an object code interpreter used to run it.
898
899 The "Corresponding Source" for a work in object code form means all
900 the source code needed to generate, install, and (for an executable
901 work) run the object code and to modify the work, including scripts to
902 control those activities. However, it does not include the work's
903 System Libraries, or general-purpose tools or generally available free
904 programs which are used unmodified in performing those activities but
905 which are not part of the work. For example, Corresponding Source
906 includes interface definition files associated with source files for
907 the work, and the source code for shared libraries and dynamically
908 linked subprograms that the work is specifically designed to require,
909 such as by intimate data communication or control flow between those
910 subprograms and other parts of the work.
911
912 The Corresponding Source need not include anything that users
913 can regenerate automatically from other parts of the Corresponding
914 Source.
915
916 The Corresponding Source for a work in source code form is that
917 same work.
918
919 2. Basic Permissions.
920
921 All rights granted under this License are granted for the term of
922 copyright on the Program, and are irrevocable provided the stated
923 conditions are met. This License explicitly affirms your unlimited
924 permission to run the unmodified Program. The output from running a
925 covered work is covered by this License only if the output, given its
926 content, constitutes a covered work. This License acknowledges your
927 rights of fair use or other equivalent, as provided by copyright law.
928
929 You may make, run and propagate covered works that you do not
930 convey, without conditions so long as your license otherwise remains
931 in force. You may convey covered works to others for the sole purpose
932 of having them make modifications exclusively for you, or provide you
933 with facilities for running those works, provided that you comply with
934 the terms of this License in conveying all material for which you do
935 not control copyright. Those thus making or running the covered works
936 for you must do so exclusively on your behalf, under your direction
937 and control, on terms that prohibit them from making any copies of
938 your copyrighted material outside their relationship with you.
939
940 Conveying under any other circumstances is permitted solely under
941 the conditions stated below. Sublicensing is not allowed; section 10
942 makes it unnecessary.
943
944 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
945
946 No covered work shall be deemed part of an effective technological
947 measure under any applicable law fulfilling obligations under article
948 11 of the WIPO copyright treaty adopted on 20 December 1996, or
949 similar laws prohibiting or restricting circumvention of such
950 measures.
951
952 When you convey a covered work, you waive any legal power to forbid
953 circumvention of technological measures to the extent such circumvention
954 is effected by exercising rights under this License with respect to
955 the covered work, and you disclaim any intention to limit operation or
956 modification of the work as a means of enforcing, against the work's
957 users, your or third parties' legal rights to forbid circumvention of
958 technological measures.
959
960 4. Conveying Verbatim Copies.
961
962 You may convey verbatim copies of the Program's source code as you
963 receive it, in any medium, provided that you conspicuously and
964 appropriately publish on each copy an appropriate copyright notice;
965 keep intact all notices stating that this License and any
966 non-permissive terms added in accord with section 7 apply to the code;
967 keep intact all notices of the absence of any warranty; and give all
968 recipients a copy of this License along with the Program.
969
970 You may charge any price or no price for each copy that you convey,
971 and you may offer support or warranty protection for a fee.
972
973 5. Conveying Modified Source Versions.
974
975 You may convey a work based on the Program, or the modifications to
976 produce it from the Program, in the form of source code under the
977 terms of section 4, provided that you also meet all of these conditions:
978
979 a) The work must carry prominent notices stating that you modified
980 it, and giving a relevant date.
981
982 b) The work must carry prominent notices stating that it is
983 released under this License and any conditions added under section
984 7. This requirement modifies the requirement in section 4 to
985 "keep intact all notices".
986
987 c) You must license the entire work, as a whole, under this
988 License to anyone who comes into possession of a copy. This
989 License will therefore apply, along with any applicable section 7
990 additional terms, to the whole of the work, and all its parts,
991 regardless of how they are packaged. This License gives no
992 permission to license the work in any other way, but it does not
993 invalidate such permission if you have separately received it.
994
995 d) If the work has interactive user interfaces, each must display
996 Appropriate Legal Notices; however, if the Program has interactive
997 interfaces that do not display Appropriate Legal Notices, your
998 work need not make them do so.
999
1000 A compilation of a covered work with other separate and independent
1001 works, which are not by their nature extensions of the covered work,
1002 and which are not combined with it such as to form a larger program,
1003 in or on a volume of a storage or distribution medium, is called an
1004 "aggregate" if the compilation and its resulting copyright are not
1005 used to limit the access or legal rights of the compilation's users
1006 beyond what the individual works permit. Inclusion of a covered work
1007 in an aggregate does not cause this License to apply to the other
1008 parts of the aggregate.
1009
1010 6. Conveying Non-Source Forms.
1011
1012 You may convey a covered work in object code form under the terms
1013 of sections 4 and 5, provided that you also convey the
1014 machine-readable Corresponding Source under the terms of this License,
1015 in one of these ways:
1016
1017 a) Convey the object code in, or embodied in, a physical product
1018 (including a physical distribution medium), accompanied by the
1019 Corresponding Source fixed on a durable physical medium
1020 customarily used for software interchange.
1021
1022 b) Convey the object code in, or embodied in, a physical product
1023 (including a physical distribution medium), accompanied by a
1024 written offer, valid for at least three years and valid for as
1025 long as you offer spare parts or customer support for that product
1026 model, to give anyone who possesses the object code either (1) a
1027 copy of the Corresponding Source for all the software in the
1028 product that is covered by this License, on a durable physical
1029 medium customarily used for software interchange, for a price no
1030 more than your reasonable cost of physically performing this
1031 conveying of source, or (2) access to copy the
1032 Corresponding Source from a network server at no charge.
1033
1034 c) Convey individual copies of the object code with a copy of the
1035 written offer to provide the Corresponding Source. This
1036 alternative is allowed only occasionally and noncommercially, and
1037 only if you received the object code with such an offer, in accord
1038 with subsection 6b.
1039
1040 d) Convey the object code by offering access from a designated
1041 place (gratis or for a charge), and offer equivalent access to the
1042 Corresponding Source in the same way through the same place at no
1043 further charge. You need not require recipients to copy the
1044 Corresponding Source along with the object code. If the place to
1045 copy the object code is a network server, the Corresponding Source
1046 may be on a different server (operated by you or a third party)
1047 that supports equivalent copying facilities, provided you maintain
1048 clear directions next to the object code saying where to find the
1049 Corresponding Source. Regardless of what server hosts the
1050 Corresponding Source, you remain obligated to ensure that it is
1051 available for as long as needed to satisfy these requirements.
1052
1053 e) Convey the object code using peer-to-peer transmission, provided
1054 you inform other peers where the object code and Corresponding
1055 Source of the work are being offered to the general public at no
1056 charge under subsection 6d.
1057
1058 A separable portion of the object code, whose source code is excluded
1059 from the Corresponding Source as a System Library, need not be
1060 included in conveying the object code work.
1061
1062 A "User Product" is either (1) a "consumer product", which means any
1063 tangible personal property which is normally used for personal, family,
1064 or household purposes, or (2) anything designed or sold for incorporation
1065 into a dwelling. In determining whether a product is a consumer product,
1066 doubtful cases shall be resolved in favor of coverage. For a particular
1067 product received by a particular user, "normally used" refers to a
1068 typical or common use of that class of product, regardless of the status
1069 of the particular user or of the way in which the particular user
1070 actually uses, or expects or is expected to use, the product. A product
1071 is a consumer product regardless of whether the product has substantial
1072 commercial, industrial or non-consumer uses, unless such uses represent
1073 the only significant mode of use of the product.
1074
1075 "Installation Information" for a User Product means any methods,
1076 procedures, authorization keys, or other information required to install
1077 and execute modified versions of a covered work in that User Product from
1078 a modified version of its Corresponding Source. The information must
1079 suffice to ensure that the continued functioning of the modified object
1080 code is in no case prevented or interfered with solely because
1081 modification has been made.
1082
1083 If you convey an object code work under this section in, or with, or
1084 specifically for use in, a User Product, and the conveying occurs as
1085 part of a transaction in which the right of possession and use of the
1086 User Product is transferred to the recipient in perpetuity or for a
1087 fixed term (regardless of how the transaction is characterized), the
1088 Corresponding Source conveyed under this section must be accompanied
1089 by the Installation Information. But this requirement does not apply
1090 if neither you nor any third party retains the ability to install
1091 modified object code on the User Product (for example, the work has
1092 been installed in ROM).
1093
1094 The requirement to provide Installation Information does not include a
1095 requirement to continue to provide support service, warranty, or updates
1096 for a work that has been modified or installed by the recipient, or for
1097 the User Product in which it has been modified or installed. Access to a
1098 network may be denied when the modification itself materially and
1099 adversely affects the operation of the network or violates the rules and
1100 protocols for communication across the network.
1101
1102 Corresponding Source conveyed, and Installation Information provided,
1103 in accord with this section must be in a format that is publicly
1104 documented (and with an implementation available to the public in
1105 source code form), and must require no special password or key for
1106 unpacking, reading or copying.
1107
1108 7. Additional Terms.
1109
1110 "Additional permissions" are terms that supplement the terms of this
1111 License by making exceptions from one or more of its conditions.
1112 Additional permissions that are applicable to the entire Program shall
1113 be treated as though they were included in this License, to the extent
1114 that they are valid under applicable law. If additional permissions
1115 apply only to part of the Program, that part may be used separately
1116 under those permissions, but the entire Program remains governed by
1117 this License without regard to the additional permissions.
1118
1119 When you convey a copy of a covered work, you may at your option
1120 remove any additional permissions from that copy, or from any part of
1121 it. (Additional permissions may be written to require their own
1122 removal in certain cases when you modify the work.) You may place
1123 additional permissions on material, added by you to a covered work,
1124 for which you have or can give appropriate copyright permission.
1125
1126 Notwithstanding any other provision of this License, for material you
1127 add to a covered work, you may (if authorized by the copyright holders of
1128 that material) supplement the terms of this License with terms:
1129
1130 a) Disclaiming warranty or limiting liability differently from the
1131 terms of sections 15 and 16 of this License; or
1132
1133 b) Requiring preservation of specified reasonable legal notices or
1134 author attributions in that material or in the Appropriate Legal
1135 Notices displayed by works containing it; or
1136
1137 c) Prohibiting misrepresentation of the origin of that material, or
1138 requiring that modified versions of such material be marked in
1139 reasonable ways as different from the original version; or
1140
1141 d) Limiting the use for publicity purposes of names of licensors or
1142 authors of the material; or
1143
1144 e) Declining to grant rights under trademark law for use of some
1145 trade names, trademarks, or service marks; or
1146
1147 f) Requiring indemnification of licensors and authors of that
1148 material by anyone who conveys the material (or modified versions of
1149 it) with contractual assumptions of liability to the recipient, for
1150 any liability that these contractual assumptions directly impose on
1151 those licensors and authors.
1152
1153 All other non-permissive additional terms are considered "further
1154 restrictions" within the meaning of section 10. If the Program as you
1155 received it, or any part of it, contains a notice stating that it is
1156 governed by this License along with a term that is a further
1157 restriction, you may remove that term. If a license document contains
1158 a further restriction but permits relicensing or conveying under this
1159 License, you may add to a covered work material governed by the terms
1160 of that license document, provided that the further restriction does
1161 not survive such relicensing or conveying.
1162
1163 If you add terms to a covered work in accord with this section, you
1164 must place, in the relevant source files, a statement of the
1165 additional terms that apply to those files, or a notice indicating
1166 where to find the applicable terms.
1167
1168 Additional terms, permissive or non-permissive, may be stated in the
1169 form of a separately written license, or stated as exceptions;
1170 the above requirements apply either way.
1171
1172 8. Termination.
1173
1174 You may not propagate or modify a covered work except as expressly
1175 provided under this License. Any attempt otherwise to propagate or
1176 modify it is void, and will automatically terminate your rights under
1177 this License (including any patent licenses granted under the third
1178 paragraph of section 11).
1179
1180 However, if you cease all violation of this License, then your
1181 license from a particular copyright holder is reinstated (a)
1182 provisionally, unless and until the copyright holder explicitly and
1183 finally terminates your license, and (b) permanently, if the copyright
1184 holder fails to notify you of the violation by some reasonable means
1185 prior to 60 days after the cessation.
1186
1187 Moreover, your license from a particular copyright holder is
1188 reinstated permanently if the copyright holder notifies you of the
1189 violation by some reasonable means, this is the first time you have
1190 received notice of violation of this License (for any work) from that
1191 copyright holder, and you cure the violation prior to 30 days after
1192 your receipt of the notice.
1193
1194 Termination of your rights under this section does not terminate the
1195 licenses of parties who have received copies or rights from you under
1196 this License. If your rights have been terminated and not permanently
1197 reinstated, you do not qualify to receive new licenses for the same
1198 material under section 10.
1199
1200 9. Acceptance Not Required for Having Copies.
1201
1202 You are not required to accept this License in order to receive or
1203 run a copy of the Program. Ancillary propagation of a covered work
1204 occurring solely as a consequence of using peer-to-peer transmission
1205 to receive a copy likewise does not require acceptance. However,
1206 nothing other than this License grants you permission to propagate or
1207 modify any covered work. These actions infringe copyright if you do
1208 not accept this License. Therefore, by modifying or propagating a
1209 covered work, you indicate your acceptance of this License to do so.
1210
1211 10. Automatic Licensing of Downstream Recipients.
1212
1213 Each time you convey a covered work, the recipient automatically
1214 receives a license from the original licensors, to run, modify and
1215 propagate that work, subject to this License. You are not responsible
1216 for enforcing compliance by third parties with this License.
1217
1218 An "entity transaction" is a transaction transferring control of an
1219 organization, or substantially all assets of one, or subdividing an
1220 organization, or merging organizations. If propagation of a covered
1221 work results from an entity transaction, each party to that
1222 transaction who receives a copy of the work also receives whatever
1223 licenses to the work the party's predecessor in interest had or could
1224 give under the previous paragraph, plus a right to possession of the
1225 Corresponding Source of the work from the predecessor in interest, if
1226 the predecessor has it or can get it with reasonable efforts.
1227
1228 You may not impose any further restrictions on the exercise of the
1229 rights granted or affirmed under this License. For example, you may
1230 not impose a license fee, royalty, or other charge for exercise of
1231 rights granted under this License, and you may not initiate litigation
1232 (including a cross-claim or counterclaim in a lawsuit) alleging that
1233 any patent claim is infringed by making, using, selling, offering for
1234 sale, or importing the Program or any portion of it.
1235
1236 11. Patents.
1237
1238 A "contributor" is a copyright holder who authorizes use under this
1239 License of the Program or a work on which the Program is based. The
1240 work thus licensed is called the contributor's "contributor version".
1241
1242 A contributor's "essential patent claims" are all patent claims
1243 owned or controlled by the contributor, whether already acquired or
1244 hereafter acquired, that would be infringed by some manner, permitted
1245 by this License, of making, using, or selling its contributor version,
1246 but do not include claims that would be infringed only as a
1247 consequence of further modification of the contributor version. For
1248 purposes of this definition, "control" includes the right to grant
1249 patent sublicenses in a manner consistent with the requirements of
1250 this License.
1251
1252 Each contributor grants you a non-exclusive, worldwide, royalty-free
1253 patent license under the contributor's essential patent claims, to
1254 make, use, sell, offer for sale, import and otherwise run, modify and
1255 propagate the contents of its contributor version.
1256
1257 In the following three paragraphs, a "patent license" is any express
1258 agreement or commitment, however denominated, not to enforce a patent
1259 (such as an express permission to practice a patent or covenant not to
1260 sue for patent infringement). To "grant" such a patent license to a
1261 party means to make such an agreement or commitment not to enforce a
1262 patent against the party.
1263
1264 If you convey a covered work, knowingly relying on a patent license,
1265 and the Corresponding Source of the work is not available for anyone
1266 to copy, free of charge and under the terms of this License, through a
1267 publicly available network server or other readily accessible means,
1268 then you must either (1) cause the Corresponding Source to be so
1269 available, or (2) arrange to deprive yourself of the benefit of the
1270 patent license for this particular work, or (3) arrange, in a manner
1271 consistent with the requirements of this License, to extend the patent
1272 license to downstream recipients. "Knowingly relying" means you have
1273 actual knowledge that, but for the patent license, your conveying the
1274 covered work in a country, or your recipient's use of the covered work
1275 in a country, would infringe one or more identifiable patents in that
1276 country that you have reason to believe are valid.
1277
1278 If, pursuant to or in connection with a single transaction or
1279 arrangement, you convey, or propagate by procuring conveyance of, a
1280 covered work, and grant a patent license to some of the parties
1281 receiving the covered work authorizing them to use, propagate, modify
1282 or convey a specific copy of the covered work, then the patent license
1283 you grant is automatically extended to all recipients of the covered
1284 work and works based on it.
1285
1286 A patent license is "discriminatory" if it does not include within
1287 the scope of its coverage, prohibits the exercise of, or is
1288 conditioned on the non-exercise of one or more of the rights that are
1289 specifically granted under this License. You may not convey a covered
1290 work if you are a party to an arrangement with a third party that is
1291 in the business of distributing software, under which you make payment
1292 to the third party based on the extent of your activity of conveying
1293 the work, and under which the third party grants, to any of the
1294 parties who would receive the covered work from you, a discriminatory
1295 patent license (a) in connection with copies of the covered work
1296 conveyed by you (or copies made from those copies), or (b) primarily
1297 for and in connection with specific products or compilations that
1298 contain the covered work, unless you entered into that arrangement,
1299 or that patent license was granted, prior to 28 March 2007.
1300
1301 Nothing in this License shall be construed as excluding or limiting
1302 any implied license or other defenses to infringement that may
1303 otherwise be available to you under applicable patent law.
1304
1305 12. No Surrender of Others' Freedom.
1306
1307 If conditions are imposed on you (whether by court order, agreement or
1308 otherwise) that contradict the conditions of this License, they do not
1309 excuse you from the conditions of this License. If you cannot convey a
1310 covered work so as to satisfy simultaneously your obligations under this
1311 License and any other pertinent obligations, then as a consequence you may
1312 not convey it at all. For example, if you agree to terms that obligate you
1313 to collect a royalty for further conveying from those to whom you convey
1314 the Program, the only way you could satisfy both those terms and this
1315 License would be to refrain entirely from conveying the Program.
1316
1317 13. Use with the GNU Affero General Public License.
1318
1319 Notwithstanding any other provision of this License, you have
1320 permission to link or combine any covered work with a work licensed
1321 under version 3 of the GNU Affero General Public License into a single
1322 combined work, and to convey the resulting work. The terms of this
1323 License will continue to apply to the part which is the covered work,
1324 but the special requirements of the GNU Affero General Public License,
1325 section 13, concerning interaction through a network will apply to the
1326 combination as such.
1327
1328 14. Revised Versions of this License.
1329
1330 The Free Software Foundation may publish revised and/or new versions of
1331 the GNU General Public License from time to time. Such new versions will
1332 be similar in spirit to the present version, but may differ in detail to
1333 address new problems or concerns.
1334
1335 Each version is given a distinguishing version number. If the
1336 Program specifies that a certain numbered version of the GNU General
1337 Public License "or any later version" applies to it, you have the
1338 option of following the terms and conditions either of that numbered
1339 version or of any later version published by the Free Software
1340 Foundation. If the Program does not specify a version number of the
1341 GNU General Public License, you may choose any version ever published
1342 by the Free Software Foundation.
1343
1344 If the Program specifies that a proxy can decide which future
1345 versions of the GNU General Public License can be used, that proxy's
1346 public statement of acceptance of a version permanently authorizes you
1347 to choose that version for the Program.
1348
1349 Later license versions may give you additional or different
1350 permissions. However, no additional obligations are imposed on any
1351 author or copyright holder as a result of your choosing to follow a
1352 later version.
1353
1354 15. Disclaimer of Warranty.
1355
1356 THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
1357 APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
1358 HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
1359 OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
1360 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1361 PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
1362 IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
1363 ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
1364
1365 16. Limitation of Liability.
1366
1367 IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
1368 WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
1369 THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
1370 GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
1371 USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
1372 DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
1373 PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
1374 EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
1375 SUCH DAMAGES.
1376
1377 17. Interpretation of Sections 15 and 16.
1378
1379 If the disclaimer of warranty and limitation of liability provided
1380 above cannot be given local legal effect according to their terms,
1381 reviewing courts shall apply local law that most closely approximates
1382 an absolute waiver of all civil liability in connection with the
1383 Program, unless a warranty or assumption of liability accompanies a
1384 copy of the Program in return for a fee.
1385
1386 END OF TERMS AND CONDITIONS
1387
1388 How to Apply These Terms to Your New Programs
1389
1390 If you develop a new program, and you want it to be of the greatest
1391 possible use to the public, the best way to achieve this is to make it
1392 free software which everyone can redistribute and change under these terms.
1393
1394 To do so, attach the following notices to the program. It is safest
1395 to attach them to the start of each source file to most effectively
1396 state the exclusion of warranty; and each file should have at least
1397 the "copyright" line and a pointer to where the full notice is found.
1398
1399 <one line to give the program's name and a brief idea of what it does.>
1400 Copyright (C) <year> <name of author>
1401
1402 This program is free software: you can redistribute it and/or modify
1403 it under the terms of the GNU General Public License as published by
1404 the Free Software Foundation, either version 3 of the License, or
1405 (at your option) any later version.
1406
1407 This program is distributed in the hope that it will be useful,
1408 but WITHOUT ANY WARRANTY; without even the implied warranty of
1409 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1410 GNU General Public License for more details.
1411
1412 You should have received a copy of the GNU General Public License
1413 along with this program. If not, see <http://www.gnu.org/licenses/>.
1414
1415 Also add information on how to contact you by electronic and paper mail.
1416
1417 If the program does terminal interaction, make it output a short
1418 notice like this when it starts in an interactive mode:
1419
1420 <program> Copyright (C) <year> <name of author>
1421 This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
1422 This is free software, and you are welcome to redistribute it
1423 under certain conditions; type `show c' for details.
1424
1425 The hypothetical commands `show w' and `show c' should show the appropriate
1426 parts of the General Public License. Of course, your program's commands
1427 might be different; for a GUI interface, you would use an "about box".
1428
1429 You should also get your employer (if you work as a programmer) or school,
1430 if any, to sign a "copyright disclaimer" for the program, if necessary.
1431 For more information on this, and how to apply and follow the GNU GPL, see
1432 <http://www.gnu.org/licenses/>.
1433
1434 The GNU General Public License does not permit incorporating your program
1435 into proprietary programs. If your program is a subroutine library, you
1436 may consider it more useful to permit linking proprietary applications with
1437 the library. If this is what you want to do, use the GNU Lesser General
1438 Public License instead of this License. But first, please read
1439 <http://www.gnu.org/philosophy/why-not-lgpl.html>.
1440
-
+ 65A8797E0181E25A392820473F105126FFD8C5DD0FA57011D04FF984E852F7E338EE6FBDA3C5FA176F1021B404E4712005AA9FC4D25041D924611F09D539074A
smg_comms/mpi/README
(0 . 0)(1 . 89)
1445 NB: this is used by the smg_rsa component of EuCrypt.
1446
1447 What you see here is a very classic version of the GNU MPI (bignum) library.
1448 It has been surgically removed from GnuPG 1.4.10, specifically as found at:
1449
1450 http://trilema.com/wp-content/uploads/2015/10/gnupg-1.4.10.tar.gz.asc
1451
1452 SHA512(gnupg-1.4.10.tar.gz) :
1453 d037041d2e6882fd3b999500b5a7b42be2c224836afc358e1f8a2465c1b74473d518f185b7c324b2c8dec4ffb70e9e34a03c94d1a54cc55d297f40c9745f6e1b
1454
1455 Recommended compilation:
1456 1) gprbuild mpi.gpr
1457
1458 Tests:
1459 2) cd tests
1460 3) gprbuild
1461 4) ./test_mpi
1462 5) output is:
1463 37A063D056817668C7AA3418F29
1464 6) q: 'Waaaaaa, it barfed!'
1465 a: You are probably using GCC 5 or LLVM. Stop.
1466
1467
1468 CHANGES FROM ORIGINAL:
1469
1470 1) Everything pertaining to Automake was nuked, and the earth where it stood -
1471 salted.
1472
1473 Instead, we now have a conventional Makefile. It builds precisely
1474 ONE THING - a single 'mpi.a' library suitable for static linking into
1475 another project. This will turn up in 'bin'.
1476
1477 Among other things, this now means that all KNOBS now reside in a
1478 MANUALLY-controlled 'knobs.h' found in 'include'. If you are building
1479 on some very peculiar unix, please read it and adjust as appropriate.
1480 It contains ONLY those knobs which actually pertain to the code.
1481
1482 The Makefile contains a 'check-syntax' - users of Emacs and Flymake
1483 will see proper error-highlighting.
1484
1485 2) ALL chip-specific ASM optimizations (including those found in longlong.h)
1486 have been nuked.
1487
1488 3) GPG-specific cruft has been amputated to the extent practical.
1489
1490 The logging system has been retained, but it can be easily torn out,
1491 which I may choose to do in the near future.
1492
1493 The I/O buffering system has been retained. I may choose to remove it
1494 in the near future.
1495
1496 The 'secure memory' (unpageable alloc) system has been retained.
1497
1498 'Localization' and all related idiocies have been nuked.
1499 Write hieroglyphs at home, leave them there, civilized folk
1500 don't need'em in their source code.
1501
1502 4) Other code has been altered solely to the extent required by items
1503 (1), (2), and (3).
1504
1505 Cruft which appears in dead #ifdefs may be removed in the future.
1506 Don't get comfortable with it being there.
1507
1508 5) Readers who wish to know EXACTLY what I changed, should get a copy of the
1509 original tarball and write a simple script involving 'find' and 'vdiff',
1510 which sadly did not fit in the margins of this page.
1511
1512 6) To use the library, include 'include/mpi.h' in your project,
1513 and statically link with 'bin/mpi.a'.
1514
1515 7) The original code was distributed under GPL 3, which may apply on
1516 your planet and is therefore included. (See COPYING.)
1517
1518 ----------
1519 UPDATE #1:
1520 ----------
1521
1522 1) Abolished the logging subsystem inherited from GPG.
1523
1524 2) Abolished the I/O buffering subsystem, from same.
1525
1526 3) Eliminated all #ifdef blocks pertaining to RiscOS.
1527
1528 4) config.h is now knobs.h and is considerably shorter
1529 on account of there now being a great many fewer knobs.
1530
1531 5) Eliminated certain blocks of dead code.
1532
1533 6) Inserted notice of modifications as specified in GPL-3
-
+ F829705D787E0DE60B165CCD6BE182B11C11BC80E43B3B536A2062A7247B102A9EC8906E3D48C0D7EC71D6757678FD573728D12EF3FD3AE2DA9924B7593BC581
smg_comms/mpi/bin/README
(0 . 0)(1 . 1)
1538 S.MG, 2018
-
+ 1E58D3ECA9C3CC986A0B371F931498784570BBAECB5DCF98E85F159C2E7FFF90CCB30063DA8CA10F6D9D6C9E25DEEACE497436496E3D48EF4AE49F364D02182C
smg_comms/mpi/include/knobs.h
(0 . 0)(1 . 75)
1543 /* knobs.h -- Originally generated from config.h.in by autoconf.
1544 * But there is no more autoconf in this project.
1545 *
1546 * No Such Labs. (C) 2015. See README.
1547 *
1548 * This program is free software: you can redistribute it and/or modify
1549 * it under the terms of the GNU General Public License as published by
1550 * the Free Software Foundation, either version 3 of the License, or
1551 * (at your option) any later version.
1552 *
1553 * This program is distributed in the hope that it will be useful,
1554 * but WITHOUT ANY WARRANTY; without even the implied warranty of
1555 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1556 * GNU General Public License for more details.
1557 *
1558 * You should have received a copy of the GNU General Public License
1559 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1560 */
1561
1562 #ifndef GNUPG_CONFIG_H_INCLUDED
1563 #define GNUPG_CONFIG_H_INCLUDED
1564
1565 /* Report memory usage. */
1566 //#define M_DEBUG 1
1567
1568 /* Define to 1 if you have the `atexit' function. */
1569 #define HAVE_ATEXIT 1
1570
1571 /* Defined if the mlock() call does not work */
1572 /* #undef HAVE_BROKEN_MLOCK */
1573
1574 /* Defined if a `byte' is typedef'd */
1575 /* #undef HAVE_BYTE_TYPEDEF */
1576
1577 /* defined if we run on some of the PCDOS like systems (DOS, Windoze. OS/2)
1578 with special properties like no file modes */
1579 /* #undef HAVE_DOSISH_SYSTEM */
1580
1581 /* Define to 1 if you have the `getpagesize' function. */
1582 #define HAVE_GETPAGESIZE 1
1583
1584 /* Define to 1 if you have the <inttypes.h> header file. */
1585 #define HAVE_INTTYPES_H 1
1586
1587 /* Define to 1 if you have the `memmove' function. */
1588 #define HAVE_MEMMOVE 1
1589
1590 /* Defined if the system supports an mlock() call */
1591 #define HAVE_MLOCK 1
1592
1593 /* Define to 1 if you have the `mmap' function. */
1594 #define HAVE_MMAP 1
1595
1596 /* Define to 1 if you have the `plock' function. */
1597 /* #undef HAVE_PLOCK */
1598
1599 /* Define to 1 if you have the `raise' function. */
1600 #define HAVE_RAISE 1
1601
1602 /* Define to 1 if you have the `sysconf' function. */
1603 #define HAVE_SYSCONF 1
1604
1605 /* Defined if a `u16' is typedef'd */
1606 /* #undef HAVE_U16_TYPEDEF */
1607
1608 /* Defined if a `u32' is typedef'd */
1609 /* #undef HAVE_U32_TYPEDEF */
1610
1611 /* Defined if a `ulong' is typedef'd */
1612 #define HAVE_ULONG_TYPEDEF 1
1613
1614 /* Defined if a `ushort' is typedef'd */
1615 #define HAVE_USHORT_TYPEDEF 1
1616
1617 #endif /*GNUPG_CONFIG_H_INCLUDED*/
-
+ 0418E5BDE9C91CCF99BC408F3088AA1EF37C3F8318EBC3BABC9D9AB283A2ED3B158F0057ED885B0C336C69C4F58AC1FF4721D9188072DEC45391C0F2CCA7B250
smg_comms/mpi/include/longlong.h
(0 . 0)(1 . 226)
1622 /* longlong.h -- definitions for mixed size 32/64 bit arithmetic.
1623 * Modified by No Such Labs. (C) 2015. See README.
1624 *
1625 * This file was originally part of Gnu Privacy Guard (GPG), ver. 1.4.10,
1626 * SHA256(gnupg-1.4.10.tar.gz):
1627 * 0bfd74660a2f6cedcf7d8256db4a63c996ffebbcdc2cf54397bfb72878c5a85a
1628 * (C) 1994-2005 Free Software Foundation, Inc.
1629 *
1630 * This program is free software: you can redistribute it and/or modify
1631 * it under the terms of the GNU General Public License as published by
1632 * the Free Software Foundation, either version 3 of the License, or
1633 * (at your option) any later version.
1634 *
1635 * This program is distributed in the hope that it will be useful,
1636 * but WITHOUT ANY WARRANTY; without even the implied warranty of
1637 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1638 * GNU General Public License for more details.
1639 *
1640 * You should have received a copy of the GNU General Public License
1641 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1642 */
1643
1644 /* You have to define the following before including this file:
1645
1646 UWtype -- An unsigned type, default type for operations (typically a "word")
1647 UHWtype -- An unsigned type, at least half the size of UWtype.
1648 UDWtype -- An unsigned type, at least twice as large a UWtype
1649 W_TYPE_SIZE -- size in bits of UWtype
1650
1651 SItype, USItype -- Signed and unsigned 32 bit types.
1652 DItype, UDItype -- Signed and unsigned 64 bit types.
1653
1654 On a 32 bit machine UWtype should typically be USItype;
1655 on a 64 bit machine, UWtype should typically be UDItype.
1656 */
1657
1658 #define __BITS4 (W_TYPE_SIZE / 4)
1659 #define __ll_B ((UWtype) 1 << (W_TYPE_SIZE / 2))
1660 #define __ll_lowpart(t) ((UWtype) (t) & (__ll_B - 1))
1661 #define __ll_highpart(t) ((UWtype) (t) >> (W_TYPE_SIZE / 2))
1662
1663 /* This is used to make sure no undesirable sharing between different libraries
1664 that use this file takes place. */
1665 #ifndef __MPN
1666 #define __MPN(x) __##x
1667 #endif
1668
1669 /***************************************
1670 *********** Generic Versions ********
1671 ***************************************/
1672 #if !defined (umul_ppmm) && defined (__umulsidi3)
1673 #define umul_ppmm(ph, pl, m0, m1) \
1674 { \
1675 UDWtype __ll = __umulsidi3 (m0, m1); \
1676 ph = (UWtype) (__ll >> W_TYPE_SIZE); \
1677 pl = (UWtype) __ll; \
1678 }
1679 #endif
1680
1681 #if !defined (__umulsidi3)
1682 #define __umulsidi3(u, v) \
1683 ({UWtype __hi, __lo; \
1684 umul_ppmm (__hi, __lo, u, v); \
1685 ((UDWtype) __hi << W_TYPE_SIZE) | __lo; })
1686 #endif
1687
1688 /* If this machine has no inline assembler, use C macros. */
1689
1690 #if !defined (add_ssaaaa)
1691 #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
1692 do { \
1693 UWtype __x; \
1694 __x = (al) + (bl); \
1695 (sh) = (ah) + (bh) + (__x < (al)); \
1696 (sl) = __x; \
1697 } while (0)
1698 #endif
1699
1700 #if !defined (sub_ddmmss)
1701 #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
1702 do { \
1703 UWtype __x; \
1704 __x = (al) - (bl); \
1705 (sh) = (ah) - (bh) - (__x > (al)); \
1706 (sl) = __x; \
1707 } while (0)
1708 #endif
1709
1710 #if !defined (umul_ppmm)
1711 #define umul_ppmm(w1, w0, u, v) \
1712 do { \
1713 UWtype __x0, __x1, __x2, __x3; \
1714 UHWtype __ul, __vl, __uh, __vh; \
1715 UWtype __u = (u), __v = (v); \
1716 \
1717 __ul = __ll_lowpart (__u); \
1718 __uh = __ll_highpart (__u); \
1719 __vl = __ll_lowpart (__v); \
1720 __vh = __ll_highpart (__v); \
1721 \
1722 __x0 = (UWtype) __ul * __vl; \
1723 __x1 = (UWtype) __ul * __vh; \
1724 __x2 = (UWtype) __uh * __vl; \
1725 __x3 = (UWtype) __uh * __vh; \
1726 \
1727 __x1 += __ll_highpart (__x0);/* this can't give carry */ \
1728 __x1 += __x2; /* but this indeed can */ \
1729 if (__x1 < __x2) /* did we get it? */ \
1730 __x3 += __ll_B; /* yes, add it in the proper pos. */ \
1731 \
1732 (w1) = __x3 + __ll_highpart (__x1); \
1733 (w0) = (__ll_lowpart (__x1) << W_TYPE_SIZE/2) + __ll_lowpart (__x0);\
1734 } while (0)
1735 #endif
1736
1737 #if !defined (umul_ppmm)
1738 #define smul_ppmm(w1, w0, u, v) \
1739 do { \
1740 UWtype __w1; \
1741 UWtype __m0 = (u), __m1 = (v); \
1742 umul_ppmm (__w1, w0, __m0, __m1); \
1743 (w1) = __w1 - (-(__m0 >> (W_TYPE_SIZE - 1)) & __m1) \
1744 - (-(__m1 >> (W_TYPE_SIZE - 1)) & __m0); \
1745 } while (0)
1746 #endif
1747
1748 /* Define this unconditionally, so it can be used for debugging. */
1749 #define __udiv_qrnnd_c(q, r, n1, n0, d) \
1750 do { \
1751 UWtype __d1, __d0, __q1, __q0, __r1, __r0, __m; \
1752 __d1 = __ll_highpart (d); \
1753 __d0 = __ll_lowpart (d); \
1754 \
1755 __r1 = (n1) % __d1; \
1756 __q1 = (n1) / __d1; \
1757 __m = (UWtype) __q1 * __d0; \
1758 __r1 = __r1 * __ll_B | __ll_highpart (n0); \
1759 if (__r1 < __m) \
1760 { \
1761 __q1--, __r1 += (d); \
1762 if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\
1763 if (__r1 < __m) \
1764 __q1--, __r1 += (d); \
1765 } \
1766 __r1 -= __m; \
1767 \
1768 __r0 = __r1 % __d1; \
1769 __q0 = __r1 / __d1; \
1770 __m = (UWtype) __q0 * __d0; \
1771 __r0 = __r0 * __ll_B | __ll_lowpart (n0); \
1772 if (__r0 < __m) \
1773 { \
1774 __q0--, __r0 += (d); \
1775 if (__r0 >= (d)) \
1776 if (__r0 < __m) \
1777 __q0--, __r0 += (d); \
1778 } \
1779 __r0 -= __m; \
1780 \
1781 (q) = (UWtype) __q1 * __ll_B | __q0; \
1782 (r) = __r0; \
1783 } while (0)
1784
1785 /* If the processor has no udiv_qrnnd but sdiv_qrnnd, go through
1786 __udiv_w_sdiv (defined in libgcc or elsewhere). */
1787 #if !defined (udiv_qrnnd) && defined (sdiv_qrnnd)
1788 #define udiv_qrnnd(q, r, nh, nl, d) \
1789 do { \
1790 UWtype __r; \
1791 (q) = __MPN(udiv_w_sdiv) (&__r, nh, nl, d); \
1792 (r) = __r; \
1793 } while (0)
1794 #endif
1795
1796 /* If udiv_qrnnd was not defined for this processor, use __udiv_qrnnd_c. */
1797 #if !defined (udiv_qrnnd)
1798 #define UDIV_NEEDS_NORMALIZATION 1
1799 #define udiv_qrnnd __udiv_qrnnd_c
1800 #endif
1801
1802 #if !defined (count_leading_zeros)
1803 extern
1804 #ifdef __STDC__
1805 const
1806 #endif
1807 unsigned char __clz_tab[];
1808 #define MPI_INTERNAL_NEED_CLZ_TAB 1
1809 #define count_leading_zeros(count, x) \
1810 do { \
1811 UWtype __xr = (x); \
1812 UWtype __a; \
1813 \
1814 if (W_TYPE_SIZE <= 32) \
1815 { \
1816 __a = __xr < ((UWtype) 1 << 2*__BITS4) \
1817 ? (__xr < ((UWtype) 1 << __BITS4) ? 0 : __BITS4) \
1818 : (__xr < ((UWtype) 1 << 3*__BITS4) ? 2*__BITS4 : 3*__BITS4);\
1819 } \
1820 else \
1821 { \
1822 for (__a = W_TYPE_SIZE - 8; __a > 0; __a -= 8) \
1823 if (((__xr >> __a) & 0xff) != 0) \
1824 break; \
1825 } \
1826 \
1827 (count) = W_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a); \
1828 } while (0)
1829 /* This version gives a well-defined value for zero. */
1830 #define COUNT_LEADING_ZEROS_0 W_TYPE_SIZE
1831 #endif
1832
1833 #if !defined (count_trailing_zeros)
1834 /* Define count_trailing_zeros using count_leading_zeros. The latter might be
1835 defined in asm, but if it is not, the C version above is good enough. */
1836 #define count_trailing_zeros(count, x) \
1837 do { \
1838 UWtype __ctz_x = (x); \
1839 UWtype __ctz_c; \
1840 count_leading_zeros (__ctz_c, __ctz_x & -__ctz_x); \
1841 (count) = W_TYPE_SIZE - 1 - __ctz_c; \
1842 } while (0)
1843 #endif
1844
1845 #ifndef UDIV_NEEDS_NORMALIZATION
1846 #define UDIV_NEEDS_NORMALIZATION 0
1847 #endif
-
+ 27C0BD5775F26059D615F270D9E74C36E5C55F72FBA1A95DE0E15F66DE1EEC857E8470AA62BDE31CBA19024F80A3CF8E8B487582703F142B3C167EB02B0A0E86
smg_comms/mpi/include/memory.h
(0 . 0)(1 . 103)
1852 /* memory.h - memory allocation
1853 * Modified by No Such Labs. (C) 2015. See README.
1854 *
1855 * This file was originally part of Gnu Privacy Guard (GPG), ver. 1.4.10,
1856 * SHA256(gnupg-1.4.10.tar.gz):
1857 * 0bfd74660a2f6cedcf7d8256db4a63c996ffebbcdc2cf54397bfb72878c5a85a
1858 * (C) 1994-2005 Free Software Foundation, Inc.
1859 *
1860 * This program is free software: you can redistribute it and/or modify
1861 * it under the terms of the GNU General Public License as published by
1862 * the Free Software Foundation, either version 3 of the License, or
1863 * (at your option) any later version.
1864 *
1865 * This program is distributed in the hope that it will be useful,
1866 * but WITHOUT ANY WARRANTY; without even the implied warranty of
1867 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1868 * GNU General Public License for more details.
1869 *
1870 * You should have received a copy of the GNU General Public License
1871 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1872 */
1873
1874 #ifndef G10_MEMORY_H
1875 #define G10_MEMORY_H
1876
1877 #ifdef M_DEBUG
1878
1879 #ifndef STR
1880 #define STR(v) #v
1881 #endif
1882
1883 #define M_DBGINFO(a) __FUNCTION__ "["__FILE__ ":" STR(a) "]"
1884
1885 #define xmalloc(n) m_debug_alloc((n), M_DBGINFO( __LINE__ ) )
1886 #define xtrymalloc(n) m_debug_trymalloc ((n), M_DBGINFO( __LINE__ ))
1887 #define xmalloc_clear(n) m_debug_alloc_clear((n), M_DBGINFO(__LINE__) )
1888 #define xmalloc_secure(n) m_debug_alloc_secure(n), M_DBGINFO(__LINE__) )
1889 #define xmalloc_secure_clear(n) m_debug_alloc_secure_clear((n), M_DBGINFO(__LINE__) )
1890 #define xrealloc(n,m) m_debug_realloc((n),(m), M_DBGINFO(__LINE__) )
1891 #define xfree(n) m_debug_free((n), M_DBGINFO(__LINE__) )
1892 #define m_check(n) m_debug_check((n), M_DBGINFO(__LINE__) )
1893 /*#define m_copy(a) m_debug_copy((a), M_DBGINFO(__LINE__) )*/
1894 #define xstrdup(a) m_debug_strdup((a), M_DBGINFO(__LINE__) )
1895 #define xtrystrdup(a) m_debug_trystrdup((a), M_DBGINFO(__LINE__) )
1896
1897 void *m_debug_alloc( size_t n, const char *info );
1898 void *m_debug_trymalloc (size_t n, const char *info);
1899 void *m_debug_alloc_clear( size_t n, const char *info );
1900 void *m_debug_alloc_secure( size_t n, const char *info );
1901 void *m_debug_alloc_secure_clear( size_t n, const char *info );
1902 void *m_debug_realloc( void *a, size_t n, const char *info );
1903 void m_debug_free( void *p, const char *info );
1904 void m_debug_check( const void *a, const char *info );
1905 /*void *m_debug_copy( const void *a, const char *info );*/
1906 char *m_debug_strdup( const char *a, const char *info );
1907 char *m_debug_trystrdup (const char *a, const char *info);
1908
1909 #else
1910 void *xmalloc( size_t n );
1911 void *xtrymalloc (size_t n);
1912 void *xmalloc_clear( size_t n );
1913 void *xmalloc_secure( size_t n );
1914 void *xmalloc_secure_clear( size_t n );
1915 void *xrealloc( void *a, size_t n );
1916 void xfree( void *p );
1917 void m_check( const void *a );
1918 /*void *m_copy( const void *a );*/
1919 char *xstrdup( const char * a);
1920 char *xtrystrdup (const char *a);
1921 #endif
1922
1923 size_t m_size( const void *a );
1924 void m_print_stats(const char *prefix);
1925
1926 /* The follwing functions should be preferred over xmalloc_clear. */
1927 void *xcalloc (size_t n, size_t m);
1928 void *xcalloc_secure (size_t n, size_t m);
1929
1930
1931 /*-- secmem.c --*/
1932 int secmem_init( size_t npool );
1933 void secmem_term( void );
1934 void *secmem_malloc( size_t size );
1935 void *secmexrealloc( void *a, size_t newsize );
1936 void secmem_free( void *a );
1937 int m_is_secure( const void *p );
1938 void secmem_dump_stats(void);
1939 void secmem_set_flags( unsigned flags );
1940 unsigned secmem_get_flags(void);
1941
1942
1943 #define DBG_MEMORY memory_debug_mode
1944 #define DBG_MEMSTAT memory_stat_debug_mode
1945
1946 #ifndef EXTERN_UNLESS_MAIN_MODULE
1947 #define EXTERN_UNLESS_MAIN_MODULE
1948 #endif
1949 EXTERN_UNLESS_MAIN_MODULE int memory_debug_mode;
1950 EXTERN_UNLESS_MAIN_MODULE int memory_stat_debug_mode;
1951
1952
1953
1954 #endif /*G10_MEMORY_H*/
-
+ 2EA77D3E9C3D040649368883BDCAECA474685EF6968E358CDD744647292902E584E34949CABA771CB43145F3AC1FCE64932CF2E7D48AD514B84EE81FE5492C58
smg_comms/mpi/include/mpi-inline.h
(0 . 0)(1 . 121)
1959 /* mpi-inline.h - Internal to the Multi Precision Integers
1960 * Modified by No Such Labs. (C) 2015. See README.
1961 *
1962 * This file was originally part of Gnu Privacy Guard (GPG), ver. 1.4.10,
1963 * SHA256(gnupg-1.4.10.tar.gz):
1964 * 0bfd74660a2f6cedcf7d8256db4a63c996ffebbcdc2cf54397bfb72878c5a85a
1965 * (C) 1994-2005 Free Software Foundation, Inc.
1966 *
1967 * This program is free software: you can redistribute it and/or modify
1968 * it under the terms of the GNU General Public License as published by
1969 * the Free Software Foundation, either version 3 of the License, or
1970 * (at your option) any later version.
1971 *
1972 * This program is distributed in the hope that it will be useful,
1973 * but WITHOUT ANY WARRANTY; without even the implied warranty of
1974 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1975 * GNU General Public License for more details.
1976 *
1977 * You should have received a copy of the GNU General Public License
1978 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1979 */
1980
1981 #ifndef G10_MPI_INLINE_H
1982 #define G10_MPI_INLINE_H
1983
1984 #ifndef G10_MPI_INLINE_DECL
1985 #define G10_MPI_INLINE_DECL extern __inline__
1986 #endif
1987
1988 G10_MPI_INLINE_DECL mpi_limb_t
1989 mpihelp_add_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
1990 mpi_size_t s1_size, mpi_limb_t s2_limb)
1991 {
1992 mpi_limb_t x;
1993
1994 x = *s1_ptr++;
1995 s2_limb += x;
1996 *res_ptr++ = s2_limb;
1997 if( s2_limb < x ) { /* sum is less than the left operand: handle carry */
1998 while( --s1_size ) {
1999 x = *s1_ptr++ + 1; /* add carry */
2000 *res_ptr++ = x; /* and store */
2001 if( x ) /* not 0 (no overflow): we can stop */
2002 goto leave;
2003 }
2004 return 1; /* return carry (size of s1 to small) */
2005 }
2006
2007 leave:
2008 if( res_ptr != s1_ptr ) { /* not the same variable */
2009 mpi_size_t i; /* copy the rest */
2010 for( i=0; i < s1_size-1; i++ )
2011 res_ptr[i] = s1_ptr[i];
2012 }
2013 return 0; /* no carry */
2014 }
2015
2016
2017
2018 G10_MPI_INLINE_DECL mpi_limb_t
2019 mpihelp_add(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size,
2020 mpi_ptr_t s2_ptr, mpi_size_t s2_size)
2021 {
2022 mpi_limb_t cy = 0;
2023
2024 if( s2_size )
2025 cy = mpihelp_add_n( res_ptr, s1_ptr, s2_ptr, s2_size );
2026
2027 if( s1_size - s2_size )
2028 cy = mpihelp_add_1( res_ptr + s2_size, s1_ptr + s2_size,
2029 s1_size - s2_size, cy);
2030 return cy;
2031 }
2032
2033
2034 G10_MPI_INLINE_DECL mpi_limb_t
2035 mpihelp_sub_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
2036 mpi_size_t s1_size, mpi_limb_t s2_limb )
2037 {
2038 mpi_limb_t x;
2039
2040 x = *s1_ptr++;
2041 s2_limb = x - s2_limb;
2042 *res_ptr++ = s2_limb;
2043 if( s2_limb > x ) {
2044 while( --s1_size ) {
2045 x = *s1_ptr++;
2046 *res_ptr++ = x - 1;
2047 if( x )
2048 goto leave;
2049 }
2050 return 1;
2051 }
2052
2053 leave:
2054 if( res_ptr != s1_ptr ) {
2055 mpi_size_t i;
2056 for( i=0; i < s1_size-1; i++ )
2057 res_ptr[i] = s1_ptr[i];
2058 }
2059 return 0;
2060 }
2061
2062
2063
2064 G10_MPI_INLINE_DECL mpi_limb_t
2065 mpihelp_sub( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size,
2066 mpi_ptr_t s2_ptr, mpi_size_t s2_size)
2067 {
2068 mpi_limb_t cy = 0;
2069
2070 if( s2_size )
2071 cy = mpihelp_sub_n(res_ptr, s1_ptr, s2_ptr, s2_size);
2072
2073 if( s1_size - s2_size )
2074 cy = mpihelp_sub_1(res_ptr + s2_size, s1_ptr + s2_size,
2075 s1_size - s2_size, cy);
2076 return cy;
2077 }
2078
2079 #endif /*G10_MPI_INLINE_H*/
-
+ 0EC90EEED7BB58E2D737FDDAF5CD8101CFB114C9D0824457384E5C199B4E1A75F1762BCD465CD4B675FE19DA36197EE9BFF0D3E24ED6B9E4C26A1A05FFC7386E
smg_comms/mpi/include/mpi-internal.h
(0 . 0)(1 . 287)
2084 /* mpi-internal.h - Internal to the Multi Precision Integers
2085 * Modified by No Such Labs. (C) 2015. See README.
2086 * Modified by S.MG, 2017: fixing broken MPN_COPY_INCR macro. See EuCrypt patches.
2087 *
2088 * This file was originally part of Gnu Privacy Guard (GPG), ver. 1.4.10,
2089 * SHA256(gnupg-1.4.10.tar.gz):
2090 * 0bfd74660a2f6cedcf7d8256db4a63c996ffebbcdc2cf54397bfb72878c5a85a
2091 * (C) 1994-2005 Free Software Foundation, Inc.
2092 *
2093 * This program is free software: you can redistribute it and/or modify
2094 * it under the terms of the GNU General Public License as published by
2095 * the Free Software Foundation, either version 3 of the License, or
2096 * (at your option) any later version.
2097 *
2098 * This program is distributed in the hope that it will be useful,
2099 * but WITHOUT ANY WARRANTY; without even the implied warranty of
2100 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2101 * GNU General Public License for more details.
2102 *
2103 * You should have received a copy of the GNU General Public License
2104 * along with this program. If not, see <http://www.gnu.org/licenses/>.
2105 */
2106
2107 #ifndef G10_MPI_INTERNAL_H
2108 #define G10_MPI_INTERNAL_H
2109
2110 #include "mpi.h"
2111
2112 /* from the old mpi-asm-defs.h */
2113 #define BYTES_PER_MPI_LIMB (SIZEOF_UNSIGNED_LONG)
2114
2115 #if BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_INT
2116 typedef unsigned int mpi_limb_t;
2117 typedef signed int mpi_limb_signed_t;
2118 #elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_LONG
2119 typedef unsigned long int mpi_limb_t;
2120 typedef signed long int mpi_limb_signed_t;
2121 #elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_LONG_LONG
2122 typedef unsigned long long int mpi_limb_t;
2123 typedef signed long long int mpi_limb_signed_t;
2124 #elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_SHORT
2125 typedef unsigned short int mpi_limb_t;
2126 typedef signed short int mpi_limb_signed_t;
2127 #else
2128 #error BYTES_PER_MPI_LIMB does not match any C type
2129 #endif
2130 #define BITS_PER_MPI_LIMB (8*BYTES_PER_MPI_LIMB)
2131
2132
2133 struct gcry_mpi {
2134 int alloced; /* array size (# of allocated limbs) */
2135 int nlimbs; /* number of valid limbs */
2136 unsigned int nbits; /* the real number of valid bits (info only) */
2137 int sign; /* indicates a negative number */
2138 unsigned flags; /* bit 0: array must be allocated in secure memory space */
2139 /* bit 1: not used */
2140 /* bit 2: the limb is a pointer to some xmalloced data */
2141 mpi_limb_t *d; /* array with the limbs */
2142 };
2143
2144
2145
2146 /* If KARATSUBA_THRESHOLD is not already defined, define it to a
2147 * value which is good on most machines. */
2148
2149 /* tested 4, 16, 32 and 64, where 16 gave the best performance when
2150 * checking a 768 and a 1024 bit ElGamal signature.
2151 * (wk 22.12.97) */
2152 #ifndef KARATSUBA_THRESHOLD
2153 #define KARATSUBA_THRESHOLD 16
2154 #endif
2155
2156 /* The code can't handle KARATSUBA_THRESHOLD smaller than 2. */
2157 #if KARATSUBA_THRESHOLD < 2
2158 #undef KARATSUBA_THRESHOLD
2159 #define KARATSUBA_THRESHOLD 2
2160 #endif
2161
2162
2163 typedef mpi_limb_t *mpi_ptr_t; /* pointer to a limb */
2164 typedef int mpi_size_t; /* (must be a signed type) */
2165
2166 #define ABS(x) (x >= 0 ? x : -x)
2167 #define MIN(l,o) ((l) < (o) ? (l) : (o))
2168 #define MAX(h,i) ((h) > (i) ? (h) : (i))
2169 #define RESIZE_IF_NEEDED(a,b) \
2170 do { \
2171 if( (a)->alloced < (b) ) \
2172 mpi_resize((a), (b)); \
2173 } while(0)
2174
2175 /* Copy N limbs from S to D. */
2176 #define MPN_COPY( d, s, n) \
2177 do { \
2178 mpi_size_t _i; \
2179 for( _i = 0; _i < (n); _i++ ) \
2180 (d)[_i] = (s)[_i]; \
2181 } while(0)
2182
2183 #define MPN_COPY_INCR( d, s, n) \
2184 do { \
2185 mpi_size_t _i; \
2186 for( _i = 0; _i < (n); _i++ ) \
2187 (d)[_i] = (s)[_i]; \
2188 } while (0)
2189
2190 #define MPN_COPY_DECR( d, s, n ) \
2191 do { \
2192 mpi_size_t _i; \
2193 for( _i = (n)-1; _i >= 0; _i--) \
2194 (d)[_i] = (s)[_i]; \
2195 } while(0)
2196
2197 /* Zero N limbs at D */
2198 #define MPN_ZERO(d, n) \
2199 do { \
2200 int _i; \
2201 for( _i = 0; _i < (n); _i++ ) \
2202 (d)[_i] = 0; \
2203 } while (0)
2204
2205 #define MPN_NORMALIZE(d, n) \
2206 do { \
2207 while( (n) > 0 ) { \
2208 if( (d)[(n)-1] ) \
2209 break; \
2210 (n)--; \
2211 } \
2212 } while(0)
2213
2214 #define MPN_NORMALIZE_NOT_ZERO(d, n) \
2215 do { \
2216 for(;;) { \
2217 if( (d)[(n)-1] ) \
2218 break; \
2219 (n)--; \
2220 } \
2221 } while(0)
2222
2223 #define MPN_MUL_N_RECURSE(prodp, up, vp, size, tspace) \
2224 do { \
2225 if( (size) < KARATSUBA_THRESHOLD ) \
2226 mul_n_basecase (prodp, up, vp, size); \
2227 else \
2228 mul_n (prodp, up, vp, size, tspace); \
2229 } while (0);
2230
2231
2232 /* Divide the two-limb number in (NH,,NL) by D, with DI being the largest
2233 * limb not larger than (2**(2*BITS_PER_MP_LIMB))/D - (2**BITS_PER_MP_LIMB).
2234 * If this would yield overflow, DI should be the largest possible number
2235 * (i.e., only ones). For correct operation, the most significant bit of D
2236 * has to be set. Put the quotient in Q and the remainder in R.
2237 */
2238 #define UDIV_QRNND_PREINV(q, r, nh, nl, d, di) \
2239 do { \
2240 mpi_limb_t _q, _ql, _r; \
2241 mpi_limb_t _xh, _xl; \
2242 umul_ppmm (_q, _ql, (nh), (di)); \
2243 _q += (nh); /* DI is 2**BITS_PER_MPI_LIMB too small */ \
2244 umul_ppmm (_xh, _xl, _q, (d)); \
2245 sub_ddmmss (_xh, _r, (nh), (nl), _xh, _xl); \
2246 if( _xh ) { \
2247 sub_ddmmss (_xh, _r, _xh, _r, 0, (d)); \
2248 _q++; \
2249 if( _xh) { \
2250 sub_ddmmss (_xh, _r, _xh, _r, 0, (d)); \
2251 _q++; \
2252 } \
2253 } \
2254 if( _r >= (d) ) { \
2255 _r -= (d); \
2256 _q++; \
2257 } \
2258 (r) = _r; \
2259 (q) = _q; \
2260 } while (0)
2261
2262
2263 /*-- mpiutil.c --*/
2264 #ifdef M_DEBUG
2265 #define mpi_alloc_limb_space(n,f) mpi_debug_alloc_limb_space((n),(f), M_DBGINFO( __LINE__ ) )
2266 #define mpi_free_limb_space(n) mpi_debug_free_limb_space((n), M_DBGINFO( __LINE__ ) )
2267 mpi_ptr_t mpi_debug_alloc_limb_space( unsigned nlimbs, int sec, const char *info );
2268 void mpi_debug_free_limb_space( mpi_ptr_t a, const char *info );
2269 #else
2270 mpi_ptr_t mpi_alloc_limb_space( unsigned nlimbs, int sec );
2271 void mpi_free_limb_space( mpi_ptr_t a );
2272 #endif
2273 void mpi_assign_limb_space( MPI a, mpi_ptr_t ap, unsigned nlimbs );
2274
2275 /*-- mpi-bit.c --*/
2276 void mpi_rshift_limbs( MPI a, unsigned int count );
2277 void mpi_lshift_limbs( MPI a, unsigned int count );
2278
2279
2280 /*-- mpihelp-add.c --*/
2281 mpi_limb_t mpihelp_add_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
2282 mpi_size_t s1_size, mpi_limb_t s2_limb );
2283 mpi_limb_t mpihelp_add_n( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
2284 mpi_ptr_t s2_ptr, mpi_size_t size);
2285 mpi_limb_t mpihelp_add(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size,
2286 mpi_ptr_t s2_ptr, mpi_size_t s2_size);
2287
2288 /*-- mpihelp-sub.c --*/
2289 mpi_limb_t mpihelp_sub_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
2290 mpi_size_t s1_size, mpi_limb_t s2_limb );
2291 mpi_limb_t mpihelp_sub_n( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
2292 mpi_ptr_t s2_ptr, mpi_size_t size);
2293 mpi_limb_t mpihelp_sub(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size,
2294 mpi_ptr_t s2_ptr, mpi_size_t s2_size);
2295
2296 /*-- mpihelp-cmp.c --*/
2297 int mpihelp_cmp( mpi_ptr_t op1_ptr, mpi_ptr_t op2_ptr, mpi_size_t size );
2298
2299 /*-- mpihelp-mul.c --*/
2300
2301 struct karatsuba_ctx {
2302 struct karatsuba_ctx *next;
2303 mpi_ptr_t tspace;
2304 mpi_size_t tspace_size;
2305 mpi_ptr_t tp;
2306 mpi_size_t tp_size;
2307 };
2308
2309 void mpihelp_release_karatsuba_ctx( struct karatsuba_ctx *ctx );
2310
2311 mpi_limb_t mpihelp_addmul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
2312 mpi_size_t s1_size, mpi_limb_t s2_limb);
2313 mpi_limb_t mpihelp_submul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
2314 mpi_size_t s1_size, mpi_limb_t s2_limb);
2315 void mpihelp_mul_n( mpi_ptr_t prodp, mpi_ptr_t up, mpi_ptr_t vp,
2316 mpi_size_t size);
2317 mpi_limb_t mpihelp_mul( mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t usize,
2318 mpi_ptr_t vp, mpi_size_t vsize);
2319 void mpih_sqr_n_basecase( mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t size );
2320 void mpih_sqr_n( mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t size,
2321 mpi_ptr_t tspace);
2322
2323 void mpihelp_mul_karatsuba_case( mpi_ptr_t prodp,
2324 mpi_ptr_t up, mpi_size_t usize,
2325 mpi_ptr_t vp, mpi_size_t vsize,
2326 struct karatsuba_ctx *ctx );
2327
2328
2329 /*-- mpihelp-mul_1.c (or xxx/cpu/ *.S) --*/
2330 mpi_limb_t mpihelp_mul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
2331 mpi_size_t s1_size, mpi_limb_t s2_limb);
2332
2333 /*-- mpihelp-div.c --*/
2334 mpi_limb_t mpihelp_mod_1(mpi_ptr_t dividend_ptr, mpi_size_t dividend_size,
2335 mpi_limb_t divisor_limb);
2336 mpi_limb_t mpihelp_divrem( mpi_ptr_t qp, mpi_size_t qextra_limbs,
2337 mpi_ptr_t np, mpi_size_t nsize,
2338 mpi_ptr_t dp, mpi_size_t dsize);
2339 mpi_limb_t mpihelp_divmod_1( mpi_ptr_t quot_ptr,
2340 mpi_ptr_t dividend_ptr, mpi_size_t dividend_size,
2341 mpi_limb_t divisor_limb);
2342
2343 /*-- mpihelp-shift.c --*/
2344 mpi_limb_t mpihelp_lshift( mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize,
2345 unsigned cnt);
2346 mpi_limb_t mpihelp_rshift( mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize,
2347 unsigned cnt);
2348
2349
2350 /* Define stuff for longlong.h. */
2351 #define W_TYPE_SIZE BITS_PER_MPI_LIMB
2352 typedef mpi_limb_t UWtype;
2353 typedef unsigned int UHWtype;
2354 #if defined (__GNUC__)
2355 typedef unsigned int UQItype __attribute__ ((mode (QI)));
2356 typedef int SItype __attribute__ ((mode (SI)));
2357 typedef unsigned int USItype __attribute__ ((mode (SI)));
2358 typedef int DItype __attribute__ ((mode (DI)));
2359 typedef unsigned int UDItype __attribute__ ((mode (DI)));
2360 #else
2361 typedef unsigned char UQItype;
2362 typedef long SItype;
2363 typedef unsigned long USItype;
2364 #endif
2365
2366 #ifdef __GNUC__
2367 #include "mpi-inline.h"
2368 #endif
2369
2370 #endif /*G10_MPI_INTERNAL_H*/
-
+ D86FF3ED23FF796D0C35B550F60142DD5A7242343DCAE7CA74558C30B5FEC1749AAF6A0207F4BF39DF464BCC60FF37A6495965D3E7DAD5AD70C0AEB7A7C2A46C
smg_comms/mpi/include/mpi.h
(0 . 0)(1 . 152)
2375 /* mpi.h - Multi Precision Integers
2376 * Modified by No Such Labs. (C) 2015. See README.
2377 * Modified by S.MG, 2018. Added mpi_get_alloced, function for retrieving currently allocated number of limbs.
2378 *
2379 * This file was originally part of Gnu Privacy Guard (GPG), ver. 1.4.10,
2380 * SHA256(gnupg-1.4.10.tar.gz):
2381 * 0bfd74660a2f6cedcf7d8256db4a63c996ffebbcdc2cf54397bfb72878c5a85a
2382 * (C) 1994-2005 Free Software Foundation, Inc.
2383 *
2384 * This program is free software: you can redistribute it and/or modify
2385 * it under the terms of the GNU General Public License as published by
2386 * the Free Software Foundation, either version 3 of the License, or
2387 * (at your option) any later version.
2388 *
2389 * This program is distributed in the hope that it will be useful,
2390 * but WITHOUT ANY WARRANTY; without even the implied warranty of
2391 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2392 * GNU General Public License for more details.
2393 *
2394 * You should have received a copy of the GNU General Public License
2395 * along with this program. If not, see <http://www.gnu.org/licenses/>.
2396 */
2397
2398 #ifndef G10_MPI_H
2399 #define G10_MPI_H
2400
2401 #include <stdio.h>
2402 #include "knobs.h"
2403 #include "types.h"
2404 #include "memory.h"
2405
2406 #ifndef EXTERN_UNLESS_MAIN_MODULE
2407 #define EXTERN_UNLESS_MAIN_MODULE
2408 #endif
2409
2410 #define DBG_MPI mpi_debug_mode
2411 EXTERN_UNLESS_MAIN_MODULE int mpi_debug_mode;
2412
2413
2414 struct gcry_mpi;
2415 typedef struct gcry_mpi *MPI;
2416
2417
2418 /*-- mpiutil.c --*/
2419
2420 #ifdef M_DEBUG
2421 #define mpi_alloc(n) mpi_debug_alloc((n), M_DBGINFO( __LINE__ ) )
2422 #define mpi_alloc_secure(n) mpi_debug_alloc_secure((n), M_DBGINFO( __LINE__ ) )
2423 #define mpi_alloc_like(n) mpi_debug_alloc_like((n), M_DBGINFO( __LINE__ ) )
2424 #define mpi_free(a) mpi_debug_free((a), M_DBGINFO(__LINE__) )
2425 #define mpi_resize(a,b) mpi_debug_resize((a),(b), M_DBGINFO(__LINE__) )
2426 #define mpi_copy(a) mpi_debug_copy((a), M_DBGINFO(__LINE__) )
2427 MPI mpi_debug_alloc( unsigned nlimbs, const char *info );
2428 MPI mpi_debug_alloc_secure( unsigned nlimbs, const char *info );
2429 MPI mpi_debug_alloc_like( MPI a, const char *info );
2430 void mpi_debug_free( MPI a, const char *info );
2431 void mpi_debug_resize( MPI a, unsigned nlimbs, const char *info );
2432 MPI mpi_debug_copy( MPI a, const char *info );
2433 #else
2434 MPI mpi_alloc( unsigned nlimbs );
2435 MPI mpi_alloc_secure( unsigned nlimbs );
2436 MPI mpi_alloc_like( MPI a );
2437 void mpi_free( MPI a );
2438 void mpi_resize( MPI a, unsigned nlimbs );
2439 MPI mpi_copy( MPI a );
2440 #endif
2441 #define mpi_is_opaque(a) ((a) && (mpi_get_flags (a)&4))
2442 MPI mpi_set_opaque( MPI a, void *p, unsigned int len );
2443 void *mpi_get_opaque( MPI a, unsigned int *len );
2444 #define mpi_is_secure(a) ((a) && (mpi_get_flags (a)&1))
2445 void mpi_set_secure( MPI a );
2446 void mpi_clear( MPI a );
2447 void mpi_set( MPI w, MPI u);
2448 void mpi_set_ui( MPI w, ulong u);
2449 MPI mpi_alloc_set_ui( unsigned long u);
2450 void mpi_m_check( MPI a );
2451 void mpi_swap( MPI a, MPI b);
2452 int mpi_get_nlimbs (MPI a);
2453 int mpi_get_alloced (MPI a); /* returns the allocated memory space for this MPI, in number of limbs */
2454 int mpi_is_neg (MPI a);
2455 unsigned int mpi_nlimb_hint_from_nbytes (unsigned int nbytes);
2456 unsigned int mpi_nlimb_hint_from_nbits (unsigned int nbits);
2457 unsigned int mpi_get_flags (MPI a);
2458
2459 /*-- mpicoder.c --*/
2460 MPI mpi_read_from_buffer(byte *buffer, unsigned *ret_nread, int secure);
2461 int mpi_fromstr(MPI val, const char *str);
2462 int mpi_print( FILE *fp, MPI a, int mode );
2463 //void g10_log_mpidump( const char *text, MPI a );
2464 byte *mpi_get_buffer( MPI a, unsigned *nbytes, int *sign );
2465 byte *mpi_get_secure_buffer( MPI a, unsigned *nbytes, int *sign );
2466 void mpi_set_buffer( MPI a, const byte *buffer, unsigned nbytes, int sign );
2467
2468 #define log_mpidump g10_log_mpidump
2469
2470 /*-- mpi-add.c --*/
2471 void mpi_add_ui(MPI w, MPI u, ulong v );
2472 void mpi_add(MPI w, MPI u, MPI v);
2473 void mpi_addm(MPI w, MPI u, MPI v, MPI m);
2474 void mpi_sub_ui(MPI w, MPI u, ulong v );
2475 void mpi_sub( MPI w, MPI u, MPI v);
2476 void mpi_subm( MPI w, MPI u, MPI v, MPI m);
2477
2478 /*-- mpi-mul.c --*/
2479 void mpi_mul_ui(MPI w, MPI u, ulong v );
2480 void mpi_mul_2exp( MPI w, MPI u, ulong cnt);
2481 void mpi_mul( MPI w, MPI u, MPI v);
2482 void mpi_mulm( MPI w, MPI u, MPI v, MPI m);
2483
2484 /*-- mpi-div.c --*/
2485 ulong mpi_fdiv_r_ui( MPI rem, MPI dividend, ulong divisor );
2486 void mpi_fdiv_r( MPI rem, MPI dividend, MPI divisor );
2487 void mpi_fdiv_q( MPI quot, MPI dividend, MPI divisor );
2488 void mpi_fdiv_qr( MPI quot, MPI rem, MPI dividend, MPI divisor );
2489 void mpi_tdiv_r( MPI rem, MPI num, MPI den);
2490 void mpi_tdiv_qr( MPI quot, MPI rem, MPI num, MPI den);
2491 void mpi_tdiv_q_2exp( MPI w, MPI u, unsigned count );
2492 int mpi_divisible_ui(MPI dividend, ulong divisor );
2493
2494 /*-- mpi-gcd.c --*/
2495 int mpi_gcd( MPI g, MPI a, MPI b );
2496
2497 /*-- mpi-pow.c --*/
2498 void mpi_pow( MPI w, MPI u, MPI v);
2499 void mpi_powm( MPI res, MPI base, MPI exponent, MPI mod);
2500
2501 /*-- mpi-mpow.c --*/
2502 void mpi_mulpowm( MPI res, MPI *basearray, MPI *exparray, MPI mod);
2503
2504 /*-- mpi-cmp.c --*/
2505 int mpi_cmp_ui( MPI u, ulong v );
2506 int mpi_cmp( MPI u, MPI v );
2507
2508 /*-- mpi-scan.c --*/
2509 int mpi_getbyte( MPI a, unsigned idx );
2510 void mpi_putbyte( MPI a, unsigned idx, int value );
2511 unsigned mpi_trailing_zeros( MPI a );
2512
2513 /*-- mpi-bit.c --*/
2514 void mpi_normalize( MPI a );
2515 unsigned mpi_get_nbits( MPI a );
2516 int mpi_test_bit( MPI a, unsigned n );
2517 void mpi_set_bit( MPI a, unsigned n );
2518 void mpi_set_highbit( MPI a, unsigned n );
2519 void mpi_clear_highbit( MPI a, unsigned n );
2520 void mpi_clear_bit( MPI a, unsigned n );
2521 void mpi_rshift( MPI x, MPI a, unsigned n );
2522
2523 /*-- mpi-inv.c --*/
2524 void mpi_invm( MPI x, MPI u, MPI v );
2525
2526 #endif /*G10_MPI_H*/
-
+ FAB4D9725D153347B3E67DCBC53ED25F5F8CD8149D35B17F11CE06CD62A825368F95B95F65F394395CEBE34BAA02AFD4F0B331D3019BA6E8B0DB73A947A7878A
smg_comms/mpi/include/types.h
(0 . 0)(1 . 138)
2531 /* types.h - some common typedefs
2532 * Modified by No Such Labs. (C) 2015. See README.
2533 *
2534 * This file was originally part of Gnu Privacy Guard (GPG), ver. 1.4.10,
2535 * SHA256(gnupg-1.4.10.tar.gz):
2536 * 0bfd74660a2f6cedcf7d8256db4a63c996ffebbcdc2cf54397bfb72878c5a85a
2537 * (C) 1994-2005 Free Software Foundation, Inc.
2538 *
2539 * This program is free software: you can redistribute it and/or modify
2540 * it under the terms of the GNU General Public License as published by
2541 * the Free Software Foundation, either version 3 of the License, or
2542 * (at your option) any later version.
2543 *
2544 * This program is distributed in the hope that it will be useful,
2545 * but WITHOUT ANY WARRANTY; without even the implied warranty of
2546 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2547 * GNU General Public License for more details.
2548 *
2549 * You should have received a copy of the GNU General Public License
2550 * along with this program. If not, see <http://www.gnu.org/licenses/>.
2551 */
2552
2553 #ifndef G10_TYPES_H
2554 #define G10_TYPES_H
2555
2556 #ifdef HAVE_INTTYPES_H
2557 /* For uint64_t */
2558 #include <inttypes.h>
2559 #endif
2560
2561 /* The AC_CHECK_SIZEOF() in configure fails for some machines.
2562 * we provide some fallback values here */
2563 #if !SIZEOF_UNSIGNED_SHORT
2564 #undef SIZEOF_UNSIGNED_SHORT
2565 #define SIZEOF_UNSIGNED_SHORT 2
2566 #endif
2567 #if !SIZEOF_UNSIGNED_INT
2568 #undef SIZEOF_UNSIGNED_INT
2569 #define SIZEOF_UNSIGNED_INT 4
2570 #endif
2571 #if !SIZEOF_UNSIGNED_LONG
2572 #undef SIZEOF_UNSIGNED_LONG
2573 #define SIZEOF_UNSIGNED_LONG 4
2574 #endif
2575
2576
2577 #include <sys/types.h>
2578
2579
2580 #ifndef HAVE_BYTE_TYPEDEF
2581 #undef byte /* maybe there is a macro with this name */
2582 typedef unsigned char byte;
2583 #define HAVE_BYTE_TYPEDEF
2584 #endif
2585
2586 #ifndef HAVE_USHORT_TYPEDEF
2587 #undef ushort /* maybe there is a macro with this name */
2588 typedef unsigned short ushort;
2589 #define HAVE_USHORT_TYPEDEF
2590 #endif
2591
2592 #ifndef HAVE_ULONG_TYPEDEF
2593 #undef ulong /* maybe there is a macro with this name */
2594 typedef unsigned long ulong;
2595 #define HAVE_ULONG_TYPEDEF
2596 #endif
2597
2598 #ifndef HAVE_U16_TYPEDEF
2599 #undef u16 /* maybe there is a macro with this name */
2600 #if SIZEOF_UNSIGNED_INT == 2
2601 typedef unsigned int u16;
2602 #elif SIZEOF_UNSIGNED_SHORT == 2
2603 typedef unsigned short u16;
2604 #else
2605 #error no typedef for u16
2606 #endif
2607 #define HAVE_U16_TYPEDEF
2608 #endif
2609
2610 #ifndef HAVE_U32_TYPEDEF
2611 #undef u32 /* maybe there is a macro with this name */
2612 #if SIZEOF_UNSIGNED_INT == 4
2613 typedef unsigned int u32;
2614 #elif SIZEOF_UNSIGNED_LONG == 4
2615 typedef unsigned long u32;
2616 #else
2617 #error no typedef for u32
2618 #endif
2619 #define HAVE_U32_TYPEDEF
2620 #endif
2621
2622 /****************
2623 * Warning: Some systems segfault when this u64 typedef and
2624 * the dummy code in cipher/md.c is not available. Examples are
2625 * Solaris and IRIX.
2626 */
2627 #ifndef HAVE_U64_TYPEDEF
2628 #undef u64 /* maybe there is a macro with this name */
2629 #if SIZEOF_UINT64_T == 8
2630 typedef uint64_t u64;
2631 #define U64_C(c) (UINT64_C(c))
2632 #define HAVE_U64_TYPEDEF
2633 #elif SIZEOF_UNSIGNED_INT == 8
2634 typedef unsigned int u64;
2635 #define U64_C(c) (c ## U)
2636 #define HAVE_U64_TYPEDEF
2637 #elif SIZEOF_UNSIGNED_LONG == 8
2638 typedef unsigned long u64;
2639 #define U64_C(c) (c ## UL)
2640 #define HAVE_U64_TYPEDEF
2641 #elif SIZEOF_UNSIGNED_LONG_LONG == 8
2642 typedef unsigned long long u64;
2643 #define U64_C(c) (c ## ULL)
2644 #define HAVE_U64_TYPEDEF
2645 #endif
2646 #endif
2647
2648 typedef union {
2649 int a;
2650 short b;
2651 char c[1];
2652 long d;
2653 #ifdef HAVE_U64_TYPEDEF
2654 u64 e;
2655 #endif
2656 float f;
2657 double g;
2658 } PROPERLY_ALIGNED_TYPE;
2659
2660 struct string_list {
2661 struct string_list *next;
2662 unsigned int flags;
2663 char d[1];
2664 };
2665 typedef struct string_list *STRLIST;
2666 typedef struct string_list *strlist_t;
2667
2668 #endif /*G10_TYPES_H*/
-
+ 9CB4E6A599501CCB7615C4DA88439D29C483B03D85BA4FC5A02C2B2FBF2920AEDE4E99F0438D86802183B05F3A113CA597A676B18D373F2D5E39D9D6F65553B2
smg_comms/mpi/include/util.h
(0 . 0)(1 . 86)
2673 /* util.h
2674 * Modified by No Such Labs. (C) 2015. See README.
2675 *
2676 * This file was originally part of Gnu Privacy Guard (GPG), ver. 1.4.10,
2677 * SHA256(gnupg-1.4.10.tar.gz):
2678 * 0bfd74660a2f6cedcf7d8256db4a63c996ffebbcdc2cf54397bfb72878c5a85a
2679 * (C) 1994-2005 Free Software Foundation, Inc.
2680 *
2681 * This program is free software: you can redistribute it and/or modify
2682 * it under the terms of the GNU General Public License as published by
2683 * the Free Software Foundation, either version 3 of the License, or
2684 * (at your option) any later version.
2685 *
2686 * This program is distributed in the hope that it will be useful,
2687 * but WITHOUT ANY WARRANTY; without even the implied warranty of
2688 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2689 * GNU General Public License for more details.
2690 *
2691 * You should have received a copy of the GNU General Public License
2692 * along with this program. If not, see <http://www.gnu.org/licenses/>.
2693 */
2694
2695 #ifndef G10_UTIL_H
2696 #define G10_UTIL_H
2697
2698 #if defined (_WIN32) || defined (__CYGWIN32__)
2699 #include <stdarg.h>
2700 #endif
2701
2702 #include "types.h"
2703 #include "types.h"
2704 #include "mpi.h"
2705
2706 #define log_hexdump printf
2707 #define log_bug printf
2708 #define log_bug0 printf
2709 #define log_fatal printf
2710 #define log_error printf
2711 #define log_info printf
2712 #define log_warning printf
2713 #define log_debug printf
2714
2715 #define g10_log_print_prefix printf
2716
2717
2718 #ifndef HAVE_MEMMOVE
2719 #define memmove(d, s, n) bcopy((s), (d), (n))
2720 #endif
2721
2722
2723 /**** other missing stuff ****/
2724 #ifndef HAVE_ATEXIT /* For SunOS */
2725 #define atexit(a) (on_exit((a),0))
2726 #endif
2727
2728 #ifndef HAVE_RAISE
2729 #define raise(a) kill(getpid(), (a))
2730 #endif
2731
2732 /******** some macros ************/
2733 #ifndef STR
2734 #define STR(v) #v
2735 #endif
2736 #define STR2(v) STR(v)
2737 #define DIM(v) (sizeof(v)/sizeof((v)[0]))
2738 #define DIMof(type,member) DIM(((type *)0)->member)
2739
2740 #define wipememory2(_ptr,_set,_len) do { volatile char *_vptr=(volatile char *)(_ptr); size_t _vlen=(_len); while(_vlen) { *_vptr=(_set); _vptr++; _vlen--; } } while(0)
2741 #define wipememory(_ptr,_len) wipememory2(_ptr,0,_len)
2742
2743 /*-- macros to replace ctype ones and avoid locale problems --*/
2744 #define spacep(p) (*(p) == ' ' || *(p) == '\t')
2745 #define digitp(p) (*(p) >= '0' && *(p) <= '9')
2746 #define hexdigitp(a) (digitp (a) \
2747 || (*(a) >= 'A' && *(a) <= 'F') \
2748 || (*(a) >= 'a' && *(a) <= 'f'))
2749 /* the atoi macros assume that the buffer has only valid digits */
2750 #define atoi_1(p) (*(p) - '0' )
2751 #define atoi_2(p) ((atoi_1(p) * 10) + atoi_1((p)+1))
2752 #define atoi_4(p) ((atoi_2(p) * 100) + atoi_2((p)+2))
2753 #define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \
2754 *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10))
2755 #define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1))
2756
2757
2758 #endif /*G10_UTIL_H*/
-
+ 739F6960D138E5AB2EB53F41872BEF6DE1A66EE43161B6B8A69D12849F13332E48DB2392566A8736D6B2BF7272DFC01AA2BFE927D917F152BE75AE821DE1AFD6
smg_comms/mpi/memory.c
(0 . 0)(1 . 671)
2763 /* memory.c - memory allocation
2764 * Modified by No Such Labs. (C) 2015. See README.
2765 *
2766 * This file was originally part of Gnu Privacy Guard (GPG), ver. 1.4.10,
2767 * SHA256(gnupg-1.4.10.tar.gz):
2768 * 0bfd74660a2f6cedcf7d8256db4a63c996ffebbcdc2cf54397bfb72878c5a85a
2769 * (C) 1994-2005 Free Software Foundation, Inc.
2770 *
2771 * This program is free software: you can redistribute it and/or modify
2772 * it under the terms of the GNU General Public License as published by
2773 * the Free Software Foundation, either version 3 of the License, or
2774 * (at your option) any later version.
2775 *
2776 * This program is distributed in the hope that it will be useful,
2777 * but WITHOUT ANY WARRANTY; without even the implied warranty of
2778 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2779 * GNU General Public License for more details.
2780 *
2781 * You should have received a copy of the GNU General Public License
2782 * along with this program. If not, see <http://www.gnu.org/licenses/>.
2783 */
2784
2785 /* We use our own memory allocation functions instead of plain malloc(),
2786 * so that we can provide some special enhancements:
2787 * a) functions to provide memory from a secure memory.
2788 * b) by looking at the requested allocation size we
2789 * can reuse memory very quickly (e.g. MPI storage)
2790 * (really needed?)
2791 * c) memory usage reporting if compiled with M_DEBUG
2792 * d) memory checking if compiled with M_GUARD
2793 */
2794
2795 #include <stdio.h>
2796 #include <stdlib.h>
2797 #include <stdarg.h>
2798 #include <string.h>
2799
2800 #include "knobs.h"
2801 #include "types.h"
2802 #include "memory.h"
2803 #include "util.h"
2804
2805 #define MAGIC_NOR_BYTE 0x55
2806 #define MAGIC_SEC_BYTE 0xcc
2807 #define MAGIC_END_BYTE 0xaa
2808
2809 /* This is a very crude alignment check which does not work on all CPUs
2810 * IIRC, I once introduced it for testing on an Alpha. We should better
2811 * replace this guard stuff with one provided by a modern malloc library
2812 */
2813 #if SIZEOF_UNSIGNED_LONG == 8
2814 #define EXTRA_ALIGN 4
2815 #else
2816 #define EXTRA_ALIGN 0
2817 #endif
2818
2819 #if defined(M_DEBUG) || defined(M_GUARD)
2820 static void membug( const char *fmt, ... );
2821 #endif
2822
2823 #ifdef M_DEBUG
2824
2825 #ifndef M_GUARD
2826 #define M_GUARD 1
2827 #endif
2828 #undef xmalloc
2829 #undef xtrymalloc
2830 #undef xmalloc_clear
2831 #undef xmalloc_secure
2832 #undef xmalloc_secure_clear
2833 #undef xrealloc
2834 #undef xfree
2835 #undef m_check
2836 #undef xstrdup
2837 #undef xtrystrdup
2838 #define FNAME(a) m_debug_ ##a
2839 #define FNAMEX(a) m_debug_ ##a
2840 #define FNAMEXM(a) m_debug_ ##a
2841 #define FNAMEPRT , const char *info
2842 #define FNAMEARG , info
2843
2844 #define store_len(p,n,m) do { add_entry(p,n,m, \
2845 info, __FUNCTION__); } while(0)
2846 #else
2847 #define FNAME(a) m_ ##a
2848 #define FNAMEX(a) x ##a
2849 #define FNAMEXM(a) xm ##a
2850 #define FNAMEPRT
2851 #define FNAMEARG
2852 #define store_len(p,n,m) do { ((byte*)p)[EXTRA_ALIGN+0] = n; \
2853 ((byte*)p)[EXTRA_ALIGN+1] = n >> 8 ; \
2854 ((byte*)p)[EXTRA_ALIGN+2] = n >> 16 ; \
2855 ((byte*)p)[EXTRA_ALIGN+3] = m? MAGIC_SEC_BYTE \
2856 : MAGIC_NOR_BYTE; \
2857 } while(0)
2858 #endif
2859
2860
2861 #ifdef M_GUARD
2862 static long used_memory;
2863 #endif
2864
2865 #ifdef M_DEBUG /* stuff used for memory debuging */
2866
2867 struct info_entry {
2868 struct info_entry *next;
2869 unsigned count; /* call count */
2870 const char *info; /* the reference to the info string */
2871 };
2872
2873 struct memtbl_entry {
2874 const void *user_p; /* for reference: the pointer given to the user */
2875 size_t user_n; /* length requested by the user */
2876 struct memtbl_entry *next; /* to build a list of unused entries */
2877 const struct info_entry *info; /* points into the table with */
2878 /* the info strings */
2879 unsigned inuse:1; /* this entry is in use */
2880 unsigned count:31;
2881 };
2882
2883
2884 #define INFO_BUCKETS 53
2885 #define info_hash(p) ( *(u32*)((p)) % INFO_BUCKETS )
2886 static struct info_entry *info_strings[INFO_BUCKETS]; /* hash table */
2887
2888 static struct memtbl_entry *memtbl; /* the table with the memory info */
2889 static unsigned memtbl_size; /* number of allocated entries */
2890 static unsigned memtbl_len; /* number of used entries */
2891 static struct memtbl_entry *memtbl_unused;/* to keep track of unused entries */
2892
2893 static void dump_table_at_exit(void);
2894 static void dump_table(void);
2895 static void check_allmem( const char *info );
2896
2897 /****************
2898 * Put the new P into the debug table and return a pointer to the table entry.
2899 * mode is true for security. BY is the name of the function which called us.
2900 */
2901 static void
2902 add_entry( byte *p, unsigned n, int mode, const char *info, const char *by )
2903 {
2904 unsigned index;
2905 struct memtbl_entry *e;
2906 struct info_entry *ie;
2907
2908 if( memtbl_len < memtbl_size )
2909 index = memtbl_len++;
2910 else {
2911 struct memtbl_entry *e;
2912 /* look for a used entry in the table. We take the first one,
2913 * so that freed entries remain as long as possible in the table
2914 * (free appends a new one)
2915 */
2916 if( (e = memtbl_unused) ) {
2917 index = e - memtbl;
2918 memtbl_unused = e->next;
2919 e->next = NULL;
2920 }
2921 else { /* no free entries in the table: extend the table */
2922 if( !memtbl_size ) { /* first time */
2923 memtbl_size = 100;
2924 if( !(memtbl = calloc( memtbl_size, sizeof *memtbl )) )
2925 membug("memory debug table malloc failed\n");
2926 index = 0;
2927 memtbl_len = 1;
2928 atexit( dump_table_at_exit );
2929 }
2930 else { /* realloc */
2931 unsigned n = memtbl_size / 4; /* enlarge by 25% */
2932 if(!(memtbl = realloc(memtbl, (memtbl_size+n)*sizeof *memtbl)))
2933 membug("memory debug table realloc failed\n");
2934 memset(memtbl+memtbl_size, 0, n*sizeof *memtbl );
2935 memtbl_size += n;
2936 index = memtbl_len++;
2937 }
2938 }
2939 }
2940 e = memtbl+index;
2941 if( e->inuse )
2942 membug("Ooops: entry %u is flagged as in use\n", index);
2943 e->user_p = p + EXTRA_ALIGN + 4;
2944 e->user_n = n;
2945 e->count++;
2946 if( e->next )
2947 membug("Ooops: entry is in free entry list\n");
2948 /* do we already have this info string */
2949 for( ie = info_strings[info_hash(info)]; ie; ie = ie->next )
2950 if( ie->info == info )
2951 break;
2952 if( !ie ) { /* no: make a new entry */
2953 if( !(ie = malloc( sizeof *ie )) )
2954 membug("can't allocate info entry\n");
2955 ie->next = info_strings[info_hash(info)];
2956 info_strings[info_hash(info)] = ie;
2957 ie->info = info;
2958 ie->count = 0;
2959 }
2960 ie->count++;
2961 e->info = ie;
2962 e->inuse = 1;
2963
2964 /* put the index at the start of the memory */
2965 p[EXTRA_ALIGN+0] = index;
2966 p[EXTRA_ALIGN+1] = index >> 8 ;
2967 p[EXTRA_ALIGN+2] = index >> 16 ;
2968 p[EXTRA_ALIGN+3] = mode? MAGIC_SEC_BYTE : MAGIC_NOR_BYTE ;
2969 if( DBG_MEMORY )
2970 log_debug( "%s allocates %u bytes using %s\n", info, e->user_n, by );
2971 }
2972
2973
2974
2975 /****************
2976 * Check that the memory block is correct. The magic byte has already been
2977 * checked. Checks which are done here:
2978 * - see whether the index points into our memory table
2979 * - see whether P is the same as the one stored in the table
2980 * - see whether we have already freed this block.
2981 */
2982 struct memtbl_entry *
2983 check_mem( const byte *p, const char *info )
2984 {
2985 unsigned n;
2986 struct memtbl_entry *e;
2987
2988 n = p[EXTRA_ALIGN+0];
2989 n |= p[EXTRA_ALIGN+1] << 8;
2990 n |= p[EXTRA_ALIGN+2] << 16;
2991
2992 if( n >= memtbl_len )
2993 membug("memory at %p corrupted: index=%u table_len=%u (%s)\n",
2994 p+EXTRA_ALIGN+4, n, memtbl_len, info );
2995 e = memtbl+n;
2996
2997 if( e->user_p != p+EXTRA_ALIGN+4 )
2998 membug("memory at %p corrupted: reference mismatch (%s)\n",
2999 p+EXTRA_ALIGN+4, info );
3000 if( !e->inuse )
3001 membug("memory at %p corrupted: marked as free (%s)\n",
3002 p+EXTRA_ALIGN+4, info );
3003
3004 if( !(p[EXTRA_ALIGN+3] == MAGIC_NOR_BYTE
3005 || p[EXTRA_ALIGN+3] == MAGIC_SEC_BYTE) )
3006 membug("memory at %p corrupted: underflow=%02x (%s)\n",
3007 p+EXTRA_ALIGN+4, p[EXTRA_ALIGN+3], info );
3008 if( p[EXTRA_ALIGN+4+e->user_n] != MAGIC_END_BYTE )
3009 membug("memory at %p corrupted: overflow=%02x (%s)\n",
3010 p+EXTRA_ALIGN+4, p[EXTRA_ALIGN+4+e->user_n], info );
3011 return e;
3012 }
3013
3014
3015 /****************
3016 * free the entry and the memory (replaces free)
3017 */
3018 static void
3019 free_entry( byte *p, const char *info )
3020 {
3021 struct memtbl_entry *e, *e2;
3022
3023 check_allmem("add_entry");
3024
3025 e = check_mem(p, info);
3026 if( DBG_MEMORY )
3027 log_debug( "%s frees %u bytes alloced by %s\n",
3028 info, e->user_n, e->info->info );
3029 if( !e->inuse ) {
3030 if( e->user_p == p + EXTRA_ALIGN+ 4 )
3031 membug("freeing an already freed pointer at %p\n", p+EXTRA_ALIGN+4 );
3032 else
3033 membug("freeing pointer %p which is flagged as freed\n", p+EXTRA_ALIGN+4 );
3034 }
3035
3036 e->inuse = 0;
3037 e->next = NULL;
3038 if( !memtbl_unused )
3039 memtbl_unused = e;
3040 else {
3041 for(e2=memtbl_unused; e2->next; e2 = e2->next )
3042 ;
3043 e2->next = e;
3044 }
3045 if( m_is_secure(p+EXTRA_ALIGN+4) )
3046 secmem_free(p);
3047 else {
3048 memset(p,'f', e->user_n+5);
3049 free(p);
3050 }
3051 }
3052
3053 static void
3054 dump_entry(struct memtbl_entry *e )
3055 {
3056 unsigned n = e - memtbl;
3057
3058 fprintf(stderr, "mem %4u%c %5u %p %5u %s (%u)\n",
3059 n, e->inuse?'a':'u', e->count, e->user_p, e->user_n,
3060 e->info->info, e->info->count );
3061
3062
3063 }
3064
3065
3066 static void
3067 dump_table_at_exit( void)
3068 {
3069 if( DBG_MEMSTAT )
3070 dump_table();
3071 }
3072
3073 static void
3074 dump_table( void)
3075 {
3076 unsigned n;
3077 struct memtbl_entry *e;
3078 ulong sum = 0, chunks =0;
3079
3080 for( e = memtbl, n = 0; n < memtbl_len; n++, e++ ) {
3081 if(e->inuse) {
3082 dump_entry(e);
3083 sum += e->user_n;
3084 chunks++;
3085 }
3086 }
3087 fprintf(stderr, " memory used: %8lu bytes in %ld chunks\n",
3088 sum, chunks );
3089 }
3090
3091
3092 static void
3093 check_allmem( const char *info )
3094 {
3095 unsigned n;
3096 struct memtbl_entry *e;
3097
3098 for( e = memtbl, n = 0; n < memtbl_len; n++, e++ ) {
3099 if( e->inuse ) {
3100 check_mem(e->user_p-4-EXTRA_ALIGN, info);
3101 }
3102 }
3103 }
3104
3105 #endif /* M_DEBUG */
3106
3107 #if defined(M_DEBUG) || defined(M_GUARD)
3108 static void
3109 membug( const char *fmt, ... )
3110 {
3111 va_list arg_ptr ;
3112
3113 fprintf(stderr, "\nMemory Error: " ) ;
3114 va_start( arg_ptr, fmt ) ;
3115 vfprintf(stderr,fmt,arg_ptr) ;
3116 va_end(arg_ptr);
3117 fflush(stderr);
3118 #ifdef M_DEBUG
3119 if( DBG_MEMSTAT )
3120 dump_table();
3121 #endif
3122 abort();
3123 }
3124 #endif
3125
3126 void
3127 m_print_stats( const char *prefix )
3128 {
3129 #ifdef M_DEBUG
3130 unsigned n;
3131 struct memtbl_entry *e;
3132 ulong sum = 0, chunks =0;
3133
3134 for( e = memtbl, n = 0; n < memtbl_len; n++, e++ ) {
3135 if(e->inuse) {
3136 sum += e->user_n;
3137 chunks++;
3138 }
3139 }
3140
3141 log_debug( "%s%smemstat: %8lu bytes in %ld chunks used\n",
3142 prefix? prefix:"", prefix? ": ":"", sum, chunks );
3143 #elif defined(M_GUARD)
3144 log_debug( "%s%smemstat: %8ld bytes\n",
3145 prefix? prefix:"", prefix? ": ":"", used_memory );
3146 #endif
3147 }
3148
3149 void
3150 m_dump_table( const char *prefix )
3151 {
3152 #ifdef M_DEBUG
3153 fprintf(stderr,"Memory-Table-Dump: %s\n", prefix);
3154 dump_table();
3155 #endif
3156 m_print_stats( prefix );
3157 }
3158
3159
3160 static void
3161 out_of_core(size_t n, int secure)
3162 {
3163 log_error ("out of %s memory while allocating %u bytes\n",
3164 secure? "secure":"" ,(unsigned)n );
3165 if (secure) {
3166 /*secmem_dump_stats ();*/
3167 log_info ("(this may be caused by too many secret keys used "
3168 "simultaneously or due to excessive large key sizes)\n");
3169 }
3170 exit(2);
3171 }
3172
3173 /****************
3174 * Allocate memory of size n.
3175 * This function gives up if we do not have enough memory
3176 */
3177 void *
3178 FNAMEXM(alloc)( size_t n FNAMEPRT )
3179 {
3180 char *p;
3181
3182 #ifdef M_GUARD
3183 if(!n)
3184 out_of_core(n,0); /* should never happen */
3185 if( !(p = malloc( n + EXTRA_ALIGN+5 )) )
3186 out_of_core(n,0);
3187 store_len(p,n,0);
3188 used_memory += n;
3189 p[4+EXTRA_ALIGN+n] = MAGIC_END_BYTE;
3190 return p+EXTRA_ALIGN+4;
3191 #else
3192 /* mallocing zero bytes is undefined by ISO-C, so we better make
3193 sure that it won't happen */
3194 if (!n)
3195 n = 1;
3196 if( !(p = malloc( n )) )
3197 out_of_core(n,0);
3198 return p;
3199 #endif
3200 }
3201
3202 /* Allocate memory of size n. This function returns NULL if we do not
3203 have enough memory. */
3204 void *
3205 FNAMEX(trymalloc)(size_t n FNAMEPRT)
3206 {
3207 #ifdef M_GUARD
3208 char *p;
3209
3210 if (!n)
3211 n = 1;
3212 p = malloc (n + EXTRA_ALIGN+5);
3213 if (!p)
3214 return NULL;
3215 store_len(p,n,0);
3216 used_memory += n;
3217 p[4+EXTRA_ALIGN+n] = MAGIC_END_BYTE;
3218 return p+EXTRA_ALIGN+4;
3219 #else
3220 /* Mallocing zero bytes is undefined by ISO-C, so we better make
3221 sure that it won't happen. */
3222 return malloc (n? n: 1);
3223 #endif
3224 }
3225
3226 /****************
3227 * Allocate memory of size n from the secure memory pool.
3228 * This function gives up if we do not have enough memory
3229 */
3230 void *
3231 FNAMEXM(alloc_secure)( size_t n FNAMEPRT )
3232 {
3233 char *p;
3234
3235 #ifdef M_GUARD
3236 if(!n)
3237 out_of_core(n,1); /* should never happen */
3238 if( !(p = secmem_malloc( n +EXTRA_ALIGN+ 5 )) )
3239 out_of_core(n,1);
3240 store_len(p,n,1);
3241 p[4+EXTRA_ALIGN+n] = MAGIC_END_BYTE;
3242 return p+EXTRA_ALIGN+4;
3243 #else
3244 /* mallocing zero bytes is undefined by ISO-C, so we better make
3245 sure that it won't happen */
3246 if (!n)
3247 n = 1;
3248 if( !(p = secmem_malloc( n )) )
3249 out_of_core(n,1);
3250 return p;
3251 #endif
3252 }
3253
3254 void *
3255 FNAMEXM(alloc_clear)( size_t n FNAMEPRT )
3256 {
3257 void *p;
3258 p = FNAMEXM(alloc)( n FNAMEARG );
3259 memset(p, 0, n );
3260 return p;
3261 }
3262
3263 void *
3264 FNAMEXM(alloc_secure_clear)( size_t n FNAMEPRT)
3265 {
3266 void *p;
3267 p = FNAMEXM(alloc_secure)( n FNAMEARG );
3268 memset(p, 0, n );
3269 return p;
3270 }
3271
3272
3273 /****************
3274 * realloc and clear the old space
3275 */
3276 void *
3277 FNAMEX(realloc)( void *a, size_t n FNAMEPRT )
3278 {
3279 void *b;
3280
3281 #ifdef M_GUARD
3282 if( a ) {
3283 #error "--enable-m-guard does not currently work"
3284 unsigned char *p = a;
3285 size_t len = m_size(a);
3286
3287 if( len >= n ) /* we don't shrink for now */
3288 return a;
3289 if( p[-1] == MAGIC_SEC_BYTE )
3290 b = FNAME(alloc_secure_clear)(n FNAMEARG);
3291 else
3292 b = FNAME(alloc_clear)(n FNAMEARG);
3293 FNAME(check)(NULL FNAMEARG);
3294 memcpy(b, a, len );
3295 FNAME(free)(p FNAMEARG);
3296 }
3297 else
3298 b = FNAME(alloc)(n FNAMEARG);
3299 #else
3300 if( m_is_secure(a) ) {
3301 if( !(b = secmexrealloc( a, n )) )
3302 out_of_core(n,1);
3303 }
3304 else {
3305 if( !(b = realloc( a, n )) )
3306 out_of_core(n,0);
3307 }
3308 #endif
3309
3310 return b;
3311 }
3312
3313
3314
3315 /****************
3316 * Free a pointer
3317 */
3318 void
3319 FNAMEX(free)( void *a FNAMEPRT )
3320 {
3321 byte *p = a;
3322
3323 if( !p )
3324 return;
3325 #ifdef M_DEBUG
3326 free_entry(p-EXTRA_ALIGN-4, info);
3327 #elif defined M_GUARD
3328 m_check(p);
3329 if( m_is_secure(a) )
3330 secmem_free(p-EXTRA_ALIGN-4);
3331 else {
3332 used_memory -= m_size(a);
3333 free(p-EXTRA_ALIGN-4);
3334 }
3335 #else
3336 if( m_is_secure(a) )
3337 secmem_free(p);
3338 else
3339 free(p);
3340 #endif
3341 }
3342
3343
3344 void
3345 FNAME(check)( const void *a FNAMEPRT )
3346 {
3347 #ifdef M_GUARD
3348 const byte *p = a;
3349
3350 #ifdef M_DEBUG
3351 if( p )
3352 check_mem(p-EXTRA_ALIGN-4, info);
3353 else
3354 check_allmem(info);
3355 #else
3356 if( !p )
3357 return;
3358 if( !(p[-1] == MAGIC_NOR_BYTE || p[-1] == MAGIC_SEC_BYTE) )
3359 membug("memory at %p corrupted (underflow=%02x)\n", p, p[-1] );
3360 else if( p[m_size(p)] != MAGIC_END_BYTE )
3361 membug("memory at %p corrupted (overflow=%02x)\n", p, p[-1] );
3362 #endif
3363 #endif
3364 }
3365
3366
3367 size_t
3368 m_size( const void *a )
3369 {
3370 #ifndef M_GUARD
3371 log_debug("dummy m_size called\n");
3372 return 0;
3373 #else
3374 const byte *p = a;
3375 size_t n;
3376
3377 #ifdef M_DEBUG
3378 n = check_mem(p-EXTRA_ALIGN-4, "m_size")->user_n;
3379 #else
3380 n = ((byte*)p)[-4];
3381 n |= ((byte*)p)[-3] << 8;
3382 n |= ((byte*)p)[-2] << 16;
3383 #endif
3384 return n;
3385 #endif
3386 }
3387
3388
3389 char *
3390 FNAMEX(strdup)( const char *a FNAMEPRT )
3391 {
3392 size_t n = strlen(a);
3393 char *p = FNAMEXM(alloc)(n+1 FNAMEARG);
3394 strcpy(p, a);
3395 return p;
3396 }
3397
3398 char *
3399 FNAMEX(trystrdup)(const char *a FNAMEPRT)
3400 {
3401 size_t n = strlen (a);
3402 char *p = FNAMEX(trymalloc)(n+1 FNAMEARG);
3403 if (p)
3404 strcpy (p, a);
3405 return p;
3406 }
3407
3408
3409 /* Wrapper around xmalloc_clear to take the usual 2 arguments of a
3410 calloc style function. */
3411 void *
3412 xcalloc (size_t n, size_t m)
3413 {
3414 size_t nbytes;
3415
3416 nbytes = n * m;
3417 if (m && nbytes / m != n)
3418 out_of_core (nbytes, 0);
3419 return xmalloc_clear (nbytes);
3420 }
3421
3422 /* Wrapper around xmalloc_csecure_lear to take the usual 2 arguments
3423 of a calloc style function. */
3424 void *
3425 xcalloc_secure (size_t n, size_t m)
3426 {
3427 size_t nbytes;
3428
3429 nbytes = n * m;
3430 if (m && nbytes / m != n)
3431 out_of_core (nbytes, 1);
3432 return xmalloc_secure_clear (nbytes);
3433 }
-
+ 1D6A019FD026BF2712BE8E24EB9BAC995524336DF8EA4BF08878BDA3F95A943139E68381347974FEEA6DDAF3748ECD837FD698875324CB16C2AF13AF1E54BAA0
smg_comms/mpi/mpi-add.c
(0 . 0)(1 . 240)
3438 /* mpi-add.c - MPI functions
3439 * Modified by No Such Labs. (C) 2015. See README.
3440 *
3441 * This file was originally part of Gnu Privacy Guard (GPG), ver. 1.4.10,
3442 * SHA256(gnupg-1.4.10.tar.gz):
3443 * 0bfd74660a2f6cedcf7d8256db4a63c996ffebbcdc2cf54397bfb72878c5a85a
3444 * (C) 1994-2005 Free Software Foundation, Inc.
3445 *
3446 * This program is free software: you can redistribute it and/or modify
3447 * it under the terms of the GNU General Public License as published by
3448 * the Free Software Foundation, either version 3 of the License, or
3449 * (at your option) any later version.
3450 *
3451 * This program is distributed in the hope that it will be useful,
3452 * but WITHOUT ANY WARRANTY; without even the implied warranty of
3453 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3454 * GNU General Public License for more details.
3455 *
3456 * You should have received a copy of the GNU General Public License
3457 * along with this program. If not, see <http://www.gnu.org/licenses/>.
3458 */
3459
3460 #include <stdio.h>
3461 #include <stdlib.h>
3462
3463 #include "knobs.h"
3464 #include "mpi-internal.h"
3465
3466
3467 /****************
3468 * Add the unsigned integer V to the mpi-integer U and store the
3469 * result in W. U and V may be the same.
3470 */
3471 void
3472 mpi_add_ui(MPI w, MPI u, unsigned long v )
3473 {
3474 mpi_ptr_t wp, up;
3475 mpi_size_t usize, wsize;
3476 int usign, wsign;
3477
3478 usize = u->nlimbs;
3479 usign = u->sign;
3480 wsign = 0;
3481
3482 /* If not space for W (and possible carry), increase space. */
3483 wsize = usize + 1;
3484 if( w->alloced < wsize )
3485 mpi_resize(w, wsize);
3486
3487 /* These must be after realloc (U may be the same as W). */
3488 up = u->d;
3489 wp = w->d;
3490
3491 if( !usize ) { /* simple */
3492 wp[0] = v;
3493 wsize = v? 1:0;
3494 }
3495 else if( !usign ) { /* mpi is not negative */
3496 mpi_limb_t cy;
3497 cy = mpihelp_add_1(wp, up, usize, v);
3498 wp[usize] = cy;
3499 wsize = usize + cy;
3500 }
3501 else { /* The signs are different. Need exact comparison to determine
3502 * which operand to subtract from which. */
3503 if( usize == 1 && up[0] < v ) {
3504 wp[0] = v - up[0];
3505 wsize = 1;
3506 }
3507 else {
3508 mpihelp_sub_1(wp, up, usize, v);
3509 /* Size can decrease with at most one limb. */
3510 wsize = usize - (wp[usize-1]==0);
3511 wsign = 1;
3512 }
3513 }
3514
3515 w->nlimbs = wsize;
3516 w->sign = wsign;
3517 }
3518
3519
3520 void
3521 mpi_add(MPI w, MPI u, MPI v)
3522 {
3523 mpi_ptr_t wp, up, vp;
3524 mpi_size_t usize, vsize, wsize;
3525 int usign, vsign, wsign;
3526
3527 if( u->nlimbs < v->nlimbs ) { /* Swap U and V. */
3528 usize = v->nlimbs;
3529 usign = v->sign;
3530 vsize = u->nlimbs;
3531 vsign = u->sign;
3532 wsize = usize + 1;
3533 RESIZE_IF_NEEDED(w, wsize);
3534 /* These must be after realloc (u or v may be the same as w). */
3535 up = v->d;
3536 vp = u->d;
3537 }
3538 else {
3539 usize = u->nlimbs;
3540 usign = u->sign;
3541 vsize = v->nlimbs;
3542 vsign = v->sign;
3543 wsize = usize + 1;
3544 RESIZE_IF_NEEDED(w, wsize);
3545 /* These must be after realloc (u or v may be the same as w). */
3546 up = u->d;
3547 vp = v->d;
3548 }
3549 wp = w->d;
3550 wsign = 0;
3551
3552 if( !vsize ) { /* simple */
3553 MPN_COPY(wp, up, usize );
3554 wsize = usize;
3555 wsign = usign;
3556 }
3557 else if( usign != vsign ) { /* different sign */
3558 /* This test is right since USIZE >= VSIZE */
3559 if( usize != vsize ) {
3560 mpihelp_sub(wp, up, usize, vp, vsize);
3561 wsize = usize;
3562 MPN_NORMALIZE(wp, wsize);
3563 wsign = usign;
3564 }
3565 else if( mpihelp_cmp(up, vp, usize) < 0 ) {
3566 mpihelp_sub_n(wp, vp, up, usize);
3567 wsize = usize;
3568 MPN_NORMALIZE(wp, wsize);
3569 if( !usign )
3570 wsign = 1;
3571 }
3572 else {
3573 mpihelp_sub_n(wp, up, vp, usize);
3574 wsize = usize;
3575 MPN_NORMALIZE(wp, wsize);
3576 if( usign )
3577 wsign = 1;
3578 }
3579 }
3580 else { /* U and V have same sign. Add them. */
3581 mpi_limb_t cy = mpihelp_add(wp, up, usize, vp, vsize);
3582 wp[usize] = cy;
3583 wsize = usize + cy;
3584 if( usign )
3585 wsign = 1;
3586 }
3587
3588 w->nlimbs = wsize;
3589 w->sign = wsign;
3590 }
3591
3592
3593 /****************
3594 * Subtract the unsigned integer V from the mpi-integer U and store the
3595 * result in W.
3596 */
3597 void
3598 mpi_sub_ui(MPI w, MPI u, unsigned long v )
3599 {
3600 mpi_ptr_t wp, up;
3601 mpi_size_t usize, wsize;
3602 int usign, wsign;
3603
3604 usize = u->nlimbs;
3605 usign = u->sign;
3606 wsign = 0;
3607
3608 /* If not space for W (and possible carry), increase space. */
3609 wsize = usize + 1;
3610 if( w->alloced < wsize )
3611 mpi_resize(w, wsize);
3612
3613 /* These must be after realloc (U may be the same as W). */
3614 up = u->d;
3615 wp = w->d;
3616
3617 if( !usize ) { /* simple */
3618 wp[0] = v;
3619 wsize = v? 1:0;
3620 wsign = 1;
3621 }
3622 else if( usign ) { /* mpi and v are negative */
3623 mpi_limb_t cy;
3624 cy = mpihelp_add_1(wp, up, usize, v);
3625 wp[usize] = cy;
3626 wsize = usize + cy;
3627 }
3628 else { /* The signs are different. Need exact comparison to determine
3629 * which operand to subtract from which. */
3630 if( usize == 1 && up[0] < v ) {
3631 wp[0] = v - up[0];
3632 wsize = 1;
3633 wsign = 1;
3634 }
3635 else {
3636 mpihelp_sub_1(wp, up, usize, v);
3637 /* Size can decrease with at most one limb. */
3638 wsize = usize - (wp[usize-1]==0);
3639 }
3640 }
3641
3642 w->nlimbs = wsize;
3643 w->sign = wsign;
3644 }
3645
3646 void
3647 mpi_sub(MPI w, MPI u, MPI v)
3648 {
3649 if( w == v ) {
3650 MPI vv = mpi_copy(v);
3651 vv->sign = !vv->sign;
3652 mpi_add( w, u, vv );
3653 mpi_free(vv);
3654 }
3655 else {
3656 /* fixme: this is not thread-save (we temp. modify v) */
3657 v->sign = !v->sign;
3658 mpi_add( w, u, v );
3659 v->sign = !v->sign;
3660 }
3661 }
3662
3663
3664 void
3665 mpi_addm( MPI w, MPI u, MPI v, MPI m)
3666 {
3667 mpi_add(w, u, v);
3668 mpi_fdiv_r( w, w, m );
3669 }
3670
3671 void
3672 mpi_subm( MPI w, MPI u, MPI v, MPI m)
3673 {
3674 mpi_sub(w, u, v);
3675 mpi_fdiv_r( w, w, m );
3676 }
3677
-
+ 36AA7BC45976C3792B00414443B35C0DE1C172B5D2DDF26FF62736CF8642F3D2260FD45216F075DA1024A27CED6E03004A41CC3A7508877462A7A06C11EA4339
smg_comms/mpi/mpi-bit.c
(0 . 0)(1 . 262)
3682 /* mpi-bit.c - MPI bit level fucntions
3683 * Modified by No Such Labs. (C) 2015. See README.
3684 *
3685 * This file was originally part of Gnu Privacy Guard (GPG), ver. 1.4.10,
3686 * SHA256(gnupg-1.4.10.tar.gz):
3687 * 0bfd74660a2f6cedcf7d8256db4a63c996ffebbcdc2cf54397bfb72878c5a85a
3688 * (C) 1994-2005 Free Software Foundation, Inc.
3689 *
3690 * This program is free software: you can redistribute it and/or modify
3691 * it under the terms of the GNU General Public License as published by
3692 * the Free Software Foundation, either version 3 of the License, or
3693 * (at your option) any later version.
3694 *
3695 * This program is distributed in the hope that it will be useful,
3696 * but WITHOUT ANY WARRANTY; without even the implied warranty of
3697 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3698 * GNU General Public License for more details.
3699 *
3700 * You should have received a copy of the GNU General Public License
3701 * along with this program. If not, see <http://www.gnu.org/licenses/>.
3702 */
3703
3704 #include <stdio.h>
3705 #include <stdlib.h>
3706 #include <assert.h>
3707
3708 #include "knobs.h"
3709 #include "mpi-internal.h"
3710 #include "longlong.h"
3711
3712
3713 #ifdef MPI_INTERNAL_NEED_CLZ_TAB
3714 #ifdef __STDC__
3715 const
3716 #endif
3717 unsigned char
3718 __clz_tab[] =
3719 {
3720 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
3721 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
3722 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
3723 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
3724 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
3725 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
3726 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
3727 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
3728 };
3729 #endif
3730
3731
3732 #define A_LIMB_1 ((mpi_limb_t)1)
3733
3734
3735 /****************
3736 * Sometimes we have MSL (most significant limbs) which are 0;
3737 * this is for some reasons not good, so this function removes them.
3738 */
3739 void
3740 mpi_normalize( MPI a )
3741 {
3742 if( mpi_is_opaque (a) )
3743 return;
3744
3745 for( ; a->nlimbs && !a->d[a->nlimbs-1]; a->nlimbs-- )
3746 ;
3747 }
3748
3749
3750
3751 /****************
3752 * Return the number of bits in A.
3753 */
3754 unsigned
3755 mpi_get_nbits( MPI a )
3756 {
3757 unsigned n;
3758
3759 mpi_normalize( a );
3760 if( a->nlimbs ) {
3761 mpi_limb_t alimb = a->d[a->nlimbs-1];
3762 if( alimb )
3763 count_leading_zeros( n, alimb );
3764 else
3765 n = BITS_PER_MPI_LIMB;
3766 n = BITS_PER_MPI_LIMB - n + (a->nlimbs-1) * BITS_PER_MPI_LIMB;
3767 }
3768 else
3769 n = 0;
3770 return n;
3771 }
3772
3773
3774 /****************
3775 * Test whether bit N is set.
3776 */
3777 int
3778 mpi_test_bit( MPI a, unsigned n )
3779 {
3780 unsigned limbno, bitno;
3781 mpi_limb_t limb;
3782
3783 limbno = n / BITS_PER_MPI_LIMB;
3784 bitno = n % BITS_PER_MPI_LIMB;
3785
3786 if( limbno >= a->nlimbs )
3787 return 0; /* too far left: this is a 0 */
3788 limb = a->d[limbno];
3789 return (limb & (A_LIMB_1 << bitno))? 1: 0;
3790 }
3791
3792
3793 /****************
3794 * Set bit N of A.
3795 */
3796 void
3797 mpi_set_bit( MPI a, unsigned n )
3798 {
3799 unsigned limbno, bitno;
3800
3801 limbno = n / BITS_PER_MPI_LIMB;
3802 bitno = n % BITS_PER_MPI_LIMB;
3803
3804 if( limbno >= a->nlimbs ) { /* resize */
3805 if( a->alloced >= limbno )
3806 mpi_resize(a, limbno+1 );
3807 a->nlimbs = limbno+1;
3808 }
3809 a->d[limbno] |= (A_LIMB_1<<bitno);
3810 }
3811
3812 /****************
3813 * Set bit N of A. and clear all bits above
3814 */
3815 void
3816 mpi_set_highbit( MPI a, unsigned n )
3817 {
3818 unsigned limbno, bitno;
3819
3820 limbno = n / BITS_PER_MPI_LIMB;
3821 bitno = n % BITS_PER_MPI_LIMB;
3822
3823 if( limbno >= a->nlimbs ) { /* resize */
3824 if( a->alloced >= limbno )
3825 mpi_resize(a, limbno+1 );
3826 a->nlimbs = limbno+1;
3827 }
3828 a->d[limbno] |= (A_LIMB_1<<bitno);
3829 for( bitno++; bitno < BITS_PER_MPI_LIMB; bitno++ )
3830 a->d[limbno] &= ~(A_LIMB_1 << bitno);
3831 a->nlimbs = limbno+1;
3832 }
3833
3834 /****************
3835 * clear bit N of A and all bits above
3836 */
3837 void
3838 mpi_clear_highbit( MPI a, unsigned n )
3839 {
3840 unsigned limbno, bitno;
3841
3842 limbno = n / BITS_PER_MPI_LIMB;
3843 bitno = n % BITS_PER_MPI_LIMB;
3844
3845 if( limbno >= a->nlimbs )
3846 return; /* not allocated, so no effect */
3847
3848 for( ; bitno < BITS_PER_MPI_LIMB; bitno++ )
3849 a->d[limbno] &= ~(A_LIMB_1 << bitno);
3850
3851 /* adjust nlimbs to clear any leading zero-value limbs (normalize) */
3852 a->nlimbs = limbno+1;
3853 for( ; a->nlimbs && !a->d[a->nlimbs-1]; a->nlimbs-- );
3854
3855 }
3856
3857 /****************
3858 * Clear bit N of A.
3859 */
3860 void
3861 mpi_clear_bit( MPI a, unsigned n )
3862 {
3863 unsigned limbno, bitno;
3864
3865 limbno = n / BITS_PER_MPI_LIMB;
3866 bitno = n % BITS_PER_MPI_LIMB;
3867
3868 if( limbno >= a->nlimbs )
3869 return; /* don't need to clear this bit, it's to far to left */
3870 a->d[limbno] &= ~(A_LIMB_1 << bitno);
3871 }
3872
3873
3874 /****************
3875 * Shift A by N bits to the right
3876 * FIXME: should use alloc_limb if X and A are same.
3877 */
3878 void
3879 mpi_rshift( MPI x, MPI a, unsigned n )
3880 {
3881 mpi_ptr_t xp;
3882 mpi_size_t xsize;
3883
3884 xsize = a->nlimbs;
3885 x->sign = a->sign;
3886 RESIZE_IF_NEEDED(x, xsize);
3887 xp = x->d;
3888
3889 if( xsize ) {
3890 mpihelp_rshift( xp, a->d, xsize, n);
3891 MPN_NORMALIZE( xp, xsize);
3892 }
3893 x->nlimbs = xsize;
3894 }
3895
3896
3897 /****************
3898 * Shift A by COUNT limbs to the left
3899 * This is used only within the MPI library
3900 */
3901 void
3902 mpi_lshift_limbs( MPI a, unsigned int count )
3903 {
3904 mpi_ptr_t ap = a->d;
3905 int n = a->nlimbs;
3906 int i;
3907
3908 if( !count || !n )
3909 return;
3910
3911 RESIZE_IF_NEEDED( a, n+count );
3912
3913 for( i = n-1; i >= 0; i-- )
3914 ap[i+count] = ap[i];
3915 for(i=0; i < count; i++ )
3916 ap[i] = 0;
3917 a->nlimbs += count;
3918 }
3919
3920
3921 /****************
3922 * Shift A by COUNT limbs to the right
3923 * This is used only within the MPI library
3924 */
3925 void
3926 mpi_rshift_limbs( MPI a, unsigned int count )
3927 {
3928 mpi_ptr_t ap = a->d;
3929 mpi_size_t n = a->nlimbs;
3930 unsigned int i;
3931
3932 if( count >= n ) {
3933 a->nlimbs = 0;
3934 return;
3935 }
3936
3937 for( i = 0; i < n - count; i++ )
3938 ap[i] = ap[i+count];
3939 ap[i] = 0;
3940 a->nlimbs -= count;
3941 }
3942
3943
-
+ 9225D6FAA31311EA2857E6C9A8AD497846F41ECA0BF07B0EBC7601B05251AF751E68226CE7BB6B9F261FB182A5BE9BB1A05AEE4F222764D2F9CA28BFC59CFA99
smg_comms/mpi/mpi-cmp.c
(0 . 0)(1 . 77)
3948 /* mpi-cmp.c - MPI functions
3949 * Modified by No Such Labs. (C) 2015. See README.
3950 *
3951 * This file was originally part of Gnu Privacy Guard (GPG), ver. 1.4.10,
3952 * SHA256(gnupg-1.4.10.tar.gz):
3953 * 0bfd74660a2f6cedcf7d8256db4a63c996ffebbcdc2cf54397bfb72878c5a85a
3954 * (C) 1994-2005 Free Software Foundation, Inc.
3955 *
3956 * This program is free software: you can redistribute it and/or modify
3957 * it under the terms of the GNU General Public License as published by
3958 * the Free Software Foundation, either version 3 of the License, or
3959 * (at your option) any later version.
3960 *
3961 * This program is distributed in the hope that it will be useful,
3962 * but WITHOUT ANY WARRANTY; without even the implied warranty of
3963 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3964 * GNU General Public License for more details.
3965 *
3966 * You should have received a copy of the GNU General Public License
3967 * along with this program. If not, see <http://www.gnu.org/licenses/>.
3968 */
3969
3970 #include <stdio.h>
3971 #include <stdlib.h>
3972
3973 #include "knobs.h"
3974 #include "mpi-internal.h"
3975
3976 int
3977 mpi_cmp_ui( MPI u, unsigned long v )
3978 {
3979 mpi_limb_t limb = v;
3980
3981 mpi_normalize( u );
3982 if( !u->nlimbs && !limb )
3983 return 0;
3984 if( u->sign )
3985 return -1;
3986 if( u->nlimbs > 1 )
3987 return 1;
3988
3989 if( u->d[0] == limb )
3990 return 0;
3991 else if( u->d[0] > limb )
3992 return 1;
3993 else
3994 return -1;
3995 }
3996
3997 int
3998 mpi_cmp( MPI u, MPI v )
3999 {
4000 mpi_size_t usize, vsize;
4001 int cmp;
4002
4003 mpi_normalize( u );
4004 mpi_normalize( v );
4005 usize = u->nlimbs;
4006 vsize = v->nlimbs;
4007 if( !u->sign && v->sign )
4008 return 1;
4009 if( u->sign && !v->sign )
4010 return -1;
4011 if( usize != vsize && !u->sign && !v->sign )
4012 return usize - vsize;
4013 if( usize != vsize && u->sign && v->sign )
4014 return vsize + usize;
4015 if( !usize )
4016 return 0;
4017 if( !(cmp=mpihelp_cmp( u->d, v->d, usize )) )
4018 return 0;
4019 if( (cmp < 0?1:0) == (u->sign?1:0))
4020 return 1;
4021 return -1;
4022 }
4023
4024
-
+ 4C816E02A36ADBCAE224E0F6ECBEF7D46811A2ADD9D33B677165936BEE0D5E8B4900490904C25E0EAE3E8616CC3BD7F7DF13269EA4ADDE641814BE563F820667
smg_comms/mpi/mpi-div.c
(0 . 0)(1 . 316)
4029 /* mpi-div.c - MPI functions
4030 * Modified by No Such Labs. (C) 2015. See README.
4031 *
4032 * This file was originally part of Gnu Privacy Guard (GPG), ver. 1.4.10,
4033 * SHA256(gnupg-1.4.10.tar.gz):
4034 * 0bfd74660a2f6cedcf7d8256db4a63c996ffebbcdc2cf54397bfb72878c5a85a
4035 * (C) 1994-2005 Free Software Foundation, Inc.
4036 *
4037 * This program is free software: you can redistribute it and/or modify
4038 * it under the terms of the GNU General Public License as published by
4039 * the Free Software Foundation, either version 3 of the License, or
4040 * (at your option) any later version.
4041 *
4042 * This program is distributed in the hope that it will be useful,
4043 * but WITHOUT ANY WARRANTY; without even the implied warranty of
4044 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4045 * GNU General Public License for more details.
4046 *
4047 * You should have received a copy of the GNU General Public License
4048 * along with this program. If not, see <http://www.gnu.org/licenses/>.
4049 */
4050
4051 #include <stdio.h>
4052 #include <stdlib.h>
4053
4054 #include "knobs.h"
4055 #include "mpi-internal.h"
4056 #include "longlong.h"
4057
4058
4059
4060 void
4061 mpi_fdiv_r( MPI rem, MPI dividend, MPI divisor )
4062 {
4063 int divisor_sign = divisor->sign;
4064 MPI temp_divisor = NULL;
4065
4066 /* We need the original value of the divisor after the remainder has been
4067 * preliminary calculated. We have to copy it to temporary space if it's
4068 * the same variable as REM. */
4069 if( rem == divisor ) {
4070 temp_divisor = mpi_copy( divisor );
4071 divisor = temp_divisor;
4072 }
4073
4074 mpi_tdiv_r( rem, dividend, divisor );
4075
4076 if( ((divisor_sign?1:0) ^ (dividend->sign?1:0)) && rem->nlimbs )
4077 mpi_add( rem, rem, divisor);
4078
4079 if( temp_divisor )
4080 mpi_free(temp_divisor);
4081 }
4082
4083
4084
4085 /****************
4086 * Division rounding the quotient towards -infinity.
4087 * The remainder gets the same sign as the denominator.
4088 * rem is optional
4089 */
4090
4091 ulong
4092 mpi_fdiv_r_ui( MPI rem, MPI dividend, ulong divisor )
4093 {
4094 mpi_limb_t rlimb;
4095
4096 rlimb = mpihelp_mod_1( dividend->d, dividend->nlimbs, divisor );
4097 if( rlimb && dividend->sign )
4098 rlimb = divisor - rlimb;
4099
4100 if( rem ) {
4101 rem->d[0] = rlimb;
4102 rem->nlimbs = rlimb? 1:0;
4103 }
4104 return rlimb;
4105 }
4106
4107
4108 void
4109 mpi_fdiv_q( MPI quot, MPI dividend, MPI divisor )
4110 {
4111 MPI tmp = mpi_alloc( mpi_get_nlimbs(quot) );
4112 mpi_fdiv_qr( quot, tmp, dividend, divisor);
4113 mpi_free(tmp);
4114 }
4115
4116 void
4117 mpi_fdiv_qr( MPI quot, MPI rem, MPI dividend, MPI divisor )
4118 {
4119 int divisor_sign = divisor->sign;
4120 MPI temp_divisor = NULL;
4121
4122 if( quot == divisor || rem == divisor ) {
4123 temp_divisor = mpi_copy( divisor );
4124 divisor = temp_divisor;
4125 }
4126
4127 mpi_tdiv_qr( quot, rem, dividend, divisor );
4128
4129 if( (divisor_sign ^ dividend->sign) && rem->nlimbs ) {
4130 mpi_sub_ui( quot, quot, 1 );
4131 mpi_add( rem, rem, divisor);
4132 }
4133
4134 if( temp_divisor )
4135 mpi_free(temp_divisor);
4136 }
4137
4138
4139 /* If den == quot, den needs temporary storage.
4140 * If den == rem, den needs temporary storage.
4141 * If num == quot, num needs temporary storage.
4142 * If den has temporary storage, it can be normalized while being copied,
4143 * i.e no extra storage should be allocated.
4144 */
4145
4146 void
4147 mpi_tdiv_r( MPI rem, MPI num, MPI den)
4148 {
4149 mpi_tdiv_qr(NULL, rem, num, den );
4150 }
4151
4152 void
4153 mpi_tdiv_qr( MPI quot, MPI rem, MPI num, MPI den)
4154 {
4155 mpi_ptr_t np, dp;
4156 mpi_ptr_t qp, rp;
4157 mpi_size_t nsize = num->nlimbs;
4158 mpi_size_t dsize = den->nlimbs;
4159 mpi_size_t qsize, rsize;
4160 mpi_size_t sign_remainder = num->sign;
4161 mpi_size_t sign_quotient = num->sign ^ den->sign;
4162 unsigned normalization_steps;
4163 mpi_limb_t q_limb;
4164 mpi_ptr_t marker[5];
4165 int markidx=0;
4166
4167 /* Ensure space is enough for quotient and remainder.
4168 * We need space for an extra limb in the remainder, because it's
4169 * up-shifted (normalized) below. */
4170 rsize = nsize + 1;
4171 mpi_resize( rem, rsize);
4172
4173 qsize = rsize - dsize; /* qsize cannot be bigger than this. */
4174 if( qsize <= 0 ) {
4175 if( num != rem ) {
4176 rem->nlimbs = num->nlimbs;
4177 rem->sign = num->sign;
4178 MPN_COPY(rem->d, num->d, nsize);
4179 }
4180 if( quot ) {
4181 /* This needs to follow the assignment to rem, in case the
4182 * numerator and quotient are the same. */
4183 quot->nlimbs = 0;
4184 quot->sign = 0;
4185 }
4186 return;
4187 }
4188
4189 if( quot )
4190 mpi_resize( quot, qsize);
4191
4192 /* Read pointers here, when reallocation is finished. */
4193 np = num->d;
4194 dp = den->d;
4195 rp = rem->d;
4196
4197 /* Optimize division by a single-limb divisor. */
4198 if( dsize == 1 ) {
4199 mpi_limb_t rlimb;
4200 if( quot ) {
4201 qp = quot->d;
4202 rlimb = mpihelp_divmod_1( qp, np, nsize, dp[0] );
4203 qsize -= qp[qsize - 1] == 0;
4204 quot->nlimbs = qsize;
4205 quot->sign = sign_quotient;
4206 }
4207 else
4208 rlimb = mpihelp_mod_1( np, nsize, dp[0] );
4209 rp[0] = rlimb;
4210 rsize = rlimb != 0?1:0;
4211 rem->nlimbs = rsize;
4212 rem->sign = sign_remainder;
4213 return;
4214 }
4215
4216
4217 if( quot ) {
4218 qp = quot->d;
4219 /* Make sure QP and NP point to different objects. Otherwise the
4220 * numerator would be gradually overwritten by the quotient limbs. */
4221 if(qp == np) { /* Copy NP object to temporary space. */
4222 np = marker[markidx++] = mpi_alloc_limb_space(nsize,
4223 mpi_is_secure(quot));
4224 MPN_COPY(np, qp, nsize);
4225 }
4226 }
4227 else /* Put quotient at top of remainder. */
4228 qp = rp + dsize;
4229
4230 count_leading_zeros( normalization_steps, dp[dsize - 1] );
4231
4232 /* Normalize the denominator, i.e. make its most significant bit set by
4233 * shifting it NORMALIZATION_STEPS bits to the left. Also shift the
4234 * numerator the same number of steps (to keep the quotient the same!).
4235 */
4236 if( normalization_steps ) {
4237 mpi_ptr_t tp;
4238 mpi_limb_t nlimb;
4239
4240 /* Shift up the denominator setting the most significant bit of
4241 * the most significant word. Use temporary storage not to clobber
4242 * the original contents of the denominator. */
4243 tp = marker[markidx++] = mpi_alloc_limb_space(dsize,mpi_is_secure(den));
4244 mpihelp_lshift( tp, dp, dsize, normalization_steps );
4245 dp = tp;
4246
4247 /* Shift up the numerator, possibly introducing a new most
4248 * significant word. Move the shifted numerator in the remainder
4249 * meanwhile. */
4250 nlimb = mpihelp_lshift(rp, np, nsize, normalization_steps);
4251 if( nlimb ) {
4252 rp[nsize] = nlimb;
4253 rsize = nsize + 1;
4254 }
4255 else
4256 rsize = nsize;
4257 }
4258 else {
4259 /* The denominator is already normalized, as required. Copy it to
4260 * temporary space if it overlaps with the quotient or remainder. */
4261 if( dp == rp || (quot && (dp == qp))) {
4262 mpi_ptr_t tp;
4263
4264 tp = marker[markidx++] = mpi_alloc_limb_space(dsize, mpi_is_secure(den));
4265 MPN_COPY( tp, dp, dsize );
4266 dp = tp;
4267 }
4268
4269 /* Move the numerator to the remainder. */
4270 if( rp != np )
4271 MPN_COPY(rp, np, nsize);
4272
4273 rsize = nsize;
4274 }
4275
4276 q_limb = mpihelp_divrem( qp, 0, rp, rsize, dp, dsize );
4277
4278 if( quot ) {
4279 qsize = rsize - dsize;
4280 if(q_limb) {
4281 qp[qsize] = q_limb;
4282 qsize += 1;
4283 }
4284
4285 quot->nlimbs = qsize;
4286 quot->sign = sign_quotient;
4287 }
4288
4289 rsize = dsize;
4290 MPN_NORMALIZE (rp, rsize);
4291
4292 if( normalization_steps && rsize ) {
4293 mpihelp_rshift(rp, rp, rsize, normalization_steps);
4294 rsize -= rp[rsize - 1] == 0?1:0;
4295 }
4296
4297 rem->nlimbs = rsize;
4298 rem->sign = sign_remainder;
4299 while( markidx )
4300 mpi_free_limb_space(marker[--markidx]);
4301 }
4302
4303 void
4304 mpi_tdiv_q_2exp( MPI w, MPI u, unsigned count )
4305 {
4306 mpi_size_t usize, wsize;
4307 mpi_size_t limb_cnt;
4308
4309 usize = u->nlimbs;
4310 limb_cnt = count / BITS_PER_MPI_LIMB;
4311 wsize = usize - limb_cnt;
4312 if( limb_cnt >= usize )
4313 w->nlimbs = 0;
4314 else {
4315 mpi_ptr_t wp;
4316 mpi_ptr_t up;
4317
4318 RESIZE_IF_NEEDED( w, wsize );
4319 wp = w->d;
4320 up = u->d;
4321
4322 count %= BITS_PER_MPI_LIMB;
4323 if( count ) {
4324 mpihelp_rshift( wp, up + limb_cnt, wsize, count );
4325 wsize -= !wp[wsize - 1];
4326 }
4327 else {
4328 MPN_COPY_INCR( wp, up + limb_cnt, wsize);
4329 }
4330
4331 w->nlimbs = wsize;
4332 }
4333 }
4334
4335 /****************
4336 * Check whether dividend is divisible by divisor
4337 * (note: divisor must fit into a limb)
4338 */
4339 int
4340 mpi_divisible_ui(MPI dividend, ulong divisor )
4341 {
4342 return !mpihelp_mod_1( dividend->d, dividend->nlimbs, divisor );
4343 }
4344
-
+ 0AD3099F1DB858EB1D25E7BCCC7461F981ADAB9F7853346EF97A161639D3BCC31F22539ABB342C96EB087F0FCE3C91BB26A7E9C78C92DC33CA1FCA5EFCF534FE
smg_comms/mpi/mpi-gcd.c
(0 . 0)(1 . 57)
4349 /* mpi-gcd.c - MPI functions
4350 * Modified by No Such Labs. (C) 2015. See README.
4351 *
4352 * This file was originally part of Gnu Privacy Guard (GPG), ver. 1.4.10,
4353 * SHA256(gnupg-1.4.10.tar.gz):
4354 * 0bfd74660a2f6cedcf7d8256db4a63c996ffebbcdc2cf54397bfb72878c5a85a
4355 * (C) 1994-2005 Free Software Foundation, Inc.
4356 *
4357 * This program is free software: you can redistribute it and/or modify
4358 * it under the terms of the GNU General Public License as published by
4359 * the Free Software Foundation, either version 3 of the License, or
4360 * (at your option) any later version.
4361 *
4362 * This program is distributed in the hope that it will be useful,
4363 * but WITHOUT ANY WARRANTY; without even the implied warranty of
4364 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4365 * GNU General Public License for more details.
4366 *
4367 * You should have received a copy of the GNU General Public License
4368 * along with this program. If not, see <http://www.gnu.org/licenses/>.
4369 */
4370
4371 #include <stdio.h>
4372 #include <stdlib.h>
4373
4374 #include "knobs.h"
4375 #include "mpi-internal.h"
4376
4377 /****************
4378 * Find the greatest common divisor G of A and B.
4379 * Return: true if this 1, false in all other cases
4380 */
4381 int
4382 mpi_gcd( MPI g, MPI xa, MPI xb )
4383 {
4384 MPI a, b;
4385
4386 a = mpi_copy(xa);
4387 b = mpi_copy(xb);
4388
4389 /* TAOCP Vol II, 4.5.2, Algorithm A */
4390 a->sign = 0;
4391 b->sign = 0;
4392 while( mpi_cmp_ui( b, 0 ) ) {
4393 mpi_fdiv_r( g, a, b ); /* g used as temorary variable */
4394 mpi_set(a,b);
4395 mpi_set(b,g);
4396 }
4397 mpi_set(g, a);
4398
4399 mpi_free(a);
4400 mpi_free(b);
4401 return !mpi_cmp_ui( g, 1);
4402 }
4403
4404
4405
-
+ F9C2A485A76A2A0C12704D4683A4DC6A891B82217EB70B6FEE22D4CDE87FE7453C99463136A677C4520F9ACE2B110EBD856214AFDEC5104EB2CB0774573F09CA
smg_comms/mpi/mpi-inline.c
(0 . 0)(1 . 39)
4410 /* mpi-inline.c
4411 * Modified by No Such Labs. (C) 2015. See README.
4412 *
4413 * This file was originally part of Gnu Privacy Guard (GPG), ver. 1.4.10,
4414 * SHA256(gnupg-1.4.10.tar.gz):
4415 * 0bfd74660a2f6cedcf7d8256db4a63c996ffebbcdc2cf54397bfb72878c5a85a
4416 * (C) 1994-2005 Free Software Foundation, Inc.
4417 *
4418 * This program is free software: you can redistribute it and/or modify
4419 * it under the terms of the GNU General Public License as published by
4420 * the Free Software Foundation, either version 3 of the License, or
4421 * (at your option) any later version.
4422 *
4423 * This program is distributed in the hope that it will be useful,
4424 * but WITHOUT ANY WARRANTY; without even the implied warranty of
4425 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4426 * GNU General Public License for more details.
4427 *
4428 * You should have received a copy of the GNU General Public License
4429 * along with this program. If not, see <http://www.gnu.org/licenses/>.
4430 */
4431
4432 #include <stdio.h>
4433 #include <stdlib.h>
4434
4435 #include "knobs.h"
4436
4437 /* put the inline functions as real functions into the lib */
4438 #define G10_MPI_INLINE_DECL
4439
4440 #include "mpi-internal.h"
4441
4442 /* always include the header becuase it is only
4443 * included by mpi-internal if __GCC__ is defined but we
4444 * need it here in all cases and the above definition of
4445 * of the macro allows us to do so
4446 */
4447 #include "mpi-inline.h"
4448
-
+ BD7B8BD954F2DDD627A55179B48C589DEE37155BA3A2984C0E7AD6CC32C1C4A53DD0E9BE5BD9A1EC1B6EE9C04E98DD40ADFB2FEC78BD2F24FF4E6EC6F723CB55
smg_comms/mpi/mpi-inv.c
(0 . 0)(1 . 270)
4453 /* mpi-inv.c - MPI functions
4454 * Modified by No Such Labs. (C) 2015. See README.
4455 *
4456 * This file was originally part of Gnu Privacy Guard (GPG), ver. 1.4.10,
4457 * SHA256(gnupg-1.4.10.tar.gz):
4458 * 0bfd74660a2f6cedcf7d8256db4a63c996ffebbcdc2cf54397bfb72878c5a85a
4459 * (C) 1994-2005 Free Software Foundation, Inc.
4460 *
4461 * This program is free software: you can redistribute it and/or modify
4462 * it under the terms of the GNU General Public License as published by
4463 * the Free Software Foundation, either version 3 of the License, or
4464 * (at your option) any later version.
4465 *
4466 * This program is distributed in the hope that it will be useful,
4467 * but WITHOUT ANY WARRANTY; without even the implied warranty of
4468 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4469 * GNU General Public License for more details.
4470 *
4471 * You should have received a copy of the GNU General Public License
4472 * along with this program. If not, see <http://www.gnu.org/licenses/>.
4473 */
4474
4475 #include <stdio.h>
4476 #include <stdlib.h>
4477
4478 #include "knobs.h"
4479 #include "mpi-internal.h"
4480
4481
4482 /****************
4483 * Calculate the multiplicative inverse X of A mod N
4484 * That is: Find the solution x for
4485 * 1 = (a*x) mod n
4486 */
4487 void
4488 mpi_invm( MPI x, MPI a, MPI n )
4489 {
4490 #if 0
4491 MPI u, v, u1, u2, u3, v1, v2, v3, q, t1, t2, t3;
4492 MPI ta, tb, tc;
4493
4494 u = mpi_copy(a);
4495 v = mpi_copy(n);
4496 u1 = mpi_alloc_set_ui(1);
4497 u2 = mpi_alloc_set_ui(0);
4498 u3 = mpi_copy(u);
4499 v1 = mpi_alloc_set_ui(0);
4500 v2 = mpi_alloc_set_ui(1);
4501 v3 = mpi_copy(v);
4502 q = mpi_alloc( mpi_get_nlimbs(u)+1 );
4503 t1 = mpi_alloc( mpi_get_nlimbs(u)+1 );
4504 t2 = mpi_alloc( mpi_get_nlimbs(u)+1 );
4505 t3 = mpi_alloc( mpi_get_nlimbs(u)+1 );
4506 while( mpi_cmp_ui( v3, 0 ) ) {
4507 mpi_fdiv_q( q, u3, v3 );
4508 mpi_mul(t1, v1, q); mpi_mul(t2, v2, q); mpi_mul(t3, v3, q);
4509 mpi_sub(t1, u1, t1); mpi_sub(t2, u2, t2); mpi_sub(t3, u3, t3);
4510 mpi_set(u1, v1); mpi_set(u2, v2); mpi_set(u3, v3);
4511 mpi_set(v1, t1); mpi_set(v2, t2); mpi_set(v3, t3);
4512 }
4513 /* log_debug("result:\n");
4514 log_mpidump("q =", q );
4515 log_mpidump("u1=", u1);
4516 log_mpidump("u2=", u2);
4517 log_mpidump("u3=", u3);
4518 log_mpidump("v1=", v1);
4519 log_mpidump("v2=", v2); */
4520 mpi_set(x, u1);
4521
4522 mpi_free(u1);
4523 mpi_free(u2);
4524 mpi_free(u3);
4525 mpi_free(v1);
4526 mpi_free(v2);
4527 mpi_free(v3);
4528 mpi_free(q);
4529 mpi_free(t1);
4530 mpi_free(t2);
4531 mpi_free(t3);
4532 mpi_free(u);
4533 mpi_free(v);
4534 #elif 0
4535 /* Extended Euclid's algorithm (See TAOPC Vol II, 4.5.2, Alg X)
4536 * modified according to Michael Penk's solution for Exercice 35 */
4537
4538 /* FIXME: we can simplify this in most cases (see Knuth) */
4539 MPI u, v, u1, u2, u3, v1, v2, v3, t1, t2, t3;
4540 unsigned k;
4541 int sign;
4542
4543 u = mpi_copy(a);
4544 v = mpi_copy(n);
4545 for(k=0; !mpi_test_bit(u,0) && !mpi_test_bit(v,0); k++ ) {
4546 mpi_rshift(u, u, 1);
4547 mpi_rshift(v, v, 1);
4548 }
4549
4550
4551 u1 = mpi_alloc_set_ui(1);
4552 u2 = mpi_alloc_set_ui(0);
4553 u3 = mpi_copy(u);
4554 v1 = mpi_copy(v); /* !-- used as const 1 */
4555 v2 = mpi_alloc( mpi_get_nlimbs(u) ); mpi_sub( v2, u1, u );
4556 v3 = mpi_copy(v);
4557 if( mpi_test_bit(u, 0) ) { /* u is odd */
4558 t1 = mpi_alloc_set_ui(0);
4559 t2 = mpi_alloc_set_ui(1); t2->sign = 1;
4560 t3 = mpi_copy(v); t3->sign = !t3->sign;
4561 goto Y4;
4562 }
4563 else {
4564 t1 = mpi_alloc_set_ui(1);
4565 t2 = mpi_alloc_set_ui(0);
4566 t3 = mpi_copy(u);
4567 }
4568 do {
4569 do {
4570 if( mpi_test_bit(t1, 0) || mpi_test_bit(t2, 0) ) { /* one is odd */
4571 mpi_add(t1, t1, v);
4572 mpi_sub(t2, t2, u);
4573 }
4574 mpi_rshift(t1, t1, 1);
4575 mpi_rshift(t2, t2, 1);
4576 mpi_rshift(t3, t3, 1);
4577 Y4:
4578 ;
4579 } while( !mpi_test_bit( t3, 0 ) ); /* while t3 is even */
4580
4581 if( !t3->sign ) {
4582 mpi_set(u1, t1);
4583 mpi_set(u2, t2);
4584 mpi_set(u3, t3);
4585 }
4586 else {
4587 mpi_sub(v1, v, t1);
4588 sign = u->sign; u->sign = !u->sign;
4589 mpi_sub(v2, u, t2);
4590 u->sign = sign;
4591 sign = t3->sign; t3->sign = !t3->sign;
4592 mpi_set(v3, t3);
4593 t3->sign = sign;
4594 }
4595 mpi_sub(t1, u1, v1);
4596 mpi_sub(t2, u2, v2);
4597 mpi_sub(t3, u3, v3);
4598 if( t1->sign ) {
4599 mpi_add(t1, t1, v);
4600 mpi_sub(t2, t2, u);
4601 }
4602 } while( mpi_cmp_ui( t3, 0 ) ); /* while t3 != 0 */
4603 /* mpi_lshift( u3, k ); */
4604 mpi_set(x, u1);
4605
4606 mpi_free(u1);
4607 mpi_free(u2);
4608 mpi_free(u3);
4609 mpi_free(v1);
4610 mpi_free(v2);
4611 mpi_free(v3);
4612 mpi_free(t1);
4613 mpi_free(t2);
4614 mpi_free(t3);
4615 #else
4616 /* Extended Euclid's algorithm (See TAOPC Vol II, 4.5.2, Alg X)
4617 * modified according to Michael Penk's solution for Exercice 35
4618 * with further enhancement */
4619 MPI u, v, u1, u2=NULL, u3, v1, v2=NULL, v3, t1, t2=NULL, t3;
4620 unsigned k;
4621 int sign;
4622 int odd ;
4623
4624 u = mpi_copy(a);
4625 v = mpi_copy(n);
4626
4627 for(k=0; !mpi_test_bit(u,0) && !mpi_test_bit(v,0); k++ ) {
4628 mpi_rshift(u, u, 1);
4629 mpi_rshift(v, v, 1);
4630 }
4631 odd = mpi_test_bit(v,0);
4632
4633 u1 = mpi_alloc_set_ui(1);
4634 if( !odd )
4635 u2 = mpi_alloc_set_ui(0);
4636 u3 = mpi_copy(u);
4637 v1 = mpi_copy(v);
4638 if( !odd ) {
4639 v2 = mpi_alloc( mpi_get_nlimbs(u) );
4640 mpi_sub( v2, u1, u ); /* U is used as const 1 */
4641 }
4642 v3 = mpi_copy(v);
4643 if( mpi_test_bit(u, 0) ) { /* u is odd */
4644 t1 = mpi_alloc_set_ui(0);
4645 if( !odd ) {
4646 t2 = mpi_alloc_set_ui(1); t2->sign = 1;
4647 }
4648 t3 = mpi_copy(v); t3->sign = !t3->sign;
4649 goto Y4;
4650 }
4651 else {
4652 t1 = mpi_alloc_set_ui(1);
4653 if( !odd )
4654 t2 = mpi_alloc_set_ui(0);
4655 t3 = mpi_copy(u);
4656 }
4657 do {
4658 do {
4659 if( !odd ) {
4660 if( mpi_test_bit(t1, 0) || mpi_test_bit(t2, 0) ) { /* one is odd */
4661 mpi_add(t1, t1, v);
4662 mpi_sub(t2, t2, u);
4663 }
4664 mpi_rshift(t1, t1, 1);
4665 mpi_rshift(t2, t2, 1);
4666 mpi_rshift(t3, t3, 1);
4667 }
4668 else {
4669 if( mpi_test_bit(t1, 0) )
4670 mpi_add(t1, t1, v);
4671 mpi_rshift(t1, t1, 1);
4672 mpi_rshift(t3, t3, 1);
4673 }
4674 Y4:
4675 ;
4676 } while( !mpi_test_bit( t3, 0 ) ); /* while t3 is even */
4677
4678 if( !t3->sign ) {
4679 mpi_set(u1, t1);
4680 if( !odd )
4681 mpi_set(u2, t2);
4682 mpi_set(u3, t3);
4683 }
4684 else {
4685 mpi_sub(v1, v, t1);
4686 sign = u->sign; u->sign = !u->sign;
4687 if( !odd )
4688 mpi_sub(v2, u, t2);
4689 u->sign = sign;
4690 sign = t3->sign; t3->sign = !t3->sign;
4691 mpi_set(v3, t3);
4692 t3->sign = sign;
4693 }
4694 mpi_sub(t1, u1, v1);
4695 if( !odd )
4696 mpi_sub(t2, u2, v2);
4697 mpi_sub(t3, u3, v3);
4698 if( t1->sign ) {
4699 mpi_add(t1, t1, v);
4700 if( !odd )
4701 mpi_sub(t2, t2, u);
4702 }
4703 } while( mpi_cmp_ui( t3, 0 ) ); /* while t3 != 0 */
4704 /* mpi_lshift( u3, k ); */
4705 mpi_set(x, u1);
4706
4707 mpi_free(u1);
4708 mpi_free(v1);
4709 mpi_free(t1);
4710 if( !odd ) {
4711 mpi_free(u2);
4712 mpi_free(v2);
4713 mpi_free(t2);
4714 }
4715 mpi_free(u3);
4716 mpi_free(v3);
4717 mpi_free(t3);
4718
4719 mpi_free(u);
4720 mpi_free(v);
4721 #endif
4722 }
-
+ 221190B0F2BADE0E8F32E7ABB9A0CDA81A2B15A0ABE6AB54596B4823C41149EBB93338FA4CE7C6C4809618A53A173003F7FEBD510F188509E0D7FDD466596130
smg_comms/mpi/mpi-mpow.c
(0 . 0)(1 . 103)
4727 /* mpi-mpow.c - MPI functions
4728 * Modified by No Such Labs. (C) 2015. See README.
4729 *
4730 * This file was originally part of Gnu Privacy Guard (GPG), ver. 1.4.10,
4731 * SHA256(gnupg-1.4.10.tar.gz):
4732 * 0bfd74660a2f6cedcf7d8256db4a63c996ffebbcdc2cf54397bfb72878c5a85a
4733 * (C) 1994-2005 Free Software Foundation, Inc.
4734 *
4735 * This program is free software: you can redistribute it and/or modify
4736 * it under the terms of the GNU General Public License as published by
4737 * the Free Software Foundation, either version 3 of the License, or
4738 * (at your option) any later version.
4739 *
4740 * This program is distributed in the hope that it will be useful,
4741 * but WITHOUT ANY WARRANTY; without even the implied warranty of
4742 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4743 * GNU General Public License for more details.
4744 *
4745 * You should have received a copy of the GNU General Public License
4746 * along with this program. If not, see <http://www.gnu.org/licenses/>.
4747 */
4748
4749 #include <stdio.h>
4750 #include <stdlib.h>
4751 #include <assert.h>
4752
4753 #include "knobs.h"
4754 #include "mpi-internal.h"
4755 #include "longlong.h"
4756
4757
4758 static int
4759 build_index( MPI *exparray, int k, int i, int t )
4760 {
4761 int j, bitno;
4762 int idx = 0;
4763
4764 bitno = t-i;
4765 for(j=k-1; j >= 0; j-- ) {
4766 idx <<= 1;
4767 if( mpi_test_bit( exparray[j], bitno ) )
4768 idx |= 1;
4769 }
4770 return idx;
4771 }
4772
4773 /****************
4774 * RES = (BASE[0] ^ EXP[0]) * (BASE[1] ^ EXP[1]) * ... * mod M
4775 */
4776 void
4777 mpi_mulpowm( MPI res, MPI *basearray, MPI *exparray, MPI m)
4778 {
4779 int k; /* number of elements */
4780 int t; /* bit size of largest exponent */
4781 int i, j, idx;
4782 MPI *G; /* table with precomputed values of size 2^k */
4783 MPI tmp;
4784
4785 for(k=0; basearray[k]; k++ )
4786 ;
4787 assert(k);
4788 for(t=0, i=0; (tmp=exparray[i]); i++ ) {
4789 j = mpi_get_nbits(tmp);
4790 if( j > t )
4791 t = j;
4792 }
4793 assert(i==k);
4794 assert(t);
4795 assert( k < 10 );
4796
4797 G = xmalloc_clear( (1<<k) * sizeof *G );
4798 /* and calculate */
4799 tmp = mpi_alloc( mpi_get_nlimbs(m)+1 );
4800 mpi_set_ui( res, 1 );
4801 for(i = 1; i <= t; i++ ) {
4802 mpi_mulm(tmp, res, res, m );
4803 idx = build_index( exparray, k, i, t );
4804 assert( idx >= 0 && idx < (1<<k) );
4805 if( !G[idx] ) {
4806 if( !idx )
4807 G[0] = mpi_alloc_set_ui( 1 );
4808 else {
4809 for(j=0; j < k; j++ ) {
4810 if( (idx & (1<<j) ) ) {
4811 if( !G[idx] )
4812 G[idx] = mpi_copy( basearray[j] );
4813 else
4814 mpi_mulm( G[idx], G[idx], basearray[j], m );
4815 }
4816 }
4817 if( !G[idx] )
4818 G[idx] = mpi_alloc(0);
4819 }
4820 }
4821 mpi_mulm(res, tmp, G[idx], m );
4822 }
4823
4824 /* cleanup */
4825 mpi_free(tmp);
4826 for(i=0; i < (1<<k); i++ )
4827 mpi_free(G[i]);
4828 xfree(G);
4829 }
-
+ F70DDD8CDF793CD1A95B6C84A9C73BFF0EF7BE6BB56483AAE08E26AAF004AAB695E34F4CD0982BF5D188374E9FD07241B225BA763EFACB78EDA586FC84E3CBE2
smg_comms/mpi/mpi-mul.c
(0 . 0)(1 . 209)
4834 /* mpi-mul.c - MPI functions
4835 * Modified by No Such Labs. (C) 2015. See README.
4836 *
4837 * This file was originally part of Gnu Privacy Guard (GPG), ver. 1.4.10,
4838 * SHA256(gnupg-1.4.10.tar.gz):
4839 * 0bfd74660a2f6cedcf7d8256db4a63c996ffebbcdc2cf54397bfb72878c5a85a
4840 * (C) 1994-2005 Free Software Foundation, Inc.
4841 *
4842 * This program is free software: you can redistribute it and/or modify
4843 * it under the terms of the GNU General Public License as published by
4844 * the Free Software Foundation, either version 3 of the License, or
4845 * (at your option) any later version.
4846 *
4847 * This program is distributed in the hope that it will be useful,
4848 * but WITHOUT ANY WARRANTY; without even the implied warranty of
4849 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4850 * GNU General Public License for more details.
4851 *
4852 * You should have received a copy of the GNU General Public License
4853 * along with this program. If not, see <http://www.gnu.org/licenses/>.
4854 */
4855
4856 #include <stdio.h>
4857 #include <stdlib.h>
4858
4859 #include "knobs.h"
4860 #include "mpi-internal.h"
4861
4862
4863 void
4864 mpi_mul_ui( MPI prod, MPI mult, unsigned long small_mult )
4865 {
4866 mpi_size_t size, prod_size;
4867 mpi_ptr_t prod_ptr;
4868 mpi_limb_t cy;
4869 int sign;
4870
4871 size = mult->nlimbs;
4872 sign = mult->sign;
4873
4874 if( !size || !small_mult ) {
4875 prod->nlimbs = 0;
4876 prod->sign = 0;
4877 return;
4878 }
4879
4880 prod_size = size + 1;
4881 if( prod->alloced < prod_size )
4882 mpi_resize( prod, prod_size );
4883 prod_ptr = prod->d;
4884
4885 cy = mpihelp_mul_1( prod_ptr, mult->d, size, (mpi_limb_t)small_mult );
4886 if( cy )
4887 prod_ptr[size++] = cy;
4888 prod->nlimbs = size;
4889 prod->sign = sign;
4890 }
4891
4892
4893 void
4894 mpi_mul_2exp( MPI w, MPI u, unsigned long cnt)
4895 {
4896 mpi_size_t usize, wsize, limb_cnt;
4897 mpi_ptr_t wp;
4898 mpi_limb_t wlimb;
4899 int usign, wsign;
4900
4901 usize = u->nlimbs;
4902 usign = u->sign;
4903
4904 if( !usize ) {
4905 w->nlimbs = 0;
4906 w->sign = 0;
4907 return;
4908 }
4909
4910 limb_cnt = cnt / BITS_PER_MPI_LIMB;
4911 wsize = usize + limb_cnt + 1;
4912 if( w->alloced < wsize )
4913 mpi_resize(w, wsize );
4914 wp = w->d;
4915 wsize = usize + limb_cnt;
4916 wsign = usign;
4917
4918 cnt %= BITS_PER_MPI_LIMB;
4919 if( cnt ) {
4920 wlimb = mpihelp_lshift( wp + limb_cnt, u->d, usize, cnt );
4921 if( wlimb ) {
4922 wp[wsize] = wlimb;
4923 wsize++;
4924 }
4925 }
4926 else {
4927 MPN_COPY_DECR( wp + limb_cnt, u->d, usize );
4928 }
4929
4930 /* Zero all whole limbs at low end. Do it here and not before calling
4931 * mpn_lshift, not to lose for U == W. */
4932 MPN_ZERO( wp, limb_cnt );
4933
4934 w->nlimbs = wsize;
4935 w->sign = wsign;
4936 }
4937
4938
4939
4940 void
4941 mpi_mul( MPI w, MPI u, MPI v)
4942 {
4943 mpi_size_t usize, vsize, wsize;
4944 mpi_ptr_t up, vp, wp;
4945 mpi_limb_t cy;
4946 int usign, vsign, usecure, vsecure, sign_product;
4947 int assign_wp=0;
4948 mpi_ptr_t tmp_limb=NULL;
4949
4950
4951 if( u->nlimbs < v->nlimbs ) { /* Swap U and V. */
4952 usize = v->nlimbs;
4953 usign = v->sign;
4954 usecure = mpi_is_secure(v);
4955 up = v->d;
4956 vsize = u->nlimbs;
4957 vsign = u->sign;
4958 vsecure = mpi_is_secure(u);
4959 vp = u->d;
4960 }
4961 else {
4962 usize = u->nlimbs;
4963 usign = u->sign;
4964 usecure = mpi_is_secure(u);
4965 up = u->d;
4966 vsize = v->nlimbs;
4967 vsign = v->sign;
4968 vsecure = mpi_is_secure(v);
4969 vp = v->d;
4970 }
4971 sign_product = usign ^ vsign;
4972 wp = w->d;
4973
4974 /* Ensure W has space enough to store the result. */
4975 wsize = usize + vsize;
4976 if ( !mpi_is_secure (w) && (mpi_is_secure (u) || mpi_is_secure (v)) ) {
4977 /* w is not allocated in secure space but u or v is. To make sure
4978 * that no temporray results are stored in w, we temporary use
4979 * a newly allocated limb space for w */
4980 wp = mpi_alloc_limb_space( wsize, 1 );
4981 assign_wp = 2; /* mark it as 2 so that we can later copy it back to
4982 * mormal memory */
4983 }
4984 else if( w->alloced < wsize ) {
4985 if( wp == up || wp == vp ) {
4986 wp = mpi_alloc_limb_space( wsize, mpi_is_secure(w) );
4987 assign_wp = 1;
4988 }
4989 else {
4990 mpi_resize(w, wsize );
4991 wp = w->d;
4992 }
4993 }
4994 else { /* Make U and V not overlap with W. */
4995 if( wp == up ) {
4996 /* W and U are identical. Allocate temporary space for U. */
4997 up = tmp_limb = mpi_alloc_limb_space( usize, usecure );
4998 /* Is V identical too? Keep it identical with U. */
4999 if( wp == vp )
5000 vp = up;
5001 /* Copy to the temporary space. */
5002 MPN_COPY( up, wp, usize );
5003 }
5004 else if( wp == vp ) {
5005 /* W and V are identical. Allocate temporary space for V. */
5006 vp = tmp_limb = mpi_alloc_limb_space( vsize, vsecure );
5007 /* Copy to the temporary space. */
5008 MPN_COPY( vp, wp, vsize );
5009 }
5010 }
5011
5012 if( !vsize )
5013 wsize = 0;
5014 else {
5015 cy = mpihelp_mul( wp, up, usize, vp, vsize );
5016 wsize -= cy? 0:1;
5017 }
5018
5019 if( assign_wp ) {
5020 if (assign_wp == 2) {
5021 /* copy the temp wp from secure memory back to normal memory */
5022 mpi_ptr_t tmp_wp = mpi_alloc_limb_space (wsize, 0);
5023 MPN_COPY (tmp_wp, wp, wsize);
5024 mpi_free_limb_space (wp);
5025 wp = tmp_wp;
5026 }
5027 mpi_assign_limb_space( w, wp, wsize );
5028 }
5029 w->nlimbs = wsize;
5030 w->sign = sign_product;
5031 if( tmp_limb )
5032 mpi_free_limb_space( tmp_limb );
5033 }
5034
5035
5036 void
5037 mpi_mulm( MPI w, MPI u, MPI v, MPI m)
5038 {
5039 mpi_mul(w, u, v);
5040 mpi_fdiv_r( w, w, m );
5041 }
5042
-
+ BBB0C95D94298E81A2357FDA16069A02AB02DC1B36A48E6585200DF41E235C56EA25317C5A851AA7E9F5C5C5FBEA684D039377205030715C3FD8E06F31D3BA6D
smg_comms/mpi/mpi-pow.c
(0 . 0)(1 . 291)
5047 /* mpi-pow.c - MPI functions
5048 * Modified by No Such Labs. (C) 2015. See README.
5049 *
5050 * This file was originally part of Gnu Privacy Guard (GPG), ver. 1.4.10,
5051 * SHA256(gnupg-1.4.10.tar.gz):
5052 * 0bfd74660a2f6cedcf7d8256db4a63c996ffebbcdc2cf54397bfb72878c5a85a
5053 * (C) 1994-2005 Free Software Foundation, Inc.
5054 *
5055 * This program is free software: you can redistribute it and/or modify
5056 * it under the terms of the GNU General Public License as published by
5057 * the Free Software Foundation, either version 3 of the License, or
5058 * (at your option) any later version.
5059 *
5060 * This program is distributed in the hope that it will be useful,
5061 * but WITHOUT ANY WARRANTY; without even the implied warranty of
5062 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5063 * GNU General Public License for more details.
5064 *
5065 * You should have received a copy of the GNU General Public License
5066 * along with this program. If not, see <http://www.gnu.org/licenses/>.
5067 */
5068
5069 #include <stdio.h>
5070 #include <stdlib.h>
5071 #include <string.h>
5072 #include <assert.h>
5073
5074 #include "knobs.h"
5075 #include "mpi-internal.h"
5076 #include "longlong.h"
5077
5078
5079
5080 /****************
5081 * RES = BASE ^ EXP mod MOD
5082 */
5083 void
5084 mpi_powm( MPI res, MPI base, MPI exponent, MPI mod)
5085 {
5086 mpi_ptr_t rp, ep, mp, bp;
5087 mpi_size_t esize, msize, bsize, rsize;
5088 int esign, msign, bsign, rsign;
5089 int esec, msec, bsec, rsec;
5090 mpi_size_t size;
5091 int mod_shift_cnt;
5092 int negative_result;
5093 mpi_ptr_t mp_marker=NULL, bp_marker=NULL, ep_marker=NULL;
5094 mpi_ptr_t xp_marker=NULL;
5095 int assign_rp=0;
5096 mpi_ptr_t tspace = NULL;
5097 mpi_size_t tsize=0; /* to avoid compiler warning */
5098 /* fixme: we should check that the warning is void*/
5099
5100 esize = exponent->nlimbs;
5101 msize = mod->nlimbs;
5102 size = 2 * msize;
5103 esign = exponent->sign;
5104 msign = mod->sign;
5105
5106 esec = mpi_is_secure(exponent);
5107 msec = mpi_is_secure(mod);
5108 bsec = mpi_is_secure(base);
5109 rsec = mpi_is_secure(res);
5110
5111 rp = res->d;
5112 ep = exponent->d;
5113
5114 if( !msize )
5115 msize = 1 / msize; /* provoke a signal */
5116
5117 if( !esize ) {
5118 /* Exponent is zero, result is 1 mod MOD, i.e., 1 or 0
5119 * depending on if MOD equals 1. */
5120 rp[0] = 1;
5121 res->nlimbs = (msize == 1 && mod->d[0] == 1) ? 0 : 1;
5122 res->sign = 0;
5123 goto leave;
5124 }
5125
5126 /* Normalize MOD (i.e. make its most significant bit set) as required by
5127 * mpn_divrem. This will make the intermediate values in the calculation
5128 * slightly larger, but the correct result is obtained after a final
5129 * reduction using the original MOD value. */
5130 mp = mp_marker = mpi_alloc_limb_space(msize, msec);
5131 count_leading_zeros( mod_shift_cnt, mod->d[msize-1] );
5132 if( mod_shift_cnt )
5133 mpihelp_lshift( mp, mod->d, msize, mod_shift_cnt );
5134 else
5135 MPN_COPY( mp, mod->d, msize );
5136
5137 bsize = base->nlimbs;
5138 bsign = base->sign;
5139 if( bsize > msize ) { /* The base is larger than the module. Reduce it. */
5140 /* Allocate (BSIZE + 1) with space for remainder and quotient.
5141 * (The quotient is (bsize - msize + 1) limbs.) */
5142 bp = bp_marker = mpi_alloc_limb_space( bsize + 1, bsec );
5143 MPN_COPY( bp, base->d, bsize );
5144 /* We don't care about the quotient, store it above the remainder,
5145 * at BP + MSIZE. */
5146 mpihelp_divrem( bp + msize, 0, bp, bsize, mp, msize );
5147 bsize = msize;
5148 /* Canonicalize the base, since we are going to multiply with it
5149 * quite a few times. */
5150 MPN_NORMALIZE( bp, bsize );
5151 }
5152 else
5153 bp = base->d;
5154
5155 if( !bsize ) {
5156 res->nlimbs = 0;
5157 res->sign = 0;
5158 goto leave;
5159 }
5160
5161 if( res->alloced < size ) {
5162 /* We have to allocate more space for RES. If any of the input
5163 * parameters are identical to RES, defer deallocation of the old
5164 * space. */
5165 if( rp == ep || rp == mp || rp == bp ) {
5166 rp = mpi_alloc_limb_space( size, rsec );
5167 assign_rp = 1;
5168 }
5169 else {
5170 mpi_resize( res, size );
5171 rp = res->d;
5172 }
5173 }
5174 else { /* Make BASE, EXPONENT and MOD not overlap with RES. */
5175 if( rp == bp ) {
5176 /* RES and BASE are identical. Allocate temp. space for BASE. */
5177 assert( !bp_marker );
5178 bp = bp_marker = mpi_alloc_limb_space( bsize, bsec );
5179 MPN_COPY(bp, rp, bsize);
5180 }
5181 if( rp == ep ) {
5182 /* RES and EXPONENT are identical.
5183 Allocate temp. space for EXPONENT. */
5184 ep = ep_marker = mpi_alloc_limb_space( esize, esec );
5185 MPN_COPY(ep, rp, esize);
5186 }
5187 if( rp == mp ) {
5188 /* RES and MOD are identical. Allocate temporary space for MOD.*/
5189 assert( !mp_marker );
5190 mp = mp_marker = mpi_alloc_limb_space( msize, msec );
5191 MPN_COPY(mp, rp, msize);
5192 }
5193 }
5194
5195 MPN_COPY( rp, bp, bsize );
5196 rsize = bsize;
5197 rsign = bsign;
5198
5199 {
5200 mpi_size_t i;
5201 mpi_ptr_t xp = xp_marker = mpi_alloc_limb_space( 2 * (msize + 1), msec );
5202 int c;
5203 mpi_limb_t e;
5204 mpi_limb_t carry_limb;
5205 struct karatsuba_ctx karactx;
5206
5207 memset( &karactx, 0, sizeof karactx );
5208 negative_result = (ep[0] & 1) && base->sign;
5209
5210 i = esize - 1;
5211 e = ep[i];
5212 count_leading_zeros (c, e);
5213 e = (e << c) << 1; /* shift the exp bits to the left, lose msb */
5214 c = BITS_PER_MPI_LIMB - 1 - c;
5215
5216 /* Main loop.
5217 *
5218 * Make the result be pointed to alternately by XP and RP. This
5219 * helps us avoid block copying, which would otherwise be necessary
5220 * with the overlap restrictions of mpihelp_divmod. With 50% probability
5221 * the result after this loop will be in the area originally pointed
5222 * by RP (==RES->d), and with 50% probability in the area originally
5223 * pointed to by XP.
5224 */
5225
5226 for(;;) {
5227 while( c ) {
5228 mpi_ptr_t tp;
5229 mpi_size_t xsize;
5230
5231 /*mpihelp_mul_n(xp, rp, rp, rsize);*/
5232 if( rsize < KARATSUBA_THRESHOLD )
5233 mpih_sqr_n_basecase( xp, rp, rsize );
5234 else {
5235 if( !tspace ) {
5236 tsize = 2 * rsize;
5237 tspace = mpi_alloc_limb_space( tsize, 0 );
5238 }
5239 else if( tsize < (2*rsize) ) {
5240 mpi_free_limb_space( tspace );
5241 tsize = 2 * rsize;
5242 tspace = mpi_alloc_limb_space( tsize, 0 );
5243 }
5244 mpih_sqr_n( xp, rp, rsize, tspace );
5245 }
5246
5247 xsize = 2 * rsize;
5248 if( xsize > msize ) {
5249 mpihelp_divrem(xp + msize, 0, xp, xsize, mp, msize);
5250 xsize = msize;
5251 }
5252
5253 tp = rp; rp = xp; xp = tp;
5254 rsize = xsize;
5255
5256 if( (mpi_limb_signed_t)e < 0 ) {
5257 /*mpihelp_mul( xp, rp, rsize, bp, bsize );*/
5258 if( bsize < KARATSUBA_THRESHOLD ) {
5259 mpihelp_mul( xp, rp, rsize, bp, bsize );
5260 }
5261 else {
5262 mpihelp_mul_karatsuba_case(
5263 xp, rp, rsize, bp, bsize, &karactx );
5264 }
5265
5266 xsize = rsize + bsize;
5267 if( xsize > msize ) {
5268 mpihelp_divrem(xp + msize, 0, xp, xsize, mp, msize);
5269 xsize = msize;
5270 }
5271
5272 tp = rp; rp = xp; xp = tp;
5273 rsize = xsize;
5274 }
5275 e <<= 1;
5276 c--;
5277 }
5278
5279 i--;
5280 if( i < 0 )
5281 break;
5282 e = ep[i];
5283 c = BITS_PER_MPI_LIMB;
5284 }
5285
5286 /* We shifted MOD, the modulo reduction argument, left MOD_SHIFT_CNT
5287 * steps. Adjust the result by reducing it with the original MOD.
5288 *
5289 * Also make sure the result is put in RES->d (where it already
5290 * might be, see above).
5291 */
5292 if( mod_shift_cnt ) {
5293 carry_limb = mpihelp_lshift( res->d, rp, rsize, mod_shift_cnt);
5294 rp = res->d;
5295 if( carry_limb ) {
5296 rp[rsize] = carry_limb;
5297 rsize++;
5298 }
5299 }
5300 else {
5301 MPN_COPY( res->d, rp, rsize);
5302 rp = res->d;
5303 }
5304
5305 if( rsize >= msize ) {
5306 mpihelp_divrem(rp + msize, 0, rp, rsize, mp, msize);
5307 rsize = msize;
5308 }
5309
5310 /* Remove any leading zero words from the result. */
5311 if( mod_shift_cnt )
5312 mpihelp_rshift( rp, rp, rsize, mod_shift_cnt);
5313 MPN_NORMALIZE (rp, rsize);
5314
5315 mpihelp_release_karatsuba_ctx( &karactx );
5316 }
5317
5318 if( negative_result && rsize ) {
5319 if( mod_shift_cnt )
5320 mpihelp_rshift( mp, mp, msize, mod_shift_cnt);
5321 mpihelp_sub( rp, mp, msize, rp, rsize);
5322 rsize = msize;
5323 rsign = msign;
5324 MPN_NORMALIZE(rp, rsize);
5325 }
5326 res->nlimbs = rsize;
5327 res->sign = rsign;
5328
5329 leave:
5330 if( assign_rp ) mpi_assign_limb_space( res, rp, size );
5331 if( mp_marker ) mpi_free_limb_space( mp_marker );
5332 if( bp_marker ) mpi_free_limb_space( bp_marker );
5333 if( ep_marker ) mpi_free_limb_space( ep_marker );
5334 if( xp_marker ) mpi_free_limb_space( xp_marker );
5335 if( tspace ) mpi_free_limb_space( tspace );
5336 }
5337
-
+ EAF2827058A07C1502EA5DA210AE7B7662B6B02AC4847D37467FB498DDB84D592CCE814DB4B15588DA8C5349E4FFE4636D267FEDF0ECEB29E63BD8DCF0249BE2
smg_comms/mpi/mpi-scan.c
(0 . 0)(1 . 56)
5342 /* mpi-scan.c - MPI functions
5343 * Modified by No Such Labs. (C) 2015. See README.
5344 * Modified by S.MG 2017 (removed code that is not used by eucrypt and at the same time so ugly it needs rewrite anyway)
5345 *
5346 * This file was originally part of Gnu Privacy Guard (GPG), ver. 1.4.10,
5347 * SHA256(gnupg-1.4.10.tar.gz):
5348 * 0bfd74660a2f6cedcf7d8256db4a63c996ffebbcdc2cf54397bfb72878c5a85a
5349 * (C) 1994-2005 Free Software Foundation, Inc.
5350 *
5351 * This program is free software: you can redistribute it and/or modify
5352 * it under the terms of the GNU General Public License as published by
5353 * the Free Software Foundation, either version 3 of the License, or
5354 * (at your option) any later version.
5355 *
5356 * This program is distributed in the hope that it will be useful,
5357 * but WITHOUT ANY WARRANTY; without even the implied warranty of
5358 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5359 * GNU General Public License for more details.
5360 *
5361 * You should have received a copy of the GNU General Public License
5362 * along with this program. If not, see <http://www.gnu.org/licenses/>.
5363 */
5364
5365 #include <stdio.h>
5366 #include <stdlib.h>
5367
5368 #include "knobs.h"
5369 #include "mpi-internal.h"
5370 #include "longlong.h"
5371
5372
5373 /****************
5374 * Count the number of zerobits at the low end of A
5375 * This is used currently by eucrypt's primality tests.
5376 */
5377 unsigned int
5378 mpi_trailing_zeros( MPI a )
5379 {
5380 unsigned n, count = 0;
5381
5382 for(n=0; n < a->nlimbs; n++ ) {
5383 if( a->d[n] ) {
5384 unsigned nn;
5385 mpi_limb_t alimb = a->d[n];
5386
5387 count_trailing_zeros( nn, alimb );
5388 count += nn;
5389 break;
5390 }
5391 count += BITS_PER_MPI_LIMB;
5392 }
5393 return count;
5394
5395 }
5396
5397
-
+ 9F5E8E039129A65969E8E89ED17DFA033676D406E8E872FD9F47FAC0BC207ACCE55201D257671B39E46DC90909109588398005F5DB9B1FDA3CDF3A97CF434F99
smg_comms/mpi/mpi.gpr
(0 . 0)(1 . 13)
5402 -- S.MG, 2018
5403
5404 project MPI is
5405 for Languages use ("C");
5406 for Library_Name use "MPI";
5407 for Library_Kind use "static";
5408
5409 for Source_Dirs use (".", "include");
5410 for Object_Dir use "obj";
5411 for Library_Dir use "bin";
5412
5413 end MPI;
5414
-
+ E415FDE563A94473CFE9E85E8862CF30F6C8B820F383F6A964AEF675E576648BC9F66F55BA7EF01E27969FE57D14293B96DAAC1525197BE392ABB5C9B1AD4040
smg_comms/mpi/mpicoder.c
(0 . 0)(1 . 347)
5419 /* mpicoder.c - Coder for the external representation of MPIs
5420 * Modified by No Such Labs. (C) 2015. See README.
5421 *
5422 * This file was originally part of Gnu Privacy Guard (GPG), ver. 1.4.10,
5423 * SHA256(gnupg-1.4.10.tar.gz):
5424 * 0bfd74660a2f6cedcf7d8256db4a63c996ffebbcdc2cf54397bfb72878c5a85a
5425 * (C) 1994-2005 Free Software Foundation, Inc.
5426 *
5427 * This program is free software: you can redistribute it and/or modify
5428 * it under the terms of the GNU General Public License as published by
5429 * the Free Software Foundation, either version 3 of the License, or
5430 * (at your option) any later version.
5431 *
5432 * This program is distributed in the hope that it will be useful,
5433 * but WITHOUT ANY WARRANTY; without even the implied warranty of
5434 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5435 * GNU General Public License for more details.
5436 *
5437 * You should have received a copy of the GNU General Public License
5438 * along with this program. If not, see <http://www.gnu.org/licenses/>.
5439 */
5440
5441 #include <stdio.h>
5442 #include <string.h>
5443 #include <stdlib.h>
5444 #include <assert.h>
5445
5446 #include "knobs.h"
5447 #include "mpi.h"
5448 #include "mpi-internal.h"
5449 #include "memory.h"
5450 #include "util.h"
5451
5452 #ifdef M_DEBUG
5453 #undef mpi_read
5454 #endif
5455
5456 #define MAX_EXTERN_MPI_BITS 16384
5457
5458
5459 MPI
5460 mpi_read_from_buffer(byte *buffer, unsigned int *ret_nread, int secure)
5461 {
5462 int i, j;
5463 unsigned nbits, nbytes, nlimbs, nread=0;
5464 mpi_limb_t a;
5465 MPI val = NULL;
5466
5467 if( *ret_nread < 2 )
5468 goto leave;
5469 nbits = buffer[0] << 8 | buffer[1];
5470 if( nbits > MAX_EXTERN_MPI_BITS ) {
5471 log_info ("mpi too large (%u bits)\n", nbits);
5472 goto leave;
5473 }
5474 buffer += 2;
5475 nread = 2;
5476
5477 nbytes = (nbits+7) / 8;
5478 nlimbs = (nbytes+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB;
5479 val = secure? mpi_alloc_secure( nlimbs )
5480 : mpi_alloc( nlimbs );
5481 i = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB;
5482 i %= BYTES_PER_MPI_LIMB;
5483 val->nbits = nbits;
5484 j= val->nlimbs = nlimbs;
5485 val->sign = 0;
5486 for( ; j > 0; j-- ) {
5487 a = 0;
5488 for(; i < BYTES_PER_MPI_LIMB; i++ ) {
5489 if( ++nread > *ret_nread ) {
5490 /* This (as well as the above error condition) may
5491 happen if we use this function to parse a decrypted
5492 MPI which didn't turn out to be a real MPI - possible
5493 because the supplied key was wrong but the OpenPGP
5494 checksum didn't caught it. */
5495 log_info ("mpi larger than buffer\n");
5496 mpi_free (val);
5497 val = NULL;
5498 goto leave;
5499 }
5500 a <<= 8;
5501 a |= *buffer++;
5502 }
5503 i = 0;
5504 val->d[j-1] = a;
5505 }
5506
5507 leave:
5508 *ret_nread = nread;
5509 return val;
5510 }
5511
5512
5513 /****************
5514 * Make an mpi from a character string.
5515 */
5516 int
5517 mpi_fromstr(MPI val, const char *str)
5518 {
5519 int hexmode=0, sign=0, prepend_zero=0, i, j, c, c1, c2;
5520 unsigned nbits, nbytes, nlimbs;
5521 mpi_limb_t a;
5522
5523 if( *str == '-' ) {
5524 sign = 1;
5525 str++;
5526 }
5527 if( *str == '0' && str[1] == 'x' )
5528 hexmode = 1;
5529 else
5530 return 1; /* other bases are not yet supported */
5531 str += 2;
5532
5533 nbits = strlen(str)*4;
5534 if( nbits % 8 )
5535 prepend_zero = 1;
5536 nbytes = (nbits+7) / 8;
5537 nlimbs = (nbytes+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB;
5538 if( val->alloced < nlimbs )
5539 mpi_resize(val, nlimbs );
5540 i = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB;
5541 i %= BYTES_PER_MPI_LIMB;
5542 j= val->nlimbs = nlimbs;
5543 val->sign = sign;
5544 for( ; j > 0; j-- ) {
5545 a = 0;
5546 for(; i < BYTES_PER_MPI_LIMB; i++ ) {
5547 if( prepend_zero ) {
5548 c1 = '0';
5549 prepend_zero = 0;
5550 }
5551 else
5552 c1 = *str++;
5553 assert(c1);
5554 c2 = *str++;
5555 assert(c2);
5556 if( c1 >= '0' && c1 <= '9' )
5557 c = c1 - '0';
5558 else if( c1 >= 'a' && c1 <= 'f' )
5559 c = c1 - 'a' + 10;
5560 else if( c1 >= 'A' && c1 <= 'F' )
5561 c = c1 - 'A' + 10;
5562 else {
5563 mpi_clear(val);
5564 return 1;
5565 }
5566 c <<= 4;
5567 if( c2 >= '0' && c2 <= '9' )
5568 c |= c2 - '0';
5569 else if( c2 >= 'a' && c2 <= 'f' )
5570 c |= c2 - 'a' + 10;
5571 else if( c2 >= 'A' && c2 <= 'F' )
5572 c |= c2 - 'A' + 10;
5573 else {
5574 mpi_clear(val);
5575 return 1;
5576 }
5577 a <<= 8;
5578 a |= c;
5579 }
5580 i = 0;
5581 val->d[j-1] = a;
5582 }
5583
5584 return 0;
5585 }
5586
5587
5588 /****************
5589 * print an MPI to the given stream and return the number of characters
5590 * printed.
5591 */
5592 int
5593 mpi_print( FILE *fp, MPI a, int mode )
5594 {
5595 int i, n=0;
5596
5597 if( a == NULL )
5598 return fprintf(fp, "[MPI_NULL]");
5599 if( !mode ) {
5600 unsigned int n1;
5601
5602 n1 = mpi_get_nbits(a);
5603 n += fprintf(fp, "[%u bits]", n1);
5604 }
5605 else {
5606 if( a->sign )
5607 putc('-', fp);
5608 #if BYTES_PER_MPI_LIMB == 2
5609 #define X "4"
5610 #elif BYTES_PER_MPI_LIMB == 4
5611 #define X "8"
5612 #elif BYTES_PER_MPI_LIMB == 8
5613 #define X "16"
5614 #else
5615 #error please define the format here
5616 #endif
5617 for(i=a->nlimbs; i > 0 ; i-- ) {
5618 n += fprintf(fp, i!=a->nlimbs? "%0" X "lX":"%lX", (ulong)a->d[i-1]);
5619 #undef X
5620 }
5621 if( !a->nlimbs )
5622 putc('0', fp );
5623 }
5624 return n;
5625 }
5626
5627
5628 /*
5629 void
5630 g10_log_mpidump( const char *text, MPI a )
5631 {
5632 FILE *fp = log_stream();
5633
5634 g10_log_print_prefix(text);
5635 mpi_print(fp, a, 1 );
5636 fputc('\n', fp);
5637 }
5638 */
5639
5640
5641 /****************
5642 * Return an xmalloced buffer with the MPI (msb first).
5643 * NBYTES receives the length of this buffer. Caller must free the
5644 * return string (This function does return a 0 byte buffer with NBYTES
5645 * set to zero if the value of A is zero. If sign is not NULL, it will
5646 * be set to the sign of the A.
5647 */
5648 static byte *
5649 do_get_buffer( MPI a, unsigned *nbytes, int *sign, int force_secure )
5650 {
5651 byte *p, *buffer;
5652 mpi_limb_t alimb;
5653 int i;
5654 unsigned int n;
5655
5656 if( sign )
5657 *sign = a->sign;
5658 *nbytes = n = a->nlimbs * BYTES_PER_MPI_LIMB;
5659 if (!n)
5660 n++; /* avoid zero length allocation */
5661 p = buffer = force_secure || mpi_is_secure(a) ? xmalloc_secure(n)
5662 : xmalloc(n);
5663
5664 for(i=a->nlimbs-1; i >= 0; i-- ) {
5665 alimb = a->d[i];
5666 #if BYTES_PER_MPI_LIMB == 4
5667 *p++ = alimb >> 24;
5668 *p++ = alimb >> 16;
5669 *p++ = alimb >> 8;
5670 *p++ = alimb ;
5671 #elif BYTES_PER_MPI_LIMB == 8
5672 *p++ = alimb >> 56;
5673 *p++ = alimb >> 48;
5674 *p++ = alimb >> 40;
5675 *p++ = alimb >> 32;
5676 *p++ = alimb >> 24;
5677 *p++ = alimb >> 16;
5678 *p++ = alimb >> 8;
5679 *p++ = alimb ;
5680 #else
5681 #error please implement for this limb size.
5682 #endif
5683 }
5684
5685 /* this is sub-optimal but we need to do the shift operation
5686 * because the caller has to free the returned buffer */
5687 for(p=buffer; !*p && *nbytes; p++, --*nbytes )
5688 ;
5689 if( p != buffer )
5690 memmove(buffer,p, *nbytes);
5691
5692 return buffer;
5693 }
5694
5695
5696 byte *
5697 mpi_get_buffer( MPI a, unsigned *nbytes, int *sign )
5698 {
5699 return do_get_buffer( a, nbytes, sign, 0 );
5700 }
5701
5702 byte *
5703 mpi_get_secure_buffer( MPI a, unsigned *nbytes, int *sign )
5704 {
5705 return do_get_buffer( a, nbytes, sign, 1 );
5706 }
5707
5708 /****************
5709 * Use BUFFER to update MPI.
5710 */
5711 void
5712 mpi_set_buffer( MPI a, const byte *buffer, unsigned nbytes, int sign )
5713 {
5714 const byte *p;
5715 mpi_limb_t alimb;
5716 int nlimbs;
5717 int i;
5718
5719 nlimbs = (nbytes + BYTES_PER_MPI_LIMB - 1) / BYTES_PER_MPI_LIMB;
5720 RESIZE_IF_NEEDED(a, nlimbs);
5721 a->sign = sign;
5722
5723 for(i=0, p = buffer+nbytes-1; p >= buffer+BYTES_PER_MPI_LIMB; ) {
5724 #if BYTES_PER_MPI_LIMB == 4
5725 alimb = (mpi_limb_t)*p-- ;
5726 alimb |= (mpi_limb_t)*p-- << 8 ;
5727 alimb |= (mpi_limb_t)*p-- << 16 ;
5728 alimb |= (mpi_limb_t)*p-- << 24 ;
5729 #elif BYTES_PER_MPI_LIMB == 8
5730 alimb = (mpi_limb_t)*p-- ;
5731 alimb |= (mpi_limb_t)*p-- << 8 ;
5732 alimb |= (mpi_limb_t)*p-- << 16 ;
5733 alimb |= (mpi_limb_t)*p-- << 24 ;
5734 alimb |= (mpi_limb_t)*p-- << 32 ;
5735 alimb |= (mpi_limb_t)*p-- << 40 ;
5736 alimb |= (mpi_limb_t)*p-- << 48 ;
5737 alimb |= (mpi_limb_t)*p-- << 56 ;
5738 #else
5739 #error please implement for this limb size.
5740 #endif
5741 a->d[i++] = alimb;
5742 }
5743 if( p >= buffer ) {
5744 #if BYTES_PER_MPI_LIMB == 4
5745 alimb = *p-- ;
5746 if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 8 ;
5747 if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 16 ;
5748 if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 24 ;
5749 #elif BYTES_PER_MPI_LIMB == 8
5750 alimb = (mpi_limb_t)*p-- ;
5751 if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 8 ;
5752 if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 16 ;
5753 if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 24 ;
5754 if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 32 ;
5755 if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 40 ;
5756 if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 48 ;
5757 if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 56 ;
5758 #else
5759 #error please implement for this limb size.
5760 #endif
5761 a->d[i++] = alimb;
5762 }
5763 a->nlimbs = i;
5764 assert( i == nlimbs );
5765 }
-
+ B5713900ED6F31370C3136B3BEBC4A96603A0F319D1E75ABD706219BD6FDD5C5105F9E33275DF06ABD1321552FFC342DCF41C15CC28873FAEE616A0D62974467
smg_comms/mpi/mpih-add1.c
(0 . 0)(1 . 59)
5770 /* mpihelp-add_1.c - MPI helper functions
5771 * Modified by No Such Labs. (C) 2015. See README.
5772 *
5773 * This file was originally part of Gnu Privacy Guard (GPG), ver. 1.4.10,
5774 * SHA256(gnupg-1.4.10.tar.gz):
5775 * 0bfd74660a2f6cedcf7d8256db4a63c996ffebbcdc2cf54397bfb72878c5a85a
5776 * (C) 1994-2005 Free Software Foundation, Inc.
5777 *
5778 * This program is free software: you can redistribute it and/or modify
5779 * it under the terms of the GNU General Public License as published by
5780 * the Free Software Foundation, either version 3 of the License, or
5781 * (at your option) any later version.
5782 *
5783 * This program is distributed in the hope that it will be useful,
5784 * but WITHOUT ANY WARRANTY; without even the implied warranty of
5785 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5786 * GNU General Public License for more details.
5787 *
5788 * You should have received a copy of the GNU General Public License
5789 * along with this program. If not, see <http://www.gnu.org/licenses/>.
5790 */
5791
5792 #include <stdio.h>
5793 #include <stdlib.h>
5794
5795 #include "knobs.h"
5796 #include "mpi-internal.h"
5797 #include "longlong.h"
5798
5799 mpi_limb_t
5800 mpihelp_add_n( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
5801 mpi_ptr_t s2_ptr, mpi_size_t size)
5802 {
5803 mpi_limb_t x, y, cy;
5804 mpi_size_t j;
5805
5806 /* The loop counter and index J goes from -SIZE to -1. This way
5807 the loop becomes faster. */
5808 j = -size;
5809
5810 /* Offset the base pointers to compensate for the negative indices. */
5811 s1_ptr -= j;
5812 s2_ptr -= j;
5813 res_ptr -= j;
5814
5815 cy = 0;
5816 do {
5817 y = s2_ptr[j];
5818 x = s1_ptr[j];
5819 y += cy; /* add previous carry to one addend */
5820 cy = y < cy; /* get out carry from that addition */
5821 y += x; /* add other addend */
5822 cy += y < x; /* get out carry from that add, combine */
5823 res_ptr[j] = y;
5824 } while( ++j );
5825
5826 return cy;
5827 }
5828
-
+ E789CEA1E3A670F80F48773AE523B6BA57FA5BDBC170D552037871C9E22F04BC697ED636C9DCC13BDAF1DDC7E86748CEE33CF8519F619E8E6F7F4486A549C881
smg_comms/mpi/mpih-cmp.c
(0 . 0)(1 . 55)
5833 /* mpihelp-sub.c - MPI helper functions
5834 * Modified by No Such Labs. (C) 2015. See README.
5835 *
5836 * This file was originally part of Gnu Privacy Guard (GPG), ver. 1.4.10,
5837 * SHA256(gnupg-1.4.10.tar.gz):
5838 * 0bfd74660a2f6cedcf7d8256db4a63c996ffebbcdc2cf54397bfb72878c5a85a
5839 * (C) 1994-2005 Free Software Foundation, Inc.
5840 *
5841 * This program is free software: you can redistribute it and/or modify
5842 * it under the terms of the GNU General Public License as published by
5843 * the Free Software Foundation, either version 3 of the License, or
5844 * (at your option) any later version.
5845 *
5846 * This program is distributed in the hope that it will be useful,
5847 * but WITHOUT ANY WARRANTY; without even the implied warranty of
5848 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5849 * GNU General Public License for more details.
5850 *
5851 * You should have received a copy of the GNU General Public License
5852 * along with this program. If not, see <http://www.gnu.org/licenses/>.
5853 */
5854
5855 #include <stdio.h>
5856 #include <stdlib.h>
5857
5858 #include "knobs.h"
5859 #include "mpi-internal.h"
5860
5861 /****************
5862 * Compare OP1_PTR/OP1_SIZE with OP2_PTR/OP2_SIZE.
5863 * There are no restrictions on the relative sizes of
5864 * the two arguments.
5865 * Return 1 if OP1 > OP2, 0 if they are equal, and -1 if OP1 < OP2.
5866 */
5867 int
5868 mpihelp_cmp( mpi_ptr_t op1_ptr, mpi_ptr_t op2_ptr, mpi_size_t size )
5869 {
5870 mpi_size_t i;
5871 mpi_limb_t op1_word, op2_word;
5872
5873 for( i = size - 1; i >= 0 ; i--) {
5874 op1_word = op1_ptr[i];
5875 op2_word = op2_ptr[i];
5876 if( op1_word != op2_word )
5877 goto diff;
5878 }
5879 return 0;
5880
5881 diff:
5882 /* This can *not* be simplified to
5883 * op2_word - op2_word
5884 * since that expression might give signed overflow. */
5885 return (op1_word > op2_word) ? 1 : -1;
5886 }
5887
-
+ 49EF731356E9C2E54D04CB0F5C4A68285AD1CA1C27015AACEFDA5F0CB5AC676A0DC47B1656AB2057E1CFFCC58E837B1010E85391A8F570CCDDA24630B28620F7
smg_comms/mpi/mpih-div.c
(0 . 0)(1 . 529)
5892 /* mpihelp-div.c - MPI helper functions
5893 * Modified by No Such Labs. (C) 2015. See README.
5894 *
5895 * This file was originally part of Gnu Privacy Guard (GPG), ver. 1.4.10,
5896 * SHA256(gnupg-1.4.10.tar.gz):
5897 * 0bfd74660a2f6cedcf7d8256db4a63c996ffebbcdc2cf54397bfb72878c5a85a
5898 * (C) 1994-2005 Free Software Foundation, Inc.
5899 *
5900 * This program is free software: you can redistribute it and/or modify
5901 * it under the terms of the GNU General Public License as published by
5902 * the Free Software Foundation, either version 3 of the License, or
5903 * (at your option) any later version.
5904 *
5905 * This program is distributed in the hope that it will be useful,
5906 * but WITHOUT ANY WARRANTY; without even the implied warranty of
5907 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5908 * GNU General Public License for more details.
5909 *
5910 * You should have received a copy of the GNU General Public License
5911 * along with this program. If not, see <http://www.gnu.org/licenses/>.
5912 */
5913
5914 #include <stdio.h>
5915 #include <stdlib.h>
5916
5917 #include "knobs.h"
5918 #include "mpi-internal.h"
5919 #include "longlong.h"
5920
5921 #ifndef UMUL_TIME
5922 #define UMUL_TIME 1
5923 #endif
5924 #ifndef UDIV_TIME
5925 #define UDIV_TIME UMUL_TIME
5926 #endif
5927
5928 /* FIXME: We should be using invert_limb (or invert_normalized_limb)
5929 * here (not udiv_qrnnd).
5930 */
5931
5932 mpi_limb_t
5933 mpihelp_mod_1(mpi_ptr_t dividend_ptr, mpi_size_t dividend_size,
5934 mpi_limb_t divisor_limb)
5935 {
5936 mpi_size_t i;
5937 mpi_limb_t n1, n0, r;
5938 int dummy;
5939
5940 /* Botch: Should this be handled at all? Rely on callers? */
5941 if( !dividend_size )
5942 return 0;
5943
5944 /* If multiplication is much faster than division, and the
5945 * dividend is large, pre-invert the divisor, and use
5946 * only multiplications in the inner loop.
5947 *
5948 * This test should be read:
5949 * Does it ever help to use udiv_qrnnd_preinv?
5950 * && Does what we save compensate for the inversion overhead?
5951 */
5952 if( UDIV_TIME > (2 * UMUL_TIME + 6)
5953 && (UDIV_TIME - (2 * UMUL_TIME + 6)) * dividend_size > UDIV_TIME ) {
5954 int normalization_steps;
5955
5956 count_leading_zeros( normalization_steps, divisor_limb );
5957 if( normalization_steps ) {
5958 mpi_limb_t divisor_limb_inverted;
5959
5960 divisor_limb <<= normalization_steps;
5961
5962 /* Compute (2**2N - 2**N * DIVISOR_LIMB) / DIVISOR_LIMB. The
5963 * result is a (N+1)-bit approximation to 1/DIVISOR_LIMB, with the
5964 * most significant bit (with weight 2**N) implicit.
5965 *
5966 * Special case for DIVISOR_LIMB == 100...000.
5967 */
5968 if( !(divisor_limb << 1) )
5969 divisor_limb_inverted = ~(mpi_limb_t)0;
5970 else
5971 udiv_qrnnd(divisor_limb_inverted, dummy,
5972 -divisor_limb, 0, divisor_limb);
5973
5974 n1 = dividend_ptr[dividend_size - 1];
5975 r = n1 >> (BITS_PER_MPI_LIMB - normalization_steps);
5976
5977 /* Possible optimization:
5978 * if (r == 0
5979 * && divisor_limb > ((n1 << normalization_steps)
5980 * | (dividend_ptr[dividend_size - 2] >> ...)))
5981 * ...one division less...
5982 */
5983 for( i = dividend_size - 2; i >= 0; i--) {
5984 n0 = dividend_ptr[i];
5985 UDIV_QRNND_PREINV(dummy, r, r,
5986 ((n1 << normalization_steps)
5987 | (n0 >> (BITS_PER_MPI_LIMB - normalization_steps))),
5988 divisor_limb, divisor_limb_inverted);
5989 n1 = n0;
5990 }
5991 UDIV_QRNND_PREINV(dummy, r, r,
5992 n1 << normalization_steps,
5993 divisor_limb, divisor_limb_inverted);
5994 return r >> normalization_steps;
5995 }
5996 else {
5997 mpi_limb_t divisor_limb_inverted;
5998
5999 /* Compute (2**2N - 2**N * DIVISOR_LIMB) / DIVISOR_LIMB. The
6000 * result is a (N+1)-bit approximation to 1/DIVISOR_LIMB, with the
6001 * most significant bit (with weight 2**N) implicit.
6002 *
6003 * Special case for DIVISOR_LIMB == 100...000.
6004 */
6005 if( !(divisor_limb << 1) )
6006 divisor_limb_inverted = ~(mpi_limb_t)0;
6007 else
6008 udiv_qrnnd(divisor_limb_inverted, dummy,
6009 -divisor_limb, 0, divisor_limb);
6010
6011 i = dividend_size - 1;
6012 r = dividend_ptr[i];
6013
6014 if( r >= divisor_limb )
6015 r = 0;
6016 else
6017 i--;
6018
6019 for( ; i >= 0; i--) {
6020 n0 = dividend_ptr[i];
6021 UDIV_QRNND_PREINV(dummy, r, r,
6022 n0, divisor_limb, divisor_limb_inverted);
6023 }
6024 return r;
6025 }
6026 }
6027 else {
6028 if( UDIV_NEEDS_NORMALIZATION ) {
6029 int normalization_steps;
6030
6031 count_leading_zeros(normalization_steps, divisor_limb);
6032 if( normalization_steps ) {
6033 divisor_limb <<= normalization_steps;
6034
6035 n1 = dividend_ptr[dividend_size - 1];
6036 r = n1 >> (BITS_PER_MPI_LIMB - normalization_steps);
6037
6038 /* Possible optimization:
6039 * if (r == 0
6040 * && divisor_limb > ((n1 << normalization_steps)
6041 * | (dividend_ptr[dividend_size - 2] >> ...)))
6042 * ...one division less...
6043 */
6044 for(i = dividend_size - 2; i >= 0; i--) {
6045 n0 = dividend_ptr[i];
6046 udiv_qrnnd (dummy, r, r,
6047 ((n1 << normalization_steps)
6048 | (n0 >> (BITS_PER_MPI_LIMB - normalization_steps))),
6049 divisor_limb);
6050 n1 = n0;
6051 }
6052 udiv_qrnnd (dummy, r, r,
6053 n1 << normalization_steps,
6054 divisor_limb);
6055 return r >> normalization_steps;
6056 }
6057 }
6058 /* No normalization needed, either because udiv_qrnnd doesn't require
6059 * it, or because DIVISOR_LIMB is already normalized. */
6060 i = dividend_size - 1;
6061 r = dividend_ptr[i];
6062
6063 if(r >= divisor_limb)
6064 r = 0;
6065 else
6066 i--;
6067
6068 for(; i >= 0; i--) {
6069 n0 = dividend_ptr[i];
6070 udiv_qrnnd (dummy, r, r, n0, divisor_limb);
6071 }
6072 return r;
6073 }
6074 }
6075
6076 /* Divide num (NP/NSIZE) by den (DP/DSIZE) and write
6077 * the NSIZE-DSIZE least significant quotient limbs at QP
6078 * and the DSIZE long remainder at NP. If QEXTRA_LIMBS is
6079 * non-zero, generate that many fraction bits and append them after the
6080 * other quotient limbs.
6081 * Return the most significant limb of the quotient, this is always 0 or 1.
6082 *
6083 * Preconditions:
6084 * 0. NSIZE >= DSIZE.
6085 * 1. The most significant bit of the divisor must be set.
6086 * 2. QP must either not overlap with the input operands at all, or
6087 * QP + DSIZE >= NP must hold true. (This means that it's
6088 * possible to put the quotient in the high part of NUM, right after the
6089 * remainder in NUM.
6090 * 3. NSIZE >= DSIZE, even if QEXTRA_LIMBS is non-zero.
6091 */
6092
6093 mpi_limb_t
6094 mpihelp_divrem( mpi_ptr_t qp, mpi_size_t qextra_limbs,
6095 mpi_ptr_t np, mpi_size_t nsize,
6096 mpi_ptr_t dp, mpi_size_t dsize)
6097 {
6098 mpi_limb_t most_significant_q_limb = 0;
6099
6100 switch(dsize) {
6101 case 0:
6102 /* We are asked to divide by zero, so go ahead and do it! (To make
6103 the compiler not remove this statement, return the value.) */
6104 return 1 / dsize;
6105
6106 case 1:
6107 {
6108 mpi_size_t i;
6109 mpi_limb_t n1;
6110 mpi_limb_t d;
6111
6112 d = dp[0];
6113 n1 = np[nsize - 1];
6114
6115 if( n1 >= d ) {
6116 n1 -= d;
6117 most_significant_q_limb = 1;
6118 }
6119
6120 qp += qextra_limbs;
6121 for( i = nsize - 2; i >= 0; i--)
6122 udiv_qrnnd( qp[i], n1, n1, np[i], d );
6123 qp -= qextra_limbs;
6124
6125 for( i = qextra_limbs - 1; i >= 0; i-- )
6126 udiv_qrnnd (qp[i], n1, n1, 0, d);
6127
6128 np[0] = n1;
6129 }
6130 break;
6131
6132 case 2:
6133 {
6134 mpi_size_t i;
6135 mpi_limb_t n1, n0, n2;
6136 mpi_limb_t d1, d0;
6137
6138 np += nsize - 2;
6139 d1 = dp[1];
6140 d0 = dp[0];
6141 n1 = np[1];
6142 n0 = np[0];
6143
6144 if( n1 >= d1 && (n1 > d1 || n0 >= d0) ) {
6145 sub_ddmmss (n1, n0, n1, n0, d1, d0);
6146 most_significant_q_limb = 1;
6147 }
6148
6149 for( i = qextra_limbs + nsize - 2 - 1; i >= 0; i-- ) {
6150 mpi_limb_t q;
6151 mpi_limb_t r;
6152
6153 if( i >= qextra_limbs )
6154 np--;
6155 else
6156 np[0] = 0;
6157
6158 if( n1 == d1 ) {
6159 /* Q should be either 111..111 or 111..110. Need special
6160 * treatment of this rare case as normal division would
6161 * give overflow. */
6162 q = ~(mpi_limb_t)0;
6163
6164 r = n0 + d1;
6165 if( r < d1 ) { /* Carry in the addition? */
6166 add_ssaaaa( n1, n0, r - d0, np[0], 0, d0 );
6167 qp[i] = q;
6168 continue;
6169 }
6170 n1 = d0 - (d0 != 0?1:0);
6171 n0 = -d0;
6172 }
6173 else {
6174 udiv_qrnnd (q, r, n1, n0, d1);
6175 umul_ppmm (n1, n0, d0, q);
6176 }
6177
6178 n2 = np[0];
6179 q_test:
6180 if( n1 > r || (n1 == r && n0 > n2) ) {
6181 /* The estimated Q was too large. */
6182 q--;
6183 sub_ddmmss (n1, n0, n1, n0, 0, d0);
6184 r += d1;
6185 if( r >= d1 ) /* If not carry, test Q again. */
6186 goto q_test;
6187 }
6188
6189 qp[i] = q;
6190 sub_ddmmss (n1, n0, r, n2, n1, n0);
6191 }
6192 np[1] = n1;
6193 np[0] = n0;
6194 }
6195 break;
6196
6197 default:
6198 {
6199 mpi_size_t i;
6200 mpi_limb_t dX, d1, n0;
6201
6202 np += nsize - dsize;
6203 dX = dp[dsize - 1];
6204 d1 = dp[dsize - 2];
6205 n0 = np[dsize - 1];
6206
6207 if( n0 >= dX ) {
6208 if(n0 > dX || mpihelp_cmp(np, dp, dsize - 1) >= 0 ) {
6209 mpihelp_sub_n(np, np, dp, dsize);
6210 n0 = np[dsize - 1];
6211 most_significant_q_limb = 1;
6212 }
6213 }
6214
6215 for( i = qextra_limbs + nsize - dsize - 1; i >= 0; i--) {
6216 mpi_limb_t q;
6217 mpi_limb_t n1, n2;
6218 mpi_limb_t cy_limb;
6219
6220 if( i >= qextra_limbs ) {
6221 np--;
6222 n2 = np[dsize];
6223 }
6224 else {
6225 n2 = np[dsize - 1];
6226 MPN_COPY_DECR (np + 1, np, dsize - 1);
6227 np[0] = 0;
6228 }
6229
6230 if( n0 == dX ) {
6231 /* This might over-estimate q, but it's probably not worth
6232 * the extra code here to find out. */
6233 q = ~(mpi_limb_t)0;
6234 }
6235 else {
6236 mpi_limb_t r;
6237
6238 udiv_qrnnd(q, r, n0, np[dsize - 1], dX);
6239 umul_ppmm(n1, n0, d1, q);
6240
6241 while( n1 > r || (n1 == r && n0 > np[dsize - 2])) {
6242 q--;
6243 r += dX;
6244 if( r < dX ) /* I.e. "carry in previous addition?" */
6245 break;
6246 n1 -= n0 < d1;
6247 n0 -= d1;
6248 }
6249 }
6250
6251 /* Possible optimization: We already have (q * n0) and (1 * n1)
6252 * after the calculation of q. Taking advantage of that, we
6253 * could make this loop make two iterations less. */
6254 cy_limb = mpihelp_submul_1(np, dp, dsize, q);
6255
6256 if( n2 != cy_limb ) {
6257 mpihelp_add_n(np, np, dp, dsize);
6258 q--;
6259 }
6260
6261 qp[i] = q;
6262 n0 = np[dsize - 1];
6263 }
6264 }
6265 }
6266
6267 return most_significant_q_limb;
6268 }
6269
6270
6271 /****************
6272 * Divide (DIVIDEND_PTR,,DIVIDEND_SIZE) by DIVISOR_LIMB.
6273 * Write DIVIDEND_SIZE limbs of quotient at QUOT_PTR.
6274 * Return the single-limb remainder.
6275 * There are no constraints on the value of the divisor.
6276 *
6277 * QUOT_PTR and DIVIDEND_PTR might point to the same limb.
6278 */
6279
6280 mpi_limb_t
6281 mpihelp_divmod_1( mpi_ptr_t quot_ptr,
6282 mpi_ptr_t dividend_ptr, mpi_size_t dividend_size,
6283 mpi_limb_t divisor_limb)
6284 {
6285 mpi_size_t i;
6286 mpi_limb_t n1, n0, r;
6287 int dummy;
6288
6289 if( !dividend_size )
6290 return 0;
6291
6292 /* If multiplication is much faster than division, and the
6293 * dividend is large, pre-invert the divisor, and use
6294 * only multiplications in the inner loop.
6295 *
6296 * This test should be read:
6297 * Does it ever help to use udiv_qrnnd_preinv?
6298 * && Does what we save compensate for the inversion overhead?
6299 */
6300 if( UDIV_TIME > (2 * UMUL_TIME + 6)
6301 && (UDIV_TIME - (2 * UMUL_TIME + 6)) * dividend_size > UDIV_TIME ) {
6302 int normalization_steps;
6303
6304 count_leading_zeros( normalization_steps, divisor_limb );
6305 if( normalization_steps ) {
6306 mpi_limb_t divisor_limb_inverted;
6307
6308 divisor_limb <<= normalization_steps;
6309
6310 /* Compute (2**2N - 2**N * DIVISOR_LIMB) / DIVISOR_LIMB. The
6311 * result is a (N+1)-bit approximation to 1/DIVISOR_LIMB, with the
6312 * most significant bit (with weight 2**N) implicit.
6313 */
6314 /* Special case for DIVISOR_LIMB == 100...000. */
6315 if( !(divisor_limb << 1) )
6316 divisor_limb_inverted = ~(mpi_limb_t)0;
6317 else
6318 udiv_qrnnd(divisor_limb_inverted, dummy,
6319 -divisor_limb, 0, divisor_limb);
6320
6321 n1 = dividend_ptr[dividend_size - 1];
6322 r = n1 >> (BITS_PER_MPI_LIMB - normalization_steps);
6323
6324 /* Possible optimization:
6325 * if (r == 0
6326 * && divisor_limb > ((n1 << normalization_steps)
6327 * | (dividend_ptr[dividend_size - 2] >> ...)))
6328 * ...one division less...
6329 */
6330 for( i = dividend_size - 2; i >= 0; i--) {
6331 n0 = dividend_ptr[i];
6332 UDIV_QRNND_PREINV( quot_ptr[i + 1], r, r,
6333 ((n1 << normalization_steps)
6334 | (n0 >> (BITS_PER_MPI_LIMB - normalization_steps))),
6335 divisor_limb, divisor_limb_inverted);
6336 n1 = n0;
6337 }
6338 UDIV_QRNND_PREINV( quot_ptr[0], r, r,
6339 n1 << normalization_steps,
6340 divisor_limb, divisor_limb_inverted);
6341 return r >> normalization_steps;
6342 }
6343 else {
6344 mpi_limb_t divisor_limb_inverted;
6345
6346 /* Compute (2**2N - 2**N * DIVISOR_LIMB) / DIVISOR_LIMB. The
6347 * result is a (N+1)-bit approximation to 1/DIVISOR_LIMB, with the
6348 * most significant bit (with weight 2**N) implicit.
6349 */
6350 /* Special case for DIVISOR_LIMB == 100...000. */
6351 if( !(divisor_limb << 1) )
6352 divisor_limb_inverted = ~(mpi_limb_t) 0;
6353 else
6354 udiv_qrnnd(divisor_limb_inverted, dummy,
6355 -divisor_limb, 0, divisor_limb);
6356
6357 i = dividend_size - 1;
6358 r = dividend_ptr[i];
6359
6360 if( r >= divisor_limb )
6361 r = 0;
6362 else
6363 quot_ptr[i--] = 0;
6364
6365 for( ; i >= 0; i-- ) {
6366 n0 = dividend_ptr[i];
6367 UDIV_QRNND_PREINV( quot_ptr[i], r, r,
6368 n0, divisor_limb, divisor_limb_inverted);
6369 }
6370 return r;
6371 }
6372 }
6373 else {
6374 if(UDIV_NEEDS_NORMALIZATION) {
6375 int normalization_steps;
6376
6377 count_leading_zeros (normalization_steps, divisor_limb);
6378 if( normalization_steps ) {
6379 divisor_limb <<= normalization_steps;
6380
6381 n1 = dividend_ptr[dividend_size - 1];
6382 r = n1 >> (BITS_PER_MPI_LIMB - normalization_steps);
6383
6384 /* Possible optimization:
6385 * if (r == 0
6386 * && divisor_limb > ((n1 << normalization_steps)
6387 * | (dividend_ptr[dividend_size - 2] >> ...)))
6388 * ...one division less...
6389 */
6390 for( i = dividend_size - 2; i >= 0; i--) {
6391 n0 = dividend_ptr[i];
6392 udiv_qrnnd (quot_ptr[i + 1], r, r,
6393 ((n1 << normalization_steps)
6394 | (n0 >> (BITS_PER_MPI_LIMB - normalization_steps))),
6395 divisor_limb);
6396 n1 = n0;
6397 }
6398 udiv_qrnnd (quot_ptr[0], r, r,
6399 n1 << normalization_steps,
6400 divisor_limb);
6401 return r >> normalization_steps;
6402 }
6403 }
6404 /* No normalization needed, either because udiv_qrnnd doesn't require
6405 * it, or because DIVISOR_LIMB is already normalized. */
6406 i = dividend_size - 1;
6407 r = dividend_ptr[i];
6408
6409 if(r >= divisor_limb)
6410 r = 0;
6411 else
6412 quot_ptr[i--] = 0;
6413
6414 for(; i >= 0; i--) {
6415 n0 = dividend_ptr[i];
6416 udiv_qrnnd( quot_ptr[i], r, r, n0, divisor_limb );
6417 }
6418 return r;
6419 }
6420 }
-
+ B4153B7F9F829152CA1273195628566628CA4EED54792C61CD58EC4481F83CDED7E0A6DD4E1FB632B10B20314B28A209D2CF1F78A684A64F7A9002B6E00FB2B9
smg_comms/mpi/mpih-lshift.c
(0 . 0)(1 . 64)
6425 /* mpihelp-lshift.c - MPI helper functions
6426 * Modified by No Such Labs. (C) 2015. See README.
6427 *
6428 * This file was originally part of Gnu Privacy Guard (GPG), ver. 1.4.10,
6429 * SHA256(gnupg-1.4.10.tar.gz):
6430 * 0bfd74660a2f6cedcf7d8256db4a63c996ffebbcdc2cf54397bfb72878c5a85a
6431 * (C) 1994-2005 Free Software Foundation, Inc.
6432 *
6433 * This program is free software: you can redistribute it and/or modify
6434 * it under the terms of the GNU General Public License as published by
6435 * the Free Software Foundation, either version 3 of the License, or
6436 * (at your option) any later version.
6437 *
6438 * This program is distributed in the hope that it will be useful,
6439 * but WITHOUT ANY WARRANTY; without even the implied warranty of
6440 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6441 * GNU General Public License for more details.
6442 *
6443 * You should have received a copy of the GNU General Public License
6444 * along with this program. If not, see <http://www.gnu.org/licenses/>.
6445 */
6446
6447 #include <stdio.h>
6448 #include <stdlib.h>
6449
6450 #include "knobs.h"
6451 #include "mpi-internal.h"
6452
6453 /* Shift U (pointed to by UP and USIZE digits long) CNT bits to the left
6454 * and store the USIZE least significant digits of the result at WP.
6455 * Return the bits shifted out from the most significant digit.
6456 *
6457 * Argument constraints:
6458 * 1. 0 < CNT < BITS_PER_MP_LIMB
6459 * 2. If the result is to be written over the input, WP must be >= UP.
6460 */
6461
6462 mpi_limb_t
6463 mpihelp_lshift( mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize,
6464 unsigned int cnt)
6465 {
6466 mpi_limb_t high_limb, low_limb;
6467 unsigned sh_1, sh_2;
6468 mpi_size_t i;
6469 mpi_limb_t retval;
6470
6471 sh_1 = cnt;
6472 wp += 1;
6473 sh_2 = BITS_PER_MPI_LIMB - sh_1;
6474 i = usize - 1;
6475 low_limb = up[i];
6476 retval = low_limb >> sh_2;
6477 high_limb = low_limb;
6478 while( --i >= 0 ) {
6479 low_limb = up[i];
6480 wp[i] = (high_limb << sh_1) | (low_limb >> sh_2);
6481 high_limb = low_limb;
6482 }
6483 wp[i] = high_limb << sh_1;
6484
6485 return retval;
6486 }
6487
6488
-
+ 1C5BD39C13569D58A5CFD542D96DF998B63EFD14EDFCDB9488975B69DD7796B21EF656577E9DA950CECE9D9122B7030395F0714CBBA2983B3DAFC860B34C1B85
smg_comms/mpi/mpih-mul.c
(0 . 0)(1 . 519)
6493 /* mpihelp-mul.c - MPI helper functions
6494 * Modified by No Such Labs. (C) 2015. See README.
6495 *
6496 * This file was originally part of Gnu Privacy Guard (GPG), ver. 1.4.10,
6497 * SHA256(gnupg-1.4.10.tar.gz):
6498 * 0bfd74660a2f6cedcf7d8256db4a63c996ffebbcdc2cf54397bfb72878c5a85a
6499 * (C) 1994-2005 Free Software Foundation, Inc.
6500 *
6501 * This program is free software: you can redistribute it and/or modify
6502 * it under the terms of the GNU General Public License as published by
6503 * the Free Software Foundation, either version 3 of the License, or
6504 * (at your option) any later version.
6505 *
6506 * This program is distributed in the hope that it will be useful,
6507 * but WITHOUT ANY WARRANTY; without even the implied warranty of
6508 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6509 * GNU General Public License for more details.
6510 *
6511 * You should have received a copy of the GNU General Public License
6512 * along with this program. If not, see <http://www.gnu.org/licenses/>.
6513 */
6514
6515 #include <stdio.h>
6516 #include <stdlib.h>
6517 #include <string.h>
6518
6519 #include "knobs.h"
6520 #include "mpi-internal.h"
6521 #include "longlong.h"
6522
6523
6524 #define MPN_MUL_N_RECURSE(prodp, up, vp, size, tspace) \
6525 do { \
6526 if( (size) < KARATSUBA_THRESHOLD ) \
6527 mul_n_basecase (prodp, up, vp, size); \
6528 else \
6529 mul_n (prodp, up, vp, size, tspace); \
6530 } while (0);
6531
6532 #define MPN_SQR_N_RECURSE(prodp, up, size, tspace) \
6533 do { \
6534 if ((size) < KARATSUBA_THRESHOLD) \
6535 mpih_sqr_n_basecase (prodp, up, size); \
6536 else \
6537 mpih_sqr_n (prodp, up, size, tspace); \
6538 } while (0);
6539
6540
6541 /* Multiply the natural numbers u (pointed to by UP) and v (pointed to by VP),
6542 * both with SIZE limbs, and store the result at PRODP. 2 * SIZE limbs are
6543 * always stored. Return the most significant limb.
6544 *
6545 * Argument constraints:
6546 * 1. PRODP != UP and PRODP != VP, i.e. the destination
6547 * must be distinct from the multiplier and the multiplicand.
6548 *
6549 *
6550 * Handle simple cases with traditional multiplication.
6551 *
6552 * This is the most critical code of multiplication. All multiplies rely
6553 * on this, both small and huge. Small ones arrive here immediately. Huge
6554 * ones arrive here as this is the base case for Karatsuba's recursive
6555 * algorithm below.
6556 */
6557
6558 static mpi_limb_t
6559 mul_n_basecase( mpi_ptr_t prodp, mpi_ptr_t up,
6560 mpi_ptr_t vp, mpi_size_t size)
6561 {
6562 mpi_size_t i;
6563 mpi_limb_t cy;
6564 mpi_limb_t v_limb;
6565
6566 /* Multiply by the first limb in V separately, as the result can be
6567 * stored (not added) to PROD. We also avoid a loop for zeroing. */
6568 v_limb = vp[0];
6569 if( v_limb <= 1 ) {
6570 if( v_limb == 1 )
6571 MPN_COPY( prodp, up, size );
6572 else
6573 MPN_ZERO( prodp, size );
6574 cy = 0;
6575 }
6576 else
6577 cy = mpihelp_mul_1( prodp, up, size, v_limb );
6578
6579 prodp[size] = cy;
6580 prodp++;
6581
6582 /* For each iteration in the outer loop, multiply one limb from
6583 * U with one limb from V, and add it to PROD. */
6584 for( i = 1; i < size; i++ ) {
6585 v_limb = vp[i];
6586 if( v_limb <= 1 ) {
6587 cy = 0;
6588 if( v_limb == 1 )
6589 cy = mpihelp_add_n(prodp, prodp, up, size);
6590 }
6591 else
6592 cy = mpihelp_addmul_1(prodp, up, size, v_limb);
6593
6594 prodp[size] = cy;
6595 prodp++;
6596 }
6597
6598 return cy;
6599 }
6600
6601
6602 static void
6603 mul_n( mpi_ptr_t prodp, mpi_ptr_t up, mpi_ptr_t vp,
6604 mpi_size_t size, mpi_ptr_t tspace )
6605 {
6606 if( size & 1 ) {
6607 /* The size is odd, and the code below doesn't handle that.
6608 * Multiply the least significant (size - 1) limbs with a recursive
6609 * call, and handle the most significant limb of S1 and S2
6610 * separately.
6611 * A slightly faster way to do this would be to make the Karatsuba
6612 * code below behave as if the size were even, and let it check for
6613 * odd size in the end. I.e., in essence move this code to the end.
6614 * Doing so would save us a recursive call, and potentially make the
6615 * stack grow a lot less.
6616 */
6617 mpi_size_t esize = size - 1; /* even size */
6618 mpi_limb_t cy_limb;
6619
6620 MPN_MUL_N_RECURSE( prodp, up, vp, esize, tspace );
6621 cy_limb = mpihelp_addmul_1( prodp + esize, up, esize, vp[esize] );
6622 prodp[esize + esize] = cy_limb;
6623 cy_limb = mpihelp_addmul_1( prodp + esize, vp, size, up[esize] );
6624 prodp[esize + size] = cy_limb;
6625 }
6626 else {
6627 /* Anatolij Alekseevich Karatsuba's divide-and-conquer algorithm.
6628 *
6629 * Split U in two pieces, U1 and U0, such that
6630 * U = U0 + U1*(B**n),
6631 * and V in V1 and V0, such that
6632 * V = V0 + V1*(B**n).
6633 *
6634 * UV is then computed recursively using the identity
6635 *
6636 * 2n n n n
6637 * UV = (B + B )U V + B (U -U )(V -V ) + (B + 1)U V
6638 * 1 1 1 0 0 1 0 0
6639 *
6640 * Where B = 2**BITS_PER_MP_LIMB.
6641 */
6642 mpi_size_t hsize = size >> 1;
6643 mpi_limb_t cy;
6644 int negflg;
6645
6646 /* Product H. ________________ ________________
6647 * |_____U1 x V1____||____U0 x V0_____|
6648 * Put result in upper part of PROD and pass low part of TSPACE
6649 * as new TSPACE.
6650 */
6651 MPN_MUL_N_RECURSE(prodp + size, up + hsize, vp + hsize, hsize, tspace);
6652
6653 /* Product M. ________________
6654 * |_(U1-U0)(V0-V1)_|
6655 */
6656 if( mpihelp_cmp(up + hsize, up, hsize) >= 0 ) {
6657 mpihelp_sub_n(prodp, up + hsize, up, hsize);
6658 negflg = 0;
6659 }
6660 else {
6661 mpihelp_sub_n(prodp, up, up + hsize, hsize);
6662 negflg = 1;
6663 }
6664 if( mpihelp_cmp(vp + hsize, vp, hsize) >= 0 ) {
6665 mpihelp_sub_n(prodp + hsize, vp + hsize, vp, hsize);
6666 negflg ^= 1;
6667 }
6668 else {
6669 mpihelp_sub_n(prodp + hsize, vp, vp + hsize, hsize);
6670 /* No change of NEGFLG. */
6671 }
6672 /* Read temporary operands from low part of PROD.
6673 * Put result in low part of TSPACE using upper part of TSPACE
6674 * as new TSPACE.
6675 */
6676 MPN_MUL_N_RECURSE(tspace, prodp, prodp + hsize, hsize, tspace + size);
6677
6678 /* Add/copy product H. */
6679 MPN_COPY (prodp + hsize, prodp + size, hsize);
6680 cy = mpihelp_add_n( prodp + size, prodp + size,
6681 prodp + size + hsize, hsize);
6682
6683 /* Add product M (if NEGFLG M is a negative number) */
6684 if(negflg)
6685 cy -= mpihelp_sub_n(prodp + hsize, prodp + hsize, tspace, size);
6686 else
6687 cy += mpihelp_add_n(prodp + hsize, prodp + hsize, tspace, size);
6688
6689 /* Product L. ________________ ________________
6690 * |________________||____U0 x V0_____|
6691 * Read temporary operands from low part of PROD.
6692 * Put result in low part of TSPACE using upper part of TSPACE
6693 * as new TSPACE.
6694 */
6695 MPN_MUL_N_RECURSE(tspace, up, vp, hsize, tspace + size);
6696
6697 /* Add/copy Product L (twice) */
6698
6699 cy += mpihelp_add_n(prodp + hsize, prodp + hsize, tspace, size);
6700 if( cy )
6701 mpihelp_add_1(prodp + hsize + size, prodp + hsize + size, hsize, cy);
6702
6703 MPN_COPY(prodp, tspace, hsize);
6704 cy = mpihelp_add_n(prodp + hsize, prodp + hsize, tspace + hsize, hsize);
6705 if( cy )
6706 mpihelp_add_1(prodp + size, prodp + size, size, 1);
6707 }
6708 }
6709
6710
6711 void
6712 mpih_sqr_n_basecase( mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t size )
6713 {
6714 mpi_size_t i;
6715 mpi_limb_t cy_limb;
6716 mpi_limb_t v_limb;
6717
6718 /* Multiply by the first limb in V separately, as the result can be
6719 * stored (not added) to PROD. We also avoid a loop for zeroing. */
6720 v_limb = up[0];
6721 if( v_limb <= 1 ) {
6722 if( v_limb == 1 )
6723 MPN_COPY( prodp, up, size );
6724 else
6725 MPN_ZERO(prodp, size);
6726 cy_limb = 0;
6727 }
6728 else
6729 cy_limb = mpihelp_mul_1( prodp, up, size, v_limb );
6730
6731 prodp[size] = cy_limb;
6732 prodp++;
6733
6734 /* For each iteration in the outer loop, multiply one limb from
6735 * U with one limb from V, and add it to PROD. */
6736 for( i=1; i < size; i++) {
6737 v_limb = up[i];
6738 if( v_limb <= 1 ) {
6739 cy_limb = 0;
6740 if( v_limb == 1 )
6741 cy_limb = mpihelp_add_n(prodp, prodp, up, size);
6742 }
6743 else
6744 cy_limb = mpihelp_addmul_1(prodp, up, size, v_limb);
6745
6746 prodp[size] = cy_limb;
6747 prodp++;
6748 }
6749 }
6750
6751
6752 void
6753 mpih_sqr_n( mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t size, mpi_ptr_t tspace)
6754 {
6755 if( size & 1 ) {
6756 /* The size is odd, and the code below doesn't handle that.
6757 * Multiply the least significant (size - 1) limbs with a recursive
6758 * call, and handle the most significant limb of S1 and S2
6759 * separately.
6760 * A slightly faster way to do this would be to make the Karatsuba
6761 * code below behave as if the size were even, and let it check for
6762 * odd size in the end. I.e., in essence move this code to the end.
6763 * Doing so would save us a recursive call, and potentially make the
6764 * stack grow a lot less.
6765 */
6766 mpi_size_t esize = size - 1; /* even size */
6767 mpi_limb_t cy_limb;
6768
6769 MPN_SQR_N_RECURSE( prodp, up, esize, tspace );
6770 cy_limb = mpihelp_addmul_1( prodp + esize, up, esize, up[esize] );
6771 prodp[esize + esize] = cy_limb;
6772 cy_limb = mpihelp_addmul_1( prodp + esize, up, size, up[esize] );
6773
6774 prodp[esize + size] = cy_limb;
6775 }
6776 else {
6777 mpi_size_t hsize = size >> 1;
6778 mpi_limb_t cy;
6779
6780 /* Product H. ________________ ________________
6781 * |_____U1 x U1____||____U0 x U0_____|
6782 * Put result in upper part of PROD and pass low part of TSPACE
6783 * as new TSPACE.
6784 */
6785 MPN_SQR_N_RECURSE(prodp + size, up + hsize, hsize, tspace);
6786
6787 /* Product M. ________________
6788 * |_(U1-U0)(U0-U1)_|
6789 */
6790 if( mpihelp_cmp( up + hsize, up, hsize) >= 0 )
6791 mpihelp_sub_n( prodp, up + hsize, up, hsize);
6792 else
6793 mpihelp_sub_n (prodp, up, up + hsize, hsize);
6794
6795 /* Read temporary operands from low part of PROD.
6796 * Put result in low part of TSPACE using upper part of TSPACE
6797 * as new TSPACE. */
6798 MPN_SQR_N_RECURSE(tspace, prodp, hsize, tspace + size);
6799
6800 /* Add/copy product H */
6801 MPN_COPY(prodp + hsize, prodp + size, hsize);
6802 cy = mpihelp_add_n(prodp + size, prodp + size,
6803 prodp + size + hsize, hsize);
6804
6805 /* Add product M (if NEGFLG M is a negative number). */
6806 cy -= mpihelp_sub_n (prodp + hsize, prodp + hsize, tspace, size);
6807
6808 /* Product L. ________________ ________________
6809 * |________________||____U0 x U0_____|
6810 * Read temporary operands from low part of PROD.
6811 * Put result in low part of TSPACE using upper part of TSPACE
6812 * as new TSPACE. */
6813 MPN_SQR_N_RECURSE (tspace, up, hsize, tspace + size);
6814
6815 /* Add/copy Product L (twice). */
6816 cy += mpihelp_add_n (prodp + hsize, prodp + hsize, tspace, size);
6817 if( cy )
6818 mpihelp_add_1(prodp + hsize + size, prodp + hsize + size,
6819 hsize, cy);
6820
6821 MPN_COPY(prodp, tspace, hsize);
6822 cy = mpihelp_add_n (prodp + hsize, prodp + hsize, tspace + hsize, hsize);
6823 if( cy )
6824 mpihelp_add_1 (prodp + size, prodp + size, size, 1);
6825 }
6826 }
6827
6828
6829 /* This should be made into an inline function in gmp.h. */
6830 void
6831 mpihelp_mul_n( mpi_ptr_t prodp, mpi_ptr_t up, mpi_ptr_t vp, mpi_size_t size)
6832 {
6833 int secure;
6834
6835 if( up == vp ) {
6836 if( size < KARATSUBA_THRESHOLD )
6837 mpih_sqr_n_basecase( prodp, up, size );
6838 else {
6839 mpi_ptr_t tspace;
6840 secure = m_is_secure( up );
6841 tspace = mpi_alloc_limb_space( 2 * size, secure );
6842 mpih_sqr_n( prodp, up, size, tspace );
6843 mpi_free_limb_space( tspace );
6844 }
6845 }
6846 else {
6847 if( size < KARATSUBA_THRESHOLD )
6848 mul_n_basecase( prodp, up, vp, size );
6849 else {
6850 mpi_ptr_t tspace;
6851 secure = m_is_secure( up ) || m_is_secure( vp );
6852 tspace = mpi_alloc_limb_space( 2 * size, secure );
6853 mul_n (prodp, up, vp, size, tspace);
6854 mpi_free_limb_space( tspace );
6855 }
6856 }
6857 }
6858
6859
6860
6861 void
6862 mpihelp_mul_karatsuba_case( mpi_ptr_t prodp,
6863 mpi_ptr_t up, mpi_size_t usize,
6864 mpi_ptr_t vp, mpi_size_t vsize,
6865 struct karatsuba_ctx *ctx )
6866 {
6867 mpi_limb_t cy;
6868
6869 if( !ctx->tspace || ctx->tspace_size < vsize ) {
6870 if( ctx->tspace )
6871 mpi_free_limb_space( ctx->tspace );
6872 ctx->tspace = mpi_alloc_limb_space( 2 * vsize,
6873 m_is_secure( up ) || m_is_secure( vp ) );
6874 ctx->tspace_size = vsize;
6875 }
6876
6877 MPN_MUL_N_RECURSE( prodp, up, vp, vsize, ctx->tspace );
6878
6879 prodp += vsize;
6880 up += vsize;
6881 usize -= vsize;
6882 if( usize >= vsize ) {
6883 if( !ctx->tp || ctx->tp_size < vsize ) {
6884 if( ctx->tp )
6885 mpi_free_limb_space( ctx->tp );
6886 ctx->tp = mpi_alloc_limb_space( 2 * vsize, m_is_secure( up )
6887 || m_is_secure( vp ) );
6888 ctx->tp_size = vsize;
6889 }
6890
6891 do {
6892 MPN_MUL_N_RECURSE( ctx->tp, up, vp, vsize, ctx->tspace );
6893 cy = mpihelp_add_n( prodp, prodp, ctx->tp, vsize );
6894 mpihelp_add_1( prodp + vsize, ctx->tp + vsize, vsize, cy );
6895 prodp += vsize;
6896 up += vsize;
6897 usize -= vsize;
6898 } while( usize >= vsize );
6899 }
6900
6901 if( usize ) {
6902 if( usize < KARATSUBA_THRESHOLD ) {
6903 mpihelp_mul( ctx->tspace, vp, vsize, up, usize );
6904 }
6905 else {
6906 if( !ctx->next ) {
6907 ctx->next = xmalloc_clear( sizeof *ctx );
6908 }
6909 mpihelp_mul_karatsuba_case( ctx->tspace,
6910 vp, vsize,
6911 up, usize,
6912 ctx->next );
6913 }
6914
6915 cy = mpihelp_add_n( prodp, prodp, ctx->tspace, vsize);
6916 mpihelp_add_1( prodp + vsize, ctx->tspace + vsize, usize, cy );
6917 }
6918 }
6919
6920
6921 void
6922 mpihelp_release_karatsuba_ctx( struct karatsuba_ctx *ctx )
6923 {
6924 struct karatsuba_ctx *ctx2;
6925
6926 if( ctx->tp )
6927 mpi_free_limb_space( ctx->tp );
6928 if( ctx->tspace )
6929 mpi_free_limb_space( ctx->tspace );
6930 for( ctx=ctx->next; ctx; ctx = ctx2 ) {
6931 ctx2 = ctx->next;
6932 if( ctx->tp )
6933 mpi_free_limb_space( ctx->tp );
6934 if( ctx->tspace )
6935 mpi_free_limb_space( ctx->tspace );
6936 xfree( ctx );
6937 }
6938 }
6939
6940 /* Multiply the natural numbers u (pointed to by UP, with USIZE limbs)
6941 * and v (pointed to by VP, with VSIZE limbs), and store the result at
6942 * PRODP. USIZE + VSIZE limbs are always stored, but if the input
6943 * operands are normalized. Return the most significant limb of the
6944 * result.
6945 *
6946 * NOTE: The space pointed to by PRODP is overwritten before finished
6947 * with U and V, so overlap is an error.
6948 *
6949 * Argument constraints:
6950 * 1. USIZE >= VSIZE.
6951 * 2. PRODP != UP and PRODP != VP, i.e. the destination
6952 * must be distinct from the multiplier and the multiplicand.
6953 */
6954
6955 mpi_limb_t
6956 mpihelp_mul( mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t usize,
6957 mpi_ptr_t vp, mpi_size_t vsize)
6958 {
6959 mpi_ptr_t prod_endp = prodp + usize + vsize - 1;
6960 mpi_limb_t cy;
6961 struct karatsuba_ctx ctx;
6962
6963 if( vsize < KARATSUBA_THRESHOLD ) {
6964 mpi_size_t i;
6965 mpi_limb_t v_limb;
6966
6967 if( !vsize )
6968 return 0;
6969
6970 /* Multiply by the first limb in V separately, as the result can be
6971 * stored (not added) to PROD. We also avoid a loop for zeroing. */
6972 v_limb = vp[0];
6973 if( v_limb <= 1 ) {
6974 if( v_limb == 1 )
6975 MPN_COPY( prodp, up, usize );
6976 else
6977 MPN_ZERO( prodp, usize );
6978 cy = 0;
6979 }
6980 else
6981 cy = mpihelp_mul_1( prodp, up, usize, v_limb );
6982
6983 prodp[usize] = cy;
6984 prodp++;
6985
6986 /* For each iteration in the outer loop, multiply one limb from
6987 * U with one limb from V, and add it to PROD. */
6988 for( i = 1; i < vsize; i++ ) {
6989 v_limb = vp[i];
6990 if( v_limb <= 1 ) {
6991 cy = 0;
6992 if( v_limb == 1 )
6993 cy = mpihelp_add_n(prodp, prodp, up, usize);
6994 }
6995 else
6996 cy = mpihelp_addmul_1(prodp, up, usize, v_limb);
6997
6998 prodp[usize] = cy;
6999 prodp++;
7000 }
7001
7002 return cy;
7003 }
7004
7005 memset( &ctx, 0, sizeof ctx );
7006 mpihelp_mul_karatsuba_case( prodp, up, usize, vp, vsize, &ctx );
7007 mpihelp_release_karatsuba_ctx( &ctx );
7008 return *prod_endp;
7009 }
7010
7011
-
+ 2FCC124504ADC576636A56BC387F7F6B73C60B263ED01A7DFFA2C2131F89AA6D337399EF9DB92C5423D25BA596A898AD1160AC1EAB5D49768AEAB14D08C29466
smg_comms/mpi/mpih-mul1.c
(0 . 0)(1 . 56)
7016 /* mpihelp-mul_1.c - MPI helper functions
7017 * Modified by No Such Labs. (C) 2015. See README.
7018 *
7019 * This file was originally part of Gnu Privacy Guard (GPG), ver. 1.4.10,
7020 * SHA256(gnupg-1.4.10.tar.gz):
7021 * 0bfd74660a2f6cedcf7d8256db4a63c996ffebbcdc2cf54397bfb72878c5a85a
7022 * (C) 1994-2005 Free Software Foundation, Inc.
7023 *
7024 * This program is free software: you can redistribute it and/or modify
7025 * it under the terms of the GNU General Public License as published by
7026 * the Free Software Foundation, either version 3 of the License, or
7027 * (at your option) any later version.
7028 *
7029 * This program is distributed in the hope that it will be useful,
7030 * but WITHOUT ANY WARRANTY; without even the implied warranty of
7031 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7032 * GNU General Public License for more details.
7033 *
7034 * You should have received a copy of the GNU General Public License
7035 * along with this program. If not, see <http://www.gnu.org/licenses/>.
7036 */
7037
7038 #include <stdio.h>
7039 #include <stdlib.h>
7040
7041 #include "knobs.h"
7042 #include "mpi-internal.h"
7043 #include "longlong.h"
7044
7045 mpi_limb_t
7046 mpihelp_mul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size,
7047 mpi_limb_t s2_limb)
7048 {
7049 mpi_limb_t cy_limb;
7050 mpi_size_t j;
7051 mpi_limb_t prod_high, prod_low;
7052
7053 /* The loop counter and index J goes from -S1_SIZE to -1. This way
7054 * the loop becomes faster. */
7055 j = -s1_size;
7056
7057 /* Offset the base pointers to compensate for the negative indices. */
7058 s1_ptr -= j;
7059 res_ptr -= j;
7060
7061 cy_limb = 0;
7062 do {
7063 umul_ppmm( prod_high, prod_low, s1_ptr[j], s2_limb );
7064 prod_low += cy_limb;
7065 cy_limb = (prod_low < cy_limb?1:0) + prod_high;
7066 res_ptr[j] = prod_low;
7067 } while( ++j );
7068
7069 return cy_limb;
7070 }
7071
-
+ 3B4CC6335137AE38D7A62B34E1D2319C33371D77B6169AB101B4DF8CE83EE7E10FF859F24626B13AE42AFF8CFFC805FFAA433D53FAF56C5924837AC1FAC0A6F9
smg_comms/mpi/mpih-mul2.c
(0 . 0)(1 . 61)
7076 /* mpihelp-mul_2.c - MPI helper functions
7077 * Modified by No Such Labs. (C) 2015. See README.
7078 *
7079 * This file was originally part of Gnu Privacy Guard (GPG), ver. 1.4.10,
7080 * SHA256(gnupg-1.4.10.tar.gz):
7081 * 0bfd74660a2f6cedcf7d8256db4a63c996ffebbcdc2cf54397bfb72878c5a85a
7082 * (C) 1994-2005 Free Software Foundation, Inc.
7083 *
7084 * This program is free software: you can redistribute it and/or modify
7085 * it under the terms of the GNU General Public License as published by
7086 * the Free Software Foundation, either version 3 of the License, or
7087 * (at your option) any later version.
7088 *
7089 * This program is distributed in the hope that it will be useful,
7090 * but WITHOUT ANY WARRANTY; without even the implied warranty of
7091 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7092 * GNU General Public License for more details.
7093 *
7094 * You should have received a copy of the GNU General Public License
7095 * along with this program. If not, see <http://www.gnu.org/licenses/>.
7096 */
7097
7098 #include <stdio.h>
7099 #include <stdlib.h>
7100
7101 #include "knobs.h"
7102 #include "mpi-internal.h"
7103 #include "longlong.h"
7104
7105
7106 mpi_limb_t
7107 mpihelp_addmul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
7108 mpi_size_t s1_size, mpi_limb_t s2_limb)
7109 {
7110 mpi_limb_t cy_limb;
7111 mpi_size_t j;
7112 mpi_limb_t prod_high, prod_low;
7113 mpi_limb_t x;
7114
7115 /* The loop counter and index J goes from -SIZE to -1. This way
7116 * the loop becomes faster. */
7117 j = -s1_size;
7118 res_ptr -= j;
7119 s1_ptr -= j;
7120
7121 cy_limb = 0;
7122 do {
7123 umul_ppmm( prod_high, prod_low, s1_ptr[j], s2_limb );
7124
7125 prod_low += cy_limb;
7126 cy_limb = (prod_low < cy_limb?1:0) + prod_high;
7127
7128 x = res_ptr[j];
7129 prod_low = x + prod_low;
7130 cy_limb += prod_low < x?1:0;
7131 res_ptr[j] = prod_low;
7132 } while ( ++j );
7133 return cy_limb;
7134 }
7135
7136
-
+ A6703D0851FB4F5A7C05EA94B0EA1C9DF3B79379B43C55EF10481496984DC6B58C3B26FC009607EDE37917758CC7576065049C5A511EEE7E0B9048E1A1B06654
smg_comms/mpi/mpih-mul3.c
(0 . 0)(1 . 62)
7141 /* mpihelp-mul_3.c - MPI helper functions
7142 * Modified by No Such Labs. (C) 2015. See README.
7143 *
7144 * This file was originally part of Gnu Privacy Guard (GPG), ver. 1.4.10,
7145 * SHA256(gnupg-1.4.10.tar.gz):
7146 * 0bfd74660a2f6cedcf7d8256db4a63c996ffebbcdc2cf54397bfb72878c5a85a
7147 * (C) 1994-2005 Free Software Foundation, Inc.
7148 *
7149 * This program is free software: you can redistribute it and/or modify
7150 * it under the terms of the GNU General Public License as published by
7151 * the Free Software Foundation, either version 3 of the License, or
7152 * (at your option) any later version.
7153 *
7154 * This program is distributed in the hope that it will be useful,
7155 * but WITHOUT ANY WARRANTY; without even the implied warranty of
7156 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7157 * GNU General Public License for more details.
7158 *
7159 * You should have received a copy of the GNU General Public License
7160 * along with this program. If not, see <http://www.gnu.org/licenses/>.
7161 */
7162
7163 #include <stdio.h>
7164 #include <stdlib.h>
7165
7166 #include "knobs.h"
7167 #include "mpi-internal.h"
7168 #include "longlong.h"
7169
7170
7171 mpi_limb_t
7172 mpihelp_submul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
7173 mpi_size_t s1_size, mpi_limb_t s2_limb)
7174 {
7175 mpi_limb_t cy_limb;
7176 mpi_size_t j;
7177 mpi_limb_t prod_high, prod_low;
7178 mpi_limb_t x;
7179
7180 /* The loop counter and index J goes from -SIZE to -1. This way
7181 * the loop becomes faster. */
7182 j = -s1_size;
7183 res_ptr -= j;
7184 s1_ptr -= j;
7185
7186 cy_limb = 0;
7187 do {
7188 umul_ppmm( prod_high, prod_low, s1_ptr[j], s2_limb);
7189
7190 prod_low += cy_limb;
7191 cy_limb = (prod_low < cy_limb?1:0) + prod_high;
7192
7193 x = res_ptr[j];
7194 prod_low = x - prod_low;
7195 cy_limb += prod_low > x?1:0;
7196 res_ptr[j] = prod_low;
7197 } while( ++j );
7198
7199 return cy_limb;
7200 }
7201
7202
-
+ FB51D6B55D5E9B7ADA61CE8C50C3958A5D8B38CD1673683437D572EF52469C428A68C2926739EEE75EF379DB77C713F4BD8506B53A7E259E2CE9516E23AC44EF
smg_comms/mpi/mpih-rshift.c
(0 . 0)(1 . 62)
7207 /* mpih-rshift.c - MPI helper functions
7208 * Modified by No Such Labs. (C) 2015. See README.
7209 *
7210 * This file was originally part of Gnu Privacy Guard (GPG), ver. 1.4.10,
7211 * SHA256(gnupg-1.4.10.tar.gz):
7212 * 0bfd74660a2f6cedcf7d8256db4a63c996ffebbcdc2cf54397bfb72878c5a85a
7213 * (C) 1994-2005 Free Software Foundation, Inc.
7214 *
7215 * This program is free software: you can redistribute it and/or modify
7216 * it under the terms of the GNU General Public License as published by
7217 * the Free Software Foundation, either version 3 of the License, or
7218 * (at your option) any later version.
7219 *
7220 * This program is distributed in the hope that it will be useful,
7221 * but WITHOUT ANY WARRANTY; without even the implied warranty of
7222 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7223 * GNU General Public License for more details.
7224 *
7225 * You should have received a copy of the GNU General Public License
7226 * along with this program. If not, see <http://www.gnu.org/licenses/>.
7227 */
7228
7229 #include <stdio.h>
7230 #include <stdlib.h>
7231
7232 #include "knobs.h"
7233 #include "mpi-internal.h"
7234
7235
7236 /* Shift U (pointed to by UP and USIZE limbs long) CNT bits to the right
7237 * and store the USIZE least significant limbs of the result at WP.
7238 * The bits shifted out to the right are returned.
7239 *
7240 * Argument constraints:
7241 * 1. 0 < CNT < BITS_PER_MP_LIMB
7242 * 2. If the result is to be written over the input, WP must be <= UP.
7243 */
7244
7245 mpi_limb_t
7246 mpihelp_rshift( mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize, unsigned cnt)
7247 {
7248 mpi_limb_t high_limb, low_limb;
7249 unsigned sh_1, sh_2;
7250 mpi_size_t i;
7251 mpi_limb_t retval;
7252
7253 sh_1 = cnt;
7254 wp -= 1;
7255 sh_2 = BITS_PER_MPI_LIMB - sh_1;
7256 high_limb = up[0];
7257 retval = high_limb << sh_2;
7258 low_limb = high_limb;
7259 for( i=1; i < usize; i++) {
7260 high_limb = up[i];
7261 wp[i] = (low_limb >> sh_1) | (high_limb << sh_2);
7262 low_limb = high_limb;
7263 }
7264 wp[i] = low_limb >> sh_1;
7265
7266 return retval;
7267 }
7268
-
+ 88C8DFD8A7CBBC742FE8E01121C9166DC010BA16554277137ECE7642BB6C9D94183EA6D23F4118D2BCD7A2A31A399A22A7A264EA178C0CE0BD4A2D0BF18F149F
smg_comms/mpi/mpih-sub1.c
(0 . 0)(1 . 60)
7273 /* mpihelp-add_2.c - MPI helper functions
7274 * Modified by No Such Labs. (C) 2015. See README.
7275 *
7276 * This file was originally part of Gnu Privacy Guard (GPG), ver. 1.4.10,
7277 * SHA256(gnupg-1.4.10.tar.gz):
7278 * 0bfd74660a2f6cedcf7d8256db4a63c996ffebbcdc2cf54397bfb72878c5a85a
7279 * (C) 1994-2005 Free Software Foundation, Inc.
7280 *
7281 * This program is free software: you can redistribute it and/or modify
7282 * it under the terms of the GNU General Public License as published by
7283 * the Free Software Foundation, either version 3 of the License, or
7284 * (at your option) any later version.
7285 *
7286 * This program is distributed in the hope that it will be useful,
7287 * but WITHOUT ANY WARRANTY; without even the implied warranty of
7288 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7289 * GNU General Public License for more details.
7290 *
7291 * You should have received a copy of the GNU General Public License
7292 * along with this program. If not, see <http://www.gnu.org/licenses/>.
7293 */
7294
7295 #include <stdio.h>
7296 #include <stdlib.h>
7297
7298 #include "knobs.h"
7299 #include "mpi-internal.h"
7300 #include "longlong.h"
7301
7302 mpi_limb_t
7303 mpihelp_sub_n( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
7304 mpi_ptr_t s2_ptr, mpi_size_t size)
7305 {
7306 mpi_limb_t x, y, cy;
7307 mpi_size_t j;
7308
7309 /* The loop counter and index J goes from -SIZE to -1. This way
7310 the loop becomes faster. */
7311 j = -size;
7312
7313 /* Offset the base pointers to compensate for the negative indices. */
7314 s1_ptr -= j;
7315 s2_ptr -= j;
7316 res_ptr -= j;
7317
7318 cy = 0;
7319 do {
7320 y = s2_ptr[j];
7321 x = s1_ptr[j];
7322 y += cy; /* add previous carry to subtrahend */
7323 cy = y < cy; /* get out carry from that addition */
7324 y = x - y; /* main subtract */
7325 cy += y > x; /* get out carry from the subtract, combine */
7326 res_ptr[j] = y;
7327 } while( ++j );
7328
7329 return cy;
7330 }
7331
7332
-
+ D98F0266D7C1F2466393E4951BABE3A7289CF8133821FBAF3BD139383AA5E14FC1CDAB87C6329AB6790B250CE9F141B2B7F935804EC43BC5A4933A2932A8178B
smg_comms/mpi/mpiutil.c
(0 . 0)(1 . 517)
7337 /* mpiutil.ac - Utility functions for MPI
7338 * Modified by No Such Labs. (C) 2015. See README.
7339 * Modified by S.MG, 2018. Added mpi_get_alloced(MPI a)
7340 *
7341 * This file was originally part of Gnu Privacy Guard (GPG), ver. 1.4.10,
7342 * SHA256(gnupg-1.4.10.tar.gz):
7343 * 0bfd74660a2f6cedcf7d8256db4a63c996ffebbcdc2cf54397bfb72878c5a85a
7344 * (C) 1994-2005 Free Software Foundation, Inc.
7345 *
7346 * This program is free software: you can redistribute it and/or modify
7347 * it under the terms of the GNU General Public License as published by
7348 * the Free Software Foundation, either version 3 of the License, or
7349 * (at your option) any later version.
7350 *
7351 * This program is distributed in the hope that it will be useful,
7352 * but WITHOUT ANY WARRANTY; without even the implied warranty of
7353 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7354 * GNU General Public License for more details.
7355 *
7356 * You should have received a copy of the GNU General Public License
7357 * along with this program. If not, see <http://www.gnu.org/licenses/>.
7358 */
7359
7360 #include <stdio.h>
7361 #include <stdlib.h>
7362 #include <string.h>
7363 #include <assert.h>
7364
7365 #include "knobs.h"
7366 #include "mpi.h"
7367 #include "mpi-internal.h"
7368 #include "memory.h"
7369 #include "util.h"
7370
7371
7372 #ifdef M_DEBUG
7373 #undef mpi_alloc
7374 #undef mpi_alloc_secure
7375 #undef mpi_free
7376 #endif
7377
7378 /****************
7379 * Note: It was a bad idea to use the number of limbs to allocate
7380 * because on a alpha the limbs are large but we normally need
7381 * integers of n bits - So we should chnage this to bits (or bytes).
7382 *
7383 * But mpi_alloc is used in a lot of places :-)
7384 */
7385 MPI
7386 #ifdef M_DEBUG
7387 mpi_debug_alloc( unsigned nlimbs, const char *info )
7388 #else
7389 mpi_alloc( unsigned nlimbs )
7390 #endif
7391 {
7392 MPI a;
7393
7394 if( DBG_MEMORY )
7395 log_debug("mpi_alloc(%u)\n", nlimbs*BITS_PER_MPI_LIMB );
7396 #ifdef M_DEBUG
7397 a = m_debug_alloc( sizeof *a, info );
7398 a->d = nlimbs? mpi_debug_alloc_limb_space( nlimbs, 0, info ) : NULL;
7399 #else
7400 a = xmalloc( sizeof *a );
7401 a->d = nlimbs? mpi_alloc_limb_space( nlimbs, 0 ) : NULL;
7402 #endif
7403 a->alloced = nlimbs;
7404 a->nlimbs = 0;
7405 a->sign = 0;
7406 a->flags = 0;
7407 a->nbits = 0;
7408 return a;
7409 }
7410
7411 void
7412 mpi_m_check( MPI a )
7413 {
7414 m_check(a);
7415 m_check(a->d);
7416 }
7417
7418 MPI
7419 #ifdef M_DEBUG
7420 mpi_debug_alloc_secure( unsigned nlimbs, const char *info )
7421 #else
7422 mpi_alloc_secure( unsigned nlimbs )
7423 #endif
7424 {
7425 MPI a;
7426
7427 if( DBG_MEMORY )
7428 log_debug("mpi_alloc_secure(%u)\n", nlimbs*BITS_PER_MPI_LIMB );
7429 #ifdef M_DEBUG
7430 a = m_debug_alloc( sizeof *a, info );
7431 a->d = nlimbs? mpi_debug_alloc_limb_space( nlimbs, 1, info ) : NULL;
7432 #else
7433 a = xmalloc( sizeof *a );
7434 a->d = nlimbs? mpi_alloc_limb_space( nlimbs, 1 ) : NULL;
7435 #endif
7436 a->alloced = nlimbs;
7437 a->flags = 1;
7438 a->nlimbs = 0;
7439 a->sign = 0;
7440 a->nbits = 0;
7441 return a;
7442 }
7443
7444
7445 #if 0
7446 static void *unused_limbs_5;
7447 static void *unused_limbs_32;
7448 static void *unused_limbs_64;
7449 #endif
7450
7451 mpi_ptr_t
7452 #ifdef M_DEBUG
7453 mpi_debug_alloc_limb_space( unsigned nlimbs, int secure, const char *info )
7454 #else
7455 mpi_alloc_limb_space( unsigned nlimbs, int secure )
7456 #endif
7457 {
7458 size_t len = nlimbs * sizeof(mpi_limb_t);
7459 mpi_ptr_t p;
7460
7461 if( DBG_MEMORY )
7462 log_debug("mpi_alloc_limb_space(%u)\n", (unsigned)len*8 );
7463 #if 0
7464 if( !secure ) {
7465 if( nlimbs == 5 && unused_limbs_5 ) { /* DSA 160 bits */
7466 p = unused_limbs_5;
7467 unused_limbs_5 = *p;
7468 return p;
7469 }
7470 else if( nlimbs == 32 && unused_limbs_32 ) { /* DSA 1024 bits */
7471 p = unused_limbs_32;
7472 unused_limbs_32 = *p;
7473 return p;
7474 }
7475 else if( nlimbs == 64 && unused_limbs_64 ) { /* DSA 2*1024 bits */
7476 p = unused_limbs_64;
7477 unused_limbs_64 = *p;
7478 return p;
7479 }
7480 }
7481 #endif
7482
7483 #ifdef M_DEBUG
7484 p = secure? m_debug_alloc_secure(len, info):m_debug_alloc( len, info );
7485 #else
7486 p = secure? xmalloc_secure( len ):xmalloc( len );
7487 #endif
7488
7489 return p;
7490 }
7491
7492 void
7493 #ifdef M_DEBUG
7494 mpi_debug_free_limb_space( mpi_ptr_t a, const char *info )
7495 #else
7496 mpi_free_limb_space( mpi_ptr_t a )
7497 #endif
7498 {
7499 if( !a )
7500 return;
7501 if( DBG_MEMORY )
7502 log_debug("mpi_free_limb_space of size %lu\n", (ulong)m_size(a)*8 );
7503
7504 #if 0
7505 if( !m_is_secure(a) ) {
7506 size_t nlimbs = m_size(a) / 4 ;
7507 void *p = a;
7508
7509 if( nlimbs == 5 ) { /* DSA 160 bits */
7510 *a = unused_limbs_5;
7511 unused_limbs_5 = a;
7512 return;
7513 }
7514 else if( nlimbs == 32 ) { /* DSA 1024 bits */
7515 *a = unused_limbs_32;
7516 unused_limbs_32 = a;
7517 return;
7518 }
7519 else if( nlimbs == 64 ) { /* DSA 2*1024 bits */
7520 *a = unused_limbs_64;
7521 unused_limbs_64 = a;
7522 return;
7523 }
7524 }
7525 #endif
7526
7527 xfree(a);
7528 }
7529
7530
7531 void
7532 mpi_assign_limb_space( MPI a, mpi_ptr_t ap, unsigned nlimbs )
7533 {
7534 mpi_free_limb_space(a->d);
7535 a->d = ap;
7536 a->alloced = nlimbs;
7537 }
7538
7539
7540
7541 /****************
7542 * Resize the array of A to NLIMBS. the additional space is cleared
7543 * (set to 0) [done by xrealloc()]
7544 */
7545 void
7546 #ifdef M_DEBUG
7547 mpi_debug_resize( MPI a, unsigned nlimbs, const char *info )
7548 #else
7549 mpi_resize( MPI a, unsigned nlimbs )
7550 #endif
7551 {
7552 if( nlimbs <= a->alloced )
7553 return; /* no need to do it */
7554 /* Note: a->secure is not used - instead the realloc functions
7555 * take care of it. Maybe we should drop a->secure completely
7556 * and rely on a mpi_is_secure function, which would be
7557 * a wrapper around m_is_secure
7558 */
7559 #ifdef M_DEBUG
7560 if( a->d )
7561 a->d = m_debug_realloc(a->d, nlimbs * sizeof(mpi_limb_t), info );
7562 else
7563 a->d = m_debug_alloc_clear( nlimbs * sizeof(mpi_limb_t), info );
7564 #else
7565 if( a->d )
7566 a->d = xrealloc(a->d, nlimbs * sizeof(mpi_limb_t) );
7567 else
7568 a->d = xmalloc_clear( nlimbs * sizeof(mpi_limb_t) );
7569 #endif
7570 a->alloced = nlimbs;
7571 }
7572
7573 void
7574 mpi_clear( MPI a )
7575 {
7576 a->nlimbs = 0;
7577 a->nbits = 0;
7578 a->flags = 0;
7579 }
7580
7581
7582 void
7583 #ifdef M_DEBUG
7584 mpi_debug_free( MPI a, const char *info )
7585 #else
7586 mpi_free( MPI a )
7587 #endif
7588 {
7589 if( !a )
7590 return;
7591 if( DBG_MEMORY )
7592 log_debug("mpi_free\n" );
7593 if( a->flags & 4 )
7594 xfree( a->d );
7595 else {
7596 #ifdef M_DEBUG
7597 mpi_debug_free_limb_space(a->d, info);
7598 #else
7599 mpi_free_limb_space(a->d);
7600 #endif
7601 }
7602 if( a->flags & ~7 )
7603 log_bug("invalid flag value in mpi\n");
7604 xfree(a);
7605 }
7606
7607
7608 void
7609 mpi_set_secure( MPI a )
7610 {
7611 mpi_ptr_t ap, bp;
7612
7613 if( (a->flags & 1) )
7614 return;
7615 a->flags |= 1;
7616 ap = a->d;
7617 if( !a->nlimbs ) {
7618 assert(!ap);
7619 return;
7620 }
7621 #ifdef M_DEBUG
7622 bp = mpi_debug_alloc_limb_space( a->nlimbs, 1, "set_secure" );
7623 #else
7624 bp = mpi_alloc_limb_space( a->nlimbs, 1 );
7625 #endif
7626 MPN_COPY( bp, ap, a->nlimbs );
7627 a->d = bp;
7628 #ifdef M_DEBUG
7629 mpi_debug_free_limb_space(ap, "set_secure");
7630 #else
7631 mpi_free_limb_space(ap);
7632 #endif
7633 }
7634
7635
7636 MPI
7637 mpi_set_opaque( MPI a, void *p, unsigned int len )
7638 {
7639 if( !a ) {
7640 #ifdef M_DEBUG
7641 a = mpi_debug_alloc(0,"alloc_opaque");
7642 #else
7643 a = mpi_alloc(0);
7644 #endif
7645 }
7646
7647 if( a->flags & 4 )
7648 xfree( a->d );
7649 else {
7650 #ifdef M_DEBUG
7651 mpi_debug_free_limb_space(a->d, "alloc_opaque");
7652 #else
7653 mpi_free_limb_space(a->d);
7654 #endif
7655 }
7656
7657 a->d = p;
7658 a->alloced = 0;
7659 a->nlimbs = 0;
7660 a->nbits = len;
7661 a->flags = 4;
7662 return a;
7663 }
7664
7665
7666 void *
7667 mpi_get_opaque( MPI a, unsigned int *len )
7668 {
7669 if( !(a->flags & 4) )
7670 log_bug("mpi_get_opaque on normal mpi\n");
7671 if( len )
7672 *len = a->nbits;
7673 return a->d;
7674 }
7675
7676
7677 /****************
7678 * Note: This copy function should not interpret the MPI
7679 * but copy it transparently.
7680 */
7681 MPI
7682 #ifdef M_DEBUG
7683 mpi_debug_copy( MPI a, const char *info )
7684 #else
7685 mpi_copy( MPI a )
7686 #endif
7687 {
7688 int i;
7689 MPI b;
7690
7691 if( a && (a->flags & 4) ) {
7692 void *p = m_is_secure(a->d)? xmalloc_secure( a->nbits )
7693 : xmalloc( a->nbits );
7694 memcpy( p, a->d, a->nbits );
7695 b = mpi_set_opaque( NULL, p, a->nbits );
7696 }
7697 else if( a ) {
7698 #ifdef M_DEBUG
7699 b = mpi_is_secure(a)? mpi_debug_alloc_secure( a->nlimbs, info )
7700 : mpi_debug_alloc( a->nlimbs, info );
7701 #else
7702 b = mpi_is_secure(a)? mpi_alloc_secure( a->nlimbs )
7703 : mpi_alloc( a->nlimbs );
7704 #endif
7705 b->nlimbs = a->nlimbs;
7706 b->sign = a->sign;
7707 b->flags = a->flags;
7708 b->nbits = a->nbits;
7709 for(i=0; i < b->nlimbs; i++ )
7710 b->d[i] = a->d[i];
7711 }
7712 else
7713 b = NULL;
7714 return b;
7715 }
7716
7717
7718 /****************
7719 * This function allocates an MPI which is optimized to hold
7720 * a value as large as the one given in the argument and allocates it
7721 * with the same flags as A.
7722 */
7723 MPI
7724 #ifdef M_DEBUG
7725 mpi_debug_alloc_like( MPI a, const char *info )
7726 #else
7727 mpi_alloc_like( MPI a )
7728 #endif
7729 {
7730 MPI b;
7731
7732 if( a && (a->flags & 4) ) {
7733 void *p = m_is_secure(a->d)? xmalloc_secure( a->nbits )
7734 : xmalloc( a->nbits );
7735 memcpy( p, a->d, a->nbits );
7736 b = mpi_set_opaque( NULL, p, a->nbits );
7737 }
7738 else if( a ) {
7739 #ifdef M_DEBUG
7740 b = mpi_is_secure(a)? mpi_debug_alloc_secure( a->nlimbs, info )
7741 : mpi_debug_alloc( a->nlimbs, info );
7742 #else
7743 b = mpi_is_secure(a)? mpi_alloc_secure( a->nlimbs )
7744 : mpi_alloc( a->nlimbs );
7745 #endif
7746 b->nlimbs = 0;
7747 b->sign = 0;
7748 b->flags = a->flags;
7749 b->nbits = 0;
7750 }
7751 else
7752 b = NULL;
7753 return b;
7754 }
7755
7756
7757 void
7758 mpi_set( MPI w, MPI u)
7759 {
7760 mpi_ptr_t wp, up;
7761 mpi_size_t usize = u->nlimbs;
7762 int usign = u->sign;
7763
7764 RESIZE_IF_NEEDED(w, usize);
7765 wp = w->d;
7766 up = u->d;
7767 MPN_COPY( wp, up, usize );
7768 w->nlimbs = usize;
7769 w->nbits = u->nbits;
7770 w->flags = u->flags;
7771 w->sign = usign;
7772 }
7773
7774
7775 void
7776 mpi_set_ui( MPI w, unsigned long u)
7777 {
7778 RESIZE_IF_NEEDED(w, 1);
7779 w->d[0] = u;
7780 w->nlimbs = u? 1:0;
7781 w->sign = 0;
7782 w->nbits = 0;
7783 w->flags = 0;
7784 }
7785
7786
7787 MPI
7788 mpi_alloc_set_ui( unsigned long u)
7789 {
7790 #ifdef M_DEBUG
7791 MPI w = mpi_debug_alloc(1,"alloc_set_ui");
7792 #else
7793 MPI w = mpi_alloc(1);
7794 #endif
7795 w->d[0] = u;
7796 w->nlimbs = u? 1:0;
7797 w->sign = 0;
7798 return w;
7799 }
7800
7801
7802 void
7803 mpi_swap( MPI a, MPI b)
7804 {
7805 struct gcry_mpi tmp;
7806
7807 tmp = *a; *a = *b; *b = tmp;
7808 }
7809
7810
7811 int
7812 mpi_get_nlimbs (MPI a)
7813 {
7814 return a->nlimbs;
7815 }
7816
7817 /*
7818 * Returns the allocated space for the given MPI, as number of limbs.
7819 */
7820 int
7821 mpi_get_alloced (MPI a)
7822 {
7823 return a->alloced;
7824 }
7825
7826 int
7827 mpi_is_neg (MPI a)
7828 {
7829 return a->sign;
7830 }
7831
7832
7833 /* Return the number of limbs to store an MPI which is specified by
7834 the number of bytes to represent it. */
7835 unsigned int
7836 mpi_nlimb_hint_from_nbytes (unsigned int nbytes)
7837 {
7838 return (nbytes+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB;
7839 }
7840
7841 /* Return the number of limbs to store an MPI which is specified by
7842 the number of bytes to represent it. */
7843 unsigned int
7844 mpi_nlimb_hint_from_nbits (unsigned int nbits)
7845 {
7846 return (nbits+BITS_PER_MPI_LIMB-1) / BITS_PER_MPI_LIMB;
7847 }
7848
7849 unsigned int
7850 mpi_get_flags (MPI a)
7851 {
7852 return a->flags;
7853 }
-
+ F829705D787E0DE60B165CCD6BE182B11C11BC80E43B3B536A2062A7247B102A9EC8906E3D48C0D7EC71D6757678FD573728D12EF3FD3AE2DA9924B7593BC581
smg_comms/mpi/obj/README
(0 . 0)(1 . 1)
7858 S.MG, 2018
-
+ 2B787A241AB819008B23B6235AEC68EA7EA5DC092859FF42FFE50A7BD00D710F39547E35EE66449377FE70BDD870F7BD4B40B7EDE228F6842671C5E167183493
smg_comms/mpi/secmem.c
(0 . 0)(1 . 511)
7863 /* secmem.c - memory allocation from a secure heap
7864 * Modified by No Such Labs. (C) 2015. See README.
7865 *
7866 * This file was originally part of Gnu Privacy Guard (GPG), ver. 1.4.10,
7867 * SHA256(gnupg-1.4.10.tar.gz):
7868 * 0bfd74660a2f6cedcf7d8256db4a63c996ffebbcdc2cf54397bfb72878c5a85a
7869 * (C) 1994-2005 Free Software Foundation, Inc.
7870 *
7871 * This program is free software: you can redistribute it and/or modify
7872 * it under the terms of the GNU General Public License as published by
7873 * the Free Software Foundation, either version 3 of the License, or
7874 * (at your option) any later version.
7875 *
7876 * This program is distributed in the hope that it will be useful,
7877 * but WITHOUT ANY WARRANTY; without even the implied warranty of
7878 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7879 * GNU General Public License for more details.
7880 *
7881 * You should have received a copy of the GNU General Public License
7882 * along with this program. If not, see <http://www.gnu.org/licenses/>.
7883 */
7884
7885 #include "knobs.h"
7886
7887 #include <stdio.h>
7888 #include <stdlib.h>
7889 #include <string.h>
7890 #include <errno.h>
7891 #include <stdarg.h>
7892 #include <unistd.h>
7893 #if defined(HAVE_MLOCK) || defined(HAVE_MMAP)
7894 #include <sys/mman.h>
7895 #include <sys/types.h>
7896 #include <fcntl.h>
7897 #ifdef USE_CAPABILITIES
7898 #include <sys/capability.h>
7899 #endif
7900 #ifdef HAVE_PLOCK
7901 #include <sys/lock.h>
7902 #endif
7903 #endif
7904
7905 #include "types.h"
7906 #include "memory.h"
7907 #include "util.h"
7908
7909 /* MinGW doesn't seem to prototype getpagesize, though it does have
7910 it. */
7911 #if !HAVE_DECL_GETPAGESIZE
7912 int getpagesize(void);
7913 #endif
7914
7915 #if defined(MAP_ANON) && !defined(MAP_ANONYMOUS)
7916 #define MAP_ANONYMOUS MAP_ANON
7917 #endif
7918 /* It seems that Slackware 7.1 does not know about EPERM */
7919 #if !defined(EPERM) && defined(ENOMEM)
7920 #define EPERM ENOMEM
7921 #endif
7922
7923
7924 #define DEFAULT_POOLSIZE 16384
7925
7926 typedef struct memblock_struct MEMBLOCK;
7927 struct memblock_struct {
7928 unsigned size;
7929 union {
7930 MEMBLOCK *next;
7931 PROPERLY_ALIGNED_TYPE aligned;
7932 } u;
7933 };
7934
7935
7936
7937 static void *pool;
7938 static volatile int pool_okay; /* may be checked in an atexit function */
7939 #ifdef HAVE_MMAP
7940 static volatile int pool_is_mmapped;
7941 #endif
7942 static size_t poolsize; /* allocated length */
7943 static size_t poollen; /* used length */
7944 static MEMBLOCK *unused_blocks;
7945 static unsigned max_alloced;
7946 static unsigned cur_alloced;
7947 static unsigned max_blocks;
7948 static unsigned cur_blocks;
7949 static int disable_secmem;
7950 static int show_warning;
7951 static int no_warning;
7952 static int suspend_warning;
7953
7954
7955 static void
7956 print_warn(void)
7957 {
7958 if (!no_warning)
7959 {
7960 log_info("WARNING: using insecure memory!\n");
7961 }
7962 }
7963
7964
7965 static void
7966 lock_pool( void *p, size_t n )
7967 {
7968 #if defined(USE_CAPABILITIES) && defined(HAVE_MLOCK)
7969 int err;
7970
7971 cap_set_proc( cap_from_text("cap_ipc_lock+ep") );
7972 err = mlock( p, n );
7973 if( err && errno )
7974 err = errno;
7975 cap_set_proc( cap_from_text("cap_ipc_lock+p") );
7976
7977 if( err ) {
7978 if( errno != EPERM
7979 #ifdef EAGAIN /* OpenBSD returns this */
7980 && errno != EAGAIN
7981 #endif
7982 #ifdef ENOSYS /* Some SCOs return this (function not implemented) */
7983 && errno != ENOSYS
7984 #endif
7985 #ifdef ENOMEM /* Linux can return this */
7986 && errno != ENOMEM
7987 #endif
7988 )
7989 log_error("can't lock memory: %s\n", strerror(err));
7990 show_warning = 1;
7991 }
7992
7993 #elif defined(HAVE_MLOCK)
7994 uid_t uid;
7995 int err;
7996
7997 uid = getuid();
7998
7999 #ifdef HAVE_BROKEN_MLOCK
8000 /* ick. but at least we get secured memory. about to lock
8001 entire data segment. */
8002 #ifdef HAVE_PLOCK
8003 # ifdef _AIX
8004 /* The configure for AIX returns broken mlock but the plock has
8005 the strange requirement to somehow set the stack limit first.
8006 The problem might turn out in indeterministic program behaviour
8007 and hanging processes which can somehow be solved when enough
8008 processes are clogging up the memory. To get this problem out
8009 of the way we simply don't try to lock the memory at all.
8010 */
8011 errno = EPERM;
8012 err = errno;
8013 # else /* !_AIX */
8014 err = plock( DATLOCK );
8015 if( err && errno )
8016 err = errno;
8017 # endif /*_AIX*/
8018 #else /*!HAVE_PLOCK*/
8019 if( uid ) {
8020 errno = EPERM;
8021 err = errno;
8022 }
8023 else {
8024 err = mlock( p, n );
8025 if( err && errno )
8026 err = errno;
8027 }
8028 #endif /*!HAVE_PLOCK*/
8029 #else
8030 err = mlock( p, n );
8031 if( err && errno )
8032 err = errno;
8033 #endif
8034
8035 if( uid && !geteuid() ) {
8036 /* check that we really dropped the privs.
8037 * Note: setuid(0) should always fail */
8038 if( setuid( uid ) || getuid() != geteuid() || !setuid(0) )
8039 log_fatal("failed to reset uid: %s\n", strerror(errno));
8040 }
8041
8042 if( err ) {
8043 if( errno != EPERM
8044 #ifdef EAGAIN /* OpenBSD returns this */
8045 && errno != EAGAIN
8046 #endif
8047 #ifdef ENOSYS /* Some SCOs return this (function not implemented) */
8048 && errno != ENOSYS
8049 #endif
8050 #ifdef ENOMEM /* Linux can return this */
8051 && errno != ENOMEM
8052 #endif
8053 )
8054 log_error("can't lock memory: %s\n", strerror(err));
8055 show_warning = 1;
8056 }
8057
8058 #elif defined ( __QNX__ )
8059 /* QNX does not page at all, so the whole secure memory stuff does
8060 * not make much sense. However it is still of use because it
8061 * wipes out the memory on a free().
8062 * Therefore it is sufficient to suppress the warning
8063 */
8064 #elif defined (HAVE_DOSISH_SYSTEM) || defined (__CYGWIN__)
8065 /* It does not make sense to print such a warning, given the fact that
8066 * this whole Windows !@#$% and their user base are inherently insecure
8067 */
8068 #else
8069 log_info("Please note that you don't have secure memory on this system\n");
8070 #endif
8071 }
8072
8073
8074 static void
8075 init_pool( size_t n)
8076 {
8077 long int pgsize_val;
8078 size_t pgsize;
8079
8080 poolsize = n;
8081
8082 if( disable_secmem )
8083 log_bug("secure memory is disabled");
8084
8085 #if defined(HAVE_SYSCONF) && defined(_SC_PAGESIZE)
8086 pgsize_val = sysconf (_SC_PAGESIZE);
8087 #elif defined(HAVE_GETPAGESIZE)
8088 pgsize_val = getpagesize ();
8089 #else
8090 pgsize_val = -1;
8091 #endif
8092 pgsize = (pgsize_val != -1 && pgsize_val > 0)? pgsize_val : 4096;
8093
8094
8095 #ifdef HAVE_MMAP
8096 poolsize = (poolsize + pgsize -1 ) & ~(pgsize-1);
8097 #ifdef MAP_ANONYMOUS
8098 pool = mmap( 0, poolsize, PROT_READ|PROT_WRITE,
8099 MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
8100 #else /* map /dev/zero instead */
8101 { int fd;
8102
8103 fd = open("/dev/zero", O_RDWR);
8104 if( fd == -1 ) {
8105 log_error("can't open /dev/zero: %s\n", strerror(errno) );
8106 pool = (void*)-1;
8107 }
8108 else {
8109 pool = mmap( 0, poolsize, PROT_READ|PROT_WRITE,
8110 MAP_PRIVATE, fd, 0);
8111 close (fd);
8112 }
8113 }
8114 #endif
8115 if( pool == (void*)-1 )
8116 log_info("can't mmap pool of %u bytes: %s - using malloc\n",
8117 (unsigned)poolsize, strerror(errno));
8118 else {
8119 pool_is_mmapped = 1;
8120 pool_okay = 1;
8121 }
8122
8123 #endif
8124 if( !pool_okay ) {
8125 pool = malloc( poolsize );
8126 if( !pool )
8127 log_fatal("can't allocate memory pool of %u bytes\n",
8128 (unsigned)poolsize);
8129 else
8130 pool_okay = 1;
8131 }
8132 lock_pool( pool, poolsize );
8133 poollen = 0;
8134 }
8135
8136
8137 /* concatenate unused blocks */
8138 static void
8139 compress_pool(void)
8140 {
8141 /* fixme: we really should do this */
8142 }
8143
8144 void
8145 secmem_set_flags( unsigned flags )
8146 {
8147 int was_susp = suspend_warning;
8148
8149 no_warning = flags & 1;
8150 suspend_warning = flags & 2;
8151
8152 /* and now issue the warning if it is not longer suspended */
8153 if( was_susp && !suspend_warning && show_warning ) {
8154 show_warning = 0;
8155 print_warn();
8156 }
8157 }
8158
8159 unsigned
8160 secmem_get_flags(void)
8161 {
8162 unsigned flags;
8163
8164 flags = no_warning ? 1:0;
8165 flags |= suspend_warning ? 2:0;
8166 return flags;
8167 }
8168
8169 /* Returns 1 if memory was locked, 0 if not. */
8170 int
8171 secmem_init( size_t n )
8172 {
8173 if( !n ) {
8174 #ifdef USE_CAPABILITIES
8175 /* drop all capabilities */
8176 cap_set_proc( cap_from_text("all-eip") );
8177 #elif !defined(HAVE_DOSISH_SYSTEM)
8178 uid_t uid;
8179 disable_secmem=1;
8180 uid = getuid();
8181 if( uid != geteuid() ) {
8182 if( setuid( uid ) || getuid() != geteuid() || !setuid(0) )
8183 log_fatal("failed to drop setuid\n" );
8184 }
8185 #endif
8186 }
8187 else {
8188 if( n < DEFAULT_POOLSIZE )
8189 n = DEFAULT_POOLSIZE;
8190 if( !pool_okay )
8191 init_pool(n);
8192 else
8193 log_error("Oops, secure memory pool already initialized\n");
8194 }
8195
8196 return !show_warning;
8197 }
8198
8199
8200 void *
8201 secmem_malloc( size_t size )
8202 {
8203 MEMBLOCK *mb, *mb2;
8204 int compressed=0;
8205
8206 if( !pool_okay ) {
8207 log_info(
8208 "operation is not possible without initialized secure memory\n");
8209 log_info("(you may have used the wrong program for this task)\n");
8210 exit(2);
8211 }
8212 if( show_warning && !suspend_warning ) {
8213 show_warning = 0;
8214 print_warn();
8215 }
8216
8217 /* Blocks are always a multiple of 32. Note that we allocate an
8218 extra of the size of an entire MEMBLOCK. This is required
8219 becuase we do not only need the SIZE info but also extra space
8220 to chain up unused memory blocks. */
8221 size += sizeof(MEMBLOCK);
8222 size = ((size + 31) / 32) * 32;
8223
8224 retry:
8225 /* try to get it from the used blocks */
8226 for(mb = unused_blocks,mb2=NULL; mb; mb2=mb, mb = mb->u.next )
8227 if( mb->size >= size ) {
8228 if( mb2 )
8229 mb2->u.next = mb->u.next;
8230 else
8231 unused_blocks = mb->u.next;
8232 goto leave;
8233 }
8234 /* allocate a new block */
8235 if( (poollen + size <= poolsize) ) {
8236 mb = (void*)((char*)pool + poollen);
8237 poollen += size;
8238 mb->size = size;
8239 }
8240 else if( !compressed ) {
8241 compressed=1;
8242 compress_pool();
8243 goto retry;
8244 }
8245 else
8246 return NULL;
8247
8248 leave:
8249 cur_alloced += mb->size;
8250 cur_blocks++;
8251 if( cur_alloced > max_alloced )
8252 max_alloced = cur_alloced;
8253 if( cur_blocks > max_blocks )
8254 max_blocks = cur_blocks;
8255
8256 return &mb->u.aligned.c;
8257 }
8258
8259
8260 void *
8261 secmexrealloc( void *p, size_t newsize )
8262 {
8263 MEMBLOCK *mb;
8264 size_t size;
8265 void *a;
8266
8267 mb = (MEMBLOCK*)((char*)p - ((size_t) &((MEMBLOCK*)0)->u.aligned.c));
8268 size = mb->size;
8269 if (size < sizeof(MEMBLOCK))
8270 log_bug ("secure memory corrupted at block %p\n", (void *)mb);
8271 size -= ((size_t) &((MEMBLOCK*)0)->u.aligned.c);
8272
8273 if( newsize <= size )
8274 return p; /* It is easier not to shrink the memory. */
8275 a = secmem_malloc( newsize );
8276 if ( a ) {
8277 memcpy(a, p, size);
8278 memset((char*)a+size, 0, newsize-size);
8279 secmem_free(p);
8280 }
8281 return a;
8282 }
8283
8284
8285 void
8286 secmem_free( void *a )
8287 {
8288 MEMBLOCK *mb;
8289 size_t size;
8290
8291 if( !a )
8292 return;
8293
8294 mb = (MEMBLOCK*)((char*)a - ((size_t) &((MEMBLOCK*)0)->u.aligned.c));
8295 size = mb->size;
8296 /* This does not make much sense: probably this memory is held in the
8297 * cache. We do it anyway: */
8298 wipememory2(mb, 0xff, size );
8299 wipememory2(mb, 0xaa, size );
8300 wipememory2(mb, 0x55, size );
8301 wipememory2(mb, 0x00, size );
8302 mb->size = size;
8303 mb->u.next = unused_blocks;
8304 unused_blocks = mb;
8305 cur_blocks--;
8306 cur_alloced -= size;
8307 }
8308
8309
8310 /* Check whether P points into the pool. */
8311 static int
8312 ptr_into_pool_p (const void *p)
8313 {
8314 /* We need to convert pointers to addresses. This is required by
8315 C-99 6.5.8 to avoid undefined behaviour. Using size_t is at
8316 least only implementation defined. See also
8317 http://lists.gnupg.org/pipermail/gcrypt-devel/2007-February/001102.html
8318 */
8319 size_t p_addr = (size_t)p;
8320 size_t pool_addr = (size_t)pool;
8321
8322 return p_addr >= pool_addr && p_addr < pool_addr+poolsize;
8323 }
8324
8325
8326 int
8327 m_is_secure( const void *p )
8328 {
8329 return pool_okay && ptr_into_pool_p (p);
8330 }
8331
8332
8333
8334 /****************
8335 * Warning: This code might be called by an interrupt handler
8336 * and frankly, there should really be such a handler,
8337 * to make sure that the memory is wiped out.
8338 * We hope that the OS wipes out mlocked memory after
8339 * receiving a SIGKILL - it really should do so, otherwise
8340 * there is no chance to get the secure memory cleaned.
8341 */
8342 void
8343 secmem_term()
8344 {
8345 if( !pool_okay )
8346 return;
8347
8348 wipememory2( pool, 0xff, poolsize);
8349 wipememory2( pool, 0xaa, poolsize);
8350 wipememory2( pool, 0x55, poolsize);
8351 wipememory2( pool, 0x00, poolsize);
8352 #ifdef HAVE_MMAP
8353 if( pool_is_mmapped )
8354 munmap( pool, poolsize );
8355 #endif
8356 pool = NULL;
8357 pool_okay = 0;
8358 poolsize=0;
8359 poollen=0;
8360 unused_blocks=NULL;
8361 }
8362
8363
8364 void
8365 secmem_dump_stats()
8366 {
8367 if( disable_secmem )
8368 return;
8369 fprintf(stderr,
8370 "secmem usage: %u/%u bytes in %u/%u blocks of pool %lu/%lu\n",
8371 cur_alloced, max_alloced, cur_blocks, max_blocks,
8372 (ulong)poollen, (ulong)poolsize );
8373 }
-
+ 0C71B67054A6B49A19C3F8C03751BD4D537843986814B8B970F6A127251E78042BB8DA1AF5F33D335E69322A7878D33D2A8C50DA2956E629EB0A32846258DE4E
smg_comms/mpi/tests/README
(0 . 0)(1 . 8)
8378 S.MG, 2018
8379
8380 Building:
8381 gprbuild
8382
8383 Cleaning:
8384 gprclean
8385
-
+ F829705D787E0DE60B165CCD6BE182B11C11BC80E43B3B536A2062A7247B102A9EC8906E3D48C0D7EC71D6757678FD573728D12EF3FD3AE2DA9924B7593BC581
smg_comms/mpi/tests/obj/README
(0 . 0)(1 . 1)
8390 S.MG, 2018
-
+ 5EB23A86515CC3CB7E47FCDB287828FA70F21A62026AB715BE5121F7793ABD90F5929FBA94F6DAA9B3FDB62E159D3319920903DFC7183B2890F492265C96E081
smg_comms/mpi/tests/test_mpi.c
(0 . 0)(1 . 145)
8395 #include "mpi.h"
8396 #include "mpi-internal.h" /* for BITS_PER_MPI_LIMB */
8397 #include <stdlib.h>
8398
8399 void err(char *msg)
8400 {
8401 fprintf(stderr, "%s\n", msg);
8402 exit(1);
8403 }
8404
8405 void terpri(FILE *fp)
8406 {
8407 fprintf(fp, "\n");
8408 }
8409
8410 void print_results(MPI in, MPI out, char * title)
8411 {
8412 fprintf(stdout, "******** %s ********", title);
8413 terpri(stdout);
8414
8415 fprintf(stdout, "input : ");
8416 mpi_print(stdout, in, 1);
8417 terpri(stdout);
8418
8419 fprintf(stdout, "output: ");
8420 mpi_print(stdout, out, 1);
8421 terpri(stdout);
8422
8423 terpri(stdout);
8424 fflush(stdout);
8425 }
8426
8427 /*
8428 * Test that will fail on original code and will pass after EuCrypt fix is applied.
8429 */
8430 void test_rshift()
8431 {
8432 MPI out, in, copy_in;
8433 out = mpi_alloc(0);
8434 in = mpi_alloc(0);
8435 copy_in = mpi_alloc(0);
8436
8437 mpi_fromstr(out, "0x20E92FE28E1929"); /* some value */
8438 mpi_fromstr(in, "0x2000000010000001000000002");
8439 mpi_fromstr(copy_in, "0x2000000010000001000000002"); /* to make sure the actual input is print, since call can modify in */
8440
8441 /* print value of BITS_PER_MPI_LIMB */
8442 fprintf(stdout, "BITS_PER_MPI_LIMB is %d\n", BITS_PER_MPI_LIMB);
8443
8444 /* shift by 0 */
8445 mpi_tdiv_q_2exp(out, in, 0);
8446 print_results(copy_in, out, "TEST: right shift by 0");
8447
8448 /* shift by multiple of BITS_PER_MPI_LIMB */
8449 mpi_fromstr(in, "0x2000000010000001000000002");
8450
8451 mpi_tdiv_q_2exp(out, in, BITS_PER_MPI_LIMB);
8452 print_results(copy_in, out, "TEST: right shift by BITS_PER_MPI_LIMB");
8453
8454 /* shift by non-multiple of BITS_PER_MPI_LIMB */
8455 mpi_fromstr(in, "0x2000000010000001000000002");
8456 mpi_tdiv_q_2exp(out, in, BITS_PER_MPI_LIMB - 3);
8457 print_results(copy_in, out, "TEST: right shift by BITS_PER_MPI_LIMB - 3");
8458
8459 mpi_free(copy_in);
8460 mpi_free(out);
8461 mpi_free(in);
8462 }
8463
8464 void test_highbit()
8465 {
8466 MPI in, set_out, clear_out;
8467
8468 in = mpi_alloc(0);
8469 set_out = mpi_alloc(0);
8470 clear_out = mpi_alloc(0);
8471
8472 mpi_fromstr(in, "0x2000000010000002000000004");
8473 mpi_fromstr(set_out, "0x2000000010000002000000004");
8474 mpi_fromstr(clear_out, "0x2000000010000002000000004");
8475
8476 mpi_set_highbit(set_out, 91);
8477 print_results(in, set_out, "TEST: mpi_set_highbit(in, 91)");
8478
8479 mpi_fromstr(set_out, "0x2000000010000002000000004");
8480 mpi_set_highbit(set_out, 96);
8481 print_results(in, set_out, "TEST: mpi_set_highbit(in, 96)");
8482
8483
8484 mpi_clear_highbit(clear_out, 96);
8485 print_results(in, clear_out, "TEST: mpi_clear_highbit(in, 96)");
8486
8487 mpi_fromstr(clear_out, "0x2000000010000002000000004");
8488 mpi_clear_highbit(clear_out, 1);
8489 print_results(in, clear_out, "TEST: mpi_clear_highbit(in, 1)");
8490
8491 mpi_free(in);
8492 mpi_free(set_out);
8493 mpi_free(clear_out);
8494 }
8495
8496 void test_get_nbits()
8497 {
8498 MPI m;
8499 int nbits;
8500
8501 m = mpi_alloc(0);
8502 mpi_fromstr(m, "0x0");
8503 nbits = mpi_get_nbits(m);
8504 print_results(m, m, "TEST: get_nbits");
8505 fprintf(stdout, "nbits: %d\n", nbits);
8506 mpi_free(m);
8507 }
8508
8509 int main(int ac, char **av)
8510 {
8511 MPI a, b, y;
8512 int r;
8513
8514 test_rshift();
8515 test_highbit();
8516 test_get_nbits();
8517
8518 r = secmem_init(1000);
8519 if (r==0) err("secmem init");
8520
8521 a = mpi_alloc_secure(0);
8522 b = mpi_alloc_secure(0);
8523 y = mpi_alloc_secure(0);
8524 mpi_fromstr(a, "0x1B0B206C488601");
8525 mpi_fromstr(b, "0x20E92FE28E1929");
8526 mpi_mul(y, a, b);
8527 mpi_free(a);
8528 mpi_free(b);
8529
8530 fprintf(stdout, "******** TEST: mpi_mul, see README ********");
8531 terpri(stdout);
8532 mpi_print(stdout, y, 1);
8533 mpi_free(y);
8534
8535 terpri(stdout);
8536 secmem_term();
8537
8538 return 0;
8539 }
-
+ A29B3F2A6D20F115E9150134305105FB5A21567355ECE0DDC3E3CFBD3B752D6D6FBFDBB97533F568E75898F04A01CBB555DF566B1117B1FEE5711A7912E0B29D
smg_comms/mpi/tests/test_mpi.gpr
(0 . 0)(1 . 14)
8544 -- S.MG, 2018
8545
8546 with "../mpi.gpr";
8547
8548 project test_MPI is
8549 for Languages use ("C");
8550
8551 for Source_Dirs use (".");
8552 for Object_Dir use "obj";
8553 for Exec_Dir use ".";
8554
8555 for Main use ("test_mpi.c");
8556 end test_MPI;
8557
-
+ C4E10D617469ED871477B2EF41AF5DFE7830F97A85B8A5034D2E2C9806202462A566EE6A0412C8A5245CF17FDE5E84CA7F6B1AC864ADFCB0843E6F4D8F26F571
smg_comms/rsa/README
(0 . 0)(1 . 12)
8562 S.MG, 2017
8563
8564 This is the S.MG implementation of RSA, used by the Eulora server.
8565
8566 NB: this lib is part of EuCrypt and as such, it relies on other EuCrypt components (most notably: mpi).
8567
8568 Compilation:
8569 gprbuild
8570
8571 Tests:
8572 cd tests
8573 gprbuild
-
+ EF968E74FEE9D5C5451883AFC1A47D0EB8A99C775A6B045040134A7F9C0D80DBEC3644FF9D69CF941BDBC718A6D4BED3A27A11D2EF6530453AB6E4955AA45F32
smg_comms/rsa/bin/README
(0 . 0)(1 . 1)
8578 bin folder for smg_rsa lib
-
+ FEAFFACD0ECCEEC5B42D086F1755FEDE58DD7244B52B8EF599B7E4AD79B149FCBE55F036A1C46F5BAE0A00DD3C50B1DC7D8C1BDE9958934CBCD8D01862E29B9D
smg_comms/rsa/include/knobs.h
(0 . 0)(1 . 19)
8583 #ifndef SMG_RSA_KNOBS_H
8584 #define SMG_RSA_KNOBS_H
8585
8586 #define ENTROPY_SOURCE "/dev/ttyUSB0"
8587
8588 /*
8589 * This is the number of witnesses checked by the Miller-Rabin (MR) algorithm for each candidate prime number.
8590 * The value of M_R_ITERATIONS directly affects the outer bound of MR which is calculated as 4^(-M_R_ITERATIONS)
8591 * S.MG's choice of 16 here means an outer bound of 4^(-16) = 0.0000000002,
8592 which is currently considered sufficient for Eulora's needs.
8593 If your needs are different, change this knob accordingly.
8594 * NB: if you use this to make keys for some serious use, an outer bound of 1e-10 is really not nearly good enough
8595 and therefore you'll probably want to *increase* the value of this knob.
8596 */
8597 #define M_R_ITERATIONS 16
8598
8599
8600 #endif /*SMG_RSA_KNOBS_H*/
8601
-
+ 73247011FCC9996859CAB02ADE955CD8D5FA04B85593E182645EBE0F497686ABFC771ECDF1E43B0E39506C85B25F365D80A81031FB82F13919E2FF5824EDA5EF
smg_comms/rsa/include/smg_rsa.h
(0 . 0)(1 . 242)
8606 /* smg_rsa.h
8607 * S.MG, 2017
8608 */
8609
8610 #ifndef SMG_RSA_H
8611 #define SMG_RSA_H
8612
8613 #include "mpi.h"
8614 #include "knobs.h"
8615
8616 /* A way to determine endianness at runtime.
8617 * Required for diddling a float's mantissa for instance.
8618 */
8619 static const int onect = 1;
8620 #define is_bigendian() ( (*(char*)&onect) == 0 )
8621
8622 /*
8623 * These are constants as per Eulora's protocol specification, NOT knobs!
8624 * Eulora uses RSA keys of 3920 bits (490 octets);
8625 * The above key length means 2 primes of 1960 bits (245 octets) each.
8626 * NB: if you choose here an odd key length in octets you might end up with a smaller actual key, read the code.
8627 */
8628 static const int KEY_LENGTH_OCTETS = 490;
8629
8630 typedef struct {
8631 MPI n; /* modulus */
8632 MPI e; /* public exponent */
8633 } RSA_public_key;
8634
8635 typedef struct {
8636 MPI n; /* public modulus */
8637 MPI e; /* public exponent */
8638 MPI d; /* private exponent: e*d=1 mod phi */
8639 MPI p; /* prime p */
8640 MPI q; /* prime q */
8641 MPI u; /* inverse of p mod q */
8642 } RSA_secret_key;
8643
8644
8645 /*********truerandom.c*********/
8646
8647 /*
8648 * Opens and configures (as per FG requirements) the specified entropy source (e.g. "/dev/ttyUSB0")
8649 * @param source_name the name of the file to open (e.g. "/dev/ttyUSB0")
8650 * @return the descriptor of the open file when successful; negative value otherwise
8651 */
8652 int open_entropy_source(char* source_name);
8653
8654
8655 /*
8656 * Returns noctets random octets (i.e. 8*noctets bits in total) as obtained from EuCrypt's preferred source.
8657 * Preferred source is defined in knobs.h as ENTROPY_SOURCE and should be a TRNG (e.g. Fuckgoats).
8658 * @param nboctets the length of desired random sequence, in octets
8659 * @param out pointer to allocated memory space for the requested random noctets; NB: this method does NOT allocate space!
8660 * @return the actual number of octets that were obtained from the currently configured entropy source (this is equal to noctets on successful read of required noctets)
8661 */
8662 int get_random_octets(int noctets, unsigned char *out);
8663
8664 /* Returns noctets random octets as obtained from the specified "from" source;
8665 * NB: the "from" source is considered to be the handle of an already opened stream;
8666 * This method will simply attempt to read from the source as needed!
8667 *
8668 * @param noctets the length of desired random sequence, in octets
8669 * @param out pointer to allocated memory space for the requested random octets;
8670 * NB: this method does NOT allocate space!
8671 * @param from handle of an already opened entropy source - this method will just READ from it as needed
8672 * @return the actual number of octets that were obtained
8673 */
8674 int get_random_octets_from(int noctets, unsigned char *out, int from);
8675
8676 /* Returns (in parameter *n) a *potentially biased* random float between 0 and 1
8677 * Uses bits from ENTROPY_SOURCE but it rounds when converting to float
8678 * NB: This function rounds impredictably.
8679 Use it ONLY if LSB normalization is insignificant to you!
8680 * This function uses rng_uint64 below.
8681 *
8682 * @param n - a float value (LSB rounded) between 0 and 1, obtained using
8683 * a 64-bit random integer (64 bits from ENTROPY_SOURCE)
8684 * @return - a positive value on success and a negative value in case of error
8685 * main possible cause for error: failure to open ENTROPY_SOURCE.
8686 * NB: a non-responsive/malconfigured source can result in blocking
8687 */
8688 int rng_dirty_float(float *n);
8689
8690
8691 /* Returns (in parameter *n) a randomly generated float between 1 and 2 using:
8692 * - the IEEE 754/1985 format for single float representation
8693 * - ENTROPY_SOURCE to obtain bits that are *directly* used as mantissa
8694 * NB: this value is between 1 and 2 due to the normalised format that includes
8695 * an implicit 1 ( i.e. value is (-1)^sign * 2^(e-127) * (1.mantissa) )
8696 *
8697 * From IEEE 754/1985, a description of the single float format:
8698 * msb means most significant bit
8699 * lsb means least significant bit
8700 * 1 8 23 ... widths
8701 * +-+-------+-----------------------+
8702 * |s| e | f |
8703 * +-+-------+-----------------------+
8704 * msb lsb msb lsb ... order
8705
8706 * A 32-bit single format number X is divided as shown in the figure above. The
8707 * value v of X is inferred from its constituent fields thus:
8708 * 1. If e = 255 and f != 0 , then v is NaN regardless of s
8709 * 2. If e = 255 and f = 0 , then v = (-1)^s INFINITY
8710 * 3. If 0 < e < 255 , then v = (-1)^s * 2^(e-127) * ( 1.f )
8711 * 4. If e = 0 and f != 0 , then v = (-1)^s * 2^(-126) * ( 0.f ) (denormalized
8712 * numbers)
8713 * 5. If e = 0 and f = 0 , then v = ( -1 )^s * 0 (zero)
8714 *
8715 * @param n - the address of an IEEE 754/1985 float: its mantissa will be set to
8716 * random bits obtained from ENTROPY_SOURCE; its sign will be set
8717 * to 0; its exponent will be set to 127 (the bias value so
8718 * that the actual exponent is 0).
8719 * @return - a positive value on success and a negative value in case of error
8720 * main possible cause for error: failure to open ENTROPY_SOURCE.
8721 * NB: a non-responsive/malconfigured source can result in blocking
8722 */
8723 int rng_float_754_1985(float *n);
8724
8725 /* Returns (in parameter *n) a random unsigned integer value on 32 bits.
8726 * Uses random bits from ENTROPY_SOURCE that are directly interpreted as int
8727 *
8728 * @param n - it will contain the random integer obtained by interpreting 32
8729 * bits from ENTROPY_SOURCE as an unsigned int value on 32 bits.
8730 * @return - a positive value on success and a negative value in case of error
8731 */
8732 int rng_uint32( uint32_t *n );
8733
8734 /* Returns (in parameter *n) a random unsigned integer value on 64 bits.
8735 * Uses random bits from ENTROPY_SOURCE that are directly interpreted as int
8736 *
8737 * @param n - it will contain the random integer obtained by interpreting 64
8738 * bits from ENTROPY_SOURCE as an unsigned int value on 64 bits.
8739 * @return - a positive value on success and a negative value in case of error
8740 */
8741 int rng_uint64( uint64_t *n );
8742
8743 /*********primegen.c*********/
8744
8745 /*
8746 * This is an implementation of the Miller-Rabin probabilistic primality test:
8747 * checking the specified number of randomly-chosen candidate witnesses
8748 * (i.e. with an outer bound of (1/4)^nwitnesses).
8749 * NB: a 1 result from this test means that the given n is indeed composite (non-prime)
8750 but a 0 result does not fully guarantee that n is prime!
8751 If this doesn't make sense to you, read more on probabilistic primality tests.
8752 * @param n the candidate prime number;
8753 the function will investigate whether this number is composite or *likely* to be prime.
8754 How likely? It depends on the number of witnesses checked, see next parameter.
8755 * @param nwitnesses this is the number of randomly chosen candidate witnesses to the compositeness of n
8756 that will be checked; the outer bound of the algorithm depends on this.
8757 * @param entropy_source the source of entropy (ready to read from) that will be used
8758 to choose candidate witnesses to the compositeness of n.
8759 * @return 1 if at least one witness to the compositeness of n has been found
8760 (i.e. n is certainly composite);
8761 0 if no witness to the compositeness of n was found (i.e. it is likely that n is prime)
8762 * NB: the probability that n is *not* prime although this function returned 0 is
8763 less than (1/4)^nwitnesses, but it is NOT zero.
8764 */
8765 int is_composite( MPI n, int nwitnesses, int entropy_source);
8766
8767 /**
8768 * Generates a random number that has passed the Miller-Rabin test for primality (see function is_composite above).
8769 * NB: top 2 bits and bottom bit are ALWAYS 1! (i.e. a mask 110....01 is applied to the random bits)
8770 * a prime of 8*noctets long will have only (8*noctets-3) bits that are randomly chosen!
8771 * NB: this method does NOT allocate space for the requested MPI; it is the caller's responsibility to allocate it!
8772 * The source of randomness is ENTROPY_SOURCE in eucrypt/smg_rsa/include/knobs.h
8773 * The number of witnesses checked by Miller-Rabin is M_R_ITERATIONS in eucrypt/smg_rsa/include/knobs.h
8774 * Preconditions:
8775 * noctets > 0 (at least one octet!)
8776 * output has known allocated memory for at least nlimbs(noctets)
8777 * successful access to the entropy source
8778 * @param noctets the length of the desired prime number, in octets
8779 * @param output an MPI with sufficient memory allocated for a number that is noctets long
8780 */
8781 void gen_random_prime( unsigned int noctets, MPI output);
8782
8783 /*********rsa.c*********/
8784 /*
8785 * Generates a pair of public+private RSA keys using directly the entropy source
8786 * specified in include/knobs.h
8787 *
8788 * ALL RSA keys are 8*KEY_LENGTH_OCTETS bits out of
8789 * 2 8*KEY_LENGTH_OCTETS/2 bits primes, as per TMSR spec.
8790 *
8791 * @param sk a fully-allocated structure to hold the generated keypair (secret
8792 key structure holds all the elements anyway, public key is a subset of this)
8793 *
8794 * NB: this procedure does NOT allocate memory for components in sk!
8795 * caller should ALLOCATE enough memory for all the MPIs in sk
8796 * Precondition:
8797 * MPIs in sk have known allocated memory for the nlimbs fitting their TMSR size
8798 */
8799 void gen_keypair( RSA_secret_key *sk );
8800
8801 /****************
8802 * Public key operation. Encrypt input with pk and store result into output.
8803 *
8804 * output = input^e mod n , where e,n are elements of pkey.
8805 * NB: caller should allocate *sufficient* memory for output to hold the result.
8806 * NB: NO checks are made on input!
8807 *
8808 * @param output MPI with enough allocated memory to hold result of encryption
8809 * @param input MPI containing content to encrypt; it *has to be* different from
8810 output!
8811 * @param pk the public key that will be used to encrypt input
8812 *
8813 * Precondition:
8814 * output != input
8815 * Output and input have to be two distinct MPIs because of the sorry state of
8816 the underlying mpi lib that can't handle properly the case when those are the
8817 same.
8818 */
8819 void public_rsa( MPI output, MPI input, RSA_public_key *pk );
8820
8821
8822 /****************
8823 * Secret key operation. Decrypt input with sk and store result in output.
8824 *
8825 * output = input^d mod n , where d, n are elements of skey.
8826 *
8827 * This implementation uses the Chinese Remainder Theorem (CRT):
8828 *
8829 * out1 = input ^ (d mod (p-1)) mod p
8830 * out2 = input ^ (d mod (q-1)) mod q
8831 * h = u * (out2 - out1) mod q
8832 * output = out1 + h * p
8833 *
8834 * where out1, out2 and h are intermediate values, d,n,p,q,u are elements of
8835 skey. By using CRT, encryption is *faster*. Decide for yourself if this fits
8836 your needs though!
8837 * NB: it is the caller's responsibility to allocate memory for output!
8838 * NB: NO checks are made on input!
8839 *
8840 * @param output MPI with enough allocated memory to hold result of decryption
8841 * @param input MPI containing content to decrypt
8842 * @param sk the secret key that will be used to decrypt input
8843 */
8844 void secret_rsa( MPI output, MPI input, RSA_secret_key *sk );
8845
8846 #endif /*SMG_RSA*/
8847
-
+ A2EB4B7AFC8AFE95836F6CF05B0EB589977606525747A45776A1409A65CCD52EDB062EF150226CA65E91F66ACEBEC828B050C1A2E946C542EB86D7830323DAF3
smg_comms/rsa/obj/README
(0 . 0)(1 . 1)
8852 obj folder for smg_rsa
-
+ 992C1ED9B3037031C841DB0BB5D6467D2142ACCE1E9B67DDF91D1661D7A9731452D2F2D95222AAC51EE7672A781FD2BB195692D3949E14EAF46B8E29D2243FE0
smg_comms/rsa/primegen.c
(0 . 0)(1 . 152)
8857 /* primegen.c - prime number generation and checks
8858 *
8859 * S.MG, 2017
8860 *
8861 */
8862
8863 #include <stdlib.h>
8864 #include <unistd.h>
8865 #include <assert.h>
8866
8867 #include "smg_rsa.h"
8868
8869 /****************
8870 * is_composite
8871 * Returns 1 if it finds evidence that n is composite and 0 otherwise.
8872 * NB: this is a probabilistic test and its strength is directly linked to:
8873 * - the number of witnesses AND
8874 * - the quality of the entropy source given as arguments!
8875 */
8876
8877 int is_composite( MPI n, int nwitnesses, int entropy_source) {
8878 int evidence = 0;
8879 int nlimbs = mpi_get_nlimbs(n); /* see MPI representation */
8880 unsigned int nbits = mpi_get_nbits(n); /* used bits */
8881 unsigned int noctets = (nbits + 7) / 8; /* source works on octets */
8882
8883 MPI nminus1 = mpi_alloc(nlimbs); /* n-1 value is used a LOT */
8884 MPI mpi2 = mpi_alloc_set_ui(2); /* 2 as MPI */
8885 MPI a = mpi_alloc(nlimbs); /* candidate witness */
8886 MPI y = mpi_alloc(nlimbs); /* intermediate values */
8887 MPI r = mpi_alloc(nlimbs); /* n = 1 + 2^s * r */
8888 int s; /* n = 1 + 2^s * r */
8889 int j; /* counter for loops */
8890 int nread; /* number of random octets actually read */
8891
8892 /* precondition: n > 3 */
8893 assert( nbits > 2 );
8894
8895 /* nminus1 = n - 1 as MPI */
8896 mpi_sub_ui( nminus1, n, 1);
8897
8898 /*
8899 * find r odd and s so that n = 1 + 2^s * r
8900 * n-1 = 2^s * r
8901 * s is given by the number of trailing zeros of binary n-1
8902 * r is then obtained as (n-1) / (2^s)
8903 */
8904 s = mpi_trailing_zeros( nminus1 );
8905 mpi_tdiv_q_2exp(r, nminus1, s);
8906
8907 /*
8908 * Investigate randomly chosen candidate witnesses.
8909 * Stop when either:
8910 * the specified number of witnesses (nwitnesses) have
8911 been investigated OR
8912 * a witness for compositeness of n was found
8913 */
8914 while (nwitnesses > 0 && evidence == 0) {
8915 unsigned char *p = xmalloc(noctets);
8916 do {
8917 nread = get_random_octets_from(noctets, p, entropy_source);
8918 } while (nread != noctets);
8919
8920 mpi_set_buffer(a, p, noctets, 0);
8921
8922 /* ensure that a < n-1 by making a maximum nbits-1 long:
8923 * clear all bits above nbits-2 in a
8924 * keep value of bit nbits-2 in a as it was
8925 */
8926 if (mpi_test_bit(a, nbits - 2))
8927 mpi_set_highbit(a, nbits - 2);
8928 else
8929 mpi_clear_highbit(a, nbits - 2);
8930
8931 /* ensure that 1 < a < n-1; if not, try another random number
8932 * NB: true random means a CAN end up as 0 or 1 here.
8933 */
8934 if (mpi_cmp(a, nminus1) < 0 && mpi_cmp_ui(a, 1) > 0) {
8935 /* calculate y = a^r mod n */
8936 mpi_powm(y, a, r, n);
8937 if (mpi_cmp_ui(y, 1) && mpi_cmp(y, nminus1)) {
8938 j = 1;
8939 while ( (j < s) && mpi_cmp(y, nminus1) && (evidence == 0) ) {
8940 /* calculate y = y^2 mod n */
8941 mpi_powm(y, y, mpi2, n);
8942 if (mpi_cmp_ui(y, 1) == 0)
8943 evidence = 1;
8944 j = j + 1;
8945 } /* end while */
8946 if (mpi_cmp(y, nminus1))
8947 evidence = 1;
8948 } /* end if y != 1 and y != n-1 */
8949 nwitnesses = nwitnesses - 1;
8950 } /* end if 1 < a < n-1 */
8951 xfree(p);
8952 } /* end while for investigating candidate witnesses */
8953
8954 mpi_free( nminus1 );
8955 mpi_free( mpi2 );
8956 mpi_free( a );
8957 mpi_free( y );
8958 mpi_free( r );
8959
8960 return evidence;
8961 }
8962
8963 /**
8964 * Generates a random number that has passed the Miller-Rabin test for primality (see function is_composite above).
8965 * NB: top 2 bits and bottom bit are ALWAYS 1! (i.e. a mask 11.....1 is applied)
8966 * a prime of 8*noctets long will have only 8*noctets-3 bits that are randomly chosen
8967 * NB: this method does NOT allocate space for the requested MPI; it is the caller's responsibility to allocate it!
8968 * The source of randomness is ENTROPY_SOURCE in eucrypt/smg_rsa/include/knobs.h
8969 * The number of witnesses checked by Miller-Rabin is M_R_ITERATIONS in eucrypt/smg_rsa/include/knobs.h
8970 * Preconditions:
8971 * noctets > 0 (at least one octet!)
8972 * memory allocated for noctets in output MPI
8973 * successful access to the entropy source
8974 */
8975 void gen_random_prime( unsigned int noctets, MPI output )
8976 {
8977 /* precondition: at least one octet long */
8978 assert(noctets > 0);
8979
8980 /* precondition: enough memory allocated for the limbs corresponding to noctets */
8981 unsigned int nlimbs = mpi_nlimb_hint_from_nbytes(noctets);
8982 assert(mpi_get_alloced(output) >= nlimbs);
8983
8984 /* precondition: access to the entropy source */
8985 int entropy_source = open_entropy_source(ENTROPY_SOURCE); /* source of random bits */
8986 assert(entropy_source >= 0);
8987
8988 unsigned int nbits = 8*noctets; /* length of MPI in bits */
8989
8990 /*
8991 * loop until a prime is found: get noctets of random bits, trim and apply 110...01 mask, check if prime
8992 */
8993 unsigned char *p = xmalloc( noctets );
8994 int nread;
8995 do {
8996 do {
8997 nread = get_random_octets_from( noctets, p, entropy_source );
8998 } while ( nread != noctets );
8999 mpi_set_buffer( output, p, noctets, 0); /* convert to MPI representation */
9000 mpi_set_highbit( output, nbits - 1 ); /* trim at required size and set top bit */
9001 mpi_set_bit( output, nbits - 2); /* set second top bit */
9002 mpi_set_bit( output, 0 ); /* set bottom bit to unsure odd number */
9003 } while (is_composite(output, M_R_ITERATIONS, entropy_source));
9004
9005 /* tidy up, a prime was found */
9006 xfree(p);
9007 close(entropy_source);
9008 }
-
+ 388A33BE262FAA152FB74089B6AC814C7E5C6248A5B52F91A8C69C0E19EC9F9EEA12B0551B0AADC751F73CDD5AC4004C8C493AA1E6041118A922070EAD3A7ECB
smg_comms/rsa/rsa.c
(0 . 0)(1 . 140)
9013 /*
9014 * An implementation of TMSR RSA
9015 * S.MG, 2018
9016 */
9017
9018 #include "smg_rsa.h"
9019 #include <assert.h>
9020
9021 void gen_keypair( RSA_secret_key *sk ) {
9022 /* precondition: sk is not null */
9023 assert(sk != NULL);
9024
9025 /* precondition: enough memory allocated, corresponding to key size */
9026 int noctets_pq = KEY_LENGTH_OCTETS / 2;
9027 unsigned int nlimbs_pq = mpi_nlimb_hint_from_nbytes( noctets_pq);
9028 unsigned int nlimbs_n = mpi_nlimb_hint_from_nbytes( KEY_LENGTH_OCTETS);
9029 assert( mpi_get_alloced( sk->n) >= nlimbs_n);
9030 assert( mpi_get_alloced( sk->p) >= nlimbs_pq);
9031 assert( mpi_get_alloced( sk->q) >= nlimbs_pq);
9032
9033 /* helper variables for calculating Euler's totient phi=(p-1)*(q-1) */
9034 MPI p_minus1 = mpi_alloc(nlimbs_pq);
9035 MPI q_minus1 = mpi_alloc(nlimbs_pq);
9036 MPI phi = mpi_alloc(nlimbs_n);
9037
9038 /* generate 2 random primes, p and q*/
9039 /* gen_random_prime sets top 2 bits to 1 so p*q will have KEY_LENGTH bits */
9040 /* in the extremely unlikely case that p = q, discard and generate again */
9041 do {
9042 gen_random_prime( noctets_pq, sk->p);
9043 gen_random_prime( noctets_pq, sk->q);
9044 } while ( mpi_cmp( sk->p, sk->q) == 0);
9045
9046 /* swap if needed, to ensure p < q for calculating u */
9047 if ( mpi_cmp( sk->p, sk->q) > 0)
9048 mpi_swap( sk->p, sk->q);
9049
9050 /* calculate helper for Chinese Remainder Theorem:
9051 u = p ^ -1 ( mod q )
9052 this is used to speed-up decryption.
9053 */
9054 mpi_invm( sk->u, sk->p, sk->q);
9055
9056 /* calculate modulus n = p * q */
9057 mpi_mul( sk->n, sk->p, sk->q);
9058
9059 /* calculate Euler totient: phi = (p-1)*(q-1) */
9060 mpi_sub_ui( p_minus1, sk->p, 1);
9061 mpi_sub_ui( q_minus1, sk->q, 1);
9062 mpi_mul( phi, p_minus1, q_minus1);
9063
9064 /* choose random prime e, public exponent, with 3 < e < phi */
9065 /* because e is prime, gcd(e, phi) is always 1 so no need to check it */
9066 do {
9067 gen_random_prime( noctets_pq, sk->e);
9068 } while ( (mpi_cmp_ui(sk->e, 3) < 0) || (mpi_cmp(sk->e, phi) > 0));
9069
9070 /* calculate private exponent d, 1 < d < phi, where e * d = 1 mod phi */
9071 mpi_invm( sk->d, sk->e, phi);
9072
9073 /* tidy up: free locally allocated memory for helper variables */
9074 mpi_free(phi);
9075 mpi_free(p_minus1);
9076 mpi_free(q_minus1);
9077 }
9078
9079 void public_rsa( MPI output, MPI input, RSA_public_key *pk ) {
9080
9081 /* mpi_powm can't handle output and input being same */
9082 assert (output != input);
9083
9084 /* the actual rsa op */
9085 mpi_powm( output, input, pk->e, pk->n );
9086
9087 }
9088
9089 void secret_rsa( MPI output, MPI input, RSA_secret_key *skey ) {
9090 /* at its simplest, this would be input ^ d (mod n), hence:
9091 * mpi_powm( output, input, skey->d, skey->n );
9092 * for faster decryption though, we'll use CRT and Garner's algorithm, hence:
9093 * u = p ^ (-1) (mod q) , already calculated and stored in skey
9094 * dp = d mod (p-1)
9095 * dq = d mod (q-1)
9096 * m1 = input ^ dp (mod p)
9097 * m2 = input ^ dq (mod q)
9098 * h = u * (m2 - m1) mod q
9099 * output = m1 + h * p
9100 * Note that same CRT speed up isn't available for encryption because at
9101 encryption time not enough information is available (only e and n are known).
9102 */
9103
9104 /* allocate memory for all local, helper MPIs */
9105 MPI p_minus1 = mpi_alloc( mpi_get_nlimbs( skey->p) );
9106 MPI q_minus1 = mpi_alloc( mpi_get_nlimbs( skey->q) );
9107 int nlimbs = mpi_get_nlimbs( skey->n ) + 1;
9108 MPI dp = mpi_alloc( nlimbs );
9109 MPI dq = mpi_alloc( nlimbs );
9110 MPI m1 = mpi_alloc( nlimbs );
9111 MPI m2 = mpi_alloc( nlimbs );
9112 MPI h = mpi_alloc( nlimbs );
9113
9114 /* p_minus1 = p - 1 */
9115 mpi_sub_ui( p_minus1, skey->p, 1 );
9116
9117 /* dp = d mod (p - 1) aka remainder of d / (p - 1) */
9118 mpi_fdiv_r( dp, skey->d, p_minus1 );
9119
9120 /* m1 = input ^ dp (mod p) */
9121 mpi_powm( m1, input, dp, skey->p );
9122
9123 /* q_minus1 = q - 1 */
9124 mpi_sub_ui( q_minus1, skey->q, 1 );
9125
9126 /* dq = d mod (q - 1) aka remainder of d / (q - 1) */
9127 mpi_fdiv_r( dq, skey->d, q_minus1 );
9128
9129 /* m2 = input ^ dq (mod q) */
9130 mpi_powm( m2, input, dq, skey->q );
9131
9132 /* h = u * ( m2 - m1 ) mod q */
9133 mpi_sub( h, m2, m1 );
9134 if ( mpi_is_neg( h ) )
9135 mpi_add ( h, h, skey->q );
9136 mpi_mulm( h, skey->u, h, skey->q );
9137
9138 /* output = m1 + h * p */
9139 mpi_mul ( h, h, skey->p );
9140 mpi_add ( output, m1, h );
9141
9142 /* tidy up */
9143 mpi_free ( p_minus1 );
9144 mpi_free ( q_minus1 );
9145 mpi_free ( dp );
9146 mpi_free ( dq );
9147 mpi_free ( m1 );
9148 mpi_free ( m2 );
9149 mpi_free ( h );
9150
9151 }
9152
-
+ 88B2ABCF9FAF9D0689673CC368D3E3C853147DE327EEC636B90CBA1A085EB1E8B14AE9EEE8521F121B9F5EECBECD5078A2EFE52DF1FD5A1D097E605A27A244D2
smg_comms/rsa/rsa.gpr
(0 . 0)(1 . 15)
9157 -- S.MG, 2018
9158
9159 with "../mpi/mpi.gpr";
9160
9161 project RSA is
9162 for Languages use ("C");
9163 for Library_Name use "RSA";
9164 for Library_Kind use "static";
9165
9166 for Source_Dirs use (".", "include");
9167 for Object_Dir use "obj";
9168 for Library_Dir use "bin";
9169
9170 end RSA;
9171
-
+ A2EB4B7AFC8AFE95836F6CF05B0EB589977606525747A45776A1409A65CCD52EDB062EF150226CA65E91F66ACEBEC828B050C1A2E946C542EB86D7830323DAF3
smg_comms/rsa/tests/obj/README
(0 . 0)(1 . 1)
9176 obj folder for smg_rsa
-
+ 658150D9CC3FF5F1D4A6D134C57D9EA6740BE6AEF571EF9C2BD553A3E4931A541CCF755BF51DC5349A4DBAECF04DC11E0D4FAFF4D4745E322CF22231241570F5
smg_comms/rsa/tests/smg_rsa_tests.gpr
(0 . 0)(1 . 13)
9181 -- Tests for SMG_RSA (part of EuCrypt)
9182 -- S.MG, 2018
9183
9184 with "../smg_rsa.gpr";
9185
9186 project SMG_RSA_Tests is
9187 for Languages use("C");
9188 for Source_Dirs use (".");
9189 for Object_Dir use "obj";
9190 for Exec_Dir use ".";
9191
9192 for Main use ("tests.c");
9193 end SMG_RSA_Tests;
-
+ 89B1C405D92E249341BDC0BDDC5A98D8AE8DD0349E04A165063D938F01DF557A057BE544C51B0EFB6D72D505F1424A1AA3A6D7957E83F229711677240123E2FD
smg_comms/rsa/tests/tests.c
(0 . 0)(1 . 761)
9198 #include "smg_rsa.h"
9199 #include "mpi.h"
9200
9201 #include <stdlib.h>
9202 #include <unistd.h>
9203 #include <time.h>
9204 #include <stdio.h>
9205
9206 extern void adainit(void);
9207 extern void adafinal(void);
9208
9209 void err(char *msg)
9210 {
9211 fprintf(stderr, "%s\n", msg);
9212 exit(1);
9213 }
9214
9215 void time_entropy_source(int nruns, int noctets) {
9216 unsigned char buffer[noctets];
9217 int read, i;
9218 struct timespec tstart, tend;
9219 long int diff;
9220
9221 clock_gettime(CLOCK_MONOTONIC, &tstart);
9222 for (i=0; i<nruns; i++) {
9223 read = get_random_octets(noctets,buffer);
9224 if (read != noctets)
9225 err("Failed reading from entropy source!");
9226 }
9227 clock_gettime(CLOCK_MONOTONIC, &tend);
9228
9229 diff = tend.tv_sec-tstart.tv_sec;
9230 double kbps = (nruns*noctets) / (diff*1000.0);
9231 printf("ENTROPY source timing: %d kB in %ld seconds, at an average speed of %f kB/s over %d runs of %d octets each\n", nruns*noctets, diff, kbps, nruns, noctets);
9232 }
9233
9234 void test_entropy_output(unsigned int noctets, char * filename) {
9235 FILE * out;
9236 int source;
9237 unsigned int nread, total_read, to_read;
9238 const int buffer_length = 1000;
9239 unsigned char buffer[buffer_length];
9240
9241 source = open_entropy_source(ENTROPY_SOURCE);
9242 if (source <= 0)
9243 err("unable to access entropy source!");
9244
9245 out = fopen(filename, "wb");
9246 if ( !out )
9247 err("unable to open output file for test_entropy_output!");
9248
9249 printf("TEST_ENTROPY_SOURCE: reading %u octets from %s ", noctets, ENTROPY_SOURCE);
9250 total_read = 0;
9251 while (total_read < noctets) {
9252 to_read = noctets - total_read;
9253 if (to_read > buffer_length)
9254 to_read = buffer_length;
9255
9256 nread = get_random_octets_from(to_read, buffer, source);
9257 if (nread > 0) {
9258 total_read = total_read + nread;
9259 fwrite(buffer, 1, nread, out);
9260 fflush(out);
9261 printf(".");
9262 fflush(stdout);
9263 }
9264 }
9265 printf("done.\n");
9266
9267 fclose(out);
9268 close(source);
9269 }
9270
9271 void test_is_composite(int nruns, char *hex_number, int expected) {
9272 int i;
9273 int output;
9274 int count_ok = 0;
9275 int source = open_entropy_source(ENTROPY_SOURCE);
9276 MPI p = mpi_alloc(0);
9277
9278 mpi_fromstr(p, hex_number);
9279 printf("TEST is_composite on MPI(hex) ");
9280 mpi_print(stdout, p, 1);
9281 for (i=0; i < nruns; i++) {
9282 printf(".");
9283 fflush(stdout);
9284 output = is_composite(p, M_R_ITERATIONS, source);
9285 if (output == expected)
9286 count_ok = count_ok + 1;
9287 }
9288 printf("done, with %d out of %d correct runs for expected=%d: %s\n", count_ok, nruns, expected, count_ok==nruns? "PASS":"FAIL");
9289 mpi_free(p);
9290 close(source);
9291 }
9292
9293 void time_mr(int nruns) {
9294 struct timespec tstart, tend;
9295 long int diff;
9296 int i;
9297 MPI prime;
9298 unsigned int noctets = KEY_LENGTH_OCTETS / 2;
9299 unsigned int nlimbs = mpi_nlimb_hint_from_nbytes(noctets);
9300
9301 int entropy_source = open_entropy_source(ENTROPY_SOURCE);
9302 if (entropy_source <= 0)
9303 err("can't open entropy source!");
9304
9305 /* first generate a prime of half key length, to make sure M-R will run max number of iterations */
9306 printf("Generating a prime number of %d octets length for M-R timing test\n", noctets);
9307 prime = mpi_alloc(nlimbs);
9308 gen_random_prime(noctets, prime);
9309
9310 printf("Running timing test for Miller-Rabin with %d repetitions and %d witnesses on prime number ", nruns, M_R_ITERATIONS);
9311 mpi_print(stdout, prime, 1);
9312 printf("\n");
9313 /* now do the actual runs and time it all */
9314 clock_gettime(CLOCK_MONOTONIC, &tstart);
9315 for (i=0; i<nruns; i++) {
9316 if (is_composite(prime, M_R_ITERATIONS, entropy_source))
9317 printf("FAIL");
9318 else printf(".");
9319 fflush(stdout);
9320 }
9321 clock_gettime(CLOCK_MONOTONIC, &tend);
9322
9323 diff = tend.tv_sec-tstart.tv_sec;
9324 printf("\nTimings on prime number %d octets long, %d runs of MR with %d iterations (witnesses checked) each\n", \
9325 noctets, nruns, M_R_ITERATIONS);
9326 printf("Total time: %ld seconds\nTime per MR run: %f seconds\nTime per MR iteration: %f seconds\n",\
9327 diff, diff / (1.0*nruns), diff / (1.0*nruns * M_R_ITERATIONS));
9328
9329 mpi_free(prime);
9330 close(entropy_source);
9331 }
9332
9333 void test_rpng(int nruns) {
9334 unsigned int noctets = KEY_LENGTH_OCTETS / 2;
9335 unsigned int nlimbs = mpi_nlimb_hint_from_nbytes(noctets);
9336 int entropy_source = open_entropy_source(ENTROPY_SOURCE);
9337 if (entropy_source <= 0)
9338 err("can't open entropy source!");
9339
9340 MPI prime = mpi_alloc(nlimbs);
9341 int i;
9342
9343 printf("TEST: random prime number generator with %d runs\n", nruns);
9344 for (i = 0;i < nruns; i++) {
9345 gen_random_prime(noctets, prime);
9346 printf("Run %d: ", i+1);
9347 mpi_print(stdout, prime, 1);
9348 if (is_composite(prime, M_R_ITERATIONS, entropy_source))
9349 printf(" **FAIL**\n");
9350 else
9351 printf(" **PASS**\n");
9352 }
9353
9354 mpi_free(prime);
9355 close(entropy_source);
9356 }
9357
9358 void time_rpng(int nruns) {
9359 struct timespec tstart, tend;
9360 long int diff;
9361
9362 unsigned int noctets = KEY_LENGTH_OCTETS / 2;
9363 unsigned int nlimbs = mpi_nlimb_hint_from_nbytes(noctets);
9364
9365 int entropy_source = open_entropy_source(ENTROPY_SOURCE);
9366 if (entropy_source <= 0)
9367 err("can't open entropy source!");
9368
9369 MPI prime = mpi_alloc(nlimbs);
9370 int i;
9371
9372 printf("TIMING: random prime number generator with %d runs\n", nruns);
9373 clock_gettime(CLOCK_MONOTONIC, &tstart);
9374 for (i = 0;i < nruns; i++) {
9375 gen_random_prime(noctets, prime);
9376 }
9377 clock_gettime(CLOCK_MONOTONIC, &tend);
9378
9379 diff = tend.tv_sec-tstart.tv_sec;
9380
9381 printf("TOTAL: %ld seconds\n", diff);
9382 printf("Average: %f seconds to generate one random prime of %d octets length\n", diff / (1.0*nruns), noctets);
9383 mpi_free(prime);
9384 close(entropy_source);
9385 }
9386
9387 /* Test encryption+decryption on noctets of random data, using sk
9388 * Output is written to file.
9389 */
9390 void test_rsa_keys( RSA_secret_key *sk, unsigned int noctets, FILE *file ) {
9391 RSA_public_key pk;
9392 MPI test = mpi_alloc ( mpi_nlimb_hint_from_nbytes (noctets) );
9393 MPI out1 = mpi_alloc ( mpi_nlimb_hint_from_nbytes (noctets) );
9394 MPI out2 = mpi_alloc ( mpi_nlimb_hint_from_nbytes (noctets) );
9395
9396 pk.n = mpi_copy(sk->n);
9397 pk.e = mpi_copy(sk->e);
9398 unsigned char *p;
9399 p = xmalloc(noctets);
9400
9401 fprintf(file, "TEST encrypt/decrypt on %d octets of random data\n", noctets);
9402 fflush(file);
9403 if (get_random_octets( noctets, p) == noctets) {
9404 mpi_set_buffer( test, p, noctets, 0 );
9405
9406 fprintf(file, "TEST data:\n");
9407 mpi_print(file, test, 1);
9408 fprintf(file, "\n");
9409 fflush(file);
9410
9411 public_rsa( out1, test, &pk );
9412 secret_rsa( out2, out1, sk );
9413
9414 fprintf(file, "ENCRYPTED with PUBLIC key data:\n");
9415 mpi_print(file, out1, 1);
9416 fprintf(file, "\n");
9417 fflush(file);
9418
9419 fprintf(file, "DECRYPTED with SECRET key:\n");
9420 mpi_print(file, out2, 1);
9421 fprintf(file, "\n");
9422 fflush(file);
9423
9424 if( mpi_cmp( test, out2 ) )
9425 fprintf(file, "FAILED: RSA operation: public(secret) failed\n");
9426 else
9427 fprintf(file, "PASSED: RSA operation: public(secret) passed\n");
9428 fflush(file);
9429
9430 secret_rsa( out1, test, sk );
9431 public_rsa( out2, out1, &pk );
9432 if( mpi_cmp( test, out2 ) )
9433 fprintf(file, "FAILED: RSA operation: secret(public) failed\n");
9434 else
9435 fprintf(file, "PASSED: RSA operation: secret(public) passed\n");
9436 }
9437 else
9438 fprintf(file, "FAILED: not enough bits returned from entropy source\n");
9439
9440 fflush(file);
9441 xfree(p);
9442 mpi_free( pk.n);
9443 mpi_free( pk.e);
9444
9445 mpi_free( test );
9446 mpi_free( out1 );
9447 mpi_free( out2 );
9448 }
9449
9450 void test_rsa( int nruns, FILE *fkeys, FILE *fout) {
9451 RSA_secret_key sk;
9452 int noctets = KEY_LENGTH_OCTETS;
9453 int noctets_pq = noctets / 2;
9454 int nlimbs = mpi_nlimb_hint_from_nbytes(noctets);
9455 int nlimbs_pq = mpi_nlimb_hint_from_nbytes(noctets_pq);
9456 int i;
9457
9458 sk.n = mpi_alloc(nlimbs);
9459 sk.e = mpi_alloc(nlimbs);
9460 sk.d = mpi_alloc(nlimbs);
9461 sk.p = mpi_alloc(nlimbs_pq);
9462 sk.q = mpi_alloc(nlimbs_pq);
9463 sk.u = mpi_alloc(nlimbs_pq);
9464
9465 printf("TEST RSA key generation and use with %d runs\n", nruns);
9466 fflush(stdout);
9467
9468 for (i = 0;i < nruns; i++) {
9469 gen_keypair(&sk);
9470 printf(".");
9471 fflush(stdout);
9472
9473 mpi_print(fkeys, sk.n, 1);
9474 fwrite("\n", sizeof(char), 1, fkeys);
9475
9476 mpi_print(fkeys, sk.e, 1);
9477 fwrite("\n", sizeof(char), 1, fkeys);
9478
9479 mpi_print(fkeys, sk.d, 1);
9480 fwrite("\n", sizeof(char), 1, fkeys);
9481
9482 mpi_print(fkeys, sk.p, 1);
9483 fwrite("\n", sizeof(char), 1, fkeys);
9484
9485 mpi_print(fkeys, sk.q, 1);
9486 fwrite("\n", sizeof(char), 1, fkeys);
9487
9488 mpi_print(fkeys, sk.u, 1);
9489 fwrite("\n", sizeof(char), 1, fkeys);
9490
9491 test_rsa_keys(&sk, noctets_pq, fout);
9492 printf("*");
9493 fflush(stdout);
9494 }
9495
9496 mpi_free(sk.n);
9497 mpi_free(sk.e);
9498 mpi_free(sk.d);
9499 mpi_free(sk.p);
9500 mpi_free(sk.q);
9501 mpi_free(sk.u);
9502
9503 }
9504
9505 void test_rsa_exp() {
9506 MPI msg = mpi_alloc(0);
9507 MPI expected = mpi_alloc(0);
9508 MPI result;
9509
9510 RSA_public_key pk;
9511 pk.n = mpi_alloc(0);
9512 pk.e = mpi_alloc(0);
9513
9514 printf("TEST verify of rsa exponentiation on input data: \n");
9515
9516 mpi_fromstr(msg, "0x\
9517 5B6A8A0ACF4F4DB3F82EAC2D20255E4DF3E4B7C799603210766F26EF87C8980E737579\
9518 EC08E6505A51D19654C26D806BAF1B62F9C032E0B13D02AF99F7313BFCFD68DA46836E\
9519 CA529D7360948550F982C6476C054A97FD01635AB44BFBDBE2A90BE06F7984AC8534C3\
9520 8613747F340C18176E6D5F0C10246A2FCE3A668EACB6165C2052497CA2EE483F4FD8D0\
9521 6A9911BD97E9B6720521D872BD08FF8DA11A1B8DB147F252E4E69AE6201D3B374B171D\
9522 F445EF2BF509D468FD57CEB5840349B14C6E2AAA194D9531D238B85B8F0DD352D1E596\
9523 71539B429849E5D965E438BF9EFFC338DF9AADF304C4130D5A05E006ED855F37A06242\
9524 28097EF92F6E78CAE0CB97");
9525
9526 mpi_fromstr(expected, "0x\
9527 1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\
9528 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\
9529 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\
9530 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\
9531 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003051300\
9532 D0609608648016503040203050004406255509399A3AF322C486C770C5F7F6E05E18FC\
9533 3E2219A03CA56C7501426A597187468B2F71B4A198C807171B73D0E7DBC3EEF6EA6AFF\
9534 693DE58E18FF84395BE");
9535 result = mpi_alloc( mpi_get_nlimbs(expected) );
9536
9537 mpi_fromstr(pk.n, "0x\
9538 CDD49A674BAF76D3B73E25BC6DF66EF3ABEDDCA461D3CCB6416793E3437C7806562694\
9539 73C2212D5FD5EED17AA067FEC001D8E76EC901EDEDF960304F891BD3CAD7F9A335D1A2\
9540 EC37EABEFF3FBE6D3C726DC68E599EBFE5456EF19813398CD7D548D746A30AA47D4293\
9541 968BFBAFCBF65A90DFFC87816FEE2A01E1DC699F4DDABB84965514C0D909D54FDA7062\
9542 A2037B50B771C153D5429BA4BA335EAB840F9551E9CD9DF8BB4A6DC3ED1318FF3969F7\
9543 B99D9FB90CAB968813F8AD4F9A069C9639A74D70A659C69C29692567CE863B88E191CC\
9544 9535B91B417D0AF14BE09C78B53AF9C5F494BCF2C60349FFA93C81E817AC682F0055A6\
9545 07BB56D6A281C1A04CEFE1");
9546
9547 mpi_fromstr( pk.e, "0x10001");
9548
9549 mpi_print( stdout, msg, 1);
9550 printf("\n");
9551
9552 public_rsa( result, msg, &pk);
9553 if ( mpi_cmp( result, expected) != 0 )
9554 printf( "FAILED\n");
9555 else
9556 printf( "PASSED\n");
9557
9558 printf("Expected:\n");
9559 mpi_print( stdout, expected, 1);
9560 printf("\n");
9561
9562 printf("Obtained:\n");
9563 mpi_print( stdout, result, 1);
9564 printf("\n");
9565
9566 mpi_free( pk.n );
9567 mpi_free( pk.e );
9568 mpi_free( msg );
9569 mpi_free( expected );
9570 mpi_free( result );
9571 }
9572
9573 void time_rsa_gen( int nruns ) {
9574 struct timespec tstart, tend;
9575 long int diff;
9576 int i;
9577
9578 RSA_secret_key sk;
9579 int noctets = KEY_LENGTH_OCTETS;
9580 int noctets_pq = noctets / 2;
9581 int nlimbs = mpi_nlimb_hint_from_nbytes(noctets);
9582 int nlimbs_pq = mpi_nlimb_hint_from_nbytes(noctets_pq);
9583 sk.n = mpi_alloc(nlimbs);
9584 sk.e = mpi_alloc(nlimbs);
9585 sk.d = mpi_alloc(nlimbs);
9586 sk.p = mpi_alloc(nlimbs_pq);
9587 sk.q = mpi_alloc(nlimbs_pq);
9588 sk.u = mpi_alloc(nlimbs_pq);
9589
9590 clock_gettime(CLOCK_MONOTONIC, &tstart);
9591 for (i = 0;i < nruns; i++) {
9592 gen_keypair(&sk);
9593 }
9594 clock_gettime(CLOCK_MONOTONIC, &tend);
9595
9596 diff = tend.tv_sec-tstart.tv_sec;
9597
9598 printf("TOTAL: %ld seconds for generating %d key pairs\n", diff, nruns);
9599 printf("Average (%d runs): %f seconds per TMSR RSA key pair.\n",
9600 nruns, diff / (1.0*nruns));
9601 mpi_free(sk.n);
9602 mpi_free(sk.e);
9603 mpi_free(sk.d);
9604 mpi_free(sk.p);
9605 mpi_free(sk.q);
9606 mpi_free(sk.u);
9607 }
9608
9609 void test_oaep_encr_decr( int nruns ) {
9610 /* a set of RSA keys previously generated with eucrypt */
9611 RSA_public_key pk;
9612 pk.n = mpi_alloc(0);
9613 pk.e = mpi_alloc(0);
9614
9615 RSA_secret_key sk;
9616 sk.n = mpi_alloc(0);
9617 sk.e = mpi_alloc(0);
9618 sk.d = mpi_alloc(0);
9619 sk.p = mpi_alloc(0);
9620 sk.q = mpi_alloc(0);
9621 sk.u = mpi_alloc(0);
9622
9623 mpi_fromstr(sk.n, "0x\
9624 CD2C025323BEA46FFF2FA8D7A9D39817EA713421F4AE03FA8120641193892A70BFECF5\
9625 83101635A432110D3DDE6339E3CC7ECC0AD91C026FCACE832DD3888A6FCA7BCE56C390\
9626 5A5AC8C7BC921DA675E4B62489B254EB34659D547D71165BC998983A81937BD251AEE1\
9627 2D985EC387D5376F5DCC5EF7EC530FBD6FD2AA7285EE1AF3335EA73163F0954F30402E\
9628 D7B374EE84A97B1849B0674B0DA0A2050BD79B71ABB1559F3A9CFDB8557DED7BC90CF2\
9629 09E8A847E9C226140845B7D03842162E7DA5DD16326CB1F71A248D841FE9076A09911F\
9630 2F4F5E3EA44EA8DE40332BF00406990BCCF61C322A03C456EF3A98B341E0BDBC1088CE\
9631 683E78510E76B72C2BCC1EE9AEDD80FFF18ABFC5923B2F36B581C25114AB2DF9F6C2B1\
9632 9481703FD19E313DCD7ACE15FA11B27D25BCE5388C180A7E21167FB87750599E1ED7C7\
9633 50F4A844E1DC2270C62D19671CF8F4C25B81E366B09FC850AE642136D204A9160AEECE\
9634 575B57378AA439E9DD46DC990288CD54BAA35EEE1C02456CD39458A6F1CBF012DCEDF4\
9635 27CCF3F3F53645658FC49C9C9D7F2856DB571D92B967AB5845514E0054DDB49099F5DD\
9636 04A6F6F5C5CE642276834B932881AEB648D1F25E9223971F56E249EF40CF7D80F22621\
9637 CDD0260E9E7D23746960ADB52CF2987584FB1DE95A69A39E5CB12B76E0F5C1A0529C0C\
9638 065D2E35720810F7C7983180B9A9EA0E00C11B79DC3D");
9639
9640 mpi_fromstr(sk.e, "0x\
9641 DD4856B4EE3D099A8604AE392D8EFEC094CDF01546A28BE87CB484F999E8E75CDFCD01\
9642 D04D455A6A9254C60BD28C0B03611FC3E751CC27EF768C0B401C4FD2B27C092834A6F2\
9643 49A145C4EDC47A3B3D363EC352462C945334D160AF9AA72202862912493AC6190AA3A6\
9644 149D4D8B9996BA7927D3D0D2AD00D30FD630CF464E6CAF9CF49355B9A70E05DB7AE915\
9645 F9F602772F8D11E5FCDFC7709210F248052615967090CC1F43D410C83724AA5912B2F0\
9646 52E6B39449A89A97C79C92DC8CB8DEEFCF248C1E1D2FC5BFE85165ECA31839CAA9CEB3\
9647 3A92EBDC0EB3BAC0F810938BB173C7DA21DCBB2220D44CBA0FD40A2C868FC93AC5243E\
9648 C137C27B0A76D65634EBB3");
9649
9650 mpi_fromstr(sk.d, "0x\
9651 7C8A6FA1199D99DCA45E9BDF567CA49D02B237340D7E999150BC4883AE29DEC5158521\
9652 B338F35DC883792356BDDBB3C8B3030A6DD4C6522599A3254E751F9BA1CB1061C5633C\
9653 81BBFACF6FCD64502614102DFED3F3FA284066C342D5E00953B415915331E30812E5FB\
9654 CD6680ADCCDEE40B8376A3A225F2E160EA59C7566804526D73BB660A648A3EF9802313\
9655 B2F841E8458B2AAACE7AACF31083E8F3F630298138393BC88BBD7D4AA4334949651D25\
9656 365B10DBF4A4A08E20A6CC74BFDD37C1C38E2ADC2A283DF06590DF06B46F67F6ACA67F\
9657 AC464C795261659A2F9558802D0BBAA05FD1E1AF2CDC70654723DF7EFAEA148B8CDBEB\
9658 C89EA2320AB9BBB1BC4311475DF3D91446F02EF192368DFEBAC598CCFD4407DEC58FDC\
9659 1A94CCDD6E5FBA9C52164ACEA8AEE633E557BCCEACB7A1AF656C379482D784A120A725\
9660 32F9B2B35173D505F21D5AD4CB9511BC836DC923730B70291B70290A216CA3B21CFF79\
9661 E895C35F4F7AF80E1BD9ED2773BD26919A76E4298D169160593E0335BE2A2A2D2E8516\
9662 948F657E1B1260E18808A9D463C108535FB60B3B28F711C81E5DE24F40214134A53CE5\
9663 9A952C8970A1D771EBEFFA2F4359DCF157995B3F1950DE3C6EC41B7FF837148F55F323\
9664 372AF3F20CE8B8038E750C23D8F5041FA951327859B0E47483F0A47103EF808C72C251\
9665 006FA526245291C8C84C12D2EF63FB2301EA3EEDA42B");
9666
9667 mpi_fromstr(sk.p, "0x\
9668 E236732452039C14EC1D3B8095BDDCFB7625CE27B1EA5394CF4ED09D3CEECAA4FC0BF6\
9669 2F7CE975E0C8929CE84B0259D773EA038396479BF15DA065BA70E549B248D77B4B23ED\
9670 A267308510DBEE2FD44E35D880EE7CFB81E0646AA8630165BD8988C3A8776D9E704C20\
9671 AA25CA0A3C32F27F592D5FD363B04DD57D8C61FFDCDFCCC59E2913DE0EE47769180340\
9672 E1EA5A803AA2301A010FF553A380F002601F0853FCACDB82D76FE2FACBCD6E5F294439\
9673 0799EA5AE9D7880D4E1D4AE146DC1D4E8495B9DD30E57E883923C5FC26682B7142D35C\
9674 D8A0FC561FE725A6CF419B15341F40FE0C31132CBD81DD8E50697BD1EBFFA16B522E16\
9675 F5B49A03B707218C7DA60B");
9676
9677 mpi_fromstr(sk.q, "0x\
9678 E830482A3C4F5C3A7E59C10FF8BA760DB1C6D55880B796FFDA4A82E0B60E974E81D04B\
9679 2A4AD417823EBFB4E8EFB13782943562B19B6C4A680E3BA0C8E37B5023470F4F1AC1F8\
9680 A0B10672EF75CD58BCD45E6B14503B8A6A70AFE79F6201AF56E7364A1C742BE1453FD2\
9681 24FDC9D66522EAF4466A084BCB9E46D455A2946E94CBF028770F38D0B741C2CC59308F\
9682 71D8C2B4B9C928E0AE8D68DEB48A3E9EFD84A10301EBD55F8221CA32FC567B306B2A8E\
9683 116350AFB995859FDF4378C5CFD06901494E8CFA5D8FAC564D6531FA8A2E4761F5EFBA\
9684 F78750B6F4662BE9EA4C2FAD67AF73EEB36B41FC15CB678810C19A51DF23555695C4C1\
9685 546F3FACA39CAA7BB8DBD7");
9686
9687 mpi_fromstr(sk.u, "0x\
9688 846232322775C1CD7D5569DC59E2F3E61A885AE2E9C4A4F8CB3ACBE8C3A5441E5FE348\
9689 A2A8AC9C2998FBF282222BF508AA1ECF66A76AEDD2D9C97028BFD3F6CA0542E38A5312\
9690 603C70B95650CE73F80FDD729988FBDB5595A5BF8A007EA34E54994A697906CE56354C\
9691 E00DF10EB711DEC274A62494E3D350D88736CF67A477FB600AC9F1D6580727585092BF\
9692 5EBC092CC4D6CF75769051033A1197103BE269942F372168A53771746FBA18ED6972D5\
9693 0B935A9B1D6B5B3DD50CD89A27FE93C10924E9103FACF7B4C5724A046C3D3B50CC1C78\
9694 5F5C8E00DBE1D6561F120F5294C170914BC10F978ED4356EED67A9F3A60D70AFE540FC\
9695 5373CBAE3D0A7FD1C87273");
9696
9697 /* copy the public key components */
9698 pk.n = mpi_copy( sk.n );
9699 pk.e = mpi_copy( sk.e );
9700
9701 /* some plain text message */
9702 MPI msg = mpi_alloc(0);
9703 mpi_fromstr(msg, "0x\
9704 5B6A8A0ACF4F4DB3F82EAC2D20255E4DF3E4B7C799603210766F26EF87C8980E737579\
9705 EC08E6505A51D19654C26D806BAF1B62F9C032E0B13D02AF99F7313BFCFD68DA46836E\
9706 CA529D7360948550F982C6476C054A97FD01635AB44BFBDBE2A90BE06F7984AC8534C3\
9707 28097EF92F6E78CAE0CB97");
9708
9709 /* actual testing */
9710 printf("TEST verify oaep_encr_decr on message: \n");
9711 mpi_print( stdout, msg, 1);
9712 printf("\n");
9713
9714 int nlimbs_n = mpi_nlimb_hint_from_nbytes( KEY_LENGTH_OCTETS);
9715 MPI encr = mpi_alloc( nlimbs_n );
9716 MPI decr = mpi_alloc( nlimbs_n );
9717 int success;
9718
9719 adainit();
9720 rsa_oaep_encrypt( encr, msg, &pk );
9721 rsa_oaep_decrypt( decr, encr, &sk, &success );
9722
9723 if (success <= 0 ||
9724 mpi_cmp(encr, msg) == 0 ||
9725 mpi_cmp(msg, decr) != 0)
9726 printf("FAILED: success flag is %d\n", success);
9727 else
9728 printf("PASSED\n");
9729
9730 /* attempt to decrypt corrupted block */
9731 mpi_clear( decr );
9732 rsa_oaep_decrypt( decr, pk.n, &sk, &success);
9733 if (success > 0)
9734 printf("FAILED: attempt to decrypt non-/corrupted oaep block\n");
9735 else
9736 printf("PASSED: attempt to decrypt non-/corrupted oaep block\n");
9737 adafinal();
9738
9739 /* clean up */
9740 mpi_free( sk.n );
9741 mpi_free( sk.e );
9742 mpi_free( sk.d );
9743 mpi_free( sk.p );
9744 mpi_free( sk.q );
9745 mpi_free( sk.u );
9746
9747 mpi_free( pk.n );
9748 mpi_free( pk.e );
9749
9750 mpi_free( msg );
9751 mpi_free( encr );
9752 mpi_free( decr );
9753 }
9754
9755 void test_mpi_buffer() {
9756 unsigned int noctets = 10;
9757 int nlimbs = mpi_nlimb_hint_from_nbytes( noctets );
9758 MPI m = mpi_alloc( nlimbs );
9759 unsigned char *setbuffer = xmalloc( noctets );
9760 unsigned char *getbuffer;
9761 unsigned int i, sign, mpilen, nerrors;
9762
9763 for (i=0; i< noctets; i++)
9764 setbuffer[i] = i;
9765
9766 mpi_set_buffer( m, setbuffer, noctets, 0);
9767
9768 getbuffer = mpi_get_buffer( m, &mpilen, &sign );
9769
9770 if (mpilen == noctets -1 ) {
9771 nerrors = 0;
9772 for (i=0;i<noctets-1;i++)
9773 if (setbuffer[i+1] != getbuffer[i])
9774 nerrors = nerrors + 1;
9775 if (nerrors == 0) {
9776 printf("WARNING: 0-led octet discarded by mpi_set_buffer!\n");
9777 printf("Value ret by mpi_get_buffer != value given to set_buffer!\n");
9778 }
9779 else
9780 printf("FAIL: got different lengths and %d different values!\n", nerrors);
9781 }
9782 else if (mpilen != noctets)
9783 printf("FAIL: mpilen is %d; noctets is %d\n", mpilen, noctets);
9784 else
9785 {
9786 nerrors = 0;
9787 for (i=0;i<noctets-1;i++) {
9788 if (setbuffer[i]!=getbuffer[i])
9789 nerrors= nerrors+1;
9790 }
9791 if (nerrors>0)
9792 printf("FAIL: got %d different values!\n", nerrors);
9793 else printf("PASSED: mpi_get/set_buffer\n");
9794 }
9795
9796 mpi_free(m);
9797 xfree(setbuffer);
9798 xfree(getbuffer);
9799 }
9800
9801 void test_dirty_float_rng( int nruns ) {
9802 int i, status;
9803 float dirty;
9804
9805 printf("Running test for smg rng dirty float with %d runs\n", nruns);
9806 for (i=0; i<nruns; i++) {
9807 status = rng_dirty_float( &dirty );
9808 printf("Run %d: %f status %s\n", i+1, dirty, status>0 ? "OK" : "FAIL");
9809 }
9810 }
9811
9812 void test_ieee_float_rng( int nruns ) {
9813 int i, status;
9814 float ieee;
9815
9816 printf("Running test for smg rng ieee 745/1985 float with %d runs\n", nruns);
9817 for (i=0; i<nruns; i++) {
9818 status = rng_float_754_1985( &ieee );
9819 printf("Run %d: %f status %s\n", i+1, ieee, status>0 ? "OK" : "FAIL");
9820 }
9821 }
9822
9823 void test_uint32_rng( int nruns ) {
9824 int i, status;
9825 uint32_t n;
9826
9827 printf("Running test for smg rng unsigned int32 with %d runs\n", nruns);
9828 for (i=0; i<nruns; i++) {
9829 status = rng_uint32( &n );
9830 printf("Run %d: %"PRIu32" status %s\n", i+1, n, status>0 ? "OK" : "FAIL");
9831 }
9832 }
9833
9834 void test_uint64_rng( int nruns ) {
9835 int i, status;
9836 uint64_t n;
9837
9838 printf("Running test for smg rng unsigned int64 with %d runs\n", nruns);
9839 for (i=0; i<nruns; i++) {
9840 status = rng_uint64( &n );
9841 printf("Run %d: %"PRIu64" status %s\n", i+1, n, status>0 ? "OK" : "FAIL");
9842 }
9843 }
9844
9845
9846 int main(int ac, char **av)
9847 {
9848 int nruns;
9849 int id;
9850 FILE *fk;
9851 FILE *fout;
9852
9853 if (ac<2) {
9854 printf("Usage: %s number_of_runs/octets [testID]\n", av[0]);
9855 return -1;
9856 }
9857 nruns = atoi(av[1]);
9858
9859 if (ac < 3)
9860 id = -1;
9861 else
9862 id = atoi(av[2]);
9863
9864 switch ( id ) {
9865 case 0:
9866 printf("Timing entropy source...\n");
9867 time_entropy_source(nruns, 4096);
9868 break;
9869 case 1:
9870 test_entropy_output(nruns, "entropy_source_output.txt");
9871 break;
9872 case 2:
9873 /* tests on miller-rabin */
9874 /* a few primes (decimal): 65537, 116447, 411949103, 20943302231 */
9875 test_is_composite(nruns, "0x10001", 0);
9876 test_is_composite(nruns, "0x1C6DF", 0);
9877 test_is_composite(nruns, "0x188DD82F", 0);
9878 test_is_composite(nruns, "0x4E0516E57", 0);
9879 /* a few mersenne primes (decimal): 2^13 - 1 = 8191, 2^17 - 1 = 131071, 2^31 - 1 = 2147483647 */
9880 test_is_composite(nruns, "0x1FFF", 0);
9881 test_is_composite(nruns, "0x1FFFF", 0);
9882 test_is_composite(nruns, "0x7FFFFFFF", 0);
9883 /* a few carmichael numbers, in decimal: 561, 60977817398996785 */
9884 test_is_composite(nruns, "0x231", 1);
9885 test_is_composite(nruns, "0xD8A300793EEF31", 1);
9886 /* an even number */
9887 test_is_composite(nruns, "0x15A9E672864B1E", 1);
9888 /* a phuctor-found non-prime public exponent: 170141183460469231731687303715884105731 */
9889 test_is_composite(nruns, "0x80000000000000000000000000000003", 1);
9890 break;
9891 case 3:
9892 time_mr(nruns);
9893 break;
9894 case 4:
9895 test_rpng(nruns);
9896 break;
9897 case 5:
9898 time_rpng(nruns);
9899 break;
9900 case 6:
9901 fk = fopen("keys.asc", "a");
9902 if ( fk == NULL )
9903 err("Failed to open file keys.asc!");
9904 fout = fopen("check_keys.asc", "a");
9905 if ( fout == NULL ) {
9906 fclose(fk);
9907 err("Failed to open file keys_check.asc!");
9908 }
9909 test_rsa(nruns, fk, fout);
9910 fclose(fk);
9911 fclose(fout);
9912 break;
9913 case 7:
9914 test_rsa_exp();
9915 break;
9916 case 8:
9917 time_rsa_gen(nruns);
9918 break;
9919 case 9:
9920 test_oaep_encr_decr(nruns);
9921 break;
9922 case 10:
9923 test_mpi_buffer();
9924 break;
9925 case 11:
9926 test_dirty_float_rng(nruns);
9927 break;
9928 case 12:
9929 test_ieee_float_rng(nruns);
9930 break;
9931 case 13:
9932 test_uint32_rng(nruns);
9933 break;
9934 case 14:
9935 test_uint64_rng(nruns);
9936 break;
9937 default:
9938 printf("Current test ids:\n");
9939 printf("0 for timing entropy source\n");
9940 printf("1 for entropy output test\n");
9941 printf("2 for is_composite (Miller-Rabin) test\n");
9942 printf("3 for timing Miller-Rabin\n");
9943 printf("4 for random prime number generator test\n");
9944 printf("5 for timing random prime number generator\n");
9945 printf("6 for testing rsa key pair generation and use; \
9946 writes to keys.asc and check_keys.asc\n");
9947 printf("7 for testing rsa exponentiation (fixed data)\n");
9948 printf("8 for timing rsa key pair generator\n");
9949 printf("9 for oaep encrypt/decrypt\n");
9950 printf("10 for testing mpi_set/get_buffer\n");
9951 printf("11 for testing smg_rng dirty float\n");
9952 printf("12 for testing smg_rng ieee 745/1985 float\n");
9953 printf("13 for testing smg_rng uint32 \n");
9954 printf("14 for testing smg_rng uint64 \n");
9955 }
9956
9957 return 0;
9958 }
-
+ 234021F88C073C4C0E719125E55546A98351A2CF0DF584701FF19A9E8D9EA5B134FD9FDBCC24CD412C56802099A2929B608C41D3ACF7E8FB545EB1C04F8BDF9F
smg_comms/rsa/truerandom.c
(0 . 0)(1 . 176)
9963 #include <stdio.h>
9964 #include <stdlib.h>
9965 #include <string.h>
9966
9967 #include <fcntl.h>
9968 #include <unistd.h>
9969 #include <termios.h>
9970 #include <errno.h>
9971
9972 #include "smg_rsa.h"
9973
9974
9975 int set_usb_attribs(int fd, int speed) {
9976 struct termios tty;
9977 if (tcgetattr(fd, &tty) < 0) {
9978 return -1;
9979 }
9980
9981 /* input and output speeds */
9982 cfsetospeed(&tty, (speed_t)speed);
9983 cfsetispeed(&tty, (speed_t)speed);
9984
9985 /* raw */
9986 tty.c_lflag &= ~(ECHO | ECHOE | ECHOK);
9987 tty.c_oflag &= ~OPOST;
9988
9989 /* read at least one octet at a time; BLOCK until at least VMIN octets read */
9990 tty.c_cc[VMIN] = 1;
9991 tty.c_cc[VTIME] = 0;
9992
9993 if (tcsetattr(fd, TCSAFLUSH, &tty) != 0)
9994 return -1;
9995
9996 return 0;
9997 }
9998
9999 int open_entropy_source(char* source_name) {
10000 int in, err;
10001
10002 in = open(source_name, O_RDONLY | O_NOCTTY | O_NDELAY);
10003 if (in == -1) {
10004 printf("ERROR: failure to open entropy source %s: %s\n", source_name, strerror(errno));
10005 return in; //failed to access entropy source
10006 }
10007
10008 fcntl(in, F_SETFL, 0);
10009
10010 err = set_usb_attribs(in, B115200);
10011 if (err==-1) {
10012 printf("Error setting attributes on %s: %s\n", source_name, strerror(errno));
10013 return err;
10014 }
10015
10016 return in; //source opened, return its descriptor
10017 }
10018
10019 int get_random_octets_from(int noctets, unsigned char *out, int from) {
10020
10021 int nread;
10022 int total = 0;
10023
10024 while (total < noctets) {
10025 errno = 0;
10026 nread = read(from, out+total, noctets-total);
10027 //on interrupt received just try again
10028 if (nread == -1 && errno == EINTR)
10029 continue;
10030 //on error condition abort
10031 if (errno != 0 && (nread == -1 || nread == 0)) {
10032 printf("Error reading from entropy source %s after %d read: %s\n", ENTROPY_SOURCE, total, strerror(errno));
10033 return total; //total read so far
10034 }
10035
10036 if (nread > 0)
10037 total = total + nread;
10038 }
10039 return total; //return number of octets read
10040 }
10041
10042 int get_random_octets(int noctets, unsigned char *out) {
10043 int in;
10044 int nread = 0;
10045
10046 in = open_entropy_source(ENTROPY_SOURCE);
10047 if (in > 0) {
10048 nread = get_random_octets_from(noctets, out, in);
10049 close(in);
10050 }
10051 return nread;
10052 }
10053
10054 int rng_dirty_float(float *n) {
10055 int status; /* for aborting in case of error */
10056 uint32_t r; /* a random value on 32 bits */
10057 uint32_t maxval = 0xffffffff; /* maximum value on 32 bits */
10058
10059 /* obtain a random number on 32 bits using ENTROPY_SOURCE */
10060 status = rng_uint32( &r );
10061 if ( status < 0 )
10062 return status;
10063
10064 /* calculate and assign the floating-point random value as (r*1.0)/max val */
10065 /* multiplication by 1.0 IS NEEDED to do float division rather than int div*/
10066 *n = ( r * 1.0 ) / maxval;
10067
10068 return 1;
10069 }
10070
10071 int rng_float_754_1985(float *n) {
10072 /* Single float ieee 754/1985 has 23 bits that can be set for the mantissa
10073 * (and one implicit bit=1).
10074 * Full single float ieee 754/1985 representation takes 4 octets in total.
10075 */
10076 int noctets = 4; /* number of octets to read from ENTROPY_SOURCE */
10077 int nread; /* number of octets *read* from ENTROPY_SOURCE */
10078 unsigned char bits[ noctets ]; /* the random bits from ENTROPY_SOURCE */
10079 int oSignExp, oExpM;/* offsets for sign+exponent octet, exponent+mantissa*/
10080
10081 /* obtain random bits */
10082 nread = get_random_octets( noctets, bits );
10083
10084 if (nread != noctets )
10085 return -1; /* something wrong at reading from ENTROPY_SOURCE, abort */
10086
10087 /* set offsets for bit diddling depending on endianness of iron */
10088 if (is_bigendian()) {
10089 oSignExp = 0;
10090 oExpM = 1;
10091 }
10092 else {
10093 oSignExp = 3;
10094 oExpM = 2;
10095 }
10096
10097 /* set sign=0; exponent=127; explicit mantissa = random bits (23 bits) */
10098 *(bits+oExpM) = *(bits+2) | 0x80; /* one bit of exponent set */
10099 *(bits+oSignExp) = 0x3f; /* sign=0; exponent bits for 127 */
10100
10101 /* now copy the bits to the result var (i.e. as a float's representation */
10102 memcpy( n, bits, noctets );
10103 return 1;
10104 }
10105
10106 int rng_uint32( uint32_t *n ) {
10107 int noctets = 4; /* 32 bits aka 4 octets to read from ENTROPY_SOURCE */
10108 int nread; /* the number of octets read from ENTROPY_SOURCE */
10109 unsigned char bits[ noctets ]; /* for storing the bits from ENTROPY_SOURCE */
10110
10111 /* read random 32 bits from ENTROPY_SOURCE */
10112 nread = get_random_octets( noctets, bits );
10113 if ( nread != noctets )
10114 return -1;
10115
10116 /* copy the random bits to n, to be interpreted as uint32 */
10117 /* endianness is irrelevant here - the bits are random anyway */
10118 memcpy( n, bits, noctets );
10119
10120 return 1;
10121 }
10122
10123 int rng_uint64( uint64_t *n ) {
10124 int noctets = 8; /* 64 bits aka 8 octets to read from ENTROPY_SOURCE */
10125 int nread; /* the number of octets read from ENTROPY_SOURCE */
10126 unsigned char bits[ noctets ]; /* for storing the bits from ENTROPY_SOURCE */
10127
10128 /* read random 64 bits from ENTROPY_SOURCE */
10129 nread = get_random_octets( noctets, bits );
10130 if ( nread != noctets )
10131 return -1;
10132
10133 /* copy the random bits to n, to be interpreted as uint64 */
10134 /* endianness is irrelevant here - the bits are random anyway */
10135 memcpy( n, bits, noctets );
10136
10137 return 1;
10138 }
- 5834ABB16DF880D02AC7208FB19A1C2CB14CAD43AFA73537246D0734D9A845F156F5519BC93D2DF74AA479611FC015E5F5A62023025606E5C2E43CFE894730DD
+ 1EF7799C9ABE4DF9E1BEB1903C3EA0EBA7B9AF7407DE48E0A8556933A600490BED4815F14DA7AE5554209EE93E01A55BB5479ECDDDA7560E590C9768CDE955A2
smg_comms/smg_comms.gpr
(2 . 6)(2 . 8)
10143 -- prototype implementation of S.MG communication protocol
10144 -- http://trilema.com/2018/euloras-communication-protocol-restated/
10145
10146 with "c_wrappers/c_wrappers.gpr";
10147
10148 project SMG_comms is
10149
10150 type Mode_Type is ("debug", "release");