diff --git a/2_preliminaries.typ b/2_preliminaries.typ index 33392fc..d556931 100644 --- a/2_preliminaries.typ +++ b/2_preliminaries.typ @@ -253,7 +253,7 @@ Hence, the utilization of @kemtls has an impact on the size of the certificate, // This section provides a short overview of the @pq signatures available today. // It helps with understanding size and performance considerations later on. -@pq_signature_comp shows a comparison of @ecdsa and #gls("rsa", long: false)-2048 as classical signature schemes and the @pq signature schemes selected by the @nist for standardization. +@tab:pq_signature_comp shows a comparison of @ecdsa and #gls("rsa", long: false)-2048 as classical signature schemes and the @pq signature schemes selected by the @nist for standardization. @mldsa was known as #box[CRYSTALS]-Dilithium and @nist standardized it as FIPS 204 in 2024, together with the @slhdsa as FIPS 205 @fips_204 @fips_205. A @nist draft for the @fndsa is expected in late 2024. @@ -273,6 +273,6 @@ Moreover, verifying does not rely on floating-point arithmetic, and even if it d #figure( pq_signatures, caption: [ - Comparison of selected classical signature schemes with algorithms (to be) standardized by @nist. - The #box(baseline: 0.2em, height: 1em, image("images/red-alert-icon.svg")) symbols fast, but dangerous floating-point arithmetic. @bas_westerbaan_state_2024] -) + Comparison of selected classical signature schemes with algorithms (to be) standardized by the @nist. + The #box(baseline: 0.2em, height: 1em, image("images/red-alert-icon.svg")) symbols fast, but dangerous floating-point arithmetic~@bas_westerbaan_state_2024. The CPU cycles taken from the SUPERCOP database, measured on a AMD Ryzen 7 7700; 8 x 3800MHz machine~@supercop-asym. The @pq algorithms were not listed in their final versions yet. Therefore, we used benchmarks of preliminary versions that are closest to the final standard.] +) diff --git a/3_mtc.typ b/3_mtc.typ index 065029d..8aa5fd6 100644 --- a/3_mtc.typ +++ b/3_mtc.typ @@ -46,7 +46,8 @@ Compared to today's Web@pki it has a reduced scope and assumes more prerequisite - A #emph([Transparency Service]) mirrors the @ca:pl, validates the batches, and forwards them to the @rp:pl. - A #emph([Monitor]) monitors the transparency services for suspicious or unauthorized certificates. - An #emph([Assertion]) is information that an @ap gets certified by a @ca, i.e., a public key and one or multiple domain name(s) or #gls("ip", long: false) address(es). An #emph([Abridged Assertion]) hashes the public key stored in an assertion to reduce the size, especially for potentially large @pq keys. -- A #emph([Batch]) is a collection of assertions that are certified simultaneously. The recommended #emph([Batch Duration]) is one hour, meaning that all assertions collected within this hour are certified at the same time. +- A #emph([Batch]) is a collection of assertions that are certified simultaneously. +- The #emph([Batch Duration]) is the time the batch spans. The authors recommend a Batch Duration of one hour, meaning that all assertions collected within this hour are certified at the same time in one Batch. - A #emph([Batch Tree Head]) is the Merkle Tree root node over all assertions of one batch. - An #emph([Inclusion Proof]) is a proof that a certain assertion is included in a batch. The proof consists of the hashes required to rebuild the path up to the Batch Tree Head. - A #emph([Validity Window]) is the range of consecutive batch tree heads that are valid at a time. @@ -61,7 +62,7 @@ Compared to today's Web@pki it has a reduced scope and assumes more prerequisite With this terminology, the following explains the certificate issuance flow depicted in @fig:mtc_overview + First, the @ap requests a certificate from the @ca. Due to the frequency of that operation, this should be an automated process using the @acme protocol, for example. -+ Every time a batch becomes ready, the @ca builds the Merkle Tree, signs the Batch Tree Head with a @pq algorithm, and publishes the tree to the Transparency Services. ++ Every time a batch becomes ready, the @ca builds the Merkle Tree, signs the whole Validity Window, which includes the new Batch Tree Head, with a @pq algorithm, and publishes the tree to the Transparency Services. + The @ca also sends the inclusion proof back to the @ap, which can subsequently use it to authenticate against #glspl("rp") that trust this batch. // + The Transparency Services recompute the Merkle Tree to validate the Merkle Tree Head contains exactly what is advertised and validate the signature of the Batch Tree Head. + Monitors mirror all Assertions published to the Transparency Services and check for fraudulent behavior. @@ -74,7 +75,7 @@ With this terminology, the following explains the certificate issuance flow depi The following sections elaborate on the responsibilities and objectives of the components involved. == Certification Authority -A @ca is defined by the following parameters that are publically known and cannot change. In particular, the Transparency Service trusts certain @ca:pl and uses these parameters to validate the signed validity windows it receives from the @ca:pl. +A @ca is defined by the following parameters that are publicly known and cannot change. In particular, the Transparency Service trusts certain @ca:pl and uses these parameters to validate the signed validity windows it receives from the @ca:pl. - `hash`: The hash function used to build the Merkle Tree. Currently, only #gls("sha")-256 is supported. - `issuer_id`: A @tai as defined in @rfc_tai. That is a relative @oid under the prefix `1.3.6.1.4.1`. Organizations append their @pen registered at the @iana. - `public_key`: The public key is used by the Transparency Services to validate the signed validity window. @@ -97,9 +98,15 @@ This will typically be a small time frame in which the @ca builds the Merkle Tre Subsequently, the batch transfers to the issued state, i.e., the @ca published the signed validity window and abridged assertions. As an invariant, all batches before the latest issued one must be issued as well, i.e., no gaps are allowed. -Every time a batch becomes ready, the @ca converts all assertions it found to be valid into abridged assertions by hashing the (possibly large) signature key in that assertion. -Afterward, it builds a Merkle Tree as depicted in @merkle_tree_abridged_assertion. -Lastly, the @ca signs a `LabeledValidityWindow` that contains the domain separator `Merkle Tree Crts ValidityWindow\0` to prevent cross protocol attacks, the `issuer_id`, the `batch_number`, and all Merkle Tree root hashes that are currently valid. +Every time a batch becomes ready, the @ca converts all assertions it found to be valid into abridged assertions by hashing the -- possibly large -- signature key in that assertion. +Afterward, it builds a Merkle Tree as depicted in @fig:merkle_tree_abridged_assertion. +Lastly, the @ca signs a `LabeledValidityWindow` that contains the domain separator `Merkle Tree Crts ValidityWindow\0`, the `issuer_id`, the `batch_number`, and all Merkle Tree root hashes that are currently valid. +The domain separator allows the protocol to be extended in the future, if the @ca would need to sign different structs with the same key. +One example could be the introduction of a revocation mechanism that requires the @ca to sign some data with the same key. +Signing the entire validity window instead of each tree root individually has two advantages: +For one, if a client or Transparency Service is behind more than one Tree Head, only a single signature needs to be transferred instead of multiple, which saves bandwidth and computational effort for the signature verification. +The second benefit is that it complicates split-view attacks. +A @ca would have to keep the split view for an entire validity window instead of just a single tree head, which increases the chances of it being noticed. // - As mentioned earlier: Merkle Trees @@ -112,7 +119,7 @@ Lastly, the @ca signs a `LabeledValidityWindow` that contains the domain separat #figure( merkle_tree_abridged_assertion(), -caption: [Example Merkle Tree for three abridged assertions ($"aa"_0", aa"_1", aa"_2$)]) +caption: [Example Merkle Tree for three assertions]) == The Role of the Transparency Service diff --git a/4_comparison.typ b/4_comparison.typ index 4e0a6a4..a397627 100644 --- a/4_comparison.typ +++ b/4_comparison.typ @@ -7,6 +7,7 @@ Based on the introduction to @pki in @sec:pki and the explanation of @mtc in @sec:mtc, it becomes obvious that there are significant differences between these architectures. This chapter presents the results of the analysis we conducted about the differences and the advantages and disadvantages the architectures result in. +// #heading("Advantages", level: 4, outlined: false, numbering: none) The most obvious change is the significant reduction of the certificate lifetime. The authors of @mtc propose a lifetime of 14 days. In contrast, as of October 2024, @tls leaf certificates for the Web@pki may be issued for at most 13 months, i.e., 398 days~@chrome_cert_lifetime @apple_cert_lifetime. @@ -24,8 +25,9 @@ As @ocsp entails high operational costs for @ca:pl, it is likely that @ocsp will Let's Encrypt already announced to end their @ocsp support "as soon as possible"~@lets_encrypt_end_ocsp. Instead, the CA/Browser forum tightens the requirements for @crl:pl and Mozilla is working on accumulating all revoked certificates into a small list called #emph("CRLite") since 2017, but did not enable this mechanism by default in Firefox as of version 132 from October 2024~@crlite_paper @mozilla_crlite. -Furthermore, certificate transparency is built into @mtc, as opposed to the X.509 certificate infrastructure, where it was added later on. +// Furthermore, certificate transparency is built into @mtc, as opposed to the X.509 certificate infrastructure, where it was added later on. +// #heading("Disadvantages", level: 4, outlined: false, numbering: none) A significant downside of @mtc compared to the classical certificate infrastructure is the longer issuance times. There are two aspects to this: First, the issuance of the certificate itself takes up to `batch_duration` seconds, i.e., one hour assuming the default values, and second, the time the new tree heads propagate to a relevant number of @rp:pl. The first one will not make up for the major part of the difference in practice. @@ -349,11 +351,11 @@ This does save development resources and reduces the attack surface as there exi Nowadays, Linux based operating systems such as Debian, RHEL, or Android store certificates on a well-known location for other programs to access it @go_root_store. // Debian, as an example, provides the trusted root certificates as a normal system package, which can be updated with the built-in package manager @debian_ca_certificates. -We use the X.509 file structure of Debian as an inspiration to propose a common file structure. +We use the X.509 file structure of Debian as an inspiration to bring up a common file structure. @fig:mtc_client_file_tree shows the file structure we propose for a @rp. The absolute path (`/etc/ssl/mtc`) might vary per distribution. The structure thereafter is more interesting. -We propose that each @ca lives in its own subdirectory, with the Issuer ID as the directory name. +We suggest that each @ca lives in its own subdirectory, with the Issuer ID as the directory name. The Issuer ID for @mtc:pl is an @oid, so directory names would look like `123.54.2`. The directory contains the @ca parameters, the root hashes of the validity window and optionally the signature of the validity window. As mentioned above, the signature is not necessary if the @rp trusts the Transparency Service and update mechanism. @@ -361,13 +363,13 @@ In this case, the Transparency Service is not operated by a browser vendor, but Still, the argument remains that a user needs to trust its @os vendor either way and may therefore skip synchronizing the signature. In the proposed structure, the validity window contains the same data as specified in the Internet-Draft, namely the batch number and the hashes of all valid tree heads. The @ca parameters contain the following information: -- The issuer ID, i.e., the @oid of the @ca -- The signature scheme used to sign the validity windows -- The public key of the @ca. It must match the signature scheme -- The proof type used for inclusion proof in the certificates. As of now, the only option is a #gls("sha")-256 based Merkle Tree inclusion proof -- The start time of the @ca, i.e., the time the @ca was set up. This is required to calculate the validity of a certificate based on its batch number -- The batch duration. This is required to calculate the validity of a certificate based on its batch number as well -- The validity window size. Again, This is required to calculate the validity of a certificate based on its batch number +- The issuer ID, i.e., the @oid of the @ca. +- The signature scheme used to sign the validity windows. +- The public key of the @ca. It must match the signature scheme. +- The proof type used for inclusion proof in the certificates. As of now, the only option is a #gls("sha")-256 based Merkle Tree inclusion proof. +- The start time of the @ca, i.e., the time the @ca was set up. This is required to calculate the validity of a certificate based on its batch number. +- The batch duration. This is required to calculate the validity of a certificate based on its batch number as well. +- The validity window size. Again, This is required to calculate the validity of a certificate based on its batch number. #figure( @@ -393,4 +395,65 @@ At the same time, storing some information on the @ap that is not strictly requi ) -// - The signature over the validity window has the advantage that a CA would need to keep a split view over the whole window instead of for a single batch. See https://github.com/davidben/merkle-tree-certs/issues/84 \ No newline at end of file +// - The signature over the validity window has the advantage that a CA would need to keep a split view over the whole window instead of for a single batch. See https://github.com/davidben/merkle-tree-certs/issues/84. + +== CPU Usage +The previous sections spend attention on the bytes that need to be transferred for a #gls("pq")-secure server authentication. +This section focuses on the computation required for server authentication in both systems, the classical, X.509 based and the @mtc based. +A low computational effort is beneficial for client devices, even though most have sufficient resources for complex computations. +Nevertheless, battery-powered devices may last longer and the available computing power can be used for different tasks. +For servers, which often handle numerous @tls connections, the computational efficiency is important as well, as they may need to be equipped with more powerful and therefore expensive hardware if @tls handshakes are significantly more laborious. + +We fund our estimates on the SUPERCOP project. +SUPERCOP is an acronym for #emph[System for Unified Performance Evaluation Related to Cryptographic Operations and Primitives]. +SUPERCOP publishes a database with benchmarks for various cryptographic primitives on various hardware configurations~@supercop. +All performance metrics we use were measured on the same machine with an AMD Ryzen~7~7700 with eight CPU cores at 3.8~GHz. +Unfortunately, there are no metrics for the final @pq signature algorithms available in the database yet. +Therefore, we used the benchmarks of the corresponding, preliminary algorithm versions. +For example, we used the metrics from Dilithium with level two security parameters from the third round of the @nist post quantum competition instead of #gls("mldsa")-44. + +It quickly becomes clear that a client verifying an #gls("mtc")-based server authentication requires fewer signature verifications compared to an X.509-based server authentication. +To verify an X.509 certificate chain, the client must typically verify two @sct:pl, maybe an @ocsp staple, one signature in the @ee certificate and one signature in the intermediate certificate. +Additionally, the client must verify the handshake signature. +To verify an @mtc certificate, the client must traverse up the Merkle Tree up to the root node, but does not require any asymmetric cryptography, assuming the @ca signature was verified either ahead of time or by the Transparency Service. +Just as for the X.509 system, the client must verify the handshake signature nevertheless. + +To estimate computational costs associated with the tree traversal, we assume a single hash operation with an input length of 4096-byte to create the abridged assertion. Additionally, we consider 21 or 26 hash operations, each with a 576-byte input, to reconstruct the internal nodes up to the root. +The 21 or 26 level correspond to 280 million or one billion active @ap:pl for a single @ca, as described in @sec:certificate_size. + +@tab:x509_cpu_cyles approximates the CPU cycles required for verifying an X.509 certificate chain with the same parameters as in @sec:certificate_size. +A first observation is that the verification of @rsa signatures is less computationally expensive than the verification of @ecdsa signatures. +Possibly more surprising is that the @pq secure @mldsa signature verification is less expensive than an @ecdsa signature verification. +Therefore, a certificate chain using @mldsa for all signatures requires only 27~% of the computation of a fully #gls("ecdsa")-based certificate chain. +Moreover, both @pq scenarios are less computationally expensive for a client compared to the classical scenarios. + +Nevertheless, using the @mtc architecture additionally decreases the computational costs for a client. +@tab:mtc_cpu_cyles displays the approximated CPU cycles required for validating an @mtc with the same parameters as in @sec:certificate_size. +As mentioned, only a single signature verification for the handshake is required. +The second variable which determines the computational cost is the number of active @ap:pl for a @ca. +Comparing an @ecdsa X.509 certificate chain with an @mtc that holds an @ecdsa key, reveals that the @mtc uses only 19~% of the computation the certificate chain requires. +Comparing the same @ecdsa certificate chain with an @mtc with 280 million active @ap:pl, shows that the @mtc case uses only 6.8~% of the computation the certificate chain requires. +Moreover, comparing the @pq use-cases with each other, we observe a reduction of 73~% to 85~% in the advantage of @mtc. + +#figure( + x509_cpu_cycles, + caption: [CPU cycles for verifying the server identity on a client device when using X.509 certificates. The numbers are based on the SUPERCOP database~@supercop-asym.] +) + +#figure( + mtc_cpu_cycles, + caption: [CPU cycles for verifying the server identity on a client device when using @mtc. The numbers are based on the SUPERCOP database~@supercop-asym @supercop-hash.] +) + +In terms of computation required, using @mtc or X.509 does not result in any difference for the server. +The signatures contained in the X.509 certificate are computed ahead of time by the @ca and Transparency Logs and are treated as opaque bytes by the server. +The same is true for the @mtc. +The certificate is mostly opaque to the server and, most importantly, sent as-is. +The server only computes the handshake signature during the handshake, which is necessary in the same manner for @mtc and X.509. + +// - Estimate the CPU cycles +// - Important for battery life +// - Nothing changes for the server. Either way, it has to create a single signature and send an already existing certificate. +// - We use the SUPERCOP database. SUPERCOP stands for "System for Unified Performance Evaluation Related to Cryptographic Operations and Primitives". +// - We assume SHA-256. Uses the same computer as the signatures in @tab:pq_signature_comp, an AMD Ryzen 7 7700 with 8 x 3800MHz. +// - For the path traversal, we assume 1 hash with 4096 bytes (abridged assertion) + 21/26 hashes of 576 bytes (inner nodes) \ No newline at end of file diff --git a/6_conclusion.typ b/6_conclusion.typ index 761e008..9d1d042 100644 --- a/6_conclusion.typ +++ b/6_conclusion.typ @@ -1 +1,71 @@ +#import "imports.typ": * + = Conclusion and Outlook + +Constant achievements in building quantum computers endanger many asymmetric cryptography systems used today. +This includes the signatures used in X.509-based certificates, which are used for server identification in @tls connections. +Replacing all signatures in the X.509-based architecture with #gls("pq")-secure signature schemes results in a big expansion of the certificate sizes. +This results in slower connections and more data to be transferred for each @tls handshake. + + +#cite(, form: "author") propose #glspl("mtc", long: true) to supplement the current X.509 architecture which reduces the number of signatures to shrink the size of certificates. +As a trade, certificates cannot be used immediately and the @mtc architecture requires a regular update channel between the Transparency Service and the #gls("rp", long: true). + +In this thesis, we analyzed theoretical improvements in terms of data transmission and computational effort when introducing @mtc and implemented a client as well as a server that use @mtc:pl to prove the server identity. +We showed that @mtc likely saves about 74~% to 80~% of the bytes related to the cryptographic server authentication compared to X.509 certificates when using #gls("pq")-secure signature schemes. +The actual improvement is even significant, as @mtc:pl use more efficient encoding and require less additional attributes in the certificate, such as not before / not after timestamps or @crl and @ocsp endpoints. + +In favor of small certificates, the @mtc architecture introduces an update mechanism between the Transparency Service and the @rp. +We listed three update scenarios with either 150 or 15~@ca:pl and argued that the new update mechanism does not harm the @mtc architecture too much. +Firstly, we think that 15 @mtc @ca:pl is a realistic estimate based on that @mtc are not meant as a replacement but an optional optimization of the current Web@pki. +Therefore, many @ca:pl will refrain from implementing these significant changes into their operation as they mainly serve small use-cases which do not amortize the effort to adopt @mtc. +The second argument we made is that the Transparency Services are likely operated by the browser vendors, which a user must unavoidable trust anyway. +Therefore, the @ca signatures can be checked by the Transparency Service in most cases and therefore save a lot of update bandwidth. +This results in about 12~kB update bandwidth per day and @rp. +Compared to about 900~kB to 1,300~kB per day for application updates in Chrome and Firefox, this is only a small addition. +Additionally, a single @tls handshake with @mtc instead of a @pq X.509 certificate chain amortizes the daily updates. +Other scenarios require a bigger update bandwidth, but we expect them to be relevant for only few instances (client signature checks), or far in the future if at all (150~@ca:pl). + +In addition to the size analysis, we estimated the computational cost associated with X.509 and @mtc. +We pointed out that there is no difference for a server, but clients can save about 81~% to 93~% in computational cost per handshake when using classical signature algorithms and about 73~% to 85~% when using #gls("pq")-save signature algorithms. + +To explore the practicality of the @mtc architecture, we adopted Rustls to support @mtc:pl. +This + +// - Problem statement (the bigger picture) +// - Quantum computers endanger current server identity validation in TLS +// - replacing signatures results in big certificates +// - results in fragmentation and slower connections + +// - Recap the preliminaries +// - Merkle Trees +// - PKI with OCSP, ACME, and Certificate Transparency +// - TLS handshake and KEMTLS +// - PQ signatures +// - Explanation of the MTC system +// - meant as an additional and optional improvement over the existing X.509 architecture +// - Certificate size +// - Update mechanism +// - Depends on the number of CAs and if the Transparency Service does the signature checking +// - Compared to loading a webpage or other regular updates, it has a reasonable size +// - In the best case, a single TLS handshake is enough to amortize the update size +// - CPU usage +// - PQ is better than ECDSA anyway (Better than RSA for the server) +// - MTC is even better + +- Common file structure +- Implemented + - Changes in Rustls + - Negotiation + - MTC verifier +- Various changes to the I-D + + +- Figure out a good update mechanism + - Must be PQ save + - Must be reasonably small + - Must work without MTC +- Analyze memory usage +- Use MTC in a larger real-world experiment + - Collect telemetry data +- My personal expectation: There will be bigger tests within the Google ecosystem in 2025 \ No newline at end of file diff --git a/references.bib b/references.bib index 2e4280c..e83f79d 100644 --- a/references.bib +++ b/references.bib @@ -539,10 +539,20 @@ @online{chrome_update_size urldate = {2024-12-11}, } -@online{noauthor_master_nodate, - title = {Master Thesis – style/radboud-slides.typ – Typst}, - url = {https://typst.app/project/pxkdLEVWUa1bEcgPko6Kbk}, - urldate = {2024-11-27}, +@online{supercop-hash, + title = {Measurements of hash functions on one machine: amd64; Zen 4 (a60f12); 2023 {AMD} Ryzen 7 7700; 8 x 3800MHz; hertz, supercop-20241022}, + url = {http://bench.cr.yp.to/results-hash/amd64-hertz.html}, + author = {{Daniel J. Bernstein} and {Tanja Lange}}, + urldate = {2024-12-20}, + note = {Page version: 20241215 22:59:22}, +} + +@online{supercop-asym, + title = {Measurements of public-key signature systems on one machine: amd64; Zen 4 (a60f12); 2023 {AMD} Ryzen 7 7700; 8 x 3800MHz; hertz, supercop-20241022}, + url = {http://bench.cr.yp.to/results-sign/amd64-hertz.html}, + author = {{Daniel J. Bernstein} and {Tanja Lange}}, + urldate = {2024-12-20}, + note = {Page version: 20241215 22:59:18}, } @online{merkle_town, @@ -852,6 +862,12 @@ @report{fips_205 doi = {10.6028/NIST.FIPS.205}, } +@online{supercop, + title = {{SUPERCOP}}, + url = {https://bench.cr.yp.to/supercop.html}, + urldate = {2024-12-26}, +} + @online{mozilla_crlite, title = {The End-to-End Design of {CRLite}}, url = {https://blog.mozilla.org/security/2020/01/09/crlite-part-2-end-to-end-design}, diff --git a/style/ru_template.typ b/style/ru_template.typ index 38b929e..c8b5b4c 100644 --- a/style/ru_template.typ +++ b/style/ru_template.typ @@ -29,8 +29,8 @@ set par(spacing: 0.55em, leading: 0.55em, first-line-indent: 1.8em, justify: true) show heading: it => block({ - if counter(heading).get() != (0,) { - box(counter(heading).display(), inset: (right: 1em)) + if counter(heading).get() != (0,) and it.numbering != none { + box(counter(heading).display(it.numbering), inset: (right: 1em)) } it.body }) @@ -76,7 +76,9 @@ } counter(page).update(0) - set page(numbering: "1", margin: (x: 8em, top:10em, bottom: 14em)) + set page( + numbering: "1", + margin: (x: 8em, top:10em, bottom: 14em)) doc } diff --git a/tables.typ b/tables.typ index f4914e4..e15ab98 100644 --- a/tables.typ +++ b/tables.typ @@ -81,7 +81,7 @@ table( let missing_zeros = precision - decimal_part.len() decimal_part + missing_zeros * "0" } else { - "00" + precision * "0" } let integer_part = parts.at(0).rev().clusters().enumerate() .map((item) => { @@ -90,7 +90,11 @@ table( thousands } }).rev().join("") - return integer_part + decimal + decimal_part + return if precision > 0 { + integer_part + decimal + decimal_part + } else { + integer_part + } } #let update_mechanism_size = { @@ -122,46 +126,61 @@ table( #let pq_signatures = { show table.cell: it => { - if it.y == 1 or it.y == 0 { - strong(it) - } else { + if it.y == 0 or it.y == 1{ + align(center + horizon, strong(it)) + } else if it.y == 2 { + align(center, it) + } else if it.x == 0 { + align(left, it) + } else if it.x == 1 { it + } else { + align(right, it) } } - let g = (x, body) => { + let g = (min, max, current, p: 2, ..additional) => { + let x = (current - min)/(max - min) let text_color = if x > 0.5 { white } else { black } - table.cell(fill: gradient.linear(..color.map.viridis).sample(100% - x * 100%), text(fill: text_color, body)) + let content = if additional.pos().len() > 0 { + additional.pos().at(0) + [#format_num(current, precision: p)] + } else { + [#format_num(current, precision: p)] + } + table.cell(fill: gradient.linear(..color.map.viridis).sample(100% - x * 100%), text(fill: text_color, content)) } grid( columns: (auto, auto), - gutter: 2em, + gutter: 1em, table( - columns: 6, - align: (left, center, left, left, left, left), + columns: 8, stroke: 0.3pt, table.header( - [], [], table.cell(colspan: 2)[Sizes (bytes)], table.cell(colspan: 2)[CPU time (lower is better)], - [Name], [PQ], [Public Key], [Signature], [Signing], [Verification]), - - [Ed25519], [#emoji.crossmark], g(32/1312)[32], g(64/17088)[64], g(1/8000)[1 (baseline)], g(1/7)[1 (baseline)], - [RSA-2048], [#emoji.crossmark], g(256/1312)[256], g(256/17088)[256], g(70/8000)[70], g(0.3/7)[0.3], - [ML-DSA-44], [#emoji.checkmark.box], g(1312/1312)[1,312], g(2420/17088)[2,420], g(4.8/8000)[4.8], g(0.5/7)[0.5], - [SLH-DSA-128s], [#emoji.checkmark.box], g(32/1312)[32], g(7856/17088)[7,856], g(8000/8000)[8,000], g(2.8/7)[2.8], - [SLH-DSA-128f], [#emoji.checkmark.box], g(32/1312)[32], g(17088/17088)[17,088], g(550/8000)[550], g(7/7)[7], - [FN-DSA-512], [#emoji.checkmark.box], g(897/1312)[897], g(666/17088)[666], g(8/8000)[8 #h(.3em) #box(height: 0.7em, inset: -1pt, image("images/red-alert-icon.svg"))], g(0.5/7)[0.5], + [], [], table.cell(colspan: 2)[Sizes (bytes)], table.cell(colspan: 4)[CPU cycles], + table.cell(rowspan: 2)[Name], table.cell(rowspan: 2)[PQ], table.cell(rowspan: 2)[Public Key], table.cell(rowspan: 2)[Signature], table.cell(colspan: 2)[Signing], table.cell(colspan: 2)[Verification], + [cycles], [relative], [cycles], [relative], + ), + + [Ed25519], [#emoji.crossmark], g(32, 1312, 32, p: 0), g(64, 17088, 64, p: 0), g(46314, 260458611, 46314, p: 0), g(1, 5623.76, 1), g(44881, 802701, 158754, p: 0), g(0.28, 5.06, 1), + [ECDSA P-256], [#emoji.crossmark], g(32, 1312, 32, p: 0), g(64, 17088, 64, p: 0), g(46314, 260458611, 108545, p: 0), g(1, 5623.76, 2.34), g(44881, 802701, 255095, p: 0), g(0.28, 5.06, 1.61), + [RSA-2048], [#emoji.crossmark], g(32, 1312, 256, p: 0), g(64, 17088, 256, p: 0), g(46314, 260458611, 1850021, p: 0), g(1, 5623.76, 39.95), g(44881, 802701, 44881, p: 0), g(0.28, 5.06, 0.28), + [ML-DSA-44], [#emoji.checkmark.box], g(32, 1312, 1312, p: 0), g(64, 17088, 2420, p: 0), g(46314, 260458611, 152827, p: 0), g(1, 5623.76, 3.30), g(44881, 802701, 68674, p: 0), g(0.28, 5.06, 0.43), + [SLH-DSA-128s], [#emoji.checkmark.box], g(32, 1312, 32, p: 0), g(64, 17088, 7856, p: 0), g(46314, 260458611, 260458611, p: 0), g(1, 5623.76, 5623.76), g(44881, 802701, 341835, p: 0), g(0.28, 5.06, 2.15), + [SLH-DSA-128f], [#emoji.checkmark.box], g(32, 1312, 32, p: 0), g(64, 17088, 17088, p: 0), g(46314, 260458611, 15385413, p: 0), g(1, 5623.76, 332.20), g(44881, 802701, 802701, p: 0), g(0.28, 5.06, 5.06), + [FN-DSA-512], [#emoji.checkmark.box], g(32, 1312, 897, p: 0), g(64, 17088, 666, p: 0), g(46314, 260458611, 327217, p: 0), g(1, 5623.76, 7.07, [#box(height: 0.7em, inset: -1pt, image("images/red-alert-icon.svg")) #h(.3em)]), g(44881, 802701, 62934, p: 0), g(0.28, 5.06, 0.40), ), align(horizon, grid( gutter: .5em, + align: center, text(size: .8em)[bad\ performance], rect( - width: 10pt, + width: 1em, height: 8em, fill: gradient.linear( dir: ttb, @@ -174,7 +193,104 @@ table( ) } -#let x509_certificate_sizes(kem: true, results_only: false) = { +#let mtc_cpu_cycles = { + show table.cell: it => { + if it.y == 0 or it.x == 2 { + strong(it) + } else { + it + } + } + + let f = (x) => table.cell(format_num(x, precision: 0)) + +table( + columns: 4, + + fill: (x, y) => { + if calc.even(y) and y > 0 { + gray.lighten(40%) + } + }, + + align: (x, y) => { + if calc.even(y) and y > 0 and x != 3 { + right + } else if y > 0 and x != 3 { + left + } else { + center + } + }, + + table.header( + [Handshake signature], [Tree Traversal], [$sum$], [PQ], + ), + + [ECDSA-256], [280M active APs], [], [], + f(255095), f(35734), f(290829), [#emoji.crossmark], + + [RSA-2048], [1B active APs], [], [], + f(44881), f(42243), f(87124), [#emoji.crossmark], + + [ML-DSA-44], [280M active APs], [], [], + f(68674), f(35734), f(104408), [#emoji.checkmark.box], + + [ML-DSA-44], [1B active APs], [], [], + f(68674), f(42243), f(110917), [#emoji.checkmark.box], +) +} + +#let x509_cpu_cycles = { + show table.cell: it => { + if it.y == 0 or it.y == 1 or it.x == 4 { + strong(it) + } else { + it + } + } + + let f = (x) => table.cell(format_num(x, precision: 0)) + +table( + columns: 6, + + fill: (x, y) => { + if calc.odd(y) and y > 1 { + gray.lighten(40%) + } + }, + + align: (x, y) => { + if calc.odd(y) and y > 1 and x != 5 { + right + } else if y > 1 and x != 5 { + left + } else { + center + } + }, + + table.header( + table.cell(colspan: 4)[Signatures], [$sum$], [PQ], + [Handshake],[SCT + OCSP], [EE], [Intermediate], [], [] + ), + + [ECDSA-256], [ECDSA-256], [ECDSA-256], [ECDSA-256], [], [], + f(255095), f(765285), f(255095), f(255095), f(1530570), [#emoji.crossmark], + + [RSA-2048], [ECDSA-256], [RSA-2048], [RSA-4096], [], [], + f(44881), f(765285), f(44881), f(120280), f(975327), [#emoji.crossmark], + + [ML-DSA-44], [ML-DSA-44], [ML-DSA-44], [ML-DSA-44], [], [], + f(68674), f(206022), f(68674), f(68674), f(412044), [#emoji.checkmark.box], + + [ML-DSA-44], [ML-DSA-44], [ML-DSA-44], [SLH-DSA-128s], [], [], + f(68674), f(206022), f(68674), f(341835), f(685205), [#emoji.checkmark.box], +) +} + +#let x509_certificate_sizes(kem: true) = { show table.cell: it => { if it.y == 0 or it.y == 1 or it.x == 6 { @@ -211,7 +327,7 @@ table( [ECDSA-256], [ECDSA-256], [ECDSA-256], [ECDSA-256], [ECDSA-256], [ECDSA-256], [], [], [64], [192], [64], [64], [32], [32], [448], [#emoji.crossmark], - [RSA-2048], [ECDSA], [RSA-2048], [RSA-4096], [RSA-2048], [RSA-2048], [], [], + [RSA-2048], [ECDSA-256], [RSA-2048], [RSA-4096], [RSA-2048], [RSA-2048], [], [], [256], [192], [256], [512], [256], [256], [1,728], [#emoji.crossmark], [ML-DSA-44], [ML-DSA-44], [ML-DSA-44], [ML-DSA-44], [ML-DSA-44], [ML-DSA-44], [], [],