pq_crypto 0.5.0 → 0.5.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.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +74 -2
- data/CHANGELOG.md +49 -0
- data/ext/pqcrypto/extconf.rb +101 -27
- data/ext/pqcrypto/pqcrypto_native_api.h +3 -0
- data/ext/pqcrypto/pqcrypto_ruby_secure.c +234 -9
- data/ext/pqcrypto/pqcrypto_secure.c +295 -218
- data/ext/pqcrypto/pqcrypto_secure.h +12 -3
- data/ext/pqcrypto/pqcrypto_version.h +1 -1
- data/ext/pqcrypto/vendor/.vendored +4 -2
- data/lib/pq_crypto/hybrid_kem.rb +10 -1
- data/lib/pq_crypto/version.rb +1 -1
- data/lib/pq_crypto.rb +4 -0
- data/script/vendor_libs.rb +218 -73
- metadata +1 -1
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
#include <string.h>
|
|
6
6
|
|
|
7
7
|
#include <openssl/crypto.h>
|
|
8
|
+
#include <openssl/evp.h>
|
|
8
9
|
|
|
9
10
|
#include "pqcrypto_secure.h"
|
|
10
11
|
|
|
@@ -12,6 +13,8 @@
|
|
|
12
13
|
#define RB_NOGVL_OFFLOAD_SAFE 0
|
|
13
14
|
#endif
|
|
14
15
|
|
|
16
|
+
#define PQ_MU_ABSORB_NOGVL_MIN_BYTES 16384
|
|
17
|
+
|
|
15
18
|
typedef struct {
|
|
16
19
|
int result;
|
|
17
20
|
uint8_t *public_key;
|
|
@@ -36,6 +39,25 @@ typedef struct {
|
|
|
36
39
|
const uint8_t *secret_key;
|
|
37
40
|
} kem_decapsulate_call_t;
|
|
38
41
|
|
|
42
|
+
typedef struct {
|
|
43
|
+
int result;
|
|
44
|
+
uint8_t *expanded_secret_key;
|
|
45
|
+
const uint8_t *secret_key;
|
|
46
|
+
} hybrid_expand_call_t;
|
|
47
|
+
|
|
48
|
+
typedef struct {
|
|
49
|
+
int result;
|
|
50
|
+
uint8_t *shared_secret;
|
|
51
|
+
const uint8_t *ciphertext;
|
|
52
|
+
const uint8_t *expanded_secret_key;
|
|
53
|
+
void *x25519_private_pkey;
|
|
54
|
+
} hybrid_decapsulate_expanded_pkey_call_t;
|
|
55
|
+
|
|
56
|
+
typedef struct {
|
|
57
|
+
uint8_t expanded_secret_key[PQ_HYBRID_EXPANDED_SECRETKEYBYTES];
|
|
58
|
+
EVP_PKEY *x25519_private_pkey;
|
|
59
|
+
} hybrid_expanded_key_wrapper_t;
|
|
60
|
+
|
|
39
61
|
typedef struct {
|
|
40
62
|
int result;
|
|
41
63
|
uint8_t *public_key;
|
|
@@ -68,6 +90,49 @@ static VALUE mPQCrypto;
|
|
|
68
90
|
static VALUE ePQCryptoError;
|
|
69
91
|
static VALUE ePQCryptoVerificationError;
|
|
70
92
|
|
|
93
|
+
static void hybrid_expanded_key_wrapper_free(void *ptr) {
|
|
94
|
+
hybrid_expanded_key_wrapper_t *wrapper = (hybrid_expanded_key_wrapper_t *)ptr;
|
|
95
|
+
if (!wrapper) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
pq_secure_wipe(wrapper->expanded_secret_key, sizeof(wrapper->expanded_secret_key));
|
|
99
|
+
if (wrapper->x25519_private_pkey) {
|
|
100
|
+
EVP_PKEY_free(wrapper->x25519_private_pkey);
|
|
101
|
+
wrapper->x25519_private_pkey = NULL;
|
|
102
|
+
}
|
|
103
|
+
xfree(wrapper);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
static size_t hybrid_expanded_key_wrapper_size(const void *ptr) {
|
|
107
|
+
(void)ptr;
|
|
108
|
+
return sizeof(hybrid_expanded_key_wrapper_t);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
static const rb_data_type_t hybrid_expanded_key_data_type = {
|
|
112
|
+
.wrap_struct_name = "PQCrypto::HybridKEM::ExpandedSecretKey",
|
|
113
|
+
.function =
|
|
114
|
+
{
|
|
115
|
+
.dmark = NULL,
|
|
116
|
+
.dfree = hybrid_expanded_key_wrapper_free,
|
|
117
|
+
.dsize = hybrid_expanded_key_wrapper_size,
|
|
118
|
+
.dcompact = NULL,
|
|
119
|
+
.reserved = {NULL},
|
|
120
|
+
},
|
|
121
|
+
.parent = NULL,
|
|
122
|
+
.data = NULL,
|
|
123
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY,
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
static hybrid_expanded_key_wrapper_t *hybrid_expanded_key_unwrap(VALUE obj) {
|
|
127
|
+
hybrid_expanded_key_wrapper_t *wrapper;
|
|
128
|
+
TypedData_Get_Struct(obj, hybrid_expanded_key_wrapper_t, &hybrid_expanded_key_data_type,
|
|
129
|
+
wrapper);
|
|
130
|
+
if (!wrapper || !wrapper->x25519_private_pkey) {
|
|
131
|
+
rb_raise(ePQCryptoError, "hybrid expanded secret key used after release");
|
|
132
|
+
}
|
|
133
|
+
return wrapper;
|
|
134
|
+
}
|
|
135
|
+
|
|
71
136
|
__attribute__((noreturn)) static void pq_raise_general_error(int err);
|
|
72
137
|
|
|
73
138
|
static const char *const PQC_CONTAINER_ALGORITHMS[] = {
|
|
@@ -76,18 +141,35 @@ static const char *const PQC_CONTAINER_ALGORITHMS[] = {
|
|
|
76
141
|
"ml_dsa_65",
|
|
77
142
|
};
|
|
78
143
|
|
|
144
|
+
static ID pqc_container_algorithm_ids[sizeof(PQC_CONTAINER_ALGORITHMS) /
|
|
145
|
+
sizeof(PQC_CONTAINER_ALGORITHMS[0])];
|
|
146
|
+
|
|
147
|
+
static void pq_init_algorithm_ids(void) {
|
|
148
|
+
for (size_t i = 0; i < sizeof(PQC_CONTAINER_ALGORITHMS) / sizeof(PQC_CONTAINER_ALGORITHMS[0]);
|
|
149
|
+
++i) {
|
|
150
|
+
pqc_container_algorithm_ids[i] = rb_intern(PQC_CONTAINER_ALGORITHMS[i]);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
79
154
|
static const char *pq_algorithm_symbol_to_cstr(VALUE algorithm) {
|
|
80
|
-
ID id;
|
|
81
155
|
if (SYMBOL_P(algorithm)) {
|
|
82
|
-
id = SYM2ID(algorithm);
|
|
156
|
+
ID id = SYM2ID(algorithm);
|
|
157
|
+
for (size_t i = 0; i < sizeof(PQC_CONTAINER_ALGORITHMS) / sizeof(PQC_CONTAINER_ALGORITHMS[0]);
|
|
158
|
+
++i) {
|
|
159
|
+
if (id == pqc_container_algorithm_ids[i]) {
|
|
160
|
+
return PQC_CONTAINER_ALGORITHMS[i];
|
|
161
|
+
}
|
|
162
|
+
}
|
|
83
163
|
} else {
|
|
84
164
|
VALUE str = StringValue(algorithm);
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
165
|
+
const char *ptr = RSTRING_PTR(str);
|
|
166
|
+
size_t len = (size_t)RSTRING_LEN(str);
|
|
167
|
+
for (size_t i = 0; i < sizeof(PQC_CONTAINER_ALGORITHMS) / sizeof(PQC_CONTAINER_ALGORITHMS[0]);
|
|
168
|
+
++i) {
|
|
169
|
+
size_t algorithm_len = strlen(PQC_CONTAINER_ALGORITHMS[i]);
|
|
170
|
+
if (len == algorithm_len && memcmp(ptr, PQC_CONTAINER_ALGORITHMS[i], len) == 0) {
|
|
171
|
+
return PQC_CONTAINER_ALGORITHMS[i];
|
|
172
|
+
}
|
|
91
173
|
}
|
|
92
174
|
}
|
|
93
175
|
rb_raise(rb_eArgError, "Unsupported serialization algorithm");
|
|
@@ -97,7 +179,7 @@ static VALUE pq_algorithm_cstr_to_symbol(const char *algorithm) {
|
|
|
97
179
|
for (size_t i = 0; i < sizeof(PQC_CONTAINER_ALGORITHMS) / sizeof(PQC_CONTAINER_ALGORITHMS[0]);
|
|
98
180
|
++i) {
|
|
99
181
|
if (strcmp(algorithm, PQC_CONTAINER_ALGORITHMS[i]) == 0) {
|
|
100
|
-
return ID2SYM(
|
|
182
|
+
return ID2SYM(pqc_container_algorithm_ids[i]);
|
|
101
183
|
}
|
|
102
184
|
}
|
|
103
185
|
rb_raise(rb_eArgError, "Unsupported serialization algorithm");
|
|
@@ -175,6 +257,12 @@ static void *pq_hybrid_kem_encapsulate_nogvl(void *arg) {
|
|
|
175
257
|
return NULL;
|
|
176
258
|
}
|
|
177
259
|
|
|
260
|
+
static void *pq_hybrid_kem_expand_secret_key_nogvl(void *arg) {
|
|
261
|
+
hybrid_expand_call_t *call = (hybrid_expand_call_t *)arg;
|
|
262
|
+
call->result = pq_hybrid_kem_expand_secret_key(call->expanded_secret_key, call->secret_key);
|
|
263
|
+
return NULL;
|
|
264
|
+
}
|
|
265
|
+
|
|
178
266
|
static void *pq_hybrid_kem_decapsulate_nogvl(void *arg) {
|
|
179
267
|
kem_decapsulate_call_t *call = (kem_decapsulate_call_t *)arg;
|
|
180
268
|
call->result =
|
|
@@ -182,6 +270,21 @@ static void *pq_hybrid_kem_decapsulate_nogvl(void *arg) {
|
|
|
182
270
|
return NULL;
|
|
183
271
|
}
|
|
184
272
|
|
|
273
|
+
static void *pq_hybrid_kem_decapsulate_expanded_nogvl(void *arg) {
|
|
274
|
+
kem_decapsulate_call_t *call = (kem_decapsulate_call_t *)arg;
|
|
275
|
+
call->result = pq_hybrid_kem_decapsulate_expanded(call->shared_secret, call->ciphertext,
|
|
276
|
+
call->secret_key);
|
|
277
|
+
return NULL;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
static void *pq_hybrid_kem_decapsulate_expanded_pkey_nogvl(void *arg) {
|
|
281
|
+
hybrid_decapsulate_expanded_pkey_call_t *call =
|
|
282
|
+
(hybrid_decapsulate_expanded_pkey_call_t *)arg;
|
|
283
|
+
call->result = pq_hybrid_kem_decapsulate_expanded_pkey(
|
|
284
|
+
call->shared_secret, call->ciphertext, call->expanded_secret_key, call->x25519_private_pkey);
|
|
285
|
+
return NULL;
|
|
286
|
+
}
|
|
287
|
+
|
|
185
288
|
#define PQ_DEFINE_SIGN_KEYPAIR_NOGVL(rb_name, c_call) \
|
|
186
289
|
static void *pq_##rb_name##_nogvl(void *arg) { \
|
|
187
290
|
sign_keypair_call_t *call = (sign_keypair_call_t *)arg; \
|
|
@@ -640,6 +743,66 @@ static VALUE pqcrypto_hybrid_kem_encapsulate(VALUE self, VALUE public_key) {
|
|
|
640
743
|
PQ_HYBRID_SHAREDSECRETBYTES);
|
|
641
744
|
}
|
|
642
745
|
|
|
746
|
+
static VALUE pqcrypto_hybrid_kem_expand_secret_key(VALUE self, VALUE secret_key) {
|
|
747
|
+
(void)self;
|
|
748
|
+
hybrid_expand_call_t call = {0};
|
|
749
|
+
VALUE result;
|
|
750
|
+
size_t copied_secret_key_len = 0;
|
|
751
|
+
|
|
752
|
+
pq_validate_bytes_argument(secret_key, PQ_HYBRID_SECRETKEYBYTES, "hybrid secret key");
|
|
753
|
+
|
|
754
|
+
call.secret_key = pq_copy_ruby_string(secret_key, &copied_secret_key_len);
|
|
755
|
+
call.expanded_secret_key = pq_alloc_buffer(PQ_HYBRID_EXPANDED_SECRETKEYBYTES);
|
|
756
|
+
|
|
757
|
+
rb_thread_call_without_gvl(pq_hybrid_kem_expand_secret_key_nogvl, &call, NULL, NULL);
|
|
758
|
+
pq_wipe_and_free((uint8_t *)call.secret_key, copied_secret_key_len);
|
|
759
|
+
|
|
760
|
+
if (call.result != PQ_SUCCESS) {
|
|
761
|
+
pq_wipe_and_free(call.expanded_secret_key, PQ_HYBRID_EXPANDED_SECRETKEYBYTES);
|
|
762
|
+
pq_raise_general_error(call.result);
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
result = pq_string_from_buffer(call.expanded_secret_key, PQ_HYBRID_EXPANDED_SECRETKEYBYTES);
|
|
766
|
+
pq_wipe_and_free(call.expanded_secret_key, PQ_HYBRID_EXPANDED_SECRETKEYBYTES);
|
|
767
|
+
return result;
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
static VALUE pqcrypto_hybrid_kem_expand_secret_key_object(VALUE self, VALUE secret_key) {
|
|
771
|
+
(void)self;
|
|
772
|
+
hybrid_expand_call_t call = {0};
|
|
773
|
+
size_t copied_secret_key_len = 0;
|
|
774
|
+
|
|
775
|
+
pq_validate_bytes_argument(secret_key, PQ_HYBRID_SECRETKEYBYTES, "hybrid secret key");
|
|
776
|
+
|
|
777
|
+
hybrid_expanded_key_wrapper_t *wrapper;
|
|
778
|
+
VALUE obj = TypedData_Make_Struct(rb_cObject, hybrid_expanded_key_wrapper_t,
|
|
779
|
+
&hybrid_expanded_key_data_type, wrapper);
|
|
780
|
+
memset(wrapper->expanded_secret_key, 0, sizeof(wrapper->expanded_secret_key));
|
|
781
|
+
wrapper->x25519_private_pkey = NULL;
|
|
782
|
+
|
|
783
|
+
call.secret_key = pq_copy_ruby_string(secret_key, &copied_secret_key_len);
|
|
784
|
+
call.expanded_secret_key = wrapper->expanded_secret_key;
|
|
785
|
+
|
|
786
|
+
rb_thread_call_without_gvl(pq_hybrid_kem_expand_secret_key_nogvl, &call, NULL, NULL);
|
|
787
|
+
pq_wipe_and_free((uint8_t *)call.secret_key, copied_secret_key_len);
|
|
788
|
+
|
|
789
|
+
if (call.result != PQ_SUCCESS) {
|
|
790
|
+
pq_secure_wipe(wrapper->expanded_secret_key, sizeof(wrapper->expanded_secret_key));
|
|
791
|
+
pq_raise_general_error(call.result);
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
const hybrid_expanded_secret_key_t *expanded =
|
|
795
|
+
(const hybrid_expanded_secret_key_t *)wrapper->expanded_secret_key;
|
|
796
|
+
wrapper->x25519_private_pkey = EVP_PKEY_new_raw_private_key(
|
|
797
|
+
EVP_PKEY_X25519, NULL, expanded->x25519_sk, X25519_SECRETKEYBYTES);
|
|
798
|
+
if (!wrapper->x25519_private_pkey) {
|
|
799
|
+
pq_secure_wipe(wrapper->expanded_secret_key, sizeof(wrapper->expanded_secret_key));
|
|
800
|
+
pq_raise_general_error(PQ_ERROR_OPENSSL);
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
return obj;
|
|
804
|
+
}
|
|
805
|
+
|
|
643
806
|
static VALUE pqcrypto_hybrid_kem_decapsulate(VALUE self, VALUE ciphertext, VALUE secret_key) {
|
|
644
807
|
(void)self;
|
|
645
808
|
return pq_run_kem_decapsulate(pq_hybrid_kem_decapsulate_nogvl, ciphertext,
|
|
@@ -647,6 +810,50 @@ static VALUE pqcrypto_hybrid_kem_decapsulate(VALUE self, VALUE ciphertext, VALUE
|
|
|
647
810
|
PQ_HYBRID_SHAREDSECRETBYTES);
|
|
648
811
|
}
|
|
649
812
|
|
|
813
|
+
static VALUE pqcrypto_hybrid_kem_decapsulate_expanded(VALUE self, VALUE ciphertext,
|
|
814
|
+
VALUE expanded_secret_key) {
|
|
815
|
+
(void)self;
|
|
816
|
+
return pq_run_kem_decapsulate(pq_hybrid_kem_decapsulate_expanded_nogvl, ciphertext,
|
|
817
|
+
PQ_HYBRID_CIPHERTEXTBYTES, expanded_secret_key,
|
|
818
|
+
PQ_HYBRID_EXPANDED_SECRETKEYBYTES,
|
|
819
|
+
PQ_HYBRID_SHAREDSECRETBYTES);
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
static VALUE pqcrypto_hybrid_kem_decapsulate_expanded_object(VALUE self, VALUE ciphertext,
|
|
823
|
+
VALUE expanded_secret_key_obj) {
|
|
824
|
+
(void)self;
|
|
825
|
+
hybrid_expanded_key_wrapper_t *wrapper = hybrid_expanded_key_unwrap(expanded_secret_key_obj);
|
|
826
|
+
hybrid_decapsulate_expanded_pkey_call_t call = {0};
|
|
827
|
+
VALUE result;
|
|
828
|
+
size_t copied_ciphertext_len = 0;
|
|
829
|
+
|
|
830
|
+
pq_validate_bytes_argument(ciphertext, PQ_HYBRID_CIPHERTEXTBYTES, "ciphertext");
|
|
831
|
+
|
|
832
|
+
call.ciphertext = pq_copy_ruby_string(ciphertext, &copied_ciphertext_len);
|
|
833
|
+
call.expanded_secret_key = wrapper->expanded_secret_key;
|
|
834
|
+
call.shared_secret = pq_alloc_buffer(PQ_HYBRID_SHAREDSECRETBYTES);
|
|
835
|
+
|
|
836
|
+
if (EVP_PKEY_up_ref(wrapper->x25519_private_pkey) != 1) {
|
|
837
|
+
pq_wipe_and_free((uint8_t *)call.ciphertext, copied_ciphertext_len);
|
|
838
|
+
pq_wipe_and_free(call.shared_secret, PQ_HYBRID_SHAREDSECRETBYTES);
|
|
839
|
+
pq_raise_general_error(PQ_ERROR_OPENSSL);
|
|
840
|
+
}
|
|
841
|
+
call.x25519_private_pkey = wrapper->x25519_private_pkey;
|
|
842
|
+
|
|
843
|
+
rb_thread_call_without_gvl(pq_hybrid_kem_decapsulate_expanded_pkey_nogvl, &call, NULL, NULL);
|
|
844
|
+
EVP_PKEY_free((EVP_PKEY *)call.x25519_private_pkey);
|
|
845
|
+
pq_wipe_and_free((uint8_t *)call.ciphertext, copied_ciphertext_len);
|
|
846
|
+
|
|
847
|
+
if (call.result != PQ_SUCCESS) {
|
|
848
|
+
pq_wipe_and_free(call.shared_secret, PQ_HYBRID_SHAREDSECRETBYTES);
|
|
849
|
+
pq_raise_general_error(call.result);
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
result = pq_string_from_buffer(call.shared_secret, PQ_HYBRID_SHAREDSECRETBYTES);
|
|
853
|
+
pq_wipe_and_free(call.shared_secret, PQ_HYBRID_SHAREDSECRETBYTES);
|
|
854
|
+
return result;
|
|
855
|
+
}
|
|
856
|
+
|
|
650
857
|
static VALUE pqcrypto__test_ml_kem_keypair_from_seed(VALUE self, VALUE seed) {
|
|
651
858
|
(void)self;
|
|
652
859
|
StringValue(seed);
|
|
@@ -1220,6 +1427,15 @@ static VALUE pqcrypto__native_mldsa_mu_builder_update(VALUE self, VALUE builder_
|
|
|
1220
1427
|
return Qnil;
|
|
1221
1428
|
}
|
|
1222
1429
|
|
|
1430
|
+
if (chunk_len < PQ_MU_ABSORB_NOGVL_MIN_BYTES) {
|
|
1431
|
+
int rc = pq_mu_builder_absorb(wrapper->builder, (const uint8_t *)RSTRING_PTR(chunk),
|
|
1432
|
+
chunk_len);
|
|
1433
|
+
if (rc != PQ_SUCCESS) {
|
|
1434
|
+
pq_raise_general_error(rc);
|
|
1435
|
+
}
|
|
1436
|
+
return Qnil;
|
|
1437
|
+
}
|
|
1438
|
+
|
|
1223
1439
|
uint8_t *copy = pq_alloc_buffer(chunk_len);
|
|
1224
1440
|
memcpy(copy, RSTRING_PTR(chunk), chunk_len);
|
|
1225
1441
|
|
|
@@ -1432,6 +1648,7 @@ static VALUE pqcrypto_secret_key_from_pqc_container_pem(VALUE self, VALUE pem) {
|
|
|
1432
1648
|
|
|
1433
1649
|
void Init_pqcrypto_secure(void) {
|
|
1434
1650
|
mPQCrypto = rb_define_module("PQCrypto");
|
|
1651
|
+
pq_init_algorithm_ids();
|
|
1435
1652
|
ePQCryptoError = rb_define_class_under(mPQCrypto, "Error", rb_eStandardError);
|
|
1436
1653
|
|
|
1437
1654
|
ePQCryptoVerificationError =
|
|
@@ -1478,8 +1695,16 @@ void Init_pqcrypto_secure(void) {
|
|
|
1478
1695
|
rb_define_module_function(mPQCrypto, "hybrid_kem_keypair", pqcrypto_hybrid_kem_keypair, 0);
|
|
1479
1696
|
rb_define_module_function(mPQCrypto, "hybrid_kem_encapsulate", pqcrypto_hybrid_kem_encapsulate,
|
|
1480
1697
|
1);
|
|
1698
|
+
rb_define_module_function(mPQCrypto, "hybrid_kem_expand_secret_key",
|
|
1699
|
+
pqcrypto_hybrid_kem_expand_secret_key, 1);
|
|
1700
|
+
rb_define_module_function(mPQCrypto, "hybrid_kem_expand_secret_key_object",
|
|
1701
|
+
pqcrypto_hybrid_kem_expand_secret_key_object, 1);
|
|
1481
1702
|
rb_define_module_function(mPQCrypto, "hybrid_kem_decapsulate", pqcrypto_hybrid_kem_decapsulate,
|
|
1482
1703
|
2);
|
|
1704
|
+
rb_define_module_function(mPQCrypto, "hybrid_kem_decapsulate_expanded",
|
|
1705
|
+
pqcrypto_hybrid_kem_decapsulate_expanded, 2);
|
|
1706
|
+
rb_define_module_function(mPQCrypto, "hybrid_kem_decapsulate_expanded_object",
|
|
1707
|
+
pqcrypto_hybrid_kem_decapsulate_expanded_object, 2);
|
|
1483
1708
|
rb_define_module_function(mPQCrypto, "sign_keypair", pqcrypto_sign_keypair, 0);
|
|
1484
1709
|
rb_define_module_function(mPQCrypto, "sign", pqcrypto_sign, 2);
|
|
1485
1710
|
rb_define_module_function(mPQCrypto, "verify", pqcrypto_verify, 3);
|