openssl-custom 2.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. checksums.yaml +7 -0
  2. data/BSDL +22 -0
  3. data/CONTRIBUTING.md +132 -0
  4. data/History.md +485 -0
  5. data/LICENSE.txt +56 -0
  6. data/README.md +66 -0
  7. data/ext/openssl/extconf.rb +190 -0
  8. data/ext/openssl/openssl_missing.c +106 -0
  9. data/ext/openssl/openssl_missing.h +257 -0
  10. data/ext/openssl/ossl.c +1282 -0
  11. data/ext/openssl/ossl.h +181 -0
  12. data/ext/openssl/ossl_asn1.c +1878 -0
  13. data/ext/openssl/ossl_asn1.h +62 -0
  14. data/ext/openssl/ossl_bio.c +42 -0
  15. data/ext/openssl/ossl_bio.h +16 -0
  16. data/ext/openssl/ossl_bn.c +1270 -0
  17. data/ext/openssl/ossl_bn.h +26 -0
  18. data/ext/openssl/ossl_cipher.c +1075 -0
  19. data/ext/openssl/ossl_cipher.h +20 -0
  20. data/ext/openssl/ossl_config.c +89 -0
  21. data/ext/openssl/ossl_config.h +19 -0
  22. data/ext/openssl/ossl_digest.c +425 -0
  23. data/ext/openssl/ossl_digest.h +20 -0
  24. data/ext/openssl/ossl_engine.c +567 -0
  25. data/ext/openssl/ossl_engine.h +19 -0
  26. data/ext/openssl/ossl_hmac.c +389 -0
  27. data/ext/openssl/ossl_hmac.h +18 -0
  28. data/ext/openssl/ossl_kdf.c +303 -0
  29. data/ext/openssl/ossl_kdf.h +6 -0
  30. data/ext/openssl/ossl_ns_spki.c +405 -0
  31. data/ext/openssl/ossl_ns_spki.h +19 -0
  32. data/ext/openssl/ossl_ocsp.c +2013 -0
  33. data/ext/openssl/ossl_ocsp.h +23 -0
  34. data/ext/openssl/ossl_pkcs12.c +257 -0
  35. data/ext/openssl/ossl_pkcs12.h +13 -0
  36. data/ext/openssl/ossl_pkcs7.c +1098 -0
  37. data/ext/openssl/ossl_pkcs7.h +36 -0
  38. data/ext/openssl/ossl_pkey.c +673 -0
  39. data/ext/openssl/ossl_pkey.h +241 -0
  40. data/ext/openssl/ossl_pkey_dh.c +650 -0
  41. data/ext/openssl/ossl_pkey_dsa.c +664 -0
  42. data/ext/openssl/ossl_pkey_ec.c +1827 -0
  43. data/ext/openssl/ossl_pkey_rsa.c +966 -0
  44. data/ext/openssl/ossl_rand.c +200 -0
  45. data/ext/openssl/ossl_rand.h +18 -0
  46. data/ext/openssl/ossl_ssl.c +3080 -0
  47. data/ext/openssl/ossl_ssl.h +36 -0
  48. data/ext/openssl/ossl_ssl_session.c +332 -0
  49. data/ext/openssl/ossl_ts.c +1524 -0
  50. data/ext/openssl/ossl_ts.h +16 -0
  51. data/ext/openssl/ossl_x509.c +262 -0
  52. data/ext/openssl/ossl_x509.h +115 -0
  53. data/ext/openssl/ossl_x509attr.c +324 -0
  54. data/ext/openssl/ossl_x509cert.c +846 -0
  55. data/ext/openssl/ossl_x509crl.c +542 -0
  56. data/ext/openssl/ossl_x509ext.c +491 -0
  57. data/ext/openssl/ossl_x509name.c +590 -0
  58. data/ext/openssl/ossl_x509req.c +441 -0
  59. data/ext/openssl/ossl_x509revoked.c +300 -0
  60. data/ext/openssl/ossl_x509store.c +902 -0
  61. data/ext/openssl/ruby_missing.h +24 -0
  62. data/lib/openssl/bn.rb +40 -0
  63. data/lib/openssl/buffering.rb +478 -0
  64. data/lib/openssl/cipher.rb +67 -0
  65. data/lib/openssl/config.rb +501 -0
  66. data/lib/openssl/digest.rb +73 -0
  67. data/lib/openssl/hmac.rb +13 -0
  68. data/lib/openssl/marshal.rb +30 -0
  69. data/lib/openssl/pkcs5.rb +22 -0
  70. data/lib/openssl/pkey.rb +42 -0
  71. data/lib/openssl/ssl.rb +542 -0
  72. data/lib/openssl/version.rb +5 -0
  73. data/lib/openssl/x509.rb +369 -0
  74. data/lib/openssl.rb +38 -0
  75. metadata +196 -0
