Ruby 2.0.0p353(2013-11-22revision43784)

- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

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 */
36 VALUE cBN;
37 VALUE eBNError;
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) {
50 ossl_raise(eBNError, NULL);
51 }
52 WrapBN(cBN, obj, newbn);
53
54 return obj;
55 }
56
57 BIGNUM *
58 GetBNPtr(VALUE obj)
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))) {
69 ossl_raise(eBNError, NULL);
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
92 ossl_bn_alloc(VALUE klass)
93 {
94 BIGNUM *bn;
95 VALUE obj;
96
97 if (!(bn = BN_new())) {
98 ossl_raise(eBNError, NULL);
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
113 ossl_bn_initialize(int argc, VALUE *argv, VALUE self)
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)) {
129 ossl_raise(eBNError, NULL);
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)) {
139 ossl_raise(eBNError, NULL);
140 }
141 break;
142 case 2:
143 if (!BN_bin2bn((unsigned char *)RSTRING_PTR(str), RSTRING_LENINT(str), bn)) {
144 ossl_raise(eBNError, NULL);
145 }
146 break;
147 case 10:
148 if (!BN_dec2bn(&bn, RSTRING_PTR(str))) {
149 ossl_raise(eBNError, NULL);
150 }
151 break;
152 case 16:
153 if (!BN_hex2bn(&bn, RSTRING_PTR(str))) {
154 ossl_raise(eBNError, NULL);
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
177 ossl_bn_to_s(int argc, VALUE *argv, VALUE self)
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)
193 ossl_raise(eBNError, NULL);
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)
199 ossl_raise(eBNError, NULL);
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
221 ossl_bn_to_i(VALUE self)
222 {
223 BIGNUM *bn;
224 char *txt;
225 VALUE num;
226
227 GetBN(self, bn);
228
229 if (!(txt = BN_bn2dec(bn))) {
230 ossl_raise(eBNError, NULL);
231 }
232 num = rb_cstr_to_inum(txt, 10, Qtrue);
233 OPENSSL_free(txt);
234
235 return num;
236 }
237
238 static VALUE
239 ossl_bn_to_bn(VALUE self)
240 {
241 return self;
242 }
243
244 static VALUE
245 ossl_bn_coerce(VALUE self, VALUE other)
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 }
279 BIGNUM_BOOL1(is_zero)
280 BIGNUM_BOOL1(is_one)
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 }
305 BIGNUM_1c(sqr)
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())) {
374 ossl_raise(eBNError, NULL);
375 }
376 if (!(r2 = BN_new())) {
377 BN_free(r1);
378 ossl_raise(eBNError, NULL);
379 }
380 if (!BN_div(r1, r2, bn1, bn2, ossl_bn_ctx)) {
381 BN_free(r1);
382 BN_free(r2);
383 ossl_raise(eBNError, NULL);
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 }
481 BIGNUM_SHIFT(lshift)
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 }
501 BIGNUM_SELF_SHIFT(lshift)
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
573 ossl_bn_s_generate_prime(int argc, VALUE *argv, VALUE klass)
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())) {
591 ossl_raise(eBNError, NULL);
592 }
593 if (!BN_generate_prime(result, num, safe, add, rem, NULL, NULL)) {
594 BN_free(result);
595 ossl_raise(eBNError, NULL);
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
619 ossl_bn_copy(VALUE self, VALUE other)
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)) {
631 ossl_raise(eBNError, NULL);
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 }
649 BIGNUM_CMP(cmp)
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
670 ossl_bn_is_prime(int argc, VALUE *argv, VALUE self)
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:
686 ossl_raise(eBNError, NULL);
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
703 ossl_bn_is_prime_fasttest(int argc, VALUE *argv, VALUE self)
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:
725 ossl_raise(eBNError, NULL);
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
736 Init_ossl_bn()
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
746 eBNError = rb_define_class_under(mOSSL, "BNError", eOSSLError);
747
748 cBN = rb_define_class_under(mOSSL, "BN", rb_cObject);
749
750 rb_define_alloc_func(cBN, ossl_bn_alloc);
751 rb_define_method(cBN, "initialize", ossl_bn_initialize, -1);
752
753 rb_define_copy_func(cBN, ossl_bn_copy);
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
806 rb_define_singleton_method(cBN, "generate_prime", ossl_bn_s_generate_prime, -1);
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
mOSSL
VALUE mOSSL
Definition: ossl.c:259
BIGNUM_RAND_RANGE
#define BIGNUM_RAND_RANGE(func)
Definition: ossl_bn.c:538
strlen
size_t strlen(const char *)
ossl_bn_alloc
static VALUE ossl_bn_alloc(VALUE klass)
Definition: ossl_bn.c:92
is_zero
static int is_zero(VALUE x)
Definition: bigdecimal.c:2038
rb_define_singleton_method
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
rb_check_frozen
#define rb_check_frozen(obj)
rb_eTypeError
VALUE rb_eTypeError
Definition: error.c:511
rb_define_alloc_func
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
ossl_bn_is_prime
static VALUE ossl_bn_is_prime(int argc, VALUE *argv, VALUE self)
Definition: ossl_bn.c:670
Init_ossl_bn
void Init_ossl_bn()
Definition: ossl_bn.c:736
BIGNUM_RAND
#define BIGNUM_RAND(func)
Definition: ossl_bn.c:504
TYPE
#define TYPE(x)
ossl_bn_to_bn
static VALUE ossl_bn_to_bn(VALUE self)
Definition: ossl_bn.c:239
RSTRING_PTR
#define RSTRING_PTR(str)
CLASS_OF
#define CLASS_OF(v)
NIL_P
NIL_P(eventloop_thread)
Definition: tcltklib.c:4068
GetBN
#define GetBN(obj, bn)
Definition: ossl_bn.c:21
safe
int safe
Definition: tcltklib.c:6404
rb_define_class_under
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
Definition: class.c:545
Qtrue
return Qtrue
Definition: tcltklib.c:9610
rb_ary_new3
VALUE rb_ary_new3(long n,...)
Definition: array.c:432
T_NIL
#define T_NIL
is_one
static int is_one(VALUE x)
Definition: bigdecimal.c:2061
ossl_bn_is_prime_fasttest
static VALUE ossl_bn_is_prime_fasttest(int argc, VALUE *argv, VALUE self)
Definition: ossl_bn.c:703
BIGNUM_SHIFT
#define BIGNUM_SHIFT(func)
Definition: ossl_bn.c:457
rb_define_copy_func
#define rb_define_copy_func(klass, func)
Definition: ruby_missing.h:14
BIGNUM_3c
#define BIGNUM_3c(func)
Definition: ossl_bn.c:391
BIGNUM_BOOL1
#define BIGNUM_BOOL1(func)
Definition: ossl_bn.c:263
Qfalse
return Qfalse
Definition: tcltklib.c:6779
Qnil
#define Qnil
Definition: tcltklib.c:1896
StringValuePtr
#define StringValuePtr(v)
rb_eRuntimeError
VALUE rb_eRuntimeError
Definition: error.c:510
str
static VALUE char * str
Definition: tcltklib.c:3547
add
#define add(x, y)
Definition: date_strftime.c:23
obj
static VALUE VALUE obj
Definition: tcltklib.c:3158
INT2FIX
#define INT2FIX(i)
T_STRING
#define T_STRING
eOSSLError
VALUE eOSSLError
Definition: ossl.c:264
BIGNUM_NUM
#define BIGNUM_NUM(func)
Definition: ossl_bn.c:602
buf
unsigned char buf[MIME_BUF_SIZE]
Definition: nkf.c:4308
ossl_bn_to_i
static VALUE ossl_bn_to_i(VALUE self)
Definition: ossl_bn.c:221
BIGNUM_2
#define BIGNUM_2(func)
Definition: ossl_bn.c:307
ossl_bn_eql
static VALUE ossl_bn_eql(VALUE self, VALUE other)
Definition: ossl_bn.c:653
rb_long2int
#define rb_long2int(n)
argv
VALUE * argv
Definition: tcltklib.c:1971
sub
#define sub(x, y)
Definition: date_strftime.c:24
rb_define_alias
void rb_define_alias(VALUE klass, const char *name1, const char *name2)
Defines an alias of a method.
Definition: class.c:1539
RTEST
#define RTEST(v)
result
q result
Definition: tcltklib.c:7070
ossl_bn_is_bit_set
static VALUE ossl_bn_is_bit_set(VALUE self, VALUE bit)
Definition: ossl_bn.c:444
ossl_bn_coerce
static VALUE ossl_bn_coerce(VALUE self, VALUE other)
Definition: ossl_bn.c:245
StringValue
#define StringValue(v)
ossl_bn_initialize
static VALUE ossl_bn_initialize(int argc, VALUE *argv, VALUE self)
Definition: ossl_bn.c:113
BIGNUM_CMP
#define BIGNUM_CMP(func)
Definition: ossl_bn.c:636
rb_String
VALUE rb_String(VALUE)
Definition: object.c:2738
rb_scan_args
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1570
rb_assoc_new
VALUE rb_assoc_new(VALUE car, VALUE cdr)
Definition: array.c:545
ossl_bn_div
static VALUE ossl_bn_div(VALUE self, VALUE other)
Definition: ossl_bn.c:366
T_FIXNUM
#define T_FIXNUM
argc
int argc
Definition: tcltklib.c:1970
ossl_bn_copy
static VALUE ossl_bn_copy(VALUE self, VALUE other)
Definition: ossl_bn.c:619
cBN
VALUE cBN
Definition: ossl_bn.c:36
b
Real * b
Definition: bigdecimal.c:1182
T_BIGNUM
#define T_BIGNUM
lshift
#define lshift(x, y)
Definition: time.c:172
rb_obj_is_kind_of
VALUE rb_obj_is_kind_of(VALUE, VALUE)
Definition: object.c:582
mul
#define mul(x, y)
Definition: date_strftime.c:25
rb_cObject
RUBY_EXTERN VALUE rb_cObject
Definition: ripper.y:1426
ossl_bn_ctx
BN_CTX * ossl_bn_ctx
Definition: ossl_bn.c:89
ossl_buf2str
VALUE ossl_buf2str(char *buf, int len)
Definition: ossl.c:134
klass
klass
Definition: tcltklib.c:3504
BIGNUM_BIT
#define BIGNUM_BIT(func)
Definition: ossl_bn.c:419
ossl_raise
void ossl_raise(VALUE exc, const char *fmt,...)
Definition: ossl.c:328
RSTRING_LENINT
#define RSTRING_LENINT(str)
rb_str_new
VALUE rb_str_new(const char *, long)
Definition: string.c:425
NUM2INT
#define NUM2INT(x)
ossl_bn_new
VALUE ossl_bn_new(const BIGNUM *bn)
Definition: ossl_bn.c:43
ossl.h
BIGNUM_SELF_SHIFT
#define BIGNUM_SELF_SHIFT(func)
Definition: ossl_bn.c:484
self
static struct tcltkip *VALUE self
Definition: tcltklib.c:769
VALUE
unsigned long VALUE
Definition: ripper.y:104
GetBNPtr
BIGNUM * GetBNPtr(VALUE obj)
Definition: ossl_bn.c:58
rb_define_module
VALUE rb_define_module(const char *name)
Definition: class.c:617
rb_cstr_to_inum
VALUE rb_cstr_to_inum(const char *str, int base, int badcheck)
Definition: bignum.c:579
BIGNUM_1c
#define BIGNUM_1c(func)
Definition: ossl_bn.c:283
mod
#define mod(x, y)
Definition: date_strftime.c:28
NULL
#define NULL
Definition: _sdbm.c:103
rb_define_method
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1344
ossl_bn_s_generate_prime
static VALUE ossl_bn_s_generate_prime(int argc, VALUE *argv, VALUE klass)
Definition: ossl_bn.c:573
eBNError
VALUE eBNError
Definition: ossl_bn.c:37
rb_eArgError
VALUE rb_eArgError
Definition: error.c:512
cmp
static ID cmp
Definition: compar.c:16
ossl_bn_to_s
static VALUE ossl_bn_to_s(int argc, VALUE *argv, VALUE self)
Definition: ossl_bn.c:177
WrapBN
#define WrapBN(klass, obj, bn)
Definition: ossl_bn.c:14
BIGNUM_2c
#define BIGNUM_2c(func)
Definition: ossl_bn.c:332
len
size_t len
Definition: tcltklib.c:3568