Ruby 2.1.5p273(2014-11-13revision48405)

- 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 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 */
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(integer) => aBN
110 * BN.new(string) => aBN
111 * BN.new(string, 0 | 2 | 10 | 16) => aBN
112 */
113 static VALUE
114 ossl_bn_initialize(int argc, VALUE *argv, VALUE self)
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)) {
137 ossl_raise(eBNError, NULL);
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);
159 ossl_raise(eBNError, NULL);
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)) {
171 ossl_raise(eBNError, NULL);
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)) {
181 ossl_raise(eBNError, NULL);
182 }
183 break;
184 case 2:
185 if (!BN_bin2bn((unsigned char *)RSTRING_PTR(str), RSTRING_LENINT(str), bn)) {
186 ossl_raise(eBNError, NULL);
187 }
188 break;
189 case 10:
190 if (!BN_dec2bn(&bn, RSTRING_PTR(str))) {
191 ossl_raise(eBNError, NULL);
192 }
193 break;
194 case 16:
195 if (!BN_hex2bn(&bn, RSTRING_PTR(str))) {
196 ossl_raise(eBNError, NULL);
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
219 ossl_bn_to_s(int argc, VALUE *argv, VALUE self)
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)
235 ossl_raise(eBNError, NULL);
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)
241 ossl_raise(eBNError, NULL);
242 break;
243 case 10:
244 if (!(buf = BN_bn2dec(bn))) ossl_raise(eBNError, NULL);
245 str = ossl_buf2str(buf, rb_long2int(strlen(buf)));
246 break;
247 case 16:
248 if (!(buf = BN_bn2hex(bn))) ossl_raise(eBNError, NULL);
249 str = ossl_buf2str(buf, rb_long2int(strlen(buf)));
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
263 ossl_bn_to_i(VALUE self)
264 {
265 BIGNUM *bn;
266 char *txt;
267 VALUE num;
268
269 GetBN(self, bn);
270
271 if (!(txt = BN_bn2hex(bn))) {
272 ossl_raise(eBNError, NULL);
273 }
274 num = rb_cstr_to_inum(txt, 16, Qtrue);
275 OPENSSL_free(txt);
276
277 return num;
278 }
279
280 static VALUE
281 ossl_bn_to_bn(VALUE self)
282 {
283 return self;
284 }
285
286 static VALUE
287 ossl_bn_coerce(VALUE self, VALUE other)
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 }
321 BIGNUM_BOOL1(is_zero)
322 BIGNUM_BOOL1(is_one)
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 }
347 BIGNUM_1c(sqr)
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())) {
416 ossl_raise(eBNError, NULL);
417 }
418 if (!(r2 = BN_new())) {
419 BN_free(r1);
420 ossl_raise(eBNError, NULL);
421 }
422 if (!BN_div(r1, r2, bn1, bn2, ossl_bn_ctx)) {
423 BN_free(r1);
424 BN_free(r2);
425 ossl_raise(eBNError, NULL);
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 }
523 BIGNUM_SHIFT(lshift)
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 }
543 BIGNUM_SELF_SHIFT(lshift)
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
615 ossl_bn_s_generate_prime(int argc, VALUE *argv, VALUE klass)
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())) {
633 ossl_raise(eBNError, NULL);
634 }
635 if (!BN_generate_prime(result, num, safe, add, rem, NULL, NULL)) {
636 BN_free(result);
637 ossl_raise(eBNError, NULL);
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
661 ossl_bn_copy(VALUE self, VALUE other)
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)) {
673 ossl_raise(eBNError, NULL);
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 }
691 BIGNUM_CMP(cmp)
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
712 ossl_bn_is_prime(int argc, VALUE *argv, VALUE self)
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:
728 ossl_raise(eBNError, NULL);
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
745 ossl_bn_is_prime_fasttest(int argc, VALUE *argv, VALUE self)
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:
767 ossl_raise(eBNError, NULL);
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
778 Init_ossl_bn()
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
788 eBNError = rb_define_class_under(mOSSL, "BNError", eOSSLError);
789
790 cBN = rb_define_class_under(mOSSL, "BN", rb_cObject);
791
792 rb_define_alloc_func(cBN, ossl_bn_alloc);
793 rb_define_method(cBN, "initialize", ossl_bn_initialize, -1);
794
795 rb_define_copy_func(cBN, ossl_bn_copy);
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
848 rb_define_singleton_method(cBN, "generate_prime", ossl_bn_s_generate_prime, -1);
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
mOSSL
VALUE mOSSL
Definition: ossl.c:259
BIGNUM_RAND_RANGE
#define BIGNUM_RAND_RANGE(func)
Definition: ossl_bn.c:580
strlen
size_t strlen(const char *)
T_FIXNUM
#define T_FIXNUM
Definition: ruby.h:489
rb_String
VALUE rb_String(VALUE)
Definition: object.c:2986
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:2094
NUM2INT
#define NUM2INT(x)
Definition: ruby.h:630
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:1655
CLASS_OF
#define CLASS_OF(v)
Definition: ruby.h:440
Qtrue
#define Qtrue
Definition: ruby.h:426
rb_eTypeError
VALUE rb_eTypeError
Definition: error.c:548
ossl_bn_is_prime
static VALUE ossl_bn_is_prime(int argc, VALUE *argv, VALUE self)
Definition: ossl_bn.c:712
rb_long2int
#define rb_long2int(n)
Definition: ruby.h:317
Init_ossl_bn
void Init_ossl_bn()
Definition: ossl_bn.c:778
BIGNUM_RAND
#define BIGNUM_RAND(func)
Definition: ossl_bn.c:546
labs
static long labs(long const x)
Definition: bigdecimal.h:62
ossl_bn_to_bn
static VALUE ossl_bn_to_bn(VALUE self)
Definition: ossl_bn.c:281
GetBN
#define GetBN(obj, bn)
Definition: ossl_bn.c:21
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:676
rb_define_alloc_func
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
rb_obj_is_kind_of
VALUE rb_obj_is_kind_of(VALUE, VALUE)
Definition: object.c:652
is_one
static int is_one(VALUE x)
Definition: bigdecimal.c:2117
ossl_bn_is_prime_fasttest
static VALUE ossl_bn_is_prime_fasttest(int argc, VALUE *argv, VALUE self)
Definition: ossl_bn.c:745
RB_TYPE_P
#define RB_TYPE_P(obj, type)
Definition: ruby.h:1664
BIGNUM_SHIFT
#define BIGNUM_SHIFT(func)
Definition: ossl_bn.c:499
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:433
BIGNUM_BOOL1
#define BIGNUM_BOOL1(func)
Definition: ossl_bn.c:305
rb_cObject
RUBY_EXTERN VALUE rb_cObject
Definition: ruby.h:1553
rb_eRuntimeError
VALUE rb_eRuntimeError
Definition: error.c:547
T_NIL
#define T_NIL
Definition: ruby.h:476
NIL_P
#define NIL_P(v)
Definition: ruby.h:438
add
#define add(x, y)
Definition: date_strftime.c:23
eOSSLError
VALUE eOSSLError
Definition: ossl.c:264
TYPE
#define TYPE(x)
Definition: ruby.h:505
argc
int argc
Definition: ruby.c:131
BIGNUM_NUM
#define BIGNUM_NUM(func)
Definition: ossl_bn.c:644
Qfalse
#define Qfalse
Definition: ruby.h:425
ALLOCV_N
#define ALLOCV_N(type, v, n)
Definition: ruby.h:1348
T_BIGNUM
#define T_BIGNUM
Definition: ruby.h:487
ossl_bn_to_i
static VALUE ossl_bn_to_i(VALUE self)
Definition: ossl_bn.c:263
ALLOCV_END
#define ALLOCV_END(v)
Definition: ruby.h:1349
BIGNUM_2
#define BIGNUM_2(func)
RBIGNUM_DIGITS
#define RBIGNUM_DIGITS(b)
Definition: ruby.h:1109
ossl_bn_eql
static VALUE ossl_bn_eql(VALUE self, VALUE other)
Definition: ossl_bn.c:695
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:1697
ossl_bn_coerce
static VALUE ossl_bn_coerce(VALUE self, VALUE other)
Definition: ossl_bn.c:287
ossl_bn_initialize
static VALUE ossl_bn_initialize(int argc, VALUE *argv, VALUE self)
Definition: ossl_bn.c:114
BIGNUM_CMP
#define BIGNUM_CMP(func)
Definition: ossl_bn.c:678
rb_scan_args
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1728
buf
unsigned char buf[MIME_BUF_SIZE]
Definition: nkf.c:4308
rb_assoc_new
VALUE rb_assoc_new(VALUE car, VALUE cdr)
Definition: array.c:616
Qnil
#define Qnil
Definition: ruby.h:427
VALUE
unsigned long VALUE
Definition: ruby.h:88
result
static VALUE result
Definition: nkf.c:40
ossl_bn_copy
static VALUE ossl_bn_copy(VALUE self, VALUE other)
Definition: ossl_bn.c:661
rb_ary_new3
#define rb_ary_new3
Definition: intern.h:91
cBN
VALUE cBN
Definition: ossl_bn.c:36
bin
char bin[32]
Definition: siphash.c:134
lshift
#define lshift(x, y)
Definition: time.c:172
RSTRING_PTR
#define RSTRING_PTR(str)
Definition: ruby.h:845
INT2FIX
#define INT2FIX(i)
Definition: ruby.h:231
mul
#define mul(x, y)
Definition: date_strftime.c:25
ossl_bn_ctx
BN_CTX * ossl_bn_ctx
Definition: ossl_bn.c:89
RTEST
#define RTEST(v)
Definition: ruby.h:437
T_STRING
#define T_STRING
Definition: ruby.h:482
ossl_buf2str
VALUE ossl_buf2str(char *buf, int len)
Definition: ossl.c:134
BIGNUM_BIT
#define BIGNUM_BIT(func)
ossl_raise
void ossl_raise(VALUE exc, const char *fmt,...)
Definition: ossl.c:333
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:526
SIZEOF_BDIGITS
#define SIZEOF_BDIGITS
Definition: bigdecimal.h:50
StringValuePtr
#define StringValuePtr(v)
Definition: ruby.h:540
RSTRING_LENINT
#define RSTRING_LENINT(str)
Definition: ruby.h:853
rb_check_frozen
#define rb_check_frozen(obj)
Definition: intern.h:277
RBIGNUM_SIGN
#define RBIGNUM_SIGN(b)
Definition: ruby.h:1093
GetBNPtr
BIGNUM * GetBNPtr(VALUE obj)
Definition: ossl_bn.c:58
rb_define_module
VALUE rb_define_module(const char *name)
Definition: class.c:746
rb_cstr_to_inum
VALUE rb_cstr_to_inum(const char *str, int base, int badcheck)
Definition: bignum.c:3963
BIGNUM_1c
#define BIGNUM_1c(func)
Definition: ossl_bn.c:325
mod
#define mod(x, y)
Definition: date_strftime.c:28
NULL
#define NULL
Definition: _sdbm.c:103
FIX2LONG
#define FIX2LONG(x)
Definition: ruby.h:345
RBIGNUM_LENINT
#define RBIGNUM_LENINT(b)
Definition: ruby.h:1113
rb_define_method
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1488
ossl_bn_s_generate_prime
static VALUE ossl_bn_s_generate_prime(int argc, VALUE *argv, VALUE klass)
Definition: ossl_bn.c:615
eBNError
VALUE eBNError
Definition: ossl_bn.c:37
rb_eArgError
VALUE rb_eArgError
Definition: error.c:549
cmp
static ID cmp
Definition: compar.c:16
BDIGIT
#define BDIGIT
Definition: bigdecimal.h:47
argv
char ** argv
Definition: ruby.c:132
StringValue
#define StringValue(v)
Definition: ruby.h:539
ossl_bn_to_s
static VALUE ossl_bn_to_s(int argc, VALUE *argv, VALUE self)
Definition: ossl_bn.c:219
WrapBN
#define WrapBN(klass, obj, bn)
Definition: ossl_bn.c:14
rb_str_new
VALUE rb_str_new(const char *, long)
Definition: string.c:534
BIGNUM_2c
#define BIGNUM_2c(func)