pq_crypto 0.6.7 → 0.6.8

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cf8d3b17b9579ef551ef337aab16a9eb356846a36ff492577e2d728ec0e285e2
4
- data.tar.gz: 26c3c3646d066617e37cb2cb1219e7ee5ca640488c84b480b6259461999b48e5
3
+ metadata.gz: db8e5b65d14cc5dcc4950a2da14b781efcf4c8dd17774cffc076e9d5591509ca
4
+ data.tar.gz: '09cf8c3e990a416ab0f8f77fe2a2a6067fdd8a3f4d00607a4162e4259d6044bd'
5
5
  SHA512:
6
- metadata.gz: bd58150566a566af1c3083ef2c72538acafb6b15c5ebe954d0d7af35f96cdf41a5f1fe17c8d3c956e29b3c51bd89b29ec24245749efbca82389b1d2dc3c91ede
7
- data.tar.gz: 5d974df3a99f9284da5c5cdfff25ba1808dc083063c12f97db6b803a34aa15687a0cda9565c8617edd95015c8d23139181d56d69d2483a3ac17b2239bec3cba3
6
+ metadata.gz: 81a8509efb9d280100975a8e4a9a0a6aab70061b49bbc48a396de490723c316abe63442cfb041c68dbeefd9383fba647b198318082723ffb9bace9d0ffd12c78
7
+ data.tar.gz: 1055665295f23df22a53880fbf02a2e8d0c0cb33f1b65a43b1fe2f1f040da829bcaf4895440093addc432f15fb9c21792f28bf41e2949c90b9c93bc2784e5e93
data/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.6.8] - 2026-10-28
4
+
5
+ ### Changed
6
+
7
+ - **Refactored Ruby serialization and streaming paths.** Split SPKI and PKCS#8
8
+ decoding into focused validation steps, shared the seed/expanded-key codecs,
9
+ and consolidated ML-DSA streaming builder cleanup. SPKI algorithm matching
10
+ now uses one shared validator. Public APIs and encoded formats are unchanged.
11
+
3
12
  ## [0.6.7] - 2026-08-10
4
13
 
5
14
  ### Fixed
@@ -8,6 +8,8 @@
8
8
  #if defined(__clang__) || defined(__GNUC__)
9
9
  #pragma GCC diagnostic pop
10
10
  #endif
11
+ #include <stdbool.h>
12
+ #include <stdatomic.h>
11
13
  #include <stdlib.h>
12
14
  #include <string.h>
13
15
 
