openssl-custom 2.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+ }