jwt-pq 0.3.0 → 0.4.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 +29 -1
- data/README.md +1 -0
- data/jwt-pq.gemspec +1 -1
- data/lib/jwt/pq/algorithms/hybrid_eddsa.rb +20 -10
- data/lib/jwt/pq/version.rb +1 -1
- metadata +1 -4
- data/bench/fixtures/ml_dsa_65_sk.pem +0 -128
- data/bench/sign_throughput.rb +0 -26
- data/bench/verify_throughput.rb +0 -29
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d662c64af196cc33ed4b288a641442317fe49881eef85bfadc2385c0bee7e63f
|
|
4
|
+
data.tar.gz: 599a753241ae95a168461d1a7f61b2a2b2147da13f1456479758873657fb18f5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c360bb8b3b5a8fdad530e3cba2f6d3630999d635669d85e5ac57854f746bbf8250559073d258ca2aa95f0f443208aded8c90b68a15f75f58a00370963fa5c943
|
|
7
|
+
data.tar.gz: e57d739e3567413f845a685caf55305d7704120fee29adf31ab09cbb0a85cbc2b6c0713ad4e85db73c65c1238d323ab04ab5e079adef06f2918a2114fb06aa96
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,33 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.4.0] - 2026-04-19
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- Hybrid-sign throughput benchmark at `bench/hybrid_sign_throughput.rb`
|
|
15
|
+
- Hybrid-verify throughput benchmark at `bench/hybrid_verify_throughput.rb`
|
|
16
|
+
- Parameterized `bench/sign_throughput.rb` and `bench/verify_throughput.rb` via `ALG` env var — previously hardcoded to `ML-DSA-65`, now supports all three security levels
|
|
17
|
+
- PEM key fixtures for ML-DSA-44 and ML-DSA-87 under `bench/fixtures/`
|
|
18
|
+
- `bench/generate_fixtures.rb` to regenerate bench fixtures idempotently
|
|
19
|
+
- Cross-implementation interop CI against `dilithium-py` (independent pure-Python ML-DSA / FIPS 204 implementation) — runs on push, PR, and weekly
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
|
|
23
|
+
- **Hybrid EdDSA+ML-DSA-65 sign throughput: +12.1%** (5200 → 5831 sigs/s on Ruby 3.4.6 + liboqs 0.15.0). Inline type-check in `HybridEdDsa#sign` (+1.6%) plus cached frozen header hash and precomputed `ml_dsa_algorithm` at init (+10.4%) — `#header` is called once per `JWT.encode`, so eliminating the per-call Hash allocation and `String#sub` compounds noticeably.
|
|
24
|
+
- **Hybrid EdDSA+ML-DSA-65 verify throughput: +2.3%** (4812 → 4923 verifies/s). Inline type-check in `HybridEdDsa#verify`, mirroring the sign-side pattern.
|
|
25
|
+
- `bench/` directory no longer packaged into the published gem (smaller install footprint).
|
|
26
|
+
|
|
27
|
+
### Benchmarks
|
|
28
|
+
|
|
29
|
+
Throughput on Ruby 3.4.6, macOS x86_64, liboqs 0.15.0 (benchmark-ips, 2s warmup + 5s measurement):
|
|
30
|
+
|
|
31
|
+
| Algorithm | Sign | Verify |
|
|
32
|
+
|------------|----------:|-----------:|
|
|
33
|
+
| ML-DSA-44 | 9678 ops/s | 12650 ops/s |
|
|
34
|
+
| ML-DSA-65 | 6236 ops/s | 8567 ops/s |
|
|
35
|
+
| ML-DSA-87 | 3591 ops/s | 6510 ops/s |
|
|
36
|
+
|
|
10
37
|
## [0.3.0] - 2026-04-19
|
|
11
38
|
|
|
12
39
|
### Added
|
|
@@ -76,7 +103,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
76
103
|
- Optional dependency on jwt-eddsa / ed25519
|
|
77
104
|
- Error classes: `LiboqsError`, `KeyError`, `SignatureError`, `MissingDependencyError`
|
|
78
105
|
|
|
79
|
-
[Unreleased]: https://github.com/marcelopazzo/jwt-pq/compare/v0.
|
|
106
|
+
[Unreleased]: https://github.com/marcelopazzo/jwt-pq/compare/v0.4.0...HEAD
|
|
107
|
+
[0.4.0]: https://github.com/marcelopazzo/jwt-pq/compare/v0.3.0...v0.4.0
|
|
80
108
|
[0.3.0]: https://github.com/marcelopazzo/jwt-pq/compare/v0.2.0...v0.3.0
|
|
81
109
|
[0.2.0]: https://github.com/marcelopazzo/jwt-pq/compare/v0.1.0...v0.2.0
|
|
82
110
|
[0.1.0]: https://github.com/marcelopazzo/jwt-pq/releases/tag/v0.1.0
|
data/README.md
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://rubygems.org/gems/jwt-pq)
|
|
4
4
|
[](https://github.com/marcelopazzo/jwt-pq/actions/workflows/ci.yml)
|
|
5
|
+
[](https://github.com/marcelopazzo/jwt-pq/actions/workflows/interop.yml)
|
|
5
6
|
[](https://codecov.io/gh/marcelopazzo/jwt-pq)
|
|
6
7
|
|
|
7
8
|
Post-quantum JWT signatures for Ruby. Adds **ML-DSA** (FIPS 204) support to the [ruby-jwt](https://github.com/jwt/ruby-jwt) ecosystem, with an optional **hybrid EdDSA + ML-DSA** mode.
|
data/jwt-pq.gemspec
CHANGED
|
@@ -36,7 +36,7 @@ Gem::Specification.new do |spec|
|
|
|
36
36
|
|
|
37
37
|
spec.files = Dir.chdir(__dir__) do
|
|
38
38
|
`git ls-files -z`.split("\x0").reject do |f|
|
|
39
|
-
f.start_with?("spec/", "vendor/", ".github/") ||
|
|
39
|
+
f.start_with?("spec/", "vendor/", ".github/", "bench/") ||
|
|
40
40
|
f.match?(/\A(?:\.git|\.rspec|\.rubocop|jwt-pq-plan)/)
|
|
41
41
|
end
|
|
42
42
|
end
|
|
@@ -17,24 +17,36 @@ module JWT
|
|
|
17
17
|
|
|
18
18
|
def initialize(alg)
|
|
19
19
|
@alg = alg
|
|
20
|
+
@ml_dsa_algorithm = alg.sub("EdDSA+", "")
|
|
21
|
+
@header = { "alg" => alg, "pq_alg" => @ml_dsa_algorithm }.freeze
|
|
20
22
|
end
|
|
21
23
|
|
|
22
24
|
def header(*)
|
|
23
|
-
|
|
25
|
+
@header
|
|
24
26
|
end
|
|
25
27
|
|
|
26
28
|
def sign(data:, signing_key:)
|
|
27
|
-
|
|
29
|
+
unless signing_key.is_a?(JWT::PQ::HybridKey)
|
|
30
|
+
raise_sign_error!(
|
|
31
|
+
"Expected a JWT::PQ::HybridKey, got #{signing_key.class}. " \
|
|
32
|
+
"Use JWT::PQ::HybridKey.generate to create a hybrid key."
|
|
33
|
+
)
|
|
34
|
+
end
|
|
35
|
+
raise_sign_error!("Both Ed25519 and ML-DSA private keys required") unless signing_key.private?
|
|
28
36
|
|
|
29
|
-
ed_sig =
|
|
30
|
-
ml_sig =
|
|
37
|
+
ed_sig = signing_key.ed25519_signing_key.sign(data)
|
|
38
|
+
ml_sig = signing_key.ml_dsa_key.sign(data)
|
|
31
39
|
|
|
32
40
|
# Concatenate: Ed25519 (64 bytes) || ML-DSA (variable)
|
|
33
41
|
ed_sig + ml_sig
|
|
34
42
|
end
|
|
35
43
|
|
|
36
44
|
def verify(data:, signature:, verification_key:)
|
|
37
|
-
|
|
45
|
+
unless verification_key.is_a?(JWT::PQ::HybridKey)
|
|
46
|
+
raise_verify_error!(
|
|
47
|
+
"Expected a JWT::PQ::HybridKey, got #{verification_key.class}."
|
|
48
|
+
)
|
|
49
|
+
end
|
|
38
50
|
|
|
39
51
|
return false if signature.bytesize <= ED25519_SIG_SIZE
|
|
40
52
|
|
|
@@ -42,13 +54,13 @@ module JWT
|
|
|
42
54
|
ml_sig = signature.byteslice(ED25519_SIG_SIZE..)
|
|
43
55
|
|
|
44
56
|
ed_valid = begin
|
|
45
|
-
|
|
57
|
+
verification_key.ed25519_verify_key.verify(ed_sig, data)
|
|
46
58
|
true
|
|
47
59
|
rescue Ed25519::VerifyError
|
|
48
60
|
false
|
|
49
61
|
end
|
|
50
62
|
|
|
51
|
-
ml_valid =
|
|
63
|
+
ml_valid = verification_key.ml_dsa_key.verify(data, ml_sig)
|
|
52
64
|
|
|
53
65
|
ed_valid && ml_valid
|
|
54
66
|
rescue JWT::PQ::Error
|
|
@@ -57,9 +69,7 @@ module JWT
|
|
|
57
69
|
|
|
58
70
|
private
|
|
59
71
|
|
|
60
|
-
|
|
61
|
-
alg.sub("EdDSA+", "")
|
|
62
|
-
end
|
|
72
|
+
attr_reader :ml_dsa_algorithm
|
|
63
73
|
|
|
64
74
|
def resolve_signing_key(key)
|
|
65
75
|
case key
|
data/lib/jwt/pq/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: jwt-pq
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Marcelo Almeida
|
|
@@ -66,9 +66,6 @@ files:
|
|
|
66
66
|
- LICENSE
|
|
67
67
|
- README.md
|
|
68
68
|
- Rakefile
|
|
69
|
-
- bench/fixtures/ml_dsa_65_sk.pem
|
|
70
|
-
- bench/sign_throughput.rb
|
|
71
|
-
- bench/verify_throughput.rb
|
|
72
69
|
- bin/smoke.rb
|
|
73
70
|
- ext/jwt/pq/extconf.rb
|
|
74
71
|
- jwt-pq.gemspec
|
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
-----BEGIN PRIVATE KEY-----
|
|
2
|
-
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
-
cMnDbU0mRYR8GDXCFkb57vZLOGkID1aX0SFm3yIUCkyNlQA8eOc9pntwVXHh8fmD
|
|
4
|
-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
-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
-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
-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
-
YSRCJYZmUyCAI1FFNEYGQGJIEABVdkVRJjVIF3NyNRMjhxd3eFMDgUNlQmWHEiRn
|
|
9
|
-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
-
N4d2V4UDVkGGRyUmhgZjCGWIYWJkhBg0CGJxFVRIhyQnUzVgCIhUZFgRBwBWBIN3
|
|
11
|
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-
WDg4YlAjhiiCJSYVAGYlBkEENIcXFTdRYBhFZQgFhzdShSQnYoNGhRUmCHVFCHiD
|
|
23
|
-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
-
BHBUFCAUAzhYQFB0YyU4YCUBIGUyV0J4YiQXCBEUR2ZoN3FjAVARNgF2KBiFBIZo
|
|
25
|
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-
y/fiuOdPak842ilksrvz5pv6e4cZLkQB1UXRlopIdVMZQY6FV7M+z+q6ngcoFeUY
|
|
42
|
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-
6pPXk0vmLmUo1KRsSr9yE2ns0cCN7bnPGJ8wVso+ZEBlGMABTv7bSEmHpiAL2Kh5
|
|
56
|
-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
-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
-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
-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
-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
-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
-
Sa1xdq4AYhoyJluKaUP+lyGb59rL9DoYAMoY9ssSyuOXbv7tAfzat0eoSiZcss3R
|
|
63
|
-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
-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
-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
-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
-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
-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
-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
-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
-
FLJAivJVLPUZMw6VG3g10BP/gto2NBWEVYiAYOctZisIWjzXob7SyP08SpIOYxsc
|
|
72
|
-
y/9kTMnBg5rNgxN4oKD929+fQGiI8A1+NSoFokFS3tu3oa2e1tVoFohpo9Vn9NDC
|
|
73
|
-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
-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
-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
-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
-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
-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
-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
-
b7U2VUj5zuy7qg3VHDUqEF2Dyj8pgg61mlDvtfE3bz6ksYhj0AYIe5f5h/zhzHj1
|
|
81
|
-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
-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
-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
-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
-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
-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
-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
-
kq8ad/fExbXVtDOcAsr5AonmKkdVXvwcy52DvR7IB+BWMH1mkuoggKTOq3aRRytt
|
|
89
|
-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
-
/nTe/s3KVsdoJajXnnY6K1ToF4ngNJutkgkg2m7D+fh0eexZB3bstlZeU1VtlJpA
|
|
91
|
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-
mbBeB2FEiGTLWUAVJjLV897VOksehKZhRhExVK8dJzyZT3wbduPGlX+CKSBu5UbS
|
|
104
|
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
|
|
127
|
-
aEqLBCQtoXub0y7W
|
|
128
|
-
-----END PRIVATE KEY-----
|
data/bench/sign_throughput.rb
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "benchmark/ips"
|
|
4
|
-
require "jwt"
|
|
5
|
-
require "jwt/pq"
|
|
6
|
-
|
|
7
|
-
ALG = "ML-DSA-65"
|
|
8
|
-
PAYLOAD = { sub: "user-123", iat: 1_700_000_000, exp: 1_700_003_600 }.freeze
|
|
9
|
-
FIXTURE = File.expand_path("fixtures/ml_dsa_65_sk.pem", __dir__)
|
|
10
|
-
|
|
11
|
-
abort "Missing bench fixture: #{FIXTURE}" unless File.exist?(FIXTURE)
|
|
12
|
-
key = JWT::PQ::Key.from_pem(File.read(FIXTURE))
|
|
13
|
-
|
|
14
|
-
100.times { JWT.encode(PAYLOAD, key, ALG) }
|
|
15
|
-
|
|
16
|
-
report = Benchmark.ips(quiet: true) do |x|
|
|
17
|
-
x.config(time: 5, warmup: 2)
|
|
18
|
-
x.report("sign") { JWT.encode(PAYLOAD, key, ALG) }
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
entry = report.entries.first
|
|
22
|
-
ips = entry.stats.central_tendency
|
|
23
|
-
us_per_op = 1_000_000.0 / ips
|
|
24
|
-
|
|
25
|
-
puts "METRIC sigs_per_sec=#{ips.round(2)}"
|
|
26
|
-
puts "METRIC us_per_sig=#{us_per_op.round(2)}"
|
data/bench/verify_throughput.rb
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "benchmark/ips"
|
|
4
|
-
require "jwt"
|
|
5
|
-
require "jwt/pq"
|
|
6
|
-
|
|
7
|
-
ALG = "ML-DSA-65"
|
|
8
|
-
PAYLOAD = { sub: "user-123", iat: 1_700_000_000, exp: 1_700_003_600 }.freeze
|
|
9
|
-
FIXTURE = File.expand_path("fixtures/ml_dsa_65_sk.pem", __dir__)
|
|
10
|
-
|
|
11
|
-
abort "Missing bench fixture: #{FIXTURE}" unless File.exist?(FIXTURE)
|
|
12
|
-
key = JWT::PQ::Key.from_pem(File.read(FIXTURE))
|
|
13
|
-
pub_key = JWT::PQ::Key.from_public_key(ALG, key.public_key)
|
|
14
|
-
|
|
15
|
-
TOKEN = JWT.encode(PAYLOAD, key, ALG)
|
|
16
|
-
|
|
17
|
-
100.times { JWT.decode(TOKEN, pub_key, true, algorithms: [ALG], verify_expiration: false) }
|
|
18
|
-
|
|
19
|
-
report = Benchmark.ips(quiet: true) do |x|
|
|
20
|
-
x.config(time: 5, warmup: 2)
|
|
21
|
-
x.report("verify") { JWT.decode(TOKEN, pub_key, true, algorithms: [ALG], verify_expiration: false) }
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
entry = report.entries.first
|
|
25
|
-
ips = entry.stats.central_tendency
|
|
26
|
-
us_per_op = 1_000_000.0 / ips
|
|
27
|
-
|
|
28
|
-
puts "METRIC verifies_per_sec=#{ips.round(2)}"
|
|
29
|
-
puts "METRIC us_per_verify=#{us_per_op.round(2)}"
|