pq_crypto 0.5.3 → 0.6.0
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/CHANGELOG.md +11 -0
- data/GET_STARTED.md +70 -9
- data/README.md +11 -6
- data/ext/pqcrypto/pq_externalmu.c +23 -18
- data/ext/pqcrypto/pqcrypto_native_api.h +10 -0
- data/ext/pqcrypto/pqcrypto_ruby_secure.c +212 -48
- data/ext/pqcrypto/pqcrypto_secure.c +83 -84
- data/ext/pqcrypto/pqcrypto_secure.h +15 -10
- data/ext/pqcrypto/pqcrypto_version.h +1 -1
- data/lib/pq_crypto/hybrid_kem.rb +1 -0
- data/lib/pq_crypto/kem.rb +71 -29
- data/lib/pq_crypto/key.rb +90 -0
- data/lib/pq_crypto/pkcs8.rb +184 -10
- data/lib/pq_crypto/signature.rb +74 -37
- data/lib/pq_crypto/version.rb +1 -1
- data/lib/pq_crypto.rb +6 -4
- metadata +7 -3
|
@@ -81,6 +81,8 @@ typedef struct {
|
|
|
81
81
|
size_t signature_len;
|
|
82
82
|
uint8_t *message;
|
|
83
83
|
size_t message_len;
|
|
84
|
+
uint8_t *context;
|
|
85
|
+
size_t context_len;
|
|
84
86
|
const uint8_t *secret_key;
|
|
85
87
|
const uint8_t *seed;
|
|
86
88
|
size_t seed_len;
|
|
@@ -92,6 +94,8 @@ typedef struct {
|
|
|
92
94
|
size_t signature_len;
|
|
93
95
|
uint8_t *message;
|
|
94
96
|
size_t message_len;
|
|
97
|
+
uint8_t *context;
|
|
98
|
+
size_t context_len;
|
|
95
99
|
const uint8_t *public_key;
|
|
96
100
|
} verify_call_t;
|
|
97
101
|
|
|
@@ -153,6 +157,52 @@ static const char *const PQC_CONTAINER_ALGORITHMS[] = {
|
|
|
153
157
|
static ID pqc_container_algorithm_ids[sizeof(PQC_CONTAINER_ALGORITHMS) /
|
|
154
158
|
sizeof(PQC_CONTAINER_ALGORITHMS[0])];
|
|
155
159
|
|
|
160
|
+
typedef int (*pq_mldsa_pk_from_sk_fn)(uint8_t *, const uint8_t *);
|
|
161
|
+
typedef int (*pq_mldsa_signature_extmu_fn)(uint8_t *, size_t *, const uint8_t *, const uint8_t *);
|
|
162
|
+
typedef int (*pq_mldsa_verify_extmu_fn)(const uint8_t *, size_t, const uint8_t *, const uint8_t *);
|
|
163
|
+
|
|
164
|
+
typedef struct {
|
|
165
|
+
const char *name;
|
|
166
|
+
size_t public_key_len;
|
|
167
|
+
size_t secret_key_len;
|
|
168
|
+
size_t signature_len;
|
|
169
|
+
pq_mldsa_pk_from_sk_fn pk_from_sk;
|
|
170
|
+
pq_mldsa_signature_extmu_fn signature_extmu;
|
|
171
|
+
pq_mldsa_verify_extmu_fn verify_extmu;
|
|
172
|
+
} pq_mldsa_profile_t;
|
|
173
|
+
|
|
174
|
+
static const pq_mldsa_profile_t MLDSA_PROFILES[] = {
|
|
175
|
+
{"ml_dsa_44", MLDSA44_PUBLICKEYBYTES, MLDSA44_SECRETKEYBYTES, MLDSA44_BYTES,
|
|
176
|
+
pqcr_mldsa44_pk_from_sk, pqcr_mldsa44_signature_extmu, pqcr_mldsa44_verify_extmu},
|
|
177
|
+
{"ml_dsa_65", MLDSA65_PUBLICKEYBYTES, MLDSA65_SECRETKEYBYTES, MLDSA65_BYTES,
|
|
178
|
+
pqcr_mldsa65_pk_from_sk, pqcr_mldsa65_signature_extmu, pqcr_mldsa65_verify_extmu},
|
|
179
|
+
{"ml_dsa_87", MLDSA87_PUBLICKEYBYTES, MLDSA87_SECRETKEYBYTES, MLDSA87_BYTES,
|
|
180
|
+
pqcr_mldsa87_pk_from_sk, pqcr_mldsa87_signature_extmu, pqcr_mldsa87_verify_extmu},
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
static const pq_mldsa_profile_t *pq_mldsa_profile_from_value(VALUE algorithm) {
|
|
184
|
+
ID id;
|
|
185
|
+
const char *name;
|
|
186
|
+
|
|
187
|
+
if (!SYMBOL_P(algorithm)) {
|
|
188
|
+
rb_raise(rb_eArgError, "ML-DSA algorithm must be a Symbol");
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
id = SYM2ID(algorithm);
|
|
192
|
+
name = rb_id2name(id);
|
|
193
|
+
if (!name) {
|
|
194
|
+
rb_raise(rb_eArgError, "Invalid ML-DSA algorithm symbol");
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
for (size_t i = 0; i < sizeof(MLDSA_PROFILES) / sizeof(MLDSA_PROFILES[0]); ++i) {
|
|
198
|
+
if (strcmp(name, MLDSA_PROFILES[i].name) == 0) {
|
|
199
|
+
return &MLDSA_PROFILES[i];
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
rb_raise(ePQCryptoError, "Unsupported ML-DSA algorithm: %s", name);
|
|
204
|
+
}
|
|
205
|
+
|
|
156
206
|
static void pq_init_algorithm_ids(void) {
|
|
157
207
|
for (size_t i = 0; i < sizeof(PQC_CONTAINER_ALGORITHMS) / sizeof(PQC_CONTAINER_ALGORITHMS[0]);
|
|
158
208
|
++i) {
|
|
@@ -320,12 +370,13 @@ PQ_DEFINE_SIGN_KEYPAIR_FROM_SEED_NOGVL(mldsa_87_keypair_from_seed, pq_mldsa87_ke
|
|
|
320
370
|
|
|
321
371
|
#undef PQ_DEFINE_SIGN_KEYPAIR_FROM_SEED_NOGVL
|
|
322
372
|
|
|
323
|
-
#define PQ_DEFINE_SIGN_NOGVL(rb_name, c_call)
|
|
324
|
-
static void *pq_##rb_name##_nogvl(void *arg) {
|
|
325
|
-
sign_call_t *call = (sign_call_t *)arg;
|
|
326
|
-
call->result =
|
|
327
|
-
|
|
328
|
-
|
|
373
|
+
#define PQ_DEFINE_SIGN_NOGVL(rb_name, c_call) \
|
|
374
|
+
static void *pq_##rb_name##_nogvl(void *arg) { \
|
|
375
|
+
sign_call_t *call = (sign_call_t *)arg; \
|
|
376
|
+
call->result = \
|
|
377
|
+
c_call(call->signature, &call->signature_len, call->message, call->message_len, \
|
|
378
|
+
call->context, call->context_len, call->secret_key); \
|
|
379
|
+
return NULL; \
|
|
329
380
|
}
|
|
330
381
|
|
|
331
382
|
PQ_DEFINE_SIGN_NOGVL(sign, pq_sign)
|
|
@@ -373,12 +424,13 @@ PQ_DEFINE_TESTING_SIGN_FROM_SEED(mldsa_87, pq_testing_mldsa87_sign_from_seed)
|
|
|
373
424
|
#undef PQ_DEFINE_TESTING_KEYPAIR_FROM_SEED
|
|
374
425
|
#undef PQ_DEFINE_TESTING_SIGN_FROM_SEED
|
|
375
426
|
|
|
376
|
-
#define PQ_DEFINE_VERIFY_NOGVL(rb_name, c_call)
|
|
377
|
-
static void *pq_##rb_name##_nogvl(void *arg) {
|
|
378
|
-
verify_call_t *call = (verify_call_t *)arg;
|
|
379
|
-
call->result =
|
|
380
|
-
|
|
381
|
-
|
|
427
|
+
#define PQ_DEFINE_VERIFY_NOGVL(rb_name, c_call) \
|
|
428
|
+
static void *pq_##rb_name##_nogvl(void *arg) { \
|
|
429
|
+
verify_call_t *call = (verify_call_t *)arg; \
|
|
430
|
+
call->result = \
|
|
431
|
+
c_call(call->signature, call->signature_len, call->message, call->message_len, \
|
|
432
|
+
call->context, call->context_len, call->public_key); \
|
|
433
|
+
return NULL; \
|
|
382
434
|
}
|
|
383
435
|
|
|
384
436
|
PQ_DEFINE_VERIFY_NOGVL(verify, pq_verify)
|
|
@@ -812,6 +864,26 @@ static VALUE pqcrypto_hybrid_kem_expand_secret_key_object(VALUE self, VALUE secr
|
|
|
812
864
|
return obj;
|
|
813
865
|
}
|
|
814
866
|
|
|
867
|
+
static VALUE pqcrypto_hybrid_kem_expanded_secret_key_wipe(VALUE self,
|
|
868
|
+
VALUE expanded_secret_key_obj) {
|
|
869
|
+
(void)self;
|
|
870
|
+
hybrid_expanded_key_wrapper_t *wrapper;
|
|
871
|
+
|
|
872
|
+
TypedData_Get_Struct(expanded_secret_key_obj, hybrid_expanded_key_wrapper_t,
|
|
873
|
+
&hybrid_expanded_key_data_type, wrapper);
|
|
874
|
+
if (!wrapper) {
|
|
875
|
+
return Qnil;
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
pq_secure_wipe(wrapper->expanded_secret_key, sizeof(wrapper->expanded_secret_key));
|
|
879
|
+
if (wrapper->x25519_private_pkey) {
|
|
880
|
+
EVP_PKEY_free(wrapper->x25519_private_pkey);
|
|
881
|
+
wrapper->x25519_private_pkey = NULL;
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
return Qnil;
|
|
885
|
+
}
|
|
886
|
+
|
|
815
887
|
static VALUE pqcrypto_hybrid_kem_decapsulate(VALUE self, VALUE ciphertext, VALUE secret_key) {
|
|
816
888
|
(void)self;
|
|
817
889
|
return pq_run_kem_decapsulate(pq_hybrid_kem_decapsulate_nogvl, ciphertext,
|
|
@@ -1181,20 +1253,28 @@ PQ_DEFINE_RUBY_MLDSA_KEYPAIR(ml_dsa_87_keypair, mldsa_87_sign_keypair, MLDSA87_P
|
|
|
1181
1253
|
|
|
1182
1254
|
#undef PQ_DEFINE_RUBY_MLDSA_KEYPAIR
|
|
1183
1255
|
|
|
1184
|
-
static VALUE pq_run_sign(void *(*nogvl)(void *), VALUE message, VALUE secret_key,
|
|
1256
|
+
static VALUE pq_run_sign(void *(*nogvl)(void *), VALUE message, VALUE secret_key, VALUE context,
|
|
1185
1257
|
size_t secret_key_len_expected, size_t signature_len_expected) {
|
|
1186
1258
|
pq_validate_bytes_argument(secret_key, secret_key_len_expected, "secret key");
|
|
1259
|
+
StringValue(context);
|
|
1260
|
+
if (RSTRING_LEN(context) > 255) {
|
|
1261
|
+
rb_raise(rb_eArgError, "ML-DSA context length must be <= 255 bytes");
|
|
1262
|
+
}
|
|
1187
1263
|
|
|
1188
1264
|
sign_call_t call = {0};
|
|
1189
1265
|
size_t secret_key_len = 0;
|
|
1266
|
+
size_t context_len = 0;
|
|
1190
1267
|
call.secret_key = pq_copy_ruby_string(secret_key, &secret_key_len);
|
|
1191
1268
|
call.signature_len = signature_len_expected;
|
|
1192
1269
|
call.signature = pq_alloc_buffer(signature_len_expected);
|
|
1193
1270
|
call.message = pq_copy_ruby_string(message, &call.message_len);
|
|
1271
|
+
call.context = pq_copy_ruby_string(context, &context_len);
|
|
1272
|
+
call.context_len = context_len;
|
|
1194
1273
|
|
|
1195
1274
|
rb_nogvl(nogvl, &call, NULL, NULL, PQ_RB_NOGVL_OFFLOAD_SAFE);
|
|
1196
1275
|
|
|
1197
1276
|
pq_free_buffer(call.message);
|
|
1277
|
+
pq_free_buffer(call.context);
|
|
1198
1278
|
pq_wipe_and_free((uint8_t *)call.secret_key, secret_key_len);
|
|
1199
1279
|
|
|
1200
1280
|
if (call.result != PQ_SUCCESS) {
|
|
@@ -1207,10 +1287,16 @@ static VALUE pq_run_sign(void *(*nogvl)(void *), VALUE message, VALUE secret_key
|
|
|
1207
1287
|
return result;
|
|
1208
1288
|
}
|
|
1209
1289
|
|
|
1210
|
-
#define PQ_DEFINE_RUBY_MLDSA_SIGN(rb_name, nogvl_stem, sk_bytes, sig_bytes)
|
|
1211
|
-
static VALUE pqcrypto_##rb_name(
|
|
1212
|
-
(void)self;
|
|
1213
|
-
|
|
1290
|
+
#define PQ_DEFINE_RUBY_MLDSA_SIGN(rb_name, nogvl_stem, sk_bytes, sig_bytes) \
|
|
1291
|
+
static VALUE pqcrypto_##rb_name(int argc, VALUE *argv, VALUE self) { \
|
|
1292
|
+
(void)self; \
|
|
1293
|
+
VALUE message, secret_key, context; \
|
|
1294
|
+
rb_scan_args(argc, argv, "21", &message, &secret_key, &context); \
|
|
1295
|
+
if (NIL_P(context)) { \
|
|
1296
|
+
context = rb_str_new("", 0); \
|
|
1297
|
+
} \
|
|
1298
|
+
return pq_run_sign(pq_##nogvl_stem##_nogvl, message, secret_key, context, sk_bytes, \
|
|
1299
|
+
sig_bytes); \
|
|
1214
1300
|
}
|
|
1215
1301
|
|
|
1216
1302
|
PQ_DEFINE_RUBY_MLDSA_SIGN(sign, sign, PQ_MLDSA_SECRETKEYBYTES, PQ_MLDSA_BYTES)
|
|
@@ -1220,21 +1306,29 @@ PQ_DEFINE_RUBY_MLDSA_SIGN(ml_dsa_87_sign, mldsa_87_sign, MLDSA87_SECRETKEYBYTES,
|
|
|
1220
1306
|
#undef PQ_DEFINE_RUBY_MLDSA_SIGN
|
|
1221
1307
|
|
|
1222
1308
|
static VALUE pq_run_verify(void *(*nogvl)(void *), VALUE message, VALUE signature, VALUE public_key,
|
|
1223
|
-
size_t public_key_len_expected) {
|
|
1309
|
+
VALUE context, size_t public_key_len_expected) {
|
|
1224
1310
|
StringValue(signature);
|
|
1225
1311
|
pq_validate_bytes_argument(public_key, public_key_len_expected, "public key");
|
|
1312
|
+
StringValue(context);
|
|
1313
|
+
if (RSTRING_LEN(context) > 255) {
|
|
1314
|
+
rb_raise(rb_eArgError, "ML-DSA context length must be <= 255 bytes");
|
|
1315
|
+
}
|
|
1226
1316
|
|
|
1227
1317
|
verify_call_t call = {0};
|
|
1228
1318
|
size_t public_key_len = 0;
|
|
1229
1319
|
size_t signature_len = 0;
|
|
1320
|
+
size_t context_len = 0;
|
|
1230
1321
|
call.public_key = pq_copy_ruby_string(public_key, &public_key_len);
|
|
1231
1322
|
call.signature = pq_copy_ruby_string(signature, &signature_len);
|
|
1232
1323
|
call.signature_len = signature_len;
|
|
1233
1324
|
call.message = pq_copy_ruby_string(message, &call.message_len);
|
|
1325
|
+
call.context = pq_copy_ruby_string(context, &context_len);
|
|
1326
|
+
call.context_len = context_len;
|
|
1234
1327
|
|
|
1235
1328
|
rb_nogvl(nogvl, &call, NULL, NULL, PQ_RB_NOGVL_OFFLOAD_SAFE);
|
|
1236
1329
|
|
|
1237
1330
|
pq_free_buffer(call.message);
|
|
1331
|
+
pq_free_buffer(call.context);
|
|
1238
1332
|
pq_free_buffer((uint8_t *)call.public_key);
|
|
1239
1333
|
pq_free_buffer((uint8_t *)call.signature);
|
|
1240
1334
|
|
|
@@ -1247,11 +1341,16 @@ static VALUE pq_run_verify(void *(*nogvl)(void *), VALUE message, VALUE signatur
|
|
|
1247
1341
|
pq_raise_general_error(call.result);
|
|
1248
1342
|
}
|
|
1249
1343
|
|
|
1250
|
-
#define PQ_DEFINE_RUBY_MLDSA_VERIFY(rb_name, nogvl_stem, pk_bytes)
|
|
1251
|
-
static VALUE pqcrypto_##rb_name(
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1344
|
+
#define PQ_DEFINE_RUBY_MLDSA_VERIFY(rb_name, nogvl_stem, pk_bytes) \
|
|
1345
|
+
static VALUE pqcrypto_##rb_name(int argc, VALUE *argv, VALUE self) { \
|
|
1346
|
+
(void)self; \
|
|
1347
|
+
VALUE message, signature, public_key, context; \
|
|
1348
|
+
rb_scan_args(argc, argv, "31", &message, &signature, &public_key, &context); \
|
|
1349
|
+
if (NIL_P(context)) { \
|
|
1350
|
+
context = rb_str_new("", 0); \
|
|
1351
|
+
} \
|
|
1352
|
+
return pq_run_verify(pq_##nogvl_stem##_nogvl, message, signature, public_key, context, \
|
|
1353
|
+
pk_bytes); \
|
|
1255
1354
|
}
|
|
1256
1355
|
|
|
1257
1356
|
PQ_DEFINE_RUBY_MLDSA_VERIFY(verify, verify, PQ_MLDSA_PUBLICKEYBYTES)
|
|
@@ -1312,6 +1411,7 @@ typedef struct {
|
|
|
1312
1411
|
size_t signature_len;
|
|
1313
1412
|
const uint8_t *mu;
|
|
1314
1413
|
const uint8_t *secret_key;
|
|
1414
|
+
pq_mldsa_signature_extmu_fn signature_extmu;
|
|
1315
1415
|
} sign_mu_call_t;
|
|
1316
1416
|
|
|
1317
1417
|
typedef struct {
|
|
@@ -1320,6 +1420,8 @@ typedef struct {
|
|
|
1320
1420
|
size_t signature_len;
|
|
1321
1421
|
const uint8_t *mu;
|
|
1322
1422
|
const uint8_t *public_key;
|
|
1423
|
+
size_t expected_signature_len;
|
|
1424
|
+
pq_mldsa_verify_extmu_fn verify_extmu;
|
|
1323
1425
|
} verify_mu_call_t;
|
|
1324
1426
|
|
|
1325
1427
|
static void mu_builder_wrapper_free(void *ptr) {
|
|
@@ -1363,12 +1465,25 @@ static mu_builder_wrapper_t *mu_builder_unwrap(VALUE obj) {
|
|
|
1363
1465
|
return wrapper;
|
|
1364
1466
|
}
|
|
1365
1467
|
|
|
1366
|
-
static VALUE pqcrypto__native_mldsa_extract_tr(VALUE
|
|
1468
|
+
static VALUE pqcrypto__native_mldsa_extract_tr(int argc, VALUE *argv, VALUE self) {
|
|
1367
1469
|
(void)self;
|
|
1368
|
-
|
|
1470
|
+
VALUE algorithm = ID2SYM(rb_intern("ml_dsa_65"));
|
|
1471
|
+
VALUE secret_key;
|
|
1472
|
+
if (argc == 1) {
|
|
1473
|
+
secret_key = argv[0];
|
|
1474
|
+
} else if (argc == 2) {
|
|
1475
|
+
algorithm = argv[0];
|
|
1476
|
+
secret_key = argv[1];
|
|
1477
|
+
} else {
|
|
1478
|
+
rb_raise(rb_eArgError, "wrong number of arguments (given %d, expected 1..2)", argc);
|
|
1479
|
+
}
|
|
1480
|
+
|
|
1481
|
+
const pq_mldsa_profile_t *profile = pq_mldsa_profile_from_value(algorithm);
|
|
1482
|
+
pq_validate_bytes_argument(secret_key, profile->secret_key_len, "secret key");
|
|
1369
1483
|
|
|
1370
1484
|
uint8_t tr[PQ_MLDSA_TRBYTES];
|
|
1371
|
-
int rc = pq_mldsa_extract_tr_from_secret_key(tr, (const uint8_t *)RSTRING_PTR(secret_key)
|
|
1485
|
+
int rc = pq_mldsa_extract_tr_from_secret_key(tr, (const uint8_t *)RSTRING_PTR(secret_key),
|
|
1486
|
+
profile->public_key_len, profile->pk_from_sk);
|
|
1372
1487
|
if (rc != PQ_SUCCESS) {
|
|
1373
1488
|
pq_secure_wipe(tr, sizeof(tr));
|
|
1374
1489
|
pq_raise_general_error(rc);
|
|
@@ -1378,12 +1493,25 @@ static VALUE pqcrypto__native_mldsa_extract_tr(VALUE self, VALUE secret_key) {
|
|
|
1378
1493
|
return result;
|
|
1379
1494
|
}
|
|
1380
1495
|
|
|
1381
|
-
static VALUE pqcrypto__native_mldsa_compute_tr(VALUE
|
|
1496
|
+
static VALUE pqcrypto__native_mldsa_compute_tr(int argc, VALUE *argv, VALUE self) {
|
|
1382
1497
|
(void)self;
|
|
1383
|
-
|
|
1498
|
+
VALUE algorithm = ID2SYM(rb_intern("ml_dsa_65"));
|
|
1499
|
+
VALUE public_key;
|
|
1500
|
+
if (argc == 1) {
|
|
1501
|
+
public_key = argv[0];
|
|
1502
|
+
} else if (argc == 2) {
|
|
1503
|
+
algorithm = argv[0];
|
|
1504
|
+
public_key = argv[1];
|
|
1505
|
+
} else {
|
|
1506
|
+
rb_raise(rb_eArgError, "wrong number of arguments (given %d, expected 1..2)", argc);
|
|
1507
|
+
}
|
|
1508
|
+
|
|
1509
|
+
const pq_mldsa_profile_t *profile = pq_mldsa_profile_from_value(algorithm);
|
|
1510
|
+
pq_validate_bytes_argument(public_key, profile->public_key_len, "public key");
|
|
1384
1511
|
|
|
1385
1512
|
uint8_t tr[PQ_MLDSA_TRBYTES];
|
|
1386
|
-
int rc = pq_mldsa_compute_tr_from_public_key(tr, (const uint8_t *)RSTRING_PTR(public_key)
|
|
1513
|
+
int rc = pq_mldsa_compute_tr_from_public_key(tr, (const uint8_t *)RSTRING_PTR(public_key),
|
|
1514
|
+
profile->public_key_len);
|
|
1387
1515
|
if (rc != PQ_SUCCESS) {
|
|
1388
1516
|
pq_raise_general_error(rc);
|
|
1389
1517
|
}
|
|
@@ -1504,14 +1632,29 @@ static VALUE pqcrypto__native_mldsa_mu_builder_release(VALUE self, VALUE builder
|
|
|
1504
1632
|
|
|
1505
1633
|
static void *pq_sign_mu_nogvl(void *arg) {
|
|
1506
1634
|
sign_mu_call_t *call = (sign_mu_call_t *)arg;
|
|
1507
|
-
call->result = pq_sign_mu(call->signature, &call->signature_len, call->mu, call->secret_key
|
|
1635
|
+
call->result = pq_sign_mu(call->signature, &call->signature_len, call->mu, call->secret_key,
|
|
1636
|
+
call->signature_extmu);
|
|
1508
1637
|
return NULL;
|
|
1509
1638
|
}
|
|
1510
1639
|
|
|
1511
|
-
static VALUE pqcrypto__native_mldsa_sign_mu(
|
|
1640
|
+
static VALUE pqcrypto__native_mldsa_sign_mu(int argc, VALUE *argv, VALUE self) {
|
|
1512
1641
|
(void)self;
|
|
1642
|
+
VALUE algorithm = ID2SYM(rb_intern("ml_dsa_65"));
|
|
1643
|
+
VALUE mu, secret_key;
|
|
1644
|
+
if (argc == 2) {
|
|
1645
|
+
mu = argv[0];
|
|
1646
|
+
secret_key = argv[1];
|
|
1647
|
+
} else if (argc == 3) {
|
|
1648
|
+
algorithm = argv[0];
|
|
1649
|
+
mu = argv[1];
|
|
1650
|
+
secret_key = argv[2];
|
|
1651
|
+
} else {
|
|
1652
|
+
rb_raise(rb_eArgError, "wrong number of arguments (given %d, expected 2..3)", argc);
|
|
1653
|
+
}
|
|
1654
|
+
|
|
1655
|
+
const pq_mldsa_profile_t *profile = pq_mldsa_profile_from_value(algorithm);
|
|
1513
1656
|
pq_validate_bytes_argument(mu, PQ_MLDSA_MUBYTES, "mu");
|
|
1514
|
-
pq_validate_bytes_argument(secret_key,
|
|
1657
|
+
pq_validate_bytes_argument(secret_key, profile->secret_key_len, "secret key");
|
|
1515
1658
|
|
|
1516
1659
|
sign_mu_call_t call = {0};
|
|
1517
1660
|
size_t secret_key_len = 0;
|
|
@@ -1521,8 +1664,9 @@ static VALUE pqcrypto__native_mldsa_sign_mu(VALUE self, VALUE mu, VALUE secret_k
|
|
|
1521
1664
|
|
|
1522
1665
|
call.mu = mu_copy;
|
|
1523
1666
|
call.secret_key = sk_copy;
|
|
1524
|
-
call.
|
|
1525
|
-
call.
|
|
1667
|
+
call.signature_extmu = profile->signature_extmu;
|
|
1668
|
+
call.signature_len = profile->signature_len;
|
|
1669
|
+
call.signature = pq_alloc_buffer(profile->signature_len);
|
|
1526
1670
|
|
|
1527
1671
|
rb_nogvl(pq_sign_mu_nogvl, &call, NULL, NULL, PQ_RB_NOGVL_OFFLOAD_SAFE);
|
|
1528
1672
|
|
|
@@ -1541,16 +1685,32 @@ static VALUE pqcrypto__native_mldsa_sign_mu(VALUE self, VALUE mu, VALUE secret_k
|
|
|
1541
1685
|
|
|
1542
1686
|
static void *pq_verify_mu_nogvl(void *arg) {
|
|
1543
1687
|
verify_mu_call_t *call = (verify_mu_call_t *)arg;
|
|
1544
|
-
call->result = pq_verify_mu(call->signature, call->signature_len, call->mu, call->public_key
|
|
1688
|
+
call->result = pq_verify_mu(call->signature, call->signature_len, call->mu, call->public_key,
|
|
1689
|
+
call->expected_signature_len, call->verify_extmu);
|
|
1545
1690
|
return NULL;
|
|
1546
1691
|
}
|
|
1547
1692
|
|
|
1548
|
-
static VALUE pqcrypto__native_mldsa_verify_mu(
|
|
1549
|
-
VALUE public_key) {
|
|
1693
|
+
static VALUE pqcrypto__native_mldsa_verify_mu(int argc, VALUE *argv, VALUE self) {
|
|
1550
1694
|
(void)self;
|
|
1695
|
+
VALUE algorithm = ID2SYM(rb_intern("ml_dsa_65"));
|
|
1696
|
+
VALUE mu, signature, public_key;
|
|
1697
|
+
if (argc == 3) {
|
|
1698
|
+
mu = argv[0];
|
|
1699
|
+
signature = argv[1];
|
|
1700
|
+
public_key = argv[2];
|
|
1701
|
+
} else if (argc == 4) {
|
|
1702
|
+
algorithm = argv[0];
|
|
1703
|
+
mu = argv[1];
|
|
1704
|
+
signature = argv[2];
|
|
1705
|
+
public_key = argv[3];
|
|
1706
|
+
} else {
|
|
1707
|
+
rb_raise(rb_eArgError, "wrong number of arguments (given %d, expected 3..4)", argc);
|
|
1708
|
+
}
|
|
1709
|
+
|
|
1710
|
+
const pq_mldsa_profile_t *profile = pq_mldsa_profile_from_value(algorithm);
|
|
1551
1711
|
StringValue(signature);
|
|
1552
1712
|
pq_validate_bytes_argument(mu, PQ_MLDSA_MUBYTES, "mu");
|
|
1553
|
-
pq_validate_bytes_argument(public_key,
|
|
1713
|
+
pq_validate_bytes_argument(public_key, profile->public_key_len, "public key");
|
|
1554
1714
|
|
|
1555
1715
|
verify_mu_call_t call = {0};
|
|
1556
1716
|
size_t public_key_len = 0;
|
|
@@ -1564,6 +1724,8 @@ static VALUE pqcrypto__native_mldsa_verify_mu(VALUE self, VALUE mu, VALUE signat
|
|
|
1564
1724
|
call.public_key = pk_copy;
|
|
1565
1725
|
call.signature = sig_copy;
|
|
1566
1726
|
call.signature_len = signature_len;
|
|
1727
|
+
call.expected_signature_len = profile->signature_len;
|
|
1728
|
+
call.verify_extmu = profile->verify_extmu;
|
|
1567
1729
|
|
|
1568
1730
|
rb_nogvl(pq_verify_mu_nogvl, &call, NULL, NULL, PQ_RB_NOGVL_OFFLOAD_SAFE);
|
|
1569
1731
|
pq_wipe_and_free(mu_copy, mu_len);
|
|
@@ -1707,6 +1869,8 @@ void Init_pqcrypto_secure(void) {
|
|
|
1707
1869
|
pqcrypto_hybrid_kem_expand_secret_key, 1);
|
|
1708
1870
|
rb_define_module_function(mPQCrypto, "hybrid_kem_expand_secret_key_object",
|
|
1709
1871
|
pqcrypto_hybrid_kem_expand_secret_key_object, 1);
|
|
1872
|
+
rb_define_module_function(mPQCrypto, "hybrid_kem_expanded_secret_key_wipe",
|
|
1873
|
+
pqcrypto_hybrid_kem_expanded_secret_key_wipe, 1);
|
|
1710
1874
|
rb_define_module_function(mPQCrypto, "hybrid_kem_decapsulate", pqcrypto_hybrid_kem_decapsulate,
|
|
1711
1875
|
2);
|
|
1712
1876
|
rb_define_module_function(mPQCrypto, "hybrid_kem_decapsulate_expanded",
|
|
@@ -1714,20 +1878,20 @@ void Init_pqcrypto_secure(void) {
|
|
|
1714
1878
|
rb_define_module_function(mPQCrypto, "hybrid_kem_decapsulate_expanded_object",
|
|
1715
1879
|
pqcrypto_hybrid_kem_decapsulate_expanded_object, 2);
|
|
1716
1880
|
rb_define_module_function(mPQCrypto, "sign_keypair", pqcrypto_sign_keypair, 0);
|
|
1717
|
-
rb_define_module_function(mPQCrypto, "sign", pqcrypto_sign,
|
|
1718
|
-
rb_define_module_function(mPQCrypto, "verify", pqcrypto_verify,
|
|
1881
|
+
rb_define_module_function(mPQCrypto, "sign", pqcrypto_sign, -1);
|
|
1882
|
+
rb_define_module_function(mPQCrypto, "verify", pqcrypto_verify, -1);
|
|
1719
1883
|
rb_define_module_function(mPQCrypto, "ml_dsa_44_keypair", pqcrypto_ml_dsa_44_keypair, 0);
|
|
1720
1884
|
rb_define_module_function(mPQCrypto, "ml_dsa_44_keypair_from_seed",
|
|
1721
1885
|
pqcrypto_ml_dsa_44_keypair_from_seed, 1);
|
|
1722
1886
|
rb_define_module_function(mPQCrypto, "ml_dsa_keypair_from_seed",
|
|
1723
1887
|
pqcrypto_ml_dsa_keypair_from_seed, 1);
|
|
1724
|
-
rb_define_module_function(mPQCrypto, "ml_dsa_44_sign", pqcrypto_ml_dsa_44_sign,
|
|
1725
|
-
rb_define_module_function(mPQCrypto, "ml_dsa_44_verify", pqcrypto_ml_dsa_44_verify,
|
|
1888
|
+
rb_define_module_function(mPQCrypto, "ml_dsa_44_sign", pqcrypto_ml_dsa_44_sign, -1);
|
|
1889
|
+
rb_define_module_function(mPQCrypto, "ml_dsa_44_verify", pqcrypto_ml_dsa_44_verify, -1);
|
|
1726
1890
|
rb_define_module_function(mPQCrypto, "ml_dsa_87_keypair", pqcrypto_ml_dsa_87_keypair, 0);
|
|
1727
1891
|
rb_define_module_function(mPQCrypto, "ml_dsa_87_keypair_from_seed",
|
|
1728
1892
|
pqcrypto_ml_dsa_87_keypair_from_seed, 1);
|
|
1729
|
-
rb_define_module_function(mPQCrypto, "ml_dsa_87_sign", pqcrypto_ml_dsa_87_sign,
|
|
1730
|
-
rb_define_module_function(mPQCrypto, "ml_dsa_87_verify", pqcrypto_ml_dsa_87_verify,
|
|
1893
|
+
rb_define_module_function(mPQCrypto, "ml_dsa_87_sign", pqcrypto_ml_dsa_87_sign, -1);
|
|
1894
|
+
rb_define_module_function(mPQCrypto, "ml_dsa_87_verify", pqcrypto_ml_dsa_87_verify, -1);
|
|
1731
1895
|
rb_define_module_function(mPQCrypto, "ct_equals", pqcrypto_ct_equals, 2);
|
|
1732
1896
|
rb_define_module_function(mPQCrypto, "secure_wipe", pqcrypto_secure_wipe, 1);
|
|
1733
1897
|
rb_define_module_function(mPQCrypto, "version", pqcrypto_version, 0);
|
|
@@ -1748,9 +1912,9 @@ void Init_pqcrypto_secure(void) {
|
|
|
1748
1912
|
rb_define_module_function(mPQCrypto, "secret_key_from_pqc_container_pem",
|
|
1749
1913
|
pqcrypto_secret_key_from_pqc_container_pem, 1);
|
|
1750
1914
|
rb_define_module_function(mPQCrypto, "_native_mldsa_extract_tr",
|
|
1751
|
-
pqcrypto__native_mldsa_extract_tr, 1);
|
|
1915
|
+
pqcrypto__native_mldsa_extract_tr, -1);
|
|
1752
1916
|
rb_define_module_function(mPQCrypto, "_native_mldsa_compute_tr",
|
|
1753
|
-
pqcrypto__native_mldsa_compute_tr, 1);
|
|
1917
|
+
pqcrypto__native_mldsa_compute_tr, -1);
|
|
1754
1918
|
rb_define_module_function(mPQCrypto, "_native_mldsa_mu_builder_new",
|
|
1755
1919
|
pqcrypto__native_mldsa_mu_builder_new, 2);
|
|
1756
1920
|
rb_define_module_function(mPQCrypto, "_native_mldsa_mu_builder_update",
|
|
@@ -1760,9 +1924,9 @@ void Init_pqcrypto_secure(void) {
|
|
|
1760
1924
|
rb_define_module_function(mPQCrypto, "_native_mldsa_mu_builder_release",
|
|
1761
1925
|
pqcrypto__native_mldsa_mu_builder_release, 1);
|
|
1762
1926
|
rb_define_module_function(mPQCrypto, "_native_mldsa_sign_mu", pqcrypto__native_mldsa_sign_mu,
|
|
1763
|
-
|
|
1927
|
+
-1);
|
|
1764
1928
|
rb_define_module_function(mPQCrypto, "_native_mldsa_verify_mu",
|
|
1765
|
-
pqcrypto__native_mldsa_verify_mu,
|
|
1929
|
+
pqcrypto__native_mldsa_verify_mu, -1);
|
|
1766
1930
|
|
|
1767
1931
|
define_constants();
|
|
1768
1932
|
}
|