Ruby  2.0.0p451(2014-02-24revision45167)
ossl_bn.c
Go to the documentation of this file.
1 /*
2  * $Id: ossl_bn.c 40113 2013-04-04 15:56:00Z nagachika $
3  * 'OpenSSL for Ruby' project
4  * Copyright (C) 2001-2002 Technorama team <oss-ruby@technorama.net>
5  * All rights reserved.
6  */
7 /*
8  * This program is licenced under the same licence as Ruby.
9  * (See the file 'LICENCE'.)
10  */
11 /* modified by Michal Rokos <m.rokos@sh.cvut.cz> */
12 #include "ossl.h"
13 
14 #define WrapBN(klass, obj, bn) do { \
15  if (!(bn)) { \
16  ossl_raise(rb_eRuntimeError, "BN wasn't initialized!"); \
17  } \
18  (obj) = Data_Wrap_Struct((klass), 0, BN_clear_free, (bn)); \
19 } while (0)
20 
21 #define GetBN(obj, bn) do { \
22  Data_Get_Struct((obj), BIGNUM, (bn)); \
23  if (!(bn)) { \
24  ossl_raise(rb_eRuntimeError, "BN wasn't initialized!"); \
25  } \
26 } while (0)
27 
28 #define SafeGetBN(obj, bn) do { \
29  OSSL_Check_Kind((obj), cBN); \
30  GetBN((obj), (bn)); \
31 } while (0)
32 
33 /*
34  * Classes
35  */
38 
39 /*
40  * Public
41  */
42 VALUE
43 ossl_bn_new(const BIGNUM *bn)
44 {
45  BIGNUM *newbn;
46  VALUE obj;
47 
48  newbn = bn ? BN_dup(bn) : BN_new();
49  if (!newbn) {
51  }
52  WrapBN(cBN, obj, newbn);
53 
54  return obj;
55 }
56 
57 BIGNUM *
59 {
60  BIGNUM *bn = NULL;
61 
62  if (RTEST(rb_obj_is_kind_of(obj, cBN))) {
63  GetBN(obj, bn);
64  } else switch (TYPE(obj)) {
65  case T_FIXNUM:
66  case T_BIGNUM:
67  obj = rb_String(obj);
68  if (!BN_dec2bn(&bn, StringValuePtr(obj))) {
70  }
71  WrapBN(cBN, obj, bn); /* Handle potencial mem leaks */
72  break;
73  case T_NIL:
74  break;
75  default:
76  ossl_raise(rb_eTypeError, "Cannot convert into OpenSSL::BN");
77  }
78  return bn;
79 }
80 
81 /*
82  * Private
83  */
84 /*
85  * BN_CTX - is used in more difficult math. ops
86  * (Why just 1? Because Ruby itself isn't thread safe,
87  * we don't need to care about threads)
88  */
89 BN_CTX *ossl_bn_ctx;
90 
91 static VALUE
93 {
94  BIGNUM *bn;
95  VALUE obj;
96 
97  if (!(bn = BN_new())) {
99  }
100  WrapBN(klass, obj, bn);
101 
102  return obj;
103 }
104 
105 /*
106  * call-seq:
107  * BN.new => aBN
108  * BN.new(bn) => aBN
109  * BN.new(string) => aBN
110  * BN.new(string, 0 | 2 | 10 | 16) => aBN
111  */
112 static VALUE
114 {
115  BIGNUM *bn;
116  VALUE str, bs;
117  int base = 10;
118 
119  if (rb_scan_args(argc, argv, "11", &str, &bs) == 2) {
120  base = NUM2INT(bs);
121  }
122 
123  if (RTEST(rb_obj_is_kind_of(str, cBN))) {
124  BIGNUM *other;
125 
126  GetBN(self, bn);
127  GetBN(str, other); /* Safe - we checked kind_of? above */
128  if (!BN_copy(bn, other)) {
130  }
131  return self;
132  }
133 
134  StringValue(str);
135  GetBN(self, bn);
136  switch (base) {
137  case 0:
138  if (!BN_mpi2bn((unsigned char *)RSTRING_PTR(str), RSTRING_LENINT(str), bn)) {
140  }
141  break;
142  case 2:
143  if (!BN_bin2bn((unsigned char *)RSTRING_PTR(str), RSTRING_LENINT(str), bn)) {
145  }
146  break;
147  case 10:
148  if (!BN_dec2bn(&bn, RSTRING_PTR(str))) {
150  }
151  break;
152  case 16:
153  if (!BN_hex2bn(&bn, RSTRING_PTR(str))) {
155  }
156  break;
157  default:
158  ossl_raise(rb_eArgError, "invalid radix %d", base);
159  }
160  return self;
161 }
162 
163 /*
164  * call-seq:
165  * bn.to_s => string
166  * bn.to_s(base) => string
167  *
168  * === Parameters
169  * * +base+ - integer
170  * * * Valid values:
171  * * * * 0 - MPI
172  * * * * 2 - binary
173  * * * * 10 - the default
174  * * * * 16 - hex
175  */
176 static VALUE
178 {
179  BIGNUM *bn;
180  VALUE str, bs;
181  int base = 10, len;
182  char *buf;
183 
184  if (rb_scan_args(argc, argv, "01", &bs) == 1) {
185  base = NUM2INT(bs);
186  }
187  GetBN(self, bn);
188  switch (base) {
189  case 0:
190  len = BN_bn2mpi(bn, NULL);
191  str = rb_str_new(0, len);
192  if (BN_bn2mpi(bn, (unsigned char *)RSTRING_PTR(str)) != len)
194  break;
195  case 2:
196  len = BN_num_bytes(bn);
197  str = rb_str_new(0, len);
198  if (BN_bn2bin(bn, (unsigned char *)RSTRING_PTR(str)) != len)
200  break;
201  case 10:
202  if (!(buf = BN_bn2dec(bn))) ossl_raise(eBNError, NULL);
203  str = ossl_buf2str(buf, rb_long2int(strlen(buf)));
204  break;
205  case 16:
206  if (!(buf = BN_bn2hex(bn))) ossl_raise(eBNError, NULL);
207  str = ossl_buf2str(buf, rb_long2int(strlen(buf)));
208  break;
209  default:
210  ossl_raise(rb_eArgError, "invalid radix %d", base);
211  }
212 
213  return str;
214 }
215 
216 /*
217  * call-seq:
218  * bn.to_i => integer
219  */
220 static VALUE
222 {
223  BIGNUM *bn;
224  char *txt;
225  VALUE num;
226 
227  GetBN(self, bn);
228 
229  if (!(txt = BN_bn2dec(bn))) {
231  }
232  num = rb_cstr_to_inum(txt, 10, Qtrue);
233  OPENSSL_free(txt);
234 
235  return num;
236 }
237 
238 static VALUE
240 {
241  return self;
242 }
243 
244 static VALUE
246 {
247  switch(TYPE(other)) {
248  case T_STRING:
249  self = ossl_bn_to_s(0, NULL, self);
250  break;
251  case T_FIXNUM:
252  case T_BIGNUM:
253  self = ossl_bn_to_i(self);
254  break;
255  default:
256  if (!RTEST(rb_obj_is_kind_of(other, cBN))) {
257  ossl_raise(rb_eTypeError, "Don't know how to coerce");
258  }
259  }
260  return rb_assoc_new(other, self);
261 }
262 
263 #define BIGNUM_BOOL1(func) \
264  /* \
265  * call-seq: \
266  * bn.##func -> true | false \
267  * \
268  */ \
269  static VALUE \
270  ossl_bn_##func(VALUE self) \
271  { \
272  BIGNUM *bn; \
273  GetBN(self, bn); \
274  if (BN_##func(bn)) { \
275  return Qtrue; \
276  } \
277  return Qfalse; \
278  }
281 BIGNUM_BOOL1(is_odd)
282 
283 #define BIGNUM_1c(func) \
284  /* \
285  * call-seq: \
286  * bn.##func -> aBN \
287  * \
288  */ \
289  static VALUE \
290  ossl_bn_##func(VALUE self) \
291  { \
292  BIGNUM *bn, *result; \
293  VALUE obj; \
294  GetBN(self, bn); \
295  if (!(result = BN_new())) { \
296  ossl_raise(eBNError, NULL); \
297  } \
298  if (!BN_##func(result, bn, ossl_bn_ctx)) { \
299  BN_free(result); \
300  ossl_raise(eBNError, NULL); \
301  } \
302  WrapBN(CLASS_OF(self), obj, result); \
303  return obj; \
304  }
306 
307 #define BIGNUM_2(func) \
308  /* \
309  * call-seq: \
310  * bn.##func(bn2) -> aBN \
311  * \
312  */ \
313  static VALUE \
314  ossl_bn_##func(VALUE self, VALUE other) \
315  { \
316  BIGNUM *bn1, *bn2 = GetBNPtr(other), *result; \
317  VALUE obj; \
318  GetBN(self, bn1); \
319  if (!(result = BN_new())) { \
320  ossl_raise(eBNError, NULL); \
321  } \
322  if (!BN_##func(result, bn1, bn2)) { \
323  BN_free(result); \
324  ossl_raise(eBNError, NULL); \
325  } \
326  WrapBN(CLASS_OF(self), obj, result); \
327  return obj; \
328  }
329 BIGNUM_2(add)
330 BIGNUM_2(sub)
331 
332 #define BIGNUM_2c(func) \
333  /* \
334  * call-seq: \
335  * bn.##func(bn2) -> aBN \
336  * \
337  */ \
338  static VALUE \
339  ossl_bn_##func(VALUE self, VALUE other) \
340  { \
341  BIGNUM *bn1, *bn2 = GetBNPtr(other), *result; \
342  VALUE obj; \
343  GetBN(self, bn1); \
344  if (!(result = BN_new())) { \
345  ossl_raise(eBNError, NULL); \
346  } \
347  if (!BN_##func(result, bn1, bn2, ossl_bn_ctx)) { \
348  BN_free(result); \
349  ossl_raise(eBNError, NULL); \
350  } \
351  WrapBN(CLASS_OF(self), obj, result); \
352  return obj; \
353  }
354 BIGNUM_2c(mul)
355 BIGNUM_2c(mod)
356 BIGNUM_2c(exp)
357 BIGNUM_2c(gcd)
358 BIGNUM_2c(mod_sqr)
359 BIGNUM_2c(mod_inverse)
360 
361 /*
362  * call-seq:
363  * bn1 / bn2 => [result, remainder]
364  */
365 static VALUE
366 ossl_bn_div(VALUE self, VALUE other)
367 {
368  BIGNUM *bn1, *bn2 = GetBNPtr(other), *r1, *r2;
369  VALUE obj1, obj2;
370 
371  GetBN(self, bn1);
372 
373  if (!(r1 = BN_new())) {
375  }
376  if (!(r2 = BN_new())) {
377  BN_free(r1);
379  }
380  if (!BN_div(r1, r2, bn1, bn2, ossl_bn_ctx)) {
381  BN_free(r1);
382  BN_free(r2);
384  }
385  WrapBN(CLASS_OF(self), obj1, r1);
386  WrapBN(CLASS_OF(self), obj2, r2);
387 
388  return rb_ary_new3(2, obj1, obj2);
389 }
390 
391 #define BIGNUM_3c(func) \
392  /* \
393  * call-seq: \
394  * bn.##func(bn1, bn2) -> aBN \
395  * \
396  */ \
397  static VALUE \
398  ossl_bn_##func(VALUE self, VALUE other1, VALUE other2) \
399  { \
400  BIGNUM *bn1, *bn2 = GetBNPtr(other1); \
401  BIGNUM *bn3 = GetBNPtr(other2), *result; \
402  VALUE obj; \
403  GetBN(self, bn1); \
404  if (!(result = BN_new())) { \
405  ossl_raise(eBNError, NULL); \
406  } \
407  if (!BN_##func(result, bn1, bn2, bn3, ossl_bn_ctx)) { \
408  BN_free(result); \
409  ossl_raise(eBNError, NULL); \
410  } \
411  WrapBN(CLASS_OF(self), obj, result); \
412  return obj; \
413  }
414 BIGNUM_3c(mod_add)
415 BIGNUM_3c(mod_sub)
416 BIGNUM_3c(mod_mul)
417 BIGNUM_3c(mod_exp)
418 
419 #define BIGNUM_BIT(func) \
420  /* \
421  * call-seq: \
422  * bn.##func(bit) -> self \
423  * \
424  */ \
425  static VALUE \
426  ossl_bn_##func(VALUE self, VALUE bit) \
427  { \
428  BIGNUM *bn; \
429  GetBN(self, bn); \
430  if (!BN_##func(bn, NUM2INT(bit))) { \
431  ossl_raise(eBNError, NULL); \
432  } \
433  return self; \
434  }
435 BIGNUM_BIT(set_bit)
436 BIGNUM_BIT(clear_bit)
437 BIGNUM_BIT(mask_bits)
438 
439 /*
440  * call-seq:
441  * bn.bit_set?(bit) => true | false
442  */
443 static VALUE
444 ossl_bn_is_bit_set(VALUE self, VALUE bit)
445 {
446  int b;
447  BIGNUM *bn;
448 
449  b = NUM2INT(bit);
450  GetBN(self, bn);
451  if (BN_is_bit_set(bn, b)) {
452  return Qtrue;
453  }
454  return Qfalse;
455 }
456 
457 #define BIGNUM_SHIFT(func) \
458  /* \
459  * call-seq: \
460  * bn.##func(bits) -> aBN \
461  * \
462  */ \
463  static VALUE \
464  ossl_bn_##func(VALUE self, VALUE bits) \
465  { \
466  BIGNUM *bn, *result; \
467  int b; \
468  VALUE obj; \
469  b = NUM2INT(bits); \
470  GetBN(self, bn); \
471  if (!(result = BN_new())) { \
472  ossl_raise(eBNError, NULL); \
473  } \
474  if (!BN_##func(result, bn, b)) { \
475  BN_free(result); \
476  ossl_raise(eBNError, NULL); \
477  } \
478  WrapBN(CLASS_OF(self), obj, result); \
479  return obj; \
480  }
482 BIGNUM_SHIFT(rshift)
483 
484 #define BIGNUM_SELF_SHIFT(func) \
485  /* \
486  * call-seq: \
487  * bn.##func!(bits) -> self \
488  * \
489  */ \
490  static VALUE \
491  ossl_bn_self_##func(VALUE self, VALUE bits) \
492  { \
493  BIGNUM *bn; \
494  int b; \
495  b = NUM2INT(bits); \
496  GetBN(self, bn); \
497  if (!BN_##func(bn, bn, b)) \
498  ossl_raise(eBNError, NULL); \
499  return self; \
500  }
502 BIGNUM_SELF_SHIFT(rshift)
503 
504 #define BIGNUM_RAND(func) \
505  /* \
506  * call-seq: \
507  * BN.##func(bits [, fill [, odd]]) -> aBN \
508  * \
509  */ \
510  static VALUE \
511  ossl_bn_s_##func(int argc, VALUE *argv, VALUE klass) \
512  { \
513  BIGNUM *result; \
514  int bottom = 0, top = 0, b; \
515  VALUE bits, fill, odd, obj; \
516  \
517  switch (rb_scan_args(argc, argv, "12", &bits, &fill, &odd)) { \
518  case 3: \
519  bottom = (odd == Qtrue) ? 1 : 0; \
520  /* FALLTHROUGH */ \
521  case 2: \
522  top = NUM2INT(fill); \
523  } \
524  b = NUM2INT(bits); \
525  if (!(result = BN_new())) { \
526  ossl_raise(eBNError, NULL); \
527  } \
528  if (!BN_##func(result, b, top, bottom)) { \
529  BN_free(result); \
530  ossl_raise(eBNError, NULL); \
531  } \
532  WrapBN(klass, obj, result); \
533  return obj; \
534  }
535 BIGNUM_RAND(rand)
536 BIGNUM_RAND(pseudo_rand)
537 
538 #define BIGNUM_RAND_RANGE(func) \
539  /* \
540  * call-seq: \
541  * BN.##func(range) -> aBN \
542  * \
543  */ \
544  static VALUE \
545  ossl_bn_s_##func##_range(VALUE klass, VALUE range) \
546  { \
547  BIGNUM *bn = GetBNPtr(range), *result; \
548  VALUE obj; \
549  if (!(result = BN_new())) { \
550  ossl_raise(eBNError, NULL); \
551  } \
552  if (!BN_##func##_range(result, bn)) { \
553  BN_free(result); \
554  ossl_raise(eBNError, NULL); \
555  } \
556  WrapBN(klass, obj, result); \
557  return obj; \
558  }
559 BIGNUM_RAND_RANGE(rand)
560 BIGNUM_RAND_RANGE(pseudo_rand)
561 
562 /*
563  * call-seq:
564  * BN.generate_prime(bits, [, safe [, add [, rem]]]) => bn
565  *
566  * === Parameters
567  * * +bits+ - integer
568  * * +safe+ - boolean
569  * * +add+ - BN
570  * * +rem+ - BN
571  */
572 static VALUE
574 {
575  BIGNUM *add = NULL, *rem = NULL, *result;
576  int safe = 1, num;
577  VALUE vnum, vsafe, vadd, vrem, obj;
578 
579  rb_scan_args(argc, argv, "13", &vnum, &vsafe, &vadd, &vrem);
580 
581  num = NUM2INT(vnum);
582 
583  if (vsafe == Qfalse) {
584  safe = 0;
585  }
586  if (!NIL_P(vadd)) {
587  add = GetBNPtr(vadd);
588  rem = NIL_P(vrem) ? NULL : GetBNPtr(vrem);
589  }
590  if (!(result = BN_new())) {
592  }
593  if (!BN_generate_prime(result, num, safe, add, rem, NULL, NULL)) {
594  BN_free(result);
596  }
597  WrapBN(klass, obj, result);
598 
599  return obj;
600 }
601 
602 #define BIGNUM_NUM(func) \
603  /* \
604  * call-seq: \
605  * bn.##func -> integer \
606  * \
607  */ \
608  static VALUE \
609  ossl_bn_##func(VALUE self) \
610  { \
611  BIGNUM *bn; \
612  GetBN(self, bn); \
613  return INT2FIX(BN_##func(bn)); \
614  }
615 BIGNUM_NUM(num_bytes)
616 BIGNUM_NUM(num_bits)
617 
618 static VALUE
620 {
621  BIGNUM *bn1, *bn2;
622 
623  rb_check_frozen(self);
624 
625  if (self == other) return self;
626 
627  GetBN(self, bn1);
628  bn2 = GetBNPtr(other);
629 
630  if (!BN_copy(bn1, bn2)) {
632  }
633  return self;
634 }
635 
636 #define BIGNUM_CMP(func) \
637  /* \
638  * call-seq: \
639  * bn.##func(bn2) -> integer \
640  * \
641  */ \
642  static VALUE \
643  ossl_bn_##func(VALUE self, VALUE other) \
644  { \
645  BIGNUM *bn1, *bn2 = GetBNPtr(other); \
646  GetBN(self, bn1); \
647  return INT2FIX(BN_##func(bn1, bn2)); \
648  }
650 BIGNUM_CMP(ucmp)
651 
652 static VALUE
653 ossl_bn_eql(VALUE self, VALUE other)
654 {
655  if (ossl_bn_cmp(self, other) == INT2FIX(0)) {
656  return Qtrue;
657  }
658  return Qfalse;
659 }
660 
661 /*
662  * call-seq:
663  * bn.prime? => true | false
664  * bn.prime?(checks) => true | false
665  *
666  * === Parameters
667  * * +checks+ - integer
668  */
669 static VALUE
671 {
672  BIGNUM *bn;
673  VALUE vchecks;
674  int checks = BN_prime_checks;
675 
676  if (rb_scan_args(argc, argv, "01", &vchecks) == 1) {
677  checks = NUM2INT(vchecks);
678  }
679  GetBN(self, bn);
680  switch (BN_is_prime(bn, checks, NULL, ossl_bn_ctx, NULL)) {
681  case 1:
682  return Qtrue;
683  case 0:
684  return Qfalse;
685  default:
687  }
688  /* not reachable */
689  return Qnil;
690 }
691 
692 /*
693  * call-seq:
694  * bn.prime_fasttest? => true | false
695  * bn.prime_fasttest?(checks) => true | false
696  * bn.prime_fasttest?(checks, trial_div) => true | false
697  *
698  * === Parameters
699  * * +checks+ - integer
700  * * +trial_div+ - boolean
701  */
702 static VALUE
704 {
705  BIGNUM *bn;
706  VALUE vchecks, vtrivdiv;
707  int checks = BN_prime_checks, do_trial_division = 1;
708 
709  rb_scan_args(argc, argv, "02", &vchecks, &vtrivdiv);
710 
711  if (!NIL_P(vchecks)) {
712  checks = NUM2INT(vchecks);
713  }
714  GetBN(self, bn);
715  /* handle true/false */
716  if (vtrivdiv == Qfalse) {
717  do_trial_division = 0;
718  }
719  switch (BN_is_prime_fasttest(bn, checks, NULL, ossl_bn_ctx, NULL, do_trial_division)) {
720  case 1:
721  return Qtrue;
722  case 0:
723  return Qfalse;
724  default:
726  }
727  /* not reachable */
728  return Qnil;
729 }
730 
731 /*
732  * INIT
733  * (NOTE: ordering of methods is the same as in 'man bn')
734  */
735 void
737 {
738 #if 0
739  mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL */
740 #endif
741 
742  if (!(ossl_bn_ctx = BN_CTX_new())) {
743  ossl_raise(rb_eRuntimeError, "Cannot init BN_CTX");
744  }
745 
747 
749 
751  rb_define_method(cBN, "initialize", ossl_bn_initialize, -1);
752 
754  rb_define_method(cBN, "copy", ossl_bn_copy, 1);
755 
756  /* swap (=coerce?) */
757 
758  rb_define_method(cBN, "num_bytes", ossl_bn_num_bytes, 0);
759  rb_define_method(cBN, "num_bits", ossl_bn_num_bits, 0);
760  /* num_bits_word */
761 
762  rb_define_method(cBN, "+", ossl_bn_add, 1);
763  rb_define_method(cBN, "-", ossl_bn_sub, 1);
764  rb_define_method(cBN, "*", ossl_bn_mul, 1);
765  rb_define_method(cBN, "sqr", ossl_bn_sqr, 0);
766  rb_define_method(cBN, "/", ossl_bn_div, 1);
767  rb_define_method(cBN, "%", ossl_bn_mod, 1);
768  /* nnmod */
769 
770  rb_define_method(cBN, "mod_add", ossl_bn_mod_add, 2);
771  rb_define_method(cBN, "mod_sub", ossl_bn_mod_sub, 2);
772  rb_define_method(cBN, "mod_mul", ossl_bn_mod_mul, 2);
773  rb_define_method(cBN, "mod_sqr", ossl_bn_mod_sqr, 1);
774  rb_define_method(cBN, "**", ossl_bn_exp, 1);
775  rb_define_method(cBN, "mod_exp", ossl_bn_mod_exp, 2);
776  rb_define_method(cBN, "gcd", ossl_bn_gcd, 1);
777 
778  /* add_word
779  * sub_word
780  * mul_word
781  * div_word
782  * mod_word */
783 
784  rb_define_method(cBN, "cmp", ossl_bn_cmp, 1);
785  rb_define_alias(cBN, "<=>", "cmp");
786  rb_define_method(cBN, "ucmp", ossl_bn_ucmp, 1);
787  rb_define_method(cBN, "eql?", ossl_bn_eql, 1);
788  rb_define_alias(cBN, "==", "eql?");
789  rb_define_alias(cBN, "===", "eql?");
790  rb_define_method(cBN, "zero?", ossl_bn_is_zero, 0);
791  rb_define_method(cBN, "one?", ossl_bn_is_one, 0);
792  /* is_word */
793  rb_define_method(cBN, "odd?", ossl_bn_is_odd, 0);
794 
795  /* zero
796  * one
797  * value_one - DON'T IMPL.
798  * set_word
799  * get_word */
800 
801  rb_define_singleton_method(cBN, "rand", ossl_bn_s_rand, -1);
802  rb_define_singleton_method(cBN, "pseudo_rand", ossl_bn_s_pseudo_rand, -1);
803  rb_define_singleton_method(cBN, "rand_range", ossl_bn_s_rand_range, 1);
804  rb_define_singleton_method(cBN, "pseudo_rand_range", ossl_bn_s_pseudo_rand_range, 1);
805 
807  rb_define_method(cBN, "prime?", ossl_bn_is_prime, -1);
808 
809  rb_define_method(cBN, "set_bit!", ossl_bn_set_bit, 1);
810  rb_define_method(cBN, "clear_bit!", ossl_bn_clear_bit, 1);
811  rb_define_method(cBN, "bit_set?", ossl_bn_is_bit_set, 1);
812  rb_define_method(cBN, "mask_bits!", ossl_bn_mask_bits, 1);
813  rb_define_method(cBN, "<<", ossl_bn_lshift, 1);
814  rb_define_method(cBN, ">>", ossl_bn_rshift, 1);
815  rb_define_method(cBN, "lshift!", ossl_bn_self_lshift, 1);
816  rb_define_method(cBN, "rshift!", ossl_bn_self_rshift, 1);
817  /* lshift1 - DON'T IMPL. */
818  /* rshift1 - DON'T IMPL. */
819 
820  /*
821  * bn2bin
822  * bin2bn
823  * bn2hex
824  * bn2dec
825  * hex2bn
826  * dec2bn - all these are implemented in ossl_bn_initialize, and ossl_bn_to_s
827  * print - NOT IMPL.
828  * print_fp - NOT IMPL.
829  * bn2mpi
830  * mpi2bn
831  */
832  rb_define_method(cBN, "to_s", ossl_bn_to_s, -1);
833  rb_define_method(cBN, "to_i", ossl_bn_to_i, 0);
834  rb_define_alias(cBN, "to_int", "to_i");
835  rb_define_method(cBN, "to_bn", ossl_bn_to_bn, 0);
836  rb_define_method(cBN, "coerce", ossl_bn_coerce, 1);
837 
838  /*
839  * TODO:
840  * But how to: from_bin, from_mpi? PACK?
841  * to_bin
842  * to_mpi
843  */
844 
845  rb_define_method(cBN, "mod_inverse", ossl_bn_mod_inverse, 1);
846 
847  /* RECiProcal
848  * MONTgomery */
849 
850  /*
851  * TODO:
852  * Where to belong these?
853  */
854  rb_define_method(cBN, "prime_fasttest?", ossl_bn_is_prime_fasttest, -1);
855 }
856 
VALUE mOSSL
Definition: ossl.c:259
#define BIGNUM_RAND_RANGE(func)
Definition: ossl_bn.c:538
size_t strlen(const char *)
unsigned long VALUE
Definition: ripper.y:104
static VALUE ossl_bn_alloc(VALUE klass)
Definition: ossl_bn.c:92
static int is_zero(VALUE x)
Definition: bigdecimal.c:2052
void rb_define_singleton_method(VALUE obj, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a singleton method for obj.
Definition: class.c:1497
#define rb_check_frozen(obj)
VALUE rb_eTypeError
Definition: error.c:511
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
static VALUE ossl_bn_is_prime(int argc, VALUE *argv, VALUE self)
Definition: ossl_bn.c:670
void Init_ossl_bn()
Definition: ossl_bn.c:736
#define BIGNUM_RAND(func)
Definition: ossl_bn.c:504
#define TYPE(x)
static VALUE ossl_bn_to_bn(VALUE self)
Definition: ossl_bn.c:239
#define RSTRING_PTR(str)
#define CLASS_OF(v)
#define GetBN(obj, bn)
Definition: ossl_bn.c:21
#define Qnil
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
Definition: class.c:545
VALUE rb_ary_new3(long n,...)
Definition: array.c:432
#define T_NIL
static int is_one(VALUE x)
Definition: bigdecimal.c:2075
static VALUE ossl_bn_is_prime_fasttest(int argc, VALUE *argv, VALUE self)
Definition: ossl_bn.c:703
#define BIGNUM_SHIFT(func)
Definition: ossl_bn.c:457
#define rb_define_copy_func(klass, func)
Definition: ruby_missing.h:14
#define BIGNUM_3c(func)
Definition: ossl_bn.c:391
#define BIGNUM_BOOL1(func)
Definition: ossl_bn.c:263
#define StringValuePtr(v)
VALUE rb_eRuntimeError
Definition: error.c:510
#define Qtrue
#define add(x, y)
Definition: date_strftime.c:23
#define INT2FIX(i)
#define Qfalse
#define T_STRING
VALUE eOSSLError
Definition: ossl.c:264
int argc
Definition: ruby.c:130
#define BIGNUM_NUM(func)
Definition: ossl_bn.c:602
#define NIL_P(v)
static VALUE ossl_bn_to_i(VALUE self)
Definition: ossl_bn.c:221
#define BIGNUM_2(func)
static VALUE ossl_bn_eql(VALUE self, VALUE other)
Definition: ossl_bn.c:653
#define rb_long2int(n)
#define sub(x, y)
Definition: date_strftime.c:24
void rb_define_alias(VALUE klass, const char *name1, const char *name2)
Defines an alias of a method.
Definition: class.c:1539
#define RTEST(v)
static VALUE ossl_bn_coerce(VALUE self, VALUE other)
Definition: ossl_bn.c:245
#define StringValue(v)
static VALUE ossl_bn_initialize(int argc, VALUE *argv, VALUE self)
Definition: ossl_bn.c:113
#define BIGNUM_CMP(func)
Definition: ossl_bn.c:636
VALUE rb_String(VALUE)
Definition: object.c:2745
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1570
unsigned char buf[MIME_BUF_SIZE]
Definition: nkf.c:4308
VALUE rb_assoc_new(VALUE car, VALUE cdr)
Definition: array.c:545
#define T_FIXNUM
static VALUE result
Definition: nkf.c:40
static VALUE ossl_bn_copy(VALUE self, VALUE other)
Definition: ossl_bn.c:619
VALUE cBN
Definition: ossl_bn.c:36
#define T_BIGNUM
#define lshift(x, y)
Definition: time.c:172
VALUE rb_obj_is_kind_of(VALUE, VALUE)
Definition: object.c:582
#define mul(x, y)
Definition: date_strftime.c:25
RUBY_EXTERN VALUE rb_cObject
Definition: ripper.y:1426
BN_CTX * ossl_bn_ctx
Definition: ossl_bn.c:89
VALUE ossl_buf2str(char *buf, int len)
Definition: ossl.c:134
#define BIGNUM_BIT(func)
void ossl_raise(VALUE exc, const char *fmt,...)
Definition: ossl.c:332
#define RSTRING_LENINT(str)
VALUE rb_str_new(const char *, long)
Definition: string.c:425
#define NUM2INT(x)
VALUE ossl_bn_new(const BIGNUM *bn)
Definition: ossl_bn.c:43
#define BIGNUM_SELF_SHIFT(func)
Definition: ossl_bn.c:484
BIGNUM * GetBNPtr(VALUE obj)
Definition: ossl_bn.c:58
VALUE rb_define_module(const char *name)
Definition: class.c:617
VALUE rb_cstr_to_inum(const char *str, int base, int badcheck)
Definition: bignum.c:579
#define BIGNUM_1c(func)
Definition: ossl_bn.c:283
#define mod(x, y)
Definition: date_strftime.c:28
#define NULL
Definition: _sdbm.c:103
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1344
static VALUE ossl_bn_s_generate_prime(int argc, VALUE *argv, VALUE klass)
Definition: ossl_bn.c:573
VALUE eBNError
Definition: ossl_bn.c:37
VALUE rb_eArgError
Definition: error.c:512
static ID cmp
Definition: compar.c:16
char ** argv
Definition: ruby.c:131
static VALUE ossl_bn_to_s(int argc, VALUE *argv, VALUE self)
Definition: ossl_bn.c:177
#define WrapBN(klass, obj, bn)
Definition: ossl_bn.c:14
#define BIGNUM_2c(func)