@@ -1460,6 +1462,7 @@ static VALUE pqcrypto_version(VALUE self) {
1460
1462
 
1461
1463
  typedef struct {
1462
1464
  void *builder;
1465
+ atomic_bool busy;
1463
1466
  } mu_builder_wrapper_t;
1464
1467
 
1465
1468
  typedef struct {
@@ -1526,15 +1529,29 @@ static const rb_data_type_t mu_builder_data_type = {
1526
1529
  .flags = RUBY_TYPED_FREE_IMMEDIATELY,
1527
1530
  };
1528
1531
 
1529
- static mu_builder_wrapper_t *mu_builder_unwrap(VALUE obj) {
1532
+ static mu_builder_wrapper_t *mu_builder_lock(VALUE obj) {
1530
1533
  mu_builder_wrapper_t *wrapper;
1531
1534
  TypedData_Get_Struct(obj, mu_builder_wrapper_t, &mu_builder_data_type, wrapper);
1532
- if (wrapper == NULL || wrapper->builder == NULL) {
1533
- rb_raise(ePQCryptoError, "mu builder used after release");
1535
+ if (wrapper == NULL) {
1536
+ rb_raise(ePQCryptoError, "mu builder is unavailable");
1537
+ }
1538
+ if (atomic_exchange_explicit(&wrapper->busy, true, memory_order_acquire)) {
1539
+ rb_raise(ePQCryptoError, "mu builder is busy");
1534
1540
  }
1535
1541
  return wrapper;
1536
1542
  }
1537
1543
 
1544
+ static void mu_builder_unlock(mu_builder_wrapper_t *wrapper) {
1545
+ atomic_store_explicit(&wrapper->busy, false, memory_order_release);
1546
+ }
1547
+
1548
+ static void mu_builder_require_active(mu_builder_wrapper_t *wrapper) {
1549
+ if (wrapper->builder == NULL) {
1550
+ mu_builder_unlock(wrapper);
1551
+ rb_raise(ePQCryptoError, "mu builder used after release");
1552
+ }
1553
+ }
1554
+
1538
1555
  static VALUE pqcrypto__native_mldsa_extract_tr(int argc, VALUE *argv, VALUE self) {
1539
1556
  (void)self;
1540
1557
  VALUE algorithm = ID2SYM(rb_intern("ml_dsa_65"));
@@ -1614,6 +1631,7 @@ static VALUE pqcrypto__native_mldsa_mu_builder_new(VALUE self, VALUE tr, VALUE c
1614
1631
  VALUE obj =
1615
1632
  TypedData_Make_Struct(rb_cObject, mu_builder_wrapper_t, &mu_builder_data_type, wrapper);
1616
1633
  wrapper->builder = builder;
1634
+ atomic_init(&wrapper->busy, false);
1617
1635
  return obj;
1618
1636
  }
1619
1637
 
@@ -1625,24 +1643,31 @@ static void *pq_mu_absorb_nogvl(void *arg) {
1625
1643
 
1626
1644
  static VALUE pqcrypto__native_mldsa_mu_builder_update(VALUE self, VALUE builder_obj, VALUE chunk) {
1627
1645
  (void)self;
1628
- mu_builder_wrapper_t *wrapper = mu_builder_unwrap(builder_obj);
1629
1646
  StringValue(chunk);
1630
1647
 
1631
1648
  size_t chunk_len = (size_t)RSTRING_LEN(chunk);
1649
+ mu_builder_wrapper_t *wrapper = mu_builder_lock(builder_obj);
1650
+ mu_builder_require_active(wrapper);
1632
1651
  if (chunk_len == 0) {
1652
+ mu_builder_unlock(wrapper);
1633
1653
  return Qnil;
1634
1654
  }
1635
1655
 
1636
1656
  if (chunk_len < PQ_MU_ABSORB_NOGVL_MIN_BYTES) {
1637
- int rc =
1638
- pq_mu_builder_absorb(wrapper->builder, (const uint8_t *)RSTRING_PTR(chunk), chunk_len);
1657
+ int rc = pq_mu_builder_absorb(wrapper->builder,
1658
+ (const uint8_t *)RSTRING_PTR(chunk), chunk_len);
1659
+ mu_builder_unlock(wrapper);
1639
1660
  if (rc != PQ_SUCCESS) {
1640
1661
  pq_raise_general_error(rc);
1641
1662
  }
1642
1663
  return Qnil;
1643
1664
  }
1644
1665
 
1645
- uint8_t *copy = pq_alloc_buffer(chunk_len);
1666
+ uint8_t *copy = malloc(chunk_len);
1667
+ if (copy == NULL) {
1668
+ mu_builder_unlock(wrapper);
1669
+ rb_raise(rb_eNoMemError, "Memory allocation failed");
1670
+ }
1646
1671
  memcpy(copy, RSTRING_PTR(chunk), chunk_len);
1647
1672
 
1648
1673
  mu_absorb_call_t call = {0};
@@ -1651,7 +1676,9 @@ static VALUE pqcrypto__native_mldsa_mu_builder_update(VALUE self, VALUE builder_
1651
1676
  call.chunk_len = chunk_len;
1652
1677
 
1653
1678
  rb_nogvl(pq_mu_absorb_nogvl, &call, NULL, NULL, PQ_RB_NOGVL_OFFLOAD_SAFE);
1679
+ RB_GC_GUARD(builder_obj);
1654
1680
  free(copy);
1681
+ mu_builder_unlock(wrapper);
1655
1682
 
1656
1683
  if (call.result != PQ_SUCCESS) {
1657
1684
  pq_raise_general_error(call.result);
@@ -1667,7 +1694,8 @@ static void *pq_mu_finalize_nogvl(void *arg) {
1667
1694
 
1668
1695
  static VALUE pqcrypto__native_mldsa_mu_builder_finalize(VALUE self, VALUE builder_obj) {
1669
1696
  (void)self;
1670
- mu_builder_wrapper_t *wrapper = mu_builder_unwrap(builder_obj);
1697
+ mu_builder_wrapper_t *wrapper = mu_builder_lock(builder_obj);
1698
+ mu_builder_require_active(wrapper);
1671
1699
 
1672
1700
  uint8_t mu[PQ_MLDSA_MUBYTES];
1673
1701
 
@@ -1676,8 +1704,10 @@ static VALUE pqcrypto__native_mldsa_mu_builder_finalize(VALUE self, VALUE builde
1676
1704
  call.mu_out = mu;
1677
1705
 
1678
1706
  rb_nogvl(pq_mu_finalize_nogvl, &call, NULL, NULL, PQ_RB_NOGVL_OFFLOAD_SAFE);
1707
+ RB_GC_GUARD(builder_obj);
1679
1708
 
1680
1709
  wrapper->builder = NULL;
1710
+ mu_builder_unlock(wrapper);
1681
1711
 
1682
1712
  if (call.result != PQ_SUCCESS) {
1683
1713
  pq_secure_wipe(mu, sizeof(mu));
@@ -1691,12 +1721,12 @@ static VALUE pqcrypto__native_mldsa_mu_builder_finalize(VALUE self, VALUE builde
1691
1721
 
1692
1722
  static VALUE pqcrypto__native_mldsa_mu_builder_release(VALUE self, VALUE builder_obj) {
1693
1723
  (void)self;
1694
- mu_builder_wrapper_t *wrapper;
1695
- TypedData_Get_Struct(builder_obj, mu_builder_wrapper_t, &mu_builder_data_type, wrapper);
1696
- if (wrapper != NULL && wrapper->builder != NULL) {
1724
+ mu_builder_wrapper_t *wrapper = mu_builder_lock(builder_obj);
1725
+ if (wrapper->builder != NULL) {
1697
1726
  pq_mu_builder_release(wrapper->builder);
1698
1727
  wrapper->builder = NULL;
1699
1728
  }
1729
+ mu_builder_unlock(wrapper);
1700
1730
  return Qnil;
1701
1731
  }
1702
1732