Ruby  2.1.10p492(2016-04-01revision54464)
ossl_bn.c
Go to the documentation of this file.
1 /*
2  * $Id: ossl_bn.c 41613 2013-06-25 03:08:23Z akr $
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(integer) => aBN
110  * BN.new(string) => aBN
111  * BN.new(string, 0 | 2 | 10 | 16) => aBN
112  */
113 static VALUE
115 {
116  BIGNUM *bn;
117  VALUE str, bs;
118  int base = 10;
119 
120  if (rb_scan_args(argc, argv, "11", &str, &bs) == 2) {
121  base = NUM2INT(bs);
122  }
123 
124  if (RB_TYPE_P(str, T_FIXNUM)) {
125  long i;
126  unsigned char bin[sizeof(long)];
127  long n = FIX2LONG(str);
128  unsigned long un = labs(n);
129 
130  for (i = sizeof(long) - 1; 0 <= i; i--) {
131  bin[i] = un&0xff;
132  un >>= 8;
133  }
134 
135  GetBN(self, bn);
136  if (!BN_bin2bn(bin, sizeof(bin), bn)) {
138  }
139  if (n < 0) BN_set_negative(bn, 1);
140  return self;
141  }
142  else if (RB_TYPE_P(str, T_BIGNUM)) {
143  int i, j, len = RBIGNUM_LENINT(str);
144  BDIGIT *ds = RBIGNUM_DIGITS(str);
145  VALUE buf;
146  unsigned char *bin = (unsigned char*)ALLOCV_N(BDIGIT, buf, len);
147 
148  for (i = 0; len > i; i++) {
149  BDIGIT v = ds[i];
150  for (j = SIZEOF_BDIGITS - 1; 0 <= j; j--) {
151  bin[(len-1-i)*SIZEOF_BDIGITS+j] = v&0xff;
152  v >>= 8;
153  }
154  }
155 
156  GetBN(self, bn);
157  if (!BN_bin2bn(bin, (int)SIZEOF_BDIGITS*len, bn)) {
158  ALLOCV_END(buf);
160  }
161  ALLOCV_END(buf);
162  if (!RBIGNUM_SIGN(str)) BN_set_negative(bn, 1);
163  return self;
164  }
165  if (RTEST(rb_obj_is_kind_of(str, cBN))) {
166  BIGNUM *other;
167 
168  GetBN(self, bn);
169  GetBN(str, other); /* Safe - we checked kind_of? above */
170  if (!BN_copy(bn, other)) {
172  }
173  return self;
174  }
175 
176  StringValue(str);
177  GetBN(self, bn);
178  switch (base) {
179  case 0:
180  if (!BN_mpi2bn((unsigned char *)RSTRING_PTR(str), RSTRING_LENINT(str), bn)) {
182  }
183  break;
184  case 2:
185  if (!BN_bin2bn((unsigned char *)RSTRING_PTR(str), RSTRING_LENINT(str), bn)) {
187  }
188  break;
189  case 10:
190  if (!BN_dec2bn(&bn, RSTRING_PTR(str))) {
192  }
193  break;
194  case 16:
195  if (!BN_hex2bn(&bn, RSTRING_PTR(str))) {
197  }
198  break;
199  default:
200  ossl_raise(rb_eArgError, "invalid radix %d", base);
201  }
202  return self;
203 }
204 
205 /*
206  * call-seq:
207  * bn.to_s => string
208  * bn.to_s(base) => string
209  *
210  * === Parameters
211  * * +base+ - integer
212  * * * Valid values:
213  * * * * 0 - MPI
214  * * * * 2 - binary
215  * * * * 10 - the default
216  * * * * 16 - hex
217  */
218 static VALUE
220 {
221  BIGNUM *bn;
222  VALUE str, bs;
223  int base = 10, len;
224  char *buf;
225 
226  if (rb_scan_args(argc, argv, "01", &bs) == 1) {
227  base = NUM2INT(bs);
228  }
229  GetBN(self, bn);
230  switch (base) {
231  case 0:
232  len = BN_bn2mpi(bn, NULL);
233  str = rb_str_new(0, len);
234  if (BN_bn2mpi(bn, (unsigned char *)RSTRING_PTR(str)) != len)
236  break;
237  case 2:
238  len = BN_num_bytes(bn);
239  str = rb_str_new(0, len);
240  if (BN_bn2bin(bn, (unsigned char *)RSTRING_PTR(str)) != len)
242  break;
243  case 10:
244  if (!(buf = BN_bn2dec(bn))) ossl_raise(eBNError, NULL);
246  break;
247  case 16:
248  if (!(buf = BN_bn2hex(bn))) ossl_raise(eBNError, NULL);
250  break;
251  default:
252  ossl_raise(rb_eArgError, "invalid radix %d", base);
253  }
254 
255  return str;
256 }
257 
258 /*
259  * call-seq:
260  * bn.to_i => integer
261  */
262 static VALUE
264 {
265  BIGNUM *bn;
266  char *txt;
267  VALUE num;
268 
269  GetBN(self, bn);
270 
271  if (!(txt = BN_bn2hex(bn))) {
273  }
274  num = rb_cstr_to_inum(txt, 16, Qtrue);
275  OPENSSL_free(txt);
276 
277  return num;
278 }
279 
280 static VALUE
282 {
283  return self;
284 }
285 
286 static VALUE
288 {
289  switch(TYPE(other)) {
290  case T_STRING:
291  self = ossl_bn_to_s(0, NULL, self);
292  break;
293  case T_FIXNUM:
294  case T_BIGNUM:
295  self = ossl_bn_to_i(self);
296  break;
297  default:
298  if (!RTEST(rb_obj_is_kind_of(other, cBN))) {
299  ossl_raise(rb_eTypeError, "Don't know how to coerce");
300  }
301  }
302  return rb_assoc_new(other, self);
303 }
304 
305 #define BIGNUM_BOOL1(func) \
306  /* \
307  * call-seq: \
308  * bn.##func -> true | false \
309  * \
310  */ \
311  static VALUE \
312  ossl_bn_##func(VALUE self) \
313  { \
314  BIGNUM *bn; \
315  GetBN(self, bn); \
316  if (BN_##func(bn)) { \
317  return Qtrue; \
318  } \
319  return Qfalse; \
320  }
323 BIGNUM_BOOL1(is_odd)
324 
325 #define BIGNUM_1c(func) \
326  /* \
327  * call-seq: \
328  * bn.##func -> aBN \
329  * \
330  */ \
331  static VALUE \
332  ossl_bn_##func(VALUE self) \
333  { \
334  BIGNUM *bn, *result; \
335  VALUE obj; \
336  GetBN(self, bn); \
337  if (!(result = BN_new())) { \
338  ossl_raise(eBNError, NULL); \
339  } \
340  if (!BN_##func(result, bn, ossl_bn_ctx)) { \
341  BN_free(result); \
342  ossl_raise(eBNError, NULL); \
343  } \
344  WrapBN(CLASS_OF(self), obj, result); \
345  return obj; \
346  }
348 
349 #define BIGNUM_2(func) \
350  /* \
351  * call-seq: \
352  * bn.##func(bn2) -> aBN \
353  * \
354  */ \
355  static VALUE \
356  ossl_bn_##func(VALUE self, VALUE other) \
357  { \
358  BIGNUM *bn1, *bn2 = GetBNPtr(other), *result; \
359  VALUE obj; \
360  GetBN(self, bn1); \
361  if (!(result = BN_new())) { \
362  ossl_raise(eBNError, NULL); \
363  } \
364  if (!BN_##func(result, bn1, bn2)) { \
365  BN_free(result); \
366  ossl_raise(eBNError, NULL); \
367  } \
368  WrapBN(CLASS_OF(self), obj, result); \
369  return obj; \
370  }
371 BIGNUM_2(add)
372 BIGNUM_2(sub)
373 
374 #define BIGNUM_2c(func) \
375  /* \
376  * call-seq: \
377  * bn.##func(bn2) -> aBN \
378  * \
379  */ \
380  static VALUE \
381  ossl_bn_##func(VALUE self, VALUE other) \
382  { \
383  BIGNUM *bn1, *bn2 = GetBNPtr(other), *result; \
384  VALUE obj; \
385  GetBN(self, bn1); \
386  if (!(result = BN_new())) { \
387  ossl_raise(eBNError, NULL); \
388  } \
389  if (!BN_##func(result, bn1, bn2, ossl_bn_ctx)) { \
390  BN_free(result); \
391  ossl_raise(eBNError, NULL); \
392  } \
393  WrapBN(CLASS_OF(self), obj, result); \
394  return obj; \
395  }
396 BIGNUM_2c(mul)
397 BIGNUM_2c(mod)
398 BIGNUM_2c(exp)
399 BIGNUM_2c(gcd)
400 BIGNUM_2c(mod_sqr)
401 BIGNUM_2c(mod_inverse)
402 
403 /*
404  * call-seq:
405  * bn1 / bn2 => [result, remainder]
406  */
407 static VALUE
408 ossl_bn_div(VALUE self, VALUE other)
409 {
410  BIGNUM *bn1, *bn2 = GetBNPtr(other), *r1, *r2;
411  VALUE obj1, obj2;
412 
413  GetBN(self, bn1);
414 
415  if (!(r1 = BN_new())) {
417  }
418  if (!(r2 = BN_new())) {
419  BN_free(r1);
421  }
422  if (!BN_div(r1, r2, bn1, bn2, ossl_bn_ctx)) {
423  BN_free(r1);
424  BN_free(r2);
426  }
427  WrapBN(CLASS_OF(self), obj1, r1);
428  WrapBN(CLASS_OF(self), obj2, r2);
429 
430  return rb_ary_new3(2, obj1, obj2);
431 }
432 
433 #define BIGNUM_3c(func) \
434  /* \
435  * call-seq: \
436  * bn.##func(bn1, bn2) -> aBN \
437  * \
438  */ \
439  static VALUE \
440  ossl_bn_##func(VALUE self, VALUE other1, VALUE other2) \
441  { \
442  BIGNUM *bn1, *bn2 = GetBNPtr(other1); \
443  BIGNUM *bn3 = GetBNPtr(other2), *result; \
444  VALUE obj; \
445  GetBN(self, bn1); \
446  if (!(result = BN_new())) { \
447  ossl_raise(eBNError, NULL); \
448  } \
449  if (!BN_##func(result, bn1, bn2, bn3, ossl_bn_ctx)) { \
450  BN_free(result); \
451  ossl_raise(eBNError, NULL); \
452  } \
453  WrapBN(CLASS_OF(self), obj, result); \
454  return obj; \
455  }
456 BIGNUM_3c(mod_add)
457 BIGNUM_3c(mod_sub)
458 BIGNUM_3c(mod_mul)
459 BIGNUM_3c(mod_exp)
460 
461 #define BIGNUM_BIT(func) \
462  /* \
463  * call-seq: \
464  * bn.##func(bit) -> self \
465  * \
466  */ \
467  static VALUE \
468  ossl_bn_##func(VALUE self, VALUE bit) \
469  { \
470  BIGNUM *bn; \
471  GetBN(self, bn); \
472  if (!BN_##func(bn, NUM2INT(bit))) { \
473  ossl_raise(eBNError, NULL); \
474  } \
475  return self; \
476  }
477 BIGNUM_BIT(set_bit)
478 BIGNUM_BIT(clear_bit)
479 BIGNUM_BIT(mask_bits)
480 
481 /*
482  * call-seq:
483  * bn.bit_set?(bit) => true | false
484  */
485 static VALUE
486 ossl_bn_is_bit_set(VALUE self, VALUE bit)
487 {
488  int b;
489  BIGNUM *bn;
490 
491  b = NUM2INT(bit);
492  GetBN(self, bn);
493  if (BN_is_bit_set(bn, b)) {
494  return Qtrue;
495  }
496  return Qfalse;
497 }
498 
499 #define BIGNUM_SHIFT(func) \
500  /* \
501  * call-seq: \
502  * bn.##func(bits) -> aBN \
503  * \
504  */ \
505  static VALUE \
506  ossl_bn_##func(VALUE self, VALUE bits) \
507  { \
508  BIGNUM *bn, *result; \
509  int b; \
510  VALUE obj; \
511  b = NUM2INT(bits); \
512  GetBN(self, bn); \
513  if (!(result = BN_new())) { \
514  ossl_raise(eBNError, NULL); \
515  } \
516  if (!BN_##func(result, bn, b)) { \
517  BN_free(result); \
518  ossl_raise(eBNError, NULL); \
519  } \
520  WrapBN(CLASS_OF(self), obj, result); \
521  return obj; \
522  }
524 BIGNUM_SHIFT(rshift)
525 
526 #define BIGNUM_SELF_SHIFT(func) \
527  /* \
528  * call-seq: \
529  * bn.##func!(bits) -> self \
530  * \
531  */ \
532  static VALUE \
533  ossl_bn_self_##func(VALUE self, VALUE bits) \
534  { \
535  BIGNUM *bn; \
536  int b; \
537  b = NUM2INT(bits); \
538  GetBN(self, bn); \
539  if (!BN_##func(bn, bn, b)) \
540  ossl_raise(eBNError, NULL); \
541  return self; \
542  }
544 BIGNUM_SELF_SHIFT(rshift)
545 
546 #define BIGNUM_RAND(func) \
547  /* \
548  * call-seq: \
549  * BN.##func(bits [, fill [, odd]]) -> aBN \
550  * \
551  */ \
552  static VALUE \
553  ossl_bn_s_##func(int argc, VALUE *argv, VALUE klass) \
554  { \
555  BIGNUM *result; \
556  int bottom = 0, top = 0, b; \
557  VALUE bits, fill, odd, obj; \
558  \
559  switch (rb_scan_args(argc, argv, "12", &bits, &fill, &odd)) { \
560  case 3: \
561  bottom = (odd == Qtrue) ? 1 : 0; \
562  /* FALLTHROUGH */ \
563  case 2: \
564  top = NUM2INT(fill); \
565  } \
566  b = NUM2INT(bits); \
567  if (!(result = BN_new())) { \
568  ossl_raise(eBNError, NULL); \
569  } \
570  if (!BN_##func(result, b, top, bottom)) { \
571  BN_free(result); \
572  ossl_raise(eBNError, NULL); \
573  } \
574  WrapBN(klass, obj, result); \
575  return obj; \
576  }
577 BIGNUM_RAND(rand)
578 BIGNUM_RAND(pseudo_rand)
579 
580 #define BIGNUM_RAND_RANGE(func) \
581  /* \
582  * call-seq: \
583  * BN.##func(range) -> aBN \
584  * \
585  */ \
586  static VALUE \
587  ossl_bn_s_##func##_range(VALUE klass, VALUE range) \
588  { \
589  BIGNUM *bn = GetBNPtr(range), *result; \
590  VALUE obj; \
591  if (!(result = BN_new())) { \
592  ossl_raise(eBNError, NULL); \
593  } \
594  if (!BN_##func##_range(result, bn)) { \
595  BN_free(result); \
596  ossl_raise(eBNError, NULL); \
597  } \
598  WrapBN(klass, obj, result); \
599  return obj; \
600  }
601 BIGNUM_RAND_RANGE(rand)
602 BIGNUM_RAND_RANGE(pseudo_rand)
603 
604 /*
605  * call-seq:
606  * BN.generate_prime(bits, [, safe [, add [, rem]]]) => bn
607  *
608  * === Parameters
609  * * +bits+ - integer
610  * * +safe+ - boolean
611  * * +add+ - BN
612  * * +rem+ - BN
613  */
614 static VALUE
616 {
617  BIGNUM *add = NULL, *rem = NULL, *result;
618  int safe = 1, num;
619  VALUE vnum, vsafe, vadd, vrem, obj;
620 
621  rb_scan_args(argc, argv, "13", &vnum, &vsafe, &vadd, &vrem);
622 
623  num = NUM2INT(vnum);
624 
625  if (vsafe == Qfalse) {
626  safe = 0;
627  }
628  if (!NIL_P(vadd)) {
629  add = GetBNPtr(vadd);
630  rem = NIL_P(vrem) ? NULL : GetBNPtr(vrem);
631  }
632  if (!(result = BN_new())) {
634  }
635  if (!BN_generate_prime(result, num, safe, add, rem, NULL, NULL)) {
636  BN_free(result);
638  }
639  WrapBN(klass, obj, result);
640 
641  return obj;
642 }
643 
644 #define BIGNUM_NUM(func) \
645  /* \
646  * call-seq: \
647  * bn.##func -> integer \
648  * \
649  */ \
650  static VALUE \
651  ossl_bn_##func(VALUE self) \
652  { \
653  BIGNUM *bn; \
654  GetBN(self, bn); \
655  return INT2FIX(BN_##func(bn)); \
656  }
657 BIGNUM_NUM(num_bytes)
658 BIGNUM_NUM(num_bits)
659 
660 static VALUE
662 {
663  BIGNUM *bn1, *bn2;
664 
665  rb_check_frozen(self);
666 
667  if (self == other) return self;
668 
669  GetBN(self, bn1);
670  bn2 = GetBNPtr(other);
671 
672  if (!BN_copy(bn1, bn2)) {
674  }
675  return self;
676 }
677 
678 #define BIGNUM_CMP(func) \
679  /* \
680  * call-seq: \
681  * bn.##func(bn2) -> integer \
682  * \
683  */ \
684  static VALUE \
685  ossl_bn_##func(VALUE self, VALUE other) \
686  { \
687  BIGNUM *bn1, *bn2 = GetBNPtr(other); \
688  GetBN(self, bn1); \
689  return INT2FIX(BN_##func(bn1, bn2)); \
690  }
692 BIGNUM_CMP(ucmp)
693 
694 static VALUE
695 ossl_bn_eql(VALUE self, VALUE other)
696 {
697  if (ossl_bn_cmp(self, other) == INT2FIX(0)) {
698  return Qtrue;
699  }
700  return Qfalse;
701 }
702 
703 /*
704  * call-seq:
705  * bn.prime? => true | false
706  * bn.prime?(checks) => true | false
707  *
708  * === Parameters
709  * * +checks+ - integer
710  */
711 static VALUE
713 {
714  BIGNUM *bn;
715  VALUE vchecks;
716  int checks = BN_prime_checks;
717 
718  if (rb_scan_args(argc, argv, "01", &vchecks) == 1) {
719  checks = NUM2INT(vchecks);
720  }
721  GetBN(self, bn);
722  switch (BN_is_prime(bn, checks, NULL, ossl_bn_ctx, NULL)) {
723  case 1:
724  return Qtrue;
725  case 0:
726  return Qfalse;
727  default:
729  }
730  /* not reachable */
731  return Qnil;
732 }
733 
734 /*
735  * call-seq:
736  * bn.prime_fasttest? => true | false
737  * bn.prime_fasttest?(checks) => true | false
738  * bn.prime_fasttest?(checks, trial_div) => true | false
739  *
740  * === Parameters
741  * * +checks+ - integer
742  * * +trial_div+ - boolean
743  */
744 static VALUE
746 {
747  BIGNUM *bn;
748  VALUE vchecks, vtrivdiv;
749  int checks = BN_prime_checks, do_trial_division = 1;
750 
751  rb_scan_args(argc, argv, "02", &vchecks, &vtrivdiv);
752 
753  if (!NIL_P(vchecks)) {
754  checks = NUM2INT(vchecks);
755  }
756  GetBN(self, bn);
757  /* handle true/false */
758  if (vtrivdiv == Qfalse) {
759  do_trial_division = 0;
760  }
761  switch (BN_is_prime_fasttest(bn, checks, NULL, ossl_bn_ctx, NULL, do_trial_division)) {
762  case 1:
763  return Qtrue;
764  case 0:
765  return Qfalse;
766  default:
768  }
769  /* not reachable */
770  return Qnil;
771 }
772 
773 /*
774  * INIT
775  * (NOTE: ordering of methods is the same as in 'man bn')
776  */
777 void
779 {
780 #if 0
781  mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL */
782 #endif
783 
784  if (!(ossl_bn_ctx = BN_CTX_new())) {
785  ossl_raise(rb_eRuntimeError, "Cannot init BN_CTX");
786  }
787 
789 
791 
793  rb_define_method(cBN, "initialize", ossl_bn_initialize, -1);
794 
796  rb_define_method(cBN, "copy", ossl_bn_copy, 1);
797 
798  /* swap (=coerce?) */
799 
800  rb_define_method(cBN, "num_bytes", ossl_bn_num_bytes, 0);
801  rb_define_method(cBN, "num_bits", ossl_bn_num_bits, 0);
802  /* num_bits_word */
803 
804  rb_define_method(cBN, "+", ossl_bn_add, 1);
805  rb_define_method(cBN, "-", ossl_bn_sub, 1);
806  rb_define_method(cBN, "*", ossl_bn_mul, 1);
807  rb_define_method(cBN, "sqr", ossl_bn_sqr, 0);
808  rb_define_method(cBN, "/", ossl_bn_div, 1);
809  rb_define_method(cBN, "%", ossl_bn_mod, 1);
810  /* nnmod */
811 
812  rb_define_method(cBN, "mod_add", ossl_bn_mod_add, 2);
813  rb_define_method(cBN, "mod_sub", ossl_bn_mod_sub, 2);
814  rb_define_method(cBN, "mod_mul", ossl_bn_mod_mul, 2);
815  rb_define_method(cBN, "mod_sqr", ossl_bn_mod_sqr, 1);
816  rb_define_method(cBN, "**", ossl_bn_exp, 1);
817  rb_define_method(cBN, "mod_exp", ossl_bn_mod_exp, 2);
818  rb_define_method(cBN, "gcd", ossl_bn_gcd, 1);
819 
820  /* add_word
821  * sub_word
822  * mul_word
823  * div_word
824  * mod_word */
825 
826  rb_define_method(cBN, "cmp", ossl_bn_cmp, 1);
827  rb_define_alias(cBN, "<=>", "cmp");
828  rb_define_method(cBN, "ucmp", ossl_bn_ucmp, 1);
829  rb_define_method(cBN, "eql?", ossl_bn_eql, 1);
830  rb_define_alias(cBN, "==", "eql?");
831  rb_define_alias(cBN, "===", "eql?");
832  rb_define_method(cBN, "zero?", ossl_bn_is_zero, 0);
833  rb_define_method(cBN, "one?", ossl_bn_is_one, 0);
834  /* is_word */
835  rb_define_method(cBN, "odd?", ossl_bn_is_odd, 0);
836 
837  /* zero
838  * one
839  * value_one - DON'T IMPL.
840  * set_word
841  * get_word */
842 
843  rb_define_singleton_method(cBN, "rand", ossl_bn_s_rand, -1);
844  rb_define_singleton_method(cBN, "pseudo_rand", ossl_bn_s_pseudo_rand, -1);
845  rb_define_singleton_method(cBN, "rand_range", ossl_bn_s_rand_range, 1);
846  rb_define_singleton_method(cBN, "pseudo_rand_range", ossl_bn_s_pseudo_rand_range, 1);
847 
849  rb_define_method(cBN, "prime?", ossl_bn_is_prime, -1);
850 
851  rb_define_method(cBN, "set_bit!", ossl_bn_set_bit, 1);
852  rb_define_method(cBN, "clear_bit!", ossl_bn_clear_bit, 1);
853  rb_define_method(cBN, "bit_set?", ossl_bn_is_bit_set, 1);
854  rb_define_method(cBN, "mask_bits!", ossl_bn_mask_bits, 1);
855  rb_define_method(cBN, "<<", ossl_bn_lshift, 1);
856  rb_define_method(cBN, ">>", ossl_bn_rshift, 1);
857  rb_define_method(cBN, "lshift!", ossl_bn_self_lshift, 1);
858  rb_define_method(cBN, "rshift!", ossl_bn_self_rshift, 1);
859  /* lshift1 - DON'T IMPL. */
860  /* rshift1 - DON'T IMPL. */
861 
862  /*
863  * bn2bin
864  * bin2bn
865  * bn2hex
866  * bn2dec
867  * hex2bn
868  * dec2bn - all these are implemented in ossl_bn_initialize, and ossl_bn_to_s
869  * print - NOT IMPL.
870  * print_fp - NOT IMPL.
871  * bn2mpi
872  * mpi2bn
873  */
874  rb_define_method(cBN, "to_s", ossl_bn_to_s, -1);
875  rb_define_method(cBN, "to_i", ossl_bn_to_i, 0);
876  rb_define_alias(cBN, "to_int", "to_i");
877  rb_define_method(cBN, "to_bn", ossl_bn_to_bn, 0);
878  rb_define_method(cBN, "coerce", ossl_bn_coerce, 1);
879 
880  /*
881  * TODO:
882  * But how to: from_bin, from_mpi? PACK?
883  * to_bin
884  * to_mpi
885  */
886 
887  rb_define_method(cBN, "mod_inverse", ossl_bn_mod_inverse, 1);
888 
889  /* RECiProcal
890  * MONTgomery */
891 
892  /*
893  * TODO:
894  * Where to belong these?
895  */
896  rb_define_method(cBN, "prime_fasttest?", ossl_bn_is_prime_fasttest, -1);
897 }
898 
VALUE mOSSL
Definition: ossl.c:259
#define BIGNUM_RAND_RANGE(func)
Definition: ossl_bn.c:580
size_t strlen(const char *)
#define T_FIXNUM
Definition: ruby.h:489
VALUE rb_String(VALUE)
Definition: object.c:3009
static VALUE ossl_bn_alloc(VALUE klass)
Definition: ossl_bn.c:92
static int is_zero(VALUE x)
Definition: bigdecimal.c:2087
#define NUM2INT(x)
Definition: ruby.h:630
void rb_define_singleton_method(VALUE obj, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a singleton method for obj.
Definition: class.c:1646
#define CLASS_OF(v)
Definition: ruby.h:440
#define Qtrue
Definition: ruby.h:426
VALUE rb_eTypeError
Definition: error.c:548
static VALUE ossl_bn_is_prime(int argc, VALUE *argv, VALUE self)
Definition: ossl_bn.c:712
#define rb_long2int(n)
Definition: ruby.h:317
void Init_ossl_bn()
Definition: ossl_bn.c:778
#define BIGNUM_RAND(func)
Definition: ossl_bn.c:546
static long labs(long const x)
Definition: bigdecimal.h:55
static VALUE ossl_bn_to_bn(VALUE self)
Definition: ossl_bn.c:281
#define GetBN(obj, bn)
Definition: ossl_bn.c:21
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
Definition: class.c:657
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
VALUE rb_obj_is_kind_of(VALUE, VALUE)
Definition: object.c:646
static int is_one(VALUE x)
Definition: bigdecimal.c:2110
static VALUE ossl_bn_is_prime_fasttest(int argc, VALUE *argv, VALUE self)
Definition: ossl_bn.c:745
#define RB_TYPE_P(obj, type)
Definition: ruby.h:1672
#define BIGNUM_SHIFT(func)
Definition: ossl_bn.c:499
#define rb_define_copy_func(klass, func)
Definition: ruby_missing.h:14
#define BIGNUM_3c(func)
Definition: ossl_bn.c:433
#define BIGNUM_BOOL1(func)
Definition: ossl_bn.c:305
RUBY_EXTERN VALUE rb_cObject
Definition: ruby.h:1561
VALUE rb_eRuntimeError
Definition: error.c:547
#define T_NIL
Definition: ruby.h:476
#define NIL_P(v)
Definition: ruby.h:438
#define add(x, y)
Definition: date_strftime.c:23
VALUE eOSSLError
Definition: ossl.c:264
#define TYPE(x)
Definition: ruby.h:505
int argc
Definition: ruby.c:131
#define BIGNUM_NUM(func)
Definition: ossl_bn.c:644
#define Qfalse
Definition: ruby.h:425
#define ALLOCV_N(type, v, n)
Definition: ruby.h:1356
#define T_BIGNUM
Definition: ruby.h:487
static VALUE ossl_bn_to_i(VALUE self)
Definition: ossl_bn.c:263
#define ALLOCV_END(v)
Definition: ruby.h:1357
#define BIGNUM_2(func)
#define RBIGNUM_DIGITS(b)
Definition: ruby.h:1109
static VALUE ossl_bn_eql(VALUE self, VALUE other)
Definition: ossl_bn.c:695
#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:1688
static VALUE ossl_bn_coerce(VALUE self, VALUE other)
Definition: ossl_bn.c:287
static VALUE ossl_bn_initialize(int argc, VALUE *argv, VALUE self)
Definition: ossl_bn.c:114
#define BIGNUM_CMP(func)
Definition: ossl_bn.c:678
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1719
unsigned char buf[MIME_BUF_SIZE]
Definition: nkf.c:4308
VALUE rb_assoc_new(VALUE car, VALUE cdr)
Definition: array.c:620
#define Qnil
Definition: ruby.h:427
unsigned long VALUE
Definition: ruby.h:88
static VALUE result
Definition: nkf.c:40
static VALUE ossl_bn_copy(VALUE self, VALUE other)
Definition: ossl_bn.c:661
#define rb_ary_new3
Definition: intern.h:91
VALUE cBN
Definition: ossl_bn.c:36
char bin[32]
Definition: siphash.c:134
#define lshift(x, y)
Definition: time.c:172
#define RSTRING_PTR(str)
Definition: ruby.h:845
#define INT2FIX(i)
Definition: ruby.h:231
#define mul(x, y)
Definition: date_strftime.c:25
BN_CTX * ossl_bn_ctx
Definition: ossl_bn.c:89
#define RTEST(v)
Definition: ruby.h:437
#define T_STRING
Definition: ruby.h:482
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:333
VALUE ossl_bn_new(const BIGNUM *bn)
Definition: ossl_bn.c:43
#define BIGNUM_SELF_SHIFT(func)
Definition: ossl_bn.c:526
#define SIZEOF_BDIGITS
Definition: bigdecimal.h:43
#define StringValuePtr(v)
Definition: ruby.h:540
#define RSTRING_LENINT(str)
Definition: ruby.h:853
#define rb_check_frozen(obj)
Definition: intern.h:277
#define RBIGNUM_SIGN(b)
Definition: ruby.h:1093
BIGNUM * GetBNPtr(VALUE obj)
Definition: ossl_bn.c:58
VALUE rb_define_module(const char *name)
Definition: class.c:727
VALUE rb_cstr_to_inum(const char *str, int base, int badcheck)
Definition: bignum.c:3963
#define BIGNUM_1c(func)
Definition: ossl_bn.c:325
#define mod(x, y)
Definition: date_strftime.c:28
#define NULL
Definition: _sdbm.c:102
#define FIX2LONG(x)
Definition: ruby.h:345
#define RBIGNUM_LENINT(b)
Definition: ruby.h:1113
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1479
static VALUE ossl_bn_s_generate_prime(int argc, VALUE *argv, VALUE klass)
Definition: ossl_bn.c:615
VALUE eBNError
Definition: ossl_bn.c:37
VALUE rb_eArgError
Definition: error.c:549
static ID cmp
Definition: compar.c:16
#define BDIGIT
Definition: bigdecimal.h:40
char ** argv
Definition: ruby.c:132
#define StringValue(v)
Definition: ruby.h:539
static VALUE ossl_bn_to_s(int argc, VALUE *argv, VALUE self)
Definition: ossl_bn.c:219
#define WrapBN(klass, obj, bn)
Definition: ossl_bn.c:14
VALUE rb_str_new(const char *, long)
Definition: string.c:534
#define BIGNUM_2c(func)