pq_crypto 0.2.0 → 0.3.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.
@@ -4,6 +4,8 @@
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
 
9
11
  typedef struct {
@@ -63,7 +65,6 @@ static VALUE ePQCryptoError;
63
65
  static VALUE ePQCryptoVerificationError;
64
66
 
65
67
  __attribute__((noreturn)) static void pq_raise_general_error(int err);
66
- __attribute__((noreturn)) static void pq_raise_verification_error(int err);
67
68
 
68
69
  static const char *pq_algorithm_symbol_to_cstr(VALUE algorithm) {
69
70
  ID id;
@@ -75,8 +76,8 @@ static const char *pq_algorithm_symbol_to_cstr(VALUE algorithm) {
75
76
  }
76
77
  if (id == rb_intern("ml_kem_768"))
77
78
  return "ml_kem_768";
78
- if (id == rb_intern("ml_kem_768_x25519_hkdf_sha256"))
79
- return "ml_kem_768_x25519_hkdf_sha256";
79
+ if (id == rb_intern("ml_kem_768_x25519_xwing"))
80
+ return "ml_kem_768_x25519_xwing";
80
81
  if (id == rb_intern("ml_dsa_65"))
81
82
  return "ml_dsa_65";
82
83
  rb_raise(rb_eArgError, "Unsupported serialization algorithm");
@@ -85,8 +86,8 @@ static const char *pq_algorithm_symbol_to_cstr(VALUE algorithm) {
85
86
  static VALUE pq_algorithm_cstr_to_symbol(const char *algorithm) {
86
87
  if (strcmp(algorithm, "ml_kem_768") == 0)
87
88
  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"));
89
+ if (strcmp(algorithm, "ml_kem_768_x25519_xwing") == 0)
90
+ return ID2SYM(rb_intern("ml_kem_768_x25519_xwing"));
90
91
  if (strcmp(algorithm, "ml_dsa_65") == 0)
91
92
  return ID2SYM(rb_intern("ml_dsa_65"));
92
93
  rb_raise(rb_eArgError, "Unsupported serialization algorithm");
@@ -460,16 +461,6 @@ __attribute__((noreturn)) static void pq_raise_general_error(int err) {
460
461
  }
461
462
  }
462
463
 
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
464
  static VALUE pqcrypto_ml_kem_keypair(VALUE self) {
474
465
  (void)self;
475
466
  return pq_run_kem_keypair(pq_ml_kem_keypair_nogvl, PQ_MLKEM_PUBLICKEYBYTES,
@@ -512,8 +503,8 @@ static VALUE pqcrypto__test_ml_kem_keypair_from_seed(VALUE self, VALUE seed) {
512
503
  (void)self;
513
504
  StringValue(seed);
514
505
 
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");
506
+ if ((size_t)RSTRING_LEN(seed) != 64) {
507
+ rb_raise(rb_eArgError, "Deterministic ML-KEM test seed must be 64 bytes (FIPS 203 d||z)");
517
508
  }
518
509
 
519
510
  kem_keypair_call_t call = {0};
@@ -698,11 +689,29 @@ static VALUE pqcrypto_verify(VALUE self, VALUE message, VALUE signature, VALUE p
698
689
  pq_wipe_and_free((uint8_t *)call.public_key, public_key_len);
699
690
  pq_wipe_and_free((uint8_t *)call.signature, signature_len);
700
691
 
701
- if (call.result != PQ_SUCCESS) {
702
- pq_raise_verification_error(call.result);
692
+ if (call.result == PQ_SUCCESS) {
693
+ return Qtrue;
694
+ }
695
+ if (call.result == PQ_ERROR_VERIFY) {
696
+ return Qfalse;
703
697
  }
698
+ pq_raise_general_error(call.result);
699
+ }
704
700
 
705
- return Qtrue;
701
+ static VALUE pqcrypto_ct_equals(VALUE self, VALUE a, VALUE b) {
702
+ (void)self;
703
+ StringValue(a);
704
+ StringValue(b);
705
+ if (RSTRING_LEN(a) != RSTRING_LEN(b)) {
706
+ return Qfalse;
707
+ }
708
+ if (RSTRING_LEN(a) == 0) {
709
+ return Qtrue;
710
+ }
711
+ if (CRYPTO_memcmp(RSTRING_PTR(a), RSTRING_PTR(b), (size_t)RSTRING_LEN(a)) == 0) {
712
+ return Qtrue;
713
+ }
714
+ return Qfalse;
706
715
  }
707
716
 
708
717
  static VALUE pqcrypto_secure_wipe(VALUE self, VALUE str) {
@@ -780,6 +789,7 @@ static VALUE pqcrypto_secret_key_from_pqc_container_pem(VALUE self, VALUE pem) {
780
789
  void Init_pqcrypto_secure(void) {
781
790
  mPQCrypto = rb_define_module("PQCrypto");
782
791
  ePQCryptoError = rb_define_class_under(mPQCrypto, "Error", rb_eStandardError);
792
+
783
793
  ePQCryptoVerificationError =
784
794
  rb_define_class_under(mPQCrypto, "VerificationError", ePQCryptoError);
785
795
 
@@ -801,6 +811,7 @@ void Init_pqcrypto_secure(void) {
801
811
  rb_define_module_function(mPQCrypto, "sign_keypair", pqcrypto_sign_keypair, 0);
802
812
  rb_define_module_function(mPQCrypto, "sign", pqcrypto_sign, 2);
803
813
  rb_define_module_function(mPQCrypto, "verify", pqcrypto_verify, 3);
814
+ rb_define_module_function(mPQCrypto, "ct_equals", pqcrypto_ct_equals, 2);
804
815
  rb_define_module_function(mPQCrypto, "secure_wipe", pqcrypto_secure_wipe, 1);
805
816
  rb_define_module_function(mPQCrypto, "version", pqcrypto_version, 0);
806
817
  rb_define_module_function(mPQCrypto, "public_key_to_pqc_container_der",