pq_crypto 0.2.0 → 0.3.1

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.
@@ -4,8 +4,14 @@
4
4
  #include <stdlib.h>
5
5
  #include <string.h>
6
6
 
7
+ #include <openssl/crypto.h>
8
+
7
9
  #include "pqcrypto_secure.h"
8
10
 
11
+ #ifndef RB_NOGVL_OFFLOAD_SAFE
12
+ #define RB_NOGVL_OFFLOAD_SAFE 0
13
+ #endif
14
+
9
15
  typedef struct {
10
16
  int result;
11
17
  uint8_t *public_key;
@@ -63,7 +69,6 @@ static VALUE ePQCryptoError;
63
69
  static VALUE ePQCryptoVerificationError;
64
70
 
65
71
  __attribute__((noreturn)) static void pq_raise_general_error(int err);
66
- __attribute__((noreturn)) static void pq_raise_verification_error(int err);
67
72
 
68
73
  static const char *pq_algorithm_symbol_to_cstr(VALUE algorithm) {
69
74
  ID id;
@@ -75,8 +80,8 @@ static const char *pq_algorithm_symbol_to_cstr(VALUE algorithm) {
75
80
  }
76
81
  if (id == rb_intern("ml_kem_768"))
77
82
  return "ml_kem_768";
78
- if (id == rb_intern("ml_kem_768_x25519_hkdf_sha256"))
79
- return "ml_kem_768_x25519_hkdf_sha256";
83
+ if (id == rb_intern("ml_kem_768_x25519_xwing"))
84
+ return "ml_kem_768_x25519_xwing";
80
85
  if (id == rb_intern("ml_dsa_65"))
81
86
  return "ml_dsa_65";
82
87
  rb_raise(rb_eArgError, "Unsupported serialization algorithm");
@@ -85,8 +90,8 @@ static const char *pq_algorithm_symbol_to_cstr(VALUE algorithm) {
85
90
  static VALUE pq_algorithm_cstr_to_symbol(const char *algorithm) {
86
91
  if (strcmp(algorithm, "ml_kem_768") == 0)
87
92
  return ID2SYM(rb_intern("ml_kem_768"));
88
- if (strcmp(algorithm, "ml_kem_768_x25519_hkdf_sha256") == 0)
89
- return ID2SYM(rb_intern("ml_kem_768_x25519_hkdf_sha256"));
93
+ if (strcmp(algorithm, "ml_kem_768_x25519_xwing") == 0)
94
+ return ID2SYM(rb_intern("ml_kem_768_x25519_xwing"));
90
95
  if (strcmp(algorithm, "ml_dsa_65") == 0)
91
96
  return ID2SYM(rb_intern("ml_dsa_65"));
92
97
  rb_raise(rb_eArgError, "Unsupported serialization algorithm");
@@ -460,16 +465,6 @@ __attribute__((noreturn)) static void pq_raise_general_error(int err) {
460
465
  }
461
466
  }
462
467
 
463
- __attribute__((noreturn)) static void pq_raise_verification_error(int err) {
464
- switch (err) {
465
- case PQ_ERROR_VERIFY:
466
- rb_raise(ePQCryptoVerificationError, "Verification failed");
467
- break;
468
- default:
469
- pq_raise_general_error(err);
470
- }
471
- }
472
-
473
468
  static VALUE pqcrypto_ml_kem_keypair(VALUE self) {
474
469
  (void)self;
475
470
  return pq_run_kem_keypair(pq_ml_kem_keypair_nogvl, PQ_MLKEM_PUBLICKEYBYTES,
@@ -512,8 +507,8 @@ static VALUE pqcrypto__test_ml_kem_keypair_from_seed(VALUE self, VALUE seed) {
512
507
  (void)self;
513
508
  StringValue(seed);
514
509
 
515
- if ((size_t)RSTRING_LEN(seed) != 32 && (size_t)RSTRING_LEN(seed) != 64) {
516
- rb_raise(rb_eArgError, "Deterministic ML-KEM test seed must be 32 or 64 bytes");
510
+ if ((size_t)RSTRING_LEN(seed) != 64) {
511
+ rb_raise(rb_eArgError, "Deterministic ML-KEM test seed must be 64 bytes (FIPS 203 d||z)");
517
512
  }
518
513
 
519
514
  kem_keypair_call_t call = {0};
@@ -698,11 +693,29 @@ static VALUE pqcrypto_verify(VALUE self, VALUE message, VALUE signature, VALUE p
698
693
  pq_wipe_and_free((uint8_t *)call.public_key, public_key_len);
699
694
  pq_wipe_and_free((uint8_t *)call.signature, signature_len);
700
695
 
701
- if (call.result != PQ_SUCCESS) {
702
- pq_raise_verification_error(call.result);
696
+ if (call.result == PQ_SUCCESS) {
697
+ return Qtrue;
698
+ }
699
+ if (call.result == PQ_ERROR_VERIFY) {
700
+ return Qfalse;
703
701
  }
702
+ pq_raise_general_error(call.result);
703
+ }
704
704
 
705
- return Qtrue;
705
+ static VALUE pqcrypto_ct_equals(VALUE self, VALUE a, VALUE b) {
706
+ (void)self;
707
+ StringValue(a);
708
+ StringValue(b);
709
+ if (RSTRING_LEN(a) != RSTRING_LEN(b)) {
710
+ return Qfalse;
711
+ }
712
+ if (RSTRING_LEN(a) == 0) {
713
+ return Qtrue;
714
+ }
715
+ if (CRYPTO_memcmp(RSTRING_PTR(a), RSTRING_PTR(b), (size_t)RSTRING_LEN(a)) == 0) {
716
+ return Qtrue;
717
+ }
718
+ return Qfalse;
706
719
  }
707
720
 
708
721
  static VALUE pqcrypto_secure_wipe(VALUE self, VALUE str) {
@@ -780,6 +793,7 @@ static VALUE pqcrypto_secret_key_from_pqc_container_pem(VALUE self, VALUE pem) {
780
793
  void Init_pqcrypto_secure(void) {
781
794
  mPQCrypto = rb_define_module("PQCrypto");
782
795
  ePQCryptoError = rb_define_class_under(mPQCrypto, "Error", rb_eStandardError);
796
+
783
797
  ePQCryptoVerificationError =
784
798
  rb_define_class_under(mPQCrypto, "VerificationError", ePQCryptoError);
785
799
 
@@ -801,6 +815,7 @@ void Init_pqcrypto_secure(void) {
801
815
  rb_define_module_function(mPQCrypto, "sign_keypair", pqcrypto_sign_keypair, 0);
802
816
  rb_define_module_function(mPQCrypto, "sign", pqcrypto_sign, 2);
803
817
  rb_define_module_function(mPQCrypto, "verify", pqcrypto_verify, 3);
818
+ rb_define_module_function(mPQCrypto, "ct_equals", pqcrypto_ct_equals, 2);
804
819
  rb_define_module_function(mPQCrypto, "secure_wipe", pqcrypto_secure_wipe, 1);
805
820
  rb_define_module_function(mPQCrypto, "version", pqcrypto_version, 0);
806
821
  rb_define_module_function(mPQCrypto, "public_key_to_pqc_container_der",