以下の内容はドキュメントからの転記ではありません。2026年10月20日に、チェック content/libraries/verify/swift-crypto/run.sh がコンテナイメージ swift:6.4.1-noble 内で swift-crypto 5.0.3 を実行しました。このページの内容はその出力と一致していなければならず、各事実には該当する出力行を示しています。
ECDSA 署名のエンコーディング
structuredECDSASignature には 64 バイトの rawRepresentation と derRepresentation があります。そのバイト列(withUnsafeBytes)は生形式です。
チェックによる記録
fact ecdsa-signature-encoding = structured
evidence ecdsa-signature-encoding: signature(for:) returns P256.Signing.ECDSASignature: rawRepresentation 64 bytes, derRepresentation starts with 0x30 and converts back: yes, withUnsafeBytes yields the raw form: yes
ECDSA の nonce
random同じメッセージへの 2 つの署名は異なり、RFC 6979 A.2.5 の鍵とメッセージからは RFC に記載された r が得られませんでした。
チェックによる記録
fact ecdsa-nonce = random
evidence ecdsa-nonce: two signatures of one message are different; r for the RFC 6979 A.2.5 key and message equals the RFC's r: no
署名時の low-S
eithers は正規化されません。64 個の署名の中に high-S の値が現れました。
チェックによる記録
fact ecdsa-low-s-sign = either
evidence ecdsa-low-s-sign: signatures with s > n/2 among 64: yes
検証時の high-S
accepts-high-ss を n − s に置き換えた署名も検証を通りました。
チェックによる記録
fact ecdsa-low-s-verify = accepts-high-s
evidence ecdsa-low-s-verify: isValidSignature with s replaced by n - s: true
署名呼び出しがハッシュする対象
hashes-message-or-digestsignature(for: data) はデータをハッシュします。signature(for: SHA256.hash(data: message)) で作った署名は、メッセージに対して検証できました。
チェックによる記録
fact ecdsa-prehash = hashes-message-or-digest
evidence ecdsa-prehash: signature(for: SHA256.hash(data: message)) verifies with isValidSignature(_:for: message): yes
メッセージに適用されるハッシュ
curve-matchedデータに対する署名は、P-256 では SHA-256、P-384 では SHA-384、P-521 では SHA-512 のハッシュ値に対する署名として検証できました。
チェックによる記録
fact ecdsa-message-hash = curve-matched
evidence ecdsa-message-hash: signature(for: data) verifies as a signature over SHA-256 on P-256: yes, SHA-384 on P-384: yes, SHA-512 on P-521: yes
曲線に紐付くハッシュ
noneP-384 の鍵で SHA-256 のダイジェストに署名でき、その署名は検証を通りました。
チェックによる記録
fact ecdsa-hash-curve-binding = none
evidence ecdsa-hash-curve-binding: a P-384 key signed a SHA-256 digest, and the signature verifies: yes
曲線の位数より長いダイジェスト
truncatedP-256 の鍵で SHA-512 のダイジェストに署名できました。openssl pkeyutl では、ダイジェストの先頭 32 バイトに対する署名として検証できました。
チェックによる記録
fact ecdsa-long-input = truncated
evidence ecdsa-long-input: a P-256 key signed a SHA-512 digest without an error
evidence ecdsa-long-input: openssl pkeyutl verifies that signature over the first 32 digest bytes: yes
不正な形式の ECDSA 署名
throwsinit(derRepresentation:) は生の r‖s 署名と 3 バイトのデータに対して truncatedASN1Field をスローし、init(rawRepresentation:) は DER と 3 バイトのデータに対して incorrectParameterSize をスローしました。
チェックによる記録
fact ecdsa-malformed-signature = throws
evidence ecdsa-malformed-signature: ECDSASignature(derRepresentation:) with the RFC 6979 A.2.5 signature as raw r||s: threw CryptoKitASN1Error.truncatedASN1Field; with 3 bytes: threw CryptoKitASN1Error.truncatedASN1Field
evidence ecdsa-malformed-signature: ECDSASignature(rawRepresentation:) with DER: threw CryptoKitError.incorrectParameterSize; with 3 bytes: threw CryptoKitError.incorrectParameterSize
evidence ecdsa-malformed-signature: isValidSignature for a valid signature over another message: false
ECDSA の曲線
P-256P-384P-521P-256、P-384、P-521 で署名と検証ができました。ソースではそれ以外の ECDSA 曲線は宣言されていません。
チェックによる記録
fact ecdsa-curves = P-256, P-384, P-521
evidence ecdsa-curves: key types declared in Sources/Crypto and Sources/CryptoExtras: Curve25519 MLDSA65 MLDSA87 MLKEM1024 MLKEM768 P256 P384 P521 XWingMLKEM768X25519
EdDSA
Ed25519Curve25519.Signing(Ed25519)です。ソースには Ed448 の型が宣言されていません。
チェックによる記録
fact eddsa = Ed25519
決定的な Ed25519 署名
yes同じメッセージへの 2 つの署名は同一で、RFC 8032 のテスト 1 の署名と一致しました。swift-crypto の署名は OpenSSL で検証できました。
チェックによる記録
fact ed25519-deterministic = yes
evidence ed25519-deterministic: RFC 8032 test 1: the derived public key matches: yes, the RFC signature verifies: yes
evidence ed25519-deterministic: swift-crypto's signature with the same key and message equals the RFC signature: yes; two signatures are identical: yes; both verify: yes
evidence ed25519-deterministic: OpenSSL 3.0.13 pkeyutl on a swift-crypto Ed25519 signature: Signature Verified Successfully
非正規の S を含む Ed25519 署名
rejectedRFC 8032 のテスト 1 の署名で S を S + L に置き換えたものは拒否されました。
チェックによる記録
fact ed25519-non-canonical-s = rejected
evidence ed25519-non-canonical-s: the RFC 8032 test 1 signature with S replaced by S + L
位数の小さい Ed25519 公開鍵
accepted単位元(identity point)を公開鍵としてインポートでき、R = 単位元、S = 0 の署名も検証を通りました。
チェックによる記録
fact ed25519-small-order-key = accepted
evidence ed25519-small-order-key: the identity point as public key: import accepted; signature R = identity, S = 0 verifies: yes
不正な形式の Ed25519 署名
rejected0xab を 64 バイト並べた署名と 63 バイトの署名では、false が返りました。
チェックによる記録
fact ed25519-malformed-signature = rejected
evidence ed25519-malformed-signature: 64 bytes of 0xab: false; 63 bytes of the RFC signature: false
ポスト量子アルゴリズム
ML-KEMML-DSAX-WingML-KEM と X-Wing ではカプセル化とデカプセル化が一通り動作し、ML-DSA の署名も検証できました。X-Wing は HPKE 経由でも動作しました。
チェックによる記録
fact pqc = ML-KEM, ML-DSA, X-Wing
evidence pqc: ML-KEM-768: public key 1184 bytes, ciphertext 1088 bytes, shared secrets match: yes
evidence pqc: ML-KEM-1024: public key 1568 bytes, ciphertext 1568 bytes, shared secrets match: yes
evidence pqc: ML-DSA-65: public key 1952 bytes, signature 3309 bytes, verifies: yes; ML-DSA-87: signature 4627 bytes, verifies: yes
evidence pqc: X-Wing (XWingMLKEM768X25519): public key 1216 bytes, ciphertext 1120 bytes, shared secrets match: yes
evidence pqc: HPKE with XWingMLKEM768X25519_SHA256_AES_GCM_256 opens its own message: yes
ML-KEM のパラメーターセット
ML-KEM-768ML-KEM-1024MLKEM768 と MLKEM1024 ではカプセル化とデカプセル化が一通り動作しました。ソースには ML-KEM-512 の型が宣言されていません。
チェックによる記録
fact ml-kem-parameter-sets = ML-KEM-768, ML-KEM-1024
ML-DSA のパラメーターセット
ML-DSA-65ML-DSA-87MLDSA65 と MLDSA87 で署名と検証ができました。ソースには ML-DSA-44 の型が宣言されていません。
チェックによる記録
fact ml-dsa-parameter-sets = ML-DSA-65, ML-DSA-87
ML-DSA の署名モード
hedged同じメッセージへの 2 つの ML-DSA-65 署名は異なりました(ヘッジ付き署名)。
チェックによる記録
fact ml-dsa-signing = hedged
evidence ml-dsa-signing: two ML-DSA-65 signatures of one message are different
ML-DSA のコンテキスト文字列
supportedコンテキスト invoice-v1 を指定した署名は、同じコンテキストでは検証を通り、invoice-v2 を指定した場合とコンテキストなしの場合は検証に失敗しました。
チェックによる記録
fact ml-dsa-context-string = supported
evidence ml-dsa-context-string: signed with context "invoice-v1": verifies with it yes, with "invoice-v2" no, without a context no
不正な形式の ML-DSA 署名
returns-false切り詰めた署名、3 バイトのデータ、誤ったメッセージでは false が返りました。
チェックによる記録
fact ml-dsa-malformed-signature = returns-false
evidence ml-dsa-malformed-signature: isValidSignature: truncated signature false, 3 bytes false, wrong message false
改変された ML-KEM 暗号文
implicit-rejection暗号文の 1 ビットを反転させると、decapsulate は送信者側の鍵とは異なる鍵を返しました。
チェックによる記録
fact ml-kem-modified-ciphertext = implicit-rejection
evidence ml-kem-modified-ciphertext: ML-KEM-768 with one ciphertext bit flipped: decapsulate returned a key that differs from the sender's
ポスト量子暗号の秘密鍵
seed-onlyseedRepresentation は ML-KEM-768 では 64 バイト、ML-DSA-65 では 32 バイトで、そこから復元した鍵は元の鍵と一致しました。
チェックによる記録
fact pq-private-keys = seed-only
evidence pq-private-keys: ML-KEM-768 seedRepresentation 64 bytes, integrityCheckedRepresentation 96 bytes; ML-DSA-65 seedRepresentation 32 bytes, integrityCheckedRepresentation 64 bytes
evidence pq-private-keys: keys rebuilt from the seed alone have the same public key: ML-KEM-768 yes, ML-DSA-65 yes
公開鍵の形式
spki-pemspki-dersec1-uncompressedsec1-compressedraw-xyraw-32P-256 の SPKI(PEM と DER)、SEC1 の非圧縮形式と圧縮形式、生の x‖y、さらに Ed25519 の 32 バイトの生データは、いずれも書き出しと読み戻しができました。
チェックによる記録
fact public-key-formats = spki-pem, spki-der, sec1-uncompressed, sec1-compressed, raw-xy, raw-32
evidence public-key-formats: P-256 public key sizes: raw 64, x963 65, compressed 33, DER 91; PEM header -----BEGIN PUBLIC KEY-----; Ed25519 raw 32
evidence public-key-formats: written and read back: spki-pem yes, spki-der yes, sec1-uncompressed yes, sec1-compressed yes, raw-xy yes, raw-32 yes
秘密鍵の形式
pkcs8-pempkcs8-dersec1-pemsec1-derraw-scalarseed-32PKCS#8 と SEC1(PEM または DER)、P-256 の生のスカラー、Ed25519 のシードを読み込めます。書き出しは PKCS#8 で、暗号化された PKCS#8 は拒否されます。
チェックによる記録
fact private-key-formats = pkcs8-pem, pkcs8-der, sec1-pem, sec1-der, raw-scalar, seed-32
evidence private-key-formats: P-256 private key written as: derRepresentation PKCS#8 (138 bytes), pemRepresentation -----BEGIN PRIVATE KEY-----, rawRepresentation 32 bytes, x963Representation 97 bytes
evidence private-key-formats: OpenSSL-written P-256 keys read: pkcs8-pem yes, pkcs8-der yes, encrypted-pkcs8 no, sec1-pem yes, sec1-der yes; encrypted PKCS#8: threw CryptoKitASN1Error.invalidPEMDocument