@@ -0,0 +1,1270 @@
1
+ /*
2
+ * 'OpenSSL for Ruby' project
3
+ * Copyright (C) 2001-2002 Technorama team <oss-ruby@technorama.net>
4
+ * All rights reserved.
5
+ */
6
+ /*
7
+ * This program is licensed under the same licence as Ruby.
8
+ * (See the file 'LICENCE'.)
9
+ */
10
+ /* modified by Michal Rokos <m.rokos@sh.cvut.cz> */
11
+ #include "ossl.h"
12
+
13
+ #if HAVE_RB_EXT_RACTOR_SAFE
14
+ #include <ruby/ractor.h>
15
+ #endif
16
+
17
+ #define NewBN(klass) \
18
+ TypedData_Wrap_Struct((klass), &ossl_bn_type, 0)
19
+ #define SetBN(obj, bn) do { \
20
+ if (!(bn)) { \
21
+ ossl_raise(rb_eRuntimeError, "BN wasn't initialized!"); \
22
+ } \
23
+ RTYPEDDATA_DATA(obj) = (bn); \
24
+ } while (0)
25
+
26
+ #define GetBN(obj, bn) do { \
27
+ TypedData_Get_Struct((obj), BIGNUM, &ossl_bn_type, (bn)); \
28
+ if (!(bn)) { \
29
+ ossl_raise(rb_eRuntimeError, "BN wasn't initialized!"); \
30
+ } \
31
+ } while (0)
32
+
33
+ static void
34
+ ossl_bn_free(void *ptr)
35
+ {
36
+ BN_clear_free(ptr);
37
+ }
38
+
39
+ static const rb_data_type_t ossl_bn_type = {
40
+ "OpenSSL/BN",
41
+ {
42
+ 0, ossl_bn_free,
43
+ },
44
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
45
+ };
46
+
47
+ /*
48
+ * Classes
49
+ */
50
+ VALUE cBN;
51
+
52
+ /* Document-class: OpenSSL::BNError
53
+ *
54
+ * Generic Error for all of OpenSSL::BN (big num)
55
+ */
56
+ VALUE eBNError;
57
+
58
+ /*
59
+ * Public
60
+ */
61
+ VALUE
62
+ ossl_bn_new(const BIGNUM *bn)
63
+ {
64
+ BIGNUM *newbn;
65
+ VALUE obj;
66
+
67
+ obj = NewBN(cBN);
68
+ newbn = bn ? BN_dup(bn) : BN_new();
69
+ if (!newbn) {
70
+ ossl_raise(eBNError, NULL);
71
+ }
72
+ SetBN(obj, newbn);
73
+
74
+ return obj;
75
+ }
76
+
77
+ static BIGNUM *
78
+ integer_to_bnptr(VALUE obj, BIGNUM *orig)
79
+ {
80
+ BIGNUM *bn;
81
+
82
+ if (FIXNUM_P(obj)) {
83
+ long i;
84
+ unsigned char bin[sizeof(long)];
85
+ long n = FIX2LONG(obj);
86
+ unsigned long un = labs(n);
87
+
88
+ for (i = sizeof(long) - 1; 0 <= i; i--) {
89
+ bin[i] = un & 0xff;
90
+ un >>= 8;
91
+ }
92
+
93
+ bn = BN_bin2bn(bin, sizeof(bin), orig);
94
+ if (!bn)
95
+ ossl_raise(eBNError, "BN_bin2bn");
96
+ if (n < 0)
97
+ BN_set_negative(bn, 1);
98
+ }
99
+ else { /* assuming Bignum */
100
+ size_t len = rb_absint_size(obj, NULL);
101
+ unsigned char *bin;
102
+ VALUE buf;
103
+ int sign;
104
+
105
+ if (INT_MAX < len) {
106
+ rb_raise(eBNError, "bignum too long");
107
+ }
108
+ bin = (unsigned char*)ALLOCV_N(unsigned char, buf, len);
109
+ sign = rb_integer_pack(obj, bin, len, 1, 0, INTEGER_PACK_BIG_ENDIAN);
110
+
111
+ bn = BN_bin2bn(bin, (int)len, orig);
112
+ ALLOCV_END(buf);
113
+ if (!bn)
114
+ ossl_raise(eBNError, "BN_bin2bn");
115
+ if (sign < 0)
116
+ BN_set_negative(bn, 1);
117
+ }
118
+
119
+ return bn;
120
+ }
121
+
122
+ static VALUE
123
+ try_convert_to_bn(VALUE obj)
124
+ {
125
+ BIGNUM *bn;
126
+ VALUE newobj = Qnil;
127
+
128
+ if (rb_obj_is_kind_of(obj, cBN))
129
+ return obj;
130
+ if (RB_INTEGER_TYPE_P(obj)) {
131
+ newobj = NewBN(cBN); /* Handle potential mem leaks */
132
+ bn = integer_to_bnptr(obj, NULL);
133
+ SetBN(newobj, bn);
134
+ }
135
+
136
+ return newobj;
137
+ }
138
+
139
+ BIGNUM *
140
+ ossl_bn_value_ptr(volatile VALUE *ptr)
141
+ {
142
+ VALUE tmp;
143
+ BIGNUM *bn;
144
+
145
+ tmp = try_convert_to_bn(*ptr);
146
+ if (NIL_P(tmp))
147
+ ossl_raise(rb_eTypeError, "Cannot convert into OpenSSL::BN");
148
+ GetBN(tmp, bn);
149
+ *ptr = tmp;
150
+
151
+ return bn;
152
+ }
153
+
154
+ /*
155
+ * Private
156
+ */
157
+
158
+ #if HAVE_RB_EXT_RACTOR_SAFE
159
+ void
160
+ ossl_bn_ctx_free(void *ptr)
161
+ {
162
+ BN_CTX *ctx = (BN_CTX *)ptr;
163
+ BN_CTX_free(ctx);
164
+ }
165
+
166
+ struct rb_ractor_local_storage_type ossl_bn_ctx_key_type = {
167
+ NULL, // mark
168
+ ossl_bn_ctx_free,
169
+ };
170
+
171
+ rb_ractor_local_key_t ossl_bn_ctx_key;
172
+
173
+ BN_CTX *
174
+ ossl_bn_ctx_get(void)
175
+ {
176
+ // stored in ractor local storage
177
+
178
+ BN_CTX *ctx = rb_ractor_local_storage_ptr(ossl_bn_ctx_key);
179
+ if (!ctx) {
180
+ if (!(ctx = BN_CTX_new())) {
181
+ ossl_raise(rb_eRuntimeError, "Cannot init BN_CTX");
182
+ }
183
+ rb_ractor_local_storage_ptr_set(ossl_bn_ctx_key, ctx);
184
+ }
185
+ return ctx;
186
+ }
187
+ #else
188
+ // for ruby 2.x
189
+ static BN_CTX *gv_ossl_bn_ctx;
190
+
191
+ BN_CTX *
192
+ ossl_bn_ctx_get(void)
193
+ {
194
+ if (gv_ossl_bn_ctx == NULL) {
195
+ if (!(gv_ossl_bn_ctx = BN_CTX_new())) {
196
+ ossl_raise(rb_eRuntimeError, "Cannot init BN_CTX");
197
+ }
198
+ }
199
+ return gv_ossl_bn_ctx;
200
+ }
201
+
202
+ void
203
+ ossl_bn_ctx_free(void)
204
+ {
205
+ BN_CTX_free(gv_ossl_bn_ctx);
206
+ gv_ossl_bn_ctx = NULL;
207
+ }
208
+ #endif
209
+
210
+ static VALUE
211
+ ossl_bn_alloc(VALUE klass)
212
+ {
213
+ BIGNUM *bn;
214
+ VALUE obj = NewBN(klass);
215
+
216
+ if (!(bn = BN_new())) {
217
+ ossl_raise(eBNError, NULL);
218
+ }
219
+ SetBN(obj, bn);
220
+
221
+ return obj;
222
+ }
223
+
224
+ /*
225
+ * call-seq:
226
+ * OpenSSL::BN.new(bn) => aBN
227
+ * OpenSSL::BN.new(integer) => aBN
228
+ * OpenSSL::BN.new(string) => aBN
229
+ * OpenSSL::BN.new(string, 0 | 2 | 10 | 16) => aBN
230
+ *
231
+ * Construct a new OpenSSL BIGNUM object.
232
+ */
233
+ static VALUE
234
+ ossl_bn_initialize(int argc, VALUE *argv, VALUE self)
235
+ {
236
+ BIGNUM *bn;
237
+ VALUE str, bs;
238
+ int base = 10;
239
+ char *ptr;
240
+
241
+ if (rb_scan_args(argc, argv, "11", &str, &bs) == 2) {
242
+ base = NUM2INT(bs);
243
+ }
244
+
245
+ if (NIL_P(str)) {
246
+ ossl_raise(rb_eArgError, "invalid argument");
247
+ }
248
+
249
+ if (RB_INTEGER_TYPE_P(str)) {
250
+ GetBN(self, bn);
251
+ integer_to_bnptr(str, bn);
252
+
253
+ return self;
254
+ }
255
+
256
+ if (RTEST(rb_obj_is_kind_of(str, cBN))) {
257
+ BIGNUM *other;
258
+
259
+ GetBN(self, bn);
260
+ GetBN(str, other); /* Safe - we checked kind_of? above */
261
+ if (!BN_copy(bn, other)) {
262
+ ossl_raise(eBNError, NULL);
263
+ }
264
+ return self;
265
+ }
266
+
267
+ GetBN(self, bn);
268
+ switch (base) {
269
+ case 0:
270
+ ptr = StringValuePtr(str);
271
+ if (!BN_mpi2bn((unsigned char *)ptr, RSTRING_LENINT(str), bn)) {
272
+ ossl_raise(eBNError, NULL);
273
+ }
274
+ break;
275
+ case 2:
276
+ ptr = StringValuePtr(str);
277
+ if (!BN_bin2bn((unsigned char *)ptr, RSTRING_LENINT(str), bn)) {
278
+ ossl_raise(eBNError, NULL);
279
+ }
280
+ break;
281
+ case 10:
282
+ if (!BN_dec2bn(&bn, StringValueCStr(str))) {
283
+ ossl_raise(eBNError, NULL);
284
+ }
285
+ break;
286
+ case 16:
287
+ if (!BN_hex2bn(&bn, StringValueCStr(str))) {
288
+ ossl_raise(eBNError, NULL);
289
+ }
290
+ break;
291
+ default:
292
+ ossl_raise(rb_eArgError, "invalid radix %d", base);
293
+ }
294
+ return self;
295
+ }
296
+
297
+ /*
298
+ * call-seq:
299
+ * bn.to_s => string
300
+ * bn.to_s(base) => string
301
+ *
302
+ * === Parameters
303
+ * * _base_ - Integer
304
+ * Valid values:
305
+ * * 0 - MPI
306
+ * * 2 - binary
307
+ * * 10 - the default
308
+ * * 16 - hex
309
+ */
310
+ static VALUE
311
+ ossl_bn_to_s(int argc, VALUE *argv, VALUE self)
312
+ {
313
+ BIGNUM *bn;
314
+ VALUE str, bs;
315
+ int base = 10, len;
316
+ char *buf;
317
+
318
+ if (rb_scan_args(argc, argv, "01", &bs) == 1) {
319
+ base = NUM2INT(bs);
320
+ }
321
+ GetBN(self, bn);
322
+ switch (base) {
323
+ case 0:
324
+ len = BN_bn2mpi(bn, NULL);
325
+ str = rb_str_new(0, len);
326
+ if (BN_bn2mpi(bn, (unsigned char *)RSTRING_PTR(str)) != len)
327
+ ossl_raise(eBNError, NULL);
328
+ break;
329
+ case 2:
330
+ len = BN_num_bytes(bn);
331
+ str = rb_str_new(0, len);
332
+ if (BN_bn2bin(bn, (unsigned char *)RSTRING_PTR(str)) != len)
333
+ ossl_raise(eBNError, NULL);
334
+ break;
335
+ case 10:
336
+ if (!(buf = BN_bn2dec(bn))) ossl_raise(eBNError, NULL);
337
+ str = ossl_buf2str(buf, rb_long2int(strlen(buf)));
338
+ break;
339
+ case 16:
340
+ if (!(buf = BN_bn2hex(bn))) ossl_raise(eBNError, NULL);
341
+ str = ossl_buf2str(buf, rb_long2int(strlen(buf)));
342
+ break;
343
+ default:
344
+ ossl_raise(rb_eArgError, "invalid radix %d", base);
345
+ }
346
+
347
+ return str;
348
+ }
349
+
350
+ /*
351
+ * call-seq:
352
+ * bn.to_i => integer
353
+ */
354
+ static VALUE
355
+ ossl_bn_to_i(VALUE self)
356
+ {
357
+ BIGNUM *bn;
358
+ char *txt;
359
+ VALUE num;
360
+
361
+ GetBN(self, bn);
362
+
363
+ if (!(txt = BN_bn2hex(bn))) {
364
+ ossl_raise(eBNError, NULL);
365
+ }
366
+ num = rb_cstr_to_inum(txt, 16, Qtrue);
367
+ OPENSSL_free(txt);
368
+
369
+ return num;
370
+ }
371
+
372
+ static VALUE
373
+ ossl_bn_to_bn(VALUE self)
374
+ {
375
+ return self;
376
+ }
377
+
378
+ static VALUE
379
+ ossl_bn_coerce(VALUE self, VALUE other)
380
+ {
381
+ switch(TYPE(other)) {
382
+ case T_STRING:
383
+ self = ossl_bn_to_s(0, NULL, self);
384
+ break;
385
+ case T_FIXNUM:
386
+ case T_BIGNUM:
387
+ self = ossl_bn_to_i(self);
388
+ break;
389
+ default:
390
+ if (!RTEST(rb_obj_is_kind_of(other, cBN))) {
391
+ ossl_raise(rb_eTypeError, "Don't know how to coerce");
392
+ }
393
+ }
394
+ return rb_assoc_new(other, self);
395
+ }
396
+
397
+ #define BIGNUM_BOOL1(func) \
398
+ static VALUE \
399
+ ossl_bn_##func(VALUE self) \
400
+ { \
401
+ BIGNUM *bn; \
402
+ GetBN(self, bn); \
403
+ if (BN_##func(bn)) { \
404
+ return Qtrue; \
405
+ } \
406
+ return Qfalse; \
407
+ }
408
+
409
+ /*
410
+ * Document-method: OpenSSL::BN#zero?
411
+ * call-seq:
412
+ * bn.zero? => true | false
413
+ */
414
+ BIGNUM_BOOL1(is_zero)
415
+
416
+ /*
417
+ * Document-method: OpenSSL::BN#one?
418
+ * call-seq:
419
+ * bn.one? => true | false
420
+ */
421
+ BIGNUM_BOOL1(is_one)
422
+
423
+ /*
424
+ * Document-method: OpenSSL::BN#odd?
425
+ * call-seq:
426
+ * bn.odd? => true | false
427
+ */
428
+ BIGNUM_BOOL1(is_odd)
429
+
430
+ /*
431
+ * call-seq:
432
+ * bn.negative? => true | false
433
+ */
434
+ static VALUE
435
+ ossl_bn_is_negative(VALUE self)
436
+ {
437
+ BIGNUM *bn;
438
+
439
+ GetBN(self, bn);
440
+ if (BN_is_zero(bn))
441
+ return Qfalse;
442
+ return BN_is_negative(bn) ? Qtrue : Qfalse;
443
+ }
444
+
445
+ #define BIGNUM_1c(func) \
446
+ static VALUE \
447
+ ossl_bn_##func(VALUE self) \
448
+ { \
449
+ BIGNUM *bn, *result; \
450
+ VALUE obj; \
451
+ GetBN(self, bn); \
452
+ obj = NewBN(rb_obj_class(self)); \
453
+ if (!(result = BN_new())) { \
454
+ ossl_raise(eBNError, NULL); \
455
+ } \
456
+ if (BN_##func(result, bn, ossl_bn_ctx) <= 0) { \
457
+ BN_free(result); \
458
+ ossl_raise(eBNError, NULL); \
459
+ } \
460
+ SetBN(obj, result); \
461
+ return obj; \
462
+ }
463
+
464
+ /*
465
+ * Document-method: OpenSSL::BN#sqr
466
+ * call-seq:
467
+ * bn.sqr => aBN
468
+ */
469
+ BIGNUM_1c(sqr)
470
+
471
+ #define BIGNUM_2(func) \
472
+ static VALUE \
473
+ ossl_bn_##func(VALUE self, VALUE other) \
474
+ { \
475
+ BIGNUM *bn1, *bn2 = GetBNPtr(other), *result; \
476
+ VALUE obj; \
477
+ GetBN(self, bn1); \
478
+ obj = NewBN(rb_obj_class(self)); \
479
+ if (!(result = BN_new())) { \
480
+ ossl_raise(eBNError, NULL); \
481
+ } \
482
+ if (BN_##func(result, bn1, bn2) <= 0) { \
483
+ BN_free(result); \
484
+ ossl_raise(eBNError, NULL); \
485
+ } \
486
+ SetBN(obj, result); \
487
+ return obj; \
488
+ }
489
+
490
+ /*
491
+ * Document-method: OpenSSL::BN#+
492
+ * call-seq:
493
+ * bn + bn2 => aBN
494
+ */
495
+ BIGNUM_2(add)
496
+
497
+ /*
498
+ * Document-method: OpenSSL::BN#-
499
+ * call-seq:
500
+ * bn - bn2 => aBN
501
+ */
502
+ BIGNUM_2(sub)
503
+
504
+ #define BIGNUM_2c(func) \
505
+ static VALUE \
506
+ ossl_bn_##func(VALUE self, VALUE other) \
507
+ { \
508
+ BIGNUM *bn1, *bn2 = GetBNPtr(other), *result; \
509
+ VALUE obj; \
510
+ GetBN(self, bn1); \
511
+ obj = NewBN(rb_obj_class(self)); \
512
+ if (!(result = BN_new())) { \
513
+ ossl_raise(eBNError, NULL); \
514
+ } \
515
+ if (BN_##func(result, bn1, bn2, ossl_bn_ctx) <= 0) { \
516
+ BN_free(result); \
517
+ ossl_raise(eBNError, NULL); \
518
+ } \
519
+ SetBN(obj, result); \
520
+ return obj; \
521
+ }
522
+
523
+ /*
524
+ * Document-method: OpenSSL::BN#*
525
+ * call-seq:
526
+ * bn * bn2 => aBN
527
+ */
528
+ BIGNUM_2c(mul)
529
+
530
+ /*
531
+ * Document-method: OpenSSL::BN#%
532
+ * call-seq:
533
+ * bn % bn2 => aBN
534
+ */
535
+ BIGNUM_2c(mod)
536
+
537
+ /*
538
+ * Document-method: OpenSSL::BN#**
539
+ * call-seq:
540
+ * bn ** bn2 => aBN
541
+ */
542
+ BIGNUM_2c(exp)
543
+
544
+ /*
545
+ * Document-method: OpenSSL::BN#gcd
546
+ * call-seq:
547
+ * bn.gcd(bn2) => aBN
548
+ */
549
+ BIGNUM_2c(gcd)
550
+
551
+ /*
552
+ * Document-method: OpenSSL::BN#mod_sqr
553
+ * call-seq:
554
+ * bn.mod_sqr(bn2) => aBN
555
+ */
556
+ BIGNUM_2c(mod_sqr)
557
+
558
+ /*
559
+ * call-seq:
560
+ * bn.mod_inverse(bn2) => aBN
561
+ */
562
+ static VALUE
563
+ ossl_bn_mod_inverse(VALUE self, VALUE other)
564
+ {
565
+ BIGNUM *bn1, *bn2 = GetBNPtr(other), *result;
566
+ VALUE obj;
567
+ GetBN(self, bn1);
568
+ obj = NewBN(rb_obj_class(self));
569
+ if (!(result = BN_mod_inverse(NULL, bn1, bn2, ossl_bn_ctx)))
570
+ ossl_raise(eBNError, "BN_mod_inverse");
571
+ SetBN(obj, result);
572
+ return obj;
573
+ }
574
+
575
+ /*
576
+ * call-seq:
577
+ * bn1 / bn2 => [result, remainder]
578
+ *
579
+ * Division of OpenSSL::BN instances
580
+ */
581
+ static VALUE
582
+ ossl_bn_div(VALUE self, VALUE other)
583
+ {
584
+ BIGNUM *bn1, *bn2 = GetBNPtr(other), *r1, *r2;
585
+ VALUE klass, obj1, obj2;
586
+
587
+ GetBN(self, bn1);
588
+
589
+ klass = rb_obj_class(self);
590
+ obj1 = NewBN(klass);
591
+ obj2 = NewBN(klass);
592
+ if (!(r1 = BN_new())) {
593
+ ossl_raise(eBNError, NULL);
594
+ }
595
+ if (!(r2 = BN_new())) {
596
+ BN_free(r1);
597
+ ossl_raise(eBNError, NULL);
598
+ }
599
+ if (!BN_div(r1, r2, bn1, bn2, ossl_bn_ctx)) {
600
+ BN_free(r1);
601
+ BN_free(r2);
602
+ ossl_raise(eBNError, NULL);
603
+ }
604
+ SetBN(obj1, r1);
605
+ SetBN(obj2, r2);
606
+
607
+ return rb_ary_new3(2, obj1, obj2);
608
+ }
609
+
610
+ #define BIGNUM_3c(func) \
611
+ static VALUE \
612
+ ossl_bn_##func(VALUE self, VALUE other1, VALUE other2) \
613
+ { \
614
+ BIGNUM *bn1, *bn2 = GetBNPtr(other1); \
615
+ BIGNUM *bn3 = GetBNPtr(other2), *result; \
616
+ VALUE obj; \
617
+ GetBN(self, bn1); \
618
+ obj = NewBN(rb_obj_class(self)); \
619
+ if (!(result = BN_new())) { \
620
+ ossl_raise(eBNError, NULL); \
621
+ } \
622
+ if (BN_##func(result, bn1, bn2, bn3, ossl_bn_ctx) <= 0) { \
623
+ BN_free(result); \
624
+ ossl_raise(eBNError, NULL); \
625
+ } \
626
+ SetBN(obj, result); \
627
+ return obj; \
628
+ }
629
+
630
+ /*
631
+ * Document-method: OpenSSL::BN#mod_add
632
+ * call-seq:
633
+ * bn.mod_add(bn1, bn2) -> aBN
634
+ */
635
+ BIGNUM_3c(mod_add)
636
+
637
+ /*
638
+ * Document-method: OpenSSL::BN#mod_sub
639
+ * call-seq:
640
+ * bn.mod_sub(bn1, bn2) -> aBN
641
+ */
642
+ BIGNUM_3c(mod_sub)
643
+
644
+ /*
645
+ * Document-method: OpenSSL::BN#mod_mul
646
+ * call-seq:
647
+ * bn.mod_mul(bn1, bn2) -> aBN
648
+ */
649
+ BIGNUM_3c(mod_mul)
650
+
651
+ /*
652
+ * Document-method: OpenSSL::BN#mod_exp
653
+ * call-seq:
654
+ * bn.mod_exp(bn1, bn2) -> aBN
655
+ */
656
+ BIGNUM_3c(mod_exp)
657
+
658
+ #define BIGNUM_BIT(func) \
659
+ static VALUE \
660
+ ossl_bn_##func(VALUE self, VALUE bit) \
661
+ { \
662
+ BIGNUM *bn; \
663
+ GetBN(self, bn); \
664
+ if (BN_##func(bn, NUM2INT(bit)) <= 0) { \
665
+ ossl_raise(eBNError, NULL); \
666
+ } \
667
+ return self; \
668
+ }
669
+
670
+ /*
671
+ * Document-method: OpenSSL::BN#set_bit!
672
+ * call-seq:
673
+ * bn.set_bit!(bit) -> self
674
+ */
675
+ BIGNUM_BIT(set_bit)
676
+
677
+ /*
678
+ * Document-method: OpenSSL::BN#clear_bit!
679
+ * call-seq:
680
+ * bn.clear_bit!(bit) -> self
681
+ */
682
+ BIGNUM_BIT(clear_bit)
683
+
684
+ /*
685
+ * Document-method: OpenSSL::BN#mask_bit!
686
+ * call-seq:
687
+ * bn.mask_bit!(bit) -> self
688
+ */
689
+ BIGNUM_BIT(mask_bits)
690
+
691
+ /*
692
+ * call-seq:
693
+ * bn.bit_set?(bit) => true | false
694
+ *
695
+ * Tests bit _bit_ in _bn_ and returns +true+ if set, +false+ if not set.
696
+ */
697
+ static VALUE
698
+ ossl_bn_is_bit_set(VALUE self, VALUE bit)
699
+ {
700
+ int b;
701
+ BIGNUM *bn;
702
+
703
+ b = NUM2INT(bit);
704
+ GetBN(self, bn);
705
+ if (BN_is_bit_set(bn, b)) {
706
+ return Qtrue;
707
+ }
708
+ return Qfalse;
709
+ }
710
+
711
+ #define BIGNUM_SHIFT(func) \
712
+ static VALUE \
713
+ ossl_bn_##func(VALUE self, VALUE bits) \
714
+ { \
715
+ BIGNUM *bn, *result; \
716
+ int b; \
717
+ VALUE obj; \
718
+ b = NUM2INT(bits); \
719
+ GetBN(self, bn); \
720
+ obj = NewBN(rb_obj_class(self)); \
721
+ if (!(result = BN_new())) { \
722
+ ossl_raise(eBNError, NULL); \
723
+ } \
724
+ if (BN_##func(result, bn, b) <= 0) { \
725
+ BN_free(result); \
726
+ ossl_raise(eBNError, NULL); \
727
+ } \
728
+ SetBN(obj, result); \
729
+ return obj; \
730
+ }
731
+
732
+ /*
733
+ * Document-method: OpenSSL::BN#<<
734
+ * call-seq:
735
+ * bn << bits -> aBN
736
+ */
737
+ BIGNUM_SHIFT(lshift)
738
+
739
+ /*
740
+ * Document-method: OpenSSL::BN#>>
741
+ * call-seq:
742
+ * bn >> bits -> aBN
743
+ */
744
+ BIGNUM_SHIFT(rshift)
745
+
746
+ #define BIGNUM_SELF_SHIFT(func) \
747
+ static VALUE \
748
+ ossl_bn_self_##func(VALUE self, VALUE bits) \
749
+ { \
750
+ BIGNUM *bn; \
751
+ int b; \
752
+ b = NUM2INT(bits); \
753
+ GetBN(self, bn); \
754
+ if (BN_##func(bn, bn, b) <= 0) \
755
+ ossl_raise(eBNError, NULL); \
756
+ return self; \
757
+ }
758
+
759
+ /*
760
+ * Document-method: OpenSSL::BN#lshift!
761
+ * call-seq:
762
+ * bn.lshift!(bits) -> self
763
+ */
764
+ BIGNUM_SELF_SHIFT(lshift)
765
+
766
+ /*
767
+ * Document-method: OpenSSL::BN#rshift!
768
+ * call-seq:
769
+ * bn.rshift!(bits) -> self
770
+ */
771
+ BIGNUM_SELF_SHIFT(rshift)
772
+
773
+ #define BIGNUM_RAND(func) \
774
+ static VALUE \
775
+ ossl_bn_s_##func(int argc, VALUE *argv, VALUE klass) \
776
+ { \
777
+ BIGNUM *result; \
778
+ int bottom = 0, top = 0, b; \
779
+ VALUE bits, fill, odd, obj; \
780
+ \
781
+ switch (rb_scan_args(argc, argv, "12", &bits, &fill, &odd)) { \
782
+ case 3: \
783
+ bottom = (odd == Qtrue) ? 1 : 0; \
784
+ /* FALLTHROUGH */ \
785
+ case 2: \
786
+ top = NUM2INT(fill); \
787
+ } \
788
+ b = NUM2INT(bits); \
789
+ obj = NewBN(klass); \
790
+ if (!(result = BN_new())) { \
791
+ ossl_raise(eBNError, NULL); \
792
+ } \
793
+ if (BN_##func(result, b, top, bottom) <= 0) { \
794
+ BN_free(result); \
795
+ ossl_raise(eBNError, NULL); \
796
+ } \
797
+ SetBN(obj, result); \
798
+ return obj; \
799
+ }
800
+
801
+ /*
802
+ * Document-method: OpenSSL::BN.rand
803
+ * BN.rand(bits [, fill [, odd]]) -> aBN
804
+ */
805
+ BIGNUM_RAND(rand)
806
+
807
+ /*
808
+ * Document-method: OpenSSL::BN.pseudo_rand
809
+ * BN.pseudo_rand(bits [, fill [, odd]]) -> aBN
810
+ */
811
+ BIGNUM_RAND(pseudo_rand)
812
+
813
+ #define BIGNUM_RAND_RANGE(func) \
814
+ static VALUE \
815
+ ossl_bn_s_##func##_range(VALUE klass, VALUE range) \
816
+ { \
817
+ BIGNUM *bn = GetBNPtr(range), *result; \
818
+ VALUE obj = NewBN(klass); \
819
+ if (!(result = BN_new())) { \
820
+ ossl_raise(eBNError, NULL); \
821
+ } \
822
+ if (BN_##func##_range(result, bn) <= 0) { \
823
+ BN_free(result); \
824
+ ossl_raise(eBNError, NULL); \
825
+ } \
826
+ SetBN(obj, result); \
827
+ return obj; \
828
+ }
829
+
830
+ /*
831
+ * Document-method: OpenSSL::BN.rand_range
832
+ * call-seq:
833
+ * BN.rand_range(range) -> aBN
834
+ *
835
+ */
836
+ BIGNUM_RAND_RANGE(rand)
837
+
838
+ /*
839
+ * Document-method: OpenSSL::BN.pseudo_rand_range
840
+ * call-seq:
841
+ * BN.pseudo_rand_range(range) -> aBN
842
+ *
843
+ */
844
+ BIGNUM_RAND_RANGE(pseudo_rand)
845
+
846
+ /*
847
+ * call-seq:
848
+ * BN.generate_prime(bits, [, safe [, add [, rem]]]) => bn
849
+ *
850
+ * Generates a random prime number of bit length _bits_. If _safe_ is set to
851
+ * +true+, generates a safe prime. If _add_ is specified, generates a prime that
852
+ * fulfills condition <tt>p % add = rem</tt>.
853
+ *
854
+ * === Parameters
855
+ * * _bits_ - integer
856
+ * * _safe_ - boolean
857
+ * * _add_ - BN
858
+ * * _rem_ - BN
859
+ */
860
+ static VALUE
861
+ ossl_bn_s_generate_prime(int argc, VALUE *argv, VALUE klass)
862
+ {
863
+ BIGNUM *add = NULL, *rem = NULL, *result;
864
+ int safe = 1, num;
865
+ VALUE vnum, vsafe, vadd, vrem, obj;
866
+
867
+ rb_scan_args(argc, argv, "13", &vnum, &vsafe, &vadd, &vrem);
868
+
869
+ num = NUM2INT(vnum);
870
+
871
+ if (vsafe == Qfalse) {
872
+ safe = 0;
873
+ }
874
+ if (!NIL_P(vadd)) {
875
+ add = GetBNPtr(vadd);
876
+ rem = NIL_P(vrem) ? NULL : GetBNPtr(vrem);
877
+ }
878
+ obj = NewBN(klass);
879
+ if (!(result = BN_new())) {
880
+ ossl_raise(eBNError, NULL);
881
+ }
882
+ if (!BN_generate_prime_ex(result, num, safe, add, rem, NULL)) {
883
+ BN_free(result);
884
+ ossl_raise(eBNError, NULL);
885
+ }
886
+ SetBN(obj, result);
887
+
888
+ return obj;
889
+ }
890
+
891
+ #define BIGNUM_NUM(func) \
892
+ static VALUE \
893
+ ossl_bn_##func(VALUE self) \
894
+ { \
895
+ BIGNUM *bn; \
896
+ GetBN(self, bn); \
897
+ return INT2NUM(BN_##func(bn)); \
898
+ }
899
+
900
+ /*
901
+ * Document-method: OpenSSL::BN#num_bytes
902
+ * call-seq:
903
+ * bn.num_bytes => integer
904
+ */
905
+ BIGNUM_NUM(num_bytes)
906
+
907
+ /*
908
+ * Document-method: OpenSSL::BN#num_bits
909
+ * call-seq:
910
+ * bn.num_bits => integer
911
+ */
912
+ BIGNUM_NUM(num_bits)
913
+
914
+ static VALUE
915
+ ossl_bn_copy(VALUE self, VALUE other)
916
+ {
917
+ BIGNUM *bn1, *bn2;
918
+
919
+ rb_check_frozen(self);
920
+
921
+ if (self == other) return self;
922
+
923
+ GetBN(self, bn1);
924
+ bn2 = GetBNPtr(other);
925
+
926
+ if (!BN_copy(bn1, bn2)) {
927
+ ossl_raise(eBNError, NULL);
928
+ }
929
+ return self;
930
+ }
931
+
932
+ /*
933
+ * call-seq:
934
+ * +bn -> aBN
935
+ */
936
+ static VALUE
937
+ ossl_bn_uplus(VALUE self)
938
+ {
939
+ return self;
940
+ }
941
+
942
+ /*
943
+ * call-seq:
944
+ * -bn -> aBN
945
+ */
946
+ static VALUE
947
+ ossl_bn_uminus(VALUE self)
948
+ {
949
+ VALUE obj;
950
+ BIGNUM *bn1, *bn2;
951
+
952
+ GetBN(self, bn1);
953
+ obj = NewBN(cBN);
954
+ bn2 = BN_dup(bn1);
955
+ if (!bn2)
956
+ ossl_raise(eBNError, "BN_dup");
957
+ SetBN(obj, bn2);
958
+ BN_set_negative(bn2, !BN_is_negative(bn2));
959
+
960
+ return obj;
961
+ }
962
+
963
+ #define BIGNUM_CMP(func) \
964
+ static VALUE \
965
+ ossl_bn_##func(VALUE self, VALUE other) \
966
+ { \
967
+ BIGNUM *bn1, *bn2 = GetBNPtr(other); \
968
+ GetBN(self, bn1); \
969
+ return INT2NUM(BN_##func(bn1, bn2)); \
970
+ }
971
+
972
+ /*
973
+ * Document-method: OpenSSL::BN#cmp
974
+ * call-seq:
975
+ * bn.cmp(bn2) => integer
976
+ */
977
+ /*
978
+ * Document-method: OpenSSL::BN#<=>
979
+ * call-seq:
980
+ * bn <=> bn2 => integer
981
+ */
982
+ BIGNUM_CMP(cmp)
983
+
984
+ /*
985
+ * Document-method: OpenSSL::BN#ucmp
986
+ * call-seq:
987
+ * bn.ucmp(bn2) => integer
988
+ */
989
+ BIGNUM_CMP(ucmp)
990
+
991
+ /*
992
+ * call-seq:
993
+ * bn == obj => true or false
994
+ *
995
+ * Returns +true+ only if _obj_ has the same value as _bn_. Contrast this
996
+ * with OpenSSL::BN#eql?, which requires obj to be OpenSSL::BN.
997
+ */
998
+ static VALUE
999
+ ossl_bn_eq(VALUE self, VALUE other)
1000
+ {
1001
+ BIGNUM *bn1, *bn2;
1002
+
1003
+ GetBN(self, bn1);
1004
+ other = try_convert_to_bn(other);
1005
+ if (NIL_P(other))
1006
+ return Qfalse;
1007
+ GetBN(other, bn2);
1008
+
1009
+ if (!BN_cmp(bn1, bn2)) {
1010
+ return Qtrue;
1011
+ }
1012
+ return Qfalse;
1013
+ }
1014
+
1015
+ /*
1016
+ * call-seq:
1017
+ * bn.eql?(obj) => true or false
1018
+ *
1019
+ * Returns <code>true</code> only if <i>obj</i> is a
1020
+ * <code>OpenSSL::BN</code> with the same value as <i>bn</i>. Contrast this
1021
+ * with OpenSSL::BN#==, which performs type conversions.
1022
+ */
1023
+ static VALUE
1024
+ ossl_bn_eql(VALUE self, VALUE other)
1025
+ {
1026
+ BIGNUM *bn1, *bn2;
1027
+
1028
+ if (!rb_obj_is_kind_of(other, cBN))
1029
+ return Qfalse;
1030
+ GetBN(self, bn1);
1031
+ GetBN(other, bn2);
1032
+
1033
+ return BN_cmp(bn1, bn2) ? Qfalse : Qtrue;
1034
+ }
1035
+
1036
+ /*
1037
+ * call-seq:
1038
+ * bn.hash => Integer
1039
+ *
1040
+ * Returns a hash code for this object.
1041
+ *
1042
+ * See also Object#hash.
1043
+ */
1044
+ static VALUE
1045
+ ossl_bn_hash(VALUE self)
1046
+ {
1047
+ BIGNUM *bn;
1048
+ VALUE tmp, hash;
1049
+ unsigned char *buf;
1050
+ int len;
1051
+
1052
+ GetBN(self, bn);
1053
+ len = BN_num_bytes(bn);
1054
+ buf = ALLOCV(tmp, len);
1055
+ if (BN_bn2bin(bn, buf) != len) {
1056
+ ALLOCV_END(tmp);
1057
+ ossl_raise(eBNError, "BN_bn2bin");
1058
+ }
1059
+
1060
+ hash = ST2FIX(rb_memhash(buf, len));
1061
+ ALLOCV_END(tmp);
1062
+
1063
+ return hash;
1064
+ }
1065
+
1066
+ /*
1067
+ * call-seq:
1068
+ * bn.prime? => true | false
1069
+ * bn.prime?(checks) => true | false
1070
+ *
1071
+ * Performs a Miller-Rabin probabilistic primality test with _checks_
1072
+ * iterations. If _checks_ is not specified, a number of iterations is used
1073
+ * that yields a false positive rate of at most 2^-80 for random input.
1074
+ *
1075
+ * === Parameters
1076
+ * * _checks_ - integer
1077
+ */
1078
+ static VALUE
1079
+ ossl_bn_is_prime(int argc, VALUE *argv, VALUE self)
1080
+ {
1081
+ BIGNUM *bn;
1082
+ VALUE vchecks;
1083
+ int checks = BN_prime_checks;
1084
+
1085
+ if (rb_scan_args(argc, argv, "01", &vchecks) == 1) {
1086
+ checks = NUM2INT(vchecks);
1087
+ }
1088
+ GetBN(self, bn);
1089
+ switch (BN_is_prime_ex(bn, checks, ossl_bn_ctx, NULL)) {
1090
+ case 1:
1091
+ return Qtrue;
1092
+ case 0:
1093
+ return Qfalse;
1094
+ default:
1095
+ ossl_raise(eBNError, NULL);
1096
+ }
1097
+ /* not reachable */
1098
+ return Qnil;
1099
+ }
1100
+
1101
+ /*
1102
+ * call-seq:
1103
+ * bn.prime_fasttest? => true | false
1104
+ * bn.prime_fasttest?(checks) => true | false
1105
+ * bn.prime_fasttest?(checks, trial_div) => true | false
1106
+ *
1107
+ * Performs a Miller-Rabin primality test. This is same as #prime? except this
1108
+ * first attempts trial divisions with some small primes.
1109
+ *
1110
+ * === Parameters
1111
+ * * _checks_ - integer
1112
+ * * _trial_div_ - boolean
1113
+ */
1114
+ static VALUE
1115
+ ossl_bn_is_prime_fasttest(int argc, VALUE *argv, VALUE self)
1116
+ {
1117
+ BIGNUM *bn;
1118
+ VALUE vchecks, vtrivdiv;
1119
+ int checks = BN_prime_checks, do_trial_division = 1;
1120
+
1121
+ rb_scan_args(argc, argv, "02", &vchecks, &vtrivdiv);
1122
+
1123
+ if (!NIL_P(vchecks)) {
1124
+ checks = NUM2INT(vchecks);
1125
+ }
1126
+ GetBN(self, bn);
1127
+ /* handle true/false */
1128
+ if (vtrivdiv == Qfalse) {
1129
+ do_trial_division = 0;
1130
+ }
1131
+ switch (BN_is_prime_fasttest_ex(bn, checks, ossl_bn_ctx, do_trial_division, NULL)) {
1132
+ case 1:
1133
+ return Qtrue;
1134
+ case 0:
1135
+ return Qfalse;
1136
+ default:
1137
+ ossl_raise(eBNError, NULL);
1138
+ }
1139
+ /* not reachable */
1140
+ return Qnil;
1141
+ }
1142
+
1143
+ /*
1144
+ * INIT
1145
+ * (NOTE: ordering of methods is the same as in 'man bn')
1146
+ */
1147
+ void
1148
+ Init_ossl_bn(void)
1149
+ {
1150
+ #if 0
1151
+ mOSSL = rb_define_module("OpenSSL");
1152
+ eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
1153
+ #endif
1154
+
1155
+ #ifdef HAVE_RB_EXT_RACTOR_SAFE
1156
+ ossl_bn_ctx_key = rb_ractor_local_storage_ptr_newkey(&ossl_bn_ctx_key_type);
1157
+ #else
1158
+ ossl_bn_ctx_get();
1159
+ #endif
1160
+
1161
+ eBNError = rb_define_class_under(mOSSL, "BNError", eOSSLError);
1162
+
1163
+ cBN = rb_define_class_under(mOSSL, "BN", rb_cObject);
1164
+
1165
+ rb_define_alloc_func(cBN, ossl_bn_alloc);
1166
+ rb_define_method(cBN, "initialize", ossl_bn_initialize, -1);
1167
+
1168
+ rb_define_method(cBN, "initialize_copy", ossl_bn_copy, 1);
1169
+ rb_define_method(cBN, "copy", ossl_bn_copy, 1);
1170
+
1171
+ /* swap (=coerce?) */
1172
+
1173
+ rb_define_method(cBN, "num_bytes", ossl_bn_num_bytes, 0);
1174
+ rb_define_method(cBN, "num_bits", ossl_bn_num_bits, 0);
1175
+ /* num_bits_word */
1176
+
1177
+ rb_define_method(cBN, "+@", ossl_bn_uplus, 0);
1178
+ rb_define_method(cBN, "-@", ossl_bn_uminus, 0);
1179
+
1180
+ rb_define_method(cBN, "+", ossl_bn_add, 1);
1181
+ rb_define_method(cBN, "-", ossl_bn_sub, 1);
1182
+ rb_define_method(cBN, "*", ossl_bn_mul, 1);
1183
+ rb_define_method(cBN, "sqr", ossl_bn_sqr, 0);
1184
+ rb_define_method(cBN, "/", ossl_bn_div, 1);
1185
+ rb_define_method(cBN, "%", ossl_bn_mod, 1);
1186
+ /* nnmod */
1187
+
1188
+ rb_define_method(cBN, "mod_add", ossl_bn_mod_add, 2);
1189
+ rb_define_method(cBN, "mod_sub", ossl_bn_mod_sub, 2);
1190
+ rb_define_method(cBN, "mod_mul", ossl_bn_mod_mul, 2);
1191
+ rb_define_method(cBN, "mod_sqr", ossl_bn_mod_sqr, 1);
1192
+ rb_define_method(cBN, "**", ossl_bn_exp, 1);
1193
+ rb_define_method(cBN, "mod_exp", ossl_bn_mod_exp, 2);
1194
+ rb_define_method(cBN, "gcd", ossl_bn_gcd, 1);
1195
+
1196
+ /* add_word
1197
+ * sub_word
1198
+ * mul_word
1199
+ * div_word
1200
+ * mod_word */
1201
+
1202
+ rb_define_method(cBN, "cmp", ossl_bn_cmp, 1);
1203
+ rb_define_alias(cBN, "<=>", "cmp");
1204
+ rb_define_method(cBN, "ucmp", ossl_bn_ucmp, 1);
1205
+ rb_define_method(cBN, "eql?", ossl_bn_eql, 1);
1206
+ rb_define_method(cBN, "hash", ossl_bn_hash, 0);
1207
+ rb_define_method(cBN, "==", ossl_bn_eq, 1);
1208
+ rb_define_alias(cBN, "===", "==");
1209
+ rb_define_method(cBN, "zero?", ossl_bn_is_zero, 0);
1210
+ rb_define_method(cBN, "one?", ossl_bn_is_one, 0);
1211
+ /* is_word */
1212
+ rb_define_method(cBN, "odd?", ossl_bn_is_odd, 0);
1213
+ rb_define_method(cBN, "negative?", ossl_bn_is_negative, 0);
1214
+
1215
+ /* zero
1216
+ * one
1217
+ * value_one - DON'T IMPL.
1218
+ * set_word
1219
+ * get_word */
1220
+
1221
+ rb_define_singleton_method(cBN, "rand", ossl_bn_s_rand, -1);
1222
+ rb_define_singleton_method(cBN, "pseudo_rand", ossl_bn_s_pseudo_rand, -1);
1223
+ rb_define_singleton_method(cBN, "rand_range", ossl_bn_s_rand_range, 1);
1224
+ rb_define_singleton_method(cBN, "pseudo_rand_range", ossl_bn_s_pseudo_rand_range, 1);
1225
+
1226
+ rb_define_singleton_method(cBN, "generate_prime", ossl_bn_s_generate_prime, -1);
1227
+ rb_define_method(cBN, "prime?", ossl_bn_is_prime, -1);
1228
+ rb_define_method(cBN, "prime_fasttest?", ossl_bn_is_prime_fasttest, -1);
1229
+
1230
+ rb_define_method(cBN, "set_bit!", ossl_bn_set_bit, 1);
1231
+ rb_define_method(cBN, "clear_bit!", ossl_bn_clear_bit, 1);
1232
+ rb_define_method(cBN, "bit_set?", ossl_bn_is_bit_set, 1);
1233
+ rb_define_method(cBN, "mask_bits!", ossl_bn_mask_bits, 1);
1234
+ rb_define_method(cBN, "<<", ossl_bn_lshift, 1);
1235
+ rb_define_method(cBN, ">>", ossl_bn_rshift, 1);
1236
+ rb_define_method(cBN, "lshift!", ossl_bn_self_lshift, 1);
1237
+ rb_define_method(cBN, "rshift!", ossl_bn_self_rshift, 1);
1238
+ /* lshift1 - DON'T IMPL. */
1239
+ /* rshift1 - DON'T IMPL. */
1240
+
1241
+ /*
1242
+ * bn2bin
1243
+ * bin2bn
1244
+ * bn2hex
1245
+ * bn2dec
1246
+ * hex2bn
1247
+ * dec2bn - all these are implemented in ossl_bn_initialize, and ossl_bn_to_s
1248
+ * print - NOT IMPL.
1249
+ * print_fp - NOT IMPL.
1250
+ * bn2mpi
1251
+ * mpi2bn
1252
+ */
1253
+ rb_define_method(cBN, "to_s", ossl_bn_to_s, -1);
1254
+ rb_define_method(cBN, "to_i", ossl_bn_to_i, 0);
1255
+ rb_define_alias(cBN, "to_int", "to_i");
1256
+ rb_define_method(cBN, "to_bn", ossl_bn_to_bn, 0);
1257
+ rb_define_method(cBN, "coerce", ossl_bn_coerce, 1);
1258
+
1259
+ /*
1260
+ * TODO:
1261
+ * But how to: from_bin, from_mpi? PACK?
1262
+ * to_bin
1263
+ * to_mpi
1264
+ */
1265
+
1266
+ rb_define_method(cBN, "mod_inverse", ossl_bn_mod_inverse, 1);
1267
+
1268
+ /* RECiProcal
1269
+ * MONTgomery */
1270
+ }