pq_crypto-seal 0.1.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 +7 -0
- data/.github/workflows/ci.yml +66 -0
- data/CHANGELOG.md +44 -0
- data/FORMAT.md +139 -0
- data/GET_STARTED.md +30 -0
- data/Gemfile +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +215 -0
- data/RELEASING.md +34 -0
- data/Rakefile +19 -0
- data/SECURITY.md +85 -0
- data/VENDORING.md +14 -0
- data/ext/pq_crypto_seal/aegis_unused_stubs.c +20 -0
- data/ext/pq_crypto_seal/extconf.rb +296 -0
- data/ext/pq_crypto_seal/pq_crypto_seal.c +390 -0
- data/ext/pq_crypto_seal/vendor/libaegis/LICENSE +21 -0
- data/ext/pq_crypto_seal/vendor/libaegis/TREE_SHA256 +1 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128l/aegis128l.c +246 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128l/aegis128l_aesni.c +73 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128l/aegis128l_aesni.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128l/aegis128l_altivec.c +70 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128l/aegis128l_altivec.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128l/aegis128l_common.h +691 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128l/aegis128l_neon_aes.c +77 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128l/aegis128l_neon_aes.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128l/aegis128l_neon_sha3.c +86 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128l/aegis128l_neon_sha3.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128l/aegis128l_soft.c +63 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128l/aegis128l_soft.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128l/implementations.h +40 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x2/aegis128x2.c +247 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x2/aegis128x2_aesni.c +108 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x2/aegis128x2_aesni.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x2/aegis128x2_altivec.c +103 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x2/aegis128x2_altivec.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x2/aegis128x2_avx2.c +79 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x2/aegis128x2_avx2.h +11 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x2/aegis128x2_common.h +795 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x2/aegis128x2_neon_aes.c +111 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x2/aegis128x2_neon_aes.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x2/aegis128x2_soft.c +96 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x2/aegis128x2_soft.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x2/implementations.h +40 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/aegis128x4.c +252 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/aegis128x4_aesni.c +117 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/aegis128x4_aesni.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/aegis128x4_altivec.c +111 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/aegis128x4_altivec.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/aegis128x4_avx2.c +112 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/aegis128x4_avx2.h +11 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/aegis128x4_avx512.c +85 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/aegis128x4_avx512.h +11 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/aegis128x4_common.h +808 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/aegis128x4_neon_aes.c +119 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/aegis128x4_neon_aes.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/aegis128x4_soft.c +104 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/aegis128x4_soft.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/implementations.h +41 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256/aegis256.c +240 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256/aegis256_aesni.c +68 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256/aegis256_aesni.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256/aegis256_altivec.c +68 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256/aegis256_altivec.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256/aegis256_common.h +673 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256/aegis256_neon_aes.c +75 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256/aegis256_neon_aes.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256/aegis256_soft.c +58 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256/aegis256_soft.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256/implementations.h +39 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x2/aegis256x2.c +247 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x2/aegis256x2_aesni.c +103 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x2/aegis256x2_aesni.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x2/aegis256x2_altivec.c +101 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x2/aegis256x2_altivec.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x2/aegis256x2_avx2.c +74 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x2/aegis256x2_avx2.h +11 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x2/aegis256x2_common.h +790 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x2/aegis256x2_neon_aes.c +109 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x2/aegis256x2_neon_aes.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x2/aegis256x2_soft.c +91 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x2/aegis256x2_soft.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x2/implementations.h +41 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/aegis256x4.c +252 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/aegis256x4_aesni.c +112 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/aegis256x4_aesni.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/aegis256x4_altivec.c +109 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/aegis256x4_altivec.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/aegis256x4_avx2.c +107 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/aegis256x4_avx2.h +11 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/aegis256x4_avx512.c +79 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/aegis256x4_avx512.h +11 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/aegis256x4_common.h +805 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/aegis256x4_neon_aes.c +117 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/aegis256x4_neon_aes.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/aegis256x4_soft.c +99 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/aegis256x4_soft.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/implementations.h +42 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/common/common.c +81 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/common/common.h +144 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/common/cpu.c +378 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/common/cpu.h +34 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/common/keccak.c +187 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/common/keccak.h +13 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/common/softaes.c +338 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/common/softaes.h +69 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/include/aegis.h +77 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/include/aegis128l.h +311 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/include/aegis128x2.h +313 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/include/aegis128x4.h +313 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/include/aegis256.h +311 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/include/aegis256x2.h +313 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/include/aegis256x4.h +313 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/include/aegis_raf.h +580 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/raf/raf.c +87 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/raf/raf_aegis128l.c +20 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/raf/raf_aegis128x2.c +20 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/raf/raf_aegis128x4.c +20 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/raf/raf_aegis256.c +20 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/raf/raf_aegis256x2.c +20 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/raf/raf_aegis256x4.c +20 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/raf/raf_internal.h +152 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/raf/raf_merkle.c +268 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/raf/raf_merkle.h +165 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/raf/raf_variant.h +1119 -0
- data/fuzz/decrypt_fuzz.rb +119 -0
- data/lib/pq_crypto/seal/binary.rb +62 -0
- data/lib/pq_crypto/seal/core.rb +398 -0
- data/lib/pq_crypto/seal/errors.rb +15 -0
- data/lib/pq_crypto/seal/format.rb +275 -0
- data/lib/pq_crypto/seal/io.rb +336 -0
- data/lib/pq_crypto/seal/native.rb +13 -0
- data/lib/pq_crypto/seal/padding.rb +47 -0
- data/lib/pq_crypto/seal/version.rb +6 -0
- data/lib/pq_crypto/seal.rb +32 -0
- data/pq_crypto-seal.gemspec +37 -0
- data/script/vendor_libs.rb +79 -0
- data/test/aegis_vectors_test.rb +54 -0
- data/test/golden_vectors_test.rb +183 -0
- data/test/io_test.rb +125 -0
- data/test/native_test.rb +36 -0
- data/test/seal_test.rb +238 -0
- data/test/test_helper.rb +6 -0
- metadata +244 -0
data/test/seal_test.rb
ADDED
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
require_relative "test_helper"
|
|
3
|
+
|
|
4
|
+
class SealTest < Minitest::Test
|
|
5
|
+
def setup
|
|
6
|
+
@alice = PQCrypto::HybridKEM.generate(PQCrypto::Seal::WRAP_KEM_ALGORITHM)
|
|
7
|
+
@bob = PQCrypto::HybridKEM.generate(PQCrypto::Seal::WRAP_KEM_ALGORITHM)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def test_multi_recipient_round_trip_and_padding
|
|
11
|
+
data = ("image" * 10_000).b
|
|
12
|
+
envelope = PQCrypto::Seal.encrypt(
|
|
13
|
+
data, to: [@alice.public_key, @bob.public_key],
|
|
14
|
+
metadata: "private", public_metadata: "public"
|
|
15
|
+
)
|
|
16
|
+
alice = PQCrypto::Seal.open(envelope, with: @alice)
|
|
17
|
+
bob = PQCrypto::Seal.open(envelope, with: @bob)
|
|
18
|
+
assert_equal data, alice.data
|
|
19
|
+
assert_equal data, bob.data
|
|
20
|
+
assert_equal "private", alice.metadata
|
|
21
|
+
assert_equal "public", alice.public_metadata
|
|
22
|
+
assert_equal PQCrypto::Seal::Format::PADDING_PADME, alice.padding_policy_id
|
|
23
|
+
assert_operator envelope.bytesize, :>=, data.bytesize
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def test_wrong_recipient_and_tampering_fail
|
|
27
|
+
envelope = PQCrypto::Seal.encrypt("secret", to: @alice.public_key)
|
|
28
|
+
stranger = PQCrypto::HybridKEM.generate(PQCrypto::Seal::WRAP_KEM_ALGORITHM)
|
|
29
|
+
assert_raises(PQCrypto::Seal::RecipientNotFoundError) do
|
|
30
|
+
PQCrypto::Seal.decrypt(envelope, with: stranger)
|
|
31
|
+
end
|
|
32
|
+
broken = envelope.dup
|
|
33
|
+
broken.setbyte(broken.bytesize - 1, broken.getbyte(-1) ^ 1)
|
|
34
|
+
assert_raises(PQCrypto::Seal::AuthenticationError) do
|
|
35
|
+
PQCrypto::Seal.decrypt(broken, with: @alice)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def test_rebuild_recipients_preserves_payload
|
|
40
|
+
envelope = PQCrypto::Seal.encrypt("document", to: @alice.public_key)
|
|
41
|
+
rebuilt = PQCrypto::Seal.rebuild_recipients(
|
|
42
|
+
envelope, with: @alice,
|
|
43
|
+
recipients: [@alice.public_key, @bob.public_key]
|
|
44
|
+
)
|
|
45
|
+
assert_equal "document", PQCrypto::Seal.decrypt(rebuilt, with: @bob)
|
|
46
|
+
assert_raises(PQCrypto::Seal::RecipientNotFoundError) do
|
|
47
|
+
PQCrypto::Seal.decrypt(envelope, with: @bob)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def test_rebuild_randomizes_entire_recipient_section
|
|
52
|
+
envelope = PQCrypto::Seal.encrypt("document", to: @alice.public_key)
|
|
53
|
+
rebuilt = PQCrypto::Seal.rebuild_recipients(
|
|
54
|
+
envelope, with: @alice, recipients: [@alice.public_key]
|
|
55
|
+
)
|
|
56
|
+
original_info = PQCrypto::Seal.inspect_envelope(envelope)
|
|
57
|
+
rebuilt_info = PQCrypto::Seal.inspect_envelope(rebuilt)
|
|
58
|
+
assert_equal original_info.payload_id, rebuilt_info.payload_id
|
|
59
|
+
refute_equal envelope, rebuilt
|
|
60
|
+
assert_equal "document", PQCrypto::Seal.decrypt(rebuilt, with: @alice)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def test_padme_and_none_policy_ids
|
|
64
|
+
data = "x" * 12_345
|
|
65
|
+
metadata = "m" * 19
|
|
66
|
+
envelope = PQCrypto::Seal.encrypt(data, to: @alice.public_key, metadata: metadata, padding: :padme)
|
|
67
|
+
info = PQCrypto::Seal.inspect_envelope(envelope)
|
|
68
|
+
assert_equal PQCrypto::Seal::Format::PADDING_PADME, info.padding_policy_id
|
|
69
|
+
assert_equal data, PQCrypto::Seal.decrypt(envelope, with: @alice)
|
|
70
|
+
|
|
71
|
+
none_env = PQCrypto::Seal.encrypt("hi", to: @alice.public_key, padding: :none)
|
|
72
|
+
assert_equal PQCrypto::Seal::Format::PADDING_NONE,
|
|
73
|
+
PQCrypto::Seal.inspect_envelope(none_env).padding_policy_id
|
|
74
|
+
assert_equal "hi", PQCrypto::Seal.decrypt(none_env, with: @alice)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def test_truncation_trailing_bytes_and_payload_tamper_fail
|
|
78
|
+
envelope = PQCrypto::Seal.encrypt("secret" * 100, to: @alice.public_key)
|
|
79
|
+
assert_raises(PQCrypto::Seal::FormatError) do
|
|
80
|
+
PQCrypto::Seal.decrypt(envelope.byteslice(0, envelope.bytesize - 1), with: @alice)
|
|
81
|
+
end
|
|
82
|
+
assert_raises(PQCrypto::Seal::FormatError) do
|
|
83
|
+
PQCrypto::Seal.decrypt(envelope + "x", with: @alice)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
info = PQCrypto::Seal.inspect_envelope(envelope)
|
|
87
|
+
payload_offset = info.envelope_bytes - info.padded_inner_length - PQCrypto::Seal::Format::TAG_BYTES
|
|
88
|
+
broken = envelope.dup
|
|
89
|
+
broken.setbyte(payload_offset, broken.getbyte(payload_offset) ^ 1)
|
|
90
|
+
assert_raises(PQCrypto::Seal::AuthenticationError) do
|
|
91
|
+
PQCrypto::Seal.decrypt(broken, with: @alice)
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def test_separately_loaded_credentials_and_duplicate_rejection
|
|
96
|
+
credentials = PQCrypto::Seal.credentials(
|
|
97
|
+
secret_key: @alice.secret_key, public_key: @alice.public_key
|
|
98
|
+
)
|
|
99
|
+
envelope = PQCrypto::Seal.encrypt("x", to: @alice.public_key)
|
|
100
|
+
assert_equal "x", PQCrypto::Seal.decrypt(envelope, with: credentials)
|
|
101
|
+
assert_raises(PQCrypto::Seal::InvalidConfigurationError) do
|
|
102
|
+
PQCrypto::Seal.encrypt("x", to: [@alice.public_key, @alice.public_key])
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def test_rotate_dek_preserves_envelope_size_by_default
|
|
107
|
+
envelope = PQCrypto::Seal.encrypt(
|
|
108
|
+
"document" * 500, to: @alice.public_key, padding: { to: 20_000 }
|
|
109
|
+
)
|
|
110
|
+
rotated = PQCrypto::Seal.rotate_dek(
|
|
111
|
+
envelope, with: @alice, recipients: [@alice.public_key, @bob.public_key]
|
|
112
|
+
)
|
|
113
|
+
assert_equal envelope.bytesize, rotated.bytesize
|
|
114
|
+
assert_equal "document" * 500, PQCrypto::Seal.decrypt(rotated, with: @bob)
|
|
115
|
+
assert_equal PQCrypto::Seal::Format::PADDING_FIXED,
|
|
116
|
+
PQCrypto::Seal.inspect_envelope(rotated).padding_policy_id
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def test_capacity_is_fixed_policy
|
|
120
|
+
assert_raises(PQCrypto::Seal::RecipientCapacityExceeded) do
|
|
121
|
+
keys = 5.times.map { PQCrypto::HybridKEM.generate(PQCrypto::Seal::WRAP_KEM_ALGORITHM).public_key }
|
|
122
|
+
PQCrypto::Seal.encrypt("x", to: keys, recipient_capacity: 4)
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def test_internals_are_not_public
|
|
127
|
+
refute PQCrypto::Seal.respond_to?(:unwrap_dek)
|
|
128
|
+
refute PQCrypto::Seal.respond_to?(:derive_kek)
|
|
129
|
+
refute PQCrypto::Seal.respond_to?(:build_slot)
|
|
130
|
+
refute PQCrypto::Seal.respond_to?(:parse_envelope)
|
|
131
|
+
refute PQCrypto::Seal.respond_to?(:wipe_string!)
|
|
132
|
+
assert PQCrypto::Seal.respond_to?(:encrypt)
|
|
133
|
+
assert PQCrypto::Seal.respond_to?(:decrypt)
|
|
134
|
+
assert PQCrypto::Seal.respond_to?(:open)
|
|
135
|
+
assert PQCrypto::Seal.respond_to?(:digest)
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def test_resource_limit_rejects_huge_declared_inner
|
|
139
|
+
envelope = PQCrypto::Seal.encrypt("tiny", to: @alice.public_key, padding: :none)
|
|
140
|
+
assert_raises(PQCrypto::Seal::ResourceLimitError) do
|
|
141
|
+
PQCrypto::Seal.decrypt(envelope, with: @alice, max_staging_bytes: 8)
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def test_malformed_capacity_is_format_error
|
|
146
|
+
envelope = PQCrypto::Seal.encrypt("x", to: @alice.public_key, padding: :none)
|
|
147
|
+
# capacity sits after magic(8)+ver(1)+hdrlen(4)+suite(2)+lookup(1)+flags(2)+pad_policy(1)+pid(32)+nonce(32)
|
|
148
|
+
offset = 8 + 1 + 4 + 2 + 1 + 2 + 1 + 32 + 32
|
|
149
|
+
broken = envelope.dup
|
|
150
|
+
broken.setbyte(offset, 0xff)
|
|
151
|
+
broken.setbyte(offset + 1, 0xff)
|
|
152
|
+
assert_raises(PQCrypto::Seal::FormatError) do
|
|
153
|
+
PQCrypto::Seal.decrypt(broken, with: @alice)
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def test_array_credentials_form
|
|
158
|
+
envelope = PQCrypto::Seal.encrypt("array-cred", to: @alice.public_key, padding: :none)
|
|
159
|
+
assert_equal "array-cred",
|
|
160
|
+
PQCrypto::Seal.decrypt(envelope, with: [@alice.secret_key, @alice.public_key])
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def test_fixed_and_bucket_padding_policies
|
|
164
|
+
fixed = PQCrypto::Seal.encrypt("x", to: @alice.public_key, padding: { to: 12_000 })
|
|
165
|
+
assert_equal 12_000, fixed.bytesize
|
|
166
|
+
assert_equal PQCrypto::Seal::Format::PADDING_FIXED,
|
|
167
|
+
PQCrypto::Seal.inspect_envelope(fixed).padding_policy_id
|
|
168
|
+
assert_equal "x", PQCrypto::Seal.decrypt(fixed, with: @alice)
|
|
169
|
+
|
|
170
|
+
bucketed = PQCrypto::Seal.encrypt("y", to: @alice.public_key, padding: { buckets: [8_000, 16_000, 32_000] })
|
|
171
|
+
assert_includes [8_000, 16_000, 32_000], bucketed.bytesize
|
|
172
|
+
assert_equal PQCrypto::Seal::Format::PADDING_BUCKETS,
|
|
173
|
+
PQCrypto::Seal.inspect_envelope(bucketed).padding_policy_id
|
|
174
|
+
assert_equal "y", PQCrypto::Seal.decrypt(bucketed, with: @alice)
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def test_digest_changes_on_recipient_rebuild
|
|
178
|
+
envelope = PQCrypto::Seal.encrypt("stable-payload", to: @alice.public_key, padding: :none)
|
|
179
|
+
d1 = PQCrypto::Seal.digest(envelope)
|
|
180
|
+
rebuilt = PQCrypto::Seal.rebuild_recipients(
|
|
181
|
+
envelope, with: @alice, recipients: [@alice.public_key, @bob.public_key]
|
|
182
|
+
)
|
|
183
|
+
d2 = PQCrypto::Seal.digest(rebuilt)
|
|
184
|
+
refute_equal d1, d2
|
|
185
|
+
assert_equal PQCrypto::Seal.open(envelope, with: @alice).payload_id,
|
|
186
|
+
PQCrypto::Seal.open(rebuilt, with: @alice).payload_id
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
def test_wrap_kem_algorithm_is_pinned
|
|
190
|
+
assert_equal :ml_kem_768_x25519_xwing, PQCrypto::Seal::WRAP_KEM_ALGORITHM
|
|
191
|
+
assert_equal 1216, PQCrypto::Seal::Format::XWING_PUBLIC_KEY_BYTES
|
|
192
|
+
assert_equal 1120, PQCrypto::Seal::Format::XWING_CIPHERTEXT_BYTES
|
|
193
|
+
assert_equal 32, PQCrypto::Seal::Format::XWING_SHARED_SECRET_BYTES
|
|
194
|
+
refute PQCrypto::Seal::Format.const_defined?(:XWING_SECRET_KEY_BYTES)
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
def test_index_binding_prevents_naive_slot_duplication
|
|
198
|
+
# wrap_ad / derive_kek bind slot_index, so byte-copying a real slot into
|
|
199
|
+
# another index cannot open a second time for the same recipient.
|
|
200
|
+
envelope = PQCrypto::Seal.encrypt(
|
|
201
|
+
"ambig", to: @alice.public_key, recipient_capacity: 2, slot_size: 2048, padding: :none
|
|
202
|
+
)
|
|
203
|
+
header = PQCrypto::Seal::Format.parse_header(envelope)
|
|
204
|
+
section_offset = header.raw.bytesize
|
|
205
|
+
slots_offset = section_offset + 2 + PQCrypto::Seal::Format::SECTION_ID_BYTES
|
|
206
|
+
slot0 = envelope.byteslice(slots_offset, header.slot_size)
|
|
207
|
+
broken = envelope.dup
|
|
208
|
+
broken[slots_offset + header.slot_size, header.slot_size] = slot0
|
|
209
|
+
assert_equal "ambig", PQCrypto::Seal.decrypt(broken, with: @alice)
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
def test_two_valid_stanzas_for_same_recipient_are_ambiguous
|
|
213
|
+
# Defense-in-depth: a crafted envelope with two correctly-built slots for
|
|
214
|
+
# the same public key (different indices) must not pick an arbitrary DEK.
|
|
215
|
+
envelope = PQCrypto::Seal.encrypt(
|
|
216
|
+
"ambig", to: @alice.public_key, recipient_capacity: 2, slot_size: 2048, padding: :none
|
|
217
|
+
)
|
|
218
|
+
header, section, ciphertext, tag = PQCrypto::Seal.send(:parse_envelope, envelope)
|
|
219
|
+
dek = PQCrypto::Seal.send(:unwrap_dek, header, section, @alice)
|
|
220
|
+
crafted_section = PQCrypto::Seal.send(
|
|
221
|
+
:build_recipient_section,
|
|
222
|
+
recipients: [@alice.public_key, @alice.public_key],
|
|
223
|
+
capacity: 2,
|
|
224
|
+
slot_size: header.slot_size,
|
|
225
|
+
payload_id: header.payload_id,
|
|
226
|
+
header_hash: PQCrypto::Seal.const_get(:Native).sha256(header.raw),
|
|
227
|
+
dek: dek,
|
|
228
|
+
wrap_suite_id: PQCrypto::Seal::Format::WRAP_SUITE_MLKEM768_X25519_AEGIS256
|
|
229
|
+
)
|
|
230
|
+
crafted = header.raw + crafted_section + ciphertext + tag
|
|
231
|
+
assert_raises(PQCrypto::Seal::AmbiguousRecipientStanzas) do
|
|
232
|
+
PQCrypto::Seal.decrypt(crafted, with: @alice)
|
|
233
|
+
end
|
|
234
|
+
ensure
|
|
235
|
+
PQCrypto::Seal.send(:wipe_string!, dek) if defined?(dek)
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
ADDED
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: pq_crypto-seal
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Roman Khaidarov
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: exe
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2026-07-20 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: pq_crypto
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: 0.6.4
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: 0.6.4
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: minitest
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - "~>"
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '5.14'
|
|
34
|
+
type: :development
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - "~>"
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '5.14'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: rake
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - "~>"
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '13.0'
|
|
48
|
+
type: :development
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - "~>"
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '13.0'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: rake-compiler
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - "~>"
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '1.2'
|
|
62
|
+
type: :development
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - "~>"
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '1.2'
|
|
69
|
+
description: Versioned multi-recipient document encryption using PQCrypto hybrid KEM,
|
|
70
|
+
HKDF-SHA256, and vendored AEGIS-256.
|
|
71
|
+
email:
|
|
72
|
+
- roman-haidarov@users.noreply.github.com
|
|
73
|
+
executables: []
|
|
74
|
+
extensions:
|
|
75
|
+
- ext/pq_crypto_seal/extconf.rb
|
|
76
|
+
extra_rdoc_files: []
|
|
77
|
+
files:
|
|
78
|
+
- ".github/workflows/ci.yml"
|
|
79
|
+
- CHANGELOG.md
|
|
80
|
+
- FORMAT.md
|
|
81
|
+
- GET_STARTED.md
|
|
82
|
+
- Gemfile
|
|
83
|
+
- LICENSE.txt
|
|
84
|
+
- README.md
|
|
85
|
+
- RELEASING.md
|
|
86
|
+
- Rakefile
|
|
87
|
+
- SECURITY.md
|
|
88
|
+
- VENDORING.md
|
|
89
|
+
- ext/pq_crypto_seal/aegis_unused_stubs.c
|
|
90
|
+
- ext/pq_crypto_seal/extconf.rb
|
|
91
|
+
- ext/pq_crypto_seal/pq_crypto_seal.c
|
|
92
|
+
- ext/pq_crypto_seal/vendor/libaegis/LICENSE
|
|
93
|
+
- ext/pq_crypto_seal/vendor/libaegis/TREE_SHA256
|
|
94
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis128l/aegis128l.c
|
|
95
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis128l/aegis128l_aesni.c
|
|
96
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis128l/aegis128l_aesni.h
|
|
97
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis128l/aegis128l_altivec.c
|
|
98
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis128l/aegis128l_altivec.h
|
|
99
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis128l/aegis128l_common.h
|
|
100
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis128l/aegis128l_neon_aes.c
|
|
101
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis128l/aegis128l_neon_aes.h
|
|
102
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis128l/aegis128l_neon_sha3.c
|
|
103
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis128l/aegis128l_neon_sha3.h
|
|
104
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis128l/aegis128l_soft.c
|
|
105
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis128l/aegis128l_soft.h
|
|
106
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis128l/implementations.h
|
|
107
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis128x2/aegis128x2.c
|
|
108
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis128x2/aegis128x2_aesni.c
|
|
109
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis128x2/aegis128x2_aesni.h
|
|
110
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis128x2/aegis128x2_altivec.c
|
|
111
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis128x2/aegis128x2_altivec.h
|
|
112
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis128x2/aegis128x2_avx2.c
|
|
113
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis128x2/aegis128x2_avx2.h
|
|
114
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis128x2/aegis128x2_common.h
|
|
115
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis128x2/aegis128x2_neon_aes.c
|
|
116
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis128x2/aegis128x2_neon_aes.h
|
|
117
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis128x2/aegis128x2_soft.c
|
|
118
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis128x2/aegis128x2_soft.h
|
|
119
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis128x2/implementations.h
|
|
120
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/aegis128x4.c
|
|
121
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/aegis128x4_aesni.c
|
|
122
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/aegis128x4_aesni.h
|
|
123
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/aegis128x4_altivec.c
|
|
124
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/aegis128x4_altivec.h
|
|
125
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/aegis128x4_avx2.c
|
|
126
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/aegis128x4_avx2.h
|
|
127
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/aegis128x4_avx512.c
|
|
128
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/aegis128x4_avx512.h
|
|
129
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/aegis128x4_common.h
|
|
130
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/aegis128x4_neon_aes.c
|
|
131
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/aegis128x4_neon_aes.h
|
|
132
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/aegis128x4_soft.c
|
|
133
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/aegis128x4_soft.h
|
|
134
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/implementations.h
|
|
135
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis256/aegis256.c
|
|
136
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis256/aegis256_aesni.c
|
|
137
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis256/aegis256_aesni.h
|
|
138
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis256/aegis256_altivec.c
|
|
139
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis256/aegis256_altivec.h
|
|
140
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis256/aegis256_common.h
|
|
141
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis256/aegis256_neon_aes.c
|
|
142
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis256/aegis256_neon_aes.h
|
|
143
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis256/aegis256_soft.c
|
|
144
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis256/aegis256_soft.h
|
|
145
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis256/implementations.h
|
|
146
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis256x2/aegis256x2.c
|
|
147
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis256x2/aegis256x2_aesni.c
|
|
148
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis256x2/aegis256x2_aesni.h
|
|
149
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis256x2/aegis256x2_altivec.c
|
|
150
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis256x2/aegis256x2_altivec.h
|
|
151
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis256x2/aegis256x2_avx2.c
|
|
152
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis256x2/aegis256x2_avx2.h
|
|
153
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis256x2/aegis256x2_common.h
|
|
154
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis256x2/aegis256x2_neon_aes.c
|
|
155
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis256x2/aegis256x2_neon_aes.h
|
|
156
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis256x2/aegis256x2_soft.c
|
|
157
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis256x2/aegis256x2_soft.h
|
|
158
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis256x2/implementations.h
|
|
159
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/aegis256x4.c
|
|
160
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/aegis256x4_aesni.c
|
|
161
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/aegis256x4_aesni.h
|
|
162
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/aegis256x4_altivec.c
|
|
163
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/aegis256x4_altivec.h
|
|
164
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/aegis256x4_avx2.c
|
|
165
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/aegis256x4_avx2.h
|
|
166
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/aegis256x4_avx512.c
|
|
167
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/aegis256x4_avx512.h
|
|
168
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/aegis256x4_common.h
|
|
169
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/aegis256x4_neon_aes.c
|
|
170
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/aegis256x4_neon_aes.h
|
|
171
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/aegis256x4_soft.c
|
|
172
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/aegis256x4_soft.h
|
|
173
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/implementations.h
|
|
174
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/common/common.c
|
|
175
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/common/common.h
|
|
176
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/common/cpu.c
|
|
177
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/common/cpu.h
|
|
178
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/common/keccak.c
|
|
179
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/common/keccak.h
|
|
180
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/common/softaes.c
|
|
181
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/common/softaes.h
|
|
182
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/include/aegis.h
|
|
183
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/include/aegis128l.h
|
|
184
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/include/aegis128x2.h
|
|
185
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/include/aegis128x4.h
|
|
186
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/include/aegis256.h
|
|
187
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/include/aegis256x2.h
|
|
188
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/include/aegis256x4.h
|
|
189
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/include/aegis_raf.h
|
|
190
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/raf/raf.c
|
|
191
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/raf/raf_aegis128l.c
|
|
192
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/raf/raf_aegis128x2.c
|
|
193
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/raf/raf_aegis128x4.c
|
|
194
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/raf/raf_aegis256.c
|
|
195
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/raf/raf_aegis256x2.c
|
|
196
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/raf/raf_aegis256x4.c
|
|
197
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/raf/raf_internal.h
|
|
198
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/raf/raf_merkle.c
|
|
199
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/raf/raf_merkle.h
|
|
200
|
+
- ext/pq_crypto_seal/vendor/libaegis/src/raf/raf_variant.h
|
|
201
|
+
- fuzz/decrypt_fuzz.rb
|
|
202
|
+
- lib/pq_crypto/seal.rb
|
|
203
|
+
- lib/pq_crypto/seal/binary.rb
|
|
204
|
+
- lib/pq_crypto/seal/core.rb
|
|
205
|
+
- lib/pq_crypto/seal/errors.rb
|
|
206
|
+
- lib/pq_crypto/seal/format.rb
|
|
207
|
+
- lib/pq_crypto/seal/io.rb
|
|
208
|
+
- lib/pq_crypto/seal/native.rb
|
|
209
|
+
- lib/pq_crypto/seal/padding.rb
|
|
210
|
+
- lib/pq_crypto/seal/version.rb
|
|
211
|
+
- pq_crypto-seal.gemspec
|
|
212
|
+
- script/vendor_libs.rb
|
|
213
|
+
- test/aegis_vectors_test.rb
|
|
214
|
+
- test/golden_vectors_test.rb
|
|
215
|
+
- test/io_test.rb
|
|
216
|
+
- test/native_test.rb
|
|
217
|
+
- test/seal_test.rb
|
|
218
|
+
- test/test_helper.rb
|
|
219
|
+
homepage: https://github.com/roman-haidarov/pq_crypto-seal
|
|
220
|
+
licenses:
|
|
221
|
+
- MIT
|
|
222
|
+
metadata:
|
|
223
|
+
source_code_uri: https://github.com/roman-haidarov/pq_crypto-seal
|
|
224
|
+
changelog_uri: https://github.com/roman-haidarov/pq_crypto-seal/blob/main/CHANGELOG.md
|
|
225
|
+
post_install_message:
|
|
226
|
+
rdoc_options: []
|
|
227
|
+
require_paths:
|
|
228
|
+
- lib
|
|
229
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
230
|
+
requirements:
|
|
231
|
+
- - ">="
|
|
232
|
+
- !ruby/object:Gem::Version
|
|
233
|
+
version: 2.7.1
|
|
234
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
235
|
+
requirements:
|
|
236
|
+
- - ">="
|
|
237
|
+
- !ruby/object:Gem::Version
|
|
238
|
+
version: '0'
|
|
239
|
+
requirements: []
|
|
240
|
+
rubygems_version: 3.4.22
|
|
241
|
+
signing_key:
|
|
242
|
+
specification_version: 4
|
|
243
|
+
summary: Post-quantum envelope encryption for Ruby
|
|
244
|
+
test_files: []